{"slug":"expected-move-from-implied-volatility","qid":"implied_vs_realized","label":"Implied vs realized: median 30-day expected move and what six stocks did next","post_title":"Expected Move From Implied Volatility","post_url":"/blog/expected-move-from-implied-volatility#q-implied_vs_realized","columns":["ticker","windows_tested","implied_move_pct","realized_move_pct","realized_over_implied_pct"],"rows":[{"ticker":"NVDA","windows_tested":103,"implied_move_pct":13.3,"realized_move_pct":6.77,"realized_over_implied_pct":23.3},{"ticker":"AAPL","windows_tested":103,"implied_move_pct":7.51,"realized_move_pct":5.71,"realized_over_implied_pct":35.9},{"ticker":"MSFT","windows_tested":103,"implied_move_pct":7.19,"realized_move_pct":4.7,"realized_over_implied_pct":27.2},{"ticker":"XOM","windows_tested":103,"implied_move_pct":6.58,"realized_move_pct":4.14,"realized_over_implied_pct":24.3},{"ticker":"KO","windows_tested":103,"implied_move_pct":5.17,"realized_move_pct":2.69,"realized_over_implied_pct":29.1},{"ticker":"SPY","windows_tested":103,"implied_move_pct":4.37,"realized_move_pct":2.68,"realized_over_implied_pct":24.3}],"shape":"table","sql":"WITH obs AS (\n    SELECT underlying_symbol AS ticker,\n           date AS obs_date,\n           avg(toFloat64(implied_volatility)) AS iv,\n           avg(toFloat64(underlying_close)) AS spot\n    FROM global_markets.options_greeks\n    WHERE underlying_symbol IN ('NVDA', 'AAPL', 'MSFT', 'XOM', 'SPY', 'KO')\n      AND date BETWEEN toDate('2024-06-12') AND toDate('2026-06-17')\n      AND toDayOfWeek(date) = 3\n      AND iv_converged = 1\n      AND volume > 0\n      AND days_to_expiry BETWEEN 25 AND 40\n      AND abs(toFloat64(strike_price) / toFloat64(underlying_close) - 1) < 0.05\n    GROUP BY ticker, obs_date\n    HAVING count() >= 4 AND avg(toFloat64(implied_volatility)) > 0.01\n),\npx AS (\n    SELECT underlying_symbol AS ticker,\n           date AS px_date,\n           avg(toFloat64(underlying_close)) AS close_px\n    FROM global_markets.options_greeks\n    WHERE underlying_symbol IN ('NVDA', 'AAPL', 'MSFT', 'XOM', 'SPY', 'KO')\n      AND date BETWEEN toDate('2024-06-12') AND toDate('2026-07-25')\n      AND days_to_expiry BETWEEN 5 AND 60\n      AND abs(toFloat64(strike_price) / toFloat64(underlying_close) - 1) < 0.02\n    GROUP BY ticker, px_date\n),\nmoves AS (\n    SELECT obs.ticker AS ticker,\n           obs.obs_date AS obs_date,\n           any(obs.iv) AS iv,\n           any(obs.spot) AS spot,\n           argMin(px.close_px, px.px_date) AS end_px,\n           min(dateDiff('day', obs.obs_date, px.px_date)) AS elapsed_days\n    FROM obs\n    INNER JOIN px ON obs.ticker = px.ticker\n    WHERE px.px_date >= addDays(obs.obs_date, 30)\n      AND px.px_date <= addDays(obs.obs_date, 36)\n    GROUP BY ticker, obs_date\n)\nSELECT ticker,\n       count() AS windows_tested,\n       round(quantileDeterministic(0.5)(100 * iv * sqrt(elapsed_days / 365), cityHash64(obs_date)), 2) AS implied_move_pct,\n       round(quantileDeterministic(0.5)(100 * abs(end_px / spot - 1), cityHash64(obs_date)), 2) AS realized_move_pct,\n       round(100 * countIf(abs(end_px / spot - 1) > iv * sqrt(elapsed_days / 365)) / count(), 1) AS realized_over_implied_pct\nFROM moves\nGROUP BY ticker\nORDER BY implied_move_pct DESC","computed_at":"2026-08-22T04:05:43.843416+00:00","elapsed":6.227693715}