17、机器学习辅助基差预测:特征工程构建、LSTM时序预测、XGBoost信号增强

基差预测这件事,做久了你会发现一个规律:传统统计模型能解释的东西,其实很有限。我刚开始做基差交易那几年,全靠ARIMA和GARCH硬扛,效果嘛...只能说勉强糊口。后来我把机器学习引进来,才真正打开了新世界的大门。

这一章,我就跟你聊聊怎么用机器学习来辅助基差预测。说白了,就是把特征工程、LSTM时序预测、XGBoost信号增强这三板斧用好。嗯,内容有点干,但都是实战经验。

17.1 特征工程:基差预测的"原材料"

机器学习圈有句老话:数据和特征决定了上限,模型只是逼近这个上限。我个人非常认同。你想想看,基差预测的特征工程,其实比选模型更重要。

17.1.1 基础特征分类

我习惯把特征分成三大类:

  • 价格类特征:现货价格、期货价格、近远月价差、跨品种价差
  • 基本面特征:库存数据、仓单数量、持仓量、成交量、基差率
  • 衍生特征:滚动窗口统计量(均值、标准差、偏度)、技术指标(RSI、MACD、布林带)

举个例子,我在做螺纹钢基差预测时,发现库存变化率这个特征特别重要。库存一降,基差往往就拉大。但如果你只看库存绝对值,效果反而不好。为什么?因为市场交易的是预期,不是现状。

核心原则:特征要反映"变化"和"预期",而不是"状态"。

17.1.2 时序特征构造技巧

这里我分享几个实战中验证过的技巧:

  1. 滞后特征:基差本身有自相关性,lag(1)到lag(5)是标配
  2. 差分特征:一阶差分能消除趋势,二阶差分能捕捉加速度
  3. 滚动统计:过去N天的均值、最大值、最小值、波动率
  4. 日历特征:交割月倒数天数、星期几、是否临近交割

我的习惯:每次加新特征前,先做一次相关性分析。如果两个特征相关系数超过0.8,我会考虑只保留一个。不然模型容易过拟合。

17.2 LSTM时序预测:让模型"记住"基差的节奏

传统的时间序列模型,比如ARIMA,有个硬伤:它假设当前值只跟过去有限步有关。但基差这东西,有时候会受很久以前的事件影响。比如一次政策调整,可能影响未来三个月的基差走势。

LSTM(长短期记忆网络)正好能解决这个问题。它的核心优势就是能记住长期依赖关系

17.2.1 LSTM模型结构

我画了一张图,帮你理解LSTM是怎么处理基差数据的:

LSTM基差预测流程 输入特征序列 LSTM单元 (遗忘门/输入门/输出门) LSTM单元 (遗忘门/输入门/输出门) LSTM单元 (遗忘门/输入门/输出门) 全连接层 基差预测值 t-n, ..., t-1 时间步展开

你看这个结构,输入的是过去N天的特征序列,每个时间步对应一个LSTM单元。这些单元之间会传递"细胞状态",也就是长期记忆。我刚开始用LSTM时,总担心它过拟合,后来发现只要数据量够(至少1000个样本以上),效果确实比传统模型好。

17.2.2 实战代码示例

下面是我在项目中常用的LSTM预测代码框架:

import numpy as np
import pandas as pd
from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import LSTM, Dense, Dropout
from sklearn.preprocessing import MinMaxScaler

# 数据准备
def create_sequences(data, seq_length=20):
    X, y = [], []
    for i in range(len(data) - seq_length):
        X.append(data[i:i+seq_length])
        y.append(data[i+seq_length, 0])  # 预测基差
    return np.array(X), np.array(y)

# 构建模型
model = Sequential([
    LSTM(64, return_sequences=True, input_shape=(seq_length, n_features)),
    Dropout(0.2),
    LSTM(32, return_sequences=False),
    Dropout(0.2),
    Dense(16, activation='relu'),
    Dense(1)
])

model.compile(optimizer='adam', loss='mse')
model.fit(X_train, y_train, epochs=50, batch_size=32, validation_split=0.2)

避坑指南:我曾经在LSTM的序列长度上吃过亏。序列太短(比如5天),模型学不到长期规律;序列太长(比如60天),训练速度慢且容易过拟合。我个人建议从20天开始调参,效果比较均衡。

17.3 XGBoost信号增强:给预测结果"上保险"

LSTM预测出来的基差,说实话,有时候会"飘"。尤其是在市场结构发生突变时,LSTM的反应会慢半拍。这时候,XGBoost就派上用场了。

我的做法是:用XGBoost对LSTM的预测结果进行二次修正。说白了,就是让两个模型互相验证。

17.3.1 信号增强的逻辑

具体流程是这样的:

  1. LSTM输出基差预测值,记为 pred_lstm
  2. 提取当前时刻的强信号特征(比如库存变化、持仓量异动、基差偏离度)
  3. pred_lstm 和这些特征一起输入XGBoost
  4. XGBoost输出最终的基差预测值

你可能会问:为什么不直接用XGBoost做预测?嗯,这里有个关键点:LSTM擅长捕捉时序依赖,XGBoost擅长处理非线性特征交互。两者结合,效果是1+1>2。

17.3.2 XGBoost特征工程

我在XGBoost阶段,会额外加入一些"事件型"特征:

特征名称 计算方式 作用
基差偏离度 (当前基差 - 历史均值) / 历史标准差 识别极端行情
持仓量异动 当前持仓量 / 过去5日均值 - 1 捕捉资金动向
库存变化率 (当前库存 - 上周库存) / 上周库存 基本面驱动
LSTM置信度 1 / (1 + 预测方差) 模型自身信心

17.3.3 实战代码示例

import xgboost as xgb
from sklearn.model_selection import train_test_split

# 准备XGBoost的输入特征
# features: [pred_lstm, 基差偏离度, 持仓量异动, 库存变化率, LSTM置信度]
X_xgb = np.column_stack([
    pred_lstm,          # LSTM预测值
    basis_deviation,    # 基差偏离度
    position_change,    # 持仓量异动
    inventory_change,   # 库存变化率
    lstm_confidence     # LSTM置信度
])

# 训练XGBoost
model_xgb = xgb.XGBRegressor(
    n_estimators=200,
    max_depth=5,
    learning_rate=0.05,
    subsample=0.8,
    colsample_bytree=0.8
)

model_xgb.fit(X_train, y_train)

# 特征重要性分析
importance = model_xgb.feature_importances_
print(f"特征重要性: {importance}")

我的经验:XGBoost的max_depth不要设太大,3-5就够。太深了容易记住噪声。另外,subsample设0.8左右,能增加模型的鲁棒性。

17.4 整体流程与回测验证

把上面这些串起来,完整的基差预测流程是这样的:

  1. 数据采集:获取现货、期货、库存、持仓等数据
  2. 特征工程:构造基础特征 + 时序特征 + 事件特征
  3. LSTM训练:用历史序列预测基差
  4. XGBoost增强:用LSTM输出 + 强信号特征做二次修正
  5. 信号生成:根据最终预测值生成交易信号
  6. 回测验证:检验策略的夏普比率、最大回撤等指标

我记得有一次,纯LSTM策略的回测夏普只有0.8,加上XGBoost增强后,直接跳到了1.4。你想想看,这个提升幅度有多大。

核心总结:LSTM负责"时序记忆",XGBoost负责"特征交互"。两者结合,才是基差预测的完整解法。

嗯,这一章的内容就到这里。机器学习辅助基差预测,说白了就是让模型帮你做两件事:记住过去,理解当下。如果你能把特征工程做好,LSTM和XGBoost调参到位,基差预测的准确率会有质的飞跃。


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