Files
sanguo_vnpy_v2/docs/superpowers/specs/2026-07-11-backtest-result-page-design.md
T

97 lines
4.9 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 富回测结果页(聚宽级)设计文档
- **日期**: 2026-07-11
- **子项目**: #1 富回测结果页(前端向聚宽看齐,第一期)
- **内核**: 保留 vnpyCtaTemplate 单标的),仅升级结果展示 + 补相对基准指标
- **状态**: 已设计,自主推进至验收
---
## 1. 背景与目标
用户诉求:"前端功能向聚宽(JoinQuant)看齐,内核保留 vnpy"。第一期不做在线编辑器(策略在本地 IDE 写),专注**富回测结果页**——把现有简陋的 `Result.vue` 升级到聚宽级(10 指标卡 + 5 图 + 4 tab + 时间缩放),并补齐后端"相对基准指标"计算能力。
### 成功标准
1. CTA 单标的策略回测后,结果页展示聚宽级 10 指标 + 5 图 + 4 tab + 时间缩放
2. Alpha/Beta/Sortino/IR 口径与聚宽一致(聚宽=Pyfolio+empyrical 同源)
3. 基准可选 沪深300 / 中证500
4. 本地 pytest + NAS 容器 pytest + 前端 vitest 全绿,覆盖率 ≥80%
5. 部署到 NAS 容器,真实回测可出聚宽级展示
## 2. 非目标 (YAGNI)
- ❌ 多股票组合结果(选股/轮动策略 → 子项目 #5,需 vnpy_portfoliostrategy
- ❌ 在线策略编辑器(子项目 #2,用户明确推迟)
- ❌ 自定义基准(沪深300/中证500 二选一够 MVP,D 选项后加)
- ❌ Tick/分钟级结果(本期只日级 CTA)
## 3. 数据前提(先干的活)
| 数据 | 现状 | 处置 |
|------|------|------|
| 沪深300 指数日线 | ❌ 缺(只有成分股名单) | 下载 → `日线数据/daily/{year}/sh000300_daily.parquet` |
| 中证500 (000905) 日线 | ✅ 现成 (`sz000905_daily.parquet`) | 直接用 |
- **下载约束**:直连不走代理、单线程限速(遵循 `data-download-constraints` 记忆)
- **datareader 扩展**:新增 `read_index_daily(code: str, start, end) -> DataFrame`,复用现有 parquet 读取路径
## 4. 后端设计
### 4.1 指标计算模块 `sanguo_backtest/metrics.py`(新增)
- **输入**vnpy `daily_df`net_pnl / 资金曲线)+ 基准日线收益序列
- **计算**(用 `empyrical`Quantopian 出品,聚宽同源):
- 标量:`total_return / annual_return / alpha / beta / sharpe_ratio / sortino_ratio / information_ratio / annual_volatility / max_drawdown`
- 基准:`benchmark_return / benchmark_volatility`
- 时序:逐日累计收益(策略/基准)、逐日 alpha、逐日 beta(rolling)、逐日 drawdown
- **输出**`MetricsResult`(标量 dict + 时序 dict),纯函数、可单测
- **依赖**`empyrical`pip,纯 Python 无坑)
### 4.2 回测流程改造
- `run_cta_backtest` 跑完 vnpy 后,按 `benchmark` 配置加载基准日线,调用 `metrics.py`
- 结果入库:标量指标 → `backtest_results.db`;时序 → `{task_id}_*.json`
### 4.3 API 扩展(sanguo_api
- `POST /backtest/cta` 入参加 `benchmark: Literal["hs300","zz500"] = "hs300"`
- `GET /task/:id/result` 出参增 `relative_metrics`
- 新增端点:
- `GET /task/:id/benchmark-curve` → 累计收益(策略+基准)时序
- `GET /task/:id/risk-series` → alpha/beta/vol/drawdown 逐日序列
- `GET /task/:id/daily-holdings` → 每日持仓表
- `GET /task/:id/log` → 回测日志
## 5. 前端设计(重构 `views/backtest/Result.vue`
### 5.1 布局(高仿聚宽结果页官方截图)
- **顶部**10 指标卡(el-card 网格)
- **中部**5 图纵向堆叠(echarts)+ 时间缩放选择器(1周/1月/6月/1年/全部)
- **Tab**:收益概述 / 交易详情 / 每日持仓&收益 / 日志输出
### 5.2 新增组件(`components/backtest/`
- `MetricCards.vue` — 10 指标卡
- `BenchmarkCurve.vue` — 策略 vs 基准累计收益
- `AlphaChart.vue` / `BetaChart.vue` — 逐日 alpha/beta
- `VolatilityChart.vue` — 策略 vs 基准波动率
- `DrawdownChart.vue` — 逐日回撤
- 复用:`EquityChart / TradesTable / KlineChart`
### 5.3 风格
- 沿用 element-plus + echarts + Composition API `<script setup>`(匹配现有代码)
## 6. 数据流
回测提交 → TaskPool worker 跑 vnpy → `daily_df``metrics.py`(+基准) → 存 DB+json → 前端拉 API → echarts 渲染
## 7. 测试(TDD
- `tests/backtest/test_metrics.py`:固定 `daily_df` + 基准 → 断言 alpha/beta/sharpe(与 empyrical 直接计算对照)
- `tests/api/test_routes.py`:新端点返回结构 + benchmark 入参
- `frontend` vitest:图组件渲染测试
- 覆盖率 ≥80%
## 8. 部署
- 本地开发 → rsync 到 NAS**不排除 tests/data**,见 `rsync-tests-data-sync` 记忆)
- `/var/packages/Docker/target/usr/bin/docker restart sanguo_vnpy_v2`
- 容器内 pytest 复验
## 9. 验收(三向一致性检查)
- [ ] 需求↔设计↔编码一致:10 指标 + 5 图 + 4 tab 全实现,基准可选沪深300/中证500
- [ ] 测试全绿(本地 Mac + NAS 容器 + 前端 vitest
- [ ] NAS 部署后可访问结果页,真实 CTA 回测出聚宽级展示
- [ ] alpha/beta 数值合理(与聚宽同口径抽查一致)