From 6c461d4d9c78f59447778d2d5048c502b1c5a555 Mon Sep 17 00:00:00 2001 From: claude_dev Date: Sat, 11 Jul 2026 13:16:49 +0800 Subject: [PATCH] =?UTF-8?q?docs(spec):=20=E5=AF=8C=E5=9B=9E=E6=B5=8B?= =?UTF-8?q?=E7=BB=93=E6=9E=9C=E9=A1=B5=E8=AE=BE=E8=AE=A1(v1)=E2=80=94?= =?UTF-8?q?=E8=81=9A=E5=AE=BD=E7=BA=A710=E6=8C=87=E6=A0=87+5=E5=9B=BE+4tab?= =?UTF-8?q?,=20empyrical=E5=90=8E=E7=AB=AF=E7=AE=97=E7=9B=B8=E5=AF=B9?= =?UTF-8?q?=E5=9F=BA=E5=87=86=E6=8C=87=E6=A0=87?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../2026-07-11-backtest-result-page-design.md | 96 +++++++++++++++++++ 1 file changed, 96 insertions(+) create mode 100644 docs/superpowers/specs/2026-07-11-backtest-result-page-design.md diff --git a/docs/superpowers/specs/2026-07-11-backtest-result-page-design.md b/docs/superpowers/specs/2026-07-11-backtest-result-page-design.md new file mode 100644 index 0000000..5527410 --- /dev/null +++ b/docs/superpowers/specs/2026-07-11-backtest-result-page-design.md @@ -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 `