{"slug":"investing-at-all-time-highs","qid":"drawdowns","label":"drawdowns","post_title":"investing-at-all-time-highs","post_url":"/blog/investing-at-all-time-highs#q-drawdowns","columns":["peak_label","trough_label","decline_pct","days_to_new_high","new_high_label"],"rows":[{"peak_label":"Oct 9, 2007","trough_label":"Mar 9, 2009","decline_pct":56.5,"days_to_new_high":1983,"new_high_label":"Mar 14, 2013"},{"peak_label":"Feb 19, 2020","trough_label":"Mar 23, 2020","decline_pct":34.1,"days_to_new_high":181,"new_high_label":"Aug 18, 2020"},{"peak_label":"Jan 3, 2022","trough_label":"Oct 12, 2022","decline_pct":25.4,"days_to_new_high":746,"new_high_label":"Jan 19, 2024"},{"peak_label":"Sep 20, 2018","trough_label":"Dec 24, 2018","decline_pct":20.2,"days_to_new_high":221,"new_high_label":"Apr 29, 2019"},{"peak_label":"Feb 19, 2025","trough_label":"Apr 8, 2025","decline_pct":19,"days_to_new_high":128,"new_high_label":"Jun 27, 2025"},{"peak_label":"May 21, 2015","trough_label":"Feb 11, 2016","decline_pct":14.4,"days_to_new_high":418,"new_high_label":"Jul 12, 2016"},{"peak_label":"Jan 26, 2018","trough_label":"Apr 2, 2018","decline_pct":10.2,"days_to_new_high":210,"new_high_label":"Aug 24, 2018"}],"shape":"table","sql":"WITH\n    daily AS\n    (\n        SELECT\n            date,\n            toFloat64(argMax(close, _ingest_time)) AS close\n        FROM global_markets.stocks_daily_aggs\n        WHERE ticker = 'SPY'\n        GROUP BY date\n    ),\n    flagged AS\n    (\n        SELECT\n            date,\n            close,\n            close >= max(close) OVER (ORDER BY date ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) AS is_record,\n            min(date) OVER ()                                                                          AS series_start\n        FROM daily\n    ),\n    runs AS\n    (\n        SELECT\n            date,\n            close,\n            series_start,\n            max(if(is_record = 1, date, toDate('1970-01-01'))) OVER (ORDER BY date ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) AS peak_date\n        FROM flagged\n    ),\n    by_peak AS\n    (\n        SELECT\n            peak_date,\n            argMin(close, date) AS peak_close,\n            min(close)          AS trough_close,\n            argMin(date, close) AS trough_date\n        FROM runs\n        WHERE peak_date >= addYears(series_start, 4)\n        GROUP BY peak_date\n    ),\n    with_next AS\n    (\n        SELECT\n            peak_date,\n            peak_close,\n            trough_close,\n            trough_date,\n            leadInFrame(peak_date, 1) OVER (ORDER BY peak_date ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING) AS next_peak\n        FROM by_peak\n    )\nSELECT\n    formatDateTime(peak_date, '%b %e, %Y')                                        AS peak_label,\n    formatDateTime(trough_date, '%b %e, %Y')                                      AS trough_label,\n    round(100 * (1 - trough_close / peak_close), 1)                               AS decline_pct,\n    if(next_peak > peak_date, dateDiff('day', peak_date, next_peak), 0)           AS days_to_new_high,\n    if(next_peak > peak_date, formatDateTime(next_peak, '%b %e, %Y'), 'not yet')  AS new_high_label\nFROM with_next\nWHERE decline_pct >= 10\nORDER BY decline_pct DESC\nLIMIT 10","computed_at":"2026-09-20T15:14:15.543644+00:00","elapsed":0.003143244}