Statistical Arbitrage: Pairs Trading and Cointegration
Module: Fintech AI | Difficulty: Advanced
Cointegration
Engle-Granger Test
- Regress on
- Test residuals for unit root
- If stationary, pair is cointegrated
Half-Life of Mean Reversion
where is the AR(1) coefficient.
import numpy as np
from statsmodels.tsa.stattools import coint
class PairsTrading:
def __init__(self, lookback=60, z_entry=2, z_exit=0.5):
self.lookback = lookback; self.z_entry = z_entry; self.z_exit = z_exit
def find_pairs(self, prices_df, significance=0.05):
pairs = []
symbols = prices_df.columns
for i in range(len(symbols)):
for j in range(i+1, len(symbols)):
score, pvalue, _ = coint(prices_df[symbols[i]], prices_df[symbols[j]])
if pvalue < significance:
pairs.append((symbols[i], symbols[j], pvalue))
return pairs
def generate_signal(self, prices1, prices2):
spread = prices1 - np.polyfit(prices2, prices1, 1)[0] * prices2
z = (spread[-1] - spread.mean()) / spread.std()
if z < -self.z_entry: return 'long_spread'
elif z > self.z_entry: return 'short_spread'
elif abs(z) < self.z_exit: return 'close'
return 'hold'
Research Insight: Pairs trading profitability has declined as more participants exploit the same opportunities. However, the strategy remains profitable when combined with machine learning for pair selection and signal generation. The key is finding pairs with fast mean reversion and high Sharpe ratios.