{"slug":"how-markets-recover-from-crashes","qid":"buckets","label":"How far below its high the S&P 500 sits: share of trading days since 2016","post_title":"How Markets Recover From Crashes","post_url":"/blog/how-markets-recover-from-crashes#q-buckets","columns":["bucket","pct_of_trading_days"],"rows":[{"bucket":"At a new high","pct_of_trading_days":29.7},{"bucket":"Within 5% of the high","pct_of_trading_days":38.7},{"bucket":"5-10% below","pct_of_trading_days":15.1},{"bucket":"10-20% below","pct_of_trading_days":13.6},{"bucket":"More than 20% below","pct_of_trading_days":2.8}],"shape":"ranking","sql":"WITH d AS (\n    SELECT toDate(toTimeZone(window_start, 'America/New_York')) AS dt,\n           argMax(toFloat64(close), toTimeZone(window_start, 'America/New_York')) AS c\n    FROM global_markets.delayed_stocks_minute_aggs\n    WHERE ticker = 'SPY' AND window_start >= '2016-01-01'\n      AND (toHour(toTimeZone(window_start, 'America/New_York')) * 60\n           + toMinute(toTimeZone(window_start, 'America/New_York'))) BETWEEN 570 AND 959\n    GROUP BY dt\n),\ndd AS (\n    SELECT dt,\n           (c / max(c) OVER (ORDER BY dt ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) - 1) * 100 AS ddpct\n    FROM d\n),\nb AS (\n    SELECT multiIf(ddpct >= -0.5, 'At a new high',\n                   ddpct >= -5,   'Within 5% of the high',\n                   ddpct >= -10,  '5-10% below',\n                   ddpct >= -20,  '10-20% below',\n                                  'More than 20% below') AS bucket,\n           multiIf(ddpct >= -0.5, 0, ddpct >= -5, 1, ddpct >= -10, 2, ddpct >= -20, 3, 4) AS ord\n    FROM dd\n)\nSELECT bucket, round(100.0 * count() / (SELECT count() FROM b), 1) AS pct_of_trading_days\nFROM b GROUP BY bucket, ord ORDER BY ord","computed_at":"2026-07-16T11:18:59.921389+00:00","elapsed":0.002964873}