系统手册
4. 截面回测引擎
用「日期 for-loop + 截面矩阵运算」逐日模拟组合净值,输出绩效与报告。为什么抛弃事件驱动。
作用:用「日期 for-loop + 截面矩阵运算」逐日模拟组合净值,输出绩效与报告。
源码地图
| 文件 | 关键对象 | 作用 |
|---|---|---|
src/backtest/engine.py | BacktestEngine._shift_signals | T 信号基于 T-1 因子(防未来函数核心) |
_simulate | 逐日:调仓判定 → 风控 → 换手成本 → 净值累乘 | |
BacktestConfig.rebalance_freq / rebalance_phase | 调仓周期 / 相位(timing-luck 分析) | |
src/backtest/portfolio.py | PortfolioBuilder.build_weights | 等权 / 评分加权 |
src/backtest/risk.py | RiskManager.apply / update_drawdown | 单票上限 / 总仓上限 / 回撤止损 |
src/backtest/metrics.py | compute_metrics | Sharpe / MaxDD / Calmar / 胜率 / 盈亏比 |
src/backtest/report.py | BacktestReport.generate | 净值曲线图 + CSV |
src/backtest/run_backtest.py | main | 命令行入口 |
为什么自研
Alpha101 是每日对 500 只标的进行截面评分排序的截面问题,而非针对单只标的的突破交易。Backtrader 等事件驱动框架在此场景下性能开销过高;自研矩阵驱动引擎约 300 行代码,执行效率更优,且更容易从结构上杜绝未来函数。
已知问题与修复
回撤止损从未触发(#31)
止损计算写成 nav / max(nav, 1.0) - 1,净值未跌破初始本金时止损永远不触发 → 已修复。未经自动化测试验证的风控规则不具备可靠性(#34 / #36)。 见 事故档案 · 止损逻辑失效。
回测与实盘三路分叉(#31)
回测与实盘的「信号 / 风控 / 因子筛选」三条路径各自独立实现,结果无法复现 → 强制统一到唯一的 SignalGenerator + RiskManager。见 事故档案 · 回测实盘路径分叉。
量化要点
- 换手成本 =
turnover × commission_rate × 2(双边)。 rebalance_phase用于评估「调仓相位运气(timing luck)」——同一策略不同起调日,结果可能差很多。
当前状态
历史回测在特定区间与参数下得到 Sharpe 1.3–1.8 量级的结果。口径不一、均为局部拟合,须与 SPY/QQQ 基准对比才有意义——详见 指标口径与免责声明。
缺口 / TODO
RiskManager仅在回测生效,未接入执行路径(#34)。
上一层:3. 因子与信号 DWS · 下一层:5. 交易执行层 ADS