← 文档库
📄 文档learn/选股策略/02-选股-因子回测验证与修正.md
🌱 创建于2026-07-02 10:52
✏️ 修改于2026-07-02 10:55
👁️ 浏览量—
🔗 短链接/~learn/s/c760fbc6
🔐 可见性

选股因子回测验证与修正

> 最后更新:2026-07-02 > > 本文档记录选股因子的实际回测验证过程和修正结论。它是 01-选股-多因子设计方案 的后续验证文档——设计方案提出了 5 因子框架,本文档用数据证明其中 4 个因子在 A 股上无效并修正为单因子动量。

---

一、背景

设计方案 V1 提出 5 个等权重因子:

因子 名称 预期作用
---------------------
momentum 动量(40+80 日,R² + 回撤惩罚) 选出趋势最强势的股票
stability 波动率稳定性 奖励平稳上涨、惩罚剧烈波动
anti_overbought 反追高 避免买入涨得过高的股票
volume_confirm 量价确认 奖励放量上涨、惩罚缩量下跌
liquidity 流动性 剔除无人问津的股票

首次全量跑完后,选出的 TOP 10 如下(2026-07-02):

排名 代码 名称 评分 20日涨幅
----------------------------------
1 600705.SH 中航产融 0.807 —
2 600837.SH 海通证券 0.794 —
3 688158.SH 优刻得 0.758 -5.6%
4 300435.SZ 中泰股份 0.766 —
5 300058.SZ 蓝色光标 0.770 —

直觉上就不对——一堆跌的、横盘的股票竟然进了 TOP。下面用数据逐因子剖析。

---

二、因子诊断(2026-07-02 截面,1145 只股票)

2.1 反追高因子(anti_overbought)—— 彻底失效

得分分布: mean=0.909, p25=1.0, p50=1.0, p75=1.0
得分=1.0 的比例: 937/1134 = 82.6%
得分为 1.0 的股票过去 20 日均收益: -7.65%(正收益仅 9/50)

为什么会这样?

反追高因子的设计是:偏离 60 日均线 < 15% 不惩罚(得满分 1.0),偏离 15%-50% 线性惩罚。

但在 A 股现实中,「偏离均线 15% 以上」是一个极罕见的场景——大部分股票要么在均线附近震荡(得 1.0),要么在均线下方(还是得 1.0,因为偏离度 < 15%)。只有在短时间内暴涨 15%+ 的妖股才会被惩罚。

结果:82.6% 的股票得分完全相同(=1.0),等于 20% 的权重被浪费,而且得满分的股票里 82% 在亏钱。

2.2 量价确认因子(volume_confirm)—— 公式有 bug

量价确认 = sign(20日收益) × (20日均量/60日均量 − 1)

这个公式的致命缺陷:

下跌缩量的死股被奖励 +0.5,这完全违背了「量价确认」的本意。回测中「动量 + 量价确认」组合每期收益仅 +0.15%(其他组合 +2% 以上),接近腰斩。

2.3 稳定性因子(stability)—— 方向错误

stability = 1 − (40日波动率 / 120日波动率)

这个公式奖励「近期波动远小于历史波动」的股票。但问题是——在 A 股,一只从 100 跌到 50 再横盘 40 天的股,40 日波动极低、120 日波动很高,stability = 1 − 0.2/0.5 = 0.6,比正常温和上涨的股得分还高。

结论:稳定性因子奖励的是「跌完以后死掉的股票」,而非「稳步上涨的股票」。

2.4 流动性因子(liquidity)—— 量纲不兼容

liquidity = avg_amount × 0.5 + avg_turnover × 0.5

日均成交额 6 亿(如招商银行)→ score = 3 亿。日均成交额 6000 万(小盘股)→ score = 3000 万。量纲差异 50000 倍,rank 归一化后勉强能用,但和动量因子的 rank 分数放在一起加权,信息比例完全失衡。

---

三、回测验证

3.1 回测参数

参数 值
-----------
股票池 1249-1405 只(缓存中有数据的过滤后股)
时间范围 2024-10-11 → 2026-05-29(20 个月)
频率 双周(周五),79 期
持仓 每期选 Top 10 等权
基准 每期所有过滤后的股票等权
评估 持有 20 个交易日的平均收益

3.2 结果

配置 每期均收益 胜率 累积收益 vs 基准
------:--::--::--::--:
动量(40+80日,R²+回撤惩罚) +5.33% 61% 1324% ✅ 胜出
原始 5 因子(含反追高) +2.98% 59% 716% ❌ 落后
动量(20+40日,无回撤惩罚) +2.90% 62% 375% ❌ 落后
动量(60日纯收益) +2.20% 57% 237% ❌ 落后
动量+稳定性+量价 +2.42% 58% 396% ❌ 落后
基准(等权全市场) +3.49% — 1258% —

3.3 核心结论

3.4 当前选股实操验证(2026-07-02 截面,纯动量)

排名 代码 名称 行业 20日涨幅 40日涨幅
--------------------------------------------
1 920438.BJ 戈碧迦 元器件 +129% +265%
2 300868.SZ 杰美特 元器件 +49% +119%
3 300975.SZ 商络电子 元器件 +17% +148%
4 688766.SH 普冉股份 半导体 +134% +221%
5 003004.SZ 声迅股份 IT设备 +11% +148%
6 301188.SZ 力诺药包 玻璃 +50% +137%
7 605376.SH 博迁新材 小金属 +44% +108%
8 301200.SZ 大族数控 专用机械 +35% +107%
9 688545.SH 兴福电子 元器件 +89% +158%
10 688233.SH 神工股份 半导体 +201% +235%

所有 10 只股过去 20 日全部正收益!

---

四、当前因子规格(最终采用)

动量因子(唯一因子)

raw = 40日收益 × 0.6 + 80日收益 × 0.4

R²趋势质量:
  对 40 日归一化价格做线性回归
  slope ≤ 0 → R² 为负值(下跌趋势打负分)
  slope > 0 → R² 越大越得分(趋势越平滑越高)
  clamp(R², -1, 1); min(R², 0.3)

回撤惩罚:
  距 80 日高点回撤 0~5%   → 不惩罚(×1.0)
  距 80 日高点回撤 5~15%  → 轻微惩罚(×0.7)
  距 80 日高点回撤 >15%   → 重度惩罚(×0.3)

final_score = raw × max(R², 0.3) × 回撤惩罚

归一化 & 加权

normalize(method='rank')  → 百分位排名(0-1 区间)
weight = 1.0
无其他因子参与加权

分散化

---

五、文件结构

selection/stock/
├── factor/
│   ├── momentum.py          # ★ 唯一生产因子
│   ├── stability.py         # 保留但未使用
│   ├── anti_overbought.py   # 保留但未使用
│   ├── volume_confirm.py    # 保留但未使用(公式有 bug)
│   └── liquidity.py         # 保留但已改为 StockDataFetcher 的过滤层
├── backtest_simple.py       # 回测脚本(可随时重新验证)
└── engine.py                # _default_selector() 已改为单因子动量

保留其他因子代码的目的是方便后续继续实验——任何新因子想法都可以通过 backtest_simple.py 加一行配置快速验证。

---

六、下一步 TODO

▶ 📜 变更历史(2 次提交)

9872ff22026-07-02 10:55docs: 选股文档文件名补上「选股」前缀,与ETF文档明确区分
8a14dfc2026-07-02 10:52docs: 选股因子回测验证报告 — 从5因子到纯动量的修正历程
🍃quant 知识库
by 伊甸园和枫

🔊 播放设置

勾选音源后调节配比,总和自动归一化
已选 0 个 · 合计:0%
合成中...
00:00/00:00
1.0x

分享图片

生成中...