{"slug":"scoring-forecasts-with-the-brier-score","qid":"horizon","label":"The market's Brier score across expiry horizons, SPY","post_title":"Brier Score: How to Grade a Forecast","post_url":"/blog/scoring-forecasts-with-the-brier-score#q-horizon","columns":["horizon","market_brier","coin_flip_brier","sample_size"],"rows":[{"horizon":"1 to 7 days","market_brier":0.1084,"coin_flip_brier":0.25,"sample_size":151673},{"horizon":"8 to 14 days","market_brier":0.1269,"coin_flip_brier":0.25,"sample_size":160991},{"horizon":"15 to 30 days","market_brier":0.1264,"coin_flip_brier":0.25,"sample_size":152490},{"horizon":"31 to 60 days","market_brier":0.1471,"coin_flip_brier":0.25,"sample_size":201080},{"horizon":"61 to 120 days","market_brier":0.1337,"coin_flip_brier":0.25,"sample_size":182387},{"horizon":"121 to 250 days","market_brier":0.1218,"coin_flip_brier":0.25,"sample_size":157962}],"shape":"ranking","sql":"WITH settle AS\n(\n    SELECT\n        date                             AS settle_date,\n        any(toFloat64(underlying_close)) AS settle_px\n    FROM global_markets.options_greeks\n    WHERE underlying_symbol = 'SPY'\n      AND date >= '2025-01-01'\n      AND date <  '2026-08-01'\n    GROUP BY date\n),\nscored AS\n(\n    SELECT\n        multiIf(g.days_to_expiry <=   7, 1,\n                g.days_to_expiry <=  14, 2,\n                g.days_to_expiry <=  30, 3,\n                g.days_to_expiry <=  60, 4,\n                g.days_to_expiry <= 120, 5,\n                6)                                      AS horizon_rank,\n        abs(toFloat64(g.delta))                         AS stated,\n        startsWith(lower(toString(g.option_type)), 'c') AS is_call,\n        if(is_call,\n           s.settle_px > toFloat64(g.strike_price),\n           s.settle_px < toFloat64(g.strike_price))     AS finished_itm\n    FROM global_markets.options_greeks AS g\n    INNER JOIN settle AS s ON s.settle_date = g.expiration_date\n    WHERE g.underlying_symbol = 'SPY'\n      AND g.date >= '2025-01-01'\n      AND g.date <  '2026-06-01'\n      AND g.expiration_date <= '2026-07-31'\n      AND g.days_to_expiry BETWEEN 1 AND 250\n      AND g.iv_converged = 1\n      AND g.volume > 0\n      AND abs(g.delta) > 0.02\n      AND abs(g.delta) < 0.98\n)\nSELECT\n    multiIf(horizon_rank = 1, '1 to 7 days',\n            horizon_rank = 2, '8 to 14 days',\n            horizon_rank = 3, '15 to 30 days',\n            horizon_rank = 4, '31 to 60 days',\n            horizon_rank = 5, '61 to 120 days',\n            '121 to 250 days')                                       AS horizon,\n    round(avg((stated - finished_itm) * (stated - finished_itm)), 4) AS market_brier,\n    round(avg((0.5 - finished_itm) * (0.5 - finished_itm)), 4)       AS coin_flip_brier,\n    count()                                                          AS sample_size\nFROM scored\nGROUP BY horizon_rank\nORDER BY horizon_rank","computed_at":"2026-08-13T16:37:38.609006+00:00","elapsed":0.004965386}