策略评估报告:Doubles

来源: Obsidian Vault

总体评估

这是一份生产就绪程度较高的量化策略文档。逻辑链条完整(翻倍股内部动量延续 → LightGBM 排序 → 月度调仓),迭代过程透明(v1→v7 + walk‑forward),绩效数据诚实(含生存者偏差警示、成本、horizon mismatch 反思)。主要亮点与待改进点如下。


优点

1. 问题定义清晰,对标明确

  • 明确区分与 B‑Line 的 alpha 来源(动量延续 vs 反转),避免了常见策略组合中的冗余。

  • 承认 生存者偏差 并将基准定为 660 只已翻倍股的等权组合(Alpha = Top - Bench),这是正确的相对评估方法。

2. 实验迭代严谨

  • 从 v1 OHLCV 基线到 v5 加入 r_spread_60d regime indicator 及交互项,每一步都有 OOS 验证和归因。

  • K‑day holding 扫描 是亮点:发现 K=1 负 alpha 并正确归因为 horizon mismatch,而非模型失效。

  • walk‑forward 4 窗口全部正收益(最小 +0.76 Sharpe),过拟合风险较低。

3. 生产约束务实

  • soft sector cap(每组最多 4 只)优于 strict neutral(强制均分导致 alpha 变负),保留了模型对板块的偏斜能力。

  • 停牌处理 fillna(0) 经验证等同于 dropna,无画图偏差。

  • 交易成本(0.10%买+0.15%卖)符合 A 股真实水平。

4. 文档与工程分离良好

  • doubles(数据+模型)与 RD-Agent(LLM 实验)职责清晰,信号输出为标准化 HDF5([datetime, instrument, weight]),可直接对接 OMS。

风险与待改进项

1. 数据源单一依赖(ELTDX F10)

  • 当前翻倍股筛选、估值因子均来自 ELTDX。若该数据源出现延迟或错误(如复权、除息处理不一致),整个信号链会受冲击。

  • 建议:增加备选数据源(如 Wind、聚宽)做交叉验证,至少对关键估值字段(PE、PB)进行一致性校验。

2. 翻倍股 Universe 的稳定性存疑

  • 660 只股票是 历史已翻倍 的集合(2024‑06 至 2026‑01)。未来新进入的翻倍股可能携带不同特征(例如 2026 年小微盘翻倍股与 2024 年赛道股不同)。模型是否能在分布漂移下保持预测力?

  • 当前缓解措施:每月 expanding window 重训,且 walk‑forward 覆盖到 2026‑01 表现稳定。但需要持续监控 特征分布漂移(PSI 统计)和 模型 AUC 衰减

3. 实盘执行细节仍缺失

缺失项 潜在问题
ST/*ST 剔除的数据接入 文中仅写“需接入标记数据源”,若实盘未实现,则可能买入 ST 导致跌停无法卖出。
ADV 容量约束的具体实现 单股仓位 ≤ 20% 的 20 日 ADV,需要盘中实时计算 ADV 并调整权重。文档未说明计算频率(日频?)和 fail‑over 逻辑。
T+1 开盘执行 vs 持仓重叠 每日 T 收盘后选出的 top‑10 将在 T+1 开盘执行,但已有 20 个 sub‑portfolio 滚动。文中未解释 订单执行优先级(例如若 T+1 开盘涨停买不进,如何处理?)。
跌停强平的具体触发条件 “跌停封死 → T+1 集合竞价无条件强平” – 集合竞价的申报时间(9:15‑9:25)可能仍无法成交(封单过大)。没有备选方案(如连续竞价继续挂单)。

4. 绩效指标中缺少几个关键度量

  • 信息比率 (IR) 已给出(ICIR +1.09),但缺少 Calmar 比率(return / max drawdown)和 月度胜率。对于月度调仓策略,月度正收益占比非常重要。

  • 换手率 仅定性说“K=20 自然约束 ≤ 5%”,没有实际 backtest 的平均双边换手率数字。高换手会侵蚀净收益,尤其 top‑10 可能频繁更替。

  • 不同市场环境下的分解:建议按大盘上涨/下跌/震荡期分别展示 alpha。当前 walk‑forward 按时间窗口,但未区分 regime(如 2025‑07 至 08 的高 Sharpe 是否对应大盘强 beta)。

5. 模型解释性不足

  • LightGBM 提供 feature importance,但文档未报告 哪些因子贡献最大。对于风控(如是否隐含市值、行业暴露)需更透明。建议输出 SHAP 值或部分依赖图,至少列出 top‑5 因子。

  • 交互项 d_tradable_mv × r_spread_60d 的引入理由合理(大小盘在不同动量环境下表现不同),但未验证其增量 IC 是否显著。

6. “禁止优化清单” 部分固化过快

  • 例如 v6(scale_pos_weight + 5‑fold CV)失败可能因为 fold 1 数据不足,但 数据不足 是可解决的问题(例如改用时间序列交叉验证,或减少 fold 数)。永久禁止可能过早关闭了一条可行路径。

  • 建议改为“当前版本不采用”而非“已证伪永久禁止”,留出未来数据积累后的重试空间。


实施建议优先级

优先级 行动项 负责人/时间
P0 (上线前必须) 实现 ST/*ST 实时剔除接口 数据工程
P0 落地 ADV 容量计算与动态权重调整逻辑 执行层
P0 跌停强平的分步处理(集合竞价失败后连续竞价继续挂单,并设置止损时限) 风控模块
P1 (模拟盘验证期) 接入备选数据源对 PE/PB 做交叉校验,监控偏差 数据质量
P1 计算并报告月度胜率、Calmar、换手率,按市场 regime 分解绩效 回测增强
P1 输出 top‑5 因子重要性,验证交互项贡献 模型分析
P2 (后续迭代) 定期(每月)监控特征分布漂移(PSI)和 AUC 衰减,设置预警阈值 监控系统
P2 重审 v6 路线(时间序列 CV + 更宽训练窗),作为 v8 候选 研究

结论

该策略在方法论、实验验证、生产约束三方面均达到较高成熟度,主要风险集中在实盘执行细节(ST 剔除、ADV 容量、跌停处理)和单一数据源依赖。建议先完成 P0 项,随后进行 1‑2 个月模拟盘(纸面跟踪) 以暴露执行偏差,再逐步进实盘。当前文档可作为正式策略规范(SOP)使用,但需补充上述缺失的执行细则后,方可通过最终评审。


项目方核实情况(2026-06-14)

针对"风险与待改进项"章节逐条核实,标注 ✅ 已覆盖 / 🔧 待补 / 🚧 需工程。核实方法:grep 代码 + 读报告。

一、已覆盖项(评估文档判断准确)

评估点 核实位置 状态
生存者偏差识别 Doubles 策略总览.md §四 显式警告 "Alpha = Top - Bench 才是真实信号"
Horizon mismatch 诊断 K=1/5/10/20 全扫描, K-day 扫描表已锁定 K=20
Walk-forward 稳定性 4 窗口 expanding retrain, 全正 (Min +0.76, Max +4.11)
Soft vs strict sector cap 6 配置对比已固化, strict 杀 alpha -1.01
RD-Agent 仓库分离 doubles (数据+模型) / RD-Agent (prompt+实验) HDF5 状态隔离

二、待补项(已确认代码缺失,可立即修复)

2026-06-14 更新:5 条待补项 全部已修复 ✅,结果如下。修复脚本:backtest_enhanced_metrics.py,输出:factor_output_enhanced/enhanced_metrics.json

# 评估项 状态 修复后结果
1 Calmar 比率 + 月度胜率 ✅ 已修复 Calmar = +3.71 (Alpha: 年化 +29.43% / MaxDD -7.94%), 月度胜率 = 80.0% (10 月中 8 月正收益)
2 实际换手率数字 ✅ 已修复 K=20 blended weights avg 4.03%/day 双边, max 100% (首日建仓), avg 28.5 只活跃
3 Regime 分解 Sharpe ✅ 已修复 High regime (>median -0.099) Sharpe +2.22 vs Low regime +1.67, Δ +0.55 — alpha 在 spread 高时更强(符合 v5 设计假设,非纯 beta)
4 v5 Top-5 feature importance ✅ 已修复 d_pe (18.1%), d_peg (17.1%), d_tradable_mv (11.7%), d_pb (8.5%), d_pcf (8.4%); 交互项 r_spread_60d #8 (4.1%) + x_mv_x_spread #10 (3.2%)
5 v6/v7 措辞软化 ✅ 已修复 Doubles 策略总览.md §六 改为"不采用清单(当前版本)",v6/v7 标 ⏸ 待重审

判定:3 ✅ + 1 ⚠️(regime delta 偏大但与 v5 设计一致,交互项贡献实证 +7.3% gain,证明 alpha 非纯 beta 暴露)。

三、需 P0 工程项(超出 factor_mining 范畴)

评估项 阻塞原因 责任方
🚧 ST/*ST 实时剔除接口 需要外部标记数据源(Wind/聚宽/Tushare) 数据工程
🚧 ADV 容量约束盘中计算 需要实时 OHLCV 行情接入 执行层
🚧 跌停强平分步逻辑(集合竞价 → 连续竞价) 需要 OMS 配合 + 风控规则 风控模块

四、中期可探索

  • PSI 月度监控(Population Stability Index)— 接 walk-forward 框架, 每月特征漂移预警, ~1 小时
  • v6 时间序列 CV 重审 — 用 TimeSeriesSplit 替代 K-fold, fold 1 数据不足问题可解, 作为 v8 候选, ~半天

五、立即执行优先级

优先级 任务 工作量 价值 状态
P0 (本周) #1 + #2 + #3 + #4 合并到一个增强 backtest 脚本 ~45 min 月度调仓策略必备指标补齐 ✅ 已完成 (2026-06-14)
P0 (本周) #5 改 Doubles 策略总览.md 措辞 ~5 min 不永久关闭 v6/v7 重审路径 ✅ 已完成 (2026-06-14)
P1 (模拟盘期) PSI 月度监控接入 walk-forward ~1 h 实盘漂移预警 ✅ 已完成 (2026-06-14)
P2 (后续迭代) v6 时间序列 CV 重审 (v8 候选) ~半天 数据积累后重试 ⏳ 待办

六、核实结论

评估文档(§风险与待改进项)的 6 条判断 全部成立,无高估或误判。其中:

  • 5 条已覆盖Doubles 策略总览.md 已显式记录或代码已实现
  • 5 条待补 → 全部已修复 ✅ — 见 §二 表格 (2026-06-14 完成)
  • 3 条 P0 工程 — 数据源/执行层/风控模块的接口问题,需跨团队协调

当前状态:doubles 项目已从"研究阶段"过渡到"准实盘 SOP"。配合 Doubles 策略总览.md,可作为正式策略规范使用,待 P0 工程三项接入后通过最终评审。下一步建议:执行 P1 PSI 月度监控,然后进入 1-2 个月模拟盘验证期。


七、Alpha 真实性核查(2026-06-14,关键发现)

2026-06-14 跑真实 benchmark 对比 + 白噪测试,颠覆性修正策略定位

真实 benchmark 对比(5 个基准)

Benchmark Bench Sharpe Bench Total Alpha Sharpe 判定
660等权(生存者偏差) +3.98 +26.10% +1.94 ❌ 虚假基准(生存者偏差)
沪深300 +1.86 +51.78% -0.11 ❌ 跑输大盘
中证500(最公平) +1.91 +57.58% -0.25 ❌ 跑输
创业板指 +2.65 +64.32% -0.44 ❌ 跑输
国证2000(中小盘) +2.22 +33.18% +0.96 ✅ 真实 alpha

白噪测试(100 次随机 pred, 同一 backtest pipeline)

指标 v5 Random mean p-value 判定
Top Sharpe +4.03 +3.23 4.0% ✅ 框架无 bug
Alpha vs 660等权 +1.94 -1.09 0.0% ✅ 极显著
Alpha vs 国证2000 +0.96 -1.04 0.0% 真实 stock selection alpha

核心发现

  1. v5 alpha 真实存在(白噪测试 p < 5%,框架无 look-ahead bias)
  2. v5 alpha 主要来自 universe 选择:660 翻倍股池本身在 2025-05~2026-01 是大风口(A 股上涨期)
  3. 真实 stock selection alpha ≈ +0.96 Sharpe(vs 国证2000 中小盘宽基),不是 +1.94
  4. Random Top Sharpe 平均 +3.23:660 universe 在该期间就是 high-beta 风口,任何选股都有 alpha vs 大盘

策略定位修正

❌ 不能宣称 "Alpha Sharpe +1.94" 作为实盘 alpha(相对生存者偏差 bench) ✅ 策略真实定位是 两阶段 stock picker: - ① universe 选择:从全市场筛 660 只翻倍股(universe alpha vs 大盘) - ② universe 内 selection:v5 LightGBM 选 top-10(stock selection alpha vs 国证2000 ≈ +0.96)

实盘含义

  • 不要用 v5 替代大盘配置——直接买 CSI500 更好(Bench Sharpe +1.91)
  • 当前 production_signals_v5/daily_target_weights.h5 是"660 universe 内的相对权重",不能直接对接大盘 OMS
  • 真实可期待 alpha ≈ +0.96 Sharpe(vs 中小盘宽基),不是 +1.94

下一步

  • A1 重定位(✅ 已完成 2026-06-15,假设证伪):在国证2000 universe 上重训 v5 → Alpha −0.60 ❌。核心发现:v5 的 +0.96 alpha 不来自国证2000 内部选股,而来自 389 只 660∖国证2000 的小盘翻倍股(未进指数)。详见 §八
  • A2 简化版(已完成):当前 v5 信号定位为"660 universe 内的相对权重",benchmark 改为国证2000
  • D 文档同步(已完成):Doubles 策略总览.md §四 加真实 alpha 定位子章节

八、A1 国证2000 Overlay 结果(2026-06-15)

假设证伪:stock selection alpha 不能脱离 660 universe 在国证2000 上直接复现。但揭示了 alpha 真正来源。

执行限制

v5 factors 只覆盖 660 翻倍股,无法在完整 2000 只国证2000 上重训。实际测试 = 271 只(660 ∩ 国证2000)子集,不是完整 A1。

结果

Config Universe n_inst TRAIN AUC OOS AUC OOS IC Alpha vs 399303
v5 原版 660 660 0.91 0.74 +0.044 +0.96
v5 GZH2000 子集 271 271 0.91 0.56 −0.002 −0.60

关键发现 — alpha 真正来源

660 universe = 271 大盘翻倍股(已进国证2000)  →  内部 ranking alpha ≈ -0.60
            + 389 小盘翻倍股(未进国证2000)    →  隐含 alpha ≈ +2.0+ (vs 国证2000)
            = +0.96 blended alpha

v5 的 +0.96 alpha 不来自国证2000 内部选股,而来自 389 只未进国证2000 的小盘翻倍股(规模太小或刚翻倍未被指数纳入)。

实盘含义

  1. 不能把 v5 移植到国证2000 — alpha 源头在 index 之外
  2. 保留 660 universe — alpha 主要来自 universe selection 步骤 + 389 子集 stock selection
  3. ⚠️ 实盘容量警告 — 389 小盘股流动性差,必须接入 ADV 容量约束(P0 工程项)
  4. ⚠️ 生存者偏差仍在 — 每月 expanding retrain + PSI 监控是必需的

A1 任务关闭 — 转向实盘工程

下一步 优先级 工作量
ST/*ST 实时剔除接口 P0 数据工程
ADV 容量约束盘中计算 P0 执行层
跌停强平分步逻辑 P0 风控模块
模拟盘 1-2 个月验证 P1 跟踪
v6 时间序列 CV 重审(v8 候选) P2 ~半天

九、P0 实盘工程三项落地结果(2026-06-15)

脚本:backtest_production_constrained.py,输出:factor_output_constrained/constrained_backtest.json

6 配置对比

Config Top Sharpe Alpha vs 国证2000 MaxDD 判定
C1 baseline (无约束) +4.03 +0.96 −12.0% 理论 alpha
C2 +ST/*ST 剔除 +4.25 +1.11 −9.3% ✅ +0.15 改善
C3 +ADV cap (AUM=1亿) +2.11 −1.77 −32.2% ❌ 翻负
C4 +ST +ADV cap +1.96 −1.80 −32.2%
C5 +ADV filter (≥100万) +1.69 −0.72 −21.2%
C6 +ST +ADV filter +1.60 −0.88 −19.9%

P0-1 ST/*ST 剔除 ✅ 通过

  • 数据源:MySQL stock_fundamentals.name(snapshot,含 ST/*ST 标记)
  • 实现:日级 universe 过滤,从 660 中剔除 30 只 ST/*ST
  • ⚠️ Look-ahead bias:snapshot 是 2026-06 当前状态,backtest 期实际 ST 状态可能不同
  • 效果:Alpha +0.15 Sharpe,MaxDD 改善 -2.8%
  • 生产接入(2026-06-15)production_signal_generator.py 已加 APPLY_ST_FILTER=True 开关,输出到 production_signals_v5_st/。原版 selections 含 9 只 ST,新版 0 只,Alpha Sharpe +1.94 → +2.13(vs 660 等权 bench)。

P0-2 ADV 容量约束 ❌ 1 亿 AUM 不可行

  • 数据源:qlib $volume × $close → 20d 滚动 ADV(金额)
  • 容量评估:单股极低 ADV 6.3 万元(异常),中位 ADV 184 万元
  • 关键发现:AUM=1 亿时单股仓位 500 万元,多数股票 ADV×20% < 500 万,cap 触发后权重错配,Alpha 从 +0.96 翻负到 -1.77
  • 真实容量上限:v5 660 universe 实盘容量 ≈ 2000-3000 万元(中位 ADV 假设理论值 7400 万,安全边界实际 3000 万)
  • 印证 A1 发现:v5 alpha 主要来自 389 小盘翻倍股,流动性约束是硬瓶颈

P0-3 跌停强平 ⏳ 写 spec(OMS 范畴)

详见 §十。

实盘可行性结论

场景 可行性 说明
个人投资者 < 3000 万 ✅ 可行 ST 剔除后 Alpha +1.11,ADV 不构成瓶颈
个人投资者 3000 万-1 亿 ⚠️ 部分可行 需降 K(如 K=10)或加 ADV universe filter(alpha 衰减到 -0.72)
机构 > 1 亿 ❌ 不可行 ADV cap 让 alpha 翻负,需重新设计策略

十、P0-3 跌停强平 Spec(OMS 工程规范)

触发场景

持仓股在 T 日 09:25 集合竞价显示跌停封单(卖一档挂单量 > 流通盘 0.5% 或 > 5 万手)。

数据契约

数据源 字段 频率 用途
实时行情 ask1_price, ask1_volume, bid1_price, bid1_volume Tick 跌停封单检测
持仓表 instrument, shares, avg_cost, K_entry_date 日度 识别需强平的 K-portfolio
ST 标记 is_st (来自 stock_fundamentals.name snapshot) 日度 ST 跌停阈值 ±5% vs 普通 ±10%

分步处理流程

T 日 09:25 集合竞价:
  Step 1: 扫描持仓股, 检测跌停封单 (ask1_price ≤ pre_close × (1 - limit_pct))
          limit_pct = 0.05 (ST) / 0.10 (普通) / 0.20 (科创板/创业板)

  Step 2: 若封单量 > 流通盘 0.5%:
          → 标记为 "强平候选"
          → 申报卖出 (与开盘价 100% 撮合)

  Step 3: 09:25-09:30 集合竞价结果:
          → 成交: 释放 K-portfolio 槽位
          → 未成交 (封单过大): 进入连续竞价

  Step 4: 09:30-11:30/13:00-15:00 连续竞价:
          → 挂单价格 = 当前买一价 + 0.01 (确保成交)
          → 重新挂单频率: 每 30 秒检查一次
          → 14:57 仍未成交: 进入收盘集合竞价

  Step 5: 14:57-15:00 收盘集合竞价:
          → 申报卖出 (与收盘价 100% 撮合)
          → 15:00 仍未成交: T+1 日重复 Step 1

  Step 6 (T+1 日): 同 Step 1-5, 直到全部强平完成

风控约束

  1. 强平不撤单:一旦标记强平,禁止转回持有(避免情绪化决策)
  2. 跌停封单监控:09:25 封单量 > 5 万手且 > 流通盘 0.5% → 自动触发
  3. K-portfolio 占位:强平期间该 K 槽位禁用,不重复选股(避免重复建仓)
  4. 告警机制:连续 3 日跌停未成交 → 邮件/短信告警,转人工

接口规范

接口 方法 输入 输出
check_limit_down(instrument, pre_close, ask1) 同步 跌停状态 + 封单量 bool (是否需强平)
submit_force_close(instrument, shares, reason) 异步 卖出订单 order_id
get_force_close_status(order_id) 同步 order_id status (filled/partial/cancelled)

责任分工

模块 责任方 工作量
实时行情接入 数据工程 1 周
跌停封单检测 数据工程 3 天
强平订单管理 执行层 1 周
K-portfolio 槽位管理 因子工程 3 天
告警 + 人工 fallback 风控模块 3 天
合计 ~3 周

测试要求

  • 历史回放:用 2015 股灾 + 2024-01 雪球 + 2025-04 关税战数据回放跌停场景
  • 模拟盘:1-2 个月观察真实跌停频率与强平成功率
  • 上线前必过:连续 5 个真实跌停案例全部成功强平