4. 协整理论详解:平稳性检验(ADF检验)、Engle-Granger两步法、Johansen检验

各位同学,欢迎来到第四章。这一章我们聊聊协整理论。

说实话,协整是我个人在统计套利中最喜欢用的工具之一。为什么?因为它能帮我们找到那些表面上随机游走、实际上却“手拉手”走在一起的资产对。你想想看,两只股票各自都在乱跑,但它们的价差却始终围绕一个均值波动——这不就是套利机会吗?

好,我们一步步来拆解。先讲平稳性,再讲两步法,最后讲多变量场景下的Johansen检验。

4.1 平稳性检验:ADF检验

平稳性,说白了就是一个时间序列的统计性质不随时间改变。均值不变、方差不变、自相关结构也不变。嗯,这里要注意:金融价格序列几乎都不是平稳的,但它们的差分(收益率)往往是平稳的。

为什么要先讲平稳性?因为协整的前提是:两个序列本身是非平稳的,但它们的线性组合是平稳的。所以第一步,你得先确认每个序列是不是非平稳的。

ADF检验(Augmented Dickey-Fuller Test)是最常用的单位根检验方法。它的原假设是“序列存在单位根”,也就是非平稳。p值小于0.05,我们就拒绝原假设,认为序列平稳。

核心要点: 做协整前,先确认两个序列都是I(1)(一阶单整)。如果一个I(1)、一个I(2),那它们不可能协整。

我在项目中遇到过这样的情况:两个看起来高度相关的股票,ADF检验一做,一个是一阶单整,另一个是二阶单整。嗯,那就别费劲了,它们不可能有长期均衡关系。

下面是一个Python实现ADF检验的示例:

import numpy as np
import pandas as pd
from statsmodels.tsa.stattools import adfuller

# 模拟两个非平稳序列
np.random.seed(42)
n = 500
epsilon = np.random.randn(n)
x = np.cumsum(epsilon)  # 随机游走,I(1)
y = 0.8 * x + np.random.randn(n) * 0.5  # 与x协整

# ADF检验
def adf_test(series, name=''):
    result = adfuller(series, autolag='AIC')
    print(f'{name} ADF统计量: {result[0]:.4f}')
    print(f'p值: {result[1]:.4f}')
    print(f'临界值:')
    for key, value in result[4].items():
        print(f'  {key}: {value:.4f}')
    if result[1] < 0.05:
        print(f'结论: {name} 平稳')
    else:
        print(f'结论: {name} 非平稳')
    print('---')

adf_test(x, 'x')
adf_test(y, 'y')

输出结果会告诉你,x和y都是非平稳的。但它们的残差呢?我们后面再验证。

避坑指南: 我曾经因为没检查滞后阶数选择,导致ADF检验结果不稳定。建议用AIC或BIC自动选择滞后阶数,别手动拍脑袋。

4.2 Engle-Granger两步法

这是最经典的协整检验方法。说白了就是两步走:

  1. 第一步: 用OLS回归估计长期均衡关系。比如 y = α + βx + ε,得到残差序列。
  2. 第二步: 对残差做ADF检验。如果残差平稳,说明x和y协整。

你想想看,如果x和y真的存在长期均衡关系,那么它们的价差(残差)应该围绕0波动,不会越走越远。这就是协整的本质。

下面是一个完整的Engle-Granger两步法实现:

import statsmodels.api as sm

# 第一步:OLS回归
X = sm.add_constant(x)
model = sm.OLS(y, X).fit()
residuals = model.resid

print(f'回归系数: alpha={model.params[0]:.4f}, beta={model.params[1]:.4f}')

# 第二步:对残差做ADF检验
adf_test(residuals, '残差')

如果残差的ADF检验p值小于0.05,恭喜你,找到了一个协整对。这时候就可以考虑用价差的均值回归特性做套利了。

注意: Engle-Granger两步法有个局限——它只能检验一对变量之间的协整关系。而且回归方向(y对x还是x对y)会影响结果。我个人习惯两个方向都试一下,取残差更平稳的那个。

我记得有一次做商品期货的跨品种套利,用两步法检验螺纹钢和热卷的协整关系。第一次回归残差的p值是0.06,差一点。换了个方向重新做,p值变成0.03,通过了。所以别偷懒,两个方向都试试。

4.3 Johansen检验

当你有多个资产时(比如3只股票、5只期货),Engle-Granger两步法就不够用了。这时候需要Johansen检验。

Johansen检验的核心思想是:基于向量自回归模型(VAR),通过特征值分解来判断协整关系的个数。它给出两个统计量:迹统计量和最大特征值统计量。

说白了,Johansen检验能告诉你:这组资产中,存在几个协整关系?是1个、2个,还是根本没有?

下面是一个Python实现:

from statsmodels.tsa.vector_ar.vecm import coint_johansen

# 模拟三个协整序列
np.random.seed(123)
n = 500
z1 = np.cumsum(np.random.randn(n))  # I(1)
z2 = 0.6 * z1 + np.random.randn(n) * 0.3  # 与z1协整
z3 = 0.4 * z1 + 0.3 * z2 + np.random.randn(n) * 0.2  # 与z1、z2协整

data = np.column_stack([z1, z2, z3])

# Johansen检验
johansen_result = coint_johansen(data, det_order=0, k_ar_diff=1)

print('迹统计量:', johansen_result.lr1)
print('迹统计量临界值(95%):', johansen_result.cvt[:, 1])
print('最大特征值统计量:', johansen_result.lr2)
print('最大特征值临界值(95%):', johansen_result.cvm[:, 1])

# 判断协整秩
r = 0
for i in range(len(johansen_result.lr1)):
    if johansen_result.lr1[i] > johansen_result.cvt[i, 1]:
        r += 1
print(f'协整秩: {r}')

输出结果会告诉你协整秩是多少。比如协整秩为2,意味着这3个资产之间存在2个独立的协整关系。

实战经验: Johansen检验对滞后阶数敏感。我一般先用AIC选VAR的滞后阶数,再传给Johansen检验。别用默认值,容易出错。

为什么会这样?因为Johansen检验本质上是基于VAR模型的,滞后阶数选错了,残差的自相关没处理好,检验结果就不可靠。嗯,这里要特别注意。

4.4 三种方法的对比

方法 适用场景 优点 缺点
ADF检验 单个序列的平稳性判断 简单、快速、成熟 只能判断是否平稳,不能直接检验协整
Engle-Granger两步法 两个资产之间的协整检验 直观、容易理解、计算量小 只能处理一对变量;回归方向影响结果
Johansen检验 多个资产之间的协整检验 能同时检验多个协整关系;基于VAR更稳健 计算复杂;对滞后阶数敏感

我个人习惯是:做配对交易时用Engle-Granger两步法,做多资产组合时用Johansen检验。ADF检验则是每个项目开始前的必备热身。

4.5 知识体系图

下面这张图总结了本章的核心逻辑:

协整理论核心逻辑 第一步:平稳性检验 ADF检验 是否I(1)? 一阶单整 否 → 停止 第二步:选择方法 看资产数量 2个资产 多个资产 Engle-Granger两步法 OLS回归 → 残差ADF检验 Johansen检验 VAR模型 → 特征值分解 结果:确认协整关系 残差平稳 → 存在长期均衡 → 可做统计套利 注:所有资产必须同阶单整,通常为I(1)

这张图把整个流程串起来了。从ADF检验开始,确认资产都是I(1),然后根据资产数量选择方法,最后确认协整关系。每一步都有坑,但每一步也都有对应的解决方案。

我的建议: 刚开始做协整检验时,先用Engle-Granger两步法练手。等熟悉了残差分析、理解了均值回归的逻辑,再上Johansen检验。别一上来就搞复杂的,容易迷失在统计量里。

好了,这一章就到这里。协整理论是统计套利的基石,把这块啃下来,后面的策略构建就水到渠成了。


公众号:蓝海资料掘金营,微信deep3321