第四章 时间序列分析基础(下):ARIMA模型建模全流程

好,咱们接着聊。上一章我们把时间序列的平稳性、白噪声这些基础概念捋了一遍。这一章,我带你走一遍ARIMA模型的完整建模流程。说白了,就是给你一套标准动作,照着做,基本不会跑偏。

核心逻辑:ARIMA建模不是玄学,是一套可复现的工程流程。我个人的习惯是:先看数据长什么样,再决定用什么模型,最后反复验证模型靠不靠谱。

ARIMA建模流程 1. 数据预处理 缺失值·异常值·对数变换 2. 平稳性检验 ADF检验·KPSS检验 3. 差分处理 确定d值 4. 模型定阶 ACF/PACF·AIC/BIC 5. 模型拟合 ARIMA(p,d,q) 参数估计 6. 模型诊断 残差白噪声检验·Q-Q图·Ljung-Box 不通过则重新定阶 7. 模型应用:预测与交易信号生成

4.1 数据预处理——别让脏数据毁了你的模型

拿到股票价格序列,第一件事不是跑模型,而是先看看数据干不干净。我在做统计套利策略时,遇到过好几次因为数据没处理好,导致回测结果漂亮得离谱,实盘却一塌糊涂的惨案。

具体来说,你需要检查这几项:

  • 缺失值处理:停牌日、节假日会导致数据缺失。我一般用前向填充(ffill),或者直接删除。千万别用均值填充,那会引入未来信息。
  • 异常值识别:比如某天价格突然跳空,可能是数据错误。用3倍标准差法或者IQR法都能筛出来。
  • 对数变换:价格序列通常有异方差性——价格越高,波动越大。取对数能稳定方差,这是标准做法。

我的经验:对数收益率比原始价格更适合建模。原因很简单——对数收益率近似正态分布,而且具有可加性。我几乎从不对原始价格直接跑ARIMA,除非是平稳的价差序列。

4.2 平稳性检验——不平稳就别往下走了

ARIMA模型要求数据平稳。什么叫平稳?均值、方差、自协方差都不随时间变化。说白了,就是数据没有明显的趋势和季节性。

检验方法主要有两种:

检验方法 原假设 什么时候用
ADF检验 序列存在单位根(不平稳) 最常用,p值小于0.05则拒绝原假设
KPSS检验 序列平稳 与ADF互补,两者结合判断更可靠

我个人习惯两个检验都做。如果ADF说平稳,KPSS也说平稳,那基本稳了。如果结果矛盾,我会更相信ADF的结果——它在实践中表现更稳定。

4.3 差分处理——让非平稳变平稳

如果数据不平稳,怎么办?差分。一阶差分就是今天的值减去昨天的值。对于股票价格,一阶差分通常就能得到平稳序列——也就是收益率序列。

怎么确定差分阶数d?

  • 画图看:差分后的序列是否围绕0均值波动
  • ADF检验:差分后p值小于0.05
  • 经验法则:金融数据d最多取1或2,取多了会丢失信息

注意:过度差分是个坑。我曾经为了追求完美平稳性,对某只股票做了三阶差分,结果模型预测出来的全是噪声。记住,差分是为了消除趋势,不是为了消灭所有波动。

4.4 模型定阶——AIC/BIC准则帮你做选择

定阶就是确定p(自回归阶数)和q(移动平均阶数)。有两种方法:

方法一:看图法

  • ACF图(自相关函数):如果拖尾,考虑AR模型;如果截尾,考虑MA模型
  • PACF图(偏自相关函数):如果截尾,考虑AR模型;如果拖尾,考虑MA模型

方法二:信息准则法

AIC(赤池信息准则)和BIC(贝叶斯信息准则)是更客观的方法。公式我就不写了,你只需要知道:

  • AIC:倾向于选择更复杂的模型(参数更多)
  • BIC:对复杂模型惩罚更重,倾向于选择更简洁的模型
  • 两者都是越小越好

实际中怎么做?我通常用网格搜索,遍历p和q从0到5的所有组合,选AIC或BIC最小的那个。Python的pmdarima库有auto_arima函数,一键搞定。

# 自动定阶示例
from pmdarima import auto_arima

model = auto_arima(price_log_diff, 
                   start_p=0, max_p=5,
                   start_q=0, max_q=5,
                   seasonal=False,
                   trace=True,
                   error_action='ignore',
                   suppress_warnings=True,
                   stepwise=True)

print(model.summary())

4.5 模型诊断——残差必须是白噪声

模型建好了,别急着用。先做诊断。诊断的核心就一句话:残差必须是白噪声

什么意思?残差里不能有任何可预测的模式。如果残差还有自相关性,说明模型没把信息提取干净,需要重新定阶。

诊断工具:

  • 残差图:看是否围绕0随机波动,有没有明显的模式
  • Q-Q图:检查残差是否正态分布(虽然不是必须的,但正态性有助于区间估计)
  • Ljung-Box检验:统计检验残差的自相关性。p值大于0.05,说明残差是白噪声

避坑指南:我曾经在诊断阶段偷懒,看到残差图还行就直接用了。结果实盘时模型频繁失效。后来仔细一查,残差在特定时间段(比如财报发布前后)有明显的自相关性。所以,Ljung-Box检验一定要做,而且要分时段做。

4.6 实战:用Python对股票价格序列建模

好了,理论说完了,咱们动手。下面是一个完整的建模流程,我用的是某只股票的日收盘价。

import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
from statsmodels.tsa.stattools import adfuller
from statsmodels.graphics.tsaplots import plot_acf, plot_pacf
from statsmodels.tsa.arima.model import ARIMA
from statsmodels.stats.diagnostic import acorr_ljungbox

# 1. 加载数据
df = pd.read_csv('stock_price.csv', index_col='date', parse_dates=True)
price = df['close']

# 2. 对数变换 + 一阶差分
log_price = np.log(price)
log_return = log_price.diff().dropna()

# 3. 平稳性检验
adf_result = adfuller(log_return)
print(f'ADF p-value: {adf_result[1]:.4f}')  # 应该小于0.05

# 4. 画ACF和PACF图
fig, (ax1, ax2) = plt.subplots(2, 1, figsize=(10, 6))
plot_acf(log_return, lags=20, ax=ax1)
plot_pacf(log_return, lags=20, ax=ax2)
plt.show()

# 5. 拟合ARIMA模型(假设看图定阶为p=2, d=1, q=2)
model = ARIMA(log_price, order=(2, 1, 2))
result = model.fit()
print(result.summary())

# 6. 模型诊断
residuals = result.resid
lb_test = acorr_ljungbox(residuals, lags=[10, 20, 30], return_df=True)
print(lb_test)  # p值应大于0.05

# 7. 预测
forecast = result.forecast(steps=5)
print(forecast)

这段代码基本覆盖了从数据预处理到预测的全流程。你跑一遍,看看结果。如果Ljung-Box检验的p值小于0.05,说明模型没通过诊断,回去重新定阶。

一个小技巧:如果你发现模型总是通不过诊断,试试把p和q的范围扩大。有时候金融数据的记忆性比我们想象的要长。我遇到过需要p=7才能把残差中的自相关性消除干净的案例。

4.7 模型应用:从预测到交易信号

模型建好了,怎么用?在统计套利中,ARIMA模型通常用来预测价差的短期走势。比如:

  • 预测下一期的价差
  • 如果预测值偏离当前值超过某个阈值,生成交易信号
  • 结合协整关系,做配对交易

但记住一点:ARIMA模型擅长短期预测,别指望它能预测一个月后的价格。我一般只用它预测未来1-3个交易日。

好了,这一章的内容就到这儿。ARIMA建模的流程你记住了吗?预处理→平稳性检验→差分→定阶→拟合→诊断→应用。每一步都有坑,但每一步也都有解法。多练几次,你就能找到感觉。

最后说一句:模型诊断这一步,千万别跳过。我见过太多人建完模型就直接拿去交易,结果亏得一塌糊涂。记住,残差必须是白噪声——这是底线。


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