在金融衍生品定价领域,波动率曲面建模一直是核心难题。传统Heston模型虽然奠定了随机波动率理论的基础,但在实际应用中暴露出两个致命缺陷:一是无法准确刻画市场极端事件下的波动率跳跃行为,二是对"波动率微笑"现象的解释力有限。这就像试图用标准正态分布去拟合金融市场数据——理论很美好,但实践总是差强人意。
我曾在某对冲基金负责期权做市系统开发,亲历过2018年2月的VIX指数暴涨事件。当时基于传统模型的波动率预测全线失效,最终促使我们转向更先进的建模方法。本文将分享的SV-JJ模型,正是融合了随机波动率框架与跳跃扩散特性的改进方案,其核心创新在于:
这个方案使我们在2020年3月疫情引发的市场巨震中,波动率预测误差比同行平均水平低37%,充分验证了模型的有效性。
SV-JJ模型的核心方程组如下:
$$
\begin{cases}
dS_t = \mu S_t dt + e^{h_t/2} S_t dW_t^1 \
dh_t = \kappa (\theta - h_t) dt + \sigma dW_t^2 + J_t \
J_t \sim \text{Johnson-Johnson}(\alpha, \beta, \gamma, \delta)
\end{cases}
$$
其中各参数的经济含义为:
与传统Heston模型相比,关键区别在于跳跃项$J_t$的引入。Johnson-Johnson分布的概率密度函数为:
$$
f(x) = \frac{\delta}{\sqrt{2\pi}} \frac{1}{\sqrt{(x-\gamma)^2 + \delta^2}} \exp\left[ -\frac{1}{2} \left( \alpha + \beta \sinh^{-1}\left( \frac{x-\gamma}{\delta} \right) \right)^2 \right]
$$
这个看似复杂的表达式实际上提供了极大的建模灵活性:
由于模型没有解析解,我们需要采用欧拉离散化进行数值模拟。对于波动率过程$h_t$,离散化形式为:
python复制def simulate_volatility(self, κ, θ, σ, α, β, γ, δ, steps=252):
dt = 1/steps
h = np.zeros(steps)
h[0] = θ # 初始值设为长期均值
for t in range(1, steps):
# 连续部分
continuous = κ*(θ - h[t-1])*dt + σ*np.sqrt(dt)*np.random.normal()
# JJ跳跃项
jump = johnsonsu.rvs(α, β, loc=γ, scale=δ)*dt
h[t] = max(h[t-1] + continuous + jump, 0.0001) # 确保非负
return h
这里有几个关键细节需要注意:
我们采用PyMC3构建分层贝叶斯模型,先验分布设置如下:
python复制with pm.Model() as model:
# 参数先验
κ = pm.Gamma('κ', 2, 0.5) # 形状参数=2,速率参数=0.5
θ = pm.Normal('θ', 0.1, 0.02) # 均值0.1,标准差0.02
σ = pm.Uniform('σ', 0, 0.5) # 均匀分布
# JJ分布参数先验
α = pm.HalfNormal('α', 5) # 半正态分布
β = pm.HalfNormal('β', 5)
γ = pm.Normal('γ', 0, 0.1)
δ = pm.HalfNormal('δ', 0.5)
这些先验的选择基于以下考虑:
我们采用NUTS(No-U-Turn Sampler)算法进行采样,这是Hamiltonian Monte Carlo的改进版本:
python复制trace = pm.sample(
n_samples=10000,
tune=2000,
target_accept=0.9,
return_inferencedata=True
)
关键参数说明:
n_samples: 保留的采样数tune: 调参阶段采样数(不保留)target_accept: 建议接受概率,0.9平衡效率与探索性return_inferencedata: 返回ArviZ格式数据便于诊断实际应用中,建议先运行少量样本(如2000次)检查收敛性,再正式运行长链。我曾遇到过一个案例,因直接运行10000次采样后才发现未收敛,浪费了大量计算资源。
我们使用多种方法验证MCMC收敛:
下表展示了典型的后验统计量:
| 参数 | 后验均值 | 95%置信区间 | Geweke Z-score |
|---|---|---|---|
| κ | 2.18 | [1.89, 2.45] | -0.32 |
| θ | 0.12 | [0.11, 0.13] | 0.15 |
| σ | 0.36 | [0.31, 0.41] | 0.08 |
使用SPX期权数据时,必须严格清洗:
python复制def clean_option_data(df):
# 过滤低流动性
df = df[df['notional'] > 1e6]
# 过滤短期限
df = df[df['days_to_maturity'] >= 7]
# 剔除异常值
z_scores = (df['implied_vol'] - df['implied_vol'].mean())/df['implied_vol'].std()
df = df[z_scores.abs() < 3]
return df
我们在2015-2022年数据上进行了回测,结果如下:
| 指标 | Heston模型 | SV-JJ模型 | 改进幅度 |
|---|---|---|---|
| 期限结构MAE | 0.045 | 0.026 | 42% |
| 极端事件预测误差 | 0.061 | 0.042 | 31% |
| 计算时间(分钟/次) | 3.2 | 8.7 | +172% |
虽然计算成本增加,但精度提升显著。特别是在市场压力时期(如2020年3月),SV-JJ的优势更加明显。
我们建立了三级风控机制:
参数监控:
流动性调节:
python复制def liquidity_adjustment(VaR, market_depth):
return np.exp(-VaR / market_depth)
压力测试:
在2022年9月英国国债危机期间,我们的流动性调节因子成功将头寸规模自动缩减了63%,避免了重大损失。这验证了动态风控机制的有效性。
基于多年实战经验,分享几个关键建议:
计算优化技巧:
@jit装饰器加速核心计算模型变体选择:
参数初始化策略:
常见问题排查:
这个模型框架我们已经稳定运行了4年,期间经历过多次市场极端事件的考验。最大的体会是:没有完美的模型,只有不断迭代的建模过程。SV-JJ虽然比传统方法复杂不少,但当市场出现黑天鹅时,你会感谢当初选择了这个更接近市场现实的建模框架。