波动率分析:从历史到预测的完整路径
波动率这东西,说白了就是市场的心跳。做量化交易这么多年,我越来越觉得,不懂波动率就像开船不看天气预报——迟早要翻。今天咱们就聊聊波动率的几个核心概念,以及怎么用GARCH模型把它预测出来。
一、历史波动率:最朴素的度量
历史波动率,就是看过去的价格波动有多大。计算方式其实很简单:
import numpy as np
import pandas as pd
def historical_volatility(prices, window=20):
# 计算对数收益率
log_returns = np.log(prices / prices.shift(1))
# 滚动标准差,年化处理
hv = log_returns.rolling(window).std() * np.sqrt(252)
return hv
我个人习惯用20个交易日作为窗口。为什么是20?因为一个月大概有20个交易日,这个周期能较好地捕捉短期波动特征。我在项目中遇到过一个问题:如果窗口选得太短(比如5天),波动率会剧烈跳动,根本没法用;选得太长(比如60天),又反应太慢,等它告诉你波动来了,行情都走完了。
二、隐含波动率:市场在说什么?
隐含波动率就更有意思了。它不是算出来的,而是从期权价格里反推出来的。你想想看,市场上那么多交易者,他们愿意花多少钱买期权,这个价格里就包含了他们对未来波动的预期。
隐含波动率和历史波动率的差值,我把它叫做「恐慌溢价」。正常情况下,隐含波动率会略高于历史波动率,因为市场总是倾向于为不确定性多付点钱。但一旦差值拉得特别大,往往意味着市场在害怕什么。
三、波动率聚类效应:波动是会传染的
你有没有发现一个现象?市场大跌之后往往接着大跌,大涨之后往往接着大涨。这不是错觉,这就是波动率聚类效应——大的波动后面跟着大的波动,小的波动后面跟着小的波动。
为什么会这样?说白了,市场信息是成堆出现的。一个坏消息会引发连锁反应,导致更多坏消息被曝光。投资者的情绪也会传染,恐慌会自我强化。
我记得2015年股灾的时候,波动率从20%一路飙到60%以上,然后在高位持续了将近两个月。这就是典型的波动率聚类——一旦进入高波动状态,想出来可没那么容易。
四、GARCH模型:预测波动率的利器
既然波动率会聚类,那能不能预测它?当然可以。GARCH模型就是干这个的。
GARCH模型的核心思想很简单:今天的波动率,取决于昨天的波动率和昨天的收益率。用数学公式表达就是:
σ²_t = ω + α * ε²_{t-1} + β * σ²_{t-1}
其中:
- σ²_t 是今天的条件方差(波动率的平方)
- ε²_{t-1} 是昨天的收益率平方(代表新信息)
- σ²_{t-1} 是昨天的条件方差(代表旧波动)
- α 和 β 是模型参数,α+β 越接近1,波动率越持久
实际应用中,我一般用Python的arch库来实现:
from arch import arch_model
# 拟合GARCH(1,1)模型
model = arch_model(returns, vol='Garch', p=1, q=1)
result = model.fit()
# 预测未来5天的波动率
forecast = result.forecast(horizon=5)
predicted_vol = np.sqrt(forecast.variance.values[-1])
五、波动率分析的知识体系
为了让你更直观地理解这些概念之间的关系,我画了一张图:
六、实战中的注意事项
说了这么多理论,最后分享几个实战中的坑:
- 数据频率要匹配:做日频交易就用日数据,做高频交易就用分钟数据。我见过有人用日数据预测分钟级别的波动,结果一塌糊涂。
- 模型要定期重估:GARCH模型的参数不是一成不变的。市场结构变了,参数也得跟着变。我一般每个月重新拟合一次。
- 不要迷信预测:波动率预测只是概率,不是确定性。即使GARCH模型告诉你明天波动率会下降,也不代表一定不会出黑天鹅。
- 结合仓位控制:波动率预测的最终目的是指导仓位。波动率高时减仓,波动率低时加仓,这才是正确的打开方式。