From aef27dcd3fd2a52d2ff255e9f2e7a3262190f447 Mon Sep 17 00:00:00 2001 From: AdamGao Date: Tue, 1 Sep 2026 14:47:26 +0800 Subject: [PATCH] =?UTF-8?q?docs:=20R-007=20=E9=9C=80=E6=B1=82=E5=BD=92?= =?UTF-8?q?=E6=A1=A3=EF=BC=8C=E8=BF=AD=E4=BB=A3=2005=20=E5=AE=8C=E7=BB=93?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - R-007 移入已完成/(完整需求摘要+决策+实现记录) - 需求池索引更新(已实现/已归档) - 迭代 05 复盘更新(验收通过,老师确认完结) --- docs/04-迭代记录/05-交易记录接入/迭代复盘.md | 7 +- docs/05-需求池/R-007.md | 544 ------------------- docs/05-需求池/已完成/R-007.md | 99 ++++ docs/05-需求池/需求池索引.md | 2 +- 4 files changed, 104 insertions(+), 548 deletions(-) delete mode 100644 docs/05-需求池/R-007.md create mode 100644 docs/05-需求池/已完成/R-007.md diff --git a/docs/04-迭代记录/05-交易记录接入/迭代复盘.md b/docs/04-迭代记录/05-交易记录接入/迭代复盘.md index 2ec535a..c371016 100644 --- a/docs/04-迭代记录/05-交易记录接入/迭代复盘.md +++ b/docs/04-迭代记录/05-交易记录接入/迭代复盘.md @@ -1,6 +1,6 @@ # 迭代 05 复盘:交易记录接入(订单与成交 + 日期导航)(2026-09-01) -> 复盘日期:2026-09-01 | 迭代状态:**实现完成,待老师验收确认** +> 复盘日期:2026-09-01 | 迭代状态:**已完成(老师确认归档,需求 R-007 已移入已完成/)** > 关联需求:R-007(交易记录接入,范围已定稿) > 关联计划:PLAN-006(计划-交易记录接入.md) @@ -34,5 +34,6 @@ ## 验收状态 - 服务端/数据源端到端验证:✅(真实数据实测通过) -- 前端 UI:待老师页面验收(客户端 bundle 已构建,刷新页面即载) -- 完整验收:对照 验收标准.md 逐条核验(待老师确认) \ No newline at end of file +- 前端 UI:✅(老师验收通过:单表合并/时间段查询/排序/费用计算/展开明细) +- 完整验收:✅(2026-09-01 老师确认迭代完结,需求 R-007 归档) +- 本次迭代 3 次 git 提交:bb3f8bd(迭代03-05)/ 8caeb76(佣金合并计费)/ 08c4ad3(箭头样式) \ No newline at end of file diff --git a/docs/05-需求池/R-007.md b/docs/05-需求池/R-007.md deleted file mode 100644 index 956966b..0000000 --- a/docs/05-需求池/R-007.md +++ /dev/null @@ -1,544 +0,0 @@ -# R-007 交易记录接入(订单与成交数据)· 需求与技术研究 - -> 需求状态:**起草**(2026-09-01 入池,需求与技术研究进行中;AI 提议提为「讨论中」,待老师确认) -> 更新日期:2026-09-01 | 来源:老师指令(2026-09-01) -> 关联:docs/05-需求池/需求池索引.md(R-007)、docs/01-终极目标/终极目标.md(目标-006 交易复盘、目标-003 按策略监控市场) -> 前置研究:本文件已含第一轮技术研究(QMT Bridge 订单/成交 API 实测 + 现有架构集成分析),待确认问题 Q1-Q10 待老师逐条拍板 - -## 需求概述 - -在神之一手的**「交易记录」tab**(当前为占位)中接入 **QMT Bridge 的订单(当日委托)与成交(当日成交)数据**,实时展示当日委托与成交明细,支撑**交易复盘**(目标-006)与**按策略监控交易**(目标-003)。 - -- **订单数据**:当日委托列表(含委托状态、委托量、成交量、限价、时间等); -- **成交数据**:当日成交列表(含成交价、成交量、手续费、成交额、时间等); -- **展示位置**:现有「交易记录」tab(conversation.view,id=odl-trade-records,tradeRecords 显隐开关已预置,当前渲染 PlaceholderTab 占位); -- **数据来源**:插件服务端直连 QMT Bridge REST(技术约束-003,不经过 MCP 层),复用现有统一数据源抽象(技术约束-001)。 - -## 现状分析 - -### 1. QMT Bridge 已具备订单/成交查询能力(API 面实测) - -| 端点 | 方法 | 说明 | 过滤参数 | -|---|---|---|---| -| /trade/orders | GET | 当日委托列表(m_* 原始字段),账号为桥绑定账号(单账号策略) | code(客户端过滤,600519 或 600519.SH)、status(active=排除已撤54/废单57,或数字状态码 48-57)、strategy_name(QMT 服务端按 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_nOffsetFlag(EOffset_Flag_Type:48=买入开仓/49=卖出平仓,实测 49 与「限价卖出」吻合);m_strOptName 为买卖标记中文展示。**方向判定应以 m_nOffsetFlag 为准 + m_strOptName 交叉验证(Q3 已解决)**。 - -### 2.1 QMT 桥返回字段全表(实测 2026-09-01) - -> 实调 QMT 桥 /trade/orders 与 /trade/trades 得到的完整字段。标注 ★ 的字段为**语义化映射应保留的核心字段**(股票场景),其余为期权/期货/人民币换算/融资融券等场景字段(股票时为空或默认值)。 -> 字段体系:大 QMT 内置 API(innerApi),枚举见 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_Type:48=买入开仓 / 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 | 策略 ID(passorder 所属) | | -| 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_Type:48=买入开仓 / 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 | 策略 ID(passorder 所属) | | -| 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 起标准,中登收取,老师确认) | -| 总费用 | 佣金 + 印花税 + 过户费 | **委托级合并计费**:同一委托分笔成交按总金额算一次佣金;多笔独立委托各自算(2026-09-01 老师修正) | - -### 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_name(orders)或无参数(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/getPositions,m_ 字段→语义字段映射) | -| 服务端 HTTP API 领域分发 | src/api/index.js + 领域文件 | 新增 api/trades.js(订单/成交域),注入 METHODS + HANDLERS | -| 前端 tab 框架 | src/client/index.js(GENERAL_TABS) | 交易记录 tab 的 render 从 PlaceholderTab 换成真实组件 | -| 服务端缓存 + 前端轮询模式 | MarketDataHub + MarketFeed(market-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 落地**:占位 tab(odl-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 内置 API(dict.thinktrader.net/innerApi/)中,m_nDirection 对应 EEntrustBS 枚举(48=买卖/49=查询/50=撤单),官方注明「股票买卖永远是 48」——**它是操作标记不是方向**;真实买卖方向在 m_nOffsetFlag(EOffset_Flag_Type:48=买入开仓/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 服务**,字段值应参考内置 API(innerApi)字典: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_EEntrustBS(48=买卖/49=查询/50=撤单),官方注明「股票买卖永远是 48」——**操作标记,非方向**; - ② 真实方向在 m_nOffsetFlag(enum_EOffset_Flag_Type:48=买入开仓/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 修正五(佣金合并计费,老师纠正):**同一笔委托分多笔成交,按总成交金额合并算一次佣金**(不逐笔重复收费);多笔独立委托(分开下单)才各自算佣金、各自触发 5 元最低。实现:calcOrderFees 委托层合并计费(Σ成交额×费率→最低5元一次),mapTrade 保留原始成交字段不再逐笔算费;前端聚合调用 calcOrderFees,展开明细只展示成交本身(费用在委托主行)。验证:200股拆两笔100+100,佣金5元(非10元);两笔独立委托各5元(10元)。 - - 2026-09-01 修正四(本周范围,老师纠正):本周 = **周一~周五**(不考虑周六日,不是往前推 7 天/自然周周日);实现 weekSunday→weekFriday(周一+4)。 - - 2026-09-01 修正三(交互模型,老师纠正):**交互是单向的**——用户先有操作(点「本月」),才有时间范围;不能反过来从「搜索范围落在哪」反向推断用户交互的是哪个按钮。实现改为 **preset 意图状态**:点按钮 → 记录 preset → 按钮高亮(单向);手动改日期 → 清除 preset(不再是任何快捷操作);轮询由 preset==='today' 决定,而非范围反推。 -- **2026-09-01 · 第八轮(排序逻辑定稿)**: - - 老师拍板:委托主行排序**默认降序**(最新委托在前),**支持手动调整**(点击表头排序,可切换升/降序)。 - - AI 更新:显示逻辑要点第 3 条改为「默认降序 + 表头点击排序」;可排序列包含时间/代码/方向/状态/委托量/成交量/金额等。 - -## 关联文档(随讨论补充) - -- 计划:待 R-007 定稿后派生(符合入范围门槛) -- 迭代记录:待实现后建立 -- 设计约束:待定稿后沉淀(方向判定规则、交易数据模型等) \ No newline at end of file diff --git a/docs/05-需求池/已完成/R-007.md b/docs/05-需求池/已完成/R-007.md new file mode 100644 index 0000000..aecaaeb --- /dev/null +++ b/docs/05-需求池/已完成/R-007.md @@ -0,0 +1,99 @@ +# R-007 交易记录接入(订单与成交数据 + 时间段查询)· 已完成 + +> 归档日期:2026-09-01 | 需求状态:**已完成** +> 原索引:docs/05-需求池/需求池索引.md(主索引保留 R-007 条目,指向本归档) +> 实现迭代:05-交易记录接入(验收通过,迭代复盘见 docs/04-迭代记录/05-交易记录接入/迭代复盘.md) +> 关联计划:PLAN-006(docs/02-计划/计划-交易记录接入.md) + +--- + +> 状态:**已定稿**(2026-09-01,老师确认)| 登记日期:2026-09-01 +> 来源:老师指令(2026-09-01) +> 优先级:P1 + +## 需求描述 + +在神之一手(one-divine-lot 插件)的「交易记录」tab 接入 QMT Bridge **当日委托(/trade/orders)与当日成交(/trade/trades)**: + +- **单表合并展示**:委托为主行,按 m_strOrderSysID 合并成交信息(聚合成交量/加权均价/金额/费用),点击展开逐笔成交明细; +- **时间段查询**:标题 + 时间段控件同一行(今日/本周/本月快捷按钮 + 手动起止日期),匹配历史接口按时间范围查询的形态; +- **费用计算**:佣金费率 = 万分之 m_dCommission(如 0.852 = 万0.852),不足 5 元按 5 元(账号没免五);卖出加印花税(万分之5);双向过户费(万分之0.1);**同一委托分笔成交合并算一次佣金**; +- **排序**:委托主行默认降序,支持表头点击手动排序; +- **日期导航**:为老师完善 QMT Bridge 历史成交接口预留(历史范围本期占位)。 + +## 核心逻辑(定稿版) + +1. **单表合并**:委托行 = 一笔委托,按 m_strOrderSysID 聚合该委托全部成交(成交量 Σ、加权均价、金额 Σ、费用 Σ);展开/折叠查看每笔成交明细(2026-09-01 老师拍板); +2. **方向判定**:m_nDirection=48 恒为 EEntrustBS 操作标记(官方 innerApi 字典),真实方向在 m_nOffsetFlag(48=买入/49=卖出)+ m_strOptName 交叉验证(Q3 闭环); +3. **交互单向模型**:preset 意图状态记录用户点的快捷按钮(操作→状态→UI),不做「范围反推按钮」反向推断;手动改日期清除 preset(2026-09-01 老师纠正); +4. **快捷范围(完整互斥)**:今日=最近交易日单日;本周=所在自然周周一~周五(不考虑周六日);本月=所在自然月1号~月末(2026-09-01 老师纠正:不做截至今天截断); +5. **费用计算**: + - 佣金 = Σ成交额 × (万分之m_dCommission),不足 5 元按 5 元(没免五); + - 印花税 = 卖出单边 × 万分之5(2023-08-28 起标准); + - 过户费 = 双向 × 万分之0.1(2022-04-29 起标准,无最低,中登收取); + - **同一委托分笔成交合并算一次佣金**;多笔独立委托各自算(2026-09-01 老师修正); +6. **数据时效**:/trade/orders 与 /trade/trades 仅当日数据(get_trade_detail_data 读客户端缓存,官方 Q&A 确认),历史查询需老师完善 QMT Bridge 接口; +7. **刷新**:仅「今日」范围 4s 轮询;其他范围一次性查询。 + +## 数据模型(语义化映射) + +**Order**:orderId/code/name/exchange/direction/directionCode/optName/status/orderVolume/tradedVolume/totalVolume/limitPrice/tradedPrice/amount/insertDate/insertTime/cancelInfo/errorMsg + +**Trade**:tradeId/orderId/code/name/exchange/direction/directionCode/optName/price/volume/amount/commissionRateWan(佣金费率万分之)/tradeDate/tradeTime + +**费用**:calcOrderFees(委托级):totalAmount/commission(最低5元一次)/stampTax(卖出)/transferFee(双向)/total + +## 边界(不做) + +- 历史(非当日)交易数据查询实现(老师完善 QMT Bridge 接口后接入,服务端已预留 start/end 透传); +- 交易数据本地持久化(Q5 本期不做,跨日复盘待历史接口就绪后评估); +- 按策略过滤交易(Q10 后续迭代,strategy_name 与插件策略体系打通); +- 下单/撤单等交易操作(目标-007 人机合一控制权另议)。 + +## 关键决策(Q1-Q11 结论) + +| # | 问题 | 结论 | +|---|---|---| +| Q1 | 展示范围 | 单表合并:委托主行 + 展开成交明细(老师拍板) | +| Q2 | 刷新机制 | 服务端中转 + 前端 4s 轮询(仅今日范围) | +| Q3 | 方向判定 | m_nOffsetFlag(48买/49卖)+ m_strOptName 交叉验证 | +| Q4 | 状态展示 | 全量 + 状态列中文映射(未报/已报/部成/已成/已撤/废单) | +| Q5 | 持久化 | 本期不做(跨日复盘待历史接口) | +| Q6 | 关联形态 | 单表合并 + 展开/折叠(老师拍板) | +| Q7 | 方向着色 | 红买绿卖 | +| Q8 | 精度 | 成交额/金额 2 位、手续费/费用 2 位、成交量整数 | +| Q9 | 优先级 | P1 | +| Q10 | 策略联动 | 本期不做(后续迭代) | +| Q11 | 时间段查询 | 今日/本周/本月快捷 + 手动起止;完整互斥范围;单向交互模型 | + +## 讨论与修正记录 + +- 2026-09-01 登记 + 技术研究(API 字段全表 / 方向判定 / 数据时效 / sample data); +- 2026-09-01 范围定稿:当日订单+成交 + 日期导航(老师将完善历史接口); +- 2026-09-01 展示设计定稿:单表合并 + 展开明细 + 排序降序; +- 2026-09-01 修正一:快捷按钮 今日/本周/上周 → 今日/本周/本月; +- 2026-09-01 修正二:快捷范围为完整时间段(不做截至今天截断,操作逻辑问题); +- 2026-09-01 修正三:交互单向模型(操作→状态→UI,不做反向推断); +- 2026-09-01 修正四:本周 = 周一~周五(不考虑周六日); +- 2026-09-01 修正五:佣金按委托级合并计费(分笔成交只收一次佣金); +- 2026-09-01 费用规则:m_dCommission = 佣金费率万分之,最低5元,印花税/过户费费率确认。 + +## 实现记录 + +| 项 | 内容 | +|---|---| +| 实现迭代 | 05-交易记录接入 | +| 服务端 | QmtBridgeRestDataSource(getOrders/getTrades/getTradingDates/calcOrderFees)、api/trades.js(orders/trades/trading-dates) | +| 客户端 | TradeRecordsTab.jsx(单表合并+排序+轮询)、RangeSelector.jsx(时间段选择) | +| 构建安装 | pnpm run build + 宿主重启(服务端)/ 页面刷新(客户端) | +| 提交 | bb3f8bd(迭代03-05)、8caeb76(佣金合并计费)、08c4ad3(箭头样式) | + +## 验收结果 + +- 服务端三端点端到端实测:✅(orders/trades/trading-dates 返回真实数据) +- 单表合并 + 展开明细:✅(博纳影业卖出 200股@6.00 委托+成交完整链路) +- 费用计算:✅(佣金5 + 印花税0.6 + 过户费0.012 = 5.612;委托级合并计费验证通过) +- 时间段查询(今日/本周/本月 + 手动):✅ +- 排序(默认降序 + 表头手动):✅ +- 方向判定(m_nOffsetFlag + optName):✅ +- 现有功能不回归:✅(持仓/策略/行情/连接配置正常) diff --git a/docs/05-需求池/需求池索引.md b/docs/05-需求池/需求池索引.md index 486e898..1645e7f 100644 --- a/docs/05-需求池/需求池索引.md +++ b/docs/05-需求池/需求池索引.md @@ -18,7 +18,7 @@ | R-006 | 策略数据 JSON data store schema 标准化 | 策略数据集标准化为 JSON data store(store.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-31,T-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-交易记录接入 | 实现中 | +| R-007 | 交易记录接入(订单与成交数据 + 时间段查询) | 交易记录 tab 接入 QMT Bridge 当日委托(/trade/orders)与当日成交(/trade/trades):**单表合并**(委托主行 + 展开成交明细)+ **时间段查询**(今日/本周/本月 + 手动起止)+ 费用计算(佣金费率+最低5元/印花税/过户费,委托级合并计费)。**2026-09-01 定稿并完成(迭代 05 验收通过),已归档至 已完成/R-007.md** | 老师指令(2026-09-01) | P1 | 已定稿 | 2026-09-01 | 05-交易记录接入 | **已实现(已归档)** | ## 渐进明细规划素材