波动率模型入门:为什么要建模波动率?

说实话,我刚入行做量化的时候,也问过自己这个问题。

价格序列摆在那儿,直接算收益不就行了?为什么非要折腾什么波动率模型?

后来我在一次实盘回测中吃了大亏——模型在历史数据上跑得漂亮,一上线就连续爆仓。原因很简单:我没把波动率的脾气摸透。

波动率这东西,它不是老老实实服从正态分布的。它有情绪,有记忆,还会耍性子。今天咱们就来聊聊,为什么必须给它单独建模。

波动率的两个核心特征

金融时间序列里,波动率有两个非常明显的“坏习惯”。你如果不处理它们,模型基本就是废的。

1. 波动率聚集效应

什么叫聚集效应?说白了就是:大波动后面跟着大波动,小波动后面跟着小波动。

我举个例子。你去看2008年金融危机那段时间,标普500的日收益率,一天暴跌5%,第二天又跌4%,第三天还在震荡。反过来,市场平静的时候,可能连续几周每天波动都在0.5%以内。

为什么会这样?因为信息是成堆来的。坏消息往往连着出,恐慌情绪会传染。好消息也一样,乐观情绪会自我强化。

我在项目中遇到过这种情况:用普通的最小二乘法去拟合收益率,残差项根本不满足同方差假设。你算出来的标准误全是偏的,置信区间也是错的。

核心结论:波动率聚集意味着方差不是常数。传统线性模型假设“方差不变”,这在金融数据里基本不成立。

2. 杠杆效应

这个更有意思。杠杆效应说的是:价格下跌时,波动率上升得更快;价格上涨时,波动率上升得慢,甚至可能下降。

你想想看,一家公司股价跌了,它的债务权益比就上升了,财务杠杆变高,风险自然变大。股价涨了,杠杆降低,风险反而小了。

我记得有一次做美股个股的波动率分析,发现苹果股票在2018年四季度那波下跌中,隐含波动率直接翻了一倍。但后面反弹的时候,波动率下降得慢吞吞的。这就是典型的杠杆效应。

我的经验:如果你在做期权定价或者风险管理,忽略杠杆效应会导致VaR严重低估。尤其是做空头寸的时候,市场一跌,波动率飙升,你的风险敞口瞬间放大。

为什么要单独建模波动率?

好,现在咱们把问题说透。既然波动率有聚集效应和杠杆效应,那直接拿历史波动率来用行不行?

不行。原因有三:

  1. 历史波动率是滞后的。它只能告诉你过去发生了什么,不能预测未来。而风险管理需要的是前瞻性的估计。
  2. 波动率是时变的。今天的波动率和明天的波动率可能差很多。用一个固定值去套,就像穿固定尺码的鞋——脚会肿,鞋会破。
  3. 尾部风险被低估。正态分布假设下,极端事件发生的概率被严重低估。而金融市场的肥尾特征,恰恰是风险管理的核心。

所以我们需要一个模型,能够捕捉波动率的动态变化。GARCH模型就是干这个的。

GARCH模型的核心思想

GARCH模型的想法其实很朴素:今天的波动率,取决于昨天的波动率和昨天的冲击。

用数学语言说就是:

σ²_t = ω + α * ε²_{t-1} + β * σ²_{t-1}

其中:

  • σ²_t 是今天的条件方差
  • ε²_{t-1} 是昨天的收益率平方(代表冲击)
  • σ²_{t-1} 是昨天的方差
  • ω、α、β 是待估参数

这个公式你看一眼就能明白:如果昨天波动大(σ²_{t-1}大),或者昨天有大的冲击(ε²_{t-1}大),那么今天的波动率就会大。这就是聚集效应的数学表达。

注意:α+β 的值非常关键。如果 α+β 接近1,说明波动率冲击的衰减很慢,也就是“长记忆性”。我曾经见过一些股票,α+β 高达0.98,这意味着一次冲击的影响会持续好几个月。

一张图看懂波动率建模逻辑

下面我用一张SVG图,把整个知识体系串起来。你一看就明白。

波动率建模核心逻辑 金融收益率序列 观察到的两个核心特征 波动率聚集效应 | 杠杆效应 传统模型假设:方差恒定 → 失效 标准误偏误 | 置信区间错误 | VaR低估 GARCH模型:动态方差建模 时变波动率 → 更准确的VaR

这张图把整个逻辑链条说清楚了。从原始数据出发,先观察到聚集效应和杠杆效应,发现传统模型不行,然后引入GARCH模型,最后得到更准确的VaR估计。

一个简单的Python示例

光说不练假把式。我写一段代码,让你看看GARCH模型到底怎么用。

import numpy as np
import pandas as pd
import yfinance as yf
from arch import arch_model

# 下载数据
data = yf.download('AAPL', start='2020-01-01', end='2023-12-31')
returns = data['Close'].pct_change().dropna() * 100

# 拟合GARCH(1,1)模型
model = arch_model(returns, vol='Garch', p=1, q=1)
result = model.fit(disp='off')

# 查看参数
print(result.params)

# 预测未来10天的波动率
forecast = result.forecast(horizon=10)
print(forecast.variance.iloc[-1])

这段代码做了三件事:下载苹果股票数据,拟合GARCH(1,1)模型,预测未来10天的波动率。你跑一下就能看到,波动率预测值是随时间变化的,不是常数。

避坑指南:我曾经在拟合GARCH模型时,数据没做平稳性检验,结果参数估计全是发散的。记住,GARCH模型要求收益率序列是平稳的。先做ADF检验,再建模。

小结一下

波动率建模不是炫技,是刚需。聚集效应和杠杆效应是金融市场的固有特征,你不建模,就等于闭着眼睛开车。

GARCH模型给了我们一个优雅的解决方案:用昨天的波动率和昨天的冲击,来预测今天的波动率。简单,但有效。

嗯,今天就聊到这儿。下一节咱们会深入GARCH模型的参数估计和模型诊断,到时候再细聊。


专注资料整理