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检验的完整流程
在实际项目中,我通常按以下步骤操作:
- 可视化检查:先画时间序列图,看是否有明显趋势或季节性
- 确定检验形式:根据图形选择是否包含常数项和趋势项
- 选择滞后阶数:用AIC或BIC自动选择,或者手动尝试
- 执行ADF检验:获取统计量和p值
- 对比临界值:根据样本量和检验形式,查对应的临界值
- 得出结论:如果统计量小于临界值,则序列平稳;否则非平稳
下面我用一个实际案例来演示:
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看看。