{"slug":"the-volatility-risk-premium","qid":"vrp_by_moneyness","label":"The 21 session premium across strikes, puts and calls, 20 to 45 days to expiry","post_title":"The Volatility Risk Premium, Measured","post_url":"/blog/the-volatility-risk-premium#q-vrp_by_moneyness","columns":["moneyness","put_premium_pct","call_premium_pct"],"rows":[{"moneyness":"0.85-0.90","put_premium_pct":12.85,"call_premium_pct":14.6},{"moneyness":"0.90-0.95","put_premium_pct":7.77,"call_premium_pct":6.91},{"moneyness":"0.95-0.975","put_premium_pct":4.48,"call_premium_pct":3.4},{"moneyness":"0.975-1.00","put_premium_pct":2.36,"call_premium_pct":1.42},{"moneyness":"1.00-1.025","put_premium_pct":0.96,"call_premium_pct":-0.55},{"moneyness":"1.025-1.05","put_premium_pct":1.29,"call_premium_pct":-1.9},{"moneyness":"1.05-1.10","put_premium_pct":5.65,"call_premium_pct":-2.15}],"shape":"ranking","sql":"WITH\ncloses AS\n(\n    SELECT\n        date,\n        toFloat64(any(close)) AS px\n    FROM global_markets.stocks_daily_aggs\n    WHERE ticker = 'SPY'\n      AND date >= '2021-06-01'\n    GROUP BY date\n),\ndaily_returns AS\n(\n    SELECT\n        date,\n        pow(log(px / lagInFrame(px) OVER (ORDER BY date ROWS BETWEEN 1 PRECEDING AND CURRENT ROW)), 2) AS r2\n    FROM closes\n),\nforward_rv AS\n(\n    SELECT\n        date,\n        100 * sqrt(252 * avg(r2) OVER (ORDER BY date ROWS BETWEEN 1 FOLLOWING AND 21 FOLLOWING)) AS rv_pct,\n        count(r2) OVER (ORDER BY date ROWS BETWEEN 1 FOLLOWING AND 21 FOLLOWING)                 AS sessions_ahead\n    FROM daily_returns\n    WHERE isFinite(r2)\n),\ncontracts AS\n(\n    SELECT\n        date,\n        delta,\n        toFloat64(implied_volatility)                         AS iv,\n        toFloat64(strike_price) / toFloat64(underlying_close) AS moneyness_ratio\n    FROM global_markets.options_greeks\n    WHERE underlying_symbol = 'SPY'\n      AND iv_converged = 1\n      AND volume > 0\n      AND days_to_expiry BETWEEN 20 AND 45\n      AND date >= '2021-08-01'\n),\nby_day AS\n(\n    SELECT\n        c.date AS date,\n        multiIf(c.moneyness_ratio < 0.90,  '0.85-0.90',\n                c.moneyness_ratio < 0.95,  '0.90-0.95',\n                c.moneyness_ratio < 0.975, '0.95-0.975',\n                c.moneyness_ratio < 1.00,  '0.975-1.00',\n                c.moneyness_ratio < 1.025, '1.00-1.025',\n                c.moneyness_ratio < 1.05,  '1.025-1.05',\n                                           '1.05-1.10') AS moneyness,\n        avgIf(100 * c.iv, c.delta < 0)                   AS put_iv_pct,\n        avgIf(100 * c.iv, c.delta > 0)                   AS call_iv_pct,\n        any(f.rv_pct)                                    AS rv_pct\n    FROM contracts AS c\n    INNER JOIN forward_rv AS f ON f.date = c.date\n    WHERE c.moneyness_ratio BETWEEN 0.85 AND 1.10\n      AND f.sessions_ahead = 21\n    GROUP BY date, moneyness\n    HAVING countIf(c.delta < 0) > 0\n       AND countIf(c.delta > 0) > 0\n)\nSELECT\n    moneyness,\n    round(avg(put_iv_pct - rv_pct), 2)  AS put_premium_pct,\n    round(avg(call_iv_pct - rv_pct), 2) AS call_premium_pct\nFROM by_day\nGROUP BY moneyness\nORDER BY moneyness","computed_at":"2026-10-16T15:53:33.268821+00:00","elapsed":0.006314703}