ADF检验原理:数学原理、滞后阶数选择与临界值解读

各位同学,今天我们进入协整检验的核心环节——ADF检验。说实话,很多人在做量化策略时,一上来就搞回归、算残差,结果发现全是伪回归。我早期做CTA策略时就吃过这个亏,后来才老老实实把ADF检验补上。今天咱们就把这个原理彻底讲透。

一、ADF检验的数学原理

ADF检验,全称是Augmented Dickey-Fuller检验。它要解决的核心问题很简单:一个时间序列是不是平稳的?

我们先从最基础的DF检验说起。DF检验的回归方程是:

Δy_t = α + βt + γy_{t-1} + ε_t

其中,Δy_t = y_t - y_{t-1}。检验的原假设H0是γ=0,也就是序列存在单位根,非平稳。备择假设H1是γ<0,序列平稳。

但DF检验有个致命缺陷——它假设残差ε_t是白噪声。我实际项目中遇到的情况是,金融时间序列往往存在自相关,比如日收益率数据经常有滞后效应。这时候直接用DF检验,检验统计量会严重偏误。

ADF检验的改进就在于:在回归方程中加入滞后差分项,来消除残差的自相关。它的完整形式是:

Δy_t = α + βt + γy_{t-1} + δ₁Δy_{t-1} + δ₂Δy_{t-2} + ... + δ_pΔy_{t-p} + ε_t

这里p就是滞后阶数。γ仍然是我们要检验的核心系数。检验统计量是t统计量:

t_γ = γ̂ / SE(γ̂)

但这个t统计量不服从标准的t分布,而是服从Dickey-Fuller分布。所以我们需要查专门的临界值表。

核心要点:ADF检验本质上是在控制自相关的前提下,检验时间序列是否含有单位根。它比DF检验更稳健,尤其适合金融数据。

二、滞后阶数选择——这个坑我踩过

滞后阶数p的选择,是ADF检验中最容易出问题的地方。我刚开始做策略时,随便选了个p=5,结果检验结果时稳时不稳,折腾了好久才发现是滞后阶数没选对。

选择滞后阶数,主要有两种方法:

方法1:信息准则法

常用的有AIC(赤池信息准则)和BIC(贝叶斯信息准则)。公式如下:

AIC = -2ln(L) + 2k
BIC = -2ln(L) + k·ln(n)

其中L是似然函数值,k是参数个数,n是样本量。我个人习惯用BIC,因为它对参数数量惩罚更重,不容易过拟合。在量化策略中,样本量通常有限,BIC往往更可靠。

方法2:序列相关检验法

从较大的滞后阶数开始,逐步减少,直到残差不再存在自相关。可以用Ljung-Box检验来判断残差是否白噪声。

我一般这样操作:

# Python代码示例
import statsmodels.api as sm
from statsmodels.tsa.stattools import adfuller

# 假设data是价格序列
result = adfuller(data, autolag='AIC')
print(f'ADF统计量: {result[0]:.4f}')
print(f'p值: {result[1]:.4f}')
print(f'滞后阶数: {result[2]}')
print(f'样本量: {result[3]}')
print(f'临界值: {result[4]}')

这里autolag参数可以设为'AIC'或'BIC',让函数自动选择最优滞后阶数。我建议新手先用自动选择,等熟悉了再手动调整。

我的经验:对于日频数据,滞后阶数通常在5-20之间。如果数据频率更高(比如分钟级),滞后阶数可能需要更大。我曾经处理过5分钟高频数据,最后选了30阶才把自相关消除干净。

三、临界值解读——别被p值骗了

ADF检验的临界值,和标准t分布不一样。它依赖于三个因素:

  • 检验形式:是否包含常数项和趋势项
  • 样本量:样本量越小,临界值越宽
  • 显著性水平:1%、5%、10%

常见的临界值表如下(样本量较大时):

检验形式 1%临界值 5%临界值 10%临界值
无常数、无趋势 -2.58 -1.95 -1.62
有常数、无趋势 -3.43 -2.86 -2.57
有常数、有趋势 -3.96 -3.41 -3.13

解读规则很简单:如果ADF统计量小于临界值(更负),则拒绝原假设,认为序列平稳。

举个例子,假设我们检验某只股票的对数价格序列,ADF统计量是-1.23,5%临界值是-2.86。因为-1.23 > -2.86,所以不能拒绝原假设,序列非平稳。

避坑指南:我曾经犯过一个错误——只看p值不看临界值。有一次p值是0.045,刚好小于0.05,我以为序列平稳了。但后来发现样本量只有30个,临界值应该用更严格的。所以,小样本下一定要查专门的临界值表,不能依赖渐近分布。

四、ADF检验的完整流程

在实际项目中,我通常按以下步骤操作:

  1. 可视化检查:先画时间序列图,看是否有明显趋势或季节性
  2. 确定检验形式:根据图形选择是否包含常数项和趋势项
  3. 选择滞后阶数:用AIC或BIC自动选择,或者手动尝试
  4. 执行ADF检验:获取统计量和p值
  5. 对比临界值:根据样本量和检验形式,查对应的临界值
  6. 得出结论:如果统计量小于临界值,则序列平稳;否则非平稳

下面我用一个实际案例来演示:

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

# 生成一个随机游走序列(非平稳)
np.random.seed(42)
n = 200
random_walk = np.cumsum(np.random.randn(n))

# 执行ADF检验
result = adfuller(random_walk, autolag='BIC')

print('ADF检验结果:')
print(f'统计量: {result[0]:.4f}')
print(f'p值: {result[1]:.4f}')
print(f'滞后阶数: {result[2]}')
print(f'样本量: {result[3]}')
print('临界值:')
for key, value in result[4].items():
    print(f'  {key}: {value:.4f}')

# 判断
if result[0] < result[4]['5%']:
    print('结论:在5%显著性水平下,序列平稳')
else:
    print('结论:在5%显著性水平下,序列非平稳')

运行这段代码,你会发现随机游走序列的ADF统计量通常在-1到0之间,远大于-2.86的临界值,所以判断为非平稳。这符合我们的预期。

记住:ADF检验只是第一步。在协整检验中,我们通常是对回归残差做ADF检验,而不是对原始价格序列。这一点很多新手会搞混。我们下一节会详细讲这个。

五、ADF检验的局限性

没有完美的检验方法。ADF检验也有几个明显的短板:

  • 检验功效较低:当序列接近单位根(比如γ=-0.95)时,ADF检验很难区分平稳和非平稳
  • 对结构突变敏感:如果序列在某个时间点发生了结构性变化,ADF检验可能误判
  • 滞后阶数选择主观:不同准则可能给出不同结果,需要结合业务判断

我个人的做法是:ADF检验作为主要参考,同时结合KPSS检验(原假设是平稳)做交叉验证。如果两个检验结论一致,那基本就稳了。如果矛盾,就需要进一步分析数据特征。

好了,ADF检验的原理就讲到这里。记住,检验只是工具,真正的功夫在于理解你的数据。下次遇到非平稳序列,别慌,先跑个ADF看看。


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