13、订单簿预测模型:使用 LSTM/Transformer 预测未来价格、模型评估

好,咱们终于聊到预测模型了。

前面几章我们把订单簿的数据结构、特征工程、微观结构信号都捋了一遍。说白了,那些都是在为这一步做准备——用深度学习模型去预测未来的价格走势。

我个人习惯把这件事分成两个阶段:特征序列化模型建模。今天重点讲后者,但前者同样关键。

13.1 为什么是 LSTM 和 Transformer?

订单簿数据本质上是一个多变量时间序列。每一时刻,我们有买一价、卖一价、买一量、卖一量、深度斜率、订单不平衡度……几十个特征。

传统的时间序列模型(ARIMA、GARCH)处理不了这么复杂的非线性关系。而 LSTM 和 Transformer 正好擅长这个。

  • LSTM:擅长捕捉长短期依赖,对序列顺序敏感。适合订单簿这种“先有挂单、后有成交”的因果结构。
  • Transformer:通过自注意力机制,能同时关注序列中任意两个位置的关系。适合捕捉订单簿中“远距离的挂单变化对当前价格的影响”。
我的经验: 如果数据量在 10 万条以下,LSTM 往往更稳。Transformer 虽然上限高,但需要更多数据才能发挥优势。我曾经在一个小币种上试过 Transformer,结果过拟合得一塌糊涂……后来换成双层 LSTM,效果反而更好。

13.2 数据准备:滑动窗口与标签构造

模型不能直接吃原始订单簿。我们需要构造样本

具体做法是:

  1. 取过去 T 个时间步的特征序列,作为输入 X。
  2. 取未来 K 个时间步的价格变化方向或幅度,作为标签 y。
  3. 用滑动窗口在时间轴上滚动,生成大量样本。

举个例子:

# 假设 features 是形状为 (N, F) 的 numpy 数组
# N 是时间步数,F 是特征数
# T = 60(用过去 60 步预测)
# K = 5(预测未来 5 步的价格变化)

def create_samples(features, prices, T=60, K=5):
    X, y = [], []
    for i in range(T, len(features) - K):
        X.append(features[i-T:i])
        # 标签:未来 K 步的平均价格变化
        future_return = (prices[i+K] - prices[i]) / prices[i]
        y.append(future_return)
    return np.array(X), np.array(y)
注意: 千万不要用未来信息构造特征!比如用 t+1 时刻的订单簿去预测 t+1 的价格,那是作弊。我见过有人犯这个错,模型在回测上表现完美,实盘一跑就崩。

13.3 LSTM 模型搭建

LSTM 的结构其实不复杂。我一般用两层 LSTM + 一层全连接输出。

import torch
import torch.nn as nn

class OrderBookLSTM(nn.Module):
    def __init__(self, input_dim, hidden_dim=64, num_layers=2):
        super().__init__()
        self.lstm = nn.LSTM(
            input_size=input_dim,
            hidden_size=hidden_dim,
            num_layers=num_layers,
            batch_first=True,
            dropout=0.2
        )
        self.fc = nn.Linear(hidden_dim, 1)  # 输出未来价格变化

    def forward(self, x):
        # x shape: (batch, T, input_dim)
        out, (h_n, c_n) = self.lstm(x)
        # 取最后一个时间步的输出
        last_out = out[:, -1, :]
        pred = self.fc(last_out)
        return pred

这里有几个关键点:

  • batch_first=True:让输入形状为 (batch, seq_len, features),更符合直觉。
  • dropout=0.2:防止过拟合。订单簿数据噪声大,不加 dropout 很容易学偏。
  • 取最后一个时间步:因为我们只关心“看完所有历史后”的预测。

13.4 Transformer 模型搭建

Transformer 的核心是自注意力。对于订单簿数据,我习惯用编码器部分,把序列编码成一个向量,然后接一个全连接层输出。

class OrderBookTransformer(nn.Module):
    def __init__(self, input_dim, d_model=64, nhead=4, num_layers=2):
        super().__init__()
        self.embedding = nn.Linear(input_dim, d_model)
        self.pos_encoder = PositionalEncoding(d_model)  # 需要自己实现
        encoder_layer = nn.TransformerEncoderLayer(
            d_model=d_model,
            nhead=nhead,
            dim_feedforward=256,
            dropout=0.1,
            batch_first=True
        )
        self.transformer = nn.TransformerEncoder(encoder_layer, num_layers=num_layers)
        self.fc = nn.Linear(d_model, 1)

    def forward(self, x):
        x = self.embedding(x)
        x = self.pos_encoder(x)
        x = self.transformer(x)
        # 取全局平均池化或最后一个位置
        x = x.mean(dim=1)  # 全局平均池化
        return self.fc(x)
为什么用全局平均池化而不是取最后一个位置? 订单簿中,不同时间步的重要性可能不同。全局平均池化让模型自己决定关注哪些位置。我试过两种方式,平均池化在大多数情况下更稳定。

13.5 模型评估:不只是看 Loss

很多人训练完模型只看训练集和验证集的 loss,觉得 loss 降下来就万事大吉。嗯,这里要注意——对于交易模型,loss 低不代表能赚钱

我一般会做以下几项评估:

评估指标 说明 我的经验阈值
MSE / MAE 预测值与真实值的误差 相对 MSE < 0.001 算不错
方向准确率 预测涨跌方向是否正确 > 55% 就有交易价值
夏普比率(模拟交易) 用预测信号做简单策略的回测 > 1.5 才考虑实盘
最大回撤 模拟交易中的最大亏损幅度 < 10% 才安全

我曾经有一个 LSTM 模型,MSE 低得惊人,但方向准确率只有 51%。说白了,它只是学会了预测“价格不变”,因为大部分时间价格确实没怎么动。这种模型毫无意义。

13.6 避坑指南

做订单簿预测模型,有几个坑我踩过,分享给你:

  • 数据泄露:前面提过,不要用未来信息。还有一个常见错误——用整个数据集做归一化。应该用滑动窗口的方式,只基于历史数据做归一化。
  • 标签选择:预测未来 1 步还是 10 步?我建议从短周期开始(1-3 步),模型更容易学到信号。长周期预测噪声太大。
  • 过拟合:订单簿数据特征多、样本相对少,很容易过拟合。我习惯用早停法(early stopping)和权重衰减(weight decay)。
  • 交易成本:模型预测准确率 60% 看起来很牛,但扣除手续费和滑点后可能还是亏的。评估时一定要把交易成本算进去。
一个小技巧: 训练时用“方向准确率”作为早停的监控指标,而不是 loss。因为 loss 下降不一定代表方向预测变准。我试过几次,效果确实更好。

13.7 核心逻辑框架图

下面这张图总结了订单簿预测模型的完整流程:

订单簿预测模型核心流程 原始订单簿数据 特征工程 + 滑动窗口 LSTM 模型 Transformer 模型 价格预测输出 模型评估(方向准确率/夏普)

这张图把整个流程串起来了。从原始数据到特征工程,再到模型选择(LSTM 或 Transformer),最后输出预测并进行评估。你想想看,每一步都有坑,但每一步也都有优化空间。

13.8 小结

订单簿预测模型不是银弹。它只是一个工具,帮你从历史数据中提取统计规律。真正赚钱的,是你如何利用这些预测信号去构建交易策略。

我个人建议:先用 LSTM 跑通全流程,再尝试 Transformer。不要一上来就追求最复杂的模型。简单模型跑通了,你才知道问题出在数据上还是模型上。

记住一句话: 模型预测准确率 55% 加上好的风控,比 70% 准确率但没有风控要赚钱得多。