时间序列分析基础(上):平稳性检验、ACF/PACF与白噪声检验

各位做量化交易的朋友,大家好。今天我们来聊聊时间序列分析里最基础、也最绕不开的几个概念。说实话,我刚开始做统计套利那会儿,觉得这些理论东西太枯燥,直接上手跑策略。结果呢?回测曲线漂亮得不行,实盘一跑就崩。后来才明白,没做平稳性检验,就像盖楼不打地基

这一节,我们重点搞定三件事:平稳性检验(ADF和KPSS)、自相关函数(ACF)与偏自相关函数(PACF)、白噪声检验。别急,我一个一个说。

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

什么叫平稳?说白了,就是序列的统计性质不随时间变化。均值稳定、方差稳定、协方差只跟时间间隔有关,跟具体时间点无关。

我举个例子。你观察两只股票的价差序列。如果这个价差在0附近来回摆动,偶尔偏离但很快回归——这就是平稳的。如果价差一路走高,或者忽高忽低没个准——那就是非平稳。

为什么这么重要?因为统计套利的核心假设就是价差会均值回归。非平稳序列,你没法用历史规律去预测未来。

1.1 ADF检验:单位根检验的“老大哥”

ADF检验,全称Augmented Dickey-Fuller检验。它的原假设是:序列存在单位根(非平稳)。

怎么用?看p值。p值小于0.05,拒绝原假设,序列平稳。p值大于0.05,不能拒绝,序列非平稳。

我个人习惯,做价差分析时,ADF的p值至少要小于0.01才放心。0.05有时候会误判,尤其样本量不大的时候。

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

# 假设spread是你的价差序列
result = adfuller(spread, autolag='AIC')
print(f'ADF统计量: {result[0]:.4f}')
print(f'p值: {result[1]:.4f}')
if result[1] < 0.05:
    print('序列平稳,可以继续分析')
else:
    print('序列非平稳,需要差分或做其他处理')
我的经验:ADF检验对滞后阶数敏感。我一般用AIC自动选择滞后阶数,别自己瞎设。曾经有一次我手动设了滞后5阶,结果p值0.06,换成AIC自动选变成0.02——差点错过一个好策略。

1.2 KPSS检验:ADF的“互补搭档”

KPSS检验跟ADF正好相反。它的原假设是:序列是平稳的。

所以,ADF + KPSS组合使用,能更准确判断。如果ADF说平稳、KPSS也说平稳,那基本稳了。如果ADF说非平稳、KPSS也说非平稳,那肯定不稳。如果两者矛盾——嗯,数据可能有问题,或者序列有趋势项。

ADF结果 KPSS结果 结论
平稳(p<0.05) 平稳(p>0.05) 序列平稳
非平稳(p>0.05) 非平稳(p<0.05) 序列非平稳
平稳 非平稳 可能有趋势,需去趋势
非平稳 平稳 可能有结构突变
from statsmodels.tsa.stattools import kpss

result_kpss = kpss(spread, regression='c')
print(f'KPSS统计量: {result_kpss[0]:.4f}')
print(f'p值: {result_kpss[1]:.4f}')
注意:KPSS的regression参数要选对。'c'表示只检验均值平稳,'ct'表示检验趋势平稳。我一般先用'c',如果结果不理想再试'ct'。

2. 自相关函数(ACF)与偏自相关函数(PACF)

这两个东西,说白了就是看序列的“记忆性”。

ACF:当前值跟过去某个滞后值之间的相关性。比如今天价差跟昨天价差的相关性,就是滞后1阶的ACF。

PACF:剔除中间滞后项的影响后,当前值跟某个滞后值的相关性。比如剔除昨天的影响后,今天跟昨天的相关性。

为什么重要?因为ACF和PACF的形态,直接告诉你该用AR模型还是MA模型

  • ACF拖尾(缓慢衰减)、PACF截尾(某阶后突然为0)→ 用AR模型
  • ACF截尾、PACF拖尾 → 用MA模型
  • 两者都拖尾 → 用ARMA模型

我记得有一次做股指期货的价差分析,ACF拖了十几阶才衰减到0,PACF在第2阶就截尾了。我当时判断用AR(2)模型,结果拟合效果出奇的好。后来复盘,发现是因为市场微观结构导致短期记忆很强。

from statsmodels.graphics.tsaplots import plot_acf, plot_pacf
import matplotlib.pyplot as plt

fig, (ax1, ax2) = plt.subplots(2, 1, figsize=(10, 6))
plot_acf(spread, lags=20, ax=ax1)
plot_pacf(spread, lags=20, ax=ax2)
plt.show()
核心要点:看ACF/PACF图时,关注那些超出蓝色置信区间的柱子。超出越多,相关性越显著。但别过度解读——偶尔一两个超出可能是随机波动。

3. 白噪声检验:你的序列还有信息吗?

白噪声,就是纯随机序列。均值0,方差恒定,各阶自相关都为0。

为什么要检验白噪声?因为如果残差是白噪声,说明模型已经提取了所有信息。如果残差还有自相关,说明模型没建好,还有模式没捕捉到。

常用的检验方法是Ljung-Box检验。原假设:序列是白噪声(所有自相关系数都为0)。

from statsmodels.stats.diagnostic import acorr_ljungbox

# 检验残差是否为白噪声
lb_test = acorr_ljungbox(residuals, lags=[10, 20, 30], return_df=True)
print(lb_test)

看p值。如果p值都大于0.05,说明残差是白噪声,模型OK。如果某个滞后的p值小于0.05,说明那个滞后还有自相关,模型需要改进。

避坑指南:我曾经建了一个ARMA模型,残差的Ljung-Box检验p值0.04,我觉得差不多就上线了。结果实盘时,策略在特定行情下连续亏损。后来发现,残差在第7阶有个微弱但持续的自相关,正好对应一周的交易周期。从那以后,我要求所有滞后的p值都大于0.1才放心

4. 知识体系总览

下面这张图,是我自己总结的时间序列分析基础流程。每次做策略前,我都会过一遍这个流程。

时间序列分析基础流程 原始时间序列 平稳性检验(ADF + KPSS) 差分/去趋势处理 ACF/PACF分析 模型识别与白噪声检验

这个流程我用了好多年。每次拿到一个新价差序列,先跑ADF和KPSS,确认平稳后看ACF/PACF定阶,最后用Ljung-Box检验残差。一步都不能少。

好了,这一节的内容就这些。平稳性检验、ACF/PACF、白噪声检验,这三个工具是时间序列分析的基石。你想想看,如果连序列稳不平稳都不知道,后面建再多模型也是白搭。

下一节我们会继续深入,讲ARMA模型的参数估计和模型选择。到时候再聊。


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