18. 时间序列深度模型:ARIMA模型、GARCH模型、深度预测
说到市场深度和价格弹性,很多人第一反应是看盘口数据。但说实话,真正的微观结构分析,离不开时间序列建模。为什么?因为市场数据天生就是时间序列——每一笔报价、每一笔成交,都带着时间戳。你没法忽略这个维度。
我个人习惯,在分析订单簿动态时,一定会把时间序列模型作为基准线。ARIMA处理线性趋势,GARCH捕捉波动聚集,深度模型则用来挖掘非线性模式。这三者层层递进,构成了一个完整的预测框架。
核心观点:时间序列建模不是炫技,而是为了回答一个实际问题——给定过去的价格和深度数据,未来几秒或几分钟的流动性会怎么变?
18.1 ARIMA模型:线性趋势的捕捉
ARIMA,全称自回归积分滑动平均模型。名字听着唬人,说白了就是三件事的组合:
- AR(自回归):用过去的值预测当前值。比如,过去5秒的买卖价差,会影响现在的价差。
- I(差分):把非平稳数据变平稳。市场深度数据经常有趋势,差分一次就能去掉。
- MA(滑动平均):用过去的预测误差来修正当前预测。
我在项目中遇到过一个问题:直接用原始深度数据建模,结果残差一直不收敛。后来发现,是因为没有做差分。嗯,这里要注意——ARIMA要求数据平稳,否则预测全是假的。
举个实际例子。假设我们要预测未来5秒的买卖价差(spread)。代码大概长这样:
import pandas as pd
import numpy as np
from statsmodels.tsa.arima.model import ARIMA
# 假设 df 包含时间戳和 spread 列
# 先做平稳性检验
from statsmodels.tsa.stattools import adfuller
result = adfuller(df['spread'].dropna())
print(f'ADF Statistic: {result[0]}')
print(f'p-value: {result[1]}')
# 如果 p-value > 0.05,需要差分
if result[1] > 0.05:
df['spread_diff'] = df['spread'].diff().dropna()
# 用差分后的数据建模
model = ARIMA(df['spread_diff'].dropna(), order=(2,0,1))
else:
model = ARIMA(df['spread'], order=(2,1,1))
model_fit = model.fit()
print(model_fit.summary())
# 预测未来5步
forecast = model_fit.forecast(steps=5)
print(forecast)
我的经验:ARIMA的阶数选择(p,d,q)别靠猜。用AIC或BIC准则自动搜索,省时省力。我一般用pmdarima库的auto_arima函数,效果不错。
18.2 GARCH模型:波动率的聚集效应
ARIMA能预测均值,但市场数据的方差可不是常数。你想想看,大新闻出来的时候,波动率会突然飙升,然后慢慢回落。这就是所谓的波动聚集效应。
GARCH模型就是干这个的。它假设当前的方差,取决于过去的方差和过去的残差平方。说白了,大波动后面往往跟着大波动,小波动后面跟着小波动。
我曾经在回测一个高频策略时,发现ARIMA预测的价差方向是对的,但止损总是被打掉。后来一查,原来是波动率突然放大,模型没捕捉到。加上GARCH之后,止损设置动态调整,回撤直接降了30%。
代码示例:
from arch import arch_model
# 假设 returns 是收益率序列
model_garch = arch_model(returns, vol='Garch', p=1, q=1)
model_garch_fit = model_garch.fit(update_freq=5)
print(model_garch_fit.summary())
# 预测未来5期的波动率
forecast_garch = model_garch_fit.forecast(horizon=5)
print(forecast_garch.variance.iloc[-1])
避坑指南:GARCH模型对异常值非常敏感。我曾经因为一笔错误报价(比如价格突然跳了100个tick),导致模型参数完全偏离。建议先做数据清洗,把明显的异常点去掉。
18.3 深度预测:LSTM与Transformer
ARIMA和GARCH都是线性模型。但市场微观结构里,很多关系是非线性的。比如,订单簿的深度变化和价格弹性之间,可能存在复杂的交互效应。这时候,深度学习就派上用场了。
我个人最常用的是LSTM(长短期记忆网络)。为什么?因为它能记住长期依赖。比如,过去10秒的订单簿状态,可能会影响未来5秒的流动性。LSTM的门控机制,恰好能处理这种时序依赖。
不过要注意,LSTM不是万能的。我见过有人把原始价格直接扔进LSTM,结果过拟合得一塌糊涂。正确的做法是:先做特征工程。把买卖价差、订单簿斜率、成交量加权价格等微观结构指标作为输入。
代码示例(简化版):
import torch
import torch.nn as nn
class LSTMPredictor(nn.Module):
def __init__(self, input_size, hidden_size, num_layers):
super(LSTMPredictor, self).__init__()
self.lstm = nn.LSTM(input_size, hidden_size, num_layers, batch_first=True)
self.fc = nn.Linear(hidden_size, 1) # 预测未来1步的价差
def forward(self, x):
# x shape: (batch, seq_len, input_size)
out, _ = self.lstm(x)
# 取最后一个时间步的输出
out = out[:, -1, :]
out = self.fc(out)
return out
# 假设 X_train 是形状为 (样本数, 时间步长, 特征数) 的张量
model_lstm = LSTMPredictor(input_size=10, hidden_size=64, num_layers=2)
criterion = nn.MSELoss()
optimizer = torch.optim.Adam(model_lstm.parameters(), lr=0.001)
# 训练循环(略)
for epoch in range(100):
optimizer.zero_grad()
outputs = model_lstm(X_train)
loss = criterion(outputs, y_train)
loss.backward()
optimizer.step()
我的建议:别一上来就用Transformer。虽然Transformer在NLP领域很火,但金融时间序列的数据量通常不够大。LSTM在小样本场景下更稳定。如果你有百万级的数据点,再考虑Transformer。
18.4 三种模型的对比与选择
说了这么多,到底该用哪个?我整理了一个对比表,方便你快速决策:
| 模型 | 适用场景 | 优点 | 缺点 |
|---|---|---|---|
| ARIMA | 线性趋势明显的序列(如价差均值回归) | 可解释性强,计算快 | 无法处理非线性、波动聚集 |
| GARCH | 波动率预测(如风险度量、止损设置) | 专门处理异方差性 | 对异常值敏感,参数估计不稳定 |
| LSTM | 复杂非线性模式(如订单簿动态) | 能捕捉长期依赖 | 需要大量数据,调参麻烦 |
实际项目中,我通常这样组合:先用ARIMA做基准预测,再用GARCH修正置信区间,最后用LSTM捕捉残差中的非线性信号。三层叠加,效果往往比单一模型好不少。
18.5 知识体系总览
为了让你更直观地理解这三者的关系,我画了一张图:
从这张图可以看得很清楚:数据从市场深度出发,经过三个不同角度的模型处理,最终汇聚成一个综合预测结果。每个模型解决一个特定问题,缺一不可。
总结一下:ARIMA是地基,GARCH是框架,深度模型是精装修。三者结合,才能构建一个完整的市场深度预测系统。别指望一个模型打天下,那是不现实的。