STRASMORE/EXPLORE 2,749 QUERIES

rv_vs_iv

Answered against 22 years of US equities and 12 years of US options data and published with the query that produced it. This result is stored as of 2026-09-28, from what-is-market-volatility.

as of ranking 4×4read in context →
rv_vs_iv — 4 rows by 4 columns, computed from US exchange, SIP and OPRA data.
tickerrv_30d_pctiv_30_45d_pctgap_pct
NVDA38.835.1-3.7
AAPL20.524.74.2
KO15.218.33.1
SPY9.813.33.5
Rows × columns
4 × 4
Computed
Completeness
No missing values
Source
US exchange, SIP and OPRA market data
Licence
Strasmore terms · free, no signup
Formats
JSON · CSV · the SQL below

What each column holds

Column definitions for rv_vs_iv, derived from the stored result.
ColumnTypeRangeNotes
ticker text 4 distinct values (AAPL, KO, NVDA…)
rv_30d_pct number 9.8 to 38.8 percent
iv_30_45d_pct number 13.3 to 35.1 percent
gap_pct number -3.7 to 4.2 percent

Computed from Strasmore's warehouse of US exchange, SIP and OPRA market data. Equity prices are delayed; options greeks and implied volatility are end-of-day. This result is stored, not recomputed on load — it is exactly the numbers that were returned on , and the query below is what returned them.

Run it yourself

This is the exact query behind the result above. Change a ticker, a date or a column and run it against the warehouse — no account, no key. The no-signup tier is smaller than the one this page was computed on; a query that reaches past it comes back saying which plan runs it.

WITH bars AS
(
    SELECT
        ticker,
        date,
        any(toFloat64(close)) AS c
    FROM global_markets.stocks_daily_aggs
    WHERE ticker IN ('SPY', 'AAPL', 'NVDA', 'KO')
      AND date >= today() - 90
      AND date <  today()
    GROUP BY ticker, date
),
rets AS
(
    SELECT
        ticker,
        date,
        log(c / lagInFrame(c) OVER (PARTITION BY ticker ORDER BY date)) AS r
    FROM bars
),
ranked AS
(
    SELECT
        ticker,
        r,
        row_number() OVER (PARTITION BY ticker ORDER BY date DESC) AS sessions_back
    FROM rets
    WHERE isFinite(r)
),
realized AS
(
    SELECT
        ticker,
        round(stddevSampIf(r, sessions_back <= 30) * sqrt(252) * 100, 1) AS rv_30d_pct
    FROM ranked
    GROUP BY ticker
    HAVING countIf(sessions_back <= 30) >= 20
),
implied AS
(
    SELECT
        underlying_symbol                       AS ticker,
        round(avg(implied_volatility) * 100, 1) AS iv_30_45d_pct,
        count()                                 AS sample_count
    FROM global_markets.options_greeks
    WHERE underlying_symbol IN ('SPY', 'AAPL', 'NVDA', 'KO')
      AND date >= today() - 45
      AND iv_converged = 1
      AND volume > 0
      AND days_to_expiry BETWEEN 20 AND 45
      AND underlying_close > 0
      AND abs(toFloat64(strike_price) / toFloat64(underlying_close) - 1) < 0.05
    GROUP BY ticker
    HAVING sample_count >= 25
)
SELECT
    rl.ticker                                   AS ticker,
    rl.rv_30d_pct                               AS rv_30d_pct,
    im.iv_30_45d_pct                            AS iv_30_45d_pct,
    round(im.iv_30_45d_pct - rl.rv_30d_pct, 1)  AS gap_pct
FROM realized AS rl
INNER JOIN implied AS im ON im.ticker = rl.ticker
ORDER BY iv_30_45d_pct DESC
⌘/Ctrl + Enter

Work with this data in your AI assistant

Opens ready to query, with this page's data. Free, no account.