Files
sanguo_vnpy_v2/docs/superpowers/specs/2026-07-07-phase3b-vue-frontend-design.md
T
claude_dev f0f08d32c3 docs(phase3b): 投研+回测 Web 控制台(Vue 前端)设计文档
- 4 期愿景:投研→回测→模拟→实盘(国金QMT),本期 B=投研+回测
- 对齐 vnpy client 回测模块 + 投研自有
- 技术栈 Vue3+Vite+TS+ElementPlus+ECharts+Pinia
- 部署:8000 切 sanguo_api,Vue 静态挂 FastAPI,不动端口/反代
- 含后端补 5 类接口(资金曲线/每日盈亏/成交/K线/报告)
- 4 切片 S0→S1→S2→S3
2026-07-07 00:25:31 +08:00

14 KiB
Raw Blame History

Phase 3b:投研 + 回测 Web 控制台(Vue 前端)设计

日期:2026-07-07 阶段:Phase 3bB 期) 状态:设计待审阅 维护:Main Agent


1. 背景与目标

已交付:

  • Phase 1 数据层(A 股 K 线 / SQLite 读取)
  • Phase 2 因子 + 回测引擎(sanguo_factor / sanguo_backtest,真数据跑通)
  • Phase 3a 研究 APIsanguo_apiJWT / 异步任务 / WebSocket / 结果查询),本机 + 容器 pytest 通过

两个缺口:

  1. 没有前端——只有 API,用户无法在网页上操作。
  2. sanguo_api 未挂公网——实机查证:公网 vnpy.mysanguo.top → 容器:8000 现在跑的是sanguo_web(实盘交易 API44 路由),没有回测/因子接口;Phase 3a 的 sanguo_api 只在容器里 pytest 跑过。

本期目标:建一个 Vue 前端控制台,对齐 vnpy 桌面 client 的回测模块功能 + 投研(因子)自有模块,并把 sanguo_api 切到公网 8000,使整条链路从 vnpy.mysanguo.top 可用。


2. 范围

完整愿景(用户确认,4 期递进):投研 → 回测 → 模拟 → 实盘(实盘最后,走国金证券 QMT / xtquant)。

本期 B= B1)范围

类别 内容
投研 因子分析(多标的 / 多因子 / 日期)→ IC 表 + tears 报告
回测 CTA 策略回测(对齐 vnpy client 回测模块:统计全表 / 资金曲线 / 每日盈亏 / 成交记录 / K线+买卖点)+ 参数优化
前端 Vue 3 SPA
后端补 5 类新接口 + 现有接口扩展
部署 sanguo_api 到 8000Vue 静态挂 FastAPI

不在本期(out of scope

  • 模拟盘(C 期,后端模拟引擎尚未建)
  • 实盘交易(D 期,国金 QMT;旧 sanguo_web 交易路由本期下线,D 期合并回来)
  • 导航预留 4 入口,模拟/实盘灰显"敬请期待",避免日后重写布局。

3. 整体架构

浏览器 (Vue 3 SPA)
    ↕  HTTPS  vnpy.mysanguo.top   ← 外网链路不动(frpc/socat/Caddy 不碰)
FastAPI  sanguo_api  (容器:8000,从 sanguo_web 切过来)
  ├─ /            → Vue 静态文件 (StaticFilesSPA history fallback)
  ├─ /api/v1/*    → 研究 APIauth / backtest / factor / task / ws
  └─ 调后端引擎   → sanguo_backtest / sanguo_factor / sanguo_data
                      ↕
                 SQLite + A 股 K 线 (NAS /volume1/stock)

4. 前端技术栈

选型 备注
框架 Vue 3 + <script setup> + Composition API 用户指定 Vue
语言 TypeScript 控制台体量需要,利维护
构建 Vite 快、标准
UI 库 Element Plus 中文量化圈最常用,表格/表单/弹窗齐全
图表 ECharts K线 candlestick + markPoint(买卖点)/ 折线(资金曲线)/ 柱状(每日盈亏)/ 热力图(优化)
状态 Pinia Vue 3 标准
路由 Vue Router 标准
HTTP Axios + JWT 拦截器 自动附 Authorization401 回登录
实时 原生 WebSocket 对接已有 /api/v1/ws/task/{id}

前端代码目录:新建 frontend/(仓库根),与 Python 包并列。npm run build 产物输出到 FastAPI 可挂载的静态目录。


5. 部署方案(守住红线)

红线(用户多次强调):

  • 不改容器端口(8000 不变)
  • 不动 vnpy.mysanguo.top 反向代理 / 转发
  • 不碰 frpc / socat / Caddy

本期改动(只动 NAS 容器内部)

  1. 容器 uvicorn 目标:sanguo_web.api:appsanguo_api.app:create_app(用 --factory,传 db_path / file_dir / auth_config / max_workers
    • 入口脚本:docker/entrypoint.sh:283(改 uvicorn 目标)
  2. Vue 打包静态 → FastAPI StaticFiles(directory=..., html=True) 挂在 /,配 SPA history fallbackcatch-all 回 index.html
  3. 开发期:本地 Vite dev server5173+ vite.config.ts proxy /api/ws → 容器/本地 FastAPI

部署流程(沿用项目约定):本机改代码 → rsync 到 NAS 安装目录 → docker restart sanguo_vnpy_v2

已知问题:本 session rsync/scp 到 NAS 不稳(status 43 / Connection closed)。临时用 ssh sanguo-nas "cat > /path" < local 重定向;排期修 sftp 子系统。


6. 页面设计

6.1 页面地图

登录页  /login
└ 主控制台(左侧栏 4 入口)
  ├ 回测 ✅ (S1 / S3)
  │   ├ 新建回测      /backtest/new
  │   ├ 任务进度      /backtest/task/:id   WS 实时阶段)
  │   ├ 结果页        /backtest/result/:id (统计/曲线/盈亏/成交/K线买卖点)
  │   ├ 参数优化      /backtest/optimize   (S3)
  │   └ 历史任务      /backtest/history    (S3)
  ├ 投研 ✅ (S2)
  │   ├ 新建因子分析  /factor/new
  │   └ 结果页        /factor/result/:id   IC 表 / tears 报告)
  ├ 模拟 ⬜ 敬请期待(C 期)
  └ 实盘 ⬜ 敬请期待(D 期 · 国金 QMT)

6.2 页面详情

登录页:用户名 + 密码 → POST /api/v1/auth/login → 存 JWTlocalStorage)→ 跳主控制台。

主控制台 shell:顶栏(系统名 / 用户 / 登出)+ 左侧栏 4 入口(回测/投研点亮,模拟/实盘灰显)+ <router-view>

回测-新建

  • 策略下拉(GET /strategy/list)→ 选中后按 GET /strategy/{name}/params 渲染动态参数表单
  • 标的输入(如 600000)+ 日期区间 +(S3)费率/滑点/资金
  • 提交 → POST /api/v1/backtest/cta → 拿 task_id → 跳进度页

回测-进度GET /task/{id} + WS /ws/task/{id},显示状态(pending/running/done/failed+ 中文阶段("排队中/回测中/完成")。done → 跳结果页。

回测-结果(对齐 vnpy client 回测模块):

  • 统计全表(sharpe / total_return / max_drawdown / win_rate / …,来自 GET /task/{id}/result
  • 资金曲线(GET /task/{id}/equity-curve → ECharts 折线)
  • 每日盈亏(GET /task/{id}/daily-pnl → ECharts 柱状)
  • 成交记录表(GET /task/{id}/trades → Element Table
  • K线 + 买卖点(GET /kline?symbol&start&end + 成交点 → ECharts candlestick + markPoint

回测-优化S3):策略 + 参数网格 → POST /api/v1/backtest/optimize → 结果表 + 热力图(GET /task/{id}/optimization-results)。

回测-历史S3):GET /task?type=cta → 任务列表,可点回看结果。

投研-新建:因子下拉(GET /factor/list,如 ma5/ma10/ma20/vol_ma5+ 多标的(多选,如 600000/000001/300750+ 日期 → POST /api/v1/factor/analyze → 进度。

投研-结果

  • IC 表(GET /task/{id}/ic-summary:各周期 mean/std/icir/t_stat/count
  • tears 报告内嵌(GET /task/{id}/report/{factor} 返回 HTML → iframe

7. 核心流程

7.1 回测流程

选策略(DoubleMaStrategy)→ 填参数(fast_window/slow_window)→ 选标的(600000+ 日期 → 提交 → 看进度"回测中" → 完成 → 结果页:统计全表 / 资金曲线 / 每日盈亏 / 成交表 / K线带买卖箭头。体感对齐 vnpy client 回测模块。

7.2 因子分析流程

选因子(ma5+ 多标的(600000/000001/300750alphalens 横截面需 ≥2)+ 日期 → 提交 → 进度 → 结果页:IC 表(1D/5D/10D mean/icir/t_stat+ tears 报告。


8. 后端 API

8.1 现有(Phase 3a,复用)

方法 路径 用途
POST /api/v1/auth/login 登录取 JWT
POST /api/v1/backtest/cta 提交 CTA 回测 → task_id
POST /api/v1/backtest/optimize 提交参数优化 → task_id
POST /api/v1/factor/analyze 提交因子分析 → task_id
GET /api/v1/task/{id} 任务状态 + 阶段
GET /api/v1/task/{id}/result 统计 statistics
WS /api/v1/ws/task/{id}?token= 实时阶段推送

8.2 本期新增(按切片)

切片 方法 路径 返回 说明
S1 GET /api/v1/strategy/list [{name, class_name}] 枚举 vnpy_ctastrategy 可用策略
S1 GET /api/v1/strategy/{name}/params {parameters:[...], defaults:{}} 读策略类 .parameters 渲染表单
S1 GET /api/v1/task/{id}/equity-curve [{date, balance}] 暴露 BacktestResult.equity_curve
S1 GET /api/v1/task/{id}/daily-pnl [{date, pnl}] 每日盈亏
S1 GET /api/v1/task/{id}/trades [{datetime, direction, offset, price, volume}] cta_engine 需实现成交记录(现为 None)
S1 GET /api/v1/kline?symbol&start&end [{datetime, open, high, low, close, volume}] 历史 K 线(读 A 股 DB;评估能否复用旧 sanguo_web /market/kline
S2 GET /api/v1/factor/list [{name, desc}] 枚举已注册因子(ma5/ma10/ma20/vol_ma5
S2 GET /api/v1/task/{id}/ic-summary {factor:{periodD:{mean,std,icir,t_stat,count}}} 暴露 FactorReport.ic_summary
S2 GET /api/v1/task/{id}/report/{factor} HTML tears 报告服务(StaticFiles 或 FileResponse
S3 扩展 POST /api/v1/backtest/cta schema 加 rate/slippage/capital 字段;cta_engine 接收
S3 GET /api/v1/task/{id}/optimization-results [{params, statistics}] 优化结果结构化
S3 GET /api/v1/task?type=&status= [task 摘要] 任务历史列表

9. 数据契约

9.1 BacktestResult(现有,sanguo_backtest/result_store.py

task_id, type, status, strategy, symbol, params, start, end, statistics, equity_curve, trades, error_msg

9.2 新增返回结构

  • equity-curve[{date: "YYYY-MM-DD", balance: number}]
  • daily-pnl[{date, pnl: number}]
  • trades[{datetime, direction: "多/空", offset: "开/平", price, volume, commission, ...}](对齐 vnpy TradeData
  • kline[{datetime, open, high, low, close, volume}]
  • ic-summary{factor: {"1D"|"5D"|"10D": {mean, std, icir, t_stat, count}}}
  • optimization-results[{params: {...}, statistics: {...}}]

所有接口返回 JSON 安全值(Timestamp→str,已在 cta_engine statistics 处理过同样问题)。


10. 切片交付计划

每片独立可演示、可验收。S1 最重(vnpy client 对齐主战场)。

S0 脚手架

  • 前端Vite + Vue3 + TS + Element Plus + ECharts + Pinia + Router + Axios 项目骨架;登录页 + JWT 拦截器;4 入口侧栏 shell(回测/投研点亮,模拟/实盘灰显);路由 + history fallback
  • 后端:容器 uvicorn 切 sanguo_apiFastAPI 挂 SPA 静态
  • 验收:从 vnpy.mysanguo.top 能登录、看到空壳控制台

S1 回测核心(对齐 vnpy client 回测)

  • 前端:新建回测 / 进度 / 结果页(统计全表 + 资金曲线 + 每日盈亏 + 成交表 + K线买卖点)
  • 后端strategy/liststrategy/{name}/paramstask/{id}/equity-curve/daily-pnl/trades/klinecta_engine 实现成交记录
  • 验收:跑 DoubleMaStrategy on 600000,结果页与 vnpy client 回测模块一致

S2 投研核心

  • 前端:新建因子分析 / 结果页(IC 表 + tears 报告内嵌)
  • 后端factor/listtask/{id}/ic-summarytask/{id}/report/{factor}
  • 验收:跑 ma5(多标的),看 IC 表 + tears 报告

S3 优化 + 收尾

  • 前端:参数优化(热力图)/ 历史任务 / 回测费率·滑点·资金可调
  • 后端backtest/cta 加参数;optimization-resultsGET /task 列表
  • 验收:跑优化看热力图、查历史、费率可调

11. 非功能

  • 安全JWT(已有);SPA 用 localStorage 存 tokenAxios 拦截器附 Authorization: Bearer401 → 清 token 回登录;HTTPS 由外网链路保证
  • 错误处理API 错误统一 Element Plus ElMessage;任务 failed 展示 error_msg
  • 测试
    • 前端:Vitest + Vue Test Utils(工具函数 / 关键组件)
    • 后端:pytest(新接口单测 + 复用现有容器冒烟模式)
    • 容器:scripts/smoke_phase3b.py(端到端:登录 → 提交回测 → WS 进度 → 结果页接口齐)
  • 代码风格:前端遵循 ECC coding-style(小文件、不可变、早返回、命名);后端沿用现有 sanguo_* 风格

12. 风险与约束

风险 / 约束 处理
切 8000 到 sanguo_api 会下线旧交易路由 已确认(A 方案);D 期合并回来
两套 auth 都占 /api/v1/auth/login 本期只用 sanguo_api JWTsanguo_web 下线,无冲突
rsync/scp 到 NAS 不稳 ssh-exec 重定向;排期修 sftp 子系统
容器 Python 3.10 vs 本机 3.14 前端 Node 工具链独立;后端接口在容器测(沿用 Phase 3a 模式)
vnpy 零修改原则 不改 vnpy_v4.4.0/;策略/参数从类属性读
NAS CPU 弱(J4125 无 AVX2 已有 POLARS_SKIP_CPU_CHECK;前端构建在 Mac,产物部署

13. 未来(C / D 期,预留)

  • C 模拟盘:新建模拟引擎(forward 纸面交易)+ 任务类型 paper;前端点亮"模拟"入口
  • D 实盘:合并 sanguo_web 交易路由(需统一 auth,解决 /api/v1/auth/login 冲突)+ 接国金 QMTxtquant);前端点亮"实盘"入口
  • 导航骨架已预留,C/D 无需重写布局

14. 开放项(实现阶段确认)

  • /kline 是否复用旧 sanguo_web/api/v1/market/kline(依赖行情网关 vs 历史 DB)—— S1 评估
  • token 存 localStorage(简便)vs httpOnly cookie(更安全)—— S0 默认 localStorage,可调
  • 策略参数表单的复杂参数类型(范围/枚举)支持深度 —— S1 按需

参考文档

  • Phase 3a 设计:docs/superpowers/specs/2026-07-06-phase3a-web-api-design.md
  • 部署实况:docs/deployment/nas-deploy-plan.md
  • 旧 Web 部署设计:docs/design/deployment/docker-web-deployment.md