autocorrelation
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 real-returns-vs-random-walks.
| lag | return_autocorr | abs_return_autocorr |
|---|---|---|
| 01 | -0.103 | 0.314 |
| 02 | -0.014 | 0.401 |
| 03 | 0.004 | 0.34 |
| 04 | -0.035 | 0.354 |
| 05 | -0.013 | 0.357 |
| 06 | -0.032 | 0.342 |
| 07 | 0.045 | 0.326 |
| 08 | -0.039 | 0.315 |
| 09 | 0.038 | 0.314 |
| 10 | 0 | 0.304 |
- Rows × columns
- 10 × 3
- Computed
- Completeness
- No missing values
- Source
- US exchange, SIP and OPRA market data
- Licence
- Strasmore terms · free, no signup
What each column holds
| Column | Type | Range | Notes |
|---|---|---|---|
lag |
text | 10 distinct values (01, 02, 03…) | |
return_autocorr |
number | -0.103 to 0.045 | |
abs_return_autocorr |
number | 0.304 to 0.401 |
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, argMax(toFloat64(close), _ingest_time) AS px FROM global_markets.stocks_daily_aggs WHERE ticker = 'SPY' AND date >= '2006-01-01' AND date <= '2026-09-30' GROUP BY date),
rets AS (SELECT date, px / prev_px - 1 AS ret FROM (SELECT date, px, lagInFrame(px) OVER (ORDER BY date ROWS BETWEEN 1 PRECEDING AND CURRENT ROW) AS prev_px FROM daily) WHERE prev_px > 0),
series AS (SELECT arrayMap(x -> tupleElement(x, 2), arraySort(groupArray(tuple(date, ret)))) AS r FROM rets),
lagged AS (SELECT lags.k AS k, arraySlice(s.r, lags.k + 1) AS x, arraySlice(s.r, 1, length(s.r) - lags.k) AS y FROM series AS s CROSS JOIN (SELECT arrayJoin(range(1, 11)) AS k) AS lags),
sums AS
(
SELECT
k,
toFloat64(length(x)) AS n,
arraySum(x) AS sx,
arraySum(y) AS sy,
arraySum(arrayMap((a, b) -> a * b, x, y)) AS sxy,
arraySum(arrayMap(a -> a * a, x)) AS sxx,
arraySum(arrayMap(a -> a * a, y)) AS syy,
arraySum(arrayMap(a -> abs(a), x)) AS sax,
arraySum(arrayMap(a -> abs(a), y)) AS say,
arraySum(arrayMap((a, b) -> abs(a) * abs(b), x, y)) AS saxy
FROM lagged
)
SELECT
leftPad(toString(k), 2, '0') AS lag,
round((n * sxy - sx * sy) / sqrt((n * sxx - sx * sx) * (n * syy - sy * sy)), 3) AS return_autocorr,
round((n * saxy - sax * say) / sqrt((n * sxx - sax * sax) * (n * syy - say * say)), 3) AS abs_return_autocorr
FROM sums
ORDER BY k
Work with this data in your AI assistant
Opens ready to query, with this page's data. Free, no account.