{"slug":"scoring-forecasts-with-the-brier-score","qid":"calibration","label":"SPY option deltas against how often those contracts finished in the money","post_title":"Brier Score: How to Grade a Forecast","post_url":"/blog/scoring-forecasts-with-the-brier-score#q-calibration","columns":["stated_bucket","stated_pct","finished_itm_pct","sample_size"],"rows":[{"stated_bucket":"0 to 10%","stated_pct":5.2,"finished_itm_pct":3.7,"sample_size":17114},{"stated_bucket":"10 to 20%","stated_pct":14.7,"finished_itm_pct":10.7,"sample_size":11108},{"stated_bucket":"20 to 30%","stated_pct":24.8,"finished_itm_pct":20.9,"sample_size":8628},{"stated_bucket":"30 to 40%","stated_pct":34.9,"finished_itm_pct":31.6,"sample_size":7359},{"stated_bucket":"40 to 50%","stated_pct":45,"finished_itm_pct":42.8,"sample_size":6805},{"stated_bucket":"50 to 60%","stated_pct":55,"finished_itm_pct":57.2,"sample_size":6659},{"stated_bucket":"60 to 70%","stated_pct":65,"finished_itm_pct":69.9,"sample_size":6558},{"stated_bucket":"70 to 80%","stated_pct":74.9,"finished_itm_pct":80.8,"sample_size":6110},{"stated_bucket":"80 to 90%","stated_pct":84.8,"finished_itm_pct":90.5,"sample_size":5481},{"stated_bucket":"90 to 100%","stated_pct":94,"finished_itm_pct":96.5,"sample_size":3914}],"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        toUInt8(floor(abs(toFloat64(g.delta)) * 10))    AS bucket,\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 28 AND 35\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    concat(toString(bucket * 10), ' to ', toString(bucket * 10 + 10), '%') AS stated_bucket,\n    round(avg(stated) * 100, 1)       AS stated_pct,\n    round(avg(finished_itm) * 100, 1) AS finished_itm_pct,\n    count()                           AS sample_size\nFROM scored\nGROUP BY bucket\nORDER BY bucket","computed_at":"2026-08-13T16:37:38.418674+00:00","elapsed":0.004764428}