Files
sanguo_vnpy_v2/docs/research/joinquant_strategies/SUMMARY.md
T
claude_dev de04a8904b feat(portfolio): 移植3聚宽策略到BulletTrade + 8bug修正 + 数据缺口文档
三策略(聚宽py2→BulletTrade 0.9.2,BrokerFacade注入跨版本兼容):
- momentum_timing 动量择时(牛熊分界+行业RPS+均线,切回10中证行业指数)
- value_selection 价值精选(6条基本面过滤,切回沪深300)
- small_cap 小市值(去IC对冲,切回000985中证全指)

框架:
- runner_backtest 加 --strategy 分发(原硬编码all_weather)
- provider 加 get_value_metrics(价值精选6条基本面,NOTICE_DATE治前视偏差)
- 72单测全过(21+27+24)

修8个回测实测发现的真bug:
- 01第⑥条EPS绝对值0.08~0.5与①大盘矛盾→6条交集恒空致全程空仓,按注释本意改净利润同比8~50%
- 03原帖calRPS取数区间错(get_price start=end只取1天)→涨跌幅恒0 RPS失效;date.today()取真实今天非回测日
- 02 universe 000985不在constituent_unified→候选池空

VPS实测(短区间验证逻辑,非长期表现): 01价值+23%/03行业轮动+48%/02选出20只小盘

数据缺口(详见docs/research/joinquant_strategies/SUMMARY.md + data_gaps_fix_plan.md):
- 三表"1/3损坏"误报已撤回(全扫5530文件/表0损坏,沪深95%+健康,仅北交所920xxx空,不做北交所)
- 真实缺口: 行业成份股(G1已补)/000985(G2已补)/IC期货(02对冲去掉)/provider批量接口(G5待做,解锁长回测)
2026-07-28 22:20:49 +08:00

7.1 KiB
Raw Blame History

聚宽三策略移植回测总结(2026-07-27)

三策略(动量择时/价值精选/小市值IC对冲)从聚宽 py2 移植到 BulletTrade 0.9.2(聚宽API兼容),VPS 真实数据回测验证。

一、回测结果(短区间验证逻辑)

⚠️ 区间短(性能瓶颈致长期回测不实用),收益仅验证选股/交易逻辑通不通,非真实长期表现。

策略 回测区间 持仓 累计收益 最大回撤 夏普 结论
03 动量择时 2024-01~03 9宽基轮动 +30.4% (年化472%) -12.6% 2.64 择时准(年初熊市空仓避跌、2月转牛吃反弹),短区间年化虚高
02 小市值 2024-01~03 20只小盘 -0.70% -26.8% -2.70 2024初小盘股灾期,中证2000 暴跌,亏损符合现实
01 价值精选 2024-01~06 4~6只价值 +23.0% -27.6% 0.94 2024上半年价值/红利风格强势,表现合理

三策略选股 + 调仓 + 撮合链路全部跑通,逻辑正确。

二、策略问题清单

已修正的 bug(回测实测发现)

策略 原始问题 修正
03 calRPS 取数区间错(get_price(start=cur,end=cur) 只取1天)→ 涨跌幅恒0,RPS排名失效 preDate~curDate 区间算真实百分比涨跌幅
03 date.today() 取真实今天而非回测日(取数日期全错) 改用 context.current_dt
01 排序死代码(get_check_stocks_sort 排序后不截断+全买,排序无意义) 删除无意义排序,保留"全买"等额
01 第⑥条致命bug:注释"盈余成长率8-50%"但代码是 EPS 绝对值 0.08~0.5;大盘股EPS>0.5(茅台50/招行5)→ 与第①条大盘矛盾 → 6条交集恒空,策略空仓 按注释本意改"净利润同比增长率8-50%"(东财 PARENT_NETPROFIT_YOY),大盘股可入选
01 前视偏差(statDate 按报告期取数,用到未披露数据) NOTICE_DATE 公告日 ≤ 当前日 过滤
01 冗余调用(get_stock_list 调2次) 合并为1次
02 universe 000985(中证全指) 不在 constituent_unified → 候选池空 → 8次调仓全 picked 0 932000(中证20002684只小盘)
02 IC期货对冲(SubPortfolio/做空/期货)引擎不支持+无数据 对冲部分全部删除(记缺口),保留选股轮动

⚠️ 遗留问题(未修/性能/口径)

策略 问题 状态
03/02 性能慢(每日/每5日遍历大池子逐只算指标):03 每日遍历9宽基3000+只 RPS+均线;02 每次调仓遍历2684只动量(约5分钟/次) 长期回测不实用,待 provider 批量取行情优化
03 ST 过滤用当前 display_name(非历史时点) 轻微前视,未处理
01 ROE 非精确 TTM(累计净利润/期末权益,有季节性偏差) 未处理(和市场均值比较相对影响小)
01 L4=487 异常稳定(5年FCF正的股票数几乎不变) 疑似 FCF 计算口径或数据覆盖问题,待查
01 universe 默认沪深300(原策略全市场5000+) 避免逐只读三表爆炸,牺牲覆盖换可执行

三、数据缺口清单(给数据 session 补)

# 缺口 影响策略 现状 当前缓解 建议
1 行业成份股(证监会行业 A01 等 / 中证行业指数 000928-000938 03 constituent_unified 只有9个宽基,无行业 用9宽基替代(板块粒度变粗) 补行业成份股数据,恢复完整行业轮动
2 三表覆盖率1/3 [已撤回·误报] 北交所920xxx三表空 01 全扫5530文件/表 0损坏0空(<600B),沪深/创业/科创 95%+健康;仅北交所920xxx空(akshare不覆盖,~6%)。原"1/3有效"系小抽样误报(北交所排序尾部污染+可能schtask写入时序)2026-07-28全扫复核撤回 universe排除北交所(0成本,已与filter_kcbj_stock一致) 不做北交所即解;若做需jqdata/xtdata补
3 IC 期货合约日线 + 月份切换 02 完全缺失 对冲部分去掉,只做选股 若要做对冲需补 IC 期货数据 + 扩展引擎做空能力
4 中证全指 000985 成份股 02 constituent_unified 改用 932000(中证2000,更小盘更激进) 补 000985 或接受 932000 替代
5 NOTICE_DATE 缺失 [已撤回·误报] 01 全扫9/9有效文件NOTICE_DATE 全有,不缺 兜底逻辑保留但几乎不触发 无需补

四、性能瓶颈(共性,影响长期回测)

三策略选股都遍历大池子逐只算指标provider 逐只查询 dbbardata/parquet),未批量/未缓存:

策略 瓶颈 实测
03 每日遍历9宽基3000+只,逐只取30日行情算RPS+均线 2022-2024长回测 25分钟仅跑113天,停
02 每次调仓遍历2684只逐只取130日行情算动量 每次调仓约5分钟,2月回测40分钟
01 每次调仓读300只三表(沪深健康正常读取) 可接受(月度调仓,半年6次约2分钟)

优化方向(未做):provider 批量取行情(一次取一批股票N日close,pandas向量化算RPS/均线/动量),避免逐只查询。预计可提速10-50倍,使长期回测实用。

五、产出文件

类型 文件
策略 sanguo_portfolio/strategies/{momentum_timing,value_selection,small_cap}.py
Provider sanguo_portfolio/providers/local_parquet_provider.py(加 get_value_metrics)、local_unified_provider.py(委托)
Runner sanguo_portfolio/runner_backtest.py--strategy {all_weather,momentum_timing,value_selection,small_cap} 分发)
测试 tests/portfolio/test_{momentum_timing,value_selection,small_cap}.py21+27+24 = 72单测全过
移植记录 docs/research/joinquant_strategies/{01,02,03}/notes.md 各自「移植记录」节
原始代码 docs/research/joinquant_strategies/{01,02,03}/source.py(聚宽py2原样保留)

六、怎么跑

# VPS(数据在 VPS 本地,Mac 无数据)
ssh 49.232.102.198 "cd /d C:\sanguo_vnpy_v2 && C:\Python310\python.exe -X utf8 -m sanguo_portfolio.runner_backtest --strategy <name> --provider unified --start 2024-01-01 --end 2024-06-30 --cash 1000000"
# <name> ∈ {momentum_timing, value_selection, small_cap, all_weather}

七、一句话结论

三策略全部成功移植到 BulletTrade 并在 VPS 跑通回测(逻辑验证通过);过程中实测发现并修正了 8个真实bug(含策略01第⑥条致空仓的致命bug、策略03两个原帖回测失真的bug)。数据层真实缺口经全扫复核(2026-07-28,详见 data_gaps_fix_plan.md)为 2 项:行业成份股 + 中证全指000985 成份股缺失(阻断策略02/03 完整版);北交所920xxx 三表空(akshare不覆盖,universe排除即解,0成本)。原报"三表覆盖1/3 / NOTICE_DATE缺列" 系小抽样误报(北交所排序尾部污染+schtask写入时序),全扫5530文件/表 0损坏、沪深95%+健康,已撤回。另性能瓶颈(逐只取指标)待 provider 批量优化跟进。