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} />

Without baseline, an <AreaChart> fills from its value line down to the axis's lower bound — the elevation-profile form, which for an all-negative series fills from the curve down to −25% and reads as a mountain range upside down. With baseline={0}, the fill rests on zero and hangs below it, and the fixed baseline is pulled into the auto-fit domain so the zero line is always on screen. 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
Drop baselineFills 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