协整理论入门:平稳性与单位根检验

做配对交易这么多年,我最大的体会就是——千万别把两个不相关的序列硬凑在一起。你想想看,如果两个股票价格走势完全是各走各的,那所谓的“价差回归”就是空中楼阁。所以,在谈配对之前,我们必须先搞懂一个核心概念:协整

说白了,协整就是描述两个或多个非平稳时间序列之间,存在一种长期稳定的线性关系。嗯,这里要注意,单个序列可以是不平稳的,但它们的某种组合必须是平稳的。这就是协整的精髓。

核心思想:协整关系 ≠ 相关性。两个股票可能高度相关(比如同行业),但未必协整。协整要求的是价差具有均值回归特性,这才是配对交易能赚钱的根本。

1. 平稳性:时间序列的“定海神针”

先聊聊平稳性。我刚开始做量化那会儿,经常被这个概念绕晕。后来我总结了一句话:平稳序列,就是统计性质不随时间变化的序列

具体来说,一个平稳时间序列需要满足三个条件:

  • 均值恒定:序列围绕一个固定值波动,没有长期上升或下降趋势
  • 方差恒定:波动幅度不随时间变化,不会出现“前期平稳、后期剧烈震荡”
  • 协方差只与时间间隔有关:两个时间点的相关性只取决于它们相隔多远,与具体时刻无关

举个例子,白噪声就是最典型的平稳序列。而股票价格,你想想看,它长期来看是上涨的,均值在变,所以它不平稳

我的经验:在实际项目中,我很少见到严格平稳的金融数据。但没关系,我们只需要“弱平稳”就够了——均值和方差稳定,协方差只与滞后阶数有关。别被教科书上的严格定义吓到。

2. 单位根检验:判断平稳性的“试金石”

怎么判断一个序列是否平稳?最常用的方法就是单位根检验。我个人习惯用ADF检验(Augmented Dickey-Fuller Test),它也是业界标准。

ADF检验的原假设是:序列存在单位根,即非平稳。如果p值小于0.05,我们就拒绝原假设,认为序列是平稳的。

来看一段Python代码,这是我常用的写法:

from statsmodels.tsa.stattools import adfuller

def check_stationarity(series, name=''):
    result = adfuller(series.dropna())
    p_value = result[1]
    print(f'{name} ADF检验p值: {p_value:.6f}')
    if p_value < 0.05:
        print(f'→ {name} 是平稳序列')
    else:
        print(f'→ {name} 非平稳,需要差分')
    return p_value < 0.05

# 对股票价格做检验
check_stationarity(stock_a['close'], '股票A')
check_stationarity(stock_b['close'], '股票B')

我曾经踩过一个坑:直接用原始价格做ADF检验,发现p值很大,就以为序列非平稳。这没错,但问题是——很多金融序列确实非平稳,这恰恰是我们要的。因为协整的前提就是单个序列非平稳,但组合后平稳

避坑指南:我曾经遇到一个案例,两个序列的ADF检验p值都接近0.5,明显非平稳。但它们的价差序列做ADF检验时,p值竟然也大于0.05。这说明什么?说明它们根本不协整!别盲目配对,先检验再说。

3. 协整关系的数学定义

好,现在进入正题。协整的数学定义其实不复杂:

如果两个时间序列 \(X_t\) 和 \(Y_t\) 都是 \(d\) 阶单整(记为 \(I(d)\)),且存在一个非零向量 \(\beta\),使得线性组合 \(Z_t = Y_t - \beta X_t\) 是 \(I(d-b)\) 阶单整(其中 \(b > 0\)),那么 \(X_t\) 和 \(Y_t\) 存在协整关系。

翻译成人话:两个非平稳序列,它们的线性组合变成了平稳序列

对于配对交易,我们通常关注 \(d=1\) 的情况:

  • \(X_t\) 和 \(Y_t\) 都是 \(I(1)\)(一阶单整,即一阶差分后平稳)
  • 存在 \(\beta\) 使得 \(Y_t - \beta X_t\) 是 \(I(0)\)(平稳)

这个 \(\beta\) 就是对冲比率,也就是我们常说的“配对系数”。

关键点:协整关系中的 \(\beta\) 是唯一的(在标准化条件下)。这意味着两个序列之间的长期均衡关系是确定的,不会出现“今天用这个系数,明天用那个系数”的情况。这也是配对交易能稳定盈利的理论基础。

4. Engle-Granger两步法:最经典的协整检验方法

说到协整检验,Engle-Granger两步法是我用得最多的方法。它简单、直观,而且效果不错。具体分两步走:

第一步:估计协整回归

用普通最小二乘法(OLS)估计长期均衡关系:

\[ Y_t = \alpha + \beta X_t + \varepsilon_t \]

这里 \(\beta\) 就是我们要的对冲比率。残差 \(\varepsilon_t\) 代表价差。

import statsmodels.api as sm

# 第一步:OLS回归
X = sm.add_constant(stock_a['close'])
model = sm.OLS(stock_b['close'], X).fit()
beta = model.params['close']  # 对冲比率
spread = stock_b['close'] - beta * stock_a['close']  # 价差序列

print(f'对冲比率 β = {beta:.4f}')
print(f'回归R² = {model.rsquared:.4f}')

第二步:检验残差的平稳性

对残差序列 \(\varepsilon_t\) 做ADF检验。如果残差是平稳的,就说明 \(X_t\) 和 \(Y_t\) 存在协整关系。

# 第二步:检验残差平稳性
is_stationary = check_stationarity(spread, '价差序列')

if is_stationary:
    print('✅ 存在协整关系,可以构建配对交易策略')
else:
    print('❌ 不存在协整关系,换个配对试试')

我的建议:Engle-Granger两步法虽然简单,但有个小问题——它假设 \(\beta\) 在样本期内是常数。实际上,这个系数可能会随时间缓慢变化。我一般会滚动窗口估计,比如每60个交易日重新估计一次 \(\beta\),这样更稳健。

5. 一个完整的协整检验流程

把上面的步骤串起来,我通常这样操作:

  1. 数据准备:获取两只股票的历史价格,确保时间对齐
  2. 单整阶数检验:分别对两个序列做ADF检验,确认它们都是 \(I(1)\)
  3. 协整回归:用OLS估计 \(\beta\),计算价差序列
  4. 残差检验:对价差做ADF检验,确认平稳性
  5. 结论判断:如果价差平稳,则存在协整关系;否则放弃

下面这张图是我自己画的协整检验流程图,你可以对照着看:

协整检验流程图 (Engle-Granger两步法) 步骤1:获取两只股票价格序列 步骤2:ADF检验 → 确认均为I(1) 步骤3:OLS回归 → 估计β和价差 步骤4:对价差做ADF检验 p < 0.05? ✅ 存在协整关系 ❌ 不存在协整关系

总结一下:协整理论是配对交易的基石。没有协整,所谓的“价差回归”就是自欺欺人。我见过太多人拿着两个相关性高的股票就做配对,结果亏得一塌糊涂。记住:相关性 ≠ 协整,协整才是硬道理

好了,这一章的内容就到这里。下一章我们会深入讨论如何用协整关系构建实际的交易信号,包括阈值设定、仓位管理这些实战细节。到时候我会分享一些我在实盘中踩过的坑,保证让你少走弯路。

专注资料整理