你现在要在当前仓库中实现 A 股四指数轮动系统 v1 的第二阶段:信号层、组合层、回测层最小可用版本。
重要背景:
- 第一阶段数据层已经完成,并且本地数据已建库成功。
- 标的固定为 4 个指数:上证50、沪深300、创业板50、科创50。
- 当前仍然是“指数研究层回测”,不是 ETF 执行层。
- 严禁引入个股逻辑、ETF 选择逻辑、实盘交易接口。
本阶段目标:
1)实现趋势过滤信号;
2)实现相对强弱排序与风险惩罚打分;
3)实现 Top1 / Top2 / 空仓组合构建;
4)实现最小可用回测引擎;
5)输出基础绩效指标;
6)补必要测试与 README 更新。
必须严格遵守的时点语义:
- t 日收盘后,根据 t 日 close 与历史数据生成信号;
- 在 t+1 日执行调仓;
- 不允许使用 t 日收盘信号并按 t 日收盘成交;
- 测试里必须覆盖这个约束,防止未来函数和时点错配。
请实现的策略 v1 规则:
一、趋势过滤
对每个指数在 signal_date 计算以下规则:
- close > ma_20
- close > ma_60
- ma_20 > ma_60
- ret_20d > 0
满足至少 2 条,trend_pass = True。
二、综合打分
仅对 trend_pass=True 的指数参与排序。
打分由两部分组成:
- 动量分数(横截面 rank,标的池为当日 4 个指数)
- ret_5d 权重 0.20
- ret_10d 权重 0.25
- ret_20d 权重 0.30
- ret_60d 权重 0.25
- 风险惩罚(横截面 rank)
- vol_10d 权重 0.60
- vol_20d 权重 0.40
最终:final_score = score_mom - 0.30 * score_risk_penalty
三、组合规则
- 若合格标的 >= 2:支持 Top2 等权(50/50)
- 若合格标的 = 1:100% 持有该指数
- 若合格标的 = 0:空仓
- 同时支持 Top1 模式,作为可配置项
四、调仓频率
先实现:
- weekly
- every_5_days
可选支持 daily,但不是重点。
五、回测层
- 使用本地 clean/features 数据
- 使用 trade_date 序列推进
- signal_date 与 execution_date 分离
- 默认无摩擦回测,但要预留成本字段:commission_bps / slippage_bps
- 默认 cash_return = 0
六、指标输出
至少输出:
- cumulative_return
- annual_return
- max_drawdown
- annual_volatility
- sharpe
- calmar
- turnover
- rebalance_count
- cash_days_ratio
并输出每日净值、每日持仓、调仓记录。
七、建议代码结构
建议新增:
- src/signals/trend.py
- src/signals/ranker.py
- src/signals/scorer.py
- src/signals/selector.py
- src/portfolio/allocator.py
- src/portfolio/rebalance.py
- src/backtest/engine.py
- src/backtest/execution.py
- src/backtest/metrics.py
如果你认为需要微调结构,可以调整,但必须保持清晰。
八、CLI / 可运行入口
请至少提供一个可运行入口,例如:
- python3 -m src.backtest.run --config configs/strategy/top2_weekly.yaml
或者等价命令。
需要有最小配置文件支持 weekly / every_5_days 两个版本。
九、测试要求
至少覆盖:
- t 日信号、t+1 执行的时点测试
- trend filter 规则测试
- ranking / scoring 测试
- Top1 / Top2 / 空仓分配测试
- 回测净值与调仓记录基本正确性测试
十、文档要求
更新 README,补充:
- 第二阶段模块说明
- 信号与执行时点语义
- 如何运行 weekly / every_5_days 回测
- 目前仍为指数研究层,不是实盘执行层
工作方式:
- 先输出实现计划;
- 再按模块逐步实现;
- 每完成一部分就运行对应测试;
- 最后运行完整测试;
- 给出已完成模块、未完成项、假设与下一步建议。
运行环境要求:
- 使用 python3,不要假设 python 命令存在;
- 继续复用当前仓库和已有数据层;
- 如需读取本地数据,请使用现有 data 目录。
当你完全完成后,请执行:
openclaw system event --text "Done: index-rotation phase2 signal/backtest implemented" --mode now