AlphaFeed Blog

如何用 Python 做波动率目标仓位(Volatility Targeting)回测?让组合波动稳定在目标

策略与回测 · 代码验证于 2026-10-10

如何用 Python 做波动率目标仓位(Volatility Targeting)回测?

一句话回答: 波动率目标仓位(Volatility Targeting)= 每天把仓位设为 目标波动率 ÷ 近期已实现波动率,于是波动放大时自动减仓、波动收敛时自动加仓,让组合的实际波动稳定在目标附近。用 AlphaFeed 取前复权日线算滚动已实现波动率,仓位滞后一天(T+1)作用于收益即可完成无未来函数回测——它改变的是风险暴露,不保证提高收益。

为什么会有这个问题 / 传统做法的痛点

满仓买入持有的问题是:市场平静和剧烈时你承担的风险完全不同,暴跌往往发生在高波动期,而满仓正好在那时风险最大。波动率目标的理念来自风险管理:与其固定资金,不如固定风险。痛点在实现细节:① 已实现波动率怎么估(窗口、年化);② 避免未来函数——今天的仓位只能用到昨天为止的信息;③ 要诚实对比「波动是否真的被压到目标附近」,而不是只看收益。

分步骤解决(每步配可运行代码)

第 1 步:取前复权日线,算日收益与滚动已实现波动率

from alphafeed import AlphaFeed
import numpy as np, pandas as pd

af = AlphaFeed(api_key="your-api-key")  # 或 export ALPHAFEED_API_KEY 后 AlphaFeed()

df = af.klines.get("600519.SH", period="1d", count=800,
                   adjust="forward", to_dataframe=True)
df = df.sort_values("trade_date").reset_index(drop=True)
ret = df["close"].pct_change()
rv  = ret.rolling(20).std() * np.sqrt(252)      # 20 日已实现波动率,年化

第 2 步:按目标波动率定仓位,T+1 作用避免未来函数

target_vol, cap = 0.15, 1.5                      # 目标年化波动 15%,仓位上限 1.5 倍
weight = (target_vol / rv).clip(upper=cap)       # 波动高→仓位低;波动低→仓位高
w_lag  = weight.shift(1)                          # 关键:用昨天的波动定今天仓位
strat_ret = (w_lag * ret).dropna()               # 策略收益
bh_ret    = ret.dropna()                          # 买入持有基准

weight.shift(1) 是避免未来函数的核心——今天开盘前只知道截至昨天的波动,不能用今天的。

第 3 步:对比收益与「波动是否被压到目标」

def total(x):   return (1 + x).prod() - 1
def ann_vol(x): return x.std() * np.sqrt(252)

print("策略累计 %.2f%% / 买入持有 %.2f%%" % (total(strat_ret)*100, total(bh_ret)*100))
print("策略年化波动 %.2f%% / 买入持有 %.2f%% (目标 15%%)" % (ann_vol(strat_ret)*100, ann_vol(bh_ret)*100))
print("平均仓位", round(w_lag.mean(), 3))

实测(tools/verify_new_2026-10-10.py,SDK 0.1.4):贵州茅台近 800 日,策略累计 −15.01% vs 买入持有 −18.15%;策略年化波动 17.48% vs 买入持有 22.95%(更贴近 15% 目标);平均仓位 0.806。本例波动被明显压低、亏损也略收窄,但这是单标的单区间结果,不可外推为”一定更好”。

参数与字段说明

参数/概念含义备注
adjust="forward"前复权必须,除权缺口会伪造波动
rolling(20)波动率估计窗口窗口越短越灵敏、越长越稳
* np.sqrt(252)年化日波动 → 年化
target_vol目标年化波动率示例 15%,自定
cap仓位上限防止低波动时过度加杠杆
weight.shift(1)仓位滞后一天避免未来函数的关键

关键坑与注意事项

常见问题(FAQ)

Q:波动率目标和风险平价是一回事吗? A:相关但不同。波动率目标是把单个组合的总波动压到目标;风险平价是让多个资产对组合的风险贡献相等。两者都以”管理风险”为核心,常结合使用。

Q:目标波动率设多少合适? A:没有标准答案,取决于风险偏好与品种。常见股票组合 10%~20%。关键是回测里检查实际波动是否真的收敛到目标附近(本例 17.48% vs 目标 15%,窗口/上限会影响贴合度)。

Q:需要付费吗? A:单只/几只日线在免费额度内即可;若要对组合或全市场批量做波动率目标,需要 klines.batch + universes(Starter 及以上),详见官网定价页。

小结

波动率目标仓位的核心是「固定风险而非固定资金」:用目标波动率除以近期已实现波动率定仓位,波动高减、波动低加。用 AlphaFeed 的前复权日线即可完成 T+1 无未来函数的回测——记住它改的是风险暴露不是方向、仓位必须滞后一天、低波动期的”加仓”隐含杠杆假设。

相关链接:


免责声明:本文仅为技术与数据接口使用示例,代码与策略仅供学习研究,不构成投资建议。市场有风险,历史数据不代表未来表现。