STRASMORE/EXPLORE 2,882 QUERIES

gap_frequency

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 9×4read in context →
gap_frequency — 9 rows by 4 columns, computed from US exchange, SIP and OPRA data.
monthnames_measuredpositive_gap_share_pctmedian_gap_pct
2025-1043269.95.2
2025-1132087.89.3
2025-1236933.9-4
2026-0139534.4-5.1
2026-0231959.92.6
2026-0333872.56.7
2026-0435863.73.2
2026-0539638.6-1.9
2026-0635758.82.4
Rows × columns
9 × 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 gap_frequency, derived from the stored result.
ColumnTypeRangeNotes
month text 9 distinct values (2025-10, 2025-11, 2025-12…)
names_measured number 319 to 432
positive_gap_share_pct number 33.9 to 87.8 percent
median_gap_pct number -5.1 to 9.3 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
    split_tickers AS
    (
        SELECT DISTINCT ticker
        FROM global_markets.stocks_splits
        WHERE execution_date >= '2025-10-01'
          AND execution_date <  '2026-08-01'
    ),
    px AS
    (
        SELECT
            ticker                AS symbol,
            date                  AS session,
            max(toFloat64(close)) AS px
        FROM global_markets.stocks_daily_aggs
        WHERE date >= '2025-10-01'
          AND date <  '2026-08-01'
          AND ticker NOT IN (SELECT ticker FROM split_tickers)
          AND ticker NOT IN ('SPCX')
        GROUP BY symbol, session
    ),
    iv_rows AS
    (
        SELECT
            g.symbol  AS symbol,
            g.session AS session,
            g.iv      AS iv
        FROM
        (
            SELECT
                underlying_symbol       AS symbol,
                toDate(date)            AS session,
                toFloat64(strike_price) AS strike,
                implied_volatility      AS iv
            FROM global_markets.options_greeks
            WHERE date >= '2025-10-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.symbol = g.symbol AND p.session = g.session
        WHERE p.px > 10
          AND abs(g.strike / p.px - 1) < 0.05
    ),
    implied AS
    (
        SELECT
            symbol,
            iv_month,
            addMonths(iv_month, 1) AS forward_month,
            implied_vol_pct
        FROM
        (
            SELECT
                symbol,
                toStartOfMonth(session) AS iv_month,
                round(100 * avg(iv), 1) AS implied_vol_pct
            FROM iv_rows
            GROUP BY symbol, iv_month
            HAVING countDistinct(session) >= 15
               AND count() >= 150
        )
    ),
    daily_returns AS
    (
        SELECT
            symbol,
            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
                symbol,
                arraySort(groupArray((session, px))) AS series
            FROM px
            WHERE symbol IN (SELECT symbol FROM implied)
            GROUP BY symbol
        )
    ),
    realized AS
    (
        SELECT
            symbol,
            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 symbol, rv_month
        HAVING count() >= 15
    )
SELECT
    formatDateTime(implied.iv_month, '%Y-%m') AS month,
    count()                                   AS names_measured,
    round(100 * countIf(implied.implied_vol_pct > realized.realized_vol_pct) / count(), 1) AS positive_gap_share_pct,
    round(quantileDeterministic(0.5)(implied.implied_vol_pct - realized.realized_vol_pct,
                                     cityHash64(implied.symbol)), 1) AS median_gap_pct
FROM implied
INNER JOIN realized ON realized.symbol = implied.symbol
                   AND realized.rv_month = implied.forward_month
GROUP BY 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
spy_monthly_trace series 24×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 →