如何用 Python 画波动率锥(Volatility Cone)?判断当前波动是高还是低
如何用 Python 画波动率锥(Volatility Cone)?
一句话回答: 单看「当前 20 日年化波动率 35%」没有参照,不知道算高还是低。波动率锥把 5/10/20/60/120 日等多个窗口的历史年化波动率各自的分位(最小/25%/中位/75%/最大)排在一起,再标出当前值——一眼就能看出当前波动处在历史的高位还是低位。用 AlphaFeed 取回前复权日线算收益率,几行 pandas 就能做出来。
为什么会有这个问题 / 传统做法的痛点
波动率是均值回归的:高了会回落、低了会抬升。但「高/低」要和自己的历史比,还要和相同窗口比(20 日波动率不能和 120 日波动率直接比)。波动率锥正是「按窗口分别统计历史分位」的可视化,常用于判断期权贵不贵、择时是否进入高波动期。坑在于用前复权收益、统一年化口径。
分步骤解决(每步配可运行代码)
第 1 步:取前复权日线算对数收益
from alphafeed import AlphaFeed
import numpy as np
import pandas as pd
af = AlphaFeed() # 读取 ALPHAFEED_API_KEY
df = af.klines.get("600519.SH", period="1d", count=750,
adjust="forward", to_dataframe=True)
df = df.sort_values("trade_date").reset_index(drop=True)
logret = np.log(df["close"] / df["close"].shift(1)).dropna()
波动率常用对数收益;用前复权价避免除权日伪跳变。
第 2 步:各窗口的滚动年化波动率
TRADING_DAYS = 252
WINDOWS = [5, 10, 20, 60, 120]
def ann_vol(logret, w):
return logret.rolling(w).std(ddof=1) * np.sqrt(TRADING_DAYS)
vol = {w: ann_vol(logret, w).dropna() for w in WINDOWS}
第 3 步:构造波动率锥(各窗口的历史分位)
cone = pd.DataFrame({
"min": {w: vol[w].min() for w in WINDOWS},
"p25": {w: vol[w].quantile(0.25) for w in WINDOWS},
"median": {w: vol[w].median() for w in WINDOWS},
"p75": {w: vol[w].quantile(0.75) for w in WINDOWS},
"max": {w: vol[w].max() for w in WINDOWS},
"current": {w: vol[w].iloc[-1] for w in WINDOWS},
})
print((cone * 100).round(1).to_string()) # 以百分比显示
| 列 | 含义 |
|---|---|
min/max | 该窗口历史年化波动率的最小/最大 |
p25/median/p75 | 25% / 中位 / 75% 分位 |
current | 当前该窗口的年化波动率 |
第 4 步:判断当前波动的历史分位
for w in WINDOWS:
cur = vol[w].iloc[-1]
pct = (vol[w] < cur).mean() # 当前值在历史中的分位
tag = "高位" if pct >= 0.8 else ("低位" if pct <= 0.2 else "中性")
print(f"{w:>3}日: 当前 {cur*100:.1f}% 历史分位 {pct*100:.0f}% → {tag}")
关键坑与注意事项
- 用前复权对数收益:除权跳变会虚增波动率;对数收益更适合波动率可加性。
- 同窗口才可比:20 日波动率只和 20 日历史比,别跨窗口比大小——这正是「锥形」的意义。
- 统一年化口径:日频 ×√252;别和周/月频混用。
- 样本要足够长:画锥建议 ≥ 500 日,短样本分位不稳。
- 波动率均值回归但不定时:处在高位不代表马上回落,只是概率参考。
- 事件驱动的跳升:财报、停复牌、极端行情会让短窗口波动率突然冲高,解读要结合事件。
常见问题(FAQ)
Q:波动率锥有什么用? A:判断当前波动在历史中的相对高低——做期权时看隐含波动率贵不贵的参照,做择时时识别是否进入高波动期、是否适合波动率策略。
Q:为什么要多个窗口? A:短窗口反应快、长窗口更稳;把多个窗口的历史分位画成「锥」,能同时看到不同时间尺度的波动状态。
Q:用简单收益还是对数收益? A:波动率计算常用对数收益(可加性更好),日频下两者差异很小,用哪种都要前后一致。
Q:需要付费吗?
A:单只历史日线有免费额度;批量做多只波动率锥(klines.batch)需 Starter 及以上。详见定价页。
小结
波动率锥把「当前波动率」放进「同窗口历史分位」里看,解决了「35% 到底高不高」的问题。用 AlphaFeed 取前复权日线算对数收益,对多个窗口分别求滚动年化波动率与分位,几行 pandas 就能构造出锥形表并标出当前位置。关键是前复权、同窗口比较、统一年化、样本够长。
相关链接:
- AlphaFeed 官网:https://alphafeed.org/
- Python SDK 快速开始:https://docs.alphafeed.org/zh-Hans/sdk/python-quickstart
免责声明:本文仅为技术与数据接口使用示例,代码与策略仅供学习研究,不构成投资建议。市场有风险,历史数据不代表未来表现。