第十六章:机器学习辅助曲面——神经网络曲面拟合、异常检测模型、预测曲面演化
说实话,做期权做市这些年,我越来越觉得纯靠解析公式去拟合波动率曲面,有点「不够用了」。
你想想看,市场数据那么嘈杂,隐含波动率的形态又受那么多因素影响——买卖压力、事件情绪、流动性分层……传统的参数化模型(比如SVI、SSVI)虽然解释性强,但碰到极端行情或者数据稀疏的区域,拟合效果经常让我头疼。
所以这几年,我开始把机器学习方法引入到曲面处理流程里。今天就跟大家聊聊我实战中用得最多的三个方向:神经网络曲面拟合、异常检测模型、以及预测曲面演化。
一、神经网络曲面拟合——让模型自己「学」出曲面形状
传统方法里,我们通常假设波动率曲面符合某种参数形式。但真实市场里,曲面经常有「奇形怪状」的局部特征。比如我记得有一次,某只股票在财报前出现了非常陡峭的短期虚值看涨期权溢价,SVI怎么调参数都拟合不好。
后来我换了个思路:用神经网络直接去学习从「行权价、到期时间」到「隐含波动率」的映射。
具体做法其实不复杂:
- 输入层:标准化后的行权价(比如用Delta或Moneyness)、剩余到期时间(用年化或对数变换)
- 隐藏层:2-3层全连接层,每层64-128个神经元,激活函数用ReLU或Swish
- 输出层:一个神经元,输出预测的隐含波动率
我习惯在训练时加入一个正则化项,惩罚曲面的二阶导数过大——这样能保证拟合出的曲面不会太「毛躁」。说白了,就是让模型既拟合数据,又保持曲面的光滑性。
实战小技巧:
我一般不会直接用原始的行权价和到期时间作为输入。而是先做一步特征工程:
- 行权价 → 转换成
(K / F - 1)或者log(K / F) - 到期时间 → 取平方根或者对数
这样神经网络学起来会快很多,而且泛化能力更强。
# 一个简单的神经网络曲面拟合示例(PyTorch风格)
import torch
import torch.nn as nn
class VolSurfaceNet(nn.Module):
def __init__(self):
super().__init__()
self.net = nn.Sequential(
nn.Linear(2, 64),
nn.ReLU(),
nn.Linear(64, 64),
nn.ReLU(),
nn.Linear(64, 1)
)
def forward(self, x):
# x: [batch, 2] -> [moneyness, time_to_expiry]
return self.net(x)
# 训练时加入光滑性正则项
def smoothness_penalty(model, x):
# 计算输出对输入的梯度,惩罚梯度的变化率
x.requires_grad_(True)
y = model(x)
grad = torch.autograd.grad(y.sum(), x, create_graph=True)[0]
# 惩罚二阶导数(近似)
return torch.mean(grad ** 2)
用神经网络拟合曲面,最大的好处是灵活。它不需要你事先假设曲面是什么形状,数据喂进去,它自己就能学到。但缺点也很明显——可解释性差,而且如果数据质量不好,容易过拟合到噪声上。
二、异常检测模型——揪出曲面上的「坏点」
做市交易里,最怕的是什么?是报价数据里有异常点。
比如某个深度虚值期权,突然出现一个极低或极高的隐含波动率。如果你不做处理,直接拿这个点去拟合曲面,整个曲面都会被带偏。我早期就吃过这个亏——有一次因为一个错误报价,导致我的曲面在远端出现了一个「鼓包」,结果对冲策略亏了不少。
所以我现在会在曲面拟合之前,先跑一遍异常检测。
常用的方法有两种:
- 基于统计的方法:计算每个点的局部Z-score,或者用四分位距(IQR)判断离群值
- 基于模型的方法:先用一个鲁棒性强的模型(比如LOF、孤立森林)去识别异常点
我个人更倾向于用孤立森林(Isolation Forest)。为什么呢?因为它对高维数据效果好,而且不需要假设数据分布。你想想看,波动率曲面的数据点其实是有结构的——正常点应该落在曲面附近,异常点则会「孤立」出来。
避坑指南:
我曾经犯过一个错误:把异常检测的阈值设得太严,结果把很多真实的、但形态特殊的点(比如财报前的尖峰)也给剔除了。后来我学乖了——异常检测的结果只作为「预警」,最终是否剔除,要结合人工判断。特别是那些交易量大的点,即使看起来异常,也可能是市场情绪的体现。
# 使用孤立森林检测异常波动率点
from sklearn.ensemble import IsolationForest
import numpy as np
# 假设 data 是 [moneyness, time_to_expiry, implied_vol] 的三维数组
X = data[:, :2] # 只使用位置特征
y = data[:, 2] # 波动率值
# 训练孤立森林
clf = IsolationForest(contamination=0.05, random_state=42)
outlier_labels = clf.fit_predict(X)
# 标记异常点
anomalies = data[outlier_labels == -1]
print(f"检测到 {len(anomalies)} 个异常波动率点")
三、预测曲面演化——让曲面「动」起来
做市交易的核心是什么?是管理未来的风险。所以光知道当前曲面长什么样还不够,你还得知道它接下来会怎么变。
这就是「预测曲面演化」要做的事。
我常用的方法是用时序模型 + 空间特征。具体来说:
- 把曲面离散化成网格(比如10个行权价档位 × 5个到期时间档位)
- 每个网格点上的波动率,作为一个时间序列
- 用LSTM或Transformer去学习这些序列之间的时空依赖关系
嗯,这里要注意:不要单独预测每个网格点。因为曲面上的点之间是有强相关性的——比如短期ATM波动率上涨时,长期波动率通常也会跟着涨,只是幅度不同。所以我会把整个曲面作为一个「图像」来处理,用卷积LSTM或者时空图网络去捕捉这种结构。
我个人的经验:
预测曲面演化时,最重要的特征不是历史波动率本身,而是波动率的「变化率」和「斜率」。比如:
- 短期波动率的变化速度
- 偏斜(Skew)的变动方向
- 期限结构的陡峭程度
这些「二阶特征」往往比原始波动率值更有预测力。
另外,预测模型不能只输出一个「最可能」的曲面。做市交易里,你需要知道预测的不确定性。所以我习惯用贝叶斯神经网络或者分位数回归,输出预测的置信区间。这样在做Delta对冲时,我可以根据不确定性大小来调整对冲频率。
核心逻辑框架
下面这张图,是我自己整理的一个机器学习辅助曲面的整体流程。你可以看到,三个模块是串联的:先拟合、再清洗、最后预测。
总结一下
机器学习辅助曲面,说白了就是给传统方法加上了「数据驱动」的翅膀。神经网络负责灵活拟合,异常检测负责数据清洗,预测模型负责前瞻性判断。三者配合好了,你的曲面处理能力会上一个台阶。
当然,这些方法也有局限性。比如神经网络需要大量高质量数据,异常检测在低流动性品种上容易误判,预测模型在市场结构突变时可能失效。所以我的建议是:把机器学习当作工具,而不是答案。最终做决策的,还是你对市场的理解。
最后提醒一句:
别一上来就上复杂模型。先试试简单的线性回归或者随机森林,看看基线效果。很多时候,简单模型加上好的特征工程,效果并不比深度学习差。我见过太多人一上来就堆LSTM,结果过拟合得一塌糊涂。
公众号:蓝海资料掘金营,微信deep3321