Cointegration and pairs trading — mean reversion you can hunt for
▸ Pretest — guess, even if you don't know
Two oil majors have a daily RETURN correlation of 0.9. Does that guarantee the gap between their PRICES stays bounded over the next decade?
Correlated returns, drifting prices
Correlation (A2-08) lives in return space: do the two series zig together day by day? Cointegration lives in price space: is there a combination of the two prices that never wanders off? The two properties are genuinely independent — you can have either one without the other:
- Correlated but not cointegrated: two tech stocks zig together daily ( — rho, the Greek letter for a correlation coefficient) while one compounds 20% a year and the other 5%. The daily dance is synchronized; the price gap still goes to the moon.
- Cointegrated but weakly correlated: a stock and its dual-listed twin on another exchange can have noisy, modest daily return correlation. Yet arbitrageurs yank the price gap back to pennies every time it opens.
If you trade the gap between two prices, return correlation is the wrong safety check. You need the stronger property.
Cointegration: a stationary combination of non-stationary things
From D1-03: individual prices are non-stationary. They carry unit roots — shocks never decay — so there is no fixed mean to revert to, and the ADF test (augmented Dickey–Fuller, the D1-03 stationarity test) fails to reject. Two price series and ("y sub t" and "x sub t" — the two prices on day t) are cointegrated if some linear combination
is stationary. In words: the spread "z sub t" equals the price of y minus gamma (the Greek letter ) times the price of x. Gamma is the mixing weight — how many units of x you subtract per unit of y. Concrete numbers: with , , and , the spread is .
Each series wanders like a drunk, but they're two drunks handcuffed together: each path is unpredictable, the distance between them is not. The spread has a fixed mean, finite variance, and mean-reverts. That's everything the D1-03 toolkit certifies — and everything the D1-04 machinery can then exploit. Economically the handcuff is usually an arbitrage force: dual listings, share classes, an ETF versus its basket, refiner versus crude. Someone with size gets paid to close the gap, so the gap closes.
Engle–Granger in two steps
The classic test for cointegration is almost embarrassingly simple:
- Regress on by OLS — ordinary least squares, the standard line-fitting regression from A2-06. The fitted slope ("gamma-hat" — the hat marks a value estimated from data) is the hedge ratio: how many units of offset one unit of . A hedge ratio of 2 means you short 2 shares of x against each share of y you buy.
- ADF-test the residuals (D1-03). The residuals — the leftover gaps between actual and the fitted line — are exactly the spread . If ADF rejects a unit root in , the pair is cointegrated: you found a stationary combination.
One honest technicality. Because was fitted — OLS deliberately chose the combination that looks most stationary — the ADF critical values must be stricter than the off-the-shelf ones (statsmodels' coint handles this). The two-step structure, though, is exactly regression plus the stationarity test you already know.
Trading the spread
Once is certified stationary, it's an AR(1)-style mean reverter, and all of D1-04 applies to the spread. Estimate its ("phi" — the AR(1) pull-back coefficient from D1-04) and you get a half-life — the typical time for a deviation to close half its gap, which is the practical timescale of the trade. Half-life of 8 days: tradeable. Half-life of 8 months: your capital ages while the spread thinks about it.
The playbook: compute the spread's z-score, . In words: take today's spread, subtract its historical average ("z-bar" — the bar means average), and divide by its standard deviation ("sigma sub z"). The result says how many standard deviations from normal the spread is right now. Concrete numbers: average spread 10, standard deviation 2, today's spread 14.5 — the z-score is , a stretched pair. When the z-score moves beyond about ±2, short the rich side and buy the cheap side in the ratio ; exit near zero. The position is (roughly) market-neutral — you're long and short similar exposure — so the P&L comes from the gap converging, not from market direction. This is the cleanest expression in the whole curriculum of trading a statistical property rather than an opinion.
Honest warnings
- Cointegration breaks. The handcuff is economic, and economics changes: a merger, a business-model pivot, a regulation. The most infamous blowups in stat-arb — statistical arbitrage — history were "temporary" divergences that were actually regime changes (D1-10). A spread that is 6 sigma wide (six standard deviations from its mean) is either the trade of the year or a pair that has stopped being a pair. The statistics alone cannot tell you which. Use stop-losses sized to the possibility that the relationship is dead.
- In-sample hedge ratios overfit. The fitted on 2019–2022 data is not the true . The spread built with it looks more stationary in-sample — on the data used to fit it — than it will behave out-of-sample (the D1-06 ratchet in a new costume). Re-estimate on a rolling basis and check stability.
- Scanning is multiple testing. Test 1000 pairs at the 5% level and about 50 will "cointegrate" by pure luck (A2-05 — and Harvey–Liu–Zhu's factor-zoo warning applies verbatim to the pairs zoo). Demand an economic reason the pair should be linked before the test, not after.
Try it
Build the two objects everything above rests on — the hedge ratio (a regression slope via the covariance formula from A2-06) and the spread:
Implement hedge_ratio(y, x): the OLS slope of y on x, computed as np.cov(y, x)[0, 1] / np.var(x, ddof=1). And spread(y, x): the array y - hedge_ratio(y, x) * x.
⧉ Review cardWhy does high return correlation NOT protect a pairs trade?
⧉ Review cardDefine cointegration.
⧉ Review cardDescribe the Engle-Granger two-step procedure.
⧉ Review cardHow do you turn a cointegrated pair into a trade?
⧉ Review cardThree honest failure modes of pairs trading?
Map it
On paper, draw a concept map linking: unit root (D1-03), return correlation (A2-08), OLS slope (A2-06), hedge ratio, spread, ADF test, stationarity, AR(1) half-life (D1-04), z-score entry, and regime break. Arrows should say things like "tested by", "computed as", "applies to", "kills".
Predict before the next lesson
Next is D1-10: regimes and structural breaks — the lesson every warning above has been pointing at. Predict: you fit one GARCH persistence and one pairs hedge ratio on 2005–2024 pooled data. Name two historical events inside that window that plausibly changed the true parameters mid-sample. What would the pooled estimate be a blend of?
◈ Calibration check
Could you explain to a skeptic why cointegration, not correlation, justifies a pairs trade — and walk through Engle-Granger plus its three failure modes from memory?
1 = guessing · 5 = could teach it
⏻ End of lesson
Mark it read to book its 5 review cards into your deck.
Sources & further reading
- paperEngle & Granger (1987), Co-Integration and Error Correction: Representation, Estimation, and Testing, Econometrica 55(2)
- bookChan (2013), Algorithmic Trading: Winning Strategies and Their Rationale — §2, 3
- paperHarvey, Liu, Zhu (2016), ...and the Cross-Section of Expected Returns, Review of Financial Studies 29(1)