{"slug":"real-returns-vs-random-walks","qid":"run_lengths","label":"run_lengths","post_title":"real-returns-vs-random-walks","post_url":"/blog/real-returns-vs-random-walks#q-run_lengths","columns":["down_run_length","spy_runs","coin_flip_runs","down_day_share_pct","sample_from","sample_to"],"rows":[{"down_run_length":"1","spy_runs":728,"coin_flip_runs":707.4,"down_day_share_pct":45.3,"sample_from":"January 4, 2006","sample_to":"September 30, 2026"},{"down_run_length":"2","spy_runs":321,"coin_flip_runs":320.3,"down_day_share_pct":45.3,"sample_from":"January 4, 2006","sample_to":"September 30, 2026"},{"down_run_length":"3","spy_runs":153,"coin_flip_runs":145,"down_day_share_pct":45.3,"sample_from":"January 4, 2006","sample_to":"September 30, 2026"},{"down_run_length":"4","spy_runs":68,"coin_flip_runs":65.6,"down_day_share_pct":45.3,"sample_from":"January 4, 2006","sample_to":"September 30, 2026"},{"down_run_length":"5","spy_runs":30,"coin_flip_runs":29.7,"down_day_share_pct":45.3,"sample_from":"January 4, 2006","sample_to":"September 30, 2026"},{"down_run_length":"6","spy_runs":10,"coin_flip_runs":13.5,"down_day_share_pct":45.3,"sample_from":"January 4, 2006","sample_to":"September 30, 2026"},{"down_run_length":"7 plus","spy_runs":7,"coin_flip_runs":11.1,"down_day_share_pct":45.3,"sample_from":"January 4, 2006","sample_to":"September 30, 2026"}],"shape":"table","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),\nflags AS (SELECT date, if(ret < 0, 1, 0) AS down FROM rets),\nislands AS (SELECT down, row_number() OVER (ORDER BY date) - sum(down) OVER (ORDER BY date ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) AS island FROM flags),\nruns AS (SELECT island, count() AS run_length FROM islands WHERE down = 1 GROUP BY island),\nsample AS (SELECT count() AS n, avg(down) AS p, concat(monthName(min(date)), ' ', toString(toDayOfMonth(min(date))), ', ', toString(toYear(min(date)))) AS sample_from, concat(monthName(max(date)), ' ', toString(toDayOfMonth(max(date))), ', ', toString(toYear(max(date)))) AS sample_to FROM flags)\nSELECT\n    if(bucket = 7, '7 plus', toString(bucket))                                                                           AS down_run_length,\n    count()                                                                                                              AS spy_runs,\n    round(if(bucket = 7, any(n) * pow(any(p), 7) * (1 - any(p)), any(n) * pow(any(p), bucket) * pow(1 - any(p), 2)), 1)   AS coin_flip_runs,\n    round(100 * any(p), 1)                                                                                               AS down_day_share_pct,\n    any(sample_from)                                                                                                     AS sample_from,\n    any(sample_to)                                                                                                       AS sample_to\nFROM (SELECT least(r.run_length, 7) AS bucket, s.n AS n, s.p AS p, s.sample_from AS sample_from, s.sample_to AS sample_to FROM runs AS r CROSS JOIN sample AS s)\nGROUP BY bucket\nORDER BY bucket","computed_at":"2026-10-01T15:35:45.670442+00:00","elapsed":0.006128921}