Skip to main content

Drawdown

How far below its own running peak the price is, at every session. Zero at each new high, negative everywhere else — so this is an area that hangs under a fixed zero baseline rather than standing on the axis floor. It answers the question a price chart doesn't: not "what did it do" but "how much of the pain would I have sat through".

The chart​

The full year is in view. The curve touches zero exactly 20 times — those are the new highs, and there are no more of them after 2025-12-01. It bottoms at −23.5% on 2026-04-22, 97 sessions after that peak, and finishes the year still 10.1% under water.

The data​

The prices are modelled, not measured — see the fixture header for the process and the candlestick page for why. The same 251-session year as the other three finance cards.

Drawdown isn't a column in that fixture; the chart derives it. Which is the point of this page — the interesting quantity is usually one pass away from the data you have, and pond keeps it a column rather than a chart feature.

The shape of the result on this year:

StatisticValue
Maximum drawdown−23.5%, 2025-12-01 → 2026-04-22
Peak → trough97 sessions
Sessions under water231 of 251 (92%)
Sessions more than 10% under134
Recovered to the old peak?No — the year ends 10.1% down from it

92% under water is not a quirk of this realization; it is what drawdown is. The series is at zero only on the day it makes a new high, and a year has rather few of those.

Build it​

One pass, carrying the running maximum. withColumn appends the result, so what comes back is still an ordinary series:

const close = bars.column('close').toFloat64Array();
const drawdown = new Float64Array(close.length);
let peak = -Infinity;
for (let i = 0; i < close.length; i += 1) {
if (close[i] > peak) peak = close[i];
drawdown[i] = close[i] / peak - 1;
}
const series = bars.withColumn('drawdown', drawdown);

One caveat that comes with the territory: this is a path-dependent quantity, so the series you run it over has to start where the history starts. Cropping a middle slice out and computing the drawdown on that gives you the drawdown from the slice's own high, which is a different (and usually much shallower) number. The Gallery card animates by revealing a growing prefix rather than scanning a window for exactly this reason.

Then draw it. The one prop that makes this chart the shape it is:

<AreaChart series={series} column="drawdown" axis="dd" baseline={0} />

With baseline={0} (the default, written out here because it is the point of the chart) the fill rests on zero and hangs below it. With baseline="floor" it would fill from the curve down to −25% instead and read as a mountain range upside down. Zero is on the axis because the data reaches it — drawdown is exactly zero at every new high — not because of the baseline, which never changes the axis range. Values on both sides of the baseline fill in both directions, which is the same prop the mirrored in/out traffic charts use.

Two finishing touches. A percentage axis format, since a drawdown is a fraction:

<YAxis id="dd" label="drawdown" side="right" format=".0%" width={62} />

And a colour that comes from the theme, not a literal:

<AreaChart series={series} column="drawdown" axis="dd" as="out" baseline={0} />

out is the theme's below-the-baseline area role — the downward half of the mirrored-traffic pair. If your theme wants a dedicated loss tone, the fix is a role in the theme, not a hex in the chart.

Options to try​

OptionWhat it doesReach for it when
baseline="floor"Fills to the axis floor instead of zeroThe quantity has no meaningful zero (an elevation profile)
A second row with the pricePrice above, underwater curve below, one cursorReaders need to connect a dip to the price move that caused it
<Baseline value={-0.1}>A marked threshold across the plotYou have a policy line — a 10% stop, a risk limit
curve="monotone"Smooths the edge without moving the pointsDense daily data reads as noise at card size
A rolling window instead of the all-time peakDrawdown from a trailing high rather than the recordYou care about recent pain, not the 2007 peak
gaps="none"Bridges straight across missing rowsYour source has holes you'd rather not draw attention to (the honest default is 'empty')

See also​

  • <AreaChart> — baseline, gaps, curves, the mirrored two-colour composition
  • Gaps — what a missing value draws, and the modes
  • Theming — area roles, and adding one rather than passing a colour
  • Candles on a trading calendar — the price this is derived from
  • Storybook — the systematic knob walk