erwin cd5dfb9dd2 Commit research code, docs, and memory files 3 minggu lalu
..
configs cd5dfb9dd2 Commit research code, docs, and memory files 3 minggu lalu
data ace7ef22fb Import index-rotation project into cyb50-quant 3 minggu lalu
memory cd5dfb9dd2 Commit research code, docs, and memory files 3 minggu lalu
outputs cd5dfb9dd2 Commit research code, docs, and memory files 3 minggu lalu
src cd5dfb9dd2 Commit research code, docs, and memory files 3 minggu lalu
tests cd5dfb9dd2 Commit research code, docs, and memory files 3 minggu lalu
.codex ace7ef22fb Import index-rotation project into cyb50-quant 3 minggu lalu
MEMORY.md cd5dfb9dd2 Commit research code, docs, and memory files 3 minggu lalu
README.md 92616fd043 Add configurable trend threshold for signal filter 3 minggu lalu
TASK_PROMPT.md ace7ef22fb Import index-rotation project into cyb50-quant 3 minggu lalu
TASK_PROMPT_PHASE2.md ace7ef22fb Import index-rotation project into cyb50-quant 3 minggu lalu
USER.md cd5dfb9dd2 Commit research code, docs, and memory files 3 minggu lalu
pyproject.toml ace7ef22fb Import index-rotation project into cyb50-quant 3 minggu lalu

README.md

A 股四指数轮动系统 v1

本仓库当前已实现:

  • 第一阶段:数据层
  • 第二阶段:信号层、组合层、回测层最小可用版本

当前仍然是指数研究层回测,不包含个股逻辑、ETF 选择逻辑或实盘交易接口。

覆盖范围

  • 固定标的:上证50、沪深300、创业板50、科创50
  • 数据频率:日线
  • 数据来源:本地 data/ 分层
  • 回测层只读取本地 clean/features 衍生结果,不访问网络

当前模块

configs/
  instruments.yaml
  strategy/
    top2_weekly.yaml
    top2_every_5_days.yaml
data/
  raw/
  clean/
  features/
  meta/
src/
  data/
  signals/
    trend.py
    ranker.py
    scorer.py
    selector.py
  portfolio/
    allocator.py
    rebalance.py
  backtest/
    execution.py
    engine.py
    metrics.py
    run.py
tests/

数据分层

  • raw:provider 原始缓存
  • clean:标准化日线
  • features:只基于本地 clean 计算的 rolling 特征

第二阶段 v1 使用的核心字段来自 features

  • close
  • daily_return
  • ret_5d / ret_10d / ret_20d / ret_60d
  • ma_20 / ma_60
  • vol_10d / vol_20d

策略 v1 规则

1. 趋势过滤

signal_date 对每个指数检查:

  • close > ma_20
  • close > ma_60
  • ma_20 > ma_60
  • ret_20d > 0

默认满足至少 2 条时,trend_pass = True。 可通过策略配置中的 trend_min_rules 调整阈值,例如提高到 3 条以收紧入选条件。

2. 综合打分

只允许 trend_pass=True 的标的进入最终选择,但横截面 rank 仍基于当日 4 个指数计算。

动量分数:

  • ret_5d * 0.20
  • ret_10d * 0.25
  • ret_20d * 0.30
  • ret_60d * 0.25

风险惩罚:

  • vol_10d * 0.60
  • vol_20d * 0.40

最终分数:

final_score = score_mom - 0.30 * score_risk_penalty

3. 组合规则

  • Top2:若合格标的数 >= 2,持有前两名,各 50%
  • Top2:若合格标的数 = 1,单标的 100%
  • Top1:只持有第一名
  • 若合格标的数 = 0,空仓
  • 可通过策略配置中的 risk_penalty_multiplier 调整风险惩罚强度(默认 0.30

4. 调仓频率

当前支持:

  • weekly
  • every_5_days
  • daily(用于测试和最小实现,不是主配置)

信号与执行时点语义

这是第二阶段最重要的约束:

  • t 日收盘后,使用 tclose 与历史数据生成信号
  • t+1 日执行调仓
  • 不允许用 t 日收盘信号按 t 日收盘成交

当前回测只有日频 close 数据,因此 v1 采用保守语义:

  • t+1 当天先计入旧仓位从 t -> t+1 的日收益
  • 再在 t+1 收盘执行调仓
  • 新仓位从 t+2 的日收益开始生效

这能明确避免未来函数和时点错配。测试已覆盖该约束。

研究成本假设标准

当前统一使用三档成本场景:

  • optimistic = 10bp 总成本
  • base = 15bp 总成本(默认研究基准)
  • conservative = 20bp 总成本

配置文件位于:

configs/research/cost_scenarios.yaml

后续比较策略时,优先看 base,并同时检查 optimistic / conservative 两侧的稳定性。

回测输出

回测至少输出:

  • cumulative_return
  • annual_return
  • max_drawdown
  • annual_volatility
  • sharpe
  • calmar
  • turnover
  • rebalance_count
  • cash_days_ratio

同时输出:

  • 每日净值 daily_nav.csv
  • 每日持仓 daily_holdings.csv
  • 调仓记录 rebalances.csv

运行方式

Top2 周频:

python3 -m src.backtest.run --config configs/strategy/top2_weekly.yaml

Top2 每 5 个交易日:

python3 -m src.backtest.run --config configs/strategy/top2_every_5_days.yaml

Top1 每 5 个交易日(较强风险惩罚候选配置):

python3 -m src.backtest.run --config configs/strategy/top1_every_5_days_p05.yaml

Top1 每 5 个交易日(更强风险惩罚,适合低成本场景对比):

python3 -m src.backtest.run --config configs/strategy/top1_every_5_days_p06.yaml

Top1 每 5 个交易日(主候选 + 成本敏感性配置):

python3 -m src.backtest.run --config configs/strategy/top1_every_5_days_p05_cost10bp.yaml
python3 -m src.backtest.run --config configs/strategy/top1_every_5_days_p05_cost15bp.yaml
python3 -m src.backtest.run --config configs/strategy/top1_every_5_days_p05_cost20bp.yaml

默认输出目录:

outputs/backtests/<config_name>/

生成统一对比表:

python3 -m src.backtest.compare

默认会输出:

outputs/research/strategy_comparison.csv
outputs/research/strategy_comparison.md

例如:

  • outputs/backtests/top2_weekly/summary.json
  • outputs/backtests/top2_weekly/daily_nav.csv
  • outputs/backtests/top2_weekly/daily_holdings.csv
  • outputs/backtests/top2_weekly/rebalances.csv

第一阶段数据 CLI

首次全量初始化:

python3 -m src.data.bootstrap --all

按上次成功抓取位置增量更新:

python3 -m src.data.update --since-last

单标的历史回补:

python3 -m src.data.backfill --instrument sse50 --start 2003-12-31

从本地层修复下游层:

python3 -m src.data.repair --instrument sse50 --layer features

查看状态:

python3 -m src.data.status

依赖

  • python >= 3.10
  • pandas
  • PyYAML
  • pyarrow
  • akshare

测试

运行全量测试:

python3 -m unittest discover -s tests -v

当前测试覆盖:

  • 数据层编排与修复
  • 特征不使用未来数据
  • 趋势过滤规则
  • 排序与打分
  • Top1 / Top2 / 空仓 分配
  • t 日信号、t+1 执行的时点约束
  • 回测净值、持仓、调仓记录的基础正确性
  • 统一比较表中的成本标签与相对收益字段

边界与后续

当前版本仍有意保持最小化:

  • 不做 ETF 映射
  • 不做成交价建模扩展
  • 不做实盘交易接入
  • 不引入个股层逻辑

若进入下一阶段,优先建议:

  • 增加成交成本和现金收益率的更细粒度建模
  • 增加参数化样本区间与输出报表
  • 增加基准对比与分年度绩效拆解