STRASMORE/EXPLORE 2,170 QUERIES

How far the mean and volatility estimates scatter by sample length

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-08-16, from When Equal Weight Beats Optimization.

as of ranking 5×4read in context →
How far the mean and volatility estimates scatter by sample length — 5 rows by 4 columns, computed from US exchange, SIP and OPRA data.
sample_lengthmean_estimate_spread_pctvol_estimate_spread_pctwindow_count
21 sessions53.710.9239
63 sessions27.310.379
126 sessions19.69.739
252 sessions14.78.619
504 sessions10.66.69
Rows × columns
5 × 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 How far the mean and volatility estimates scatter by sample length, derived from the stored result.
ColumnTypeRangeNotes
sample_length text 5 distinct values (126 sessions, 21 sessions, 252 sessions…)
mean_estimate_spread_pct number 10.6 to 53.7 percent
vol_estimate_spread_pct number 6.6 to 10.9 percent
window_count number 9 to 239 count

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.

the exact SQL behind every number
WITH prices AS
(
    SELECT
        date,
        toFloat64(max(close)) AS c
    FROM global_markets.stocks_daily_aggs
    WHERE ticker = 'SPY'
      AND date >= '2005-01-01'
      AND date <  '2025-01-01'
    GROUP BY date
),
rets AS
(
    SELECT
        date,
        c / lagInFrame(c, 1) OVER (ORDER BY date ASC ROWS BETWEEN 1 PRECEDING AND CURRENT ROW) - 1 AS ret
    FROM prices
),
numbered AS
(
    SELECT
        ret,
        row_number() OVER (ORDER BY date ASC) AS i
    FROM rets
    WHERE isFinite(ret)
),
sweep AS
(
    SELECT
        arrayJoin([21, 63, 126, 252, 504]) AS n,
        i,
        ret
    FROM numbered
),
blocks AS
(
    SELECT
        n,
        intDiv(i - 1, n)                 AS blk,
        avg(ret) * 252 * 100             AS mean_pct,
        stddevPop(ret) * sqrt(252) * 100 AS vol_pct
    FROM sweep
    GROUP BY n, blk
    HAVING count() = n
)
SELECT
    concat(toString(n), ' sessions') AS sample_length,
    round(stddevPop(mean_pct), 1)    AS mean_estimate_spread_pct,
    round(stddevPop(vol_pct), 1)     AS vol_estimate_spread_pct,
    count()                          AS window_count
FROM blocks
GROUP BY n
ORDER BY n ASC

Run your own version of this

The same 22 years of US equities and 12 years of options data are queryable in SQL or plain English. A free account runs 100 queries a day and takes no card.

More from this analysisWhen Equal Weight Beats Optimization
Ten years of yearly estimates: the mean moves far more than the volatility ranking 6×3 A rolling one year mean return, the number an optimizer would be fed series 96×3 When market headlines publish, by New York clock hour ranking 24×2 When headlines actually land: article counts by ET clock hour, July 2026 ranking 24×4 Growth of one dollar: holding all year vs holding only November through April ranking 21×3 S&P 500 tracker: May to October vs November to April, season by season ranking 21×3 See all 2,170 queries →