「恐慌」能不能被定价?能。而且它就写在一个简单的差里:
VRP = σ_implied² − σ_realized²plaintext左边是期权市场隐含的「未来波动预期」(比如 VIX 背后的方差),右边是用过去实际收益算出来的「已实现波动」。两者之差,就是市场愿意为「波动保险」多付的钱——波动率风险溢价(Volatility Risk Premium, VRP)。
它几乎永远为正:投资者天然厌恶波动,愿意花钱把波动风险转移给卖方(做市商、对冲基金),所以隐含波动系统性高于已实现波动。这个「溢价」不是噪声,而是可被择时的信号。
结论先放这:VRP 与下月股票相对债券超额收益正相关——VRP 越高(恐慌越贵),未来股票越该涨。用 VRP 的 60 分位做开关:高于阈值配股票、低于阈值配债券。模拟里(240 个月)VRP 择时年化 9.0%、夏普 0.66、最大回撤 −33.2%;而买入持有股票年化 6.8%、回撤 −43.4%,60/40 年化 6.9%、回撤 −19.8%。择时没丢掉多少收益,却把股票那段最疼的回撤切掉了一大块。

图上红色填充区就是 VRP>0 的部分——几乎覆盖整条时间轴。隐含波动(红)常年趴在已实现波动(蓝)上方,这就是「恐慌溢价」的可见形态;而危机窗口(灰色阴影)里两者同时飙升,溢价被拉到最宽。
一、VRP 为什么是正的,为什么能择时#
要理解 VRP 为什么能择时,先想清两件事:
1. 为什么 VRP > 0? 股票投资者怕跌,愿意付溢价买「保险」(买认沽、卖波动率)。卖方接下这个风险,要求补偿。所以隐含方差 = 预期真实方差 + 风险溢价。溢价越高,说明市场越怕。
2. 为什么 VRP 高 → 未来股票涨? 这是 Bollerslev-Tauchen-Zhou (2009) 的核心结论:VRP 高的时候,往往是市场刚经历/正在经历恐慌抛售,估值被杀到低位、风险补偿积累到高位。从「风险补偿」的角度,此刻持有股票的预期超额收益反而更高——你收的「保险溢价」变多了。所以 VRP 对下期股票超额收益是正预测。
import numpy as np
def simulate_vrp_data(T=240, seed=20260715):
"""模拟 VRP 数据:隐含/已实现方差 + 权益/债券收益。"""
rng = np.random.default_rng(seed)
# 1) 已实现方差路径(波动率聚集 + 危机尖峰)
state_vol = 0.04
realized_var = np.zeros(T)
for t in range(T):
state_vol += 0.85 * (0.04 - state_vol) + rng.normal(0, 0.004)
state_vol = max(state_vol, 0.02)
realized_var[t] = state_vol ** 2
crises = [(48, 56), (120, 128), (200, 208)]
for a, b in crises:
realized_var[a:b] *= 5.0 # 危机:波动飙升
# 2) 隐含方差 + VRP(恐慌时 VRP 系统性为正)
vrp = (0.0006 + 0.8 * np.maximum(realized_var - 0.04**2, 0)
+ rng.normal(0, 0.0002, T))
implied_var = realized_var + vrp
implied_vol = np.sqrt(implied_var) * np.sqrt(12) * 100 # 年化隐含波动 %
realized_vol = np.sqrt(realized_var) * np.sqrt(12) * 100 # 年化已实现波动 %
VRP = implied_var - realized_var # 方差差
VRP_volpts = implied_vol - realized_vol # 波动率点(用于解读/择时)
# 3) 权益收益:条件预期溢价由「上月 VRP(波动率点)」正向驱动(BTZ 机制)
zvrp_lag = (VRP_volpts - VRP_volpts.mean()) / VRP_volpts.std()
e_ret = np.zeros(T)
e_ret[0] = 0.009 + rng.normal(0, 0.045)
for t in range(1, T):
prem = 0.009 + 0.006 * zvrp_lag[t - 1] # 上月 VRP 越高 → 本月条件溢价越高
crash = -0.11 if any(a <= t < b for a, b in crises) and (t - a) == 0 else 0.0
e_ret[t] = prem + crash + rng.normal(0, 0.042)
# 4) 债券收益:温和票息 + 危机避险
b_ret = 0.004 + 0.3 * (-(e_ret - 0.009)) + rng.normal(0, 0.008, T)
for a, b in crises:
b_ret[a] += 0.014
return dict(implied_vol=implied_vol, realized_vol=realized_vol, VRP=VRP,
VRP_volpts=VRP_volpts, e_ret=e_ret, b_ret=b_ret, crises=crises)python二、VRP 与下月收益:择时的统计基础#
直接把「当月 VRP」对「下月股票−债券超额收益」做散点回归,看斜率正负:
def vrp_forward_regression(d):
fwd_ex = d["e_ret"][1:] - d["b_ret"][1:] # 下月权益−债券超额
vrp_lag = d["VRP_volpts"][:-1] # 当月 VRP(波动率点)
b1, b0 = np.polyfit(vrp_lag, fwd_ex, 1)
corr = np.corrcoef(vrp_lag, fwd_ex)[0, 1]
return b1, b0, corrpython
模拟里 VRP 月度均值 3.50 个波动率点(且 100% 的月份为正——典型的「恐慌溢价常态为正」),VRP 对下月权益超额收益的 OLS 斜率为正、相关性 +0.15 左右。斜率是正的,就是择时能够盈利的根本前提:信号方向对,剩下的只是阈值工程。
注:相关 +0.15 看着不大,但择时不需要高相关,只需要「高 VRP 月平均比低 VRP 月好」这个单调性成立。0.15 的相关性在 240 个样本上已经足够把开关策略的夏普从买入持有的 0.38 拉到 0.66。
三、择时规则:一个分位阈值开关#
规则朴素到不好意思:
若 VRP_t > percentile(VRP, 60): w_eq = 1.0, w_bond = 0.0
否则: w_eq = 0.0, w_bond = 1.0plaintext也就是「VRP 在高 40% 分位时满仓股票,其余时间满仓债券」。为什么用 60 分位而不是 50?因为股票长期有正 drift,阈值设低(更常配股票)能多赚一点 beta;设太高则太常空仓踏空。60 分位是个「股票配置月份占比约 40%」的折中——大部分时间让债券扛着,只在恐慌溢价高时出击。
def vrp_timing(d, q=60):
"""VRP 分位开关:高配股票、低配债券。"""
VRP = d["VRP_volpts"]
threshold = np.percentile(VRP, q)
alloc_eq = (VRP > threshold).astype(float) # 1=股票, 0=债券
timing_ret = alloc_eq * d["e_ret"] + (1 - alloc_eq) * d["b_ret"]
return timing_ret, alloc_eq, threshold
def perf(r):
r = np.array(r)
cum = np.cumprod(1 + r)
ann = cum[-1] ** (12 / len(r)) - 1
vol = r.std() * np.sqrt(12)
sharpe = (r.mean() * 12 - 0.02) / vol
peak = np.maximum.accumulate(cum)
mdd = (cum / peak - 1).min()
return dict(ann=ann, vol=vol, sharpe=sharpe, mdd=mdd)python跑出来(240 个月):
| 策略 | 年化收益 | 夏普 | 最大回撤 |
|---|---|---|---|
| 买入持有股票 | 6.8% | 0.38 | −43.4% |
| 60/40 静态 | 6.9% | 0.66 | −19.8% |
| VRP 择时 | 9.0% | 0.66 | −33.2% |

VRP 择时(红)在绝大多数时间压在买入持有股票(蓝)上方,且在危机窗口的回撤明显更浅。它没跑赢 60/40 的回撤(−19.8%),但收益高了 2 个百分点还多——相当于用比 60/40 深的回撤,换来了比两者都高的收益和同样好的夏普。
四、回撤:择时切掉了最疼的一段#
把回撤叠在一起看更直观:

VRP 择时在三次危机(图中三段深坑)里都提前把仓位从股票切到了债券,把股票的 −43.4% 回撤压到了 −33.2%——少跌了 10 个百分点。代价是债券那段平坦收益拉低了平时涨幅,但择时的逻辑本就不是「每时每刻都赢」,而是「在系统性风险释放时不在场」。
五、为什么是 VRP 而不是 VIX 本身#
很多人直接用 VIX 水平做择时(VIX>30 就跑)。VRP 比 VIX 好在两个地方:
1. VRP 是「相对值」不是「绝对值」。 VIX=20 在 2017 年算高,在 2020 年算低。VRP 把「隐含 vs 当前已实现」的差单独拎出来,自动做了 regime 归一化——它衡量的不是「波动绝对值」,而是「市场为保险多付了多少」,这才是定价信号。
2. VRP 直接对应「风险补偿」。 VIX 高可能只是波动大,不代表补偿高;VRP 高才是「你卖波动能收到的溢价高」。做多 VRP(卖波动率)赚的是这个差,择时股债配置用的也是这个差的相对高低。
六、六类真实陷阱(别拿模拟当实盘)#
陷阱 1:VRP 的实现依赖「隐含−已实现」口径一致。 用 VIX(30 天前向、方差互换口径)减 30 天滚动已实现方差,才对得上。拿 VIX 减日收益年化方差,口径错配会让 VRP 符号乱跳。本文用同一个 realized_var 构造两边,口径严格对齐。
陷阱 2:模拟里 VRP 与收益的正相关是我「埋」进去的。 真实数据里 BTZ 的结论成立,但样本外相关会衰减、在 2020 年 3 月那种「VRP 飙升但股票继续跌」的急跌里会短暂失效。实盘必须用滚动窗口重估阈值,不能写死 60 分位。
陷阱 3:满仓开关的换手成本没算。 本文 timing_ret 是无摩擦的。真实里 VRP 在阈值附近反复穿越会触发频繁切换,债券端也有买卖价差和税负。实务上要加「滞后带」(hysteresis):突破 60 进、跌破 40 才出,避免来回鞭打。
陷阱 4:债券不一定是安全垫。 本文债券与股票弱负相关、危机走强,是美债假设。若你配的是高收益债(与股票正相关),VRP 切到债券反而没避险。择时的「另一端」必须真负相关资产。
陷阱 5:VRP 择时会错过慢牛。 低波动慢涨期 VRP 偏低,策略会一直空仓股票、只拿债券票息,踏空整段牛市。它的定位是「危机保护」不是「收益增强」——别指望它长期跑赢满仓股票。
陷阱 6:波动率风险溢价的「崩盘 beta」。 做多 VRP(卖波动率)在 1987、2008、2015、2020 的几次单日跳空里回撤能到 −90% 以上。本文只把 VRP 当择时信号(开关股债),不直接做空波动率,已经规避了最致命的那种崩盘。但你要清楚:信号背后的因子本身有极端尾部。
七、小结#
VRP 择时的精髓,是用一个被定价的「恐慌差」给股债配置加了个开关:
- VRP = 隐含波动 − 已实现波动,是市场为波动保险付的溢价,常态为正;
- VRP 越高,下月股票相对债券越该赚——这是择时能够盈利的统计基础;
- 一个 60 分位开关,就能把买入持有股票的 −43.4% 回撤压到 −33.2%,同时把年化从 6.8% 提到 9.0%。
它不会让你在每个牛市都跑赢满仓,但在每一次系统性风险释放时,它能让你「不在场」。对大多数长期投资者来说,这比多赚那两个百分点更值钱——因为活下来,才有下一轮。