Drawdown Series
Peak-to-trough drawdown series plus the maximum drawdown. Input is a returns array (prices also accepted). A standard performance primitive. Edge-first; wired to more than one Price Factor it fans out to per-ticker by_symbol results.
What (One-liner)
A Layer-1 transform: consume a returns series, emit the running drawdown series and its minimum (max drawdown). max_drawdown = -0.23 means a 23% peak-to-trough loss.
Inputs
returns(array, required) — return series (prices accepted too).
Outputs
drawdown— drawdown at each point, in (-1, 0].max_drawdown— maximum drawdown over the series, in (-1, 0].by_symbol— per-ticker map when fed by multiple Price Factors.
How to use
- Provide a
returnsarray. - Read the
drawdownarray plus themax_drawdownscalar.
Core formulas
cum_t = Π(1 + r_i) for i in 1..t (starts at 1.0)
running_max_t = max(cum_1, ..., cum_t)
dd_t = (cum_t - running_max_t) / running_max_t ∈ (-1, 0]
max_drawdown = min(drawdown)Assumptions & applicability
Assumptions: simple returns (not log) + compounding + starting 1.0.
Applicable: backtest performance, CPPI, fund fact-sheet; any asset class, any frequency, min 2 observations.
Not applicable: price-series input where returns are expected, log returns, n<2.
Known limitations
- Path-dependent — only reflects the supplied window, not an all-time peak.
- Says nothing about recovery time or drawdown frequency.
- Starting point 1.0 (not actual capital).
- log returns will have second-order error.
References
Magdon-Ismail & Atiya (2004) + Chekhlov et al. (2005) optimization embedding.
Golden Test
tests/golden/fixtures/tier1/drawdown_series/, 1e-12 tolerance, passing as of 2026-05-25. Reference: numpy manual reproduction (cumprod + maximum.accumulate).
Changelog
- 1.1.0 (2026-05-25) — Promoted to Active as Layer-1 transform; merged rich governance fields from the superseded Layer-0
drawdown_seriescard. - 1.0.0 (2026-05-23) — Initial edge-first Layer-1 Draft card.

