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(波动聚集) 深度预测(非线性) 价差均值预测 波动率区间估计 订单簿动态预测 综合预测结果

从这张图可以看得很清楚:数据从市场深度出发,经过三个不同角度的模型处理,最终汇聚成一个综合预测结果。每个模型解决一个特定问题,缺一不可。

总结一下:ARIMA是地基,GARCH是框架,深度模型是精装修。三者结合,才能构建一个完整的市场深度预测系统。别指望一个模型打天下,那是不现实的。


无相订单流研究社 微信Lucian808555