STRASMORE/EXPLORE 2,882 QUERIES

spy_monthly_trace

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-10-01, from stocks-with-the-biggest-iv-rv-gap.

as of series 24×4read in context →
spy_monthly_trace — 24 rows by 4 columns, computed from US exchange, SIP and OPRA data.
monthimplied_vol_pctrealized_vol_pctgap_pct
2024-0712.919.2-6.3
2024-081513.81.2
2024-0913.611.22.4
2024-1016.411.84.6
2024-111314.1-1.1
2024-1211.613.9-2.3
2025-0113.913.20.7
2025-0212.720.7-8
2025-0317.751.9-34.2
2025-0426.416.89.6
2025-0517.410.27.2
2025-0614.76.68.1
2025-0714.4122.4
2025-0812.67.15.5
2025-0911.313.8-2.5
2025-1015.315.4-0.1
2025-1115.58.47.1
2025-1212.410.32.1
2026-0113.413.40
2026-0215.318.2-2.9
2026-0319.411.67.8
2026-0415.69.75.9
2026-0514.717.7-3
2026-0614.712.12.6
Rows × columns
24 × 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 spy_monthly_trace, derived from the stored result.
ColumnTypeRangeNotes
month text 24 distinct values (2024-07, 2024-08, 2024-09…)
implied_vol_pct number 11.3 to 26.4 percent
realized_vol_pct number 6.6 to 51.9 percent
gap_pct number -34.2 to 9.6 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
    px AS
    (
        SELECT
            date                  AS session,
            max(toFloat64(close)) AS px
        FROM global_markets.stocks_daily_aggs
        WHERE ticker = 'SPY'
          AND date >= '2024-07-01'
          AND date <  '2026-08-01'
        GROUP BY session
    ),
    iv_rows AS
    (
        SELECT
            g.session AS session,
            g.iv      AS iv
        FROM
        (
            SELECT
                toDate(date)            AS session,
                toFloat64(strike_price) AS strike,
                implied_volatility      AS iv
            FROM global_markets.options_greeks
            WHERE underlying_symbol = 'SPY'
              AND date >= '2024-07-01'
              AND date <  '2026-07-01'
              AND lower(toString(option_type)) IN ('c', 'call')
              AND days_to_expiry BETWEEN 20 AND 45
              AND implied_volatility > 0
        ) AS g
        INNER JOIN px AS p ON p.session = g.session
        WHERE abs(g.strike / p.px - 1) < 0.05
    ),
    daily_returns AS
    (
        SELECT
            arrayJoin(arrayMap((a, b) -> (tupleElement(a, 1), log(tupleElement(a, 2) / tupleElement(b, 2))),
                               arraySlice(series, 2),
                               arraySlice(series, 1, length(series) - 1))) AS ret
        FROM
        (
            SELECT arraySort(groupArray((session, px))) AS series
            FROM px
        )
    ),
    realized AS
    (
        SELECT
            toStartOfMonth(tupleElement(ret, 1))                         AS rv_month,
            round(100 * sqrt(252) * stddevSamp(tupleElement(ret, 2)), 1) AS realized_vol_pct
        FROM daily_returns
        GROUP BY rv_month
        HAVING count() >= 15
    ),
    implied AS
    (
        SELECT
            iv_month,
            addMonths(iv_month, 1) AS forward_month,
            implied_vol_pct
        FROM
        (
            SELECT
                toStartOfMonth(session) AS iv_month,
                round(100 * avg(iv), 1) AS implied_vol_pct
            FROM iv_rows
            GROUP BY iv_month
            HAVING countDistinct(session) >= 15
        )
    )
SELECT
    formatDateTime(implied.iv_month, '%Y-%m')                     AS month,
    implied.implied_vol_pct                                       AS implied_vol_pct,
    realized.realized_vol_pct                                     AS realized_vol_pct,
    round(implied.implied_vol_pct - realized.realized_vol_pct, 1) AS gap_pct
FROM implied
INNER JOIN realized ON realized.rv_month = implied.forward_month
ORDER BY month
⌘/Ctrl + Enter

Work with this data in your AI assistant

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

More from this analysisstocks-with-the-biggest-iv-rv-gap
gap_frequency series 9×4 → gap_leaderboard ranking 12×4 → worst_gaps ranking 10×4 → The 2s10s spread by month, full history series 604×5 → One SPY $600 LEAPS call's price over two years (expired Jan 16 2026) series 470×2 → The 5s30s spread month by month, with both legs series 241×4 → See all 2,882 queries →