15. 机器学习在套利识别中的应用:使用随机森林、神经网络等模型预测套利机会
说实话,做波动率曲面套利这么多年,我最大的感触就是——人眼能看出来的机会,基本都已经被人抢光了。
曲面上的细微扭曲、期限结构里的非线性偏移、隐含波动率与已实现波动率的背离……这些信号太微弱了。靠人工盯盘?不现实。靠简单阈值规则?容易被市场风格切换打脸。
所以,我大概从2018年开始,系统性地把机器学习引入到套利识别流程中。今天这篇,我就把这几年的实战经验拆开揉碎了讲给你听。
15.1 为什么传统规则不够用?
先说说传统方法的问题。
我们常用的套利识别规则,无非是:
- 隐含波动率超过历史波动率2个标准差
- 曲面局部曲率超过某个阈值
- 蝶式价差超出理论范围
这些规则在平稳市场里挺好用。但一旦遇到事件驱动行情、流动性突变、或者波动率风格切换,阈值就失效了。
核心痛点:规则是静态的,市场是动态的。机器学习能学出「什么样的市场状态下,什么样的偏差才是真正的套利机会」。
我曾经在2020年3月那波波动率暴涨中,用固定阈值策略连续打了7次止损。后来换成随机森林模型,虽然也没完全躲过,但至少把误报率降了40%。嗯,那次教训挺深刻的。
15.2 特征工程:比模型更重要的东西
很多人一上来就调模型参数,我觉得这是本末倒置。特征工程才是机器学习套利识别的核心。
我个人习惯把特征分成四大类:
| 特征类别 | 具体特征 | 说明 |
|---|---|---|
| 曲面形态特征 | 偏度斜率、峰度曲率、期限结构斜率 | 描述曲面当前形状 |
| 时间序列特征 | 波动率变化率、均值回归速度、波动率锥位置 | 描述曲面动态变化 |
| 市场状态特征 | VIX水平、成交量变化、买卖价差、持仓量 | 描述市场微观结构 |
| 衍生特征 | PCA主成分得分、隐含-已实现波动率差、日历价差 | 组合特征,捕捉非线性关系 |
你想想看,如果只给模型输入「曲面偏差值」这一个特征,它学到的无非就是阈值优化。但如果你把市场状态也喂进去,模型就能学会「高波动环境下,偏差容忍度应该更大」这种逻辑。
我的经验:特征数量控制在20-30个之间最好。太少学不到模式,太多容易过拟合。我一般先用随机森林的特征重要性做一轮筛选,保留top20。
15.3 随机森林:快速上手的首选
随机森林是我在套利识别项目里用得最多的模型。原因很简单:它不容易过拟合,而且可解释性强。
来看一个实际代码片段。这是我用来训练套利机会分类器的核心逻辑:
import pandas as pd
import numpy as np
from sklearn.ensemble import RandomForestClassifier
from sklearn.model_selection import train_test_split
from sklearn.metrics import classification_report
# 加载特征数据
# 假设 df 包含所有特征列和标签列 'arb_opportunity'
features = ['skew_slope', 'curvature', 'term_structure_slope',
'vol_change_rate', 'vix_level', 'bid_ask_spread',
'iv_rv_diff', 'pca_score_1', 'pca_score_2']
X = df[features]
y = df['arb_opportunity'] # 1表示存在套利机会,0表示无
# 训练集/测试集划分
X_train, X_test, y_train, y_test = train_test_split(
X, y, test_size=0.3, random_state=42, stratify=y
)
# 随机森林模型
rf_model = RandomForestClassifier(
n_estimators=200,
max_depth=10,
min_samples_leaf=5,
class_weight='balanced',
random_state=42
)
rf_model.fit(X_train, y_train)
# 预测与评估
y_pred = rf_model.predict(X_test)
print(classification_report(y_test, y_pred))
# 特征重要性排序
importance_df = pd.DataFrame({
'feature': features,
'importance': rf_model.feature_importances_
}).sort_values('importance', ascending=False)
print(importance_df)
这段代码里,我特别强调两点:
- class_weight='balanced':套利机会在样本中占比通常不到5%,不做平衡处理模型会直接摆烂——全部预测为「无机会」
- max_depth=10:限制树深度,防止模型记住噪声。我试过max_depth=20,训练集准确率99%,测试集直接崩到60%
避坑指南:我曾经在特征里不小心加入了「未来信息」——用当天的收盘价计算了当天的标签,结果模型在回测里准确率高达98%。实盘一跑,直接亏成狗。切记:特征和标签的时间窗口必须严格错开。
15.4 神经网络:捕捉更复杂的曲面模式
随机森林虽然好用,但它有个局限——对曲面空间结构的建模能力有限。
什么意思呢?随机森林是把每个特征独立看待的。但波动率曲面本质上是一个二维流形,行权价和到期日之间存在复杂的交互关系。这时候,神经网络就派上用场了。
我常用的网络结构是这样的:
import torch
import torch.nn as nn
class VolSurfaceArbNet(nn.Module):
def __init__(self, input_dim=64, hidden_dim=128):
super().__init__()
# 曲面编码器:把波动率曲面展平后编码
self.encoder = nn.Sequential(
nn.Linear(input_dim, hidden_dim),
nn.BatchNorm1d(hidden_dim),
nn.ReLU(),
nn.Dropout(0.3),
nn.Linear(hidden_dim, hidden_dim // 2),
nn.ReLU(),
nn.Dropout(0.3)
)
# 市场状态分支
self.market_branch = nn.Sequential(
nn.Linear(10, 32),
nn.ReLU()
)
# 融合层
self.fusion = nn.Sequential(
nn.Linear(hidden_dim // 2 + 32, 64),
nn.ReLU(),
nn.Linear(64, 1),
nn.Sigmoid()
)
def forward(self, surface_flat, market_state):
surf_feat = self.encoder(surface_flat)
mkt_feat = self.market_branch(market_state)
combined = torch.cat([surf_feat, mkt_feat], dim=1)
return self.fusion(combined)
这个网络的设计思路是:把曲面信息和市场状态分开处理,最后融合。为什么这么做?因为曲面本身是高维的(比如10个行权价×5个期限=50维),直接拼接市场状态会让模型学偏。
训练的时候,我建议用Focal Loss替代普通的BCE Loss。原因还是那个——正负样本极度不平衡。Focal Loss会自动降低易分类样本的权重,让模型更关注那些「模棱两可」的套利机会。
实际效果:在我自己的回测中,神经网络比随机森林的F1-score高了约8个百分点。但代价是训练时间长了10倍,而且调参非常痛苦。所以我的建议是:先用随机森林快速验证特征有效性,再上神经网络做精细化建模。
15.5 模型评估:别只看准确率
做套利识别,最忌讳的就是只看准确率。
为什么?因为套利机会本身是稀缺事件。假设样本中只有2%是真正的套利机会,你模型全部预测为「无机会」,准确率也有98%。但这模型有个屁用?
我一般关注这几个指标:
| 指标 | 计算公式 | 关注原因 |
|---|---|---|
| 召回率 | TP / (TP + FN) | 漏掉了多少真正的机会? |
| 精确率 | TP / (TP + FP) | 预测的机会里,多少是真的? |
| F1-score | 2×P×R/(P+R) | 综合平衡 |
| 盈亏比 | 平均盈利/平均亏损 | 模型推荐的交易是否赚钱? |
我个人最看重的是盈亏比。哪怕模型召回率只有30%,但只要它抓到的机会盈亏比超过3:1,我就愿意用。说白了,宁可少做,不能做错。
15.6 知识体系总览
下面这张图,是我自己整理的本章节知识框架。你可以把它当作一个快速索引:
15.7 一些实战建议
最后,分享几条我踩坑踩出来的经验:
- 先做无监督学习:在跑分类模型之前,先用PCA或者t-SNE对曲面数据做降维可视化。你会发现很多套利机会其实在低维空间里是「离群点」——这能帮你快速验证特征的有效性。
- 滚动窗口训练:市场风格会变。我一般每3个月重新训练一次模型,用最近6个月的数据。太老的数据反而会引入过时的市场结构。
- 集成才是王道:我最终上线的系统,其实是随机森林+神经网络+一个简单的逻辑回归做投票。三个模型都预测「有机会」,我才出手。虽然机会少了,但胜率从62%提到了78%。
- 别忘了回测的滑点:机器学习模型在回测里表现好,不代表实盘能赚钱。因为模型识别出的机会往往伴随着流动性不足——你看到的价差,可能根本成交不了。我一般会在回测里加1-2个tick的滑点,模拟真实成交环境。
一句话总结:机器学习不是银弹,但它能帮你从「人肉盯盘」进化到「系统化扫描」。用好特征工程,选对评估指标,你就能在波动率曲面上找到那些别人看不见的「金矿」。
好了,这一章的内容就到这里。希望这些实战经验能帮你少走一些弯路。记住,模型只是工具,对市场的理解才是根本。
公众号:蓝海资料掘金营,微信deep3321