{"slug":"real-returns-vs-random-walks","qid":"simulated_drawdowns","label":"simulated_drawdowns","post_title":"real-returns-vs-random-walks","post_url":"/blog/real-returns-vs-random-walks#q-simulated_drawdowns","columns":["percentile","sim_drawdown_depth_pct","spy_drawdown_depth_pct","paths_at_least_as_deep_pct"],"rows":[{"percentile":"p05","sim_drawdown_depth_pct":31.8,"spy_drawdown_depth_pct":56.5,"paths_at_least_as_deep_pct":14},{"percentile":"p25","sim_drawdown_depth_pct":37.9,"spy_drawdown_depth_pct":56.5,"paths_at_least_as_deep_pct":14},{"percentile":"p50","sim_drawdown_depth_pct":45,"spy_drawdown_depth_pct":56.5,"paths_at_least_as_deep_pct":14},{"percentile":"p75","sim_drawdown_depth_pct":51.5,"spy_drawdown_depth_pct":56.5,"paths_at_least_as_deep_pct":14},{"percentile":"p95","sim_drawdown_depth_pct":63.3,"spy_drawdown_depth_pct":56.5,"paths_at_least_as_deep_pct":14}],"shape":"ranking","sql":"WITH daily AS (SELECT date, argMax(toFloat64(close), _ingest_time) AS px FROM global_markets.stocks_daily_aggs WHERE ticker = 'SPY' AND date >= '2006-01-01' AND date <= '2026-09-30' GROUP BY date),\nrets AS (SELECT date, px / prev_px - 1 AS ret FROM (SELECT date, px, lagInFrame(px) OVER (ORDER BY date ROWS BETWEEN 1 PRECEDING AND CURRENT ROW) AS prev_px FROM daily) WHERE prev_px > 0),\nstats AS (SELECT avg(ret) AS mu, stddevPop(ret) AS sd, count() AS n FROM rets),\nreal_curve AS (SELECT date, sum(log(1 + ret)) OVER (ORDER BY date ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) AS log_equity FROM rets),\nreal_depth AS (SELECT 100 * (1 - exp(min(log_equity - greatest(peak, 0.0)))) AS depth_pct FROM (SELECT log_equity, max(log_equity) OVER (ORDER BY date ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) AS peak FROM real_curve)),\nsteps AS (SELECT pp.p AS path_id, arrayJoin(range(toUInt32(s.n))) AS t, s.mu AS mu, s.sd AS sd FROM stats AS s CROSS JOIN (SELECT arrayJoin(range(400)) AS p) AS pp),\ndraws AS (SELECT path_id, t, mu + sd * sqrt(-2 * log((cityHash64('strasmore-walk', path_id, t) % 1000000 + 0.5) / 1000000)) * cos(2 * pi() * ((cityHash64('strasmore-phase', t, path_id) % 1000000 + 0.5) / 1000000)) AS ret FROM steps),\nsim_curve AS (SELECT path_id, t, sum(log(1 + ret)) OVER (PARTITION BY path_id ORDER BY t ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) AS log_equity FROM draws),\nsim_depth AS (SELECT path_id, 100 * (1 - exp(min(log_equity - greatest(peak, 0.0)))) AS depth_pct FROM (SELECT path_id, log_equity, max(log_equity) OVER (PARTITION BY path_id ORDER BY t ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) AS peak FROM sim_curve) GROUP BY path_id),\nsummary AS (SELECT quantilesDeterministic(0.05, 0.25, 0.5, 0.75, 0.95)(d.depth_pct, d.path_id) AS qs, round(any(r.depth_pct), 1) AS spy_depth, round(100 * countIf(d.depth_pct >= r.depth_pct) / count(), 1) AS deeper_share FROM sim_depth AS d CROSS JOIN real_depth AS r)\nSELECT\n    tupleElement(tagged, 1)           AS percentile,\n    round(tupleElement(tagged, 2), 1) AS sim_drawdown_depth_pct,\n    spy_depth                         AS spy_drawdown_depth_pct,\n    deeper_share                      AS paths_at_least_as_deep_pct\nFROM (SELECT arrayJoin(arrayZip(['p05', 'p25', 'p50', 'p75', 'p95'], qs)) AS tagged, spy_depth, deeper_share FROM summary)","computed_at":"2026-10-01T15:35:50.344304+00:00","elapsed":4.539502622}