Algorithmic Trading & Indicators Advanced

Statistical Arbitrage Pairs Trading Cointegration & Z-Score Scanner in Python

Test stock pairs for Engle-Granger cointegration using statsmodels in Python and compute rolling spread Z-Score signals for market-neutral pairs trading.

#pandas#numpy#statsmodels

Problem Statement

Correlation alone breaks down over time. True market-neutral statistical arbitrage requires testing whether the price spread between two stocks (e.g., HDFC Bank & ICICI Bank) is stationary via cointegration.

Formula / Core Logic

Spread = Log(Y) - Beta * Log(X) Z_Score = (Spread - Rolling_Mean(Spread, 20)) / Rolling_Std(Spread, 20)

Installation

pip install pandas numpy statsmodels
pairs-trading-cointegration-zscore-scanner-python.py
import numpy as np
import pandas as pd
from statsmodels.tsa.stattools import coint
import statsmodels.api as sm

def pairs_cointegration_zscore(series_y, series_x, window=20):
    score, pvalue, _ = coint(series_y, series_x)
    model = sm.OLS(series_y, sm.add_constant(series_x)).fit()
    hedge_ratio = model.params.iloc[1]
    
    spread = series_y - (hedge_ratio * series_x)
    zscore = (spread - spread.rolling(window).mean()) / spread.rolling(window).std()
    return {'P_Value': round(pvalue, 4), 'Is_Cointegrated': pvalue < 0.05, 'Hedge_Ratio': round(hedge_ratio, 4), 'Latest_ZScore': round(zscore.iloc[-1], 2)}

Get the Complete 100+ Python Quant & Automation Bundle

Instant lifetime access to all production-ready scripts, valuation models, and trading bots ($19).

Buy Full Bundle on Gumroad ($19) →

Frequently Asked Questions

Q: What Z-Score threshold triggers a pairs trade entry?

Traders typically short the spread when Z-Score > +2.0 and go long the spread when Z-Score < -2.0, exiting at 0.0.