统计套利基础:协整与配对交易
做量化这些年,我越来越觉得,统计套利是个很有意思的领域。它不像高频交易那样拼速度,也不像事件驱动那样赌消息。它靠的是——两个资产之间那种「若即若离」的关系。
说白了,就是找一对兄弟。平时各走各的路,但一旦走远了,总会有人把他们拉回来。
协整:比相关性更靠谱的东西
很多人刚开始做配对交易,第一反应是算相关系数。嗯,我当年也这么干过。结果呢?亏得挺惨。
为什么?因为相关性高,不代表价差会回归。举个例子,茅台和五粮液,相关性可能很高,但它们的价差可能越走越远,根本不回头。
协整就不一样了。它描述的是:两个时间序列的线性组合,是平稳的。你想想看,这意味着什么?意味着它们的价差,会围绕一个均值来回摆动。
核心概念:如果两个价格序列 Xt 和 Yt 满足:存在一个 β,使得 Zt = Yt - βXt 是平稳的,那么它们就是协整的。
我在项目中遇到过一对很有意思的品种:某两只银行股。相关性只有0.6左右,但协整检验的p值小于0.01。后来实盘跑了半年,年化收益15%,最大回撤不到3%。
Engle-Granger两步法
怎么检验协整?我个人习惯用Engle-Granger方法。两步走:
- 第一步:用OLS回归 Yt = α + βXt + εt,得到残差序列 εt
- 第二步:对残差做ADF检验,看它是否平稳
代码写起来也不复杂:
import statsmodels.api as sm
from statsmodels.tsa.stattools import adfuller
# 假设 y 和 x 是两个价格序列
x = sm.add_constant(x)
model = sm.OLS(y, x).fit()
residuals = model.resid
# ADF检验
adf_stat, p_value = adfuller(residuals)[:2]
if p_value < 0.05:
print("协整关系成立")
else:
print("不协整,换一对试试")
一个小技巧:我建议你在做ADF检验时,把滞后阶数设得大一点。尤其是日频数据,至少设到10。不然容易误判。
均值回归策略:核心逻辑
一旦确认了协整关系,策略就很简单了。我们盯着价差 Zt 看。当它偏离均值太远时,我们就赌它会回来。
具体怎么操作?
- 当 Zt 高于上轨:做空价差(卖Y买X)
- 当 Zt 低于下轨:做多价差(买Y卖X)
- 当 Zt 回归均值:平仓
听起来简单吧?但这里有个坑。我曾经吃过一次大亏:价差偏离后,不但没回归,反而越走越远。那次回撤了8%,我整整盯了一周的盘。
避坑指南:协整关系不是永恒的。我建议每3个月重新检验一次。如果协整关系破裂,果断止损,不要死扛。
Ornstein-Uhlenbeck过程:数学建模
说到均值回归,就不得不提Ornstein-Uhlenbeck过程。它是描述均值回归行为最经典的随机过程。
数学形式是这样的:
dX_t = θ(μ - X_t)dt + σdW_t
其中:
- θ 是回归速度(越大回归越快)
- μ 是长期均值
- σ 是波动率
说白了,这个方程告诉我们:当 Xt 偏离 μ 时,会有一股「拉力」把它往回拽。拽的力度,和偏离程度成正比。
我在实际项目中,会用最大似然估计来拟合OU过程的参数。代码大概长这样:
import numpy as np
def estimate_ou_params(series, dt=1):
# 用OLS估计OU参数
x = series[:-1]
y = series[1:]
# 回归 y = a + b*x + error
A = np.vstack([np.ones_like(x), x]).T
coeff, _ = np.linalg.lstsq(A, y, rcond=None)[:2]
a, b = coeff
theta = -np.log(b) / dt
mu = a / (1 - b)
# 估计波动率
residuals = y - (a + b * x)
sigma = np.std(residuals) * np.sqrt(-2 * np.log(b) / (1 - b**2))
return theta, mu, sigma
Z-score与开仓信号
有了OU过程的参数,我们就可以计算Z-score了。Z-score说白了就是:当前价差偏离均值多少个标准差。
公式很简单:
Z = (当前价差 - 均值) / 标准差
我一般这样设置信号:
| Z-score范围 | 操作 | 仓位 |
|---|---|---|
| |Z| < 0.5 | 不操作 | 0 |
| 0.5 ≤ |Z| < 1.5 | 轻仓试探 | 30% |
| 1.5 ≤ |Z| < 2.5 | 正常开仓 | 70% |
| |Z| ≥ 2.5 | 重仓出击 | 100% |
个人经验:阈值不是死的。波动率大的市场,我习惯把阈值调高到2.0和3.0。不然频繁开仓,手续费都亏没了。
嗯,这里要注意一点:Z-score的计算窗口期很关键。我试过20天、60天、120天。最后发现,60天的滚动窗口效果最好。太短了噪声大,太长了反应慢。
本章知识体系
下面这张图,是我梳理的本章核心逻辑。你可以把它当作一个思维导图来看:
做统计套利这些年,我最大的体会是:不要迷信模型。OU过程再漂亮,Z-score再精确,如果市场结构变了,一切都是白搭。我见过太多人,模型拟合得漂漂亮亮,一实盘就亏。为什么?因为他们忘了——市场是会变的。
所以,我的建议是:把统计套利当作一个工具,而不是圣杯。用它来捕捉那些「大概率会回归」的机会,但永远留一手,准备应对「不回归」的情况。