← 返回文档中心 · 来源:Languangxun/stock-analyzer · 同步于 2026-09-27

触发:过拟合/前视偏差审计后的口径修复。所有数字均为修复后口径重跑, 与 README 旧版(2026-09-13 白天及以前)不可直接比较。

原始日志与耗时:research/rerun_20260913/{status.txt,*.log}。 修订代码:stock_gui.py(算法源)、stock_predict.py(自动生成)、 backtest_strategy_portfolio.py、backtest_picks.py、 backtest_exit_ablation.py、backtest_exit_roll.py、 backtest_portfolio_overlay_opt.py、backtest_aggr_lottery.py、 factor_lab/chips.py 等。


一、本次修复的口径(为什么旧数字作废)

# 问题 修复
1 同日成交前视:因子/模型含 T 日收盘,却按 T 日收盘价成交 改为早盘信号:决策只用 T-1 及以前信息,T 日收盘执行;止损单在前一日收盘后设定、T 日盘中触发。覆盖 backtest_signals / _bt_events / _v4_portfolio_sim / 组合 slot/sleeve
2 验证集参与选型:消融推荐档按 val Calmar 选 推荐档改为只看训练集 Calmar,验证集仅报告
3 幸存者偏差:组合回测按”结束日距最新日 ≤45 天”剔除退市股 统一近端窗口(val 252 日 / 全样本 1000 日),窗口内退市/长停持仓按最后收盘价了结(20 根无 bar)
4 选股池未来信息:backtest_picks 用回测末日价格<2、当前 ST 名称预筛 仙股过滤改为评估日当天;不再用当前名称预剔 ST
5 hfq 绝对价格失真:彩票策略按后复权价做低价分位 按 _get_adjust 转现价口径(离线库 1366/1367 只缺系数,仍在报告中提示失真)
6 同日止损前视:ATR/Q10 用含当日 high/low/close 的值判当日盘中 止损用 T-1 的 ATR/Q10,T 日盘中触发
7 涨停价成交假设:--allow-limit-up-tiers 默认含激进档 默认全档禁止涨停价买入(显式参数可复现旧口径)
8 参数网格同段选优(彩票 48 组) 彩票网格改为前 2/3 选参、后 1/3 holdout
9 factor_lab/chips.py 负索引越界(25 只股票异常) 网格边界钳制,样本复核 400/400 无异常
10 daily_picks 可荐出陈旧/退市股;盘后仍伪装盘中 只取近 10 日有 bar 且未登记退市的代码;盘中 live 限 9:25–15:00

模型本身未变:v4 模型 IC 与旧报告几乎一致(ml IC 0.0157→0.0159), 以下差异主要来自成交时点 + 样本口径,不是模型重训效果变化。


二、每股策略消融(全A 5520 只,训练/验证 75/25)

产物:research/strategy_ablation_{per_stock,summary}.json(22:21 重跑,184s)。

档位 训练集年化中位 验证集年化中位 验证集胜率中位 验证集回撤中位 验证交易数中位
稳健 +18.6% -1.6% 40.0% -15.5% 8
均衡 +22.0% -2.1% 40.0% -19.6% 9
  • 选型算法分布(稳健档):RSI 21.0% / 布林 19.3% / 多维评分 16.9% / KDJ 16.6% / MACD 12.3% / L1 10.9% / MA趋势 3.2%。
  • 牛/熊分段(训练段):稳健 牛+28.6% / 熊+10.2%;均衡 牛+38.3% / 熊+7.8%。
  • 结论:逐股选型在训练段很漂亮(+18~22%),到样本外中位数归零转负; 这是典型的选择偏差(每只股票在 ~21 个候选里挑),不能当作可交易收益。

三、组合回测(每股消融选型聚合,slot)

产物:research/strategy_portfolio_slot_{val,all}.json。

3.1 验证段(2025-08-29 ~ 2026-09-11,241 日,5205 只,样本外)

档位 年化 回撤 Calmar Sharpe 胜率 PF 交易 超额(vs 上证)
稳健 +2.5% -10.4% 0.24 0.25 37.0% 1.06 135 +1.8pp
均衡(原冠军:弱市覆盖+停开仓) -30.6% -35.9% -0.85 -2.46 23.9% 0.36 88 -31.3pp
激进(覆盖不停开仓) -21.3% -25.4% -0.84 -1.54 28.4% 0.51 81 -22.1pp
基准 上证 +0.8% -11.3% 0.07 0.13 — — — —

3.2 全样本近端 1000 日(2022-08-01 ~ 2026-09-11,5328 只,含选型训练段)

档位 年化 回撤 Calmar Sharpe 胜率 PF 交易 超额
稳健 +13.8% -21.7% 0.64 0.82 37.5% 1.27 579 +9.4pp
均衡 +10.0% -31.5% 0.32 0.58 36.2% 1.16 334 +5.6pp
激进 +17.7% -22.9% 0.77 0.95 38.3% 1.34 311 +13.3pp
基准 上证 +4.4% -20.4% 0.21 0.36 — — — —

注意:全样本含每股选型的训练段(75%),本身偏乐观;样本外只有 3.1 的 val。 弱市覆盖层(均衡/激进)在修正口径下从”增强”变成”拖累”;覆盖层寻优协议 (portfolio_overlay_opt.json)在 train→val 下对均衡/激进选中的也是 “基线(无弱市覆盖)”,且参数平台检查多为”孤峰”。


四、v4 全A(Walk-Forward ML + 三档,5411 只)

产物:research/v4_report.json / v4_factors.json(22:18 重训完成,耗时 8316s)。

组合窗口:2025-08-15 ~ 2026-08-28(252 日,5100 只;退市股保留)

模型 IC 方向命中 样本
LightGBM (H=1/5/10 动态) 0.0159 50.5% 1.90M
q50 0.0120 50.7% 1.90M
p_up 0.0104 50.8% 1.90M
adaptive 0.0048 50.2% 1.90M
L1 形态 0.0038 50.5% 1.90M
  • 过拟合标记:是。LightGBM 训练段 IC 中位 0.645 vs 测试段 0.0159(差 0.63)。
  • 分位数覆盖:10–90 档 76.2%(目标 80%),pinball 0.012–0.026。
策略(252 日) 年化 回撤 Calmar Sharpe 交易
baseline:激进(多维评分) -19.8% -26.9% -0.73 -0.66 126
adaptive:平衡 -39.3% -47.9% -0.82 -1.73 204
full:保守 -7.2% -25.3% -0.29 -0.32 205
full:平衡(旧文档主推 exit_p=0.50) -43.2% -61.0% -0.71 -1.33 338
full:激进 -3.0% -56.6% -0.05 +0.15 149

旧报告(同日成交 + 45 天对齐):full:保守 +12.4% / full:平衡 +1.1% / full:激进 +13.6%; 新口径下分别变为 -7.2% / -43.2% / -3.0%。旧头部策略数字全部作废。


五、退出层消融与滚动复核

产物:research/v4_exit_ablation_{aggr,bal}.json、v4_exit_roll_*.json。

激进档(窗口前 126/252 日 vs 后 126 日)

变体 年化 回撤 Calmar 前半段年化 后半段年化
Full(默认) -3.0% -56.6% -0.05 +? -?
无升档再入场(选优第一) +37.0% -45.3% 0.82 +91% -0%
Q25 mkt<-2.0% +20.0% -42.6% 0.47 +59% -9%
min_hold=5 +19.5% -49.7% 0.39 +37% +5%
Q50棘轮(最差) -73.5% -74.7% -0.98 -77% -72%
  • 收益几乎全部来自 2026-06 之前的窗口,2026 下半段普遍回吐;这些变体是在 同一 252 日窗口全样本排序得到的头部候选,包含明显选择偏差。
  • 滚动 walk-forward(v4_exit_roll):激进 Full 2025 段 +12.5%、2026 段 -15.6%(回撤-56.6%);

    Q25 mkt<-2.0% 是少数 2026 仍为正的变体(+5.2%),但默认参数与前半段差异不大, 单窗口证据不足。

进出场寻优(v4_entry_exit_opt.json,T12 选参 / S3 留出)

档位 选参赢家 S1 年化 S2 年化 S3 留出年化 滚动 WF(仅 1 折)
保守 a_th-0.2 + 无Q10止损 +7.6% +47.0% +25.3% test +106% vs 默认 +53%
平衡 weak Q25 mkt<-0.6%+exitP.55 +34.0% -39.4% -82.0% test -82.9%
激进 无再入场升档 +3.0% +147.6% -73.4% test -79.3%

只有保守档留出段为正;平衡/激进留出段崩掉。WF 只有 1 折(2026-06-17~08-28), 不构成稳健证据。


六、每日荐股回测(去未来池过滤后)

产物:research/picks_backtest.json(T 日收盘打分 → T+1 开盘成交;250 日/步长5)。

口径 年化 回撤 Calmar Sharpe 胜率 PF 交易
旧(当前 ST/末日价预筛 = 幸存者/未来信息) +2.9% -28.5% 0.10 0.58 35.8% 1.04 109
本次修复后(时点价格、全池) -33.6% -37.7% -0.89 -3.20 28.2% 0.48 110

这是本次复核中变化最大的单项:旧结果几乎完全依赖”未来不会退市/不会变 ST / 最后一期价格≥2元”的股票池筛选。修复后当前荐股逻辑在该窗口为明显亏损。


七、激进双引擎(创业板·低价彩票)

产物:research/aggr_lottery_chinext_val_{big,small,grid}.json (旧 _final 文件为旧口径,不再引用)。

配置 区间 收益/回撤 Calmar 基准(创业板指) 超额
大资金(股票核心 top20/40日 + 彩票10%) 2025-03-18~09-04 +48.6% / -22.2% 1.40 +47.5% / -25.8% 约 +0.7pp/年
小资金(ETF核心MA60 + 彩票20%) 同上 +69.6% / -14.0% 3.10 同上 约 +13pp/年

网格留出(前 2/3 选参 2025-03-18~2026-03-13,后 1/3 holdout 2026-03-16~09-04,48 组)

  • selection 最优(lot_frac=0.10, lot_k=20, hold=5, vr=1.5, drop=-6%): 选参段 +36.1%/年、Calmar 2.12 → holdout +18.3%/年、Calmar 0.99、胜率 63.2%。
  • 48 组 holdout 年化全部为正(+10.1% ~ +24.7%,中位 +19.5%)。
  • 但:① holdout 段创业板指本身上涨;② 离线库 1366/1367 只股票缺 adjust 系数, 低价分位/价格上限仍用 hfq 原值,彩票选股逻辑可能失真;③ 大资金档相对指数 超额接近 0(彩票右尾主要来自 beta)。

八、其他脚本(修复后口径)

脚本/产物 关键结果
backtest_t5.py T+5 方向命中 51.2%、IC +0.0343 (t=2.30);k=1.3 时 P25-P75 覆盖 48.3%、P10-P90 71.9%
backtest_calib3.py k=1.4 覆盖 51.0% / 74.7%;k=1.5 覆盖 53.9% / 78.5%
backtest_confirm.py C1 生产口径 IC 0.1375 (t=3.37)、C2 指数加权 0.1040 (t=2.55)、C3 L1only 0.1172 (t=2.87),n=600
backtest_mega.py M1 等权+衰减 IC 0.0299 (t=2.01);M2 无衰减 0.0237 (t=1.59)
backtest_l2hybrid.py L1+L2混合 IC 0.1416;L1+L2精确行业 0.0393
backtest_l2type.py L1+L2类型(60/100) IC 0.1416
backtest_l3risk.py L1+L2 IC 0.0830;L1+L2+L3旧 0.1253
backtest_levels.py L1+L2+L3 IC 0.0880;L1 only 0.0734
backtest_bsmatrix.py 趋势策略 69 股/83 笔,加权胜率 30.9%,年化中位 -9.1%
sweep_risk.py 三档风险参数网格(样本内选择,脚本已加注)
backtest_trade.py ★th>1.0% 年化 +336%(74 笔)——样本内尖峰,不可采信(已加注)
backtest_roll_cont.py 连续权益口径:Q25 mkt<-2.0% +20.0%/-42.6%;其余变体 -26%~-34%
research/check_rot_t10.py T+10 信号分段 IC:段1 +0.0745 → 段2 -0.0040 → 段3 +0.0245;无轮动 T10only -12.0%
backtest_factor_ablation.py(全量) 超时(rc=124);全量因子穷举未跑完,改用 400 只样本复核(见第九节)

九、factor_lab 筹码越界修复与样本复核

  • bug:factor_lab/chips.py 在个股当前 bar 完全落在热身段价格区间之外时, chips[b_hi] 出现负索引越界(全量运行 25 只异常)。已钳制 b_lo/b_hi 到 [0, nbin]; 400 只样本复跑 Pass A 400/400 异常 0,修复有效。
  • 全量旧产物 research/factor_lab/validate_results.json(2026-09-12,已恢复保留)结论仍然有效, 且是最重要的负面证据:2^21 组合穷举后取训练 Top-10k,用 BH-FDR 在验证段校正, 通过数 = 0;训练/验证全组合 IC 相关仅 0.43。
  • 修复后 400 只分层样本全流程复跑(--stage all --sample 400,1818s),产物: research/factor_lab/sample400_recheck/(panel/enum/validate JSON),日志 /tmp/opencode/factor_sample400.log。关键结果:
    • BH-FDR:训练 Top-10k 在验证段 pass=0(train/val 全组合 IC 相关 0.384);
    • Walk-Forward(5 折):平均 IC +0.0114,仅 2/5 折为正;
    • 逐股时序交叉验证:稳定集等权 IC 中位 +0.0300、正 IC 占比 67.6%、事件次日均值 +0.077%; 框架 12 维 IC 中位 +0.0091;
    • LASSO 仅保留「筹码压力、BIAS60」两个非零权重因子。
    • 结论与全量一致:少数因子在验证段有微弱正向(量能/BIAS/筹码压力), 但 2^21 全组合搜索没有组合能通过多重检验校正。

十、结论

  1. 最重要的发现:旧文档的”跑赢”主要来自口径,而不是策略。 同日收盘成交、只留活到最后的股票、用 val 调参、未来信息选池,这四件事叠加 把大量负期望策略包装成了正收益。修复后:
    • 每股消融组合样本外(val 252 日):只有稳健档勉强正超额(+1.8pp);
    • v4 所有主推策略(含旧”冠军”平衡档)在 252 日窗口为负;
    • 每日荐股从 +2.9% 变为 -33.6%。
  2. v4 模型仍有微弱预测力(IC ~1.6%、命中 ~50.5%),但训练/测试 IC 差距 0.63,过拟合标记为真;在扣除交易摩擦与决策层选择偏差后不足以支撑正收益。
  3. 仍为正的部分:彩票双引擎在创业板 val 与大/小资金档为正且 holdout 通过, 但其超额主要在大资金档接近 0、小资金档依赖强 beta 段;且 hfq/现价口径缺 数据,需补 adjust 系数后复核。
  4. 旧结论处理:README 已加更正说明;research/ 下带 _final/旧时间戳的 策略 JSON 不再代表当前口径,报告与 README 以本报告数字为准。

十一、复现命令

# 1) v4 全A(含重训,约 2.3 小时;已有缓存时分钟级)
python stock_predict.py --v4
# 2) 每股消融(约 3 分钟)
python backtest_strategy_ablation.py
# 3) 组合 val / 全样本
python backtest_strategy_portfolio.py --tier all --segment val --benchmark sh000001
python backtest_strategy_portfolio.py --tier all --segment all --benchmark sh000001
# 4) 退出层 / 滚动 / 寻优
python backtest_exit_ablation.py --tier 激进 --tag aggr
python backtest_exit_ablation.py --tier 平衡 --tag bal
python backtest_exit_roll.py
python backtest_v4_entry_exit_opt.py
python backtest_portfolio_overlay_opt.py
# 5) 荐股 / 彩票(含 holdout)
python backtest_picks.py --days 250 --step 5
python backtest_aggr_lottery.py --universe chinext --segment val --grid
# 6) 因子实验室(样本复核)
python backtest_factor_ablation.py --stage all --sample 400 --chip-sample 100 --workers 8

免责声明:全部为历史统计研究,不构成投资建议。


附录:新旧差异的隔离实验(v4 full:激进)

同一份当前 v4_preds.pkl、同一股票池,只切换成交时点与窗口:

组合 年化 回撤 交易
A 旧窗口(496 日,45 天对齐) + 同日收盘成交(旧口径) +5.5% -55.4% 218
B 旧窗口 + 早盘信号(新口径) -5.4% -54.1% 210
C 新窗口(252 日统一) + 早盘信号 -3.0% -56.6% 149
  • 成交时点单独贡献约 -11pp(A→B);窗口/生存者口径再贡献约 +2pp(B→C)。
  • A 未能精确复现旧报告 +13.6%,差额来自:v4 缓存已按当前数据库重训 (数据指纹变化,折边界与预测有差异)、旧代码 highest 初始化/停牌了结等 细节;模型 IC 未变(0.0157→0.0159),可排除”模型退化”。
  • 结论:对均持仓 4~9 日、接近满仓的高换手策略,“收盘价看到信号再按同一收盘价 成交”本身贡献了旧结果的大部分收益;这与每日荐股(旧池 +2.9% → 新池 -33.6%) 相互独立地指向同一结论。

附录 B:成交假设对比(T+1 收盘 vs T+1 开盘)

引擎新增 EXEC_PX=open / --exec open 口径:决策仍只用 T-1 信息,成交价从 “次日收盘”改为”次日开盘”(跳空包含在成交价内)。预测缓存、窗口、股票池不变。

B1. v4 三档(同一预测、同一 252 日窗口)

策略 收盘成交 开盘成交
full:保守 -7.2% / -25.3% -9.8% / -24.1%
full:平衡 -43.2% / -61.0% -61.3% / -74.3%
full:激进 -3.0% / -56.6% +4.0% / -55.9%
baseline:激进 -19.8% / -26.9% -39.7% / -43.0%
adaptive:平衡 -39.3% / -47.9% -66.1% / -69.5%

B2. 每股消融组合(slot,样本外 val 252 日)

口径 稳健 均衡 激进
收盘选型 + 收盘成交(基准) +2.5% / -10.4% -30.6% / -35.9% -21.3% / -25.4%
收盘选型 + 开盘成交 +0.6% / -12.4% -13.4% / -17.7% -3.7% / -11.3%
开盘选型 + 开盘成交 -14.6% / -22.5% -21.3% / -27.0% -26.5% / -29.9%

全样本 1000 日:收盘口径 稳健 +13.8% / 均衡 +10.0% / 激进 +17.7%; 收盘选型+开盘成交变为 +9.0% / -10.2% / +4.3%;开盘选型+开盘成交 +16.1% / +9.8% / +4.1%。

  • 消融选型本身也随成交价变化:训练集年化中位 稳健 +18.6%→+20.1%、均衡 +22.0%→+23.3%, 但验证集年化中位仍在 -1.3~-1.9%(与收盘口径一致),说明换成交价不改变”选型样本外归零”的结论。

B3. 退出消融 Full(默认)

档位 收盘成交 开盘成交
激进 -3.0% / -56.6% +4.0% / -55.9%(前半段 +104%,后半段 -47%)
平衡 -43.2% / -61.0% -61.3% / -74.3%
  • 开盘口径下的头部变体仍集中在”前半段赚钱、后半段回吐”(激进档 top:目标Q90 +37.4%, 前半段 +154%、后半段 -25%),选择偏差问题不因成交价改变。

B4. 结论

  1. 结果对成交假设高度敏感(±10~20pp/年),且方向因策略而异: 动量追买类(baseline/adaptive)开盘成交更差(买在跳空上), 模型打分类 full:激进 开盘略好;组合层均衡/激进在开盘成交下反而回撤更小。
  2. 没有任何一种成交假设能救回旧报告的数字:最优组合仍只有个位数年化或为负, 且样本外选型依旧归零。旧结论的核心问题不是成交价,而是同日成交 + 幸存者 偏差 + val 选参的叠加。
  3. 每日荐股回测本来就是 T+1 开盘成交(无需切换),修复后 -33.6%。
  4. 实盘更接近哪一种:9:30 之后按开盘价/盘中价下单 → 参考 B 节”开盘成交”; 尾盘按收盘价下单 → 参考正文”收盘成交”。建议以两者中较差者为决策依据。

附录 C:V5 优化实验(横截面组合,2026-09-14)

背景:每股独立选策略被证明样本外归零;v4 决策层在 2026 段亏损。改为测试 横截面组合(每日早盘按 T-1 分数选 TopN 等权、持有 N 日轮换、可加指数 趋势闸门),统一用”前 60% 选参 / 后 40% 留出”协议。脚本: backtest_v5_cross_section.py、backtest_v5_factor_cs.py。

C1. 模型分数横截面(v4 预测缓存,500 日窗口,开盘成交)

  • 单分数(ml_dyn / p_up / q50)× Top{10,20} × 持有{5,10,20} × 闸门{无,MA20,MA60} = 54 组:设计段最优组留出段 -23.8%;全部 54 组留出段年化中位 -30.3%、 最好 +1.0%。
  • 三模型集成分 + 反转因子(rev5/rev20)扩到 108 组:留出段中位 -41.5%。 表现最好的 ens Top20 持有20(设计 +8.0% / 留出 +8.2%)在换切分后不稳: 设计比例 0.5 时留出 -25.6%,Top30/40 留出 -2.7%/-3.0%。

C2. v4 决策层跨段复核(同一预测,500 日窗口两段各 300/200 日)

策略 设计段 留出段
full:保守 -10.9% +3.5%
full:平衡 -21.0% -49.2%
full:激进 +0.1% -23.5%

(此前 252 日窗口 full:激进 开盘 +4.0% 属于特定窗口,跨段不复现。)

C3. 稳定因子集横截面(factor_lab 稳定因子:量能/L2同行业/L3同市值/

筹码压力/BIAS20/BIAS60/VOLA20;方向由训练段定,验证段测试;250 只面板)

配置 H1 年化 H2 年化 全段年化/回撤/Calmar
Top20 持有5(无闸门) +60.6% -35.7% +14.1% / -27.1% / 0.52
Top10 持有5 + MA20 闸门 +28.6% +2.6% +14.9% / -19.4% / 0.77
上证基准(同区间) +35.5% -7.8% +11.7%
  • 这是唯一”两段都为正”的候选:Top10+持有5+MA20 全段超额约 +3pp、H2 抗跌 (+2.6% vs 指数 -7.8%),但 H1 跑输指数,且配置邻域不稳(Top20 持有5 H2 -11%、 持有10 H2 -30%),不能据此宣称稳健 alpha。
  • 全 A 面板复测进行中(重建 5077 只面板 → 自动跑 Top10/20/30、持有5/10), 结果见 research/v5_factor_cs_full_*.json 与 research/rerun_20260913/ factor_cs_full.log。若全市场复测同样成立,才考虑作为 V5 备选策略。

C4. 结论

  1. 在现有数据/信号上,没有找到既稳健又显著优于基准的可交易 alpha; 横截面 ML 排序、集成、反转、v4 决策层在留出段全部失败。
  2. 稳定因子合成分 + 趋势闸门是唯一有正迹象的方向,但证据强度不足, 依赖面板范围与参数邻域,需全 A 复测确认。
  3. 若全 A 复测失败,V5 的正确定位应是”分析与风控工具”(低换手、基准对照、 诚实披露),而不是高收益策略;进一步提升需要新数据源(资金流/分钟级/ 基本面)或改变目标函数。