de04a8904b
三策略(聚宽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待做,解锁长回测)
86 lines
7.1 KiB
Markdown
86 lines
7.1 KiB
Markdown
# 聚宽三策略移植回测总结(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`(中证2000,2684只小盘) |
|
||
| 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}.py`(21+27+24 = **72单测全过**) |
|
||
| 移植记录 | `docs/research/joinquant_strategies/{01,02,03}/notes.md` 各自「移植记录」节 |
|
||
| 原始代码 | `docs/research/joinquant_strategies/{01,02,03}/source.py`(聚宽py2原样保留) |
|
||
|
||
## 六、怎么跑
|
||
|
||
```bash
|
||
# 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 批量优化跟进。
|