4. 波动率特征:历史波动率、指数加权波动率(EWMA)、已实现波动率、波动率锥

波动率是金融风险管理的核心变量,它直接度量资产收益率的离散程度。在组合风险归因训练集中,波动率特征不仅用于刻画资产自身的风险水平,更是构建协方差矩阵、计算风险贡献和压力测试的基础输入。本节将系统讲解四种最常用的波动率特征:历史波动率、指数加权波动率(EWMA)、已实现波动率以及波动率锥,并给出它们在特征工程中的具体实现与适用场景。

核心要点:波动率特征的选择直接影响风险模型的时效性与准确性。历史波动率适合长期稳定估计,EWMA 擅长捕捉近期变化,已实现波动率利用高频数据提升精度,波动率锥则提供多时间尺度下的波动率分布视角。

4.1 历史波动率(Historical Volatility, HV)

历史波动率是最基础的波动率估计方法,它基于过去一段固定窗口内的收益率标准差,并通常进行年化处理。其计算公式为:

# 历史波动率计算示例(Python)
import numpy as np
import pandas as pd

def historical_volatility(returns, window=21, annualize_factor=252):
    """
    计算历史波动率(年化)
    :param returns: 日收益率序列(Series)
    :param window: 滚动窗口长度(交易日)
    :param annualize_factor: 年化因子(日数据用252)
    :return: 年化历史波动率序列
    """
    rolling_std = returns.rolling(window=window).std()
    hv = rolling_std * np.sqrt(annualize_factor)
    return hv

# 示例:使用过去21个交易日计算年化波动率
hv_series = historical_volatility(returns, window=21)
参数 典型值 说明
窗口长度 21 / 63 / 252 分别对应1个月、1个季度、1年
年化因子 252(日) / 52(周) / 12(月) 将日波动率转换为年化波动率
去均值方式 样本标准差 / 总体标准差 样本标准差(ddof=1)更常用
特征工程建议:在训练集中,可以同时生成多个窗口的历史波动率(如 HV_21、HV_63、HV_252),作为不同时间尺度下的风险特征输入模型。窗口越短,波动率对近期市场变化的反应越快,但噪声也越大。

4.2 指数加权波动率(EWMA)

EWMA 通过衰减因子 λ 赋予近期收益率更高的权重,从而更灵敏地捕捉波动率的动态变化。其递推公式为:

σ²t = λ · σ²t-1 + (1 - λ) · r²t-1

其中 λ 通常取 0.94(日数据)或 0.97(周数据),这是 RiskMetrics 框架的经典参数。

def ewma_volatility(returns, lambda_=0.94, annualize_factor=252):
    """
    计算 EWMA 波动率(年化)
    :param returns: 日收益率序列
    :param lambda_: 衰减因子(0 < lambda_ < 1)
    :return: 年化 EWMA 波动率序列
    """
    variance = np.zeros_like(returns)
    variance[0] = returns.iloc[0] ** 2
    for t in range(1, len(returns)):
        variance[t] = lambda_ * variance[t-1] + (1 - lambda_) * (returns.iloc[t-1] ** 2)
    ewma_vol = np.sqrt(variance) * np.sqrt(annualize_factor)
    return pd.Series(ewma_vol, index=returns.index)

ewma_series = ewma_volatility(returns, lambda_=0.94)
λ 取值 半衰期(交易日) 适用场景
0.94 约 11 天 日频风险监控(RiskMetrics 标准)
0.97 约 23 天 周频或更平滑的波动率估计
0.99 约 69 天 接近等权历史波动率,长期趋势
注意:EWMA 对初始值敏感,建议使用前 20-30 个交易日的方差作为初始方差估计,或直接丢弃前期的预热期数据。在特征工程中,EWMA 通常作为“短期波动率”特征与历史波动率并列使用。

4.3 已实现波动率(Realized Volatility, RV)

已实现波动率利用日内高频收益率数据,通过求和平方日内收益率来估计当日波动率,相比日间波动率具有更高的精度。其标准形式为:

RVt = √( Σi=1M r²t,i )

其中 M 为日内采样次数,rt,i 为第 t 天第 i 个区间内的对数收益率。

def realized_volatility(intraday_prices, sampling_freq='5min'):
    """
    计算已实现波动率(日频)
    :param intraday_prices: 日内价格序列(DatetimeIndex)
    :param sampling_freq: 采样频率,如 '5min', '15min', '30min'
    :return: 日度已实现波动率
    """
    # 重采样到指定频率,取最后一个价格
    sampled = intraday_prices.resample(sampling_freq).last()
    # 计算对数收益率
    log_returns = np.log(sampled / sampled.shift(1)).dropna()
    # 每日求和平方收益率
    daily_rv = (log_returns ** 2).resample('D').sum()
    # 开方得到波动率
    rv = np.sqrt(daily_rv)
    return rv

# 假设有5分钟频率的日内价格数据
rv_daily = realized_volatility(intraday_prices, sampling_freq='5min')
采样频率 日内样本数(M) 优缺点
1 分钟 约 390 精度高,但易受微观结构噪声影响
5 分钟 约 78 平衡精度与噪声,最常用
15 分钟 约 26 噪声更小,但可能丢失日内波动细节
30 分钟 约 13 适合流动性较差的资产
特征工程价值:已实现波动率是高频数据特征的代表,在训练集中可以作为“真实波动率代理变量”用于监督学习中的标签构造,或作为强预测特征输入模型。对于无法获取高频数据的资产,可以使用已实现波动率的低频近似(如使用 30 分钟线)。

4.4 波动率锥(Volatility Cone)

波动率锥是一种可视化工具,它展示同一资产在不同时间尺度(如 5 天、21 天、63 天、252 天)下的波动率分布特征(通常包括中位数、分位数)。通过波动率锥,可以直观判断当前波动率在历史分布中的相对位置,识别波动率是否处于极端水平。

def volatility_cone(returns, windows=[5, 21, 63, 126, 252], percentiles=[0.05, 0.25, 0.50, 0.75, 0.95]):
    """
    计算波动率锥数据
    :param returns: 日收益率序列
    :param windows: 滚动窗口列表
    :param percentiles: 分位数列表
    :return: DataFrame,行=窗口,列=分位数
    """
    cone_data = {}
    for w in windows:
        hv = returns.rolling(window=w).std() * np.sqrt(252)
        cone_data[w] = np.percentile(hv.dropna(), q=[p*100 for p in percentiles])
    cone_df = pd.DataFrame(cone_data, index=[f'{p*100:.0f}%' for p in percentiles]).T
    cone_df.index.name = 'Window'
    return cone_df

cone_df = volatility_cone(returns)
print(cone_df)
训练集构造技巧:波动率锥本身不直接作为特征,但可以从中衍生出“当前波动率在锥中的分位数位置”作为特征。例如,计算当前 21 天波动率在历史 21 天波动率分布中的百分位排名,作为“波动率相对水平”指标。
四种波动率特征对比图 四种波动率特征:关系与对比 历史波动率 (HV) 等权滚动窗口 EWMA 波动率 指数衰减权重 已实现波动率 (RV) 日内高频数据 波动率锥 多时间尺度分布 低频数据输入 日收益率 → HV / EWMA 多窗口 → 波动率锥 高频数据输入 日内价格 → 已实现波动率 可作为 HV 的增强替代 波动率锥整合 HV、EWMA、RV 的多尺度信息,提供波动率分布的全局视图

4.5 特征工程综合对比

下表从多个维度对比四种波动率特征,帮助你在训练集中做出合理选择:

特征类型 数据频率 时效性 噪声水平 计算复杂度 典型特征名称
历史波动率 日频 低(等权滞后) 中等 低 hv_21, hv_63, hv_252
EWMA 波动率 日频 高(指数衰减) 中等 低 ewma_94, ewma_97
已实现波动率 日内高频 最高(当日估计) 较低(采样适当) 中 rv_5min, rv_15min
波动率锥分位数 日频(衍生) 中等 低(分布统计量) 中 hv_21_pctile, hv_63_pctile
训练集特征组合建议:
  • 基础组合:hv_21 + ewma_94 + rv_5min(覆盖短期、中期、高频三个维度)
  • 增强组合:在上述基础上加入 hv_63、hv_252 以及波动率锥分位数特征(hv_21_pctile、hv_63_pctile)
  • 衍生特征:波动率斜率(hv_21 / hv_63)、波动率冲击(rv_5min / ewma_94)等比值特征

4.6 实现注意事项

  1. 数据对齐:所有波动率特征在时间轴上必须严格对齐,避免未来信息泄露。使用 .shift(1) 确保特征基于历史数据计算。
  2. 缺失值处理:滚动窗口初期会产生 NaN,建议使用前向填充或直接丢弃预热期数据。
  3. 年化一致性:不同时间尺度的波动率必须统一年化,才能在同一尺度下比较。
  4. 极端值处理:波动率序列可能出现极端值(如市场崩盘日),建议进行 winsorize 或对数变换后再输入模型。
  5. 多资产并行:对于组合风险归因,需要对组合内所有资产同时计算上述波动率特征,并保持时间索引一致。
常见陷阱:不要将未来波动率信息泄露到训练集中。例如,计算已实现波动率时,必须使用当天的日内数据,但作为特征时只能使用 前一天的已实现波动率 来预测当天的风险。始终牢记特征工程的时间顺序约束。