{"slug":"event-contract-prices-as-probabilities","qid":"calibration","label":"Implied probability vs what happened: SPY calls 30 days from expiry, 2022 through June 2026","post_title":"Event Contract Prices as Probabilities","post_url":"/blog/event-contract-prices-as-probabilities#q-calibration","columns":["implied_bucket","contracts","implied_prob_pct","finished_above_pct"],"rows":[{"implied_bucket":"2-10%","contracts":4276,"implied_prob_pct":4.7,"finished_above_pct":4.9},{"implied_bucket":"10-20%","contracts":2262,"implied_prob_pct":14.8,"finished_above_pct":19.1},{"implied_bucket":"20-30%","contracts":1874,"implied_prob_pct":25,"finished_above_pct":32.3},{"implied_bucket":"30-40%","contracts":1832,"implied_prob_pct":35,"finished_above_pct":42.8},{"implied_bucket":"40-50%","contracts":1933,"implied_prob_pct":45,"finished_above_pct":52.6},{"implied_bucket":"50-60%","contracts":2213,"implied_prob_pct":55.1,"finished_above_pct":60.9},{"implied_bucket":"60-70%","contracts":2581,"implied_prob_pct":65.2,"finished_above_pct":70.6},{"implied_bucket":"70-80%","contracts":3071,"implied_prob_pct":75.2,"finished_above_pct":79.2},{"implied_bucket":"80-90%","contracts":3858,"implied_prob_pct":85.3,"finished_above_pct":91.1},{"implied_bucket":"90-98%","contracts":4806,"implied_prob_pct":94.3,"finished_above_pct":97.8}],"shape":"ranking","sql":"WITH px AS (\n    SELECT toDate(toTimeZone(window_start, 'America/New_York')) AS session,\n           argMax(toFloat64(close), window_start) AS close_px\n    FROM global_markets.delayed_stocks_minute_aggs\n    WHERE ticker = 'SPY'\n      AND toDate(toTimeZone(window_start, 'America/New_York')) >= toDate('2022-01-01')\n      AND toDate(toTimeZone(window_start, 'America/New_York')) <= toDate('2026-06-30')\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 session\n),\nsnap AS (\n    SELECT ticker AS contract,\n           argMin(delta, abs(days_to_expiry - 30)) AS implied_prob,\n           toFloat64(any(strike_price)) AS strike,\n           any(expiration_date) AS expiry\n    FROM global_markets.options_greeks\n    WHERE underlying_symbol = 'SPY'\n      AND date >= toDate('2022-01-01')\n      AND expiration_date <= toDate('2026-06-30')\n      AND days_to_expiry BETWEEN 25 AND 35\n      AND iv_converged = 1\n      AND volume > 0\n      AND delta > 0.02\n      AND delta < 0.98\n    GROUP BY contract\n)\nSELECT multiIf(implied_prob < 0.10, '2-10%',\n               implied_prob < 0.20, '10-20%',\n               implied_prob < 0.30, '20-30%',\n               implied_prob < 0.40, '30-40%',\n               implied_prob < 0.50, '40-50%',\n               implied_prob < 0.60, '50-60%',\n               implied_prob < 0.70, '60-70%',\n               implied_prob < 0.80, '70-80%',\n               implied_prob < 0.90, '80-90%',\n                                    '90-98%') AS implied_bucket,\n       count() AS contracts,\n       round(100 * avg(implied_prob), 1) AS implied_prob_pct,\n       round(100 * avg(close_px > strike), 1) AS finished_above_pct\nFROM snap\nINNER JOIN px ON px.session = snap.expiry\nGROUP BY implied_bucket\nORDER BY implied_prob_pct","computed_at":"2026-08-03T10:23:47.882254+00:00","elapsed":0.004364457}