协整与误差修正模型(ECM)
直觉
模块 4.4 配对交易 用到协整——两个非平稳序列的线性组合却平稳。这一节给出它的正式检验(Engle-Granger)与误差修正模型(ECM):它不光说「价差会回归」,还量化「回归得多快」。
Engle-Granger 两步法
- OLS 估计长期关系 ,得残差 (价差);
- 对残差做 ADF 检验——若平稳(拒绝单位根),则 协整。
误差修正模型
协整意味着存在长期均衡;ECM 描述「偏离均衡后如何调整」:
「人话」解释:λ 和半衰期
- (负值):上一期偏离越大,本期回调越多——负号保证「向均值拉回」;
- 半衰期 :偏离消除一半所需的期数,衡量「橡皮筋拉得多紧」;
- 越负、半衰期越短,套利机会「回归越快」。
可运行案例:AAPL/MSFT 的协整检验与 ECM
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
from statsmodels.tsa.stattools import adfuller
df = pd.read_csv('/data/aapl_msft_daily.csv', parse_dates=['date']).set_index('date')
la, lm = np.log(df['aapl_close']), np.log(df['msft_close'])
# Engle-Granger 第1步: OLS 估计长期关系
x, y = lm.values, la.values
beta = np.cov(x, y, ddof=0)[0,1] / np.var(x)
intercept = y.mean() - beta * x.mean()
spread = pd.Series(la - (intercept + beta * lm), index=la.index)
# 第2步: 残差 ADF
adf = adfuller(spread)
print(f"估计 β={beta:.3f} (合成真值≈1.30,估计有偏差=教学点)")
print(f"价差 ADF: stat={adf[0]:.2f}, p={adf[1]:.3g} → "
f"{'协整(平稳)' if adf[1] < 0.05 else '不协整'}")
# ECM: Δspread_t = λ*spread_{t-1} + c
ds = spread.diff().dropna()
lag = spread.shift(1).dropna()
common = ds.index.intersection(lag.index)
X = np.column_stack([np.ones(len(common)), lag.loc[common].values])
b, *_ = np.linalg.lstsq(X, ds.loc[common].values, rcond=None)
lam = b[1]
print(f"\nECM 调整系数 λ={lam:.4f} (负=均值回复)")
print(f"半衰期 ≈ {np.log(2)/abs(lam):.1f} 日 (偏离消除一半的速度)")
plt.figure(figsize=(9, 3.4))
plt.plot(spread, color='#2563eb', lw=0.9, label='价差(残差)')
plt.plot(spread.rolling(60).mean(), color='crimson', lw=1, label='60日均线')
plt.axhline(spread.mean(), color='gray', ls='--', lw=0.8)
plt.title('协整价差向均值回归(ECM 量化了回归速度)'); plt.legend()
plt.tight_layout(); plt.show()
小结
- Engle-Granger:OLS 估长期关系 → 对残差 ADF → 平稳即协整;
- ECM , 量化回归速度;
- 半衰期 衡量「橡皮筋松紧」,是配对交易择时的依据。