4、移动平均模型:简单移动平均(SMA)、指数加权移动平均(EWMA)、模型参数选择与实战对比
波动率预测,说白了就是猜市场未来会怎么抖。你想想看,做风控的人最怕什么?不是亏钱,是亏得不明不白。移动平均模型,就是帮我们把历史波动捋顺了,再往前看。
我个人习惯把移动平均模型分成两类:一类是「人人都会」的简单移动平均(SMA),另一类是「老手常用」的指数加权移动平均(EWMA)。今天咱们就把这两兄弟掰开揉碎了讲清楚。
4.1 简单移动平均(SMA)—— 入门级但别小看
SMA 的逻辑极其简单:取过去 N 天的波动率,算个平均值。公式长这样:
σ²_t = (1/N) * Σ(r²_{t-i}) for i = 1 to N
其中 r² 是日收益率的平方。嗯,这里要注意:我们算的是方差,不是标准差。因为方差有可加性,后面做预测更方便。
我在项目中遇到过一件事:有个同事用 SMA 做期权定价的波动率输入,窗口选了 20 天。结果遇到一次突发暴跌,SMA 死活跟不上变化,定价全偏了。为什么?因为 SMA 给每一天的权重完全一样——20 天前的数据和昨天的数据,地位平等。这在平稳市场没问题,但市场一炸,它就反应迟钝了。
4.2 指数加权移动平均(EWMA)—— 老司机的选择
EWMA 的改进思路很直接:越近的数据越重要。公式如下:
σ²_t = λ * σ²_{t-1} + (1 - λ) * r²_{t-1}
这里的 λ 叫衰减因子,通常取 0.94 或 0.97。λ 越大,历史数据衰减得越慢;λ 越小,模型对近期变化越敏感。
我曾经在风险管理系统中用 EWMA 做 VaR 计算。有一次市场连续三天大跌,SMA 的 VaR 值还在慢慢爬,EWMA 第二天就跳上去了。风控总监看到报告后问我:「你这模型是不是太敏感了?」我说:「敏感总比迟钝好,真出事的时候,早一天预警就是几千万的差别。」
4.3 模型参数选择—— 别让参数毁了你的模型
参数选择是个坑,我踩过。简单列几个原则:
- SMA 的窗口长度 N:N 越大,曲线越平滑,但滞后越严重。我一般用 20 天(一个月)或 60 天(一个季度)。做长期风控用 60 天,做短期交易用 20 天。
- EWMA 的 λ:0.94 是基准。如果你发现模型对突发事件反应太慢,降低 λ;如果噪声太多,提高 λ。
- 数据频率:日数据用 SMA 或 EWMA 都行。分钟级数据,我强烈建议用 EWMA,因为 SMA 的滞后在高频下会放大。
4.4 实战对比—— 一张表看懂差异
| 对比维度 | SMA | EWMA |
|---|---|---|
| 计算复杂度 | 极低,O(1) 更新 | 低,O(1) 更新 |
| 对近期变化的敏感度 | 低(等权重) | 高(指数衰减) |
| 滞后性 | 明显,N 越大越滞后 | 较小,λ 控制滞后 |
| 适用场景 | 平稳市场、长期风控 | 波动市场、高频交易、VaR 计算 |
| 参数调优难度 | 简单,选 N 即可 | 稍复杂,λ 需要经验 |
你看,没有绝对的好坏。SMA 简单可靠,EWMA 灵活敏感。我个人的建议是:先用 SMA 跑一遍,作为基准;再用 EWMA 做优化。如果两者差异不大,用 SMA 就行——简单的东西不容易出错。
4.5 核心逻辑框架图
下面这张图,是我自己画的知识体系。你看一眼就能明白移动平均模型在波动率预测中的位置:
4.6 代码实战—— 手把手教你算
光说不练假把式。下面是我用 Python 写的 SMA 和 EWMA 实现,你直接复制就能跑:
import numpy as np
import pandas as pd
# 模拟收益率数据
np.random.seed(42)
returns = np.random.randn(100) * 0.02 # 日收益率,标准差 2%
# SMA 计算
def sma_variance(returns, window=20):
sq_returns = returns ** 2
sma = pd.Series(sq_returns).rolling(window=window).mean()
return sma.values
# EWMA 计算
def ewma_variance(returns, lam=0.94):
sq_returns = returns ** 2
ewma = np.zeros_like(sq_returns)
ewma[0] = sq_returns[0]
for t in range(1, len(sq_returns)):
ewma[t] = lam * ewma[t-1] + (1 - lam) * sq_returns[t-1]
return ewma
# 对比输出
sma_var = sma_variance(returns, window=20)
ewma_var = ewma_variance(returns, lam=0.94)
print("SMA 最后一天方差:", round(sma_var[-1], 8))
print("EWMA 最后一天方差:", round(ewma_var[-1], 8))
好了,移动平均模型就讲到这里。记住一句话:模型是工具,不是真理。SMA 和 EWMA 各有各的脾气,你得根据市场状态选。下次遇到波动率突变,试试 EWMA,你会感谢我的。