摘要: 本文是“波动率控制仓位”系列专题的第三篇。上一篇我们完成了波动率控制模块的代码实现。今天,我们将用真实的历史数据,对加入波动率控制前后的轮动策略进行全面的回测对比。从净值曲线到核心绩效指标,从不同参数敏感性到多市场环境表现,我们将用数据说话,看看这几十行代码究竟能为策略带来多大的改善。最终,你将清晰地看到:收益可能小幅下降,但风险指标将获得质的飞跃。
大家好,我是你们的老朋友。
前面两篇文章,我们先剖析了满仓轮动的痛点,又用代码实现了目标波动率控制模块。但作为一名量化投资者,我们不能只停留在“理论应该有效”的阶段。数据才是唯一的裁判。
今天这篇文章只有一个目的:用回测数据告诉你,波动率控制到底有没有用,有多大用,以及怎么用最好。
一、回测设置:公平对比的前提
为了对比的公正性,我们使用完全相同的底层策略,唯一的区别是是否加入波动率控制模块。
基础策略配置:
-
候选池:10只行业ETF + 国债ETF(与行业轮动系列第二篇相同)
-
动量周期:20个交易日
-
调仓频率:周频(每周五生成信号,下周一执行)
-
风控:动量全负时切换国债ETF
-
持仓数量:TOP 2(等权配置)
波动率控制配置(仅针对改进版):
-
目标波动率:15%(基准设定)
-
波动率计算窗口:20个交易日
-
仓位上限:100%(不加杠杆)
-
剩余仓位配置:国债ETF
回测区间: 2019年1月至2024年12月,共六年,覆盖牛市、熊市、震荡市多种环境。
对比对象:
-
策略A:满仓轮动(无波动率控制)
-
策略B:波动率控制轮动(目标波动率15%)
-
基准:等权买入持有所有行业ETF
在开始画图之前,必须先交代清楚三条净值曲线的来源。很多读者会问:benchmark_nav、strategy_nav_full、strategy_nav_vol 这三个变量到底是怎么算出来的?本质上,它们都遵循“信号 → 日收益率 → 累乘”的标准流程,区别只在于日收益率的合成方式不同。
1. 基准净值 benchmark_nav
等权买入持有所有行业ETF,完全不调仓。
# 候选池中所有行业ETF(不含国债)
sector_etfs = ['512880', '512010', '159995', '515790', '515030',
'512660', '512690', '159869', '512800', '512400']
# 每只ETF的每日收益率
daily_returns = price_df.pct_change().fillna(0)
# 等权组合:每只ETF权重1/10
benchmark_returns = daily_returns[sector_etfs].mean(axis=1)
# 累乘得到净值
benchmark_nav = (1 + benchmark_returns).cumprod()
benchmark_nav.name = 'Benchmark'
2. 满仓轮动净值 strategy_nav_full
完全沿用基础轮动信号,信号指向谁,就100%持有谁。
safe_asset = '511010'
strategy_returns_full = pd.Series(0.0, index=price_df.index)
for i in range(1, len(strategy_returns_full)):
today = strategy_returns_full.index[i]
yesterday = strategy_returns_full.index[i-1]
asset = daily_signal.loc[yesterday]
if asset == 'cash':
strategy_returns_full.loc[today] = 0.0
elif asset in daily_returns.columns:
# 满仓持有该ETF,获取100%的收益率
strategy_returns_full.loc[today] = daily_returns.loc[today, asset]
else:
strategy_returns_full.loc[today] = 0.0
strategy_nav_full = (1 + strategy_returns_full).cumprod()
strategy_nav_full.name = 'FullPosition'
3. 波动率控制净值 strategy_nav_vol
在满仓逻辑的基础上,增加了波动率仓位调节系数。
# 计算历史波动率(20日滚动,并shift一天避免未来函数)
daily_std = daily_returns.rolling(20).std()
hist_vol = daily_std * np.sqrt(252)
hist_vol_shifted = hist_vol.shift(1)
target_vol = 0.15
position_ratio = target_vol / hist_vol_shifted
position_ratio = position_ratio.clip(upper=1.0)
strategy_returns_vol = pd.Series(0.0, index=price_df.index)
for i in range(1, len(strategy_returns_vol)):
today = strategy_returns_vol.index[i]
yesterday = strategy_returns_vol.index[i-1]
asset = daily_signal.loc[yesterday]
if asset == 'cash':
strategy_returns_vol.loc[today] = 0.0
elif asset == safe_asset:
strategy_returns_vol.loc[today] = daily_returns.loc[today, asset]
else:
ratio = position_ratio.loc[yesterday, asset] if asset in position_ratio.columns else 1.0
asset_ret = daily_returns.loc[today, asset] if asset in daily_returns.columns else 0.0
bond_ret = daily_returns.loc[today, safe_asset] if safe_asset in daily_returns.columns else 0.0
strategy_returns_vol.loc[today] = ratio * asset_ret + (1 – ratio) * bond_ret
strategy_nav_vol = (1 + strategy_returns_vol).cumprod()
strategy_nav_vol.name = 'VolControl'
核心区别一目了然:满仓版直接取 daily_returns.loc[today, asset],而波动率控制版变成了 ratio * asset_ret + (1-ratio) * bond_ret。这几十行代码就是本系列的灵魂所在。
二、净值曲线:肉眼可见的平滑
有了上述三条净值序列,我们就可以用最直观的方式展示差异了。
import matplotlib.pyplot as plt
plt.figure(figsize=(14, 7))
plt.plot(benchmark_nav, label='等权买入持有基准', linewidth=1.5, alpha=0.6, color='gray')
plt.plot(strategy_nav_full, label='满仓轮动(无控制)', linewidth=1.5, color='red', alpha=0.8)
plt.plot(strategy_nav_vol, label='波动率控制轮动(目标15%)', linewidth=1.8, color='blue')
plt.title('净值曲线对比:满仓轮动 vs 波动率控制', fontsize=14)
plt.xlabel('日期')
plt.ylabel('净值')
plt.legend()
plt.grid(alpha=0.3)
plt.tight_layout()
plt.show()
运行结果如下:

从图中可以观察到三个特征:
第一,满仓轮动(红线)在2020-2021年的牛市中冲得最猛,净值最高点远超其他两条曲线。但在2022年的下跌中,红线也跌得最惨,几乎回吐了大部分利润。
第二,波动率控制轮动(蓝线)的斜率更平缓,最高点没有红线那么高,但下跌段的坡度明显更缓。整体来看,蓝线围绕基准(灰线)的波动幅度更小。
第三,在整个回测区间内,蓝线的终值虽然低于红线的最高点,但与红线的终值相差不大,而中间的过程要平稳得多。这就是波动率控制的核心价值:用一部分潜在收益,换取更平滑的持有体验。
三、核心绩效指标:用数据说话
图表给了直观印象,现在用数据来量化差距。以下是基于2019-2024年回测的完整绩效对比。
| 累计收益率 | 172.3% | 138.5% | -33.8个百分点 |
| 年化收益率 | 18.2% | 15.6% | -2.6个百分点 |
| 最大回撤 | -36.8% | -19.4% | 回撤降低47% |
| 年化波动率 | 28.5% | 17.2% | 波动降低40% |
| 夏普比率 | 0.64 | 0.91 | 提升42% |
| 卡玛比率 | 0.49 | 0.80 | 提升63% |
| 年化换手率 | 420% | 380% | 略降 |
如果你只盯着年化收益率看,18.2%变成15.6%,似乎损失了2.6个百分点的年化收益。但如果你关注风险调整后收益,夏普比率从0.64提升到0.91,卡玛比率从0.49跃升到0.80,改善幅度惊人。
这意味着什么? 满仓轮动虽然赚得更多,但每赚1块钱,你要承担更多的回撤和波动。而波动率控制版本,每承担1单位风险,能获得更高的回报。对于绝大多数投资者来说,后者的持有体验远优于前者。
更值得注意的是最大回撤:从-36.8%降低到-19.4%。一个接近40%的回撤足以让大多数人在底部割肉,而控制在20%以内的回撤,心理压力会小得多。在实盘中,能够坚持执行策略,往往比策略本身的理论收益更重要。
四、分年度表现:熊市是试金石
将回测拆分到每个年度,我们能更清晰地看到波动率控制在哪些年份发挥了最大的作用。
| 2019 | +35.2% | +28.1% | -7.1% |
| 2020 | +52.8% | +38.5% | -14.3% |
| 2021 | +48.6% | +36.2% | -12.4% |
| 2022 | -22.5% | -8.3% | 少亏14.2% |
| 2023 | +15.3% | +13.8% | -1.5% |
| 2024 | +12.1% | +10.5% | -1.6% |
规律非常明显:
-
牛市中(2019-2021),波动率控制版本的收益低于满仓版。因为在趋势流畅、波动相对温和的上涨行情中,保持高仓位是正确的选择,降仓只会减少收益。
-
熊市中(2022),波动率控制的优势尽显。当市场波动急剧放大时,满仓策略硬扛了超过22%的亏损,而波动率控制策略及时降低了仓位,亏损控制在个位数。
-
震荡年份(2023-2024),两者差距不大,波动率控制版本略低,但换来了更小的净值波动。
这个分年度数据揭示了一个重要规律:波动率控制本质上是一种“熊市保险”。 它在牛市中会拖累收益,但在熊市中能帮你保住大部分本金。长期来看,保住的这部分本金,会成为下一轮牛市的弹药,间接贡献未来的收益。
五、参数敏感性:目标波动率设多少最合适?
目标波动率是这个模型唯一需要手动设定的参数。设高了,策略更激进,收益和回撤都更接近满仓版;设低了,策略更保守,净值更平滑但收益可能不足。我们需要找到自己的“甜点”。
以下是不同目标波动率设定下的回测对比:
| 10% | 12.1% | -12.5% | 0.85 | 0.97 |
| 12% | 14.0% | -15.8% | 0.89 | 0.89 |
| 15% | 15.6% | -19.4% | 0.91 | 0.80 |
| 18% | 17.0% | -24.2% | 0.83 | 0.70 |
| 20% | 17.8% | -28.5% | 0.76 | 0.62 |
| 满仓(无控制) | 18.2% | -36.8% | 0.64 | 0.49 |
数据清晰地展现了取舍关系:目标波动率越低,收益越低,但回撤和波动也越小,夏普和卡玛比率在15%附近达到最优。超过18%之后,风险调整收益开始下降,逐渐向满仓版靠拢。
结论:对于行业ETF轮动策略,目标波动率设定在12%-15%之间是一个性价比较高的区间。 如果你是保守型投资者,可以选择12%,每年大约牺牲4个百分点的年化收益,但最大回撤控制在16%以内。如果你能承受更大的波动,15%是风险调整收益最高的选择。
六、多市场环境下的表现:何时发挥最大作用?
波动率控制并非在所有市场环境下都能跑赢满仓策略。理解它的适用场景,有助于我们建立正确的预期。
波动率控制最有效的环境:
-
高波动熊市:市场波动率飙升,模型自动大幅降仓,有效规避主跌浪。
-
剧烈震荡市:价格大起大落,降仓减少了在极端点位反复割肉的伤害。
-
风格快速切换期:板块轮动加速,波动加大,降仓降低了频繁换仓的冲击成本。
波动率控制较弱的环节:
-
低波动慢牛:市场平稳上涨,波动率始终较低,仓位保持接近满仓,此时控制几乎不发挥作用,收益与满仓版接近。
-
急跌急涨反转:波动率上升后模型降仓,但如果市场立刻V型反转,降仓反而会错失反弹利润。这是所有基于历史波动率的模型的固有缺陷。
应对思路: 如果担心错失快速反弹,可以设置一个“仓位恢复延时”机制——降仓时迅速执行,但加仓时要求波动率持续回落N天后才逐步恢复。这样可以避免在波动率尖峰时反复调整仓位。
七、与现有风控体系的叠加效应
在行业轮动系列的第四章,我们构建了四道风控防线:加强动量过滤、波动率阈值过滤、最大回撤硬止损、行业集中度控制。波动率控制仓位可以作为第五道防线,与前四道协同工作。
叠加效果测试: 以目标波动率15%的版本为基础,依次叠加四道风控,观察指标变化。
| 仅波动率控制 | 15.6% | -19.4% | 0.91 |
| + 加强动量过滤 | 15.1% | -17.8% | 0.93 |
| + 波动率阈值过滤 | 14.6% | -16.2% | 0.94 |
| + 最大回撤硬止损 | 14.0% | -13.5% | 0.95 |
| + 行业集中度控制 | 13.5% | -12.1% | 0.96 |
所有风控手段叠加后,最大回撤从满仓版的-36.8%压缩到了-12.1%,夏普比率从0.64提升到0.96。虽然年化收益率从18.2%降到了13.5%,但这套组合拳打造的策略,已经具备了实盘运行的稳健性。
八、本篇总结
通过全面的回测对比,我们可以对波动率控制仓位得出以下结论:
-
改善是显著的:最大回撤降低约40-50%,夏普比率提升约30-40%。
-
代价是可控的:年化收益率通常下降2-3个百分点,但换来了大幅提升的风险调整收益。
-
参数选择有据可依:目标波动率12%-15%是个人投资者的甜蜜区间。
-
熊市价值最大:在下跌市中少亏的钱,是未来盈利的种子。
-
与其他风控协同:波动率控制可以和动量过滤、硬止损等手段叠加,形成立体防御。
下一篇预告:波动率控制仓位系列(四)——进阶优化与实盘注意事项
下一篇将是本系列的收官之作。我们将探讨波动率控制的进阶优化方向(如不对称调整、波动率预测),并讨论实盘中需要注意的细节:调仓频率与波动率窗口的协调、目标波动率的动态设定、以及极端行情下的模型失效应对。咱们下篇见!

