动量 Plus:2015 成分股的季度再选股¶
一键复现:
uv run python -m knowledge.Labs.momentum_plus_lab.run_lab种子来自本机冻结快照,不访问网络:uv run python -m knowledge.Labs.momentum_plus_lab.build_seed
这间实验室和旁边的 动量实验室 不是同一件事。那边用的是今天市值最大的 30 只股票,按月换仓。这里先锁定 2014-12-24 那一版标普 500 名单(2015-01-01 休市,这是元旦前最后一条公开成分记录),再在每个季度末重新选股、下一交易日收盘再平衡。
绩效区间是 2015-04-01 至 2026-09-28(11.47 年,46 次季度信号)。2014 年的价格只用于 12 个月动量暖机,不进入净值。
股票从哪来¶
公开成分记录里这一天有 464 只代码。同一家公司的两个普通股类别只留一个:去掉 GOOG(留 GOOGL)、去掉 DISCK(留 DISCA)。
雅虎在拉全市场日线时一直返回 HTTP 429,所以可交易池改用已经冻结的研究磁带 futu-us-eq50-bil-20261006。两边都有的名字是 47 只。磁带里有、但 2015 年那份名单里没有的 AMD、MRVL、RTX、BIL 不进池。其余 400 多只 2015 成分没有进这盘磁带,本实验碰不到。
这 47 只从样本第一天到最后一天都有价格。它们是 2015 年就在指数里、并且到 2026 年仍留在研究用大盘股磁带里的公司,所以等权基准本身就带幸存者偏差。比较策略时,对照物是这 47 只的季度等权,而不只是 SPY。
AAPL ADI AMAT AMGN AMZN APH AXP BAC BRK-B C CAT COST CRM CSCO CVX DE DIS GE GILD GOOGL GS HD IBM INTC JNJ JPM KLAC KO LLY LRCX MA MS MSFT MU NFLX NVDA ORCL PG QCOM STX TMO TXN UNH VZ WFC WMT XOM
价格是快照日线加上公司行为做成的前向总收益收盘价,和动量实验室同一套拆股、分红、分拆处理。SPY 来自 yf-us-etf5-20260929,所以共同交易日停在 2026-09-28,不是自然日的“今天”。
时钟和成本¶
每个日历季度的最后一个交易日收盘才算信号。下一交易日的涨跌仍算旧仓,新仓从再下一交易日开始计收益。信号日当天不能既用收盘价打分、又吃到从那天收盘起的涨幅。
前 20% 等权做多。现金收益按 0。单边成本 10 个基点,打在实际成交的权重变化上。夏普按日收益均值除以标准差再年化,无风险利率按 0。
八个策略¶
| 编号 | 规则 |
|---|---|
| S1 | 经典 12-1:跳过最近 21 个交易日,用再往前约 12 个月的涨幅排序 |
| S2 | 同样跳过 21 日,形成期改成约 6 个月 |
| S3 | 和 S1 同一排序,但 12-1 不为正的名额留成现金,不把仓位摊给剩下的股票 |
| S4 | 用 12-1 收益除以同一窗口的波动率来排序,权重仍是等权 |
| S5 | 过去 90 日对数价格的年化斜率乘以 R² |
| S6 | 在同一段 12-1 窗口里去掉对 SPY 的 beta,按特质收益排序 |
| S7 | 收盘价除以过去 252 日最高价,越接近新高越靠前 |
| S8 | 上面四项里的 12-1、残差、Clenow、52 周高做截面标准化后平均。12-1 为正且站上 200 日均线才持有。新进前 20%,已持有的可以留到前 30%。权重按 63 日波动的倒数分配,单名不超过 15% |
S4 只在排序里用一次波动率。配权若再按波动率倒数缩一遍,高波动的上涨股会被罚两次,所以没有那样做。
结果¶
| 模型 | 年化 | 波动 | 夏普 | 索提诺 | 最大回撤 | 卡玛 | 相对 SPY 的信息比 | 年化单边换手 | 平均持仓只数 | 终点倍数 |
|---|---|---|---|---|---|---|---|---|---|---|
| SPY 买入持有 | 14.0% | 17.6% | 0.83 | 1.17 | 33.7% | 0.42 | 0.00 | 0.04x | 1.0 | 4.50x |
| 2015 成分等权 | 22.2% | 19.2% | 1.14 | 1.65 | 30.9% | 0.72 | 1.44 | 0.23x | 47.0 | 9.98x |
| S1 经典 12-1 | 28.5% | 27.6% | 1.05 | 1.52 | 34.3% | 0.83 | 0.84 | 1.60x | 9.0 | 17.78x |
| S2 中期 6-1 | 28.9% | 27.2% | 1.07 | 1.55 | 38.4% | 0.75 | 0.86 | 2.37x | 9.0 | 18.38x |
| S3 绝对动量过滤 | 28.5% | 27.6% | 1.05 | 1.52 | 34.3% | 0.83 | 0.84 | 1.60x | 9.0 | 17.78x |
| S4 夏普动量 | 23.4% | 24.4% | 0.98 | 1.42 | 32.2% | 0.73 | 0.66 | 1.82x | 9.0 | 11.18x |
| S5 Clenow 趋势质量 | 31.0% | 25.8% | 1.18 | 1.70 | 41.2% | 0.75 | 0.96 | 2.88x | 9.0 | 22.20x |
| S6 残差动量 | 28.2% | 25.6% | 1.10 | 1.60 | 31.4% | 0.90 | 0.86 | 1.72x | 9.0 | 17.22x |
| S7 52 周新高接近度 | 11.4% | 19.8% | 0.65 | 0.91 | 37.5% | 0.31 | -0.16 | 2.78x | 9.0 | 3.47x |
| S8 复合 Plus | 19.8% | 22.6% | 0.91 | 1.29 | 33.1% | 0.60 | 0.45 | 2.05x | 9.9 | 7.93x |
S5 的终点倍数最高,夏普也最高。S6 的卡玛最高:收益和 S1 接近,最大回撤停在 31.4%,和等权基准的 30.9% 差不多。S7 跑输 SPY。S8 跑输这 47 只的等权。
S3 和 S1 的每一列都一样。在这 47 只里,12-1 排名前 20% 的股票在 46 个季度末的 12-1 都是正的,绝对动量没有把任何名额留成现金。过滤规则写上了,但这组样本没有给它出手的机会。
2020 年一季度是图上最深的一段共同回撤。S5 后来把净值拉到最高,全样本最大回撤也是八个策略里最深的 41.2%。S7 从 2020 年以后贴着更低的一条轨道走。
2015 年只含 4 月以后,2026 年只到 9 月 28 日。2022 年除了 S7(-4%)以外,各策略和两个基准都是负的。2026 年这段未完成的年份里,S1 和 S6 的涨幅很大,终点倍数受这段行情影响明显。
等权每个季度持有全部 47 只。S1 到 S7 每个季度固定约 9 只。S8 在 2020 和 2022 附近把持仓打到 4 只上下,趋势门槛当时确实减了仓,但全样本收益没有因此高于简单的 12-1。Clenow 的年化单边换手最高,接近 2.9 倍。
45 个完整持有期上,6 个月动量的平均秩相关约 4.7%(t 约 1.40),Clenow 约 3.7%(t 约 0.99)。12-1、夏普动量、残差和复合分数的平均秩相关都接近 0。52 周新高接近度的平均秩相关约 -6.1%(t 约 -1.60),和它跑输 SPY 是同一件事:在这组几乎一直处于牛市的大盘股里,“离新高近”分不出下一季谁更强。误差条都很大,这些 t 值不够把排序能力说成稳定。
怎么读¶
动量在这 47 只上主要加成的是收益,不是每单位风险的稳定性。等权的夏普是 1.14,S1 的夏普是 1.05。多出来的年化收益换来了更高的波动和更深的回撤。S6 是少数把回撤留在等权附近、同时又把年化做到 28% 的变体。S5 把收益做到最高,也把 2020 年那种回撤留在了账上。
S8 说明把更多规则叠在一起,不一定比单用一个排序更好。这里的门槛、缓冲和波动率配权提高了换手,全样本却落在等权下面。
复现¶
uv run python -m knowledge.Labs.momentum_plus_lab.build_seed
uv run python -m knowledge.Labs.momentum_plus_lab.run_lab
build_seed 只读本地快照。run_lab 再检查“信号日的下一交易日仍是旧仓”,然后写出 outputs/ 和 figures/。




