10. 克里金插值:地质统计学方法在波动率曲面中的应用

说实话,我第一次接触克里金插值的时候,心里是有点抵触的。

你想啊,一个搞地质的玩意儿,跟金融期权能扯上什么关系?

后来我在做一次深度虚值期权的波动率曲面构建时,发现传统的样条插值在数据稀疏区域简直惨不忍睹。嗯,那时候我才意识到——克里金这玩意儿,真香。

10.1 为什么是克里金?

传统的插值方法,比如线性插值、三次样条,它们只关心「距离」。离得近的点权重就大,离得远的就小。这逻辑在波动率曲面上其实有个致命问题:

波动率曲面是有空间相关性的,而且这种相关性不是各向同性的。

举个例子,ATM附近的波动率变化和尾部区域的波动率变化,它们的「变异模式」完全不同。普通插值法根本捕捉不到这种差异。

克里金不一样。它不光看距离,还看数据的空间结构——说白了,它知道哪些区域的数据「长得像」,哪些区域的数据「突变」。

核心思想:克里金是一种最优线性无偏估计器(BLUE)。它通过变异函数(Variogram)来描述数据的空间自相关性,然后给出每个未知点的最优权重。

10.2 变异函数:克里金的灵魂

我个人习惯把变异函数理解成「波动率的波动率」。它描述的是:两个点之间的波动率差异,跟它们的距离有什么关系。

数学上长这样:

γ(h) = 0.5 * E[(Z(x) - Z(x+h))²]

其中 Z(x) 是行权价 x 处的隐含波动率,h 是行权价差。

实际建模时,我们通常用几种理论模型来拟合经验变异函数:

模型名称 公式 特点
球状模型 γ(h) = C₀ + C·(1.5h/a - 0.5(h/a)³) 最常用,有基台值
指数模型 γ(h) = C₀ + C·(1 - exp(-h/a)) 渐近到达基台值
高斯模型 γ(h) = C₀ + C·(1 - exp(-(h/a)²)) 非常平滑,适合波动率曲面

我在项目中遇到过一个问题:用球状模型拟合短期期权时,效果还行。但一到长期限(比如2年期以上),球状模型就崩了——因为长期波动率的空间相关性衰减得更慢。后来我换成了高斯模型,才把曲面给「救」回来。

10.3 普通克里金 vs 泛克里金

这里有个坑,我踩过。

普通克里金假设波动率的均值是未知但恒定的。但实际中,波动率曲面有明显的「偏斜」和「期限结构」——均值根本就不是常数。

这时候就要用泛克里金(Universal Kriging)。它允许均值是一个关于行权价和期限的多项式函数。

我曾经踩过的坑:直接用普通克里金插值深度虚值期权,结果曲面在尾部出现了「负波动率」——这在金融上根本不可能。后来加入了一阶趋势项(行权价的一次项),才把这个问题压住。

10.4 实战:用Python实现克里金插值

我不喜欢讲太多理论,直接上代码。这是我在一个实盘项目中用过的简化版本:

import numpy as np
from scipy.optimize import minimize
from sklearn.gaussian_process import GaussianProcessRegressor
from sklearn.gaussian_process.kernels import RBF, WhiteKernel, ConstantKernel

def kriging_vol_surface(strikes, tenors, vols, target_strike, target_tenor):
    """
    泛克里金插值波动率曲面
    
    参数:
        strikes: 已知行权价数组
        tenors: 已知期限数组  
        vols: 已知波动率数组
        target_strike: 目标行权价
        target_tenor: 目标期限
    """
    # 构建特征矩阵:行权价和期限
    X = np.column_stack([strikes, tenors])
    y = vols
    
    # 定义核函数:RBF捕捉空间相关性 + 白噪声处理观测误差
    kernel = ConstantKernel(1.0) * RBF(length_scale=[0.1, 0.1]) + WhiteKernel(noise_level=0.01)
    
    # 拟合高斯过程(等价于泛克里金)
    gp = GaussianProcessRegressor(kernel=kernel, n_restarts_optimizer=10)
    gp.fit(X, y)
    
    # 预测
    X_pred = np.array([[target_strike, target_tenor]])
    vol_pred, sigma_pred = gp.predict(X_pred, return_std=True)
    
    return vol_pred[0], sigma_pred[0]

# 示例:用5个已知点插值
strikes = np.array([0.8, 0.9, 1.0, 1.1, 1.2])
tenors = np.array([0.25, 0.25, 0.25, 0.25, 0.25])
vols = np.array([0.25, 0.22, 0.20, 0.21, 0.24])

vol, uncertainty = kriging_vol_surface(strikes, tenors, vols, 0.95, 0.25)
print(f"预测波动率: {vol:.4f}, 不确定性: {uncertainty:.4f}")

个人建议:用sklearn的GaussianProcessRegressor时,记得把n_restarts_optimizer设大一点(至少10次)。我一开始用默认值1,结果每次跑出来的曲面都不一样——因为优化陷入了局部最优。

10.5 克里金 vs 其他方法的对比

你可能会问:克里金比样条插值好在哪?我直接给你看对比:

方法 优点 缺点
三次样条 计算快,实现简单 无法处理数据稀疏区域,容易过拟合
径向基函数 灵活,可调参数多 参数选择主观,缺乏统计解释
克里金 提供不确定性估计,考虑空间结构 计算量大,需要拟合变异函数

说白了,如果你只是做快速原型验证,样条就够了。但如果你要上实盘交易系统,尤其是做套利监控或风控,克里金的不确定性估计就是无价之宝。

10.6 知识体系总览

下面这张图是我自己整理的克里金在波动率曲面中的应用框架,你看一眼就能明白整体逻辑:

克里金插值在波动率曲面中的应用框架 输入数据 行权价 / 期限 / 波动率 变异函数拟合 球状 / 指数 / 高斯模型 克里金预测 最优权重 + 方差 普通克里金 均值恒定假设 泛克里金 趋势项 + 残差建模 应用场景 套利监控 | 风控估值 | 做市商定价 | 波动率套利 ⚠️ 注意事项 变异函数需根据数据特征选择 | 避免外推过远 | 计算效率需优化

10.7 避坑指南

最后分享几个我实战中总结的经验:

  • 数据预处理很重要:克里金对异常值非常敏感。我建议先做一次3-sigma剔除,否则一个错误报价就能把整个曲面带偏。
  • 不要盲目用高斯模型:虽然高斯模型平滑性好,但它假设数据无限可微。如果你的波动率曲面有「尖点」(比如临近到期时的ATM附近),高斯模型会过度平滑掉这些特征。
  • 计算效率是个问题:克里金需要求解n×n的协方差矩阵,n是已知点数量。如果曲面有1000个点,矩阵求逆就够呛。我一般用局部克里金——只取目标点附近的50-100个点来插值。

一句话总结:克里金不是万能药,但在数据稀疏且需要不确定性估计的场景下,它比任何传统插值法都靠谱。前提是——你得把变异函数选对。


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