订单簿预测:利用深度学习预测短期价格走势

FreeGuideOnline 最新 2026-06-23

订单簿预测简介

订单簿(Order Book)是电子化交易市场中所有未成交挂单的实时列表,由买卖双方的限价指令组成。它记录每一档价格上的挂单量,是市场微观结构的核心。订单簿预测试图通过分析订单簿的形态与动态变化,预测短期价格走势,属于高频量化交易中的关键技术。

近年来,深度学习凭借其从高维、非结构化数据中自动提取特征的能力,在这一领域展现出显著优势。本教程将带你从零开始,构建一个基于深度学习的订单簿预测模型,即使你此前没有相关经验,也能逐步掌握完整的构建流程。

你需要准备什么

  • Python 基础知识(熟悉 NumPy 和 Pandas)
  • 基本机器学习概念(损失函数、优化器、过拟合等)
  • 一台带 GPU 的计算机(推荐)或使用 Google Colab
  • 订单簿快照数据集(教程中将使用模拟数据说明原理)

订单簿数据的结构与预处理

理解订单簿快照

典型的订单簿快照包含两层信息:买方挂单(Bid)和卖方挂单(Ask)。Bid 按价格从高到低排列,Ask 按价格从低到高排列。每一档通常包含两个字段:价格(Price)和数量(Size)。通常我们只使用前 N 档数据(例如前 10 档),因为更远档位对短期价格的影响较小。

一个 Level 2 订单簿快照的示例:

Bid Price 10: 100.50, Size: 200
Bid Price 9:  100.45, Size: 350
...
Bid Price 1:  99.80,  Size: 500
Ask Price 1:  100.55, Size: 180
Ask Price 2:  100.60, Size: 220
...
Ask Price 10: 101.10, Size: 90

定义预测目标

短期价格走势预测通常转化为分类问题。常用的目标定义方式有两种:

  • 中间价变动方向:计算快照的中间价 mid = (best_bid + best_ask) / 2,预测未来 k 个 tick(或固定时间间隔后)中间价是上涨、下跌还是持平。
  • 价格跳动分类:预测未来一段时间内中间价的变化幅度是否超过某个阈值。

为了降低噪声并提高实用性,我们常采用 多级水平预测。例如,预测未来 10 个事件(tick)后的中间价变动方向,并定义上涨(标签 2)、持平(标签 1)、下跌(标签 0)。标签平滑(将变动极小的情况归为持平)能有效减少噪声。

特征工程

虽然深度学习能自动学习特征,但输入数据的表示方式仍然关键。将订单簿快照转换为模型输入时,通常采用以下特征:

基础特征(直接使用原始数据)

  • 各档价格与中间价的差值(标准化或相对化)
  • 各档挂单量
  • 买卖不平衡指标:(Bid_Size_1 - Ask_Size_1) / (Bid_Size_1 + Ask_Size_1)
  • 价差(Spread)

衍生特征

  • 订单簿斜率:挂单量随价格的变化率
  • 加权平均价格:按数量加权计算买卖双方的平均挂单价格
  • 深度加权中间价:考虑前几档深度后的调整中间价

时序特征(使用多个连续快照)

深度学习模型擅长处理时序数据,因此我们将多个连续快照堆叠成一个样本。例如,使用过去 10 个快照(每个快照包含 40 维特征:20 个价格+20 个数量)来预测未来标签。

数据预处理流程

  1. 数据清洗:去除明显异常的快照(如价差为负、挂单量为零等)。
  2. 缺失值处理:如果某档不存在挂单,可将价格设为 0 或使用前值填充。
  3. 标准化:对价格相关特征减均值除标准差,或采用相对于中间价的比例,消除不同标的绝对价格差异。
  4. 样本构建:用滑动窗口生成 (历史序列, 未来标签) 的监督学习样本。
  5. 类别平衡:订单簿数据往往极度不平衡(大量持平或微小波动)。可采用下采样、上采样或类别加权损失来应对。
# 示例:构建滑动窗口样本
def build_sequences(data, window_size, horizon):
    X, y = [], []
    for i in range(len(data) - window_size - horizon):
        X.append(data[i : i + window_size])   # 历史窗口
        # 计算未来 horizon 步后的中间价变动标签
        future_mid = data[i + window_size + horizon, :]["mid_price"]
        current_mid = data[i + window_size - 1, :]["mid_price"]
        if future_mid > current_mid * 1.0001:
            label = 2
        elif future_mid < current_mid * 0.9999:
            label = 0
        else:
            label = 1
        y.append(label)
    return np.array(X), np.array(y)

深度学习模型设计

处理订单簿时间序列的模型主流选项有:

  • LSTM / GRU:经典循环网络,适合捕捉时序依赖。
  • CNN(1D / 2D):一维卷积沿时间轴提取模式,二维卷积同时提取时间和特征交互。
  • Transformer:利用自注意力机制建模长期依赖,近年来表现优异。
  • 混合模型:CNN-LSTM、Transformer-CNN 等组合。

我们将重点介绍 CNN-LSTM 混合模型,因其在计算效率和预测性能间取得了良好平衡,适合初学者快速上手。

模型架构详解

模型输入形状为 (window_size, features),例如 (10 个快照, 40 维特征)。

  1. 输入层:接收形状为 (None, window_size, features) 的张量。
  2. 1D 卷积块:两层 Conv1D 用于提取局部时间模式,例如卷积核大小 3,滤波器数量 64。使用 ReLU 激活,并添加 BatchNormalization 和 Dropout 防止过拟合。
  3. 池化层:MaxPooling1D 降低时间维度,保留显著特征。
  4. LSTM 层:堆叠 1~2 层 LSTM,单元数 64 或 128。设置 return_sequences=False 输出最后时刻的隐藏状态,或者使用 Bidirectional 增强。
  5. 全连接层:Dense 层进行分类,输出层神经元数为类别数(3),激活函数 softmax。
from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import Conv1D, MaxPooling1D, LSTM, Dense, Dropout, BatchNormalization, Flatten

def build_cnn_lstm_model(window_size, features, num_classes=3):
    model = Sequential([
        Conv1D(filters=64, kernel_size=3, activation='relu', input_shape=(window_size, features)),
        BatchNormalization(),
        Conv1D(filters=64, kernel_size=3, activation='relu'),
        BatchNormalization(),
        MaxPooling1D(pool_size=2),
        Dropout(0.3),
        LSTM(128, return_sequences=False),
        Dropout(0.3),
        Dense(64, activation='relu'),
        BatchNormalization(),
        Dense(num_classes, activation='softmax')
    ])
    return model

损失函数与优化器

多分类问题使用 分类交叉熵(Categorical Crossentropy)。如果类别不平衡,可以在损失函数中设置 class_weight 参数,或使用 Focal Loss 来聚焦困难样本。

优化器常用 Adam,因其收敛快且对超参数不太敏感。学习率初始可设为 0.001,配合学习率衰减。

评估指标

由于预测任务通常面临类别不平衡,单纯使用准确率会掩盖模型真实表现。应重点关注:

  • F1 分数(宏平均或加权平均)
  • 混淆矩阵:观察各方向的预测正确率和误差分布
  • 收益相关指标:如果模型用于交易,可回测计算夏普比率、最大回撤等,但本教程侧重分类性能本身。

模型训练与调优

训练配置

  • 划分训练集、验证集、测试集(按时间顺序,避免未来信息泄漏)。
  • 批次大小:32 或 64,根据 GPU 内存调整。
  • 早停法(EarlyStopping):监控验证损失,耐心值设为 10~20 个 epoch。
  • 模型检查点(ModelCheckpoint):保存验证损失最低的模型。
  • 学习率衰减:当验证损失停滞时降低学习率。

应对过拟合的技巧

  • Dropout:在卷积层和 LSTM 层后设置 0.3~0.5。
  • L2 正则化:对权重施加惩罚。
  • 数据增强:对订单簿快照进行微小扰动(如加噪声、随机时间偏移),但需谨慎以免破坏结构。
  • 减小模型容量:先从较小网络开始,随数据量增加逐步扩大。

超参数搜索

手动调参或使用 Keras Tuner / Optuna 可优化以下参数:

  • 窗口大小(window_size)
  • 卷积核大小和滤波器数量
  • LSTM 单元数
  • 学习率及衰减策略
  • Dropout 比率

初步实验可固定窗口大小 10~20,重点调查卷积和 LSTM 容量。

从预测到交易信号

模型输出 softmax 概率,代表各方向置信度。转化为交易信号时需设置阈值,避免在低置信度时频繁交易。

示例策略

  • 如果上涨概率 > 0.6 且下跌概率 < 0.2,则发出买入信号。
  • 如果下跌概率 > 0.6 且上涨概率 < 0.2,则发出卖出信号。
  • 其他情况保持不动或平仓。

此外,应结合市场微观结构约束(手续费、滑点、最小变动价位)进行模拟,才能评估真实盈利能力。

常见问题与陷阱

1. 数据窥探(Look-ahead Bias)

确保构建样本时,标签严格在未来信息不可知的时间点定义。窗口右边界不能接触未来数据。

2. 幸存者偏差

使用的历史订单簿数据可能只包含存活下来的标的,忽略退市或合并的资产,导致训练信号过于乐观。

3. 类别不平衡

大部分时刻价格并无明显变动,如果模型总是预测“持平”,准确率可能很高但毫无用处。必须用加权损失或合适的评估指标纠正。

4. 市场状态变化

金融市场非平稳,模型需要定期再训练。可设计在线学习机制,每天或每周用新数据微调模型。

5. 实盘延迟

订单簿高频变化,从捕获快照到模型推理再到下单,中间延迟可能导致信号失效。模型应尽量轻量,特征计算和推理需在微秒级完成。

拓展:先进方法简介

掌握基础方法后,可进一步探索:

  • DeepLOB:专门为订单簿设计的深度架构,结合卷积模块提取局部价格模式,再通过 Inception 模块整合多尺度信息,最后用 LSTM 处理时序。
  • Transformer 方案:将快照序列通过位置编码输入 Transformer 编码器,利用注意力权重捕捉买卖压力变化。
  • 生成对抗模拟:使用 GAN 生成接近真实的订单簿数据,用于扩充训练集或压力测试。
  • 强化学习:把订单簿特征作为状态,直接输出交易动作,由累计收益驱动学习。
  • 多维度融合:加入成交数据(交易量和时间)、新闻情感等其他模态,提升信号稳健性。

小结与下一步

通过本教程,你已经了解了订单簿预测的核心概念、数据处理方法、CNN-LSTM 模型构建及训练技巧。动手实践是掌握该技术的最佳途径。

建议的学习路径

  1. 先获取仿真订单簿数据(如 Lobster 数据集、Bitcoin 订单簿公开数据等)。
  2. 完整实现数据预处理、模型搭建、训练和评估流程。
  3. 调整网络结构和超参数,记录实验日志。
  4. 在回测框架中尝试简单的交易规则,观察实际盈亏。

继续深入,你将能够构建更复杂的模型,并在真实的量化交易环境中部署。祝你在订单簿预测的探索中取得突破!