波动率估计:历史 / EWMA / 已实现
直觉
「波动率」就是收益率的离散程度,是风险的代名词。但「怎么算」有好几种,结论可能差很多:历史波动率看一段固定窗口的方差;EWMA 让近期波动权重更大、能快速响应;已实现波动率用高频数据累积。本节对比三种。
三种估计
1. 历史波动率
过去 期收益的样本标准差,年化乘 :
2. EWMA 波动率(RiskMetrics)
让方差呈指数衰减,近期冲击权重更大:
3. 已实现波动率
一段时间内平方收益的累加(高频视角的离散近似):
「人话」解释:为什么要分这几种?
历史波动率简单稳定,但「反应慢」——大跌之后还要等满 天才体现。 EWMA 用衰减权重,大跌当天方差就跳起来,更适合风控实时跟踪。 已实现波动率用更细颗粒的收益平方和,理论上最贴近「真实」波动,但需要高频数据。 本书日频数据下,历史与 EWMA 最好对比。
可运行案例:三种波动率并排
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
df = pd.read_csv('/data/spy_daily.csv', parse_dates=['date']).set_index('date')
r = np.log(df['close'] / df['close'].shift(1)).dropna()
# 1) 历史波动率(20日窗口年化)
hist_vol = r.rolling(20).std(ddof=0) * np.sqrt(252)
# 2) EWMA 波动率(λ=0.94) 年化
lam = 0.94
ewma_var = (r**2).ewm(alpha=1-lam, adjust=False).mean()
ewma_vol = np.sqrt(ewma_var) * np.sqrt(252)
# 3) 已实现波动率(20日内平方收益和开根, 年化)
realized = np.sqrt((r**2).rolling(20).sum()) * np.sqrt(252)
vol = pd.DataFrame({'历史': hist_vol, 'EWMA': ewma_vol, '已实现': realized})
print("波动率(年化)描述:"); print(vol.describe().round(3))
vol.plot(figsize=(9, 3.8))
plt.title("三种波动率估计对比"); plt.ylabel("年化波动率")
plt.tight_layout(); plt.show()
动手改一改
把 从 0.94 调到 0.99(衰减更慢)——EWMA 曲线会变得更平滑、对冲击反应迟钝;调到 0.80 则极其敏感。这就是「记忆长度」。
小结
- 历史波动率:固定窗口标准差,稳定但滞后;
- EWMA:指数衰减,,响应快,风控常用;
- 已实现波动率:平方收益累加,贴近真实但需高频数据。