11. 曲面平滑技术:防止过拟合,正则化与平滑惩罚项的应用

做波动率曲面这件事,说白了就是在跟噪声打架。

我刚开始做期权定价那会儿,拿到市场报价就急着往里塞参数。结果呢?曲面倒是完美贴合了当天所有数据点,可第二天一开盘,整个曲面就崩了——完全没法用。这就是典型的过拟合。

你想想看,市场报价里有多少是真正的信息,又有多少是随机噪声?我们真正想要的,是一个能抓住市场核心结构的平滑曲面,而不是一条追着每个毛刺跑的疯狗。

11.1 为什么需要平滑?

波动率曲面如果太粗糙,会带来两个致命问题:

  • 套利机会假象:不平滑的曲面可能产生日历套利或蝶式套利空间,但这些都是噪声造成的假象
  • 对冲不稳定:稍微换个行权价或期限,希腊值就剧烈跳动,你根本没法做风险管理

我记得有一次做跨式期权组合的对冲,就因为曲面局部有个小凸起,delta对冲信号一天变了七八次。后来我把曲面平滑了一下,整个世界都清净了。

核心原则:平滑不是丢掉信息,而是过滤噪声。我们要的是「结构」,不是「细节」。

11.2 过拟合的本质

过拟合说白了就是模型太「聪明」了。它记住了每一个数据点的位置,包括那些不该记住的随机波动。

举个简单的例子:假设我们有10个期权报价,你用10阶多项式去拟合,肯定能完美穿过每个点。但这条曲线在数据点之间会疯狂震荡——这就是过拟合的典型症状。

在波动率曲面建模中,过拟合的表现通常是:

  • 曲面出现不合理的局部极值
  • 相邻行权价的波动率差异过大
  • 期限结构出现锯齿状波动

注意:过拟合的曲面在样本内表现极好,但样本外预测能力几乎为零。我见过有人用200个参数去拟合50个数据点,结果就是自欺欺人。

11.3 正则化的基本思想

正则化,说白了就是给模型加个「紧箍咒」。你让模型自由发挥,它就会乱来;你给它加点约束,它反而更靠谱。

数学上,正则化就是在损失函数后面加一个惩罚项:

Loss = 数据拟合误差 + λ × 惩罚项

这里的λ是个超参数,控制惩罚的力度。λ越大,曲面越平滑;λ越小,曲面越贴合数据。

我建议你把这个λ当作一个旋钮。调得太小,过拟合;调得太大,欠拟合。怎么找到合适的值?交叉验证是个好办法,但更实际的做法是——凭经验,结合你对市场的理解来调。

11.4 常见的平滑惩罚项

不同的惩罚项会带来不同的平滑效果。我挑几个常用的说说:

11.4.1 一阶导数惩罚(L1正则化)

惩罚曲面的一阶导数大小。说白了就是让曲面不要有太大的斜率变化。

惩罚项 = ∫ |∂σ/∂K| dK + ∫ |∂σ/∂T| dT

这种惩罚会让曲面产生「分段线性」的效果。我在做短期期权曲面时比较喜欢用这个,因为短期曲面本身就应该比较平缓。

11.4.2 二阶导数惩罚(L2正则化)

惩罚曲面的二阶导数大小。这个更常用,因为它惩罚的是曲率——也就是曲面弯曲的程度。

惩罚项 = ∫ (∂²σ/∂K²)² dK + ∫ (∂²σ/∂T²)² dT

这个惩罚会让曲面变得非常光滑。我个人的习惯是,对于长期期权曲面,优先用二阶惩罚。因为长期曲面应该更平滑,不应该有太多局部波动。

11.4.3 混合惩罚

有时候单一惩罚不够用。你可以把一阶和二阶惩罚结合起来:

惩罚项 = λ₁ × 一阶惩罚 + λ₂ × 二阶惩罚

这样既能控制斜率,又能控制曲率。嗯,这里要注意:两个λ的比值需要仔细调,不然容易顾此失彼。

实战技巧:我一般先用二阶惩罚跑一遍,看看曲面的整体形状。如果发现局部有异常抖动,再适当加入一阶惩罚来压制。

11.5 实现示例:带正则化的样条拟合

下面是一个简单的Python实现,用带惩罚项的样条来拟合波动率曲面:

import numpy as np
from scipy.interpolate import UnivariateSpline

def fit_smoothed_surface(strikes, maturities, vols, smoothing=0.1):
    """
    带平滑惩罚的波动率曲面拟合
    smoothing参数越大,曲面越平滑
    """
    # 对每个期限分别拟合
    surfaces = {}
    for T in np.unique(maturities):
        mask = maturities == T
        K = strikes[mask]
        V = vols[mask]
        
        # 使用s参数控制平滑程度
        spline = UnivariateSpline(K, V, s=smoothing * len(K))
        surfaces[T] = spline
    
    return surfaces

# 使用示例
smoothing_factor = 0.05  # 这个值需要根据数据量调整
smoothed_surf = fit_smoothed_surface(
    strikes, maturities, vols, 
    smoothing=smoothing_factor
)

这段代码看着简单,但实际用起来有几个坑:

  • smoothing参数对数据量很敏感。数据点多的时候,同样的smoothing值会显得更「紧」
  • 不同期限的波动率结构不同,最好分别调参
  • 样条阶数也要注意。我一般用3次样条,太高容易过拟合

11.6 交叉验证选参

怎么选λ?凭感觉当然可以,但更靠谱的是用交叉验证。

基本思路是这样的:

  1. 把数据分成K份
  2. 用K-1份训练,1份验证
  3. 重复K次,计算平均误差
  4. 选误差最小的λ

我曾经在一个项目中用过5折交叉验证,结果选出来的λ确实比凭感觉调的好了不少。不过要注意,交叉验证计算量比较大,如果数据量很大,可以考虑用信息准则(AIC/BIC)来近似。

经验之谈:交叉验证选出来的λ往往偏小(倾向于过拟合)。我建议在交叉验证结果的基础上,把λ再放大1.5到2倍。这样得到的曲面在实际交易中更稳定。

11.7 实战中的注意事项

最后说几个我在项目中踩过的坑:

  • 不要全局统一λ:不同期限、不同行权价区域的波动率特性不同。我习惯把曲面分成几个区域,分别调参
  • 注意边界效应:在行权价的极端位置,数据稀疏,平滑惩罚容易把曲面拉得太平。这时候需要手动调整边界处的权重
  • 定期重新校准:市场结构会变,今天合适的λ明天可能就不行了。我一般每周重新做一次交叉验证

曾经踩过的坑:有一次我为了追求曲面的「美观」,把λ调得特别大。结果曲面确实漂亮了,但定价误差大得离谱。记住,平滑是为了更好地定价,不是为了好看。

11.8 知识体系总览

下面这张图总结了本章的核心逻辑:

曲面平滑技术知识体系 核心问题:过拟合 解决方案:正则化 + 平滑惩罚项 一阶导数惩罚 控制斜率变化 二阶导数惩罚 控制曲率变化 混合惩罚 综合控制 样条拟合 + 惩罚项 交叉验证选参 区域自适应调参 最终目标:稳定、可交易的波动率曲面

这张图把整个流程串起来了。从识别过拟合问题开始,到选择惩罚类型,再到具体实现和参数调优,最后得到一个稳定的曲面。每一步都有讲究,每一步都值得你花时间去琢磨。

最后说一句:平滑技术不是万能的。如果数据质量太差,再好的平滑也救不了。所以,在动手平滑之前,先花点时间清洗数据、剔除异常报价。这个投入绝对值得。

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