16、波动率预测:GARCH模型族、波动率预测评估、机器学习在波动率预测中的应用
波动率预测,说白了就是猜未来市场会怎么「抖」。做期权交易的朋友都知道,波动率是定价的灵魂。我做了这么多年量化,见过太多人把精力全放在方向判断上,结果被波动率一记闷棍打趴下。今天咱们就聊聊怎么用GARCH模型族、怎么评估预测效果,以及机器学习在这块能帮上什么忙。
16.1 GARCH模型族:从基础到实战
GARCH模型,全称是广义自回归条件异方差模型。名字挺唬人,其实核心思想很简单:波动率不是常数,它有自己的记忆和规律。我刚开始接触时也觉得公式复杂,后来发现,你把它当成一个「波动率的ARMA模型」就通了。
16.1.1 标准GARCH(1,1)
这是最常用的版本,公式长这样:
σ²_t = ω + α * ε²_{t-1} + β * σ²_{t-1}
其中:
- σ²_t:当前时刻的波动率(方差)
- ω:长期平均波动率的权重
- ε²_{t-1}:上一期的「冲击」(收益率平方)
- σ²_{t-1}:上一期的波动率
- α + β < 1:保证模型平稳
我在项目中遇到过一个问题:用日频数据拟合GARCH(1,1),α+β经常接近0.99。这意味着波动率冲击消退得特别慢,一旦有个大波动,好几天都缓不过来。嗯,这其实反映了金融市场的真实特征——波动率聚集效应。
16.1.2 扩展模型族
标准GARCH有个硬伤:它假设好消息和坏消息对波动率的影响是对称的。但做过交易的人都知道,坏消息带来的恐慌远大于好消息带来的兴奋。这就是所谓的「杠杆效应」。
我常用的几个扩展模型:
| 模型 | 核心改进 | 适用场景 |
|---|---|---|
| EGARCH | 允许非对称效应,且不需要参数约束 | 股票市场(杠杆效应明显) |
| GJR-GARCH | 用哑变量区分正负冲击 | 商品期货(冲击不对称) |
| TGARCH | 阈值模型,不同区间不同系数 | 极端行情后的波动率预测 |
| APARCH | 幂次变换,更灵活 | 多资产组合波动率建模 |
举个例子,EGARCH的公式长这样:
ln(σ²_t) = ω + α * (|z_{t-1}| - E|z_{t-1}|) + γ * z_{t-1} + β * ln(σ²_{t-1})
注意那个γ系数,如果γ < 0,说明负冲击(z_{t-1} < 0)会放大波动率。我曾在沪深300指数上跑过,γ值大约在-0.08到-0.12之间,验证了A股的杠杆效应。
16.2 波动率预测评估:别被R²骗了
预测做完了,怎么知道好不好?很多人上来就看R²,这在波动率预测里是个大坑。为什么?因为真实波动率是潜变量,我们永远看不到「真值」。你只能拿已实现波动率(RV)作为代理变量来评估。
16.2.1 常用评估指标
我个人习惯用这几个指标:
- MSE(均方误差):最基础,但对异常值敏感
- QLIKE(准似然损失):理论上最稳健,推荐使用
- MAE(平均绝对误差):直观,但统计性质不如MSE
- HMSE(异方差调整MSE):对波动率水平不敏感
QLIKE的公式:
QLIKE = (1/T) * Σ [ln(σ²_pred) + (RV / σ²_pred)]
你想想看,QLIKE为什么好?因为它对预测偏差的惩罚是非对称的——低估波动率的惩罚远大于高估。这在风控场景下特别重要,低估风险比高估风险要命得多。
16.2.2 模型比较的实操方法
我一般用Diebold-Mariano检验来比较两个模型。说白了就是看两个模型的预测误差序列有没有显著差异。代码实现很简单:
from arch.unitroot import ADF
import numpy as np
def dm_test(e1, e2, h=1):
"""Diebold-Mariano检验"""
d = e1**2 - e2**2 # 损失差分
# 计算Newey-West标准误
n = len(d)
gamma = np.cov(d[:-h], d[h:])[0,1] if h < n else 0
var_d = np.var(d) + 2 * gamma
dm_stat = np.mean(d) / np.sqrt(var_d / n)
return dm_stat
记得有一次,我用DM检验比较GARCH(1,1)和EGARCH,发现p值0.03,说明EGARCH确实显著优于标准模型。但换了样本区间后,p值变成了0.15。嗯,样本选择偏差在波动率预测里特别常见,建议多做滚动窗口验证。
16.3 机器学习在波动率预测中的应用
说到机器学习,很多人觉得是万能药。其实在波动率预测上,传统GARCH在某些场景下依然能打。但机器学习确实能处理一些GARCH搞不定的问题,比如非线性关系、多变量交互、高频数据等。
16.3.1 随机森林与梯度提升
树模型的好处是能自动捕捉交互效应。比如我发现,波动率不仅受自身历史影响,还受成交量、持仓量、VIX指数等影响。把这些特征扔进LightGBM,效果往往不错。
一个典型的特征工程:
- 滞后特征:过去5天、20天的已实现波动率
- 跳跃特征:日内最大最小价差、隔夜跳空
- 市场情绪:期权隐含波动率、偏度
- 宏观因子:利率、汇率、商品指数
我做过一个对比实验:
| 模型 | QLIKE | MSE(×10⁴) | 训练时间 |
|---|---|---|---|
| GARCH(1,1) | 0.452 | 3.21 | 0.3秒 |
| EGARCH | 0.438 | 3.05 | 0.5秒 |
| LightGBM | 0.421 | 2.89 | 45秒 |
| LSTM | 0.415 | 2.76 | 12分钟 |
你看,机器学习确实有提升,但代价是训练时间和可解释性。我个人建议:先用GARCH族模型建立基线,再考虑是否值得上ML。
16.3.2 LSTM与深度学习
LSTM在处理长序列依赖上有天然优势。但要注意,波动率预测不是典型的时序预测问题——我们预测的是方差,不是均值。所以输出层要用softplus或exp激活函数,保证预测值为正。
一个简单的LSTM架构:
import torch.nn as nn
class VolatilityLSTM(nn.Module):
def __init__(self, input_dim, hidden_dim, num_layers):
super().__init__()
self.lstm = nn.LSTM(input_dim, hidden_dim, num_layers, batch_first=True)
self.fc = nn.Sequential(
nn.Linear(hidden_dim, 32),
nn.ReLU(),
nn.Linear(32, 1),
nn.Softplus() # 保证输出为正
)
def forward(self, x):
out, _ = self.lstm(x)
return self.fc(out[:, -1, :])
我曾经用这个结构预测标普500的周度波动率,输入特征包括过去60天的日收益率、成交量、VIX。结果发现,LSTM在极端行情(如2020年3月)的预测表现优于GARCH,但在平稳市里反而略差。这其实符合直觉——深度学习擅长捕捉复杂模式,但容易过拟合到噪声上。
16.4 知识体系总览
说了这么多,咱们用一张图把核心逻辑串起来:
这张图把整个流程串起来了:从历史数据出发,你可以选GARCH族、机器学习或者混合模型,然后用QLIKE等指标评估,最终输出预测值和置信区间。我个人觉得,混合模型是未来的方向——用GARCH捕捉波动率的时序结构,用ML捕捉非线性特征,两者互补。
公众号:蓝海资料掘金营,微信deep3321