跳转至

前端监控仪表盘 — 架构总览

编写时间: 2026-03-02 对接后端: docs/architecture.md (API Gateway + 12 个微服务) 前置阅读: docs/architecture.md 第 1.2 节整体架构图、第 2.2 节各服务职责


一、技术选型

类别 技术 版本 许可 选型理由
框架 Vue 3 3.4+ MIT Composition API + TypeScript 一等支持
构建 Vite 5.x MIT 毫秒级 HMR, 开箱即用 Vue 支持
UI 库 Element Plus 2.x MIT 成熟的 Vue 3 组件库, 表格/表单/对话框丰富
状态管理 Pinia 2.x MIT Vue 官方状态库, TypeScript 友好
路由 Vue Router 4.x MIT 标准 SPA 路由
金融图表 TradingView Lightweight Charts 4.x Apache 2.0 专业 K 线 / NAV 曲线, 高性能 Canvas 渲染, 免费
通用图表 Apache ECharts 5.x Apache 2.0 热力图 / 雷达图 / 柱状图 / 桑基图, 免费
HTTP 客户端 Axios 1.x MIT 拦截器 + 请求/响应类型化
WebSocket 原生 WebSocket + 自动重连封装 - - 轻量, 无需额外依赖
CSS 工具 UnoCSS 或 TailwindCSS - MIT 原子化 CSS, 与 Element Plus 互补
语言 TypeScript 5.x Apache 2.0 类型安全, 接口契约强制

为什么不选其他方案?

方案 不选原因
Highcharts 商业许可, 非免费
D3.js 直接使用 学习曲线高, 量化场景 ECharts 已足够
AG Grid 社区版功能受限, 企业版付费
Grafana 嵌入 适合基础设施监控, 不适合业务逻辑定制 (策略对比/参数管理)

二、整体页面架构

┌─────────────────────────────────────────────────────────────────────┐
│  顶部状态条 (TopBar)                                                │
│  ┌──────────┐ ┌──────────┐ ┌──────────┐ ┌───────┐ ┌──────────┐   │
│  │ NAV 净值  │ │ 日 PnL   │ │ 最大回撤  │ │ 告警数 │ │ 系统时间  │   │
│  │ $10,234  │ │ +1.2%    │ │ -5.3%    │ │ 🔴 2  │ │ UTC      │   │
│  └──────────┘ └──────────┘ └──────────┘ └───────┘ └──────────┘   │
├──────────┬──────────────────────────────────────────────────────────┤
│          │                                                          │
│  左侧    │  主内容区 (RouterView)                                    │
│  导航    │                                                          │
│  (Aside) │  根据路由渲染对应页面                                     │
│          │                                                          │
│  总览     │                                                          │
│  仓位     │                                                          │
│  收益     │                                                          │
│  风控     │                                                          │
│  订单     │                                                          │
│  策略     │                                                          │
│  信号     │                                                          │
│  波动率   │                                                          │
│  回测     │                                                          │
│  系统     │                                                          │
│          │                                                          │
└──────────┴──────────────────────────────────────────────────────────┘

三、页面清单与功能

# 页面 路由 核心组件 数据来源 Phase
1 总览 Dashboard / KPI 卡片 + 小 NAV 曲线 + 服务状态灯 + 最近告警 聚合多接口 P1
2 仓位监控 /positions 目标 vs 实际仓位表格, 偏差高亮, 多空分布饼图 /api/v1/account/positions, /api/v1/portfolio/target-positions P1
3 收益监控 /pnl NAV 曲线 (Lightweight Charts), 日 PnL 柱状图, 回撤曲线 /api/v1/portfolio/nav, /api/v1/portfolio/pnl P1
4 风控面板 /risk 风控规则表 + 当前指标值 + 触发状态, 告警历史时间线 /api/v1/risk/* P2
5 订单审计 /orders 分页表格 (时间/symbol/方向/数量/价格/状态), 筛选器 /api/v1/orders/* P2
6 策略管理 /strategy 策略卡片列表, 参数只读, 启停开关, 参数变更表单 /api/v1/strategy/* P1 (只读) / P4 (写入)
7 信号分析 /signals 覆盖率/缺失率环形图, symbol 级信号热力图 /api/v1/signals/* P3
8 波动率监控 /volatility 组合级/策略级/symbol级三层 Tab, ECharts 热力图 /api/v1/portfolio/volatility P3
9 策略对比 /compare 双策略 NAV 叠加曲线, Sharpe/MDD/Calmar 对比卡片 /api/v1/signals/compare P3
10 系统状态 /system 服务心跳表, 任务运行状态, 数据管线延迟 /api/v1/health/* P1
11 回测结果 /backtest 回测参数表单, 结果指标卡片, NAV 曲线, IS/OOS 分割线 /api/v1/backtest/* P4

四、前端目录结构

frontend/                          # 项目根目录 (monorepo 中的子目录)
├── index.html
├── package.json
├── vite.config.ts
├── tsconfig.json
├── env.d.ts
├── public/
│   └── favicon.ico
└── src/
    ├── main.ts                    # 入口: createApp + 挂载插件
    ├── App.vue                    # 根组件: Layout 骨架
    ├── router/
    │   └── index.ts               # 路由定义
    ├── stores/                    # Pinia stores
    │   ├── portfolio.ts           # NAV / PnL / 回撤
    │   ├── positions.ts           # 当前仓位 + 目标仓位
    │   ├── strategy.ts            # 策略列表 + 参数
    │   ├── risk.ts                # 风控状态 + 告警
    │   ├── orders.ts              # 订单历史
    │   ├── signals.ts             # 信号覆盖率
    │   ├── system.ts              # 服务心跳 + 任务状态
    │   └── volatility.ts          # 波动率数据
    ├── api/                       # 后端接口封装
    │   ├── client.ts              # Axios 实例 (baseURL, 拦截器)
    │   ├── ws.ts                  # WebSocket 连接管理 (自动重连)
    │   ├── health.ts              # /api/v1/health/*
    │   ├── account.ts             # /api/v1/account/*
    │   ├── strategy.ts            # /api/v1/strategy/*
    │   ├── risk.ts                # /api/v1/risk/*
    │   ├── portfolio.ts           # /api/v1/portfolio/*
    │   ├── orders.ts              # /api/v1/orders/*
    │   ├── signals.ts             # /api/v1/signals/*
    │   └── backtest.ts            # /api/v1/backtest/*
    ├── composables/               # Vue 组合式函数
    │   ├── useWebSocket.ts        # WebSocket 连接 + 自动重连
    │   ├── usePolling.ts          # 定时轮询 + 清理
    │   └── useTheme.ts            # 暗色/亮色主题切换
    ├── components/                # 可复用组件
    │   ├── layout/
    │   │   ├── AppLayout.vue      # 主布局 (侧边栏 + 顶栏 + 内容区)
    │   │   ├── TopBar.vue         # 顶部 KPI 状态条
    │   │   └── SideNav.vue        # 左侧导航菜单
    │   │
    │   ├── charts/
    │   │   ├── NavChart.vue       # TradingView Lightweight Charts 封装
    │   │   ├── PnlBarChart.vue    # ECharts 日 PnL 柱状图
    │   │   ├── DrawdownChart.vue  # ECharts 回撤曲线
    │   │   ├── VolHeatmap.vue     # ECharts 波动率热力图
    │   │   └── SignalRadar.vue    # ECharts 信号雷达图
    │   │
    │   ├── tables/
    │   │   ├── PositionTable.vue  # 仓位表格 (目标 vs 实际)
    │   │   ├── OrderTable.vue     # 订单审计表格
    │   │   └── AlertTable.vue     # 告警历史表格
    │   │
    │   ├── cards/
    │   │   ├── KpiCard.vue        # 通用 KPI 卡片 (标题 + 值 + 变化率)
    │   │   ├── ServiceCard.vue    # 服务状态卡片 (名称 + 心跳 + 延迟)
    │   │   └── StrategyCard.vue   # 策略卡片 (名称 + 参数 + 状态)
    │   │
    │   └── common/
    │       ├── StatusDot.vue      # 状态指示灯 (绿/黄/红)
    │       ├── TimeAgo.vue        # 相对时间显示
    │       └── ConfirmDialog.vue  # 二次确认弹窗
    ├── views/                     # 页面级组件
    │   ├── DashboardView.vue
    │   ├── PositionsView.vue
    │   ├── PnlView.vue
    │   ├── RiskView.vue
    │   ├── OrdersView.vue
    │   ├── StrategyView.vue
    │   ├── SignalsView.vue
    │   ├── VolatilityView.vue
    │   ├── CompareView.vue
    │   ├── SystemView.vue
    │   └── BacktestView.vue
    └── types/                     # TypeScript 类型定义
        ├── api.ts                 # API 响应类型 (与后端 JSON Schema 对齐)
        ├── portfolio.ts           # TargetPortfolio / TargetPosition
        ├── strategy.ts            # StrategyInfo / StrategyConfig
        ├── risk.ts                # RiskRule / RiskStatus / Alert
        └── order.ts               # Order / Trade

五、数据流架构

┌───────────────────────────────────────────────────────────────┐
│                        前端 (Vue 3 SPA)                        │
│                                                               │
│  ┌─────────┐     ┌──────────┐     ┌──────────────────────┐  │
│  │  Views   │◄───│  Pinia   │◄───│  api/ + composables/ │  │
│  │  (页面)  │    │  Stores  │    │  (数据获取层)         │  │
│  └─────────┘     └──────────┘     └───────────┬──────────┘  │
│                                                │              │
│                                   ┌────────────┴───────────┐ │
│                                   │ REST (Axios) │ WS 推送  │ │
│                                   └────────────┬───────────┘ │
└────────────────────────────────────────────────┼─────────────┘
┌────────────────────────────────────────────────────────────────┐
│                 后端 API Gateway (FastAPI)                      │
│                                                                │
│  /api/v1/health/*      ← Redis (heartbeat keys)               │
│  /api/v1/account/*     ← Redis (account:balance, positions)   │
│  /api/v1/strategy/*    ← Redis (strategy:config) + YAML       │
│  /api/v1/risk/*        ← Redis (risk:status, alerts)          │
│  /api/v1/portfolio/*   ← Redis (portfolio:nav) + TimescaleDB  │
│  /api/v1/orders/*      ← TimescaleDB (orders table)           │
│  /api/v1/signals/*     ← Redis (signal:latest) + TimescaleDB  │
│                                                                │
│  /ws/positions         → 订阅 Redis Pub/Sub, 推送给前端        │
│  /ws/portfolio         → 定时从 Redis 读取, 推送给前端          │
│  /ws/alerts            → 订阅 Redis risk_rejected 通道         │
│  /ws/services          → 定时扫描 heartbeat keys, 推送给前端    │
└────────────────────────────────────────────────────────────────┘

数据刷新策略

数据类型 方式 频率 说明
服务心跳 / 任务状态 WebSocket /ws/services 30s 后端定时推送
当前仓位 WebSocket /ws/positions 30s AccountService 更新后推送
NAV / PnL WebSocket /ws/portfolio 60s 每分钟计算推送
风控告警 WebSocket /ws/alerts 实时 risk_rejected 事件触发
订单历史 REST 轮询 用户刷新 按需加载, 分页
策略参数 REST 页面加载 低频变更, 不需推送
波动率 REST 轮询 5min 计算密集, 不适合高频推送
信号覆盖率 REST 轮询 每日 日级汇总
回测结果 REST 按需 用户触发回测后查询

六、WebSocket 连接管理

自动重连封装

// composables/useWebSocket.ts 设计
interface UseWebSocketOptions {
  url: string
  onMessage: (data: any) => void
  reconnectInterval?: number   // 默认 3000ms
  maxRetries?: number          // 默认 10
}

function useWebSocket(options: UseWebSocketOptions) {
  // 1. 建立连接
  // 2. 收到消息 → 解析 JSON → 调用 onMessage
  // 3. 连接断开 → 指数退避重连
  // 4. 组件卸载 → 自动关闭连接 (onUnmounted)
  // 5. 暴露 { status, send, close } 给组件
}

后端 WebSocket 端点设计

后端每个 WebSocket 端点在 FastAPI 中实现, 模式统一:

@router.websocket("/ws/positions")
async def ws_positions(websocket: WebSocket):
    await websocket.accept()
    try:
        while True:
            # 从 Redis 读取最新仓位
            data = await redis.get("quant:account:positions")
            await websocket.send_json(json.loads(data))
            await asyncio.sleep(30)
    except WebSocketDisconnect:
        pass

七、主题与样式规范

配色方案

元素 暗色模式 亮色模式
背景 #0d1117 #ffffff
卡片背景 #161b22 #f6f8fa
正值 (盈利/多头) #3fb950 (绿) #1a7f37
负值 (亏损/空头) #f85149 (红) #cf222e
主色调 #58a6ff (蓝) #0969da
警告 #d29922 (黄) #9a6700
文本主色 #e6edf3 #1f2328
文本次色 #8b949e #656d76

响应式断点

断点 宽度 布局
Desktop >= 1280px 侧边栏 + 完整内容区
Tablet 768-1279px 折叠侧边栏 + 内容区
Mobile < 768px 底部导航 + 全宽内容 (优先级低)

八、部署方案

方案 A: S3 + CloudFront (推荐)

GitHub Actions
    ├── npm run build → 生成 dist/
    ├── aws s3 sync dist/ s3://quant-dashboard-{env}/
    └── aws cloudfront create-invalidation → 刷新 CDN 缓存

成本: ~$1-3/月 (极低流量)
优势: 零运维, 全球 CDN, HTTPS 自动

方案 B: Nginx 容器 (与后端同 ECS 集群)

Dockerfile.frontend:
    FROM node:20-alpine AS build
    COPY . .
    RUN npm ci && npm run build

    FROM nginx:alpine
    COPY --from=build /app/dist /usr/share/nginx/html
    COPY nginx.conf /etc/nginx/conf.d/default.conf

部署为 ECS Fargate Service, 256 CPU / 512MB
通过 ALB 路由: /api/* → 后端, /* → 前端

推荐: 开发阶段用 Vite dev server (代理后端), 生产用方案 A。

CORS 配置

后端 gateway.py 已有 CORS 中间件 (allow_origins=["*"]), 生产环境应限制为:

allow_origins=[
    "https://dashboard.quant-trading.example.com",
    "http://localhost:5173",  # Vite 开发服务器
]

九、与后端架构对接点

后端服务 (architecture.md) 前端对接方式 前端页面
AccountService REST /api/v1/account/* + WS /ws/positions 仓位监控, 总览
StrategyService REST /api/v1/strategy/* 策略管理, 策略对比
RiskService REST /api/v1/risk/* + WS /ws/alerts 风控面板
OrderService REST /api/v1/orders/* 订单审计
MonitorService REST /api/v1/health/* + WS /ws/services 系统状态, 总览
FeatureService REST /api/v1/signals/* 信号分析
BacktestEngine REST /api/v1/backtest/* 回测结果
API Gateway (FastAPI) 所有接口的统一入口 全部页面

关键: 前端不直接访问 Redis 或交易所 API。所有数据通过 API Gateway 中转, 后端从 Redis 读取缓存数据。