{"slug":"is-30-percent-iv-high","qid":"iv_distribution","label":"Where a 30% reading sits in each ticker's own two-year distribution","post_title":"Is 30% IV High? It Depends on the Ticker","post_url":"/blog/is-30-percent-iv-high#q-iv_distribution","columns":["symbol","sample_size","p10_iv_pct","median_iv_pct","p90_iv_pct","pct_of_days_below_30"],"rows":[{"symbol":"SPY","sample_size":500,"p10_iv_pct":13,"median_iv_pct":15.3,"p90_iv_pct":20.3,"pct_of_days_below_30":99},{"symbol":"KO","sample_size":500,"p10_iv_pct":15.4,"median_iv_pct":18.3,"p90_iv_pct":21.8,"pct_of_days_below_30":99.6},{"symbol":"MSFT","sample_size":500,"p10_iv_pct":19.2,"median_iv_pct":25.1,"p90_iv_pct":36.6,"pct_of_days_below_30":77.2},{"symbol":"AAPL","sample_size":500,"p10_iv_pct":21.1,"median_iv_pct":26.3,"p90_iv_pct":30.8,"pct_of_days_below_30":87},{"symbol":"NVDA","sample_size":500,"p10_iv_pct":35.7,"median_iv_pct":44.4,"p90_iv_pct":59,"pct_of_days_below_30":0},{"symbol":"TSLA","sample_size":500,"p10_iv_pct":44.6,"median_iv_pct":53.3,"p90_iv_pct":69.5,"pct_of_days_below_30":0},{"symbol":"COIN","sample_size":500,"p10_iv_pct":55.4,"median_iv_pct":69.7,"p90_iv_pct":81.4,"pct_of_days_below_30":0},{"symbol":"MSTR","sample_size":500,"p10_iv_pct":53.8,"median_iv_pct":75.7,"p90_iv_pct":104.6,"pct_of_days_below_30":0}],"shape":"table","sql":"WITH atm AS (\n    SELECT underlying_symbol AS symbol,\n           date,\n           avg(implied_volatility) * 100 AS iv_pct\n    FROM global_markets.options_greeks\n    WHERE underlying_symbol IN ('SPY', 'KO', 'AAPL', 'MSFT', 'NVDA', 'TSLA', 'COIN', 'MSTR')\n      AND date >= toDate('2024-08-01')\n      AND date <= toDate('2026-07-31')\n      AND iv_converged = 1\n      AND volume > 0\n      AND underlying_close > 0\n      AND days_to_expiry BETWEEN 20 AND 45\n      AND abs(toFloat64(strike_price) / toFloat64(underlying_close) - 1) < 0.05\n    GROUP BY symbol, date\n)\nSELECT symbol,\n       count() AS sample_size,\n       round(quantileDeterministic(0.1)(iv_pct, cityHash64(toString(date))), 1) AS p10_iv_pct,\n       round(quantileDeterministic(0.5)(iv_pct, cityHash64(toString(date))), 1) AS median_iv_pct,\n       round(quantileDeterministic(0.9)(iv_pct, cityHash64(toString(date))), 1) AS p90_iv_pct,\n       round(100 * countIf(iv_pct < 30) / count(), 1) AS pct_of_days_below_30\nFROM atm\nGROUP BY symbol\nHAVING count() >= 100\nORDER BY median_iv_pct","computed_at":"2026-08-02T10:03:20.044014+00:00","elapsed":0.003576556}