2. 协整理论:平稳性检验与协整关系建模
各位同学,咱们今天聊点硬核的。协整理论,说白了就是帮我们找到那些「看似随机游走,实则暗中勾连」的资产对。我刚开始做配对交易时,踩过最大的坑就是——两个股票明明走势很像,一上统计检验,全是伪回归。嗯,今天咱们就把这块彻底讲透。
2.1 为什么平稳性这么重要?
先问个问题:你拿两个随机游走的序列做回归,R²可能很高,t统计量也可能显著。但这有意义吗?
完全没有。这就是经典的「伪回归」问题。我2018年刚入行时,用茅台和五粮液跑了个回归,R²高达0.92,兴奋得不行。结果实盘一跑,亏得亲妈都不认识。后来才发现,两个非平稳序列的回归,残差也是非平稳的——说白了,它们之间根本没有稳定的关系。
所以,做配对交易的第一步,就是检验平稳性。
2.2 平稳性的定义与直观理解
一个时间序列是平稳的,意味着它的统计性质不随时间变化。具体来说:
- 均值恒定:长期来看,价格围绕一个固定值波动
- 方差恒定:波动幅度不会越来越大
- 协方差只与时间间隔有关:过去和未来的关系是稳定的
你想想看,如果两个股票的价差序列是平稳的,那它就会像一根被拉住的橡皮筋——偏离太远,迟早会弹回来。这就是配对交易赚钱的根本逻辑。
2.3 单位根检验:ADF检验实战
检验平稳性最常用的工具,就是单位根检验。我个人习惯用ADF检验(Augmented Dickey-Fuller Test)。
它的逻辑很简单:如果序列存在单位根,就是非平稳的;如果不存在,就是平稳的。
来看代码:
import numpy as np
import pandas as pd
from statsmodels.tsa.stattools import adfuller
import yfinance as yf
# 下载两只股票数据
tickers = ['AAPL', 'MSFT']
data = yf.download(tickers, start='2020-01-01', end='2023-12-31')['Adj Close']
# 对每只股票做ADF检验
for ticker in tickers:
result = adfuller(data[ticker].dropna())
print(f'{ticker} ADF统计量: {result[0]:.4f}')
print(f'p值: {result[1]:.4f}')
if result[1] < 0.05:
print(f'结论: {ticker} 是平稳序列\n')
else:
print(f'结论: {ticker} 是非平稳序列\n')
运行结果通常是:两只股票的p值都远大于0.05,说明它们都是非平稳的。嗯,这很正常——股票价格嘛,本来就是随机游走的。
2.4 协整关系建模:从理论到代码
既然单个资产不平稳,那我们就看看它们的组合是否平稳。协整检验的核心思想是:两个非平稳序列的线性组合可能是平稳的。
具体步骤分三步:
- 估计协整系数:用OLS回归,得到两个资产的线性关系
- 提取残差:残差就是价差序列
- 检验残差的平稳性:如果残差平稳,就说明存在协整关系
来看完整实现:
import statsmodels.api as sm
# 第一步:OLS回归估计协整系数
X = sm.add_constant(data['AAPL'])
model = sm.OLS(data['MSFT'], X).fit()
hedge_ratio = model.params['AAPL']
intercept = model.params['const']
print(f'对冲比率: {hedge_ratio:.4f}')
print(f'截距项: {intercept:.4f}')
# 第二步:计算价差(残差)
spread = data['MSFT'] - hedge_ratio * data['AAPL'] - intercept
# 第三步:对价差做ADF检验
result = adfuller(spread.dropna())
print(f'价差ADF统计量: {result[0]:.4f}')
print(f'p值: {result[1]:.4f}')
if result[1] < 0.05:
print('结论: 存在协整关系,可以配对交易!')
else:
print('结论: 不存在协整关系,换个组合试试')
如果p值小于0.05,恭喜你,找到了一个可以交易的配对。我曾经用这个方法在2022年找到了XOM和CVX的配对,那一年能源股波动大,但这对组合的价差非常稳定,赚了不少。
2.5 Johansen检验:多资产协整
如果你手里有三只以上的股票,想找它们之间的协整关系,那就得上Johansen检验了。它比Engle-Granger两步法更强大,能同时检验多个协整向量。
from statsmodels.tsa.vector_ar.vecm import coint_johansen
# 准备数据:至少需要两个以上资产
assets = ['AAPL', 'MSFT', 'GOOGL']
data_multi = yf.download(assets, start='2020-01-01', end='2023-12-31')['Adj Close']
# Johansen检验
result = coint_johansen(data_multi, det_order=0, k_ar_diff=1)
print('特征值:', result.eig)
print('迹统计量:', result.lr1)
print('临界值(95%):', result.cvt[:, 1])
# 判断协整秩
for i in range(len(result.lr1)):
if result.lr1[i] > result.cvt[i, 1]:
print(f'拒绝H0: 协整秩 <= {i}')
else:
print(f'接受H0: 协整秩 <= {i}')
Johansen检验会告诉你存在几个协整关系。比如结果说协整秩为1,那就意味着这三只股票之间,存在一个稳定的线性组合。
2.6 知识体系总览
下面这张图,是我自己总结的协整理论知识框架。你把它存下来,以后做配对交易时对照着看:
2.7 实战中的注意事项
最后,分享几个我踩过的坑:
- 数据频率要匹配:日线检验的协整关系,别拿到分钟线上用。我吃过这个亏,亏了大概5个点。
- 协整关系会漂移:别以为检验一次就一劳永逸。我建议每3个月重新检验一次,如果协整关系消失了,果断换组合。
- 不要过度优化:有些人为了得到漂亮的检验结果,反复调整样本区间。这是数据挖掘,不是量化交易。
- 注意交易成本:协整检验通过不代表能赚钱。高频配对交易中,手续费和滑点可能吃掉所有利润。
好了,这一章的内容就到这里。协整理论是配对交易的基石,你把它吃透了,后面的信号捕捉和风险管理才能站得住脚。下一章咱们聊「价差序列的统计套利策略」,到时候会用到今天讲的这些检验方法。
公众号:蓝海资料掘金营,微信deep3321