策略族谱:每个族在什么条件下失效
事后标签说"趋势跟随牛市 19%、熊市 -19%";换成交易时拿得到的标签,结论反过来——两套标签只有 50.4% 重合
把五个策略族放在同一批标的、同一个引擎上跑 16 年,再按市场状态拆开。
事后划分的表符合所有人的直觉:
牛 震荡 熊
趋势跟随(双均线) 19.03 3.71 -19.22
买入持有 34.29 9.76 -25.91
换成交易时真能拿到的标签(只用过去数据),同一批净值曲线:
近6月强 近6月平 近6月弱
趋势跟随(双均线) -2.46 3.71 7.08
买入持有 -0.88 3.94 31.82
两张表说的是反的。而它们用的是同一批净值曲线——变的只是"怎么给日子贴标签"。
原因在最后一节:两套标签的桶大小几乎一样(856 日 vs 856 日),但只有 50.4% 重合。
"雨天带伞"是对的。
但天气预报说的是"明天下雨"——而事后统计说的是"那天下雨了"。
用后者算出来的带伞收益率,你一天也享受不到。
一、五个族,同一个引擎
五个族都能用单标的引擎表达,所以口径严格一致(同一份数据、同一套撮合规则、同样的成本):
| 族 | 规则 | 属于哪一类 |
|---|---|---|
| 趋势跟随 | 双均线 5/20,上穿持有 | 追随价格方向 |
| 均值回归 | 跌破布林下轨买入,回到中轨卖出 | 押价格回到中枢 |
| 时序动量 | 过去 12 个月(剔除最近 1 个月)收益为正则持有 | 追随中期方向 |
| 波动率目标 | 目标年化波动 15%,按实测波动缩放仓位 | 不预测方向,只管风险 |
| 买入持有 | 全程满仓 | 基准 |
全样本表现(8 只股票均值,2010-01 ~ 2026-07):
| 策略族 | 年化% | 最大回撤% | 夏普 | 成交笔数 |
|---|---|---|---|---|
| 趋势跟随(双均线) | 0.43 | -59.4 | 0.133 | 258 |
| 均值回归(布林带) | 0.30 | -43.0 | 0.107 | 128 |
| 时序动量(12-1) | 1.17 | -61.6 | 0.171 | 122 |
| 波动率目标(15%) | 3.58 | -41.4 | 0.301 | 2118 |
| 买入持有 | 3.00 | -60.0 | 0.256 | 2 |
四个"策略"里三个跑输买入持有。唯一跑赢的是波动率目标——而它不预测任何方向,只按实测波动缩放仓位。
它赢的方式也不是多赚:年化只高 0.58 个百分点,但最大回撤从 -60.0% 降到 -41.4%。这个族的价值在风险端,不在收益端。
上表是"逐股算年化、再取算术平均"的口径。换一种汇总方式,这个 +0.58 pp 会翻转。
同一批回测,如果改成"8 只票的日收益等权合成一个组合、再算年化":
| 汇总口径 | 波动率目标 | 买入持有 | 超额 |
|---|---|---|---|
| A 逐股年化再平均 | 3.58% | 3.00% | +0.58 pp |
| B 日收益等权成组合 | 4.28% | 5.87% | -1.59 pp |
两个口径都没算错。 差别来自等权日频再平衡降低了组合波动,而波动拖累约等于方差的一半——成分越波动,能被拿回来的拖累越多:
成分年化波动均值 波动率目标 15.8% 买入持有 31.1%
等权组合年化波动 波动率目标 10.8% 买入持有 21.3%
B 相对 A 的增益 波动率目标 +0.70pp 买入持有 +2.87pp
买入持有的成分本来就更波动(它没有任何降波动作),所以在 B 口径下获益更多,直接把 +0.58 吃成了 -1.59。
"波动率目标跑赢买入持有"这句话,必须带上口径才成立。本节后续的状态拆分统一用 B 口径(等权组合日收益),因为按状态切分本来就要在同一条曲线上切。
复核脚本见 p5.6 的
code/agg_check.py;该节还会对这个 +0.58 pp 做区间检验,结论是区间跨 0。
二、但"全样本年化"这个数几乎没有信息量
因为它把 16 年里完全不同的市场状态摊平成了一个数——这正是 p4.8 那个"平均血压"的问题。
拆开看。用两套完全不同的标签拆两次。
甲、事后划分(用当期前后各 63 日的区间收益)
| 策略族 | 牛 | 震荡 | 熊 |
|---|---|---|---|
| 趋势跟随(双均线) | 19.03 | 3.71 | -19.22 |
| 均值回归(布林带) | 5.89 | 0.32 | -2.83 |
| 时序动量(12-1) | 25.50 | 3.48 | -18.71 |
| 波动率目标(15%) | 21.53 | 4.76 | -13.95 |
| 买入持有 | 34.29 | 9.76 | -25.91 |
(单位:年化收益 %,8 只股票等权)
这张表符合所有人的直觉,而且能读出每个族的真面目:
- 趋势跟随 = 削峰填谷:牛市比买入持有少赚 15.3 个百分点,熊市少亏 6.7 个百分点。它没有创造收益,它在搬运收益
- 均值回归在熊市跌得最少(-2.83%),但牛市也只有 5.89%——它大部分时间空仓
- 时序动量牛市最强(25.50%),因为它抓的就是持续性
乙、可实盘划分(只用过去 126 日收益,不含当日)
| 策略族 | 近6月强 | 近6月平 | 近6月弱 |
|---|---|---|---|
| 趋势跟随(双均线) | -2.46 | 3.71 | 7.08 |
| 均值回归(布林带) | -0.75 | -1.24 | 12.79 |
| 时序动量(12-1) | -0.73 | 1.89 | 11.88 |
| 波动率目标(15%) | 2.45 | 2.65 | 15.96 |
| 买入持有 | -0.88 | 3.94 | 31.82 |
每一族的最强状态都变成了"近6月弱"。
"这两张表矛盾"——它们不矛盾,它们在说不同的事。
甲表的标签是“这段时间是不是牛市”,乙表的标签是“过去半年涨了还是跌了”。
甲表需要知道未来 63 天,交易时你拿不到。乙表只用过去数据,交易时你拿得到——代价是它测的东西变了:它测的是"过去半年跌了 10% 之后,接下来的收益如何",而本样本给出的答案是 31.82% 年化。
这就是为什么"牛市该做趋势、熊市该空仓"这类说法几乎无法证伪:
它成立的那张表,你交易时拿不到;你拿得到的那张表,结论不一样。
凡是按"牛市/熊市"给策略择时的说法,先问一句:那个标签,当时拿得到吗?
三、桶一样大,装的不是同一批日子
两套划分的桶大小几乎完全一致:
甲(事后) 牛 1063 日 震荡 1978 日 熊 856 日
乙(可实盘) 近6月强 1063 日 近6月平 1977 日 近6月弱 856 日
但重合度只有一半:
| 两套标签落在对应桶里的比例 | 50.4%(3833 个可比较日) |
| 事后"熊"的 856 日中,当时也标为"近6月弱"的 | 309 日(36.1%) |
| 事后"牛"的 1063 日中,当时标为"近6月强"的 | 536 日(50.4%) |
事后被认定为熊市的日子里,近三分之二在当时看起来并不弱。
这就是两张表结论相反的全部来源——不是策略变了,是"哪些日子被归到哪个桶"变了。
四、波动率目标唯一跑赢,但先过成本这一关
它一只股票 16 年成交 2118 笔,平均两天一次。按 p4.2 的纪律,任何高换手结论都必须先做成本敏感性:
| 成本档 | 波动率目标 年化% | 买入持有 年化% | 超额 pp |
|---|---|---|---|
| 零成本 | 3.74 | 3.00 | +0.73 |
| 默认(2.5bp + 5bp 滑点) | 3.58 | 3.00 | +0.58 |
| 翻倍(5bp + 10bp 滑点) | 3.45 | 2.99 | +0.46 |
| 四倍(10bp + 20bp 滑点) | 3.18 | 2.98 | +0.20 |
超额随成本单调衰减,四倍成本下只剩 0.20 个百分点——基本被抹平。
所以这个族的正确说法不是"波动率目标跑赢买入持有",而是:
在本样本、本成本假设下,它用几乎相同的收益换到了小得多的回撤(-41.4% vs -60.0%);而它的收益端超额对成本高度敏感,不该被当成 alpha 来报。
🔧 动手做:唯一"跑赢"的族,经不经得起成本?(5 分钟)
五个族里只有波动率目标族全样本跑赢买入持有——但它一年换手上百次。跑 python cost_check.py。
你会看到(实测):它对买入持有的超额,零成本时 0.73pp,加上默认成本(2.5bp+5bp 滑点)只剩 0.58pp,而它做了 2118 笔成交。
想明白:唯一的"赢家"赢的幅度薄到 0.58pp、还靠上千笔换手撑着——成本再高一点、滑点估错一点,它就翻负。任何高换手的"跑赢",先过成本这一关,十有八九过不去。
五、族谱的正确用法
不是"从里面挑一个最好的",而是知道每个族的失效条件:
| 族 | 什么时候失效 |
|---|---|
| 趋势跟随 | 无趋势的反复震荡(反复被打脸);牛市中放弃大量收益 |
| 均值回归 | 趋势持续走坏时(下轨买入后继续跌) |
| 时序动量 | 趋势拐点处(信号最滞后) |
| 波动率目标 | 高换手 → 成本敏感;波动骤升时被动减仓,可能减在底部 |
| 买入持有 | 需要承受 -60% 的回撤和 p4.8 那个 1207 日的水下期 |
而"什么时候该换族"这个问题,已经被本节堵死了一半:能给出漂亮答案的标签需要未来数据,能实时拿到的标签结论不同。
这正是 p5.5 滚动前推验证要正面处理的问题:不靠事后标签,而是只用截止当日的信息做决策,再看接下来发生了什么。
📌 免责:本课为技术教学,标的为沪深300 成分股按代码序取样(非精选),五个族均为教学演示口径,所有回测为历史模拟,不构成投资建议。
三件事:
- 全样本年化几乎没有信息量。五个族里四个"策略"有三个跑输买入持有(3.00%);在逐股平均口径下唯一跑赢的波动率目标(3.58%)不预测任何方向,它的价值在最大回撤 -41.4% vs -60.0%,而收益端超额在四倍成本下只剩 0.20 pp——换成等权组合口径,这 +0.58 pp 直接翻成 -1.59 pp
- 同一批曲线,两套标签,结论相反。事后划分:趋势跟随牛市 19.03%、熊市 -19.22%(削峰填谷:牛市少赚 15.3 pp,熊市少亏 6.7 pp);可实盘划分:每一族的最强状态都是"近6月弱",买入持有 31.82%
- 原因是桶一样大但装的不是同一批日子:两套标签重合度 50.4%,事后"熊"的 856 日里当时也算弱的只有 309 日(36.1%)
一条可以直接用的追问:凡是按"牛市/熊市"给策略择时的说法,先问"那个标签当时拿得到吗"。
下一节进入多因子:因子怎么合成、为什么必须做行业与市值中性化、分层测试怎么读。只讲方法,不给任何标的名单。
🔎 来源与核验· 5 条,点开核对
