docs(spec): 富回测结果页设计(v1)—聚宽级10指标+5图+4tab, empyrical后端算相对基准指标
This commit is contained in:
@@ -0,0 +1,96 @@
|
||||
# 富回测结果页(聚宽级)设计文档
|
||||
|
||||
- **日期**: 2026-07-11
|
||||
- **子项目**: #1 富回测结果页(前端向聚宽看齐,第一期)
|
||||
- **内核**: 保留 vnpy(CtaTemplate 单标的),仅升级结果展示 + 补相对基准指标
|
||||
- **状态**: 已设计,自主推进至验收
|
||||
|
||||
---
|
||||
|
||||
## 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 数值合理(与聚宽同口径抽查一致)
|
||||
Reference in New Issue
Block a user