第十一章:基差交易的策略优化(二)——基于机器学习的基差预测模型

上一章我们聊了传统统计方法做基差预测。说实话,那些方法在行情平稳时挺好用。但市场一波动,模型就崩了。我2019年做铜的基差交易时就吃过这个亏——ARIMA模型在震荡市里预测得挺准,结果行情突变,直接把我套进去了。

后来我开始尝试机器学习。效果嘛,确实比传统方法好不少。今天我就把这几年的实战经验梳理一下,讲讲怎么用机器学习来预测基差。

为什么传统方法不够用?

传统时间序列模型有个硬伤——它假设数据是线性的。你想想看,基差受多少因素影响?库存、到港量、交割规则、资金成本、市场情绪...这些因素之间还有交互作用。线性模型根本抓不住这种复杂关系。

我记得有一次做螺纹钢的基差分析,库存数据明明在下降,按道理基差应该走强。结果基差反而跌了。后来一查,是某大厂突然检修,市场预期供应会减少,提前把基差打上去了。这种非线性关系,传统模型根本预测不了。

机器学习就不一样了。它能自动学习特征之间的交互,还能捕捉非线性模式。说白了,就是让数据自己说话。

基差预测的机器学习框架

先看整体架构。我画了个流程图,帮你理清思路:

基差预测机器学习框架 数据采集与清洗 期货价格 | 现货价格 | 库存 | 到港量 | 宏观指标 特征工程 滞后特征 | 滚动统计 | 差分 | 交互特征 | 季节性编码 模型训练与调优 XGBoost | LightGBM | 随机森林 | LSTM | 交叉验证 | 超参数搜索 评估与部署 回测 | 滑点测试 | 实盘监控 | 模型更新策略 模型迭代 核心思路:用历史数据训练模型,预测未来基差走势,指导交易决策

这个框架看着简单,但每个环节都有坑。我一个个来讲。

特征工程——决定模型上限的关键

做机器学习的人都知道一句话:数据和特征决定了模型的上限,算法只是逼近这个上限。基差预测更是如此。

我常用的特征分几类:

特征类别 具体特征 说明
价格类 期货价格、现货价格、近远月价差 基础特征,必须包含
库存类 交易所库存、社会库存、港口库存 库存变化对基差影响很大
供需类 产量、进口量、消费量、开工率 反映基本面变化
宏观类 利率、汇率、PMI、CPI 影响资金成本和市场情绪
技术类 基差滞后值、移动平均、波动率 捕捉短期趋势
时间类 月份、季度、交割月距离 季节性规律和交割效应

这里有个关键点——滞后特征。基差有很强的自相关性,今天的基差往往和昨天、前天的基差有关。我一般会取过去5天、10天、20天的基差作为特征。

我的经验:别一股脑把所有特征都扔进去。先做相关性分析,剔除高度相关的特征。我曾经把库存和产量同时放进去,结果模型过拟合得一塌糊涂。后来只保留库存,效果反而更好。

模型选择——从树模型到深度学习

我试过不少模型,说说我的感受:

XGBoost/LightGBM——这是我最常用的。训练快,效果好,还能处理缺失值。对于基差这种有大量表格数据的场景,树模型天然适合。我2021年用LightGBM做铜的基差预测,年化收益比传统方法高了8个百分点。

随机森林——比XGBoost稳定,不容易过拟合。但预测精度稍差。适合做基准模型,用来对比其他模型的效果。

LSTM——理论上适合时间序列,但实际效果没那么神。我试过用LSTM预测螺纹钢基差,训练时间长了10倍,效果只比XGBoost好一点点。除非你的数据量特别大(比如分钟级数据),否则不推荐。

来看个代码示例,这是我实际用过的LightGBM模型:

import lightgbm as lgb
import pandas as pd
from sklearn.model_selection import TimeSeriesSplit

# 加载数据
df = pd.read_csv('basis_data.csv')
features = ['futures_price', 'spot_price', 'inventory', 'arrival_volume', 
            'basis_lag1', 'basis_lag5', 'basis_ma10', 'month_sin', 'month_cos']

X = df[features]
y = df['basis_next_day']

# 时间序列交叉验证
tscv = TimeSeriesSplit(n_splits=5)

params = {
    'objective': 'regression',
    'metric': 'mae',
    'boosting_type': 'gbdt',
    'num_leaves': 31,
    'learning_rate': 0.05,
    'feature_fraction': 0.8,
    'verbose': -1
}

# 训练模型
model = lgb.LGBMRegressor(**params)
model.fit(X, y, 
          eval_set=[(X_test, y_test)],
          callbacks=[lgb.early_stopping(50)])

# 特征重要性
importance = pd.DataFrame({
    'feature': features,
    'importance': model.feature_importances_
}).sort_values('importance', ascending=False)

print(importance.head(10))
注意:千万别用普通的K折交叉验证!时间序列数据有顺序性,用随机划分会泄露未来信息。一定要用TimeSeriesSplit,按时间顺序切分训练集和测试集。我刚开始做的时候犯过这个错,回测结果漂亮得不行,实盘直接被打脸。

模型评估——别只看R²

很多人评估模型只看R²或者MAE。但做交易不一样,我们更关心的是——模型能不能帮我们赚钱。

我一般会看这几个指标:

  • 方向准确率——预测基差涨跌的方向对不对。这个比数值精度更重要。
  • 盈亏比——预测对了赚多少,错了亏多少。模型可能准确率只有55%,但盈亏比高,照样赚钱。
  • 最大回撤——模型最差的时候亏多少。这个决定了你能不能扛过去。

举个例子,我有个模型预测基差的MAE只有5个点,看起来不错。但仔细一看,它在大行情来的时候总是滞后,方向准确率只有48%。这种模型你敢用吗?

实盘部署的坑

模型训练好了,部署到实盘又是另一回事。我踩过几个坑,分享给你:

第一个坑:数据延迟。模型用的数据是收盘后的,但实盘交易是盘中。你收盘后预测明天基差涨,结果第二天开盘就跌了。怎么办?我现在的做法是盘中实时更新数据,每15分钟重新预测一次。

第二个坑:模型漂移。市场环境变了,模型就不准了。我2022年做的原油基差模型,俄乌战争后完全失效。后来我加了个监控机制——如果模型预测误差连续5天超过阈值,就自动重新训练。

第三个坑:过拟合。这个最要命。模型在历史数据上表现完美,实盘一塌糊涂。我现在的做法是:训练集用3年数据,验证集用1年,测试集用最近半年。如果三个数据集上的表现差距太大,说明过拟合了,得重新调参。

核心要点:机器学习不是万能药。它只是工具,帮你从数据中挖掘规律。但市场规律会变,模型也会失效。永远保持警惕,永远做好风控。

好了,这一章就讲到这里。机器学习做基差预测,说白了就是让模型帮你找规律。但记住,模型只是辅助,最终决策还得靠你自己的判断。下一章我们聊聊怎么把多个模型组合起来,做集成预测。


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