Quant Terminal
D1-01D1·intermediate·~21 min

Autocorrelation — does yesterday tell you anything about today?

time-seriesautocorrelationacfvolatility-clusteringljung-box

▸ Pretest — guess, even if you don't know

Across 20 years of S&P 500 daily returns, what does yesterday's return tell you about today's return?

A time series is not a bag of iid draws

Everything in the statistics track quietly assumed your sample was iid — short for "independent and identically distributed": every draw comes from the same distribution, no draw affects any other, and shuffling the data changes nothing. A time series x1,x2,,xNx_1, x_2, \ldots, x_N — read "x one, x two, up to x N" — is data where the order is information. The subscript here is a time index: xtx_t means "the value at time tt." On daily data, x5x_5 is day 5's value, and xt1x_{t-1} is the value one day before xtx_t. The trading question this raises: does what happened at time tkt-k — that is, kk steps back — tell me anything about time tt? If yes, there is structure to forecast. If no, past prices are noise and half the strategies on the internet are astrology.

Autocorrelation — literally "self-correlation" — is that question turned into a number: the correlation you learned in A2-08, applied to a series and a time-shifted copy of itself.

Lag-k autocorrelation and the ACF

A lag — how many steps back in time you look — is the one new piece of vocabulary here. Lag 1 compares each day with the day before it; lag 5 compares each day with the value five days back. The lag-kk autocorrelation is the correlation between the series and itself kk steps earlier:

ρk=Corr(xt,xtk)\rho_k = \text{Corr}(x_t, \, x_{t-k})

In words: rho-sub-k equals the correlation between the value at time tt and the value kk steps earlier. (ρ\rho is the Greek letter rho, the standard symbol for autocorrelation.) For k=1k = 1 this asks: how correlated is each day with the day before it?

The sample version pairs each observation with the one kk steps before it — element xkx_k with x0x_0, element xk+1x_{k+1} with x1x_1, and so on. In numpy that is just correlating two slices:

def autocorr(x, k):
    return np.corrcoef(x[:-k], x[k:])[0, 1]

Plot ρk\rho_k for k=1,2,3,k = 1, 2, 3, \ldots — one number per lag — and you have the autocorrelation function (ACF), the standard first diagnostic for any series. (One technical footnote: textbook ACF estimators use the full-series mean and variance for both slices, while corrcoef computes them per slice. When NkN \gg k — read "N much greater than k", i.e. far more observations than lags — the difference is negligible, but expect tiny mismatches against statsmodels.tsa.stattools.acf.)

Fact 1: returns are nearly uncorrelated

Compute the ACF of daily equity returns and you get spikes scattered around zero, mostly inside the noise band we build below. This is not a coincidence — it is competition. Suppose lag-1 autocorrelation were reliably +0.2+0.2. Then "buy the day after an up day" would print money. Everyone would do it, and the buying pressure would move today's price until the pattern vanished. Whatever linear predictability exists in liquid markets is tiny, unstable, and usually smaller than trading costs (D4-01's cost table). This is why naive "predict tomorrow's return from yesterday's" models fail: the signal they need is roughly zero by construction of a competitive market.

Fact 2: the size of returns is strongly autocorrelated

Now take the same return series — write rtr_t, "r sub t", for the return on day tt — and compute the ACF of rt|r_t| (the absolute value: the size of the move, sign stripped off) or rt2r_t^2 (the squared return, which also kills the sign). The picture flips: strong positive autocorrelation, decaying slowly over weeks to months. This is volatility clustering — the same regime behavior you met in A2-02. Turbulent days cluster together, calm days cluster together, even though the direction of each day stays unpredictable. Cont (2001) lists this pair of facts — no linear autocorrelation in returns, slow-decaying autocorrelation in their magnitudes — among the canonical "stylized facts" (well-documented empirical regularities) of asset returns.

The trading consequence: you mostly cannot forecast tomorrow's return, but you can forecast tomorrow's volatility. That asymmetry funds entire businesses — volatility forecasting models, options pricing, and risk-based position sizing all live on Fact 2.

Is that spike real? The 1-over-root-N rule

Sample autocorrelations of finite noise are never exactly zero. Suppose the data really were iid — this "no structure at all" assumption is the null hypothesis, the boring baseline you try to disprove. Even then, the sample estimate ρ^k\hat\rho_k (read "rho-hat-k" — the hat means "estimated from data") lands near zero, not on it. How near? Approximately Normal with mean 0 and standard error 1/N1/\sqrt{N} — "one over the square root of N", where NN is the number of observations. So the eyeball rule: spikes inside ±2/N\pm 2/\sqrt{N} — plus or minus two over root N — are consistent with pure noise. Concretely, one year of daily data is N=252N = 252, so the band is ±2/252±0.126\pm 2/\sqrt{252} \approx \pm 0.126 — embarrassingly wide. A lag-3 autocorrelation of 0.100.10 estimated on a year of returns is nothing.

Two cautions from earlier lessons apply. First, with 20 lags plotted, about 1 in 20 will poke outside a 95% band by pure chance — the multiple-testing trap from D4-01 in miniature. The Ljung–Box test handles this properly. It squares the sample autocorrelations of the first mm lags (where mm is however many lags you choose to check) and aggregates them into one statistic with one p-value. That tests the joint null that all mm autocorrelations are zero — one honest test instead of twenty hopeful eyeballs. Second, the 1/N1/\sqrt{N} band assumes iid data. Fact 2 says returns are not iid — volatility clusters — and that widens the true bands for return series. Treat the rule as a floor, not a verdict.

Try it

▮ EXERCISE · d1-01-ex1

Implement autocorr(x, k): the lag-k sample autocorrelation, computed as the correlation of x[:-k] with x[k:] using np.corrcoef. The result is element [0, 1] of the 2x2 correlation matrix.

⧉ Review card
Define lag-k autocorrelation and the ACF.
The correlation of a series with itself shifted k steps: Corr of x_t with x_t-k. Sample version: correlate x[:-k] with x[k:]. The ACF is this value plotted for k = 1, 2, 3, ... — the standard first diagnostic for any time series.
⧉ Review card
What are the two foundational ACF facts about asset returns?
1) Returns themselves have near-zero autocorrelation at every lag — direction does not persist, which is why naive return prediction fails. 2) Squared and absolute returns have strong, slowly decaying positive autocorrelation — volatility clusters. You cannot forecast the sign, but you can forecast the size.
⧉ Review card
How do you eyeball whether a sample autocorrelation spike is real?
Under the iid null, sample autocorrelations are roughly Normal(0, 1/N), so the standard error is 1 over root N. Spikes inside plus-or-minus 2 over root N are consistent with noise. One year of daily data (N = 252) gives a band of about plus-or-minus 0.126 — wide.
⧉ Review card
What does the Ljung-Box test do, and what problem does it fix?
It aggregates the squared sample autocorrelations of the first m lags into a single statistic with one p-value, testing the joint null that all m are zero. It fixes the multiple-testing trap of eyeballing 20 spikes and getting excited about the 1-in-20 that clears the band by chance.

Draw it

On paper, draw two ACF plots side by side for a daily stock return series, lags 1 through 20, each with the noise band at plus-or-minus 2/N2/\sqrt{N} drawn in: left panel the returns themselves, right panel the squared returns. Then annotate each panel with one sentence on what trading business it kills or enables.

Predict before the next lesson

Next up: white noise and random walks (D1-02). Before then, predict: if you flip a coin 1,000 times and chart the running total of heads-minus-tails, what will the chart look like? Would you be able to tell it apart from a real stock chart — and what patterns would you be tempted to draw on it?

◈ Calibration check

Could you compute a lag-k autocorrelation from scratch, state the two stylized ACF facts about returns, and explain the 2-over-root-N band?

1 = guessing · 5 = could teach it

⏻ End of lesson

Mark it read to book its 4 review cards into your deck.

Sources & further reading