tradingSystem/QMT_INTERFACE_REQUIREMENTS.md

82 lines
10 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 持仓系统 ↔ QMT 侧下游系统 · 数据与接口需求清单
> 用途:本清单由用户持有,与 QMT 侧(下游交易系统)协商。请下游按编号逐项答复(能提供/字段差异/时延/替代方案),答复直接回填本文档「答复」列,作为对接定稿依据。
> 背景架构调整后对下游的指挥权由决策系统bionic_trader移交持仓系统tradingSystem/PMS。`trading_order` / `trading_position` 两表仍归下游维护PMS 只读PMS 新增一条带数量的统一指令通道(见 B 部分)。
> 版本:**V2.02026-07-28** —— QMT 侧已就六项问询答复,本版回填答复并调整通道方案。
>
> **本版最大变化B 部分的表通道方案已废止**。双方商定指令下发与执行回报改走 **WebSocket 双向长连接**,协议细节见同目录 [`QMT_WS_PROTOCOL.md`](./QMT_WS_PROTOCOL.md)。B 部分保留仅供追溯不再作为实现依据。A 部分(只读数据)与 C 部分(切换约定)继续有效。
---
## A. PMS 需要读取的数据下游提供153 代理可达、严格单表查询)
| # | 数据项 | 需要的字段 | 期望更新时延 | 用途 | 答复 |
|---|---|---|---|---|---|
| A1 | 持仓快照 `trading_position` | 股票代码(点式)、持仓数量、**可用数量T+1 可卖)**、成本价(如有)、冻结数量(如有) | 盘中 ≤ 5 分钟 | 账本对账基准。当前 PMS 只确认过 `stock_code` 列可用,**请提供该表完整字段定义DDL**,尤其确认是否已有"可用数量"列——若无PMS 自行按 T+1 规则推算 | **PMS 侧实机探明2026-07-27待下游确认语义**:该表 14 列,含 `stock_code / stock_name / total_quantity / available_quantity / frozen_quantity / cost_price / market_price / market_value / profit_loss`。**可用数量列已存在**`available_quantity`本项数据需求实质已满足PMS 已按此列对接。仍请确认:①`available_quantity` 是否即 T+1 可卖口径 ②更新时延 ③`stock_code` 格式(点式/前缀式) |
| A2 | 委托与成交 `trading_order` | 委托号、股票代码、方向、委托价、委托量、状态(**完整状态枚举文档**)、成交量、成交均价、委托/成交时间、来源标识 | 状态变更后 ≤ 1 分钟 | 成交回放入账(批次/成本)、指令执行确认。**请提供完整 DDL 与状态流转说明**(现掌握的 submitted/filled/completed/pending/failed 为推断口径,需正式确认) | **PMS 侧实机探明**:该表 20 列,已见 `order_id / strategy_id / stock_code / stock_name / order_side / order_quantity / order_price / target_price / order_status` 等。**仍缺两项,是本清单里最卡 PMS 的**:①状态枚举的正式定义 ②**成交来源标识**(哪条委托对应 PMS 的哪条指令。在来源标识到位前PMS 只能按「同股同向 + 下发早于成交 + FIFO」贪心认领认领不上即判外部成交并告警——人工与 PMS 同时下单时会误判 |<br><br>**QMT 侧答复2026-07-28**:①**状态枚举**已给出 —— `submitted` 已提交 / `filled` **部分成交** / `completed` 已完成 / `pending` 挂单成功但 QMT 无响应 / `failed` 委托失败;撤单另有可靠终态。②**成交均价**将新增列。③**策略标识**字段表中已有,改造后可写入。<br><br>**PMS 侧结论**:本项**主链路已由 WebSocket 承接**`trade` 逐笔成交消息带 `instruction_id`,来源标识问题自然消解。仍需注意两点,已并入新协议:⑴表中的 `strategy_id` 是指向 `t_trading_strategy` 的整数外键(因子策略表),只能回答「是不是 PMS 下的」,回答不了「是哪一条指令」,**不足以支撑回放认领**;⑵`filled` = 部分成交这个命名与字面含义相反,协议层改用 `PARTIAL` / `FILLED` 区分,映射见新协议 §7.2。**PMS 不再读 `order_status` 判断成交** |
| A3 | 账户资金快照(**新增需求** | 总资产、可用资金、冻结资金、当日卖出可用资金T+0 回笼) | 盘中 ≤ 5 分钟;日终必须 | 总规模校准与买入前资金校验。形式不限:新表 / 现有表 / HTTP 接口均可,请给出可行方案 | **已确认可提供**,走 WebSocket 实时回传。字段与消息格式见新协议 §5.7 `snapshot{kind:"funds"}`。**`sell_return_today`(当日卖出回笼)务必提供**PMS 买入前的资金校验依赖它 |
| A4 | 成交回报明细(可选) | 若 A2 已含逐笔或聚合成交(成交量/均价),本项可免;否则请提供逐笔成交表 | 同 A2 | 部分成交场景的精确入账 | **已升格为必需项**QMT 侧确认可回传「逐笔和最终结果」。**PMS 账本以逐笔 `trade` 消息为唯一入账依据**`order_update` 仅作状态跟踪与终态校验。见新协议 §5.5 |
| A5 | 上游买入计划 `trading_buy_plan` | PMS 将作为该表的承接方(替代原决策系统 ENTRY_GATE 的角色)。请确认:①下游当前是否仍轮询 `is_active=6` 自动挂单?②切换后是否可以**停止**该轮询(统一走 B1 通道),或保留作为过渡(方案 X | — | 旧通道处置(见 C2 | **未答复,仍待确认**(新协议 Q1。另注该表唯一约束为 `(stock_code, trading_time)``buy_amount` 是金额非股数,单股分批会撞约束——这也是通道改走 WebSocket 后不再受制于该表的原因之一 |
## B. ~~PMS 写入:统一指令通道~~ 【已废止 · 2026-07-28】
> **本节方案已被 WebSocket 通道取代,不再作为实现依据,保留仅供追溯。**
> 双方商定:指令下发与执行结果(逐笔成交、最终结果、落库结果)全部走 WebSocket 双向长连接;
> 幂等与防重放由「PMS 生成的 `instruction_id` + 签名 + 时间窗」保证,不再依赖表的唯一约束。
> **现行方案见 [`QMT_WS_PROTOCOL.md`](./QMT_WS_PROTOCOL.md)。**
> 下方 B1.1~B1.7 的协商点已在新协议中逐条落实通道形式§1、响应节奏§1 心跳/实时推送)、
> 部分成交§5.4/§5.5、撤单§4.3、拒绝码§7.3、市价语义§4.2,改为**限价必填**)、建表归属(不再需要)。
### ~~B1 `pms_order_request` —— 带数量的统一买卖指令(建议表结构,可等价改为 Redis 流)~~
```sql
CREATE TABLE pms_order_request (
id BIGINT PRIMARY KEY AUTO_INCREMENT,
instruction_id VARCHAR(64) NOT NULL UNIQUE COMMENT '幂等键, PMS 生成, 重复插入应被拒绝',
ts_code VARCHAR(16) NOT NULL COMMENT '点式, 如 600000.SH',
side VARCHAR(8) NOT NULL COMMENT 'buy / sell',
qty INT NOT NULL COMMENT '股数, 整百',
limit_price DECIMAL(10,2) NULL COMMENT '限价; NULL=按下游默认方式',
valid_until DATETIME NOT NULL COMMENT '有效期, 过期未执行由下游置 EXPIRED',
source VARCHAR(16) NOT NULL DEFAULT 'pms',
status VARCHAR(16) NOT NULL DEFAULT 'NEW'
COMMENT 'NEW→ACCEPTED→EXECUTING→FILLED / PARTIAL / REJECTED / EXPIRED / CANCELLED',
exec_qty INT NULL COMMENT '已成交数量(聚合)',
exec_avg_price DECIMAL(10,2) NULL COMMENT '成交均价(聚合)',
reject_reason VARCHAR(200) NULL,
cancel_flag TINYINT NOT NULL DEFAULT 0 COMMENT 'PMS 置 1 请求撤单, 下游确认后置 status=CANCELLED',
create_time DATETIME NOT NULL,
update_time DATETIME NOT NULL,
KEY idx_status (status), KEY idx_code (ts_code)
);
```
| # | 协商点 | 说明 | 答复 |
|---|---|---|---|
| B1.1 | 通道形式 | 表轮询(上述 DDL还是 Redis 流?下游选定形式,字段语义不变 | |
| B1.2 | 轮询/响应节奏 | 下游多久拉一次 NEW期望 ≤ 1 分钟;状态回写时延期望 ≤ 1 分钟 | |
| B1.3 | 部分成交 | 有效期内持续执行到 FILLED 或到期置 PARTIALexec_qty 如实回写)——可否按此语义? | |
| B1.4 | 撤单 | PMS 置 cancel_flag=1 → 下游撤在途委托并回写 CANCELLED已成交部分保留在 exec_qty——可行 | |
| B1.5 | 拒绝码 | 涨跌停/停牌/资金不足/数量非法等 reject_reason 枚举,请提供清单 | |
| B1.6 | 市价语义 | limit_price=NULL 时下游按什么方式执行(对手价/最新价±滑点)? | |
| B1.7 | 建表归属 | 该表建在下游库还是 153 代理侧PMS 经 153 代理单表读写均可) | |
## C. 行为与切换约定
| # | 事项 | 说明 | 答复 |
|---|---|---|---|
| C1 | 幂等与重复防护 | instruction_id 唯一约束由表/流层保证;下游对同一 instruction_id 只执行一次 | |
| C2 | 旧通道停用清单 | 切换生效后,下游**停止**:①直接执行决策系统的卖出指令与盘中 ENTRY/EXIT 信号 ②(若 A5 确认)轮询 trading_buy_plan 自动挂单。此后下游只接受 WebSocket 通道指令。请确认停用方式与时点 | ⚠️ **本轮答复未涉及,是当前最大的未决项**(新协议 Q1。不定死时点切换当天两套系统会对同一只票同时下单。PMS 侧已完成信号订阅改造PMS 现已自行消化决策系统信号),下游停用的前置条件已具备 |
| C3 | 灰度共存期 | 切换初期建议双轨观察 N 个交易日旧通道只读不执行、B1 实际执行),请确认可行性 | |
| C4 | 时钟与代码格式 | 双方统一点式代码600000.SH与服务器时钟NTP日期时间字段时区 Asia/Shanghai | |
| C5 | 故障约定 | 下游不可用时 PMS 指令停发并告警PMS 侧守成);下游恢复后不补执行已过期指令 | |
| C6 | 账号与权限 | PMS 需要的库账号/代理路由(读 A1-A5、读写 B1请提供 | |
## D. 请提供的文档
| # | 文档 | 说明 | 答复 |
|---|---|---|---|
| D1 | `trading_position` / `trading_order` / `trading_buy_plan` 完整 DDL | 含索引与状态枚举正式定义 | **列名已由 PMS 实机探明**`docker compose run --rm pms-web python scripts/check_db.py` 的 [3] 段会打印三表完整列定义可直接贴进本表trading_position 14 列 / trading_order 20 列 / trading_buy_plan 25 列。**仍需下游正式提供的是语义而非列名**:状态枚举取值与流转、各数量列口径、索引 |
| D2 | 下游执行行为说明 | 委托拆单逻辑(如有)、涨跌停处理、集合竞价时段行为 | |
| D3 | 现有信号消费点清单 | 下游当前消费决策系统信号的全部位置(用于 C2 停用核对,防遗漏) | |