17、机器学习辅助基差预测:特征工程构建、LSTM时序预测、XGBoost信号增强
基差预测这件事,做久了你会发现一个规律:传统统计模型能解释的东西,其实很有限。我刚开始做基差交易那几年,全靠ARIMA和GARCH硬扛,效果嘛...只能说勉强糊口。后来我把机器学习引进来,才真正打开了新世界的大门。
这一章,我就跟你聊聊怎么用机器学习来辅助基差预测。说白了,就是把特征工程、LSTM时序预测、XGBoost信号增强这三板斧用好。嗯,内容有点干,但都是实战经验。
17.1 特征工程:基差预测的"原材料"
机器学习圈有句老话:数据和特征决定了上限,模型只是逼近这个上限。我个人非常认同。你想想看,基差预测的特征工程,其实比选模型更重要。
17.1.1 基础特征分类
我习惯把特征分成三大类:
- 价格类特征:现货价格、期货价格、近远月价差、跨品种价差
- 基本面特征:库存数据、仓单数量、持仓量、成交量、基差率
- 衍生特征:滚动窗口统计量(均值、标准差、偏度)、技术指标(RSI、MACD、布林带)
举个例子,我在做螺纹钢基差预测时,发现库存变化率这个特征特别重要。库存一降,基差往往就拉大。但如果你只看库存绝对值,效果反而不好。为什么?因为市场交易的是预期,不是现状。
核心原则:特征要反映"变化"和"预期",而不是"状态"。
17.1.2 时序特征构造技巧
这里我分享几个实战中验证过的技巧:
- 滞后特征:基差本身有自相关性,lag(1)到lag(5)是标配
- 差分特征:一阶差分能消除趋势,二阶差分能捕捉加速度
- 滚动统计:过去N天的均值、最大值、最小值、波动率
- 日历特征:交割月倒数天数、星期几、是否临近交割
我的习惯:每次加新特征前,先做一次相关性分析。如果两个特征相关系数超过0.8,我会考虑只保留一个。不然模型容易过拟合。
17.2 LSTM时序预测:让模型"记住"基差的节奏
传统的时间序列模型,比如ARIMA,有个硬伤:它假设当前值只跟过去有限步有关。但基差这东西,有时候会受很久以前的事件影响。比如一次政策调整,可能影响未来三个月的基差走势。
LSTM(长短期记忆网络)正好能解决这个问题。它的核心优势就是能记住长期依赖关系。
17.2.1 LSTM模型结构
我画了一张图,帮你理解LSTM是怎么处理基差数据的:
你看这个结构,输入的是过去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 信号增强的逻辑
具体流程是这样的:
- LSTM输出基差预测值,记为
pred_lstm - 提取当前时刻的强信号特征(比如库存变化、持仓量异动、基差偏离度)
- 将
pred_lstm和这些特征一起输入XGBoost - 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 整体流程与回测验证
把上面这些串起来,完整的基差预测流程是这样的:
- 数据采集:获取现货、期货、库存、持仓等数据
- 特征工程:构造基础特征 + 时序特征 + 事件特征
- LSTM训练:用历史序列预测基差
- XGBoost增强:用LSTM输出 + 强信号特征做二次修正
- 信号生成:根据最终预测值生成交易信号
- 回测验证:检验策略的夏普比率、最大回撤等指标
我记得有一次,纯LSTM策略的回测夏普只有0.8,加上XGBoost增强后,直接跳到了1.4。你想想看,这个提升幅度有多大。
核心总结:LSTM负责"时序记忆",XGBoost负责"特征交互"。两者结合,才是基差预测的完整解法。
嗯,这一章的内容就到这里。机器学习辅助基差预测,说白了就是让模型帮你做两件事:记住过去,理解当下。如果你能把特征工程做好,LSTM和XGBoost调参到位,基差预测的准确率会有质的飞跃。
公众号:蓝海资料掘金营,微信deep3321