feat: 迭代03-05 交易记录接入、行情实时、QMT连接配置、data store 标准化

- R-004 QMT连接配置:多配置管理 + 会话头部快捷切换(03-QMT连接配置)
- R-005 WS盘中价格实时更新:服务端中转+缓存+前端轮询(04-WS盘中价格实时更新)
- R-006 策略数据 JSON data store 标准化(store.json/market.json/schema.json)
- R-007 交易记录接入:当日订单+成交单表合并(委托主行+展开成交明细)、时间段查询(今日/本周/本月+手动起止)、费用计算(佣金费率万m_dCommission+最低5元、印花税卖出万5、过户费双向万0.1)
- 架构治理:api 按领域拆分、component 目录、QmtHealthMonitor
This commit is contained in:
2026-09-01 13:21:49 +08:00
parent 5a723d514e
commit bb3f8bd28d
57 changed files with 5244 additions and 397 deletions
@@ -0,0 +1,60 @@
# 技术实现方案:04-WS盘中价格实时更新
> 依据:PLAN-004 | 需求:R-005 设计约束:技术约束-001/003/008/010、产品约束-007
## 技术选型
- **WebSocket 客户端**:浏览器原生 WebSocket(前端直连,无需 ws 库);
- **连接地址**`ws://<激活配置host>:8610/ws`,host 来自激活 QMT 连接配置(R-004 多配置机制,复用热切换);
- **订阅协议**`POST /data/subscribe` body `{ type: 'whole', codes: ['SH','SZ'] }``{ ok, sub_id }`
- **推送消息**`{ type: 'whole', data: { '<code>': TickSnapshot } }`TickSnapshot.lastPrice = 现价;
- **快照补初值**:连接后先 `GET /data/tick?codes=<关注codes>` 拉一次快照(WS 只推增量,无 prime);
- **退订**`POST /data/unsubscribe` body `{ sub_id }`(断开时清理)。
## 架构设计
### 前端行情数据流(事件驱动)
```
QMT Bridge WS (ws://<host>:8610/ws)
│ 推送 { type:'whole', data: { code: { lastPrice, ... } } }
MarketDataProvider (React Context + useReducer)
│ 维护 prices: Map<code, { lastPrice, lastClose, stime }>
│ 事件:onPrice(codes) → 通知订阅方
3 个监控表格(AllPositionsTab / StrategyTab
│ 行渲染时读 prices.get(code) 叠加现价
PriceCell(格式化 + 红涨绿跌 + 变化高亮)
```
### 关注列表(自动汇总)
- 3 个表格各自渲染时,把出现的 code 上报给 MarketDataProvider`registerCodes(codes)`);
- Provider 合并为关注集合,作为快照拉取与推送过滤的依据;
- 简化:全量推送本来就带所有 code,前端只从 prices Map 取自己行需要的 code(无需显式过滤,天然按需)。
### 生命周期
- 挂载:获取激活配置 host → 拉快照 → 建 WS → 订阅 whole → 收推送更新 Map;
- 配置切换:监听激活配置变化(host 变化)→ 断开旧 WS → 退订 → 重建连接;
- 断开:指数退避静默重连 + 状态提示(连接中/已连接/重连中/断开)。
## 涉及设计约束
| 约束 | 内容 |
|---|---|
| 技术约束-001 | 统一数据源抽象:行情实时数据仍走 QMT Bridge 适配器口径(现价字段 lastPrice 语义一致) |
| 技术约束-003 | 直连 QMT Bridge(前端直连其原生 WS,不经过 MCP) |
| 技术约束-008 | 复用激活 QMT 连接配置的 host(多配置热切换联动 WS) |
| 技术约束-010(新增) | 前端直连 QMT Bridge WebSocket 订阅行情;服务端不中转 WS |
| 产品约束-007(新增) | 3 个监控表格展示盘中现价列:红涨绿跌着色 + 变化高亮;仅现价一项 |
## 实现步骤
1. 服务端 API:新增 `qmt-connections/active-host`(返回 { host, baseUrl, wsUrl, name });
2. MarketDataProvider.jsxWS 客户端(连接/订阅/价格 Map/快照/重连/配置切换)+ Context
3. PriceCell.jsx:现价单元格(格式化 + 涨跌色 + 高亮动画);
4. 3 表格接入:AllPositionsTab / StrategyTab 加「现价」列;
5. 构建安装 + 验收。