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
@@ -1,23 +0,0 @@
# R-004 待确认问题(单独讨论)
> 状态:**全部未确认**(逐条讨论、逐条收敛)| 创建:2026-08-28
> 关联:docs/05-需求池/R-004.md(需求草稿)、docs/05-需求池/需求池索引.mdR-004
> 用途:R-004 的需求草稿只保留概述 / 现状分析 / 功能范围;**待确认问题单独在此记录并逐条讨论**。每确认一条即更新下方状态并写入「讨论记录」。
## 待确认问题清单
| # | 问题 | 状态 | 确认日期 | 结论摘要 |
|---|---|---|---|---|
| Q1 | **「默认」的语义**:默认 = 插件启动时自动激活的配置?还是仅作为列表中的默认选中项?手动激活非默认配置后,下次启动是否回到默认? | 未确认 | - | - |
| Q2 | **生效机制**:激活配置后**立即切换**(动态重建数据源,无需重启 DSH)?还是保存后**重启生效**?(当前数据源在插件 apply 时创建一次,改为动态切换需调整架构) | 未确认 | - | - |
| Q3 | **是否提供「测试连接」按钮**:验证地址可达(请求 /health 检查 status=ok),帮助确认配置正确? | 未确认 | - | - |
| Q4 | **现有宿主配置迁移**cordis.patch.yml 中的 `qmtBaseUrl`192.168.3.43:8610)如何处理 —— 首次启动时作为**初始默认配置**自动迁入设置页? | 未确认 | - | - |
| Q5 | **超时是否纳入配置项**:timeoutMs 是否需要出现在配置表单(可选字段),还是保持代码默认值? | 未确认 | - | - |
| Q6 | **删除/切换边界**:删除当前激活配置时如何处理(禁止删除?自动切换到默认?);删除默认配置时默认标记如何转移? | 未确认 | - | - |
| Q7 | **优先级**:老师定级(P0-P2?)—— 建议 P1(提升多环境可用性,单地址当前可用) | 未确认 | - | - |
## 讨论记录
> 追加式记录:日期 · 轮次 · 结论。确认 Q1 后即追加对应结论,并回填上方表格。
- (待第一轮讨论)
-48
View File
@@ -1,48 +0,0 @@
# R-004 QMT 连接配置(多配置管理)· 初步需求草稿
> 状态:**讨论中**(初步草稿,待老师确认后定稿)| 登记日期:2026-08-28
> 来源:老师指令(2026-08-28
> 关联:docs/05-需求池/需求池索引.mdR-004
## 需求概述
在神之一手的**设置页面**新增一个子 tab「QMT 连接配置」,用于管理多个 QMT Bridge 连接配置:
- **多配置管理**:可维护多个连接配置(增 / 删 / 改 / 查);
- **一次只能激活一个**:从多个配置中单选激活一个,被激活的配置为当前生效连接;
- **可设置默认**:标记某配置为默认(语义待确认,见「待确认问题」)。
## 现状分析:插件当前使用的 QMT 连接信息
> 通过代码审查得出(src/data-source/qmt-bridge-rest.js、src/index.js、cordis.patch.yml):
| 配置项 | 当前值 | 是否必配 | 说明 |
|---|---|---|---|
| **HTTP 基础地址(baseUrl** | `http://192.168.3.43:8610` | **是(唯一必配)** | 由宿主 cordis.patch.yml 注入 `config.qmtBaseUrl`;数据源所有 REST 请求基于此地址 |
| **请求超时(timeoutMs** | 15000ms | 否(有默认值) | 代码常量 REQUEST_TIMEOUT_MS=15000,当前未暴露到配置,使用默认值 |
**分析结论**
1. **核心只需配置一个 HTTP 地址**baseUrl)—— 插件与 QMT Bridge 的所有通信都基于它(/health、/trade/*、/data/* 等 REST 端点);
2. **可选配置一个请求超时**(timeoutMs)—— 仅在需要调整超时时才需配置,可提供默认值;
3. **当前不需要其他连接参数**:无认证(QMT Bridge REST 端点无鉴权)、无账户/密码、无额外 header —— 未来若 QMT Bridge 增加鉴权,再扩展配置字段。
## 功能范围(初步)
**做**
1. 设置页新增「QMT 连接配置」子 tab(与现有「通用设置 / 策略分组」并列);
2. **配置 CRUD**
- 新增:名称(识别用,如「本机 QMT」)+ HTTP 地址(必填)+ 请求超时(可选,默认 15000ms);
- 编辑 / 删除 / 重命名;
3. **激活**:单选激活,**一次只能激活一个**;激活的配置为当前生效连接;
4. **默认**:标记某配置为默认(待确认语义);
5. **生效**:激活/修改配置后,插件数据源切换(生效机制待确认,见「待确认问题」)。
**不做(初步)**
- 认证/多账户支持(QMT Bridge 当前无鉴权,未来扩展);
- 连接状态监控(如断线重连策略)—— 后续。
## 待确认问题(单独讨论)
> 7 个待确认问题已单独记录于 **docs/05-需求池/R-004-待确认问题.md**,逐条讨论、逐条收敛,不在此文件内讨论。
- [ ] 待确认问题清单:见 `R-004-待确认问题.md`Q1-Q7,全部未确认)
+543
View File
@@ -0,0 +1,543 @@
# R-007 交易记录接入(订单与成交数据)· 需求与技术研究
> 需求状态:**起草**(2026-09-01 入池,需求与技术研究进行中;AI 提议提为「讨论中」,待老师确认)
> 更新日期:2026-09-01 来源:老师指令(2026-09-01
> 关联:docs/05-需求池/需求池索引.mdR-007)、docs/01-终极目标/终极目标.md(目标-006 交易复盘、目标-003 按策略监控市场)
> 前置研究:本文件已含第一轮技术研究(QMT Bridge 订单/成交 API 实测 + 现有架构集成分析),待确认问题 Q1-Q10 待老师逐条拍板
## 需求概述
在神之一手的**「交易记录」tab**(当前为占位)中接入 **QMT Bridge 的订单(当日委托)与成交(当日成交)数据**,实时展示当日委托与成交明细,支撑**交易复盘**(目标-006)与**按策略监控交易**(目标-003)。
- **订单数据**:当日委托列表(含委托状态、委托量、成交量、限价、时间等);
- **成交数据**:当日成交列表(含成交价、成交量、手续费、成交额、时间等);
- **展示位置**:现有「交易记录」tabconversation.viewid=odl-trade-recordstradeRecords 显隐开关已预置,当前渲染 PlaceholderTab 占位);
- **数据来源**:插件服务端直连 QMT Bridge REST(技术约束-003,不经过 MCP 层),复用现有统一数据源抽象(技术约束-001)。
## 现状分析
### 1. QMT Bridge 已具备订单/成交查询能力(API 面实测)
| 端点 | 方法 | 说明 | 过滤参数 |
|---|---|---|---|
| /trade/orders | GET | 当日委托列表(m_* 原始字段),账号为桥绑定账号(单账号策略) | code(客户端过滤,600519 或 600519.SH)、statusactive=排除已撤54/废单57,或数字状态码 48-57)、strategy_nameQMT 服务端按 passorder 策略名过滤) |
| /trade/trades | GET | 当日成交列表(m_* 原始字段) | 无(返回全部当日成交) |
**数据特性**:两类数据均由 QMT 策略线程(adjust)每 **300ms 缓存刷新**,HTTP 线程只读缓存——即数据本身是准实时的(约 300ms 延迟),服务端无需自建订阅,REST 轮询即可。
### 2. 数据结构(OpenAPI 规范 + 线上实测样本)
**Order(当日委托)核心字段**
| 字段 | 类型 | 说明 |
|---|---|---|
| m_strOrderSysID | string | 合同编号/委托号(撤单凭此号) |
| m_strInstrumentID / m_strInstrumentName | string | 证券代码(不带后缀)/ 名称 |
| m_nDirection | int | 操作标记(EEntrustBS**股票买卖永远是 48**,不表达方向,官方已注明;见 Q3 研究) |
| m_nOrderStatus | int | 委托状态码:48=未报 49=待报 50=已报(待成交) 51=已报待撤 52=部成待撤 53=部撤 54=已撤 55=部成 56=已成 57=废单 |
| m_nVolumeTotalOriginal / m_nVolumeTraded / m_nVolumeTotal | int | 委托数量(最初)/ 已成交量 / 剩余量 |
| m_dLimitPrice | number | 委托价格(限价单限价) |
| m_strInsertDate / m_strInsertTime | string | 委托日期(YYYYMMDD/ 时间(HHMMSS |
| m_dTradedPrice | number | 成交均价(股票) |
| m_strErrorMsg / m_strCancelInfo | string | 状态信息 / 废单原因 |
| m_strOptName | string | **操作名称(实测「限价卖出」,含方向语义,方向判定关键字段)** |
**Trade(当日成交)核心字段**
| 字段 | 类型 | 说明 |
|---|---|---|
| m_strTradeID | string | 成交编号 |
| m_strOrderSysID | string | 合同编号/委托号(与委托表同号,**用于关联委托↔成交**) |
| m_strInstrumentID / m_strInstrumentName | string | 证券代码(不带后缀)/ 名称 |
| m_nDirection | int | 操作标记(同订单,股票恒为 48,不判方向) |
| m_dPrice | number | 成交均价 |
| m_nVolume | int | 成交量(股) |
| m_strTradeDate / m_strTradeTime | string | 成交日期(YYYYMMDD/ 时间(HHMMSS |
| m_dCommission | number | 手续费 |
| m_dTradeAmount | number | 成交额 |
| m_strOptName | string | 操作名称(含方向语义) |
**线上实测样本**2026-09-01):当日 1 笔委托 + 1 笔成交(博纳影业 001330.SZ,限价卖出 200 股 @6.00,已成 m_nOrderStatus=56,手续费 0.852 元)。方向判定结论(官方 innerApi 字典核实):m_nDirection=48 是 EEntrustBS 的「买卖」操作标记(官方注明股票买卖永远是 48),**不表达方向**;真实方向在 m_nOffsetFlagEOffset_Flag_Type48=买入开仓/49=卖出平仓,实测 49 与「限价卖出」吻合);m_strOptName 为买卖标记中文展示。**方向判定应以 m_nOffsetFlag 为准 + m_strOptName 交叉验证(Q3 已解决)**。
### 2.1 QMT 桥返回字段全表(实测 2026-09-01
> 实调 QMT 桥 /trade/orders 与 /trade/trades 得到的完整字段。标注 ★ 的字段为**语义化映射应保留的核心字段**(股票场景),其余为期权/期货/人民币换算/融资融券等场景字段(股票时为空或默认值)。
> 字段体系:大 QMT 内置 APIinnerApi),枚举见 https://dict.thinktrader.net/innerApi/enum_constants.html
**当日委托(/trade/orders)字段表**
| 字段 | 类型 | 实测值 | 说明 | 映射 |
|---|---|---|---|---|
| m_strOrderSysID | string | 645009273 | 合同编号/委托号(唯一标识,撤单凭此号) | ★ |
| m_strOrderRef | string | SZ_645009273 | 委托引用号(带交易所前缀) | ★ |
| m_strAccountID | string | 8882874667 | 资金账号 | |
| m_strAccountKey | string | 2____10125____… | 账号组合键(内部用) | |
| m_strAccountName | string | (空) | 账号名称 | |
| m_strAccountRemark | string | (空) | 账号备注 | |
| m_strInstrumentID | string | 001330 | 证券代码(不带后缀) | ★ |
| m_strInstrumentName | string | 博纳影业 | 证券名称 | ★ |
| m_strExchangeID | string | SZ | 交易所(SH/SZ | ★ |
| m_strExchangeName | string | 深交所 | 交易所中文名 | |
| m_strUnderCode | string | (空) | 标的代码(衍生品用) | |
| m_strProductID / ProductName | string | (空) | 产品代码/名称(股票为空) | |
| m_nDirection | int | 48 | EEntrustBS 操作标记:**股票买卖恒为 48**(非方向) | |
| m_nOffsetFlag | int | 49 | **EOffset_Flag_Type48=买入开仓 / 49=卖出平仓(方向判定关键)** | ★ |
| m_nHedgeFlag | int | 49 | 投保标记(投机=49 | |
| m_nOrderPriceType | int | 50 | 价格类型(50=限价,enum_EBrokerPriceType | |
| m_eEntrustType | int | 48 | 委托类型(48=普通委托) | |
| m_strOptName | string | 限价卖出 | **买卖标记中文(方向展示/交叉验证)** | ★ |
| m_strOption / OrderParam / OrderStrategyType | string | (空) | 期权属性/委托参数/策略类型名 | |
| m_nOrderStrategyType / m_nOpType | int | 异常值 | 策略类型码/操作类型(无实际意义) | |
| m_nVolumeTotalOriginal | int | 200 | 委托数量(最初委托量) | ★ |
| m_nVolumeTraded | int | 200 | 已成交量 | ★ |
| m_nVolumeTotal | int | 0 | 剩余量(总委托-成交) | ★ |
| m_dLimitPrice | number | 6 | 委托价格(限价) | ★ |
| m_dTradedPrice | number | 6 | 成交均价 | ★ |
| m_dTradeAmount | number | 1200 | 成交金额 | ★ |
| m_dCancelAmount | number | 0 | 已撤数量 | |
| m_dOrderPriceRMB / TradeAmountRMB / ReferenceRate | number | 0 | 人民币换算/参考汇率(外币标的) | |
| m_dFrozenCommission / FrozenMargin / ShortOccupedMargin | number | 0 | 冻结手续费/保证金/卖空占用保证金 | |
| m_eCashgroupProp / m_eCoveredFlag | int | 48 / 0 | 资金组属性/遮盖标记 | |
| m_nOrderStatus | int | 56 | 委托状态:48未报 49待报 50已报 51已报待撤 52部成待撤 53部撤 54已撤 55部成 56已成 57废单 | ★ |
| m_nOrderSubmitStatus | int | 51 | 委托提交状态(51=已提交) | |
| m_strErrorMsg / m_strCancelInfo | string | (空) | 状态信息/废单原因 | |
| m_nErrorID | int | 2147483647 | 错误码(默认值=无错误) | |
| m_strInsertDate / m_strInsertTime | string | 20260901 / 101333 | 委托日期(YYYYMMDD/时间(HHMMSS | ★ |
| m_nStrategyID | int | 4322211943619263000 | 策略 IDpassorder 所属) | |
| m_strSource / m_strXTTrade | string | (空)/其他终端 | 委托来源/交易终端 | |
| m_nTaskId / FrontID / SessionID / Ref / GroupId | int | -1/2147483647 等 | 任务号/前置机/会话/引用/组号(无实际意义) | |
| m_strCompactNo / BrokerName / LocalInfo / Remark | string | (空) | 合约编号/券商/本地信息/备注 | |
| m_bEnable | bool | true | 是否有效 | |
| m_xtTag | null | null | 扩展标签 | |
**当日成交(/trade/trades)字段表**
| 字段 | 类型 | 实测值 | 说明 | 映射 |
|---|---|---|---|---|
| m_strTradeID | string | 0103000030812084 | 成交编号(唯一标识) | ★ |
| m_strOrderSysID | string | 645009273 | **合同编号/委托号(与委托表同号,关联委托↔成交)** | ★ |
| m_strOrderRef | string | SZ_645009273 | 委托引用号(带交易所前缀) | |
| m_strAccountID | string | 8882874667 | 资金账号 | |
| m_strAccountKey / AccountRemark | string | (空) | 账号组合键/备注 | |
| m_strInstrumentID | string | 001330 | 证券代码(不带后缀) | ★ |
| m_strInstrumentName | string | 博纳影业 | 证券名称 | ★ |
| m_strExchangeID / ExchangeName | string | SZ / 深交所 | 交易所 | ★ |
| m_strProductID / ProductName | string | (空) | 产品代码/名称(股票为空) | |
| m_nDirection | int | 48 | EEntrustBS 操作标记:**股票买卖恒为 48**(非方向) | |
| m_nOffsetFlag | int | 49 | **EOffset_Flag_Type48=买入开仓 / 49=卖出平仓(方向判定关键)** | ★ |
| m_nRealOffsetFlag | int | -1 | 实际操作类型(-1=未用) | |
| m_nHedgeFlag | int | 49 | 投保标记(投机=49 | |
| m_nOrderPriceType / m_eEntrustType | int | 50 / 48 | 价格类型/委托类型 | |
| m_eCoveredFlag / m_eFutureTradeType | int | 48 | 遮盖标记/期货交易类型 | |
| m_strOptName | string | 限价卖出 | **买卖标记中文(方向展示/交叉验证)** | ★ |
| m_strOperation | string | (空) | 操作描述 | |
| m_dPrice | number | 6 | 成交均价 | ★ |
| m_nVolume | int | 200 | 成交量(股) | ★ |
| m_dTradeAmount | number | 1200 | 成交金额 | ★ |
| m_dCommission | number | 0.852 | **佣金费率(万分之,2026-09-01 老师定)**0.852 = 万分之0.852 = 0.0000852(非金额);另有 m_dComssion 拼写变体同值 | ★ |
| m_dComssion | number | 0.852 | 手续费(拼写变体) | |
| m_dCloseProfit / m_nCloseTodayVolume | number/int | 0 | 平仓盈亏/平今量(期货用) | |
| m_dOrderPriceRMB / TradeAmountRMB / PriceRMB / ReferenceRate | number | 0 | 人民币换算/参考汇率 | |
| m_strTradeDate / m_strTradeTime | string | 20260901 / 101333 | 成交日期(YYYYMMDD/时间(HHMMSS | ★ |
| m_nStrategyID | int | 4322211943619263000 | 策略 IDpassorder 所属) | |
| m_nOrderStrategyType / m_strOrderStrategyType | int/string | 异常值/(空) | 委托策略类型(无实际意义) | |
| m_nTaskId / m_nGroupId / m_nRef | int | -1/2147483647/0 | 任务号/组号/引用(无实际意义) | |
| m_strSource / m_strXTTrade | string | (空)/其他终端 | 成交来源/交易终端 | |
| m_strCompactNo / LocalInfo / Remark | string | (空) | 合约编号/本地信息/备注 | |
| m_xtTag | null | null | 扩展标签 | |
**映射要点**:★ 字段共约 15 个/表,构成语义化模型(orderId/tradeId/code/name/exchange/direction/status/volumes/prices/amount/commission/time);m_nOffsetFlag+m_strOptName 双字段定方向;m_strOrderSysID 关联两表;**m_dCommission = 佣金费率(万分之),非金额(费用计算见「费用计算规则」)**。
**费用计算规则(2026-09-01 老师定,已实现 calcTradeFees**
| 费用项 | 计算 | 说明 |
|---|---|---|
| 佣金 | 成交额 × (m_dCommission ÷ 10000)**不足 5 元按 5 元** | 账号没免五,费率=万分之 m_dCommission(如 0.852 = 万0.852 |
| 印花税 | 成交额 × 万分之5(0.05% | **仅卖出**收取(2023-08-28 起标准,单边) |
| 过户费 | 成交额 × 万分之0.1(0.01‰) | **双向**收取,无最低限额(2022-04-29 起标准,中登收取,老师确认) |
| 总费用 | 佣金 + 印花税 + 过户费 | 逐笔计算后聚合展示 |
### 2.2 Sample Data(真实数据样本,2026-09-01 实调)
> 实调 QMT 桥 /trade/orders 与 /trade/trades 获取的**当日真实数据**(账号 8882874667,交易日期 20260901)。
> 当日共 1 笔委托 + 1 笔成交(博纳影业 001330.SZ 限价卖出 200 股 @6.00,已成,手续费 0.852 元)。
> 以下为**完整原始返回**(含空/默认字段),与 2.1 字段表一一对应。
**订单 Sample/trade/orders 原始返回)**
```json
{
"m_bEnable": true,
"m_dCancelAmount": 0,
"m_dFrozenCommission": 0,
"m_dFrozenMargin": 0,
"m_dLimitPrice": 6,
"m_dOrderPriceRMB": 0,
"m_dReferenceRate": 0,
"m_dShortOccupedMargin": 0,
"m_dTradeAmount": 1200,
"m_dTradeAmountRMB": 0,
"m_dTradedPrice": 6,
"m_eCashgroupProp": 48,
"m_eCoveredFlag": 0,
"m_eEntrustType": 48,
"m_nDirection": 48,
"m_nErrorID": 2147483647,
"m_nFrontID": -1,
"m_nGroupId": 2147483647,
"m_nHedgeFlag": 49,
"m_nOffsetFlag": 49,
"m_nOpType": 2147483647,
"m_nOrderPriceType": 50,
"m_nOrderStatus": 56,
"m_nOrderStrategyType": -1645423200,
"m_nOrderSubmitStatus": 51,
"m_nRef": 0,
"m_nSessionID": -1,
"m_nStrategyID": 4322211943619263000,
"m_nTaskId": -1,
"m_nVolumeTotal": 0,
"m_nVolumeTotalOriginal": 200,
"m_nVolumeTraded": 200,
"m_strAccountID": "8882874667",
"m_strAccountKey": "2____10125____105214____49____8882874667____",
"m_strAccountName": "",
"m_strAccountRemark": "",
"m_strBrokerName": "",
"m_strCancelInfo": "",
"m_strCompactNo": "",
"m_strErrorMsg": "",
"m_strExchangeID": "SZ",
"m_strExchangeName": "深交所",
"m_strInsertDate": "20260901",
"m_strInsertTime": "101333",
"m_strInstrumentID": "001330",
"m_strInstrumentName": "博纳影业",
"m_strLocalInfo": "",
"m_strOptName": "限价卖出",
"m_strOption": "",
"m_strOrderParam": "",
"m_strOrderRef": "SZ_645009273",
"m_strOrderStrategyType": "",
"m_strOrderSysID": "645009273",
"m_strProductID": "",
"m_strProductName": "",
"m_strRemark": "",
"m_strSource": "",
"m_strUnderCode": "",
"m_strXTTrade": "其他终端",
"m_xtTag": null
}
```
**成交 Sample/trade/trades 原始返回)**
```json
{
"m_dCloseProfit": 0,
"m_dCommission": 0.852,
"m_dComssion": 0.852,
"m_dOrderPriceRMB": 0,
"m_dPrice": 6,
"m_dPriceRMB": 0,
"m_dReferenceRate": 0,
"m_dTradeAmount": 1200,
"m_dTradeAmountRMB": 0,
"m_eCoveredFlag": 48,
"m_eEntrustType": 48,
"m_eFutureTradeType": 48,
"m_nCloseTodayVolume": 0,
"m_nDirection": 48,
"m_nGroupId": 2147483647,
"m_nHedgeFlag": 49,
"m_nOffsetFlag": 49,
"m_nOrderPriceType": 50,
"m_nOrderStrategyType": -296943616,
"m_nRealOffsetFlag": -1,
"m_nRef": 0,
"m_nStrategyID": 4322211943619263000,
"m_nTaskId": -1,
"m_nVolume": 200,
"m_strAccountID": "8882874667",
"m_strAccountKey": "2____10125____105214____49____8882874667____",
"m_strAccountRemark": "",
"m_strCompactNo": "",
"m_strExchangeID": "SZ",
"m_strExchangeName": "深交所",
"m_strInstrumentID": "001330",
"m_strInstrumentName": "博纳影业",
"m_strLocalInfo": "",
"m_strOperation": "",
"m_strOptName": "限价卖出",
"m_strOrderRef": "SZ_645009273",
"m_strOrderStrategyType": "",
"m_strOrderSysID": "645009273",
"m_strProductID": "",
"m_strProductName": "",
"m_strRemark": "",
"m_strSource": "",
"m_strTradeDate": "20260901",
"m_strTradeID": "0103000030812084",
"m_strTradeTime": "101333",
"m_strXTTrade": "其他终端",
"m_xtTag": null
}
```
**语义化映射结果(供数据模型参考)**
| 语义字段 | 订单值 | 成交值 | 来源字段 |
|---|---|---|---|
| orderId | 645009273 | 645009273 | m_strOrderSysID |
| tradeId | - | 0103000030812084 | m_strTradeID |
| code | 001330 | 001330 | m_strInstrumentID |
| name | 博纳影业 | 博纳影业 | m_strInstrumentName |
| exchange | SZ | SZ | m_strExchangeID |
| direction | 卖 | 卖 | m_nOffsetFlag=49 + m_strOptName=限价卖出 |
| status | 56 已成 | 已成 | m_nOrderStatus |
| orderVolume | 200 | - | m_nVolumeTotalOriginal |
| tradedVolume | 200 | 200 | m_nVolumeTraded / m_nVolume |
| limitPrice | 6 | - | m_dLimitPrice |
| price | 6 | 6 | m_dTradedPrice / m_dPrice |
| amount | 1200 | 1200 | m_dTradeAmount |
| commission | - | 0.852 | m_dCommission |
| date | 20260901 | 20260901 | m_strInsertDate / m_strTradeDate |
| time | 101333 | 101333 | m_strInsertTime / m_strTradeTime |
| accountId | 8882874667 | 8882874667 | m_strAccountID |
### 2.3 数据时效研究(能查多少天?)
> 核实日期:2026-09-01 结论来源:QMT 桥 OpenAPI 规范 + 大 QMT 内置 API 官方文档(dict.thinktrader.net/innerApi/
**结论:/trade/orders 与 /trade/trades 只能返回当日(当天交易日)的委托与成交,无法查历史。**
**证据链**
1. **QMT 桥 OpenAPI 规范**:两个端点的 summary 与 description 均明确「**当日**委托查询」「**当日**成交查询」,且参数只有 code/status/strategy_nameorders)或无参数(trades)——**没有日期范围参数**;
2. **底层函数**:QMT 桥数据由策略线程(adjust)调用 `get_trade_detail_data(account, 'stock', 'order'/'deal')` 缓存刷新(官方 code_examples 确认),官方示例全部是 3 参数调用,**无日期参数**;
3. **官方 Q&A(数据来源本质)**`get_trade_detail_data` 从**客户端本地缓存**读取(非调用时查柜台),缓存是「当前状态」——即当日委托/成交的实时快照;官方明确「不能认为查到的状态与柜台完全一致」;
4. **行情 vs 交易差异**:历史查询能力只存在于**行情**域(down_history_data / get_market_data_ex 可查历史 K线),**交易域(order/deal)没有历史查询接口**。
**对本需求的含义**
| 影响面 | 结论 |
|---|---|
| 「交易记录」tab 展示范围 | 只能展示**当日**委托与成交(当日快照) |
| 交易复盘(目标-006) | 当日复盘可完整支撑;跨日复盘需**每日落盘存档**(Q5 关联:若要做历史复盘,必须本地持久化) |
| Q5 是否持久化 | **由「可选」升级为「必要前提」**:不做持久化则复盘能力只有当日,重启即丢 |
| 数据刷新 | 当日数据准实时(300ms 缓存 + 柜台推送 50ms~6s),轮询即可 |
**结论映射**:R-007 功能范围「不做」中「历史(非当日)交易查询」一项**确认成立**(QMT Bridge 仅提供当日缓存,无法查历史);但「不做持久化」需要重新审视——若老师要支撑跨日复盘,Q5 应改为「做持久化(store.trades.json,按日存档)」或明确接受「仅当日复盘」。
### 3. 现有架构可复用点(代码审查)
| 现有能力 | 位置 | 复用方式 |
|---|---|---|
| 统一数据源抽象 + REST 直连 | src/component/QmtBridgeRestDataSource.js | 新增 getOrders()/getTrades() 方法(参照 getAsset/getPositionsm_ 字段→语义字段映射) |
| 服务端 HTTP API 领域分发 | src/api/index.js + 领域文件 | 新增 api/trades.js(订单/成交域),注入 METHODS + HANDLERS |
| 前端 tab 框架 | src/client/index.jsGENERAL_TABS | 交易记录 tab 的 render 从 PlaceholderTab 换成真实组件 |
| 服务端缓存 + 前端轮询模式 | MarketDataHub + MarketFeedmarket-snapshot | 交易数据可复用轮询模式(Q5 待定) |
| 设置显隐开关 | settings.js tabs.tradeRecords | 已预置,无需新增 |
| 涨跌着色/高亮组件 | PriceCell.jsx | 交易方向着色可复用(Q7 待定) |
## 功能范围(定稿,2026-09-01 老师拍板)
> 老师指令(2026-09-01):「先把当日订单与成交记录接进来,数据放到交易记录这个 tab 下;我会完善 QMT Bridge 历史成交的接口,所以请添加一个日期导航,根据交易日历来做一个日期导航。」
**做(本期)**
1. **数据源接入**QmtBridgeRestDataSource 新增当日委托/当日成交查询(getOrders/getTrades,语义化映射,核心字段见 2.1/2.2);
2. **服务端 API**:新增 orders / trades 端点(支持 code/status 过滤),纳入领域分发(新 api/trades.js);
3. **交易记录 tab 落地**:占位 tabodl-trade-records)替换为真实交易视图——**单表合并**:以委托行为主行,按 m_strOrderSysID 合并成交信息(聚合展示 + 行展开查看每笔成交明细);
4. **数据刷新**:服务端中转 + 前端轮询(准实时,QMT Bridge 自身 300ms 缓存;前端 3-5s 轮询);
5. **状态展示**:委托状态中文映射(未报/已报/部成/已成/已撤/废单等)、买卖方向识别(m_nOffsetFlag + m_strOptName)、成交金额/手续费展示;
6. **时间段查询(核心,v3 定稿)**:交易记录 tab 采用**起止时间段查询**(匹配历史接口按时间范围查询的形态)——标题 + 时间段控件**同一行**;控件含三个快捷按钮(**今日 / 本周 / 本月**)+ 手动起止日期(input type=date);快捷范围基于交易日历最近交易日计算且为**完整互斥时间段**(今日=最近交易日单日、本周=所在自然周**周一~周五**(不考虑周六日)、本月=所在自然月1号~月末);**交互单向模型**:preset 意图状态记录用户点的按钮,高亮=preset 匹配,不做「范围反推按钮」(2026-09-01 老师纠正:先有操作后有范围,不是反向推断);手动改日期清除 preset;「今日」范围 3-5s 轮询,其他范围一次性查询;非今日范围展示「历史数据接口开发中」占位(老师完善 QMT Bridge 历史接口后接入,服务端已预留 start/end 透传);
7. **委托↔成交合并**:按 m_strOrderSysID 关联——委托行为主行,聚合展示成交(成交量/成交价/成交额/手续费),展开后逐笔展示成交明细(2026-09-01 老师拍板)。
**不做(本期)**
- 下单/撤单等交易操作(QMT Bridge 当前为查询接口,无下单端点;目标-007 人机合一的关键决策控制权另议);
- 历史(非当日)交易查询实现(**接口由老师完善 QMT Bridge 后接入**,本期仅做日期导航占位);
- 交易数据本地持久化(Q5 本期不做,跨日复盘待历史接口就绪后评估);
- 按策略过滤交易(strategy_name 服务端过滤依赖 QMT passorder 策略名,与插件策略体系不同源,Q10 后续迭代)。
## 技术研究结论(第一轮)
1. **API 能力确认**QMT Bridge v2.0.0 已提供 /trade/orders(支持 code/status/strategy_name 过滤)+ /trade/trades(全量当日成交),数据由策略线程 300ms 缓存刷新、HTTP 线程只读缓存,**REST 轮询即可达准实时**,无需 WS 订阅(规避迭代 04 的 WS 不稳定教训);**时效边界:仅当日数据,无法查历史(2.3 数据时效研究)**;
2. **字段语义澄清(核心,官方 innerApi 字典核实)**:大 QMT 内置 APIdict.thinktrader.net/innerApi/)中,m_nDirection 对应 EEntrustBS 枚举(48=买卖/49=查询/50=撤单),官方注明「股票买卖永远是 48」——**它是操作标记不是方向**;真实买卖方向在 m_nOffsetFlagEOffset_Flag_Type48=买入开仓/49=卖出平仓,实测 49=限价卖出 完全吻合)+ m_strOptName(买卖标记中文);**方向判定规则已确定:m_nOffsetFlag 为主 + m_strOptName 交叉验证(Q3 有结论)**;
3. **字段模型清晰**:已沉淀两张字段全表(2.1 小节),语义化映射核心字段约 15 个/表(orderId/tradeId/code/name/exchange/direction/status/volumes/prices/amount/commission/time),数据模型可直接据此设计;
4. **集成路径清晰**:现有数据源抽象 / API 领域分发 / tab 框架 / 服务端缓存模式全部可复用,新增代码为增量式(1 个 API 领域文件 + 数据源 2 方法 + 前端 1 个组件);
5. **架构约束沿用**:技术约束-001/003(统一抽象 + REST 直连)、技术约束-004(webServer 自开路由)、技术约束-010 思路(服务端中转 + 缓存,前端轮询);
6. **测试隔离**:订单/成交为只读查询端点,回归测试可直连生产 API(符合技术约束-011 只读豁免),但禁止测试写操作;
7. **日期导航可行性(2026-09-01 实测)**QMT Bridge /data/calendar/trading_dates 可用(GET,支持 start/end 过滤,返回 { market, count, dates[] }dates 为 YYYYMMDD 数组)——取近 N 日交易日列表做前后切换导航即可;当日由 trading_dates 返回的最后一个交易日确定(或客户端本地日期取整)。
## 待确认问题(Q1-Q10,待老师拍板)
| # | 问题 | AI 建议 |
|---|---|---|
| # | 问题 | 结论(2026-09-01 |
|---|---|---|
| Q1 | **展示范围**:交易记录 tab 展示「当日委托 + 当日成交」两块,还是仅成交? | ✅ **两块都展示**:委托表(含状态)+ 成交表(含费用),tab 内分区块 |
| Q2 | **数据刷新机制**:服务端中转 + 前端轮询?周期? | ✅ 服务端中转 + 前端 3-5s 轮询(复用 market-snapshot 模式);QMT 自身 300ms 缓存 |
| Q3 | **买卖方向判定**m_nDirection 恒 48 不判方向,方向取哪个字段? | ✅ **m_nOffsetFlag 为主(48买/49卖)+ m_strOptName 展示交叉验证**(官方枚举核实,Q3 闭环) |
| Q4 | **委托状态展示**:默认过滤已撤/废单?还是全量? | ✅ 全量展示 + 状态列 + 可选筛选(active/全部),默认全量(首版简化:全量展示即可) |
| Q5 | **是否持久化**:跨日复盘的前提是落盘? | ✅ **本期不做持久化**(当日实时查询);跨日复盘待历史接口就绪后评估(老师将完善 QMT Bridge 历史成交接口) |
| Q6 | **委托↔成交关联形态**:两表还是单表合并? | ✅ **单表合并**:委托行为主行 + 展开/折叠查看每笔成交(老师拍板,2026-09-01);聚合成交信息在委托行展示,展开后逐笔明细 |
| Q7 | **方向着色**:买/卖如何着色? | ✅ 遵循 A 股习惯:**红买绿卖**(与行情红涨绿跌相反语义;前端实现时用色值区分) |
| Q8 | **手续费/成交额精度**:展示位与单位? | ✅ 成交额元(2 位小数)、手续费元(3 位小数)、成交量股 |
| Q9 | **优先级**:老师定级? | ✅ **P1**(交易复盘是目标-006 核心输入,tab 已占位) |
| Q10 | **与策略联动**:按插件策略过滤交易? | ✅ 本期不做(strategy_name 是 QMT passorder 概念,与插件策略不同源;后续迭代) |
| Q11 | **日期导航 → 时间段查询**2026-09-01 演进):基于交易日历的日期导航如何做? | ✅ **起止时间段查询**(老师反馈 v3):放弃单日前后导航,改为时间段(start~end);标题 + 时间段控件同一行;快捷按钮 今日/本周/本月 + 手动起止日期;匹配历史接口按时间范围查询的形态;服务端 orders/trades 预留 start/end 透传 |
## 展示设计:单表合并(委托为主,成交并入)
> 2026-09-01 老师拍板:**不要两个表,一个表**——当日委托信息为主行,根据 m_strOrderSysID 合并成交信息。
### 合并规则
- **主行 = 一笔委托**(按 m_strOrderSysID 唯一);
- **成交聚合**:该委托的全部成交(/trade/trades 中 m_strOrderSysID 匹配)聚合进主行;
- **行展开**:点击展开/折叠,展开后逐笔展示每笔成交明细(成交时间/价格/数量/金额/手续费)。
### 委托主行列(聚合态)
| 列 | 来源 | 显示逻辑 |
|---|---|---|
| 展开箭头 | - | ▸/▾ 切换(有成交才可展开;无成交置灰/隐藏) |
| 时间 | m_strInsertTime | HH:MM:SS(委托时间) |
| 代码 | m_strInstrumentID | 6 位代码 |
| 名称 | m_strInstrumentName | 中文名 |
| 方向 | m_nOffsetFlag(48买/49卖) + m_strOptName | **红买绿卖**(Q7);显示「买入/卖出」,悬停显示完整操作名(限价卖出) |
| 状态 | m_nOrderStatus | 中文映射:未报/待报/已报/已报待撤/部成待撤/部撤/已撤/部成/已成/废单 |
| 委托量 | m_nVolumeTotalOriginal | 整数 + 股 |
| 成交量 | Σ成交 m_nVolume(优先)或 m_nVolumeTraded | 聚合成交总量;无成交显示 — |
| 委托价 | m_dLimitPrice | 2 位小数;市价单显示「市价」 |
| **成交均价** | Σ(成交价×量)/Σ量 加权 | 聚合加权均价;无成交显示 — |
| **成交额** | Σ成交 m_dTradeAmount | 聚合求和;无成交显示 — |
| **手续费** | Σ成交 m_dCommission | 聚合求和(3 位小数);无成交显示 — |
### 展开明细行(每笔成交)
| 列 | 来源 | 显示逻辑 |
|---|---|---|
| 成交时间 | m_strTradeTime | HH:MM:SS |
| 成交价 | m_dPrice | 2 位小数 |
| 成交量 | m_nVolume | 整数 + 股 |
| 成交额 | m_dTradeAmount | 2 位小数 |
| 手续费 | m_dCommission | 3 位小数 |
| 成交号 | m_strTradeID | 次要,悬停/弱显示 |
### 显示逻辑要点
1. **未成交委托**(待报/已报/已撤/废单):成交量/成交均价/成交额/手续费列显示 —,状态列已明确表达,无需其他冗余;
2. **多笔成交**:主行聚合(加权均价 + 求和),展开逐笔;聚合金额与逐笔合计一致;
3. **排序**:委托主行**默认按时间降序**(最新在前,老师拍板 2026-09-01);**支持手动调整**——点击表头列排序(时间/代码/方向/状态/委托量/成交量/金额等可排序列),再次点击切换升/降序,默认回到降序;
4. **方向着色**:红买绿卖(表头或图例标注「红=买 绿=卖」,避免与行情红涨绿跌混淆);
5. **空态**:无委托时显示「今日暂无委托记录」;
6. **数量格式**:整数(股),不强制千分位(A股习惯)。
## 技术实现方案(草案,2026-09-01)
### 程序结构(改造后)
```
src/
├── component/
│ └── QmtBridgeRestDataSource.js # 改:新增 getOrders()/getTrades()(语义化映射)
├── api/
│ └── trades.js # 新增:订单/成交域(orders / trades / trading-dates 端点)
│ └── index.js # 改:合并 TRADE_METHODS
├── client/
│ └── views/
│ ├── TradeRecordsTab.jsx # 新增:交易记录 tab(日期导航 + 单表合并视图)
│ ├── OrderRow.jsx # 新增:委托主行(聚合成交,可展开)
│ ├── TradeDetailRows.jsx # 新增:展开的成交明细行(每笔成交)
│ └── DateNav.jsx # 新增:日期导航组件(交易日历驱动)
│ └── index.js # 改:tradeRecords tab 渲染 TradeRecordsTab
```
### 服务端
1. **数据源**QmtBridgeRestDataSource 新增
- `getOrders({ code, status })` → 调 `/trade/orders`,语义化映射(orderId/status/direction/volumes/prices/amount/time/...,见 2.2 映射表);
- `getTrades()` → 调 `/trade/trades`,语义化映射(tradeId/orderId/code/price/volume/amount/commission/time);
- `getTradingDates({ start, end })` → 调 `/data/calendar/trading_dates`(支持 start/end,返回 dates[])。
2. **API 域**:新建 api/trades.js,端点:
- `orders`args: code/status)→ dataSource.getOrders
- `trades` → dataSource.getTrades
- `trading-dates`args: start/end)→ dataSource.getTradingDates
- 纳入 registerApi 的 METHODS + HANDLERS。
3. **日期解析**:服务端提供「当日交易日」解析(trading_dates 最后一个日期,或本地日期取整),前端导航初始化用。
### 客户端
1. **TradeRecordsTab**:顶部日期导航(DateNav)+ 单表合并视图(委托主行 + 可展开成交明细);
2. **DateNav**:加载交易日列表(近 N 日,如 -30~+7),前后箭头切换,当日高亮;选中日期状态提升;非当日显示「历史数据接口开发中」提示(老师完善 QMT Bridge 历史接口后启用);
3. **数据加载**useRpc 调 orders / trades;当日 3-5s 轮询;切换日期时取消轮询、加载所选日期数据(历史接口就绪后);
4. **合并逻辑(前端)**fetch 两接口 → 按 m_strOrderSysID 分组成交 → 委托主行聚合(加权均价/求和金额/求和手续费)→ 展开时逐笔渲染成交明细;
5. **委托主行列**:展开箭头/时间/代码/名称/方向/状态/委托量/成交量/委托价/成交均价/成交额/手续费;
6. **展开明细列**:成交时间/成交价/成交量/成交额/手续费/成交号;
7. **着色**:红买绿卖(Q7 已定);方向列红色=买、绿色=卖,表头图例标注。
### 构建与验证
- pnpm run build + 页面刷新(客户端 bundle)或宿主重启(服务端模块);
- 回归:现有持仓/策略/行情端点不受影响(技术约束-011 只读豁免,可直连生产 API 验证 orders/trades/trading-dates 返回)。
## 讨论记录
> 追加式记录:日期 · 轮次 · 结论。
- **2026-09-01 · 第一轮(需求登记 + 技术研究)**:
- 老师指令:添加一个新的需求,接入订单与成交数据,开始需求和技术研究。
- AI 完成:需求登记 R-007(本文件);QMT Bridge API 面探索(/trade/orders + /trade/trades 端点确认);线上实测真实数据样本(博纳影业 001330.SZ 委托+成交);现有架构代码审查(数据源/API 领域/tab 框架/缓存模式可复用);形成 Q1-Q10 待确认问题。
- 状态建议:**起草 → 讨论中**(已开始需求与技术研究),待老师确认后推进。
- **2026-09-01 · 第二轮(官方字典核实,方向字段澄清)**:
- 老师指正:QMT 桥转接的是**大 QMT 服务**,字段值应参考内置 APIinnerApi)字典:https://dict.thinktrader.net/innerApi/start_now.html?id=gdJsE0 (而非 nativeApi/xtquant)。
- AI 核实(dict.thinktrader.net/innerApi/enum_constants.html + data_structure.html):
① m_nDirection 对应 enum_EEntrustBS48=买卖/49=查询/50=撤单),官方注明「股票买卖永远是 48」——**操作标记,非方向**;
② 真实方向在 m_nOffsetFlagenum_EOffset_Flag_Type48=买入开仓/49=卖出平仓/50=强平/51=平今/52=平昨/53=强减/54=本地强平);
③ m_strOptName = 买卖标记,展示委托属性的中文(实测「限价卖出」)。
- 线上实测闭环验证:博纳影业订单 m_nDirection=48、**m_nOffsetFlag=49**、m_strOptName=限价卖出 → 49=卖出平仓 与「限价卖出」完全吻合。
- 结论:**方向判定规则确定 = m_nOffsetFlag 为主(48买/49卖)+ m_strOptName 交叉验证**;Q3 由「待确认」变为「有结论,待老师确认后固化」。
- 文档同步修正:字段表 m_nDirection 释义、实测样本说明、技术研究结论第 2 条、Q3 描述。
- **2026-09-01 · 第三轮(字段全表沉淀)**:
- 老师指示「看看 QMT 桥返回了哪些字段,列一个表」「要的要的」(确认沉淀)。
- AI 实调 /trade/orders 与 /trade/trades 提取完整原始字段,整理为两张字段全表(见 2.1 小节),标注 ★ 语义化映射核心字段(约 15 个/表)。
- 关键点:① m_nOffsetFlag+m_strOptName 双字段定方向(Q3 闭环);② m_strOrderSysID 关联委托↔成交;③ 手续费字段有拼写变体 m_dComssion(取值优先 m_dCommission);④ 大量期权/期货/人民币换算字段在股票场景为空/默认值,映射时裁剪。
- **2026-09-01 · 第四轮(Sample Data 沉淀)**
- 老师指示「今天有成交数据,帮我在文档中完善 sample data」。
- AI 实调最新 /trade/orders + /trade/trades(当日 1 笔委托 + 1 笔成交:博纳影业 001330.SZ 限价卖出 200 股 @6.00,已成,手续费 0.852 元),完整原始 JSON 沉淀为 2.2 小节 Sample Data。
- 同时给出语义化映射结果表(orderId/tradeId/code/name/exchange/direction/status/volumes/prices/amount/commission/time/accountId 共 16 字段),作为数据模型直接参考。
- 注:实调确认今日数据仅此一笔(订单 645009273 = 成交 0103000030812084 同号关联),sample 覆盖委托↔成交完整链路。
- **2026-09-01 · 第五轮(数据时效研究)**:
- 老师提问:这两个接口可以返回多少天以内的成交记录?
- AI 核实(QMT 桥 OpenAPI + 大 QMT 官方文档 code_examples/question_answer):/trade/orders 与 /trade/trades **只能返回当日数据**——规范明确「当日」且无日期参数;底层 get_trade_detail_data 从客户端本地缓存读取(当前状态快照),交易域无历史查询接口(历史能力仅限行情域)。
- 沉淀 2.3 数据时效研究小节;Q5 持久化由「可选」升级为「跨日复盘的必要前提」,待老师拍板。
- **2026-09-01 · 第六轮(范围定稿 + 日期导航)**:
- 老师拍板:① 先把**当日订单与成交记录接进来**,数据放到**交易记录 tab** 下;② 老师将完善 QMT Bridge **历史成交接口**;③ 请添加一个**日期导航**,**根据交易日历**做一个日期导航。
- AI 更新:功能范围定稿(当日委托+成交 + 日期导航占位);Q1-Q10 全部有结论(Q5 本期不做持久化);新增 Q11 日期导航结论;技术实现方案草案(数据源 3 方法 / api/trades.js / TradeRecordsTab + DateNav);实测 trading_dates 接口可用。
- 状态:R-007 从「讨论中」推进,功能范围已定稿,待老师确认定稿后进入计划/迭代。
- **2026-09-01 · 第七轮(单表合并展示设计)**:
- 老师指示讨论委托/成交的显示字段与显示逻辑;AI 提出两表方案;老师拍板:**不要两个表,要一个表**——当日委托信息为主行,根据 m_strOrderSysID 合并成交信息。
- 三个决策点老师逐条确认:① **委托行展开/折叠**——主行显示订单状态 + 聚合成交信息,展开后逐笔成交明细;② 委托未成交(已撤/废单/待报)——状态列已明确,成交列显示 —;③ 聚合展示在委托行,展开后分别展示。
- AI 沉淀「展示设计:单表合并」章节:委托主行列(时间/代码/名称/方向/状态/委托量/成交量/委托价/成交均价/成交额/手续费)+ 展开明细列(成交时间/价格/量/额/手续费/成交号)+ 合并规则(按 m_strOrderSysID 分组、加权均价、求和、未成交显示 —)。
- 技术方案同步:组件改为 TradeRecordsTab + OrderRow(委托主行)+ TradeDetailRows(展开明细)+ DateNav;前端合并逻辑明确(fetch 两接口 → 分组 → 聚合)。
- **2026-09-01 · 第九轮(日期导航改版 v2)**:
- 老师反馈:顶部日期按钮没有美感——不要做成一个个按钮、不要加边框;以当前**最后一个交易日**为基准,先是**前面 7 个日期**;做成**一行**,把前一日/后一日的导航箭头也放进同一行;每个日期用**小竖线**分隔。
- AI 重写 DateNav v2:一行式布局(◀ 日期|日期|...|日期 ▶),日期为纯文本无边框,竖线 | 分隔,选中绿色加粗;基准 = 交易日历最后一个交易日(最近交易日),显示最近 + 前 7 个共 8 个;箭头 ◀ ▶ 同在一行(上一个/下一个交易日);TradeRecordsTab 的「今日」基准同步改为最近交易日(onLastDate 通知)。
- **2026-09-01 · 第十轮(时间段查询重构 v3)**:
- 老师反馈:看了历史交易接口,是按**传入时间范围**确定查询哪些日期的记录——现有单日导航逻辑不适合;倾向**按日期查询但能指定起止时间**;同时布局浪费空间(标题一行、日期导航一行)——① 日期导航改为**起止时间段**,不再用前一日/后一日;② 时间段控件与**标题同一行**;③ 新增三个功能键:**今日 / 本周 / 上周**快速查询近期数据,其余用户手动指定日期。
- AI 重构:删除 DateNav,新增 RangeSelector(今日/本周/上周快捷 + 起止日期 input);TradeRecordsTab 标题 + 时间段同一行;今日范围 4s 轮询、其他范围一次性查询;服务端 orders/trades 预留 start/end 透传(匹配历史接口形态);历史范围占位「历史数据接口开发中」。
- 决策:今日=最近交易日单日;本周=所在自然周周一~周日(完整周);本月=所在自然月1号~月末(完整月);均基于交易日历最近交易日计算。
- 2026-09-01 修正一:快捷按钮由「今日/本周/上周」改为「**今日/本周/本月**」(老师反馈,去掉上周、新增本月)。
- 2026-09-01 修正二(老师纠正):快捷范围为**完整时间段**(本月=9/1~9/30、本周=周一~周日),不做「截至今天」截断——否则月初第一天点「本月」会与「今日」重合、无法操作;这是操作逻辑问题,不是数据问题。
- 2026-09-01 · 第十一轮(费用计算规则,老师定):m_dCommission 的值是**佣金费率(万分之)**——如 0.852 = 万分之0.852 = 0.0000852(不是金额 0.852 元)。费用规则:佣金 = 成交额 × 万0.852,不足 5 元按 5 元(账号没免五);卖出加印花税(万分之5,2023-08-28 起)和过户费(万分之0.1,双向,无最低,2022-04-29 起,老师确认费率);过户费收费方中登、ETF/LOF/可转债/REITs 免收。已实现 calcTradeFees 逐笔计算 + 前端聚合展示(总费用/佣金/印花税/过户费四列)。
- 2026-09-01 修正四(本周范围,老师纠正):本周 = **周一~周五**(不考虑周六日,不是往前推 7 天/自然周周日);实现 weekSunday→weekFriday(周一+4)。
- 2026-09-01 修正三(交互模型,老师纠正):**交互是单向的**——用户先有操作(点「本月」),才有时间范围;不能反过来从「搜索范围落在哪」反向推断用户交互的是哪个按钮。实现改为 **preset 意图状态**:点按钮 → 记录 preset → 按钮高亮(单向);手动改日期 → 清除 preset(不再是任何快捷操作);轮询由 preset==='today' 决定,而非范围反推。
- **2026-09-01 · 第八轮(排序逻辑定稿)**:
- 老师拍板:委托主行排序**默认降序**(最新委托在前),**支持手动调整**(点击表头排序,可切换升/降序)。
- AI 更新:显示逻辑要点第 3 条改为「默认降序 + 表头点击排序」;可排序列包含时间/代码/方向/状态/委托量/成交量/金额等。
## 关联文档(随讨论补充)
- 计划:待 R-007 定稿后派生(符合入范围门槛)
- 迭代记录:待实现后建立
- 设计约束:待定稿后沉淀(方向判定规则、交易数据模型等)
+127
View File
@@ -0,0 +1,127 @@
# R-004 QMT 连接配置(多配置管理 + 会话头部快捷切换)· 已完成
> 归档日期:2026-08-29 需求状态:**已完成**
> 原索引:docs/05-需求池/需求池索引.md(主索引保留 R-004 条目,指向本归档)
> 定稿记录:2026-08-29 老师确认定稿(三要素满足:边界清楚 + 核心逻辑明确 + 老师确认)
> 来源:老师指令(2026-08-28
> 关联:docs/05-需求池/需求池索引.mdR-004
> 说明:待确认问题清单与讨论记录原独立记录于 R-004-待确认问题.md,2026-08-29 经老师要求整合入本文档(保留一份),原独立文件已删除。
## 需求概述
在神之一手的**设置页面**新增一个子 tab「QMT 连接配置」,用于管理多个 QMT Bridge 连接配置:
- **多配置管理**:可维护多个连接配置(增 / 删 / 改 / 查);
- **一次只能激活一个**:从多个配置中单选激活一个,被激活的配置为当前生效连接;
- **可设置默认**:标记某配置为默认(默认 = 启动时自动激活的配置,见 Q1);
- **快捷切换**:在会话窗口顶栏(PTC 模式标签旁)提供常驻下拉控件,一键切换当前激活的连接,无需进入设置页(见 Q9/Q10)。
## 现状分析:插件当前使用的 QMT 连接信息
> 通过代码审查得出(src/data-source/qmt-bridge-rest.js、src/index.js、cordis.patch.yml):
| 配置项 | 当前值 | 是否必配 | 说明 |
|---|---|---|---|
| **HTTP 基础地址(baseUrl** | `http://192.168.3.43:8610` | **是(唯一必配)** | 由宿主 cordis.patch.yml 注入 `config.qmtBaseUrl`;数据源所有 REST 请求基于此地址 |
| **请求超时(timeoutMs** | 15000ms | 否(有默认值) | 代码常量 REQUEST_TIMEOUT_MS=15000,当前未暴露到配置,使用默认值 |
**分析结论**
1. **核心只需配置一个 HTTP 地址**baseUrl)—— 插件与 QMT Bridge 的所有通信都基于它(/health、/trade/*、/data/* 等 REST 端点);
2. **可选配置一个请求超时**(timeoutMs)—— 仅在需要调整超时时才需配置,可提供默认值;
3. **当前不需要其他连接参数**:无认证(QMT Bridge REST 端点无鉴权)、无账户/密码、无额外 header —— 未来若 QMT Bridge 增加鉴权,再扩展配置字段。
**2026-08-29 讨论前代码审查补充**(支撑决策):
- 数据源的 baseUrl/timeoutMs 为**按请求读取**qmt-bridge-rest.js),激活切换只需更新数据源实例字段,无需重建实例,「立即切换」实现成本低;
- QMT Bridge 已有 `/health` 端点(插件启动检查在用),「测试连接」可直接复用;
- 策略配置已有 settings namespace + CRUD + 设置页子 tab 完整先例,连接配置存储可复用该模式。
## 功能范围(定稿)
**做**
1. 设置页新增「QMT 连接配置」子 tab(与现有「通用设置 / 策略分组」并列);
2. **配置 CRUD**:新增 / 编辑 / 删除 / 重命名;配置字段为名称(识别用)+ HTTP 地址(必填);超时不纳入表单(Q5);
3. **激活**:单选激活,**一次只能激活一个**;激活后**立即切换**生效,无需重启 DSH(Q2);
4. **默认**:标记某配置为默认;启动时自动激活默认配置,运行中手动激活其他配置立即生效,重启后回到默认(Q1);
5. **测试连接**:手动触发,请求 `/health` 返回可达性与延迟;激活不强制先测试(Q3);
6. **删除边界**:允许删除激活配置(自动切换到默认);删除默认配置时默认标记转移到列表第一条并激活之;**禁止删除最后一条**(Q6);
7. **会话头部快捷切换**:在会话窗口顶栏注册下拉控件(slot `conversation.session.header.actions`,与 DSH 内置 PTC 模式标签并排):chip 形态显示 `QMT: <激活配置名>`,点开列出全部配置(激活项勾选标记),点选即激活并 toast 反馈;头部控件**仅做切换**,配置的增删改/测试连接/默认标记仍在设置页子 tab(Q9/Q10)。
**存储**:复用现有 one-divine-lot settings namespace(与策略配置同机制),不新增独立存储文件(Q8)。
**不做**
- 认证/多账户支持(QMT Bridge 当前无鉴权,未来扩展);
- 连接状态监控(如断线重连策略)—— 后续;
- 超时(timeoutMs)配置化 —— 保持代码默认 15000ms(Q5);
- 宿主配置(cordis.patch.yml qmtBaseUrl)自动迁移 —— 首次使用手动录入(Q4);
- 激活前强制连通性校验 —— 测试连接为手动操作(Q3)。
## 待确认问题(Q1-Q10,已确认)
> 2026-08-29 由老师逐条拍板(AI 提议 + 老师确认)。Q8(存储位置)与 Q9/Q10(快捷切换)为当轮讨论新增。
| # | 问题 | 状态 | 确认日期 | 结论摘要 |
|---|---|---|---|---|
| Q1 | **「默认」的语义**:默认 = 插件启动时自动激活的配置?还是仅作为列表中的默认选中项?手动激活非默认配置后,下次启动是否回到默认? | 已确认 | 2026-08-29 | 默认 = 插件启动时自动激活的配置;运行中手动激活其他配置立即生效,重启后回到默认 |
| Q2 | **生效机制**:激活配置后**立即切换**(动态重建数据源,无需重启 DSH)?还是保存后**重启生效**?(当前数据源在插件 apply 时创建一次,改为动态切换需调整架构) | 已确认 | 2026-08-29 | 激活后**立即切换**:更新数据源实例的 baseUrl 即可,无需重启 DSH(代码审查已核实:数据源按请求读取地址,改动成本低) |
| Q3 | **是否提供「测试连接」按钮**:验证地址可达(请求 /health 检查 status=ok),帮助确认配置正确? | 已确认 | 2026-08-29 | 提供,**手动测**:请求 /health 返回可达性与延迟;激活本身不强制先测试(复用现有 /health 端点) |
| Q4 | **现有宿主配置迁移**cordis.patch.yml 中的 `qmtBaseUrl`192.168.3.43:8610)如何处理 —— 首次启动时作为**初始默认配置**自动迁入设置页? | 已确认 | 2026-08-29 | **不迁移**:首次使用手动录入配置 |
| Q5 | **超时是否纳入配置项**:timeoutMs 是否需要出现在配置表单(可选字段),还是保持代码默认值? | 已确认 | 2026-08-29 | **不纳入**表单:timeoutMs 保持代码默认 15000ms |
| Q6 | **删除/切换边界**:删除当前激活配置时如何处理(禁止删除?自动切换到默认?);删除默认配置时默认标记如何转移? | 已确认 | 2026-08-29 | 允许删除激活配置,删除后自动切换到默认配置;删除的若是默认配置,默认标记转移到列表第一条并激活之;**禁止删除最后一条**配置 |
| Q7 | **优先级**:老师定级(P0-P2?)—— 建议 P1(提升多环境可用性,单地址当前可用) | 已确认 | 2026-08-29 | **P1** |
| Q8 | **配置存储位置**2026-08-29 讨论新增):连接配置存储于何处? | 已确认 | 2026-08-29 | 复用现有 one-divine-lot settings namespace(与策略配置同机制),不新增独立存储文件 |
| Q9 | **快捷切换入口位置**2026-08-29 讨论新增):会话窗口顶栏(PTC 模式标签旁)?新建会话页?两处都放? | 已确认 | 2026-08-29 | **会话头部,PTC 模式标签旁**slot `conversation.session.header.actions`,多实例挂载点已核实可并排注册,无需改动宿主) |
| Q10 | **头部菜单能力**2026-08-29 讨论新增):仅切换激活?含每项测试连接?含管理入口? | 已确认 | 2026-08-29 | **仅切换激活**:列出配置、点选激活 + toast 反馈;测试连接与配置管理留在设置页 |
## 讨论记录
> 追加式记录:日期 · 轮次 · 结论。
- **2026-08-29 · 第一轮(代码审查 + 逐条拍板)**:
- 讨论前代码审查补充三项事实(见「现状分析」补充节):① 数据源 baseUrl/timeoutMs 按请求读取,「立即切换」成本低;② /health 端点可复用做测试连接;③ 策略配置的 settings namespace + CRUD + 设置页子 tab 模式可复用。
- 讨论中新增 Q8(配置存储位置),连同原 Q1-Q7 共 8 项由老师逐条拍板,结论见上表。
- 定稿确认环节:老师反馈「还有要调整的」,追问具体调整点未获选择。故 Q1-Q8 结论按已确认记录,**R-004 暂不定稿**,等待老师补充调整点后继续讨论。
- 文档整合:待确认问题清单与讨论记录并入本文档(老师要求保留一份),原独立文件 R-004-待确认问题.md 删除;「功能范围」一节同步按已确认决策对齐(超时移入不做、补充测试连接与删除边界、标注 Q 编号)。
- **2026-08-29 · 第二轮(新增会话头部快捷切换功能)**:
- 老师提出新功能:会话窗口顶栏(PTC 模式标签旁)增加 QMT 连接快捷切换,避免每次进设置页修改。
- AI 前置技术调研结论:PTC 标签为 DSH 内置客户端插件 ui-agent-preset 向 slot `conversation.session.header.actions` 注册的会话头部标签;该 slot 为多实例挂载点(按 order 排序、多插件共存),本插件可并排注册控件,无需改动宿主;DSH 预设标签做成只读是因宿主禁止会话中途更换预设,而 QMT 激活是插件自管逻辑(Q2 已定立即切换),头部放真切换控件成立。
- 老师拍板:功能**并入 R-004**(不拆独立需求);入口定**会话头部 PTC 标签旁**(Q9);头部菜单**仅切换激活**(Q10)。管理能力(增删改/测试连接/默认标记)仍在设置页子 tab。
- **2026-08-29 · 第三轮(定稿)**
- 老师确认需求定稿。三要素核验:① 边界清楚(做/不做清单完整,含快捷切换);② 核心逻辑明确(Q1-Q10 全部有结论,含存储、生效机制、删除边界、入口与菜单能力);③ 老师明确确认。
- 决策沉淀:产品约束-005/006、技术约束-008/009(含技术约束-003 关联变更标注)、UI约束-001/002。
- 派生计划:PLAN-003(计划-QMT连接配置.md),进入执行范围。
## 实现记录
| 项 | 内容 |
|---|---|
| 实现迭代 | 03-QMT连接配置 |
| 实现方式 | 沿用独立插件 one-divine-lot(服务端 + 客户端改造) |
| 服务端 | settings.jsqmtConnections schema + CRUD/激活/默认/启动解析 9 函数)、qmt-bridge-rest.jssetBaseUrl 热切换)、index.js(启动激活地址解析 + dataSource 注入)、api.js7 个 qmt-connections/* 端点 + /health 代理测试 + 激活/编辑/删除热切换编排) |
| 客户端 | QmtConnectionChip.jsx(会话头部快捷切换 chipslot conversation.session.header.actions order=-9)、SettingsSection.jsx(「QMT 连接配置」第三个子 tab,卡片形式)、client/index.js(头部 slot 注册) |
| 构建安装 | pnpm run build(服务端 ESM + 客户端 CJS bundle + wrap);profile 为 link 引用,构建即生效(服务端需宿主重启加载) |
**实现期间调整(2026-08-29,老师反馈)**:① chip 空配置态由「隐藏」改为「显示 + 引导提示」(消除空态不可见问题);② 设置页配置由列表形式改为**卡片形式**(自适应网格 + 长文本单行省略悬停看全文,UI约束-002 变更)。
## 验收结果(2026-08-29 线上实测,详见 docs/04-迭代记录/03-QMT连接配置/验收标准.md
- ✅ 标准 1:设置页子 tab + 配置 CRUD(实录 GEMWIN / QMT_CYY 两条真实配置)
- ✅ 标准 2:激活立即切换(切不可达配置 → 持仓立即失败;切回 → 立即恢复;全程无重启)
- ✅ 标准 3:默认/启动行为(单测覆盖启动激活默认并回写、cordis 兜底;线上激活=默认一致)
- ✅ 标准 4:测试连接(GEMWIN 可达 726msQMT_CYY 不可达 10.1s;激活无预检,符合 Q3)
- ✅ 标准 5:删除边界(线上实测删激活配置自动切回默认;删默认转移/禁删最后一条由单测覆盖)
- ✅ 标准 7:现有功能不回归(持仓/策略端点正常返回真实数据)
- ✅ 标准 6:会话头部 chip —— 老师确认完成并标记 R-004 已完成(2026-08-29
## 经验沉淀
- **服务端改动需重启宿主**:客户端 bundle 页面刷新即加载,服务端模块(api.js/settings.js 等)宿主启动时装入内存——"设置页报 unknown method 但页面能看到新 UI" 即两侧版本差的典型症状
- **空态可见性**:入口控件「无数据即隐藏」在「数据需要经该入口创建」时形成死锁,空态应显示并给引导
- **数据源热切换可行性**:baseUrl 为按请求读取的实例字段,运行期改字段即生效——无需重建实例/重启宿主(技术约束-008 的事实依据)
- **profile link 安装形态**:插件以 symlink 指向工作区时,构建产物即宿主加载物,dsh plugin add 无需重复执行
- **拼音 slug 兜底**:映射表外中文名会兜底为通用 id(如 qmt-conn),后续可扩词表或时间戳后缀增强区分度
## 关联文档
- 迭代记录:docs/04-迭代记录/03-QMT连接配置/(迭代目标 / 技术实现方案 / 验收标准)
- 计划:docs/02-计划/计划-QMT连接配置.mdPLAN-003
- 设计约束:产品约束-005/006、技术约束-003(变更标注)/008/009、UI约束-001/002
+49
View File
@@ -0,0 +1,49 @@
# R-005 WS 盘中价格实时更新 · 已完成
> 归档日期:2026-09-01 需求状态:**已完成**
> 原索引:docs/05-需求池/需求池索引.md(主索引保留 R-005 条目,指向本归档)
> 实现迭代:04-WS盘中价格实时更新(验收通过,迭代复盘见 docs/04-迭代记录/04-WS盘中价格实时更新/迭代复盘.md)
> 讨论记录:需求从 T-005 草稿转正,2026-08-31 定稿;实现过程中的架构演进(前端直连→服务端中转+行情缓存)见迭代 04 迭代说明/复盘
---
> 状态:**已定稿**(2026-08-31,老师确认)| 登记日期:2026-08-31
> 来源:T-005 草稿转正(docs/05-需求池/草稿/通过ws长连接做市场数据的实时反映.md)
> 关联:T-005ws 实时数据草稿)、R-002/R-003/R-004(已实现)
## 需求描述
在现有分仓管理工具(one-divine-lot 插件)中,实现**盘中价格实时更新**:
- 前端直连 QMT Bridge 原生 WebSocket`ws://<激活配置host>:8610/ws`),订阅 `whole`(全市场 tick 增量推送);
- 事件驱动:收到推送后,自动更新 3 个监控表格(全部持仓 / 手动做T / 网格超市)中**关注股票列表**的**盘中价格**(现价,字段 `lastPrice`);
- 本期只更新**现价**一项数据,不做市值/盈亏/五档等扩展。
## 核心逻辑(定稿版)
1. **连接拓扑**:前端直连 QMT Bridge WS(老师确认,非插件服务端中转);
2. **订阅范围**:订阅全市场行情流(`type: whole``codes: ['SH','SZ']`),前端按关注列表过滤(老师确认);
3. **关注列表来源**:3 个表格自动汇总(全部持仓 + 手动做T + 网格超市出现过的 code 合集),无需手动维护(老师确认);
4. **现价展示**3 个表格新增「现价」列(显示 `lastPrice`),红涨绿跌着色,价格变化时轻微高亮提示(老师确认);
5. **刷新机制**:现价叠加层 —— WS 维护 code→lastPrice 实时价格 Map,表格行渲染时叠加;份额/持仓仍由 REST 拉取,不整表重拉(老师确认);
6. **协议事实**2026-08-31 实测 GEMWIN 100.110.38.78:8610):
- WS 端点:`ws://<host>:8610/ws`(与 REST 同端口,OpenAPI servers 注明);
- 订阅:`POST /data/subscribe`body `{ type: 'whole', codes: ['SH','SZ'] }` → 返回 `{ ok, sub_id }`
- 退订:`POST /data/unsubscribe`body `{ sub_id }`
- 推送:`{ type: 'whole', data: { '<code>': TickSnapshot } }`TickSnapshot 含 `lastPrice / open / high / low / lastClose / volume / amount / askPrice / bidPrice / askVol / bidVol / stime / time` 等;
- 快照:`GET /data/tick?codes=<code1,code2>` 返回 `{ ok, data: { code: TickSnapshot } }`(WS 只推增量,无 prime;前端可先拉一次快照补齐初值)。
## 边界(不做)
- 不做市值/盈亏/五档等实时数据的展示(本期仅现价);
- 不做插件服务端中转 WS(老师确认前端直连);
- 不做断线重连 UI 引导(先做静默重连 + 状态提示);
- 不做关注列表手动配置(自动汇总)。
## 验收要点(详见迭代 04 验收标准)
1. 3 个表格出现「现价」列,显示关注股票的 lastPrice;
2. 价格变化自动更新(无需手动刷新);
3. 红涨绿跌着色 + 变化高亮;
4. 连接激活配置的 host 变化时,WS 随之切换(复用 QMT 多配置热切换)。
@@ -0,0 +1,25 @@
# 草稿:RSS 订阅管理
> 状态:起草(未成形想法,不进入计划/迭代范围)| 登记日期:2026-08-28
> 来源:老师指令(2026-08-28
## 想法描述
在神之一手中提供 **RSS 订阅管理**能力:管理 RSS 订阅源(增删改查),抓取并聚合订阅内容,作为资讯/消息的来源之一。
**与终极目标的关联**
- 支撑 目标-003(按策略监控市场):财经资讯/研报/公告类 RSS 可作为市场监控输入源;
- 支撑 目标-004(按策略模式管理消息):RSS 内容可作为消息管理对象(过滤、聚合、分发、通知);
- 与周边工具候选 T-004(消息/通知工具)同属消息链路,可能是其上游数据源。
## 待讨论点
- [ ] 订阅源范围:财经资讯?研报?公告?博客/专栏?具体订阅哪些源?
- [ ] 管理界面形态:设置页新增子 tab?还是独立会话 tab 展示订阅内容?
- [ ] 抓取机制:定时轮询间隔?抓取后如何存储(本地 JSON / 结构化文档)?
- [ ] 与策略的关联:订阅源是否按策略分组(不同策略关注不同源)?
- [ ] 与 T-004 消息/通知工具的关系:RSS 是否作为其数据来源,还是独立工具?
- [ ] 内容展示形态:列表?摘要+跳转原文?全文阅读?
- [ ] 优先级与排期(机制定稿后确定)
> 成熟后按「三要素」(边界清楚 / 核心逻辑明确 / 老师确认)讨论定稿,再转正到根目录形成正式需求。
+7 -3
View File
@@ -15,7 +15,10 @@
|---|---|---|---|---|---|---|---|---|
| R-002 | 分仓管理工具(持仓策略标签管理) | 验证 QMT Bridge MCP 连通(资金/持仓)。**核心逻辑(已定稿)**:① 插件设置中管理持仓策略(策略=标签,增删改 + 显示/隐藏开关);② 按设置在主窗口上方 tab 栏(对话/轨迹/上下文后)显示策略标签,每个标签下加载对应持仓数据;③ 插件处理与存储:QMT 读全量真实持仓(**插件直连 QMT Bridge RESTful 接口**,非 MCP),策略分仓数据本地保存管理。**实现方式**:独立插件,作为外部插件挂载到 DSH。第一个落地工具,源自 T-001。**2026-08-27 定稿,2026-08-28 完成,已归档至 已完成/R-002.md** | 老师指令(2026-08-27 | P0 | 已定稿 | 2026-08-28 | 01-分仓管理工具 | **已实现(已归档)** |
| R-003 | 分仓管理工具完善与优化 | 对 R-002 的完善与优化:O2 策略 tab 动态化、O3 策略 CRUD(删除弹窗确认)、O5 加载失败兜底、O6 份额快捷操作 + 设置页 tab 化(通用设置/策略分组)。**2026-08-28 定稿,2026-08-28 完成,已归档至 已完成/R-003.md** | 迭代 01 复盘 + 老师补充 | P0 | 已定稿 | 2026-08-28 | 02-分仓管理工具完善与优化 | **已实现(已归档)** |
| R-004 | QMT 连接配置(多配置管理) | 在神之一手设置页新增「QMT 连接配置」子 tab:管理多个 QMT Bridge 连接配置(CRUD),一次只能激活一个,可设置默认。**现状分析**:插件当前唯一必配项为 HTTP 基础地址(baseUrl,当前 192.168.3.43:8610),可选请求超时(timeoutMs,默认 15000ms),无认证参数。**初步草稿见 R-004.md,待讨论定稿** | 老师指令(2026-08-28 | 待定 | 讨论中 | 2026-08-28 | - | - |
| R-006 | 策略数据 JSON data store schema 标准化 | 策略数据集标准化为 JSON data storestore.schema.json / store.json 策略为中心 / store.market.json 行情持久化);旧 allocations.json 自动迁移。**2026-08-31 定稿,2026-09-01 完成(迭代 04 验收通过)** | 老师指令(2026-08-31 | P2 | 已定稿 | 2026-09-01 | 04-WS盘中价格实时更新 | **已实现(迭代 04 完结)** |
| R-005 | WS 盘中价格实时更新 | 3 个监控表格(全部持仓/手动做T/网格超市)盘中现价实时显示:服务端中转 + 行情缓存(store.market.json 持久化)+ 前端轮询读缓存;现价列 + 红涨绿跌 + 变化高亮。**2026-08-31 定稿,2026-09-01 完成(迭代 04 验收通过),已归档至 已完成/R-005.md** | 老师指令(2026-08-31T-005 转正) | P1 | 已定稿 | 2026-09-01 | 04-WS盘中价格实时更新 | **已实现(已归档)** |
| R-004 | QMT 连接配置(多配置管理 + 会话头部快捷切换) | 设置页「QMT 连接配置」子 tab:多配置 CRUD(卡片形式)、单选激活(数据源热切换立即生效)、默认标记(启动自动激活)、测试连接(/health 代理)、删除边界处理;会话头部(PTC 模式标签旁)快捷切换 chip。**2026-08-29 定稿(Q1-Q10)并完成实现与验收(7/7 通过),已归档至 已完成/R-004.md**。决策沉淀:产品约束-005/006、技术约束-003(变更)/008/009、UI约束-001/002 | 老师指令(2026-08-28 | P1 | 已定稿 | 2026-08-29 | 03-QMT连接配置 | **已实现(已归档)** |
| R-007 | 交易记录接入(订单与成交数据 + 日期导航) | 交易记录 tab 接入 QMT Bridge 当日委托(/trade/orders)与当日成交(/trade/trades)**单表合并**(委托主行 + 展开成交明细)+ **日期导航**(交易日历驱动,为历史成交接口预留);排序默认降序可手动。**2026-09-01 定稿(范围+展示设计 Q1-Q11 有结论)**,需求文件:`R-007.md` | 老师指令(2026-09-01 | P1 | 已定稿 | 2026-09-01 | 05-交易记录接入 | 实现中 |
## 渐进明细规划素材
@@ -27,5 +30,6 @@
| T-002 | 交易与复盘记录工具 | 将交易、复盘沉淀为 DSH 可管理的结构化文档,支撑市场复盘/交易复盘目标 | 起草 |
| T-003 | 策略配置文件骨架 | 定义策略的数据结构(YAML/JSON),支撑策略定义目标 | 起草 |
| T-004 | 消息/通知工具 | DSH 内消息路由与通知能力,支撑按策略模式管理消息目标 | 起草 |
| T-005 | 通过 ws 长连接做市场数据的实时反映 | WebSocket 长连接实现市场数据(持仓/行情)实时推送与展示;源自迭代 01 复盘。**2026-08-28 老师确认放草稿,不入正式需求池**,草稿文件:`草稿/通过ws长连接做市场数据的实时反映.md` | 起草 |
| T-006 | 数据池中间层 + 策略表格动态字段配置 | 服务端数据池(数据集中间层:按 code 聚合宽表、多源字段映射、填充器架构)+ 策略持仓表格动态字段配置(列配置×池行渲染)。源自 R003 讨论(2026-08-28)拆分独立,草稿文件:`草稿/数据池中间层与策略表格动态字段配置.md` | 起草 |
| T-005 | 通过 ws 长连接做市场数据的实时反映 | WebSocket 长连接实现市场数据(持仓/行情)实时推送与展示;源自迭代 01 复盘。**2026-08-31 转正为 R-005(迭代 04 实施中)**,草稿文件:`草稿/通过ws长连接做市场数据的实时反映.md` | 已转需求 R-005 |
| T-006 | 数据池中间层 + 策略表格动态字段配置 | 服务端数据池(数据集中间层:按 code 聚合宽表、多源字段映射、填充器架构)+ 策略持仓表格动态字段配置(列配置×池行渲染)。源自 R003 讨论(2026-08-28)拆分独立,草稿文件:`草稿/数据池中间层与策略表格动态字段配置.md` | 起草 |
| T-007 | RSS 订阅管理 | 管理 RSS 订阅源(增删改查)+ 抓取聚合订阅内容,作为资讯/消息来源;支撑 目标-003 市场监控、目标-004 消息管理,与 T-004 同属消息链路。**2026-08-28 老师确认先放草稿**,草稿文件:`草稿/RSS订阅管理.md` | 起草 |