Implementation Scope

This trades single-asset return shocks, not a richer cross-sectional or market-neutral statistical-arbitrage stack.

The Intuition

The z-score mean reversion strategy is the most statistically clean version of mean reversion trading: it standardises the recent return relative to its own historical distribution, then trades when that standardised deviation exceeds a threshold. It is agnostic about price levels — it operates entirely in the space of standardised deviations.

The idea originates in statistics. A z-score of +2 means the observation is 2 standard deviations above the recent mean — an event that under normality would occur about 2.5% of the time. If returns are mean-reverting, a z-score of +2 is a bet that the extreme observation will be followed by a correction toward zero. The larger the absolute z-score, the stronger the signal.

This is closely related to the "convergence trade" logic underlying statistical arbitrage: you are not betting on a direction per se, but on the reversion of a statistical anomaly. Unlike price-level strategies (Bollinger Bands), the z-score approach works on returns, which are more naturally stationary than price levels.

Key assumptions: (1) Log returns are approximately i.i.d. within the rolling window — the window mean and variance are meaningful parameters. (2) Autocorrelation in returns is negative at short lags (mean reversion). (3) The threshold is appropriately set for the instrument's volatility regime. If returns are fat-tailed (as they typically are), the 1.5-sigma event is more common than normality predicts.

The strategy fails in trending markets and during regime changes. When a new information event causes a sustained shift in the price level, the z-score keeps rising rather than reverting. Position sizing is critical: because the strategy can be wrong during trending regimes for long stretches, naive full-position sizing leads to deep drawdowns. Many practitioners use Kelly-scaled or volatility-targeted position sizing alongside z-score signals.

The Math

Read this as a compact model summary: what the signal sees, what it ignores, and where fragility can creep in.

r(t)     = log(Close(t) / Close(t-1))
mu(t)    = mean(r[t-n : t])
sigma(t) = std(r[t-n : t])
z(t)     = (r(t) - mu(t)) / sigma(t)

Signal(t) = +1  if z(t) < -threshold
          = -1  if z(t) >  threshold
          =  0  otherwise

Parameters

ParameterTypeDefaultDescription
window int 20 Rolling window for z-score calculation
threshold float 1.5 Z-score magnitude to trigger a trade

Source Code

def run(ticker: str, start: str, end: str, **params) -> dict:
    window = int(params.get("window", 20))
    threshold = float(params.get("threshold", 1.5))
    df = fetch_ohlcv(ticker, start, end)
    positions = _signal(df, window, threshold)
    return run_backtest(df, positions, ticker=ticker, start=start, end=end,
                        strategy=METADATA["slug"], params={"window": window, "threshold": threshold})

Further Reading

  • Chan, E. (2013). Algorithmic Trading, Ch. 2. Wiley.
  • Vidyamurthy, G. (2004). Pairs Trading: Quantitative Methods and Analysis. Wiley.
  • Avellaneda, M. & Lee, J. (2010). Statistical Arbitrage in the US Equities Market. Quantitative Finance, 10(7), 761–782.

When It Works / When It Fails

Works
  • Range-bound markets with approximately normal return distributions
  • Instruments with stable mean and variance over the lookback
  • Calm vol environments where z-score thresholds are meaningful
Fails
  • Fat-tailed return distributions invalidate z-score thresholds
  • Trending regimes — returns keep hitting the extreme threshold
  • Non-stationary volatility periods distort rolling normalization

Regime Fit

Transition / Calm vol
Best conditions at 1.0. Return distribution is well-behaved; z-score thresholds are reliable.
Transition / Normal vol
Strong fit at 0.75. Standardization still works well; tails slightly heavier.
Bull or Bear / Calm vol
Reduced to 0.7. Directional drift inflates the mean; z-scores require careful interpretation.
Any regime / Stressed vol
Exposure drops to 0.0. Tail events dominate and z-score threshold logic breaks down.

Compared to Alternatives

vs Bollinger
Bollinger operates on price levels with a flat SMA center; Zscore standardizes the return series. Zscore is more sensitive to recent volatility shifts.
vs RSI
RSI uses a cumulative gain/loss path; Zscore uses a standardized return deviation. The two have different sensitivity profiles across momentum and reversal regimes.
vs OU Reversion
Zscore uses rolling statistics empirically; OU explicitly models mean-reversion speed and half-life via a fitted SDE. OU is more principled for spread modeling.
Run This Strategy →