STRASMORE/EXPLORE 2,830 QUERIES

realised_vol_by_month

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-30, from buying-puts-vs-buying-calls.

as of ranking 4×3read in context →
realised_vol_by_month — 4 rows by 3 columns, computed from US exchange, SIP and OPRA data.
month_return_bandavg_realised_vol_pctmonths
fell more than 5%31.6526
fell 0 to 5%16.7160
rose 0 to 5%11.36126
rose more than 5%16.1436
Rows × columns
4 × 3
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 realised_vol_by_month, derived from the stored result.
ColumnTypeRangeNotes
month_return_band text 4 distinct values
avg_realised_vol_pct number 11.36 to 31.65 percent
months number 26 to 126

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
daily AS
(
    SELECT
        date                                                                                      AS d,
        toFloat64(close) / lagInFrame(toFloat64(close)) OVER (ORDER BY date ASC ROWS BETWEEN 1 PRECEDING AND CURRENT ROW) - 1 AS ret
    FROM global_markets.stocks_daily_aggs
    WHERE ticker = 'SPY'
      AND date >= '2006-01-01'
      AND date <  '2026-09-01'
),
months AS
(
    SELECT
        toStartOfMonth(d)                            AS month,
        (exp(sum(log(1 + ret))) - 1) * 100           AS month_return_pct,
        stddevPop(ret) * sqrt(252) * 100             AS realised_vol_pct,
        count()                                      AS sessions
    FROM daily
    WHERE abs(ret) < 0.5
    GROUP BY month
    HAVING sessions >= 15
)
SELECT
    multiIf(month_return_pct < -5, 'fell more than 5%',
            month_return_pct <  0, 'fell 0 to 5%',
            month_return_pct <  5, 'rose 0 to 5%',
                                   'rose more than 5%') AS month_return_band,
    round(avg(realised_vol_pct), 2)                     AS avg_realised_vol_pct,
    count()                                             AS months
FROM months
GROUP BY month_return_band
ORDER BY min(month_return_pct) ASC
⌘/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 analysisbuying-puts-vs-buying-calls
skew_curve ranking 6×4 → parity_ladder ranking 6×4 → breakeven_by_dte ranking 4×4 → skew_persistence series 24×4 → Top 25 weekly-options underlyings by distinct contracts traded, with expiration weekdays ranking 25×4 → Annualized volatility vs total return, 25 large caps, calmest to wildest (~2 years) ranking 25×3 → See all 2,830 queries →