量化投研看板 (Quant Desk) · 系统架构设计文档
1. 系统概述
1.1 产品定位
多策略并行管理的量化交易工作台,面向有经验的量化/策略交易者。核心能力:
- 多策略管理 — 同时管理多条交易策略,每条策略绑定独立账户
- 全链路覆盖 — 支持历史回测与实盘,绩效一屏横向对比
- AI 调研 — 自动生成个股调研报告,推送飞书通知
- 妙想(mx)金融专业能力 — 集成东方财富妙想 4 个 Skill(mx-search 情报 / mx-data 自然语言金融数据 / mx-xuangu 智能选股 / mx-zixuan 自选股双写),补充 akshare/tushare 拿不到的口径(金融专业情报、衍生指标、选股条件)
- 多 Agent 编排 — 5 类专项 Agent(Technical / Intel / Risk / Decision / Portfolio)通过 Orchestrator 4 模式(quick / standard / full / specialist)调度,单股/多股并发深度分析
- 15 个策略 Skill — YAML 驱动,支持运行时 CRUD + 热加载(无需重启)
- 告警系统 — 14 种 alert_type × 5 种 target_scope × 3 级 severity,覆盖技术/组合/大盘灯多场景
- 大盘复盘 — 工作日 18:00 自动跑 LLM 复盘,缓存 + 周末兜底
- 自动化调度 — APScheduler 统一驱动:研究 / 回测 / 结算 / 复盘 / 飞书推送 / 告警评估 / 自选股同步
1.2 技术栈
| 层级 | 技术 |
|---|---|
| 前端框架 | React 19 + TypeScript |
| 状态管理 | Zustand 5 |
| 后端框架 | Python 3.12 + FastAPI |
| ORM | SQLAlchemy 2.0 |
| 数据库 | SQLite |
| 任务调度 | APScheduler |
| LLM 协议 | LiteLLM(OpenAI / Anthropic / 自定义统一) |
| Agent 编排 | 自研 multi_agent(5 类 Agent + Orchestrator) |
2. 系统架构
2.1 核心架构图
融合了「技术分层」与「业务领域」的整体架构,覆盖 交易与回测、投研与 AI(含多 Agent 编排 + Skill Manager + 妙想 mx)、告警与大盘复盘、平台与支撑 四大域。
flowchart TB
subgraph L1["【用户接入层】 Access Layer"]
USER["量化交易员 · 策略研究人员"]
CRON["APScheduler · Cron 触发"]
end
subgraph L2["【表现层】 Presentation Layer (React 19 + Zustand 5)"]
direction TB
FE_P["16 个功能页面<br/>(Dashboard/Agent/Alerts/Backtest/Research/Skills...)"]
FE_S["9 个 Zustand Store (领域驱动)"]
FE_C["Shadcn UI + Lucide"]
end
subgraph L3["【接入与 API 层】 API Layer (FastAPI + SSE)"]
direction LR
AC1["16 个 endpoint 文件 · 80+ REST"]
AC2["SSE 流式 (agent/chat/stream)"]
end
subgraph L4["【业务逻辑层】 Service Layer (Python)"]
direction TB
subgraph SVC_TRADE["交易与回测域"]
D1["行情服务 · 结算同步 · 资金流转"]
D3["回测引擎 (dsa_backtest)"]
end
subgraph SVC_AI["投研与 AI 域"]
D2["LLM 调度 · 智能分析 · 调研"]
D4["**多 Agent 编排**"]
D4a["Technical / Intel / Risk / Decision / Portfolio 5 Agent"]
D4b["Orchestrator 4 模式: quick/standard/full/specialist"]
D4c["**Skill Manager**: 15 个 YAML skill, CRUD + 热加载"]
D6["妙想 mx 服务域"]
D6a["mx-search 搜索三源合并 (Tavily+mx+Bocha)"]
D6b["mx-data 自然语言金融数据"]
D6c["mx-xuangu 智能选股"]
D6d["mx-zixuan 自选股双写"]
end
subgraph SVC_OPS["告警与大盘复盘域"]
D7["**告警系统**<br/>14 种 alert_type · 5 种 target_scope · 3 级 severity"]
D8["**大盘复盘**<br/>工作日 18:00 · LLM 解读 + 周末兜底"]
D9["**自选股同步**<br/>东方财富 → 本地 · 08:00-22:30 区间触发"]
end
subgraph SVC_PLAT["平台与支撑域"]
D5["配置管理 · 飞书推送 · 任务调度"]
end
end
subgraph L5["【数据与能力层】 Infrastructure Layer"]
direction LR
subgraph DB["数据持久化 (SQLite + 22 个 ORM 模型)"]
DB1["业务表 (Strategy/Account/Trade/Position...)"]
DB2["SystemConfig (含 MX_* 鉴权)"]
DB3["告警/复盘/同步 (AlertRule/MarketReview/WatchlistSync)"]
end
subgraph CAP["底层外部能力"]
C1["多源行情 (Efinance/Tushare/Baostock/TickFlow)"]
C2["LLM 推理 (LiteLLM 多 provider)"]
C3["AI 搜索 (Tavily+Bocha)"]
C4["通知推送 (Feishu Webhook)"]
C5["妙想 mkapi2.dfcfs.com"]
C6["东方财富 self-select (mx-zixuan)"]
end
subgraph TOOLS["**Tool Registry** (6 类 15 个工具)"]
T1["data (4) · analysis (2) · search (4)<br/>market (2) · backtest (3) · mx (2)"]
end
end
%% 核心流转
USER --> L2
L2 --> L3
CRON --> L3
L3 --> L4
L4 --> L5
%% 内部触发
D5 -. 触发 .-> SVC_TRADE
D5 -. 触发 .-> SVC_AI
D5 -. 触发 .-> SVC_OPS
%% Agent 编排内部
D4 --- D4a
D4 --- D4b
D4 --- D4c
D4a -. 调用 .-> TOOLS
D4b -. 调度 .-> D4a
D4c -. 提供 .-> D4b
%% 妙想域
D6 --- D6a
D6 --- D6b
D6 --- D6c
D6 --- D6d
D6a -. 调用 .-> C5
D6b -. 调用 .-> C5
D6c -. 调用 .-> C5
D6d -. 调用 .-> C6
%% Ops 域
D7 -. 评估 .-> C1
D8 -. 拉数据 .-> C1
D9 -. 同步 .-> C6
%% 样式
style L1 fill:#f9fafb,stroke:#374151,stroke-width:2px
style L2 fill:#eff6ff,stroke:#2563eb,stroke-width:2px
style L3 fill:#fff7ed,stroke:#ea580c,stroke-width:2px
style L4 fill:#f5f3ff,stroke:#7c3aed,stroke-width:2px
style L5 fill:#f0fdf4,stroke:#16a34a,stroke-width:2px
style SVC_TRADE fill:#ffffff,stroke:#7c3aed,stroke-dasharray:5 5
style SVC_AI fill:#ffffff,stroke:#7c3aed,stroke-dasharray:5 5
style SVC_OPS fill:#ffffff,stroke:#7c3aed,stroke-dasharray:5 5
style SVC_PLAT fill:#ffffff,stroke:#7c3aed,stroke-dasharray:5 5
style D4 fill:#fdf4ff,stroke:#a21caf,stroke-width:2px
style D6 fill:#fdf4ff,stroke:#a21caf,stroke-width:2px
style D7 fill:#fee2e2,stroke:#dc2626,stroke-width:2px
style D8 fill:#fef3c7,stroke:#d97706,stroke-width:2px
style D9 fill:#dbeafe,stroke:#2563eb,stroke-width:2px
style C5 fill:#fef9c3,stroke:#ca8a04,stroke-width:1px
style TOOLS fill:#ecfeff,stroke:#0891b2,stroke-width:1px2.1.1 领域职责划分
| 领域 | 核心职责 | 涉及服务 |
|---|---|---|
| 交易与回测 | 行情抓取、实盘/模拟交易录入、持仓结算、回测引擎执行、交易重演 | stock_quote, settlement, dsa_backtest, trade_replay |
| 投研与 AI | 多维搜索、LLM 报告生成、智能对话、多 Agent 编排、15 个策略 Skill(YAML CRUD + 热加载)、个股深度分析 | research, llm, search, analysis, multi_agent.*, skills.manager/router/aggregator |
| 多 Agent 编排 | 5 类 Agent (Technical/Intel/Risk/Decision/Portfolio) + Orchestrator 4 模式 (quick/standard/full/specialist) | multi_agent.orchestrator, multi_agent.agents.*, multi_agent.skills.skill_agent |
| 告警 | 14 种 alert_type(技术指标/组合风险/大盘灯)× 5 种 target_scope × 3 级 severity,60s 周期评估 + 冷却 + 飞书推送 | alerts endpoint + AlertRule/Trigger/Notification/Cooldown 模型 |
| 大盘复盘 | 工作日 18:00 LLM 解读大盘 + 周末兜底取最近一次复盘 | dashboard.market_review + MarketReview 模型 + market_analyzer |
| 自选股同步 | 东方财富 self-select → 本地 watchlist 全量镜像,08:00-22:30 区间按 30min 间隔触发 | watchlist_sync_service + WATCHLIST_SYNC_* 配置 |
| 妙想 mx 服务 | 东方财富妙想 4 个 Skill 集成 — 搜索三源合并 / 自然语言金融数据 / 智能选股 / 自选股双写,统一鉴权与限流熔断 | mx_data_service, mx_xuangu_service, mx_zixuan_service, search_service._search_mx |
| 平台与支撑 | 自动化任务调度(APScheduler)、飞书通知推送、系统配置管理、工作区文件托管 | scheduler, feishu_sender, config, workspace |
2.2 API 路由总览
16 个 endpoint 文件,80+ REST + SSE 端点。
| 模块 | 基础路径 | 主要端点 |
|---|---|---|
| 账户管理 | /accounts | GET / · POST / · GET /{id} · PUT /{id} · DELETE /{id} · GET /{id}/cash · GET /{id}/fund-flows · POST /{id}/deposit · POST /{id}/withdraw |
| 持仓管理 | /positions | GET / · GET /basic · GET /simple · POST /close |
| 交易记录 | /trades | GET / · POST / · PUT /{id} · DELETE /{id} |
| 看板概览 | /dashboard | GET /kpis · GET /chart-data · GET /strategies · GET /positions · GET /market-overview · GET /market-review |
| 回测引擎 | /backtest | GET / · POST /(账户回测)· GET /dsa/*(dsa_backtest 内联)· POST /plans/*(调度) |
| 投研任务 | /research | GET/POST /tasks · GET/PUT/DELETE /tasks/{id} · GET/POST /reports · POST /batch-push |
| AI Agent | /agent | GET/POST /sessions · POST /chat · POST /chat/stream (SSE) · POST /research · POST /orchestrate(多 Agent 编排,4 模式)· GET /orchestrator/modes · GET /tools |
| Skills CRUD | /agent/skills | GET / · GET /{id} · POST / · PUT /{id} · DELETE /{id} · POST /reload(YAML 热加载) |
| 深度分析 | /analysis | POST /analyze · GET /status/{id} · GET /tasks · GET /history |
| 异步任务事件流 | /tasks | GET /tasks · GET /tasks/{id} · DELETE /tasks/{id} · GET /tasks/{id}/events(SSE 任务事件) |
| 告警系统 | /alerts | GET /types(14 种 alert_type schema)· GET/POST/PATCH/DELETE /rules · POST /rules/{id}/enable(disable、test) · GET /triggers · GET /notifications |
| 组合管理 | /portfolio | GET/POST /trades · PUT/DELETE /trades/{id} · GET /snapshot · GET /accounts · POST /imports/csv/commit · GET /imports/csv/brokers |
| 股票行情 | /stocks | GET /{code}/quote · GET /{code}/intraday · GET /{code}/history · POST /batch-quote · GET /{code}/mx-query(mx-data)· POST /xuangu(mx-xuangu)· GET/POST/PUT/DELETE /watchlist(mx-zixuan 双写)· POST /watchlist/sync-from-eastmoney · GET /watchlist/sync-status · POST /parse-import |
| 搜索推送 | /search | GET /news(tavily+mx+bocha 三源合并)· GET /intel(6 维度 tavily+mx 双源)· POST /feishu/send |
| 策略工作区 | /workspace | GET /strategies · GET/PUT/POST/DELETE /files · POST /strategies/{id}/seed · GET /scan · GET /file-content · PUT /file-write |
| 系统设置 | /settings | GET /(含 ?category=llm、data、mx、backtest、notify、agent、alert、market_review、watchlist、research)· GET /{key} · PUT /{key} · POST /{key}/reset |
| 策略管理 | /strategies | GET / · POST / · GET/PUT/DELETE /{id} |
配套前端:16 个页面(Dashboard / Agent / Agent-Skills / Alerts / Backtest / Research / Analysis / Workspace / Xuangu / Watchlist / Settings 等),9 个 Zustand Store。
配套数据:15 个 Skill YAML(5 trend / 8 framework / 1 reversal / 1 pattern),YAML 驱动 + 在线 CRUD + 热加载。
2.3 运行机制与规范
2.3.1 自动化任务调度时序
sequenceDiagram
autonumber
participant CRON as APScheduler
participant SVC as Services
participant DB as SQLite
participant EXT as 外部依赖
participant FE as React Frontend
participant U as 用户
par 每日 09:30 工作日
CRON->>SVC: run_research_task(task_id)
SVC->>EXT: Tavily+mx-search 新闻
SVC->>EXT: efinance/tushare 行情
SVC->>SVC: research_service 3阶段pipeline
SVC->>EXT: LLM 生成报告
SVC->>DB: 写入 research_reports
SVC->>EXT: FeishuSender 推送卡片
end
par 每日 09:30 / 自定义Cron
CRON->>SVC: run_backtest_plan(plan_id)
SVC->>DB: 读取 dsa_backtest_run
SVC->>SVC: dsa_backtest_engine 计算收益
SVC->>DB: 写入 dsa_backtest_result/summary
end
par 每日 15:10 工作日
CRON->>SVC: settle_positions_sync()
SVC->>EXT: stock_quote_service 收盘价
SVC->>DB: 固化浮盈亏
end
par 每日 18:00 工作日
CRON->>SVC: market_review.regenerate()
SVC->>EXT: market_analyzer 拉行情
SVC->>SVC: 大盘灯/涨跌家数/板块强弱
SVC->>EXT: LLM 解读生成 Markdown
SVC->>DB: 写入 market_reviews
end
par 每日 08:00-22:30 每 30min
CRON->>SVC: watchlist_sync_service.run_with_lock()
SVC->>EXT: mx-zixuan self-select API
SVC->>DB: 增量 diff 写 watchlist
SVC->>DB: 记录 WATCHLIST_SYNC_LAST_RESULT
end
par 60s 周期
CRON->>SVC: alert_worker.evaluate_all()
SVC->>DB: 读 active rules
SVC->>EXT: 行情/技术指标/组合
SVC->>SVC: 命中检查 + cooldown 去重
SVC->>DB: 写 alert_triggers
SVC->>EXT: FeishuSender 推卡片
end
par 每日 18:00 工作日
CRON->>SVC: run_batch_push()
SVC->>DB: 汇总当日 reports
SVC->>EXT: 推送飞书日报
end
U->>FE: 打开 Dashboard
FE->>SVC: GET /api/v1/dashboard/kpis
SVC->>DB: 聚合 KPI/图表
DB-->>FE: JSON
FE-->>U: Recharts 渲染2.3.2 策略执行与回测架构
策略与 AI 信号通过「多 Agent 编排 → AnalysisHistory 固化 → DSA 回测评估」闭环实现持续追踪。信号通过多 Agent 编排后直接落 analysis_history 表(不再有独立的 signal 端点)。
flowchart LR
subgraph AGENT["多 Agent 编排"]
A1["POST /agent/orchestrate"] --> A2["5 Agent 阶段<br/>Technical/Intel/Risk/Decision/Portfolio"]
A2 --> A3["DecisionAgent<br/>输出 buy/sell/hold/neutral"]
end
subgraph STORAGE["规范化存储 (DB)"]
S1["AnalysisHistory (DB)"]
end
subgraph EVAL["回测与评估 (DSA Engine)"]
E1["配置评估窗口 (默认 10 交易日)"]
E2["检查止盈/止损触发"]
E3["计算胜率/方向准确率"]
E4["生成 BacktestRun/Result"]
end
A3 -- "规范化 Payload" --> S1
S1 -- "回测数据源" --> E1
E1 --> E2 --> E3 --> E4策略信号生命周期
| 阶段 | 核心动作 | 说明 |
|---|---|---|
| ① 决策产生 | POST /agent/orchestrate 多 Agent 编排 | 4 种模式(quick/standard/full/specialist)输出 buy/sell/hold/neutral |
| ② 信号固化 | 直接写入 AnalysisHistory 表 | 含 stop_loss / take_profit / sentiment_score / operation_advice |
| ③ 效果评估 | POST /backtest/dsa/run | 在评估窗口(默认 10 交易日)内模拟价格波动,判断信号优劣 |
| ④ 闭环反馈 | 绩效 Dashboard + 告警 worker | 统计胜率、方向准确率、止损触发率,可触发 portfolio_drawdown 等告警 |
2.3.3 AI 策略输出与评估规范
1. 信号 Advice 枚举映射
| operation\_advice | 方向预期 | 仓位建议 | 评估逻辑说明 |
|---|---|---|---|
buy | up (上涨) | long (做多) | 价格触及 take_profit 为盈利 |
sell | down (下跌) | cash (空仓) | 价格触及 stop_loss (反向) 为盈利 |
hold | not\_down (不跌) | long (做多) | 价格未触及止损且维持收益为盈利 |
neutral | flat (中性) | cash (空仓) | 波动在极小范围内为中性 |
2. 核心 KPI 定义
| 指标 | 计算公式 / 说明 |
|---|---|
| 方向准确率 | 实际涨跌方向与预测方向一致的信号数 / 总评估数 |
| 胜率 (Win Rate) | 盈利信号数 / (盈利 + 亏损) |
| 止损触发率 | 触及止损价的信号比例(反映风险控制能力) |
| 平均收益率 | 所有信号在窗口期内的平均模拟收益率 |
3. 输出格式与落点
| 输出方 | 格式与内容 | 落点 |
|---|---|---|
| 智能问股 | SSE 流式 Markdown + 技能图谱 | 浏览器前端展示 |
| 调研报告 | Markdown + 评级(强烈推荐/推荐/中性/回避) | 数据库 + 飞书卡片推送 |
| 回测报告 | 结构化 JSON (含 KPI 与逐笔明细) | 数据库 + 回测历史列表 |
| 多 Agent 编排 | 分阶段结构化 Signal + Stage 耗时 | 浏览器前端展示 + DB |
| 告警触发 | 飞书卡片 + 站内通知 | DB (alert_triggers / alert_notifications) |
2.3.4 多 Agent 编排架构
quant-desk 引入「5 类专项 Agent + Orchestrator 4 模式 + Skill Manager」的多 Agent 体系,对单股/多股并发做深度分析。
flowchart TB
subgraph ORCH["Orchestrator (4 模式)"]
O1["quick: technical → decision (≈10s)"]
O2["standard: technical → intel → decision (≈20s)"]
O3["full: technical → intel → risk → decision (≈30s)"]
O4["specialist: ... + skill×3 → aggregator → decision (≈60s)"]
end
subgraph AGENTS["5 类专项 Agent"]
A1["TechnicalAgent<br/>K线/均线/技术指标/量能"]
A2["IntelAgent<br/>新闻/6 维度/研报/公告"]
A3["RiskAgent<br/>异常/止损/集中度"]
A4["DecisionAgent<br/>汇总 → buy/sell/hold/neutral"]
A5["PortfolioAgent<br/>组合视角/跨标的对比"]
end
subgraph SKILLS["Skill Manager (15 个 YAML)"]
S1["trend (5): bull_trend/ma/shrink/volume/dragon"]
S2["framework (8): chan/wave/box/emotion/event/expectation/growth/hot"]
S3["reversal (1): bottom_volume"]
S4["pattern (1): one_yang_three_yin"]
SA["YAML CRUD + reload (热加载, 免重启)"]
end
subgraph TOOLS["Tool Registry (6 类 15 个)"]
T1["data · analysis · search<br/>market · backtest · mx"]
end
O1 --> A1 --> A4
O2 --> A1 --> A2 --> A4
O3 --> A1 --> A2 --> A3 --> A4
O4 --> A1 --> A2 --> A3 --> SKILLS --> AGG["Aggregator"] --> A4
A4 -. 可选升级 .-> A5
A1 -. 调用 .-> TOOLS
A2 -. 调用 .-> TOOLS
A3 -. 调用 .-> TOOLS
SKILLS -. 调用 .-> TOOLS
style ORCH fill:#fdf4ff,stroke:#a21caf
style AGENTS fill:#eff6ff,stroke:#2563eb
style SKILLS fill:#fef3c7,stroke:#d97706
style TOOLS fill:#ecfeff,stroke:#0891b2Skill 分类(15 个)
| 类别 | 数量 | Skill | 默认行为 |
|---|---|---|---|
| trend | 5 | bull_trend(默认 active + router)/ ma_golden_cross / shrink_pullback(默认 router)/ volume_breakout(默认 active=false)/ dragon_head | 趋势跟踪类 |
| framework | 8 | chan_theory / wave_theory / box_oscillation / emotion_cycle / event_driven / expectation_repricing / growth_quality / hot_theme | 框架/逻辑类 |
| reversal | 1 | bottom_volume | 反转信号 |
| pattern | 1 | one_yang_three_yin | K 线形态 |
关键设计要点
| 维度 | 设计 | 实现 |
|---|---|---|
| 5 Agent 职责分离 | Technical 拿行情/技术、Intel 拿情报、Risk 拿风控、Decision 汇总、Portfolio 升级 | app/services/multi_agent/agents/*.py |
| Orchestrator 4 模式 | quick/standard/full/specialist 阶段递增,按耗时/场景选用 | app/services/multi_agent/orchestrator.py + factory.list_orchestrator_modes |
| Specialist 模式 | 标准流 + 3 个 skill agent 并行(按 default_priority 选)→ Aggregator 聚合成统一结论 | multi_agent.skills.skill_agent + aggregator |
| YAML CRUD + 热加载 | 15 个 skill 存 backend/app/data/agent_skills/*.yaml,在线 POST/PUT/DELETE 后 POST /skills/reload 立即生效 | multi_agent.skills.manager + GET/POST/PUT/DELETE /agent/skills |
| Tool Registry 6 类 | data/analysis/search/market/backtest/mx 共 15 个工具,LLM 通过 to_openai_tools() 拿 flat schema | app/services/multi_agent/tools/registry.py + __init__.register_all_tools |
| 国产 LLM 工具白名单 | 国产 LLM 调未授权工具时硬拒,返回提示而非让 LLM 自由发挥 | agent.py:_executor 白名单校验 |
| MX 工具降级 | mx_query_finance_data / mx_query_stocks 调用失败时 LLM 用其他工具继续,不阻断 | mx_data_service._query_via_script + 服务熔断 |
| PortfolioAgent 升级 | 多股请求自动启用,给出组合视角 vs 单股视角对比 | chat/stream 检测 stock_codes 多于 1 切换 |
2.3.5 告警系统架构
14 种 alert_type × 5 种 target_scope × 3 级 severity,60 秒周期评估 + 冷却去重 + 飞书推送。
flowchart LR
subgraph ALERT_TYPES["14 种 alert_type (3 大类)"]
T1["技术指标类<br/>price_cross · price_change_percent<br/>volume_spike · ma_price_cross<br/>rsi_threshold · macd_cross<br/>kdj_cross · cci_threshold"]
T2["组合风险类<br/>portfolio_stop_loss<br/>portfolio_concentration<br/>portfolio_drawdown<br/>portfolio_price_stale"]
T3["大盘灯类<br/>market_light_status<br/>market_light_score_drop"]
end
subgraph SCOPES["5 种 target_scope"]
S1["stock (单股)"]
S2["sector (板块)"]
S3["account (账户)"]
S4["portfolio (组合)"]
S5["market (大盘)"]
end
subgraph SEV["3 级 severity"]
V1["info (提示)"]
V2["warning (警告)"]
V3["critical (紧急)"]
end
subgraph WORKER["告警 Worker (60s 周期)"]
W1["拉取 enabled rules"]
W2["dry-run target (10s 超时)"]
W3["命中检查"]
W4["cooldown 去重 (默认 300s)"]
W5["写 alert_triggers + alert_notifications"]
W6["飞书卡片推送"]
end
T1 --> W1
T2 --> W1
T3 --> W1
S1 --> W1
S2 --> W1
S3 --> W1
S4 --> W1
S5 --> W1
V1 --> W1
V2 --> W1
V3 --> W1
W1 --> W2 --> W3 --> W4 --> W5 --> W6
style T1 fill:#dbeafe,stroke:#2563eb
style T2 fill:#fee2e2,stroke:#dc2626
style T3 fill:#fef3c7,stroke:#d97706
style WORKER fill:#f0fdf4,stroke:#16a34a关键设计要点
| 维度 | 设计 | 实现 |
|---|---|---|
| 数据模型 | 4 表:alert_rules (规则) · alert_triggers (触发历史) · alert_notifications (推送历史) · alert_cooldowns (冷却) | app/models/alert_*.py |
| 规则配置 | parameters (JSON) / cooldown_policy (JSON) / notification_policy (JSON) 全部可配置 | AlertRule 模型 |
| 静默时段 | ALERT_QUIET_HOURS_START / ALERT_QUIET_HOURS_END 全局静默 | app/core/config.py |
| Dry-run 端点 | POST /alerts/rules/{id}/test 立即评估一次不写 trigger,方便规则调试 | alerts.py:test_rule |
| 双超时 | 单标 dry-run 10s,整次 dry-run 30s(防规则卡死 worker) | ALERT_DRY_RUN_TARGET_TIMEOUT_SECONDS / ALERT_DRY_RUN_TOTAL_TIMEOUT_SECONDS |
| Worker 周期 | 默认 60s,可调;总开关 ALERT_WORKER_ENABLED | ALERT_WORKER_INTERVAL_SECONDS |
2.3.6 大盘复盘架构
工作日 18:00 自动跑 LLM 复盘,缓存 + 周末兜底。
flowchart TB
subgraph TRIGGERS["触发源"]
T1["CRON: 0 18 * * 1-5 (工作日 18:00)"]
T2["手动: GET /dashboard/market-review?use_cache=false"]
end
subgraph PIPELINE["复盘 Pipeline"]
S1["1. 查今日缓存 (market_reviews)"]
S2["2. 周末兜底: 取最近一次复盘<br/>(trade_date desc → created_at desc)"]
S3["3. 实时生成 (async)"]
S4["3a. market_analyzer 拉行情"]
S5["3b. 构建 大盘灯 + 涨跌家数 + 板块强弱"]
S6["3c. LLM 生成 Markdown 复盘"]
S7["3d. 写 market_reviews"]
end
subgraph GUARDS["兜底守卫"]
G1["is_weekend = today.weekday() >= 5"]
G2["use_cache=True + 非周末 → 走缓存"]
G3["is_weekend → 跳过生成, 走兜底"]
G4["冷启动 (库内无历史) → 走生成, logger.warning"]
end
T1 --> S1
T2 --> S1
S1 -->|hit| DONE["返 market_review.to_dict()"]
S1 -->|miss + is_weekend| S2
S2 -->|hit| DONE
S2 -->|miss| S4
S1 -->|miss + 工作日| S3 --> S4
S4 --> S5 --> S6 --> S7 --> DONE
style TRIGGERS fill:#fff7ed,stroke:#ea580c
style PIPELINE fill:#eff6ff,stroke:#2563eb
style GUARDS fill:#fef2f2,stroke:#dc2626关键设计要点
| 维度 | 设计 | 实现 |
|---|---|---|
| 双触发 | APScheduler 工作日 18:00 + 手动 ?use_cache=false | app/core/scheduler.py + dashboard.py:get_market_review |
| 周末兜底 | 周末无行情数据,不调 LLM(省 token),直接返最近一次复盘 | dashboard.py is_weekend 分支 |
| 冷启动兜底 | 库内一条都没有时仍走生成路径(首次会调用 LLM) | logger.warning("周末 + 库内无历史, 走生成路径") |
| async 化 | 同步 LLM 调用改 async,避免阻塞 uvicorn worker | app/market_analyzer.get_market_overview |
| 缓存 key | (region, trade_date) 唯一约束,今日 trade_date 命中即返 | MarketReview model |
| 专用 LLM | 可选 MARKET_REVIEW_LLM_MODEL 配置专用模型(空=全局 LLM_MODEL) | app/core/config.py |
2.3.7 自选股同步架构
东方财富妙想 self-select → 本地 watchlist 全量镜像,08:00-22:30 区间按 30min 间隔触发。
flowchart LR
subgraph SCHED["调度"]
S1["APScheduler 08:00-22:30"]
S2["WATCHLIST_SYNC_INTERVAL_MINUTES<br/>默认 30, 仅接受 60 的约数"]
S3["手动: POST /stocks/watchlist/sync-from-eastmoney"]
end
subgraph LOCK["分布式锁"]
L1["Redis / DB lock 防止并发"]
end
subgraph PIPE["同步 Pipeline"]
P1["拉东方财富 self-select API"]
P2["diff vs 本地 watchlist"]
P3["added / deleted / unchanged"]
P4["写本地 watchlist (妙想为镜像)"]
P5["记录 WATCHLIST_SYNC_LAST_RESULT"]
end
S1 --> L1
S2 --> L1
S3 --> L1
L1 --> P1 --> P2 --> P3 --> P4 --> P5
style SCHED fill:#fff7ed,stroke:#ea580c
style LOCK fill:#fef2f2,stroke:#dc2626
style PIPE fill:#eff6ff,stroke:#2563eb关键设计要点
| 维度 | 设计 | 实现 |
|---|---|---|
| 数据源为东方财富 | mx-zixuan self-select API 是单一真相源 | mx_zixuan_service.list_watchlist |
| 本地为镜像 | 妙想失败不影响本地业务 | stocks.py:watchlist POST/PUT/DELETE 异步双写 |
| 锁 | 进程级 + 手动同步并发安全 | run_watchlist_sync_with_lock |
| 结果可查 | WATCHLIST_SYNC_LAST_RESULT 存最近一次 JSON 结果(成功/added/deleted/error) | get_last_run_status |
| 配置 | WATCHLIST_SYNC_ENABLED / WATCHLIST_SYNC_INTERVAL_MINUTES 可调 | config_service |
2.3.8 妙想 mx 服务架构
东方财富妙想提供 5 个 Skill(mx-search / mx-data / mx-xuangu / mx-zixuan / mx-moni),quant-desk 已集成前 4 个,覆盖金融专业情报搜索 / 自然语言金融数据查询 / 智能选股 / 自选股双写四大场景。mx-moni(模拟组合)暂不集成,quant-desk 已有真实交易 + 回测闭环。
flowchart LR
subgraph SRC["妙想 4 个 Skill"]
S1["mx-search<br/>金融专业情报<br/>(公告/研报/政策)"]
S2["mx-data<br/>自然语言金融数据<br/>(财务/估值/行情)"]
S3["mx-xuangu<br/>智能选股<br/>(条件筛选)"]
S4["mx-zixuan<br/>自选股管理<br/>(add/del)"]
end
subgraph SVC["Service 层(统一鉴权 + 限流熔断)"]
direction TB
SE1["search_service._search_mx"]
SE2["mx_data_service"]
SE3["mx_xuangu_service"]
SE4["mx_zixuan_service"]
CB["模块级熔断器<br/>5min(113) / 1h(401/403)"]
AUTH["SystemConfig.MX_APIKEY<br/>(DB-only 统一鉴权)"]
end
subgraph API["API 端点"]
A1["GET /search/news<br/>GET /search/intel"]
A2["GET /stocks/{code}/mx-query"]
A3["POST /stocks/xuangu"]
A4["POST /stocks/watchlist<br/>(双写妙想)"]
end
subgraph FE["前端页面"]
F1["Research / 智能问股"]
F2["股票详情 - 妙想数据 Tab"]
F3["妙想问股 page"]
F4["自选列表 page"]
end
subgraph EXT["外部"]
M["mkapi2.dfcfs.com<br/>妙想 API"]
end
S1 --> SE1 --> A1 --> F1
S2 --> SE2 --> A2 --> F2
S3 --> SE3 --> A3 --> F3
S4 --> SE4 --> A4 --> F4
SE1 -. 同源 .-> CB
SE2 -. 同源 .-> CB
SE3 -. 同源 .-> CB
SE4 -. 同源 .-> CB
AUTH -. 配置 .-> SE1
AUTH -. 配置 .-> SE2
AUTH -. 配置 .-> SE3
AUTH -. 配置 .-> SE4
SE1 --> M
SE2 --> M
SE3 --> M
SE4 --> M关键设计要点
| 维度 | 设计 | 实现 |
|---|---|---|
| 统一鉴权 | 4 个 service 共享 MX_APIKEY / MX_BASE_URL / MX_ENABLED,DB-only(不依赖 .env/env) | config_service.get_config_value(db, "MX_APIKEY") |
| 限流熔断 | 妙想 API 每日免费 150 次(status 113 = 限流)。113 触发 5min 冷却,401/403 触发 1h 冷却,熔断期 short-circuit 零 HTTP 浪费 | mx_xuangu_service._record_rate_limit / mx_zixuan_service._record_rate_limit |
| 直连 + 脚本兜底 | service 优先直连 mkapi2.dfcfs.com,失败时降级到 ~/.hermes/skills/mx-*/ 脚本 | mx_data_service._query_via_script / mx_xuangu_service._search_via_script |
| 自选股双写 | 本地 watchlist add/delete 同步到妙想镜像,妙想失败不影响本地业务 | stocks.py:101-110 异步调用 mx_zixuan_service.add_to_mx_watchlist |
| 三源搜索合并 | /search/news tavily + mx + bocha 并行,URL+标题前 30 字去重,provider 标签智能切换 | search_service.search_stock_news |
| 选股技术列友好化 | 妙想返回 CHOICE_INNER_CODE / IN_OPTIONAL / CHG<NUM>{DATE} 等英文技术列 → 后端映射成中文(选股编号 / 已在自选 / 衍生XXX DATE) | mx_xuangu_service._normalize_column_name |
| MX_ENABLED 总开关 | false 时所有 mx-* 端点返回 503(用于降级运营/限流) | 每个 service is_enabled(db) 守卫 |
| 硬错不再兜底 | MX_APIKEY 未配置 等硬配置错 → 不再降级到脚本(脚本也需 key),错误直达用户 | mx_xuangu_service.is_hard_config_error |
妙想 vs quant-desk 已有数据源对比
| 场景 | quant-desk 已有 | 妙想 mx 补充 |
|---|---|---|
| 行情 | Efinance / Tushare / Baostock / TickFlow | 历年行情(5-10 年开高低收) |
| 财务 | Tushare 利润表/资产负债表 | 5-10 年净利润/营收/毛利率连续时间序列 |
| 估值 | Tushare PE/PB | PE/PB 历史分位 + 历史区间 |
| 持仓 | Tushare 机构持仓 | 机构持仓变化趋势 |
| 搜索 | Tavily + Bocha | mx-search 公告 PDF / 券商研报(带分析师+评级) |
| 选股 | 策略回测 | mx-xuangu 自然语言选股(条件筛选) |
| 自选股 | 本地 watchlist | 妙想 zixuan(多端同步) |
3. 数据模型
3.1 核心实体关系
erDiagram
STRATEGY ||--o{ ACCOUNT : "1:N"
STRATEGY ||--o{ BACKTEST_RUN : "1:N"
STRATEGY ||--o{ RESEARCH_TASK : "1:N"
STRATEGY ||--o{ TRADE : "1:N"
ACCOUNT ||--o{ POSITION : "1:N"
ACCOUNT ||--o{ TRADE : "1:N"
BACKTEST_RUN ||--o{ BACKTEST_RESULT : "1:N"
RESEARCH_TASK ||--o{ RESEARCH_REPORT : "1:N"
STRATEGY {
string id PK
string name
string description
string asset_class
string status
json parameters
timestamp created_at
}
ACCOUNT {
string id PK
string name
string strategy_id FK
decimal total_assets
decimal available_cash
decimal return_percent
string status
}
POSITION {
int id PK
string account_id FK
string ticker
string side
int quantity
decimal cost_price
decimal current_price
decimal unrealized_pnl
timestamp updated_at
}
TRADE {
int id PK
string account_id FK
string strategy_id FK
string ticker
string side
decimal price
int quantity
decimal fee
timestamp executed_at
}
BACKTEST_RUN {
string id PK
string strategy_id FK
string status
timestamp created_at
}
BACKTEST_RESULT {
string id PK
string run_id FK
decimal total_return
decimal annualized_return
decimal max_drawdown
decimal sharpe_ratio
}
RESEARCH_TASK {
string id PK
string strategy_id FK
string company_name
string ticker
boolean enabled
string push_timing
string cron_expression
}
RESEARCH_REPORT {
string id PK
string task_id FK
string company_name
string ticker
string summary
string rating
timestamp generated_at
}3.2 核心实体
Strategy(策略) — 交易策略主表
| 字段 | 类型 | 说明 |
|---|---|---|
| id | TEXT PK | UUID |
| name | TEXT | 策略名称 |
| description | TEXT | 描述 |
| asset\_class | TEXT | 资产类别(A股/美股/期权/期货) |
| status | TEXT | 状态(运行中/回测中/已暂停) |
| parameters | JSON | 策略参数 |
| created\_at | TIMESTAMP | 创建时间 |
Account(账户) — 策略关联账户
| 字段 | 类型 | 说明 |
|---|---|---|
| id | TEXT PK | UUID |
| name | TEXT | 账户名称 |
| strategy\_id | TEXT FK | 关联策略 |
| total\_assets | DECIMAL | 总资产 |
| available\_cash | DECIMAL | 可用资金 |
| return\_percent | DECIMAL | 收益率 |
| status | TEXT | 状态(正常/异常/已禁用) |
Position(持仓) — 账户持仓
| 字段 | 类型 | 说明 |
|---|---|---|
| id | INTEGER PK | 自增 |
| account\_id | TEXT FK | 关联账户 |
| ticker | TEXT | 股票代码 |
| side | TEXT | 方向(多/空) |
| quantity | INTEGER | 数量 |
| cost\_price | DECIMAL | 成本价 |
| current\_price | DECIMAL | 当前价 |
| unrealized\_pnl | DECIMAL | 浮盈亏 |
| updated\_at | TIMESTAMP | 更新时间 |
Trade(交易) — 成交记录
| 字段 | 类型 | 说明 |
|---|---|---|
| id | INTEGER PK | 自增 |
| account\_id | TEXT FK | 关联账户 |
| strategy\_id | TEXT FK | 关联策略 |
| ticker | TEXT | 股票代码 |
| side | TEXT | 方向(买入/卖出) |
| price | DECIMAL | 成交价 |
| quantity | INTEGER | 数量 |
| fee | DECIMAL | 手续费 |
| executed\_at | TIMESTAMP | 成交时间 |
BacktestRun / BacktestResult / BacktestSummary — 回测运行与结果
ResearchTask / ResearchReport — 调研任务与生成的报告
AnalysisTask / AnalysisHistory — 个股分析任务与历史(直接接多 Agent 编排输出,存 stop_loss / take_profit / sentiment_score / operation_advice)
Watchlist — 自选股(本地 + 妙想双向)
PortfolioTrade — 组合交易记录
AccountFundFlow — 账户资金流水
ChatSession — Agent 对话会话(含 mode 字段:chat / orchestrate)
WorkspaceFile — Workspace 代码文件
SystemConfig — 系统配置,分类(category)含:
llm— LLM 服务(LLM_API_KEY/LLM_BASE_URL/LLM_MODEL/AGENT_ENABLED)data— 多源行情与搜索(Tushare / Tavily / Efinance / Baostock / TickFlow / MiniMax Search)mx— 妙想(mx)鉴权(MX_APIKEY/MX_BASE_URL/MX_ENABLED)backtest— 回测参数notify— 飞书 Webhookagent— 多 Agent 编排(AGENT_MAX_STEPS/AGENT_MEMORY_ENABLED/AGENT_RISK_OVERRIDE_ENABLED/AGENT_SPECIALIST_MAX_SKILLS)alert— 告警系统(ALERT_WORKER_*/ALERT_DEFAULT_COOLDOWN_SECONDS/ALERT_QUIET_HOURS_*/ALERT_DRY_RUN_*)market_review— 大盘复盘(MARKET_REVIEW_*)watchlist— 自选股同步(WATCHLIST_SYNC_*)research— 调研任务调度(RESEARCH_BATCH_PUSH)
StockDaily — 股票日线数据缓存
MarketReview — 大盘复盘记录,按 (region, trade_date) 唯一约束
AlertRule / AlertTrigger / AlertNotification / AlertCooldown — 告警规则、触发历史、推送历史、冷却记录
4. 项目结构
quant-desk/
├── docs/
│ ├── architecture.md # 本文档
│ ├── backtest-user-guide.md
│ ├── backtest.md
│ ├── dsa-migration-analysis.md
│ └── product-brief.md
│
├── frontend/quant-desk-web/src/
│ ├── pages/ # 16 个页面
│ │ ├── dashboard.page.tsx
│ │ ├── strategies.page.tsx
│ │ ├── backtest.page.tsx
│ │ ├── accounts.page.tsx
│ │ ├── positions.page.tsx
│ │ ├── trades.page.tsx
│ │ ├── research.page.tsx
│ │ ├── agent.page.tsx # 4 模式 Orchestrator 切换
│ │ ├── agent-skills.page.tsx # Skill CRUD
│ │ ├── alerts.page.tsx # 告警规则管理
│ │ ├── analysis.page.tsx
│ │ ├── workspace.page.tsx
│ │ ├── signals.page.tsx # 下线提示页
│ │ ├── xuangu.page.tsx # 妙想问股
│ │ ├── watchlist.page.tsx
│ │ └── settings.page.tsx # 含 agent/alert/market_review 等分类
│ ├── stores/ # 9 个 Zustand Store
│ ├── components/
│ │ ├── layout/ # Layout · Sidebar
│ │ └── shared/ # KpiCard · StatusBadge · ConfirmDialog · Toast
│ ├── lib/ # api/error/format/notification
│ ├── data/ (theme.json)
│ └── core/ (app entry)
│
├── backend/app/
│ ├── api/v1/
│ │ ├── api.py # 路由汇总注册
│ │ └── endpoints/ # 16 个端点文件
│ │ ├── strategies.py
│ │ ├── accounts.py
│ │ ├── positions.py
│ │ ├── trades.py
│ │ ├── dashboard.py # 含 market-overview / market-review
│ │ ├── portfolio.py # 含 imports/csv/*
│ │ ├── backtest.py # 整合 dsa/plans 子路由
│ │ ├── research.py
│ │ ├── agent.py # 多 Agent 编排 + Skills CRUD + Tools 列表
│ │ ├── analysis.py
│ │ ├── stocks.py # 含 intraday / mx-query / watchlist/sync-*
│ │ ├── search.py
│ │ ├── workspace.py # 含 file-content
│ │ ├── settings.py
│ │ ├── alerts.py # 告警系统
│ │ └── tasks.py # 异步任务事件流
│ ├── services/ # 21 个服务 + multi_agent 子模块
│ │ ├── stock_quote_service.py
│ │ ├── efinance_fetcher.py
│ │ ├── tushare_fetcher.py
│ │ ├── baostock_fetcher.py
│ │ ├── tickflow_fetcher.py
│ │ ├── data_source_base.py
│ │ ├── llm_service.py
│ │ ├── research_service.py
│ │ ├── search_service.py # 含 _search_mx
│ │ ├── mx_data_service.py # mx-data
│ │ ├── mx_xuangu_service.py # mx-xuangu
│ │ ├── mx_zixuan_service.py # mx-zixuan
│ │ ├── dsa_backtest_service.py
│ │ ├── dsa_backtest_engine.py
│ │ ├── trade_replay_service.py
│ │ ├── trade_replay_engine.py
│ │ ├── history_comparison_service.py
│ │ ├── settlement_service.py
│ │ ├── account_fund_flow_service.py
│ │ ├── config_service.py # DEFAULT_CONFIGS: llm/data/mx/backtest/notify/agent/alert/market_review/watchlist/research
│ │ ├── feishu_sender.py
│ │ ├── watchlist_sync_service.py # 自选股同步
│ │ ├── market_analyzer.py # 大盘复盘 + 大盘灯
│ │ └── multi_agent/ # 多 Agent 编排子系统
│ │ ├── orchestrator.py # AgentOrchestrator (4 模式调度)
│ │ ├── factory.py # list_orchestrator_modes + build_agent_executor
│ │ ├── executor.py # AgentExecutor (单 agent 旧模式)
│ │ ├── base.py # BaseAgent
│ │ ├── conversation.py
│ │ ├── chat_context.py
│ │ ├── events.py
│ │ ├── memory.py # AgentMemory
│ │ ├── protocols.py # Signal / AgentContext / AgentOpinion
│ │ ├── provider_trace.py
│ │ ├── agents/ # 5 类专项 Agent
│ │ │ ├── decision_agent.py
│ │ │ ├── intel_agent.py
│ │ │ ├── portfolio_agent.py
│ │ │ ├── risk_agent.py
│ │ │ └── technical_agent.py
│ │ └── tools/ # Tool Registry (6 类 15 个)
│ │ ├── registry.py # ToolRegistry + default_registry
│ │ ├── data_tools.py
│ │ ├── analysis_tools.py
│ │ ├── search_tools.py
│ │ ├── market_tools.py
│ │ ├── backtest_tools.py
│ │ └── mx_tools.py # mx_query_finance_data + mx_query_stocks
│ ├── data/
│ │ └── agent_skills/ # 15 个 Skill YAML
│ │ ├── bull_trend.yaml (default_active+router)
│ │ ├── ma_golden_cross.yaml
│ │ ├── shrink_pullback.yaml (default_router)
│ │ ├── volume_breakout.yaml (default_active=false)
│ │ ├── dragon_head.yaml
│ │ ├── chan_theory.yaml
│ │ ├── wave_theory.yaml
│ │ ├── box_oscillation.yaml
│ │ ├── emotion_cycle.yaml
│ │ ├── event_driven.yaml
│ │ ├── expectation_repricing.yaml
│ │ ├── growth_quality.yaml
│ │ ├── hot_theme.yaml
│ │ ├── bottom_volume.yaml
│ │ └── one_yang_three_yin.yaml
│ ├── models/ # 22 个 ORM 模型
│ ├── schemas/ # Pydantic 请求/响应模型
│ └── core/ # config · database · scheduler
│
├── stocks-skill/
│ └── SKILL.md # 量化工作台外部调用手册
│
├── backend/main.py
├── backend/seed.py
└── backend/quant_desk.db5. 关键设计决策
5.1 为什么用 Zustand 而非 Redux?
- 项目规模适中,不需要 Redux 的严格范式
- Zustand API 更简洁,减少样板代码
- 每个页面独立 Store,天然支持代码分割
5.2 为什么用 FastAPI + Python?
- Python 生态在量化/数据科学领域成熟
- FastAPI 原生支持异步,性能优秀
- Pydantic 提供强类型校验,与 TypeScript 前端类型可对应
- SQLAlchemy 2.0 支持异步 ORM
5.3 多数据源设计
行情数据通过统一的 DataSourceBase 抽象,支持多源切换:
efinance_fetcher— 东方财富,免费但数据快tushare_fetcher— Tushare Pro,需要 tokenbaostock_fetcher— 宝泉,免费,中文tickflow_fetcher— TickFlow,冷备数据源


Comments | NOTHING
该文章已经关闭评论