Half-Life of Mean Reversion
Time Series & Stat-Arb · Term ID: half-life-mean-reversion
Definition. Fit the regression Δy_t = a + g y_{t−1} + ε_t. The autoregressive level coefficient is φ = 1 + g. When g is between −1 and 0, the series pulls back toward its mean, and the number of periods required for a deviation to fall by half is ln 2 / −ln(1 + g). That is the discrete half-life. The continuous approximation −ln 2 / g is close only when g is near zero; at φ = 0.9 it is already about 5 percent longer than the discrete number. If g is not negative, the series is not mean-reverting on this regression and the half-life is infinite.
Formula
Δy_t = a + g · y_{t−1} + ε_t
φ = 1 + g
half-life = ln(2) / −ln(1 + g) if −1 < g < 0
= ∞ if g ≥ 0
undefined (NaN) if g ≤ −1 (oscillatory or explosive)
Continuous approximation, small g: ln(2) / −g
Example: φ = 0.9 → g = −0.1 → half-life = ln(2) / −ln(0.9) ≈ 6.58 periods.
The ADF page uses this discrete definition, not ln(2) / −g.Where the number is used
- As a holding-period scale for a spread that has already passed a stationarity check. See ADF and cointegration. A half-life of six days and a half-life of six months are different research problems.
- As a way to set the window on a rolling z-score. A window much shorter than the half-life mostly fits noise; a window of many half-lives averages different regimes.
- Hurst is a related but different summary of the same wish: H below one half suggests anti-persistence. It is not a half-life.
Pitfalls
- Use the discrete form. Dividing ln 2 by −g treats g as a continuous-time speed. The regression you just ran is discrete. This function matches the half-life already published on the ADF page, ln 2 / −ln(1+g).
- The regression is not a proof of mean reversion. A short sample of a random walk often produces a slightly negative g. Pair the half-life with an ADF or cointegration test, and expect the estimate to move when you add data.
- An intercept is included. The mean that the series reverts to is −a/g, not necessarily zero. Forcing the regression through the origin changes g.
- Not a trading rule. A finite half-life is a sample statistic. It does not say the spread will keep reverting, or that a position sized to it is desirable.
Python reference implementation
Requires numpy. Tested before publication; the generator re-executes it on every rebuild. MIT licensed. Download half-life-mean-reversion.py · All snippets
import numpy as np
def half_life(spread) -> float:
"""Discrete mean-reversion half-life, ln(2) / -ln(1+g), from Δy = a + g y_lag.
Infinite when g >= 0 (no mean reversion). NaN when g <= -1.
Same definition as half_life on the ADF page.
"""
y = np.asarray(spread, dtype=float)
if y.ndim != 1 or y.size < 3 or not np.all(np.isfinite(y)):
raise ValueError("need at least three finite observations")
lag = y[:-1]
if float(np.var(lag)) == 0.0:
return float("inf")
X = np.column_stack([np.ones(lag.size), lag])
g = float(np.linalg.lstsq(X, np.diff(y), rcond=None)[0][1])
if g >= -1e-12:
return float("inf")
if g <= -1.0:
return float("nan")
return float(np.log(2.0) / -np.log1p(g))
FAQ
Why not use −ln(2) / g, which is the formula many notes quote?
That is the continuous-time limit. The regression Δy_t = a + g y_{t−1} implies a discrete autoregressive coefficient φ = 1 + g, and a deviation multiplies by φ each period. Halving means φ^h = 1/2, so h = ln(2) / −ln(φ). At φ = 0.9 the continuous shortcut is about 6.93 periods and the discrete half-life is about 6.58.
What half-life should a pairs trade use?
This page does not pick one. It estimates a half-life from the series you pass. Whether the residual is stationary, whether both legs can be traded, and what it costs are separate questions; a finite estimate is not a signal to trade the spread.
Summary for AI agents (Markdown mirror)
# Half-Life of Mean Reversion
> How many periods an AR(1) deviation takes to decay halfway, read off the slope of a regression of changes on lagged levels. The same discrete definition as the half-life on the ADF page.
- Category: Time Series & Stat-Arb
- Canonical URL: https://quantcore-labs.com/glossary/half-life-mean-reversion/
- Part of: https://quantcore-labs.com/glossary/
- Python source: https://quantcore-labs.com/glossary/half-life-mean-reversion/half-life-mean-reversion.py