docs: miniQMT停服迁移评估(大QMT+xtquant_big_convert, deadline 0918) [nas]
CI/CD / test (push) Successful in 26s
CI/CD / nas-deploy (push) Successful in 26s
CI/CD / nas-verify (push) Successful in 9s

This commit is contained in:
2026-09-07 13:14:26 +08:00
parent 5ab7ce8102
commit ce10547a4a
@@ -0,0 +1,81 @@
# miniQMT 停服迁移评估(xtquant_big_convert / 大QMT RPC
> 2026-09-07 infra session 出品。背景:券商通知 **2026-09-18 停 miniQMT**(用户与国金确认),VPS 上 8 组合实盘 + 8 影子 + CTA/bridge/monitor + xt_eod 采集全部依赖 XtMiniQmt(模拟端,账号 66639661)。
> 依据:双 agent 只读探查(对方仓库 `~/.openclaw/sanguo_projects/xtquant_big_convert` v0.3.25 + 我方调用面盘点),本文引用均来自探查报告的文件:行号。
## 一、结论
**方向可行:xtquant_big_convert 的 xtquant shim 兼容面覆盖我方三形态全部交易 API 与绝大多数行情 API,回调机制完整,多客户端(16 引擎)协议级支持。** 但有 4 个风险,其中前 2 个是 go/no-go 级,必须在动手前闭环:
### 🔴 R1(置顶):我们跑的是「模拟端」,对方 server 可能只在「实盘模式」工作
- 我们的 miniQMT 是**国金QMT交易端模拟**(路径 `C:\国金QMT交易端模拟\userdata_mini`,66639661 模拟账号),全平台是 QMT 模拟柜台上的纸面交易
- 对方 README.md:264 明言:**「模拟模式下单返回 -1 且查不到」「QMT 必须实盘模式才能收到完整回报」**
- 待办:①在装好的大 QMT 上用模拟账号实测 server 下单路径 ②若确认不行,问维护者(issue/群,项目日更很活跃)③与券商确认模拟柜台与大QMT模拟模式的对应关系。**此项不闭环,整个迁移无从谈起**
### 🔴 R2:大 QMT 客户端与权限尚未确认
- VPS 现只有 XtMiniQmt 极简版;大 QMT 是另一个完整客户端(如 `D:\国金证券QMT交易端\`),需券商侧权限 + 安装 + 下载内置 Python 组件
- 用户 09-07 与券商确认了停服日期,**大 QMT 权限口径待补核**——若需审批,这是 11 天里最长周期项,最先启动
### 🟡 R3:串行吞吐与头阻塞
- 对方约束:交易类请求全部 defer 到 QMT 主线程 adjust 串行(Redis 串行 20 次/s,4 线程并发 143 次/s);慢调用堵队列(实测首次 `get_financial_data` 346s
- 我方压力:16 引擎轮询叠加(vnpy_qmt EVENT_TIMER + bullet_trade LiveEngine 轮询 query_orders/trades)开盘段可能 >20 req/s
- 对策(工程化可解):①组合实盘链路本就是轮询制,迁移时顺势切回调制(对方有全套推送)或调低轮询频率 ②`get_financial_data/download_financial_data` 等重数据腿限时盘后跑或改走本地 sanguo_datafundamentals provider 本就有本地化计划)
### 🟡 R4xtdata 长尾接口待验证(xt_eod 断供风险)
- 对方明确缺口:`get_sector_list`/`get_holidays` 仅 fallback、`get_stock_type` 不可用
- 我方在用但对方报告未明确列出的:`get_stock_list_in_sector`xt_eod 的 ETF/基金/北交所名单命脉)、`get_index_weight`/`get_divid_factors`/`get_trading_dates`bullet_trade MiniQMTProvider)——需装好后逐个验证;`call_method` 万能入口可兜底一部分
- 若不支持:ETF/基金/北交所 EOD 断供 → 数据 session 另找源(与交易迁移解耦)
## 二、接口对照(我方最小集 vs 对方兼容面)
**交易(三形态合并去重)——全绿 ✅**
| 我方调用 | 对方实现 | 备注 |
|---|---|---|
| `XtQuantTrader(path,session)/start/connect/subscribe/stop/register_callback` | shim `BigQmtXtTrader`xtquant_compat.py:4864 | connect 语义=连 Redis/ZMQ**session_id 撞车问题(08-30 案)自动消失**;path 参数失效 |
| `order_stock` 同步 8 参(bridge/bullet_trade | :3576-3586int 子类 OrderId>0 成功/-1 失败,str()=合同号) | 契约同 miniQMT |
| `order_stock_async`vnpy_qmt | :4184-4208<1ms 返回 seq | 「事件先于响应」常态,按 order_remark 设屏障(我们 remark 指纹体系现成) |
| `cancel_order_stock(_sysid)`+async | :4333/:4312/:4654/:4701 | 返回 0 成功/-1 失败 |
| `query_stock_asset/positions/orders/trades`+async+callback 参数) | :3222/:3322/:3473/:3495async 变体 :4584-4651 | 服务端白名单 137 只读+3 下单 |
| 回调 `on_disconnected/on_stock_asset/on_stock_order/on_stock_trade/on_stock_position/on_order_error/on_cancel_error/on_order_stock_async_response/on_cancel_order_stock_async_response` | `XtQuantTraderCallback` 基类全套(xtquant_compat.py:88-123 | Redis PUBLISH+XADDstream maxlen 2000 可短时回放),柜台回报 ms 级 |
| `StockAccount(id[,type])`/`XtOrder/XtTrade/...`/`xtconstant`ORDER_* 48-57、市价链) | shim xttype + 539 常量 | 我们三套状态码映射不用改 |
**行情——大面积绿,四个待验证**
| 我方调用 | 对方 |
|---|---|
| `get_full_tick`(影子撮合价/涨跌停、实盘自检、fundamentals 批量) | ✅ 但注意破坏性变更:`get_full_tick(["SH"])` 默认只取股票,要全量传 `types=["all"]` |
| `get_market_data(_ex)/get_local_data/get_instrument_detail/get_last_quote/subscribe_quote/subscribe_whole_quote/unsubscribe_*/download_history_data(2)` | ✅(订阅多客户端引用计数共享) |
| `get_financial_data/download_financial_data` | ✅ 但重腿盘后跑(R3 |
| `get_stock_list_in_sector` / `get_index_weight` / `get_divid_factors` / `get_trading_dates` | ⚠️ 待验证(R4 |
## 三、我方三形态迁移差异(探查 B 的链路梳理)
| 形态 | 现状 | 迁移动作 |
|---|---|---|
| A. HTTP bridge(备胎) | 纯同步 API、无回调 | shim 顶替后零改动;remark 现传空——若启用需补指纹 |
| B. vnpy_qmt CTA(进程内) | 全 async+callback | shim 兼容签名;回调链最全,重点联调 |
| C. bullet_trade QmtBroker(组合实盘×8 主路径) | 同步 API+轮询制、回调只挂 on_disconnected、`bt:live_{id}:{hash}` remark 归因 | **最小改动**:装 shim 即可跑;轮询 query 兼容;remark 往返保真是验收重点(对方 0.3.25 #216 正好修了 strategy_name 归因优先级) |
| 影子×8 | 无 xttrader,仅 xtdata 取价 | shim 顶替 xtdata`get_full_tick` 注意 types 参数 |
| xt_eod 采集 schtask | get_stock_list_in_sector+download_history_data2 | 客户端 pip 包装上即连(跨平台),R4 验证后定去留 |
**连接参数变化**`SANGUO_QMT_PATH`userdata_mini 扫描)与 session_id 体系全部失效 → 换成 Redis/ZMQ 端点配置;`live_accounts` 注入 env 的机制保留,只换内容。多账号单 server 或多策略实例(对方 README.md:813-865)——我们单账号 66639661,单 server 足够。
**执行回报广播过滤**:对方按 account_id 广播全部委托/成交,16 引擎各自按 order_remark 过滤——我们已有 remark 指纹库(7b7667e 重建 own 集 + live_{id} 唯一 label),天然匹配。
## 四、灰度时间表(deadline 09-18,目标 09-15 全量切完留 3 天观察)
| 阶段 | 日 | 内容 | 闸门 |
|---|---|---|---|
| P0 前置 | 09-08 前 | **用户**:券商确认大QMT权限+下载安装到 VPS(`D:\国金证券QMT交易端\`),下载 python 库组件 | 大 QMT 能登录(模拟+实盘口径都问清) |
| P1 部署 | D+1 | Redis-windows 装同机(bind 127.0.0.1+强密码)或 ZMQ`deploy_qmt_bridge.ps1`QMT 模型交易页加载 `BIGQMT_REDIS_DRYRUN.py`(**实盘模式、不勾"启动本地python"** | server 起、Redis 队列可见 |
| P2 只读验证 | D+1~2 | pip 装 clienteditable 防 shim 冲突);跑通 query_stock_asset/positions/orders + get_full_tick**R1 模拟模式实测 + R4 四接口验证** | 只读全绿;R1/R4 定性 |
| P3 下单冒烟 | D+2~3 | 官方 6 步灰度第 4 步开 `rpc_allow_order_methods=True`;模拟小单 1 笔买+卖,验 remark 往返/成交回报/撤单 | 冒烟单闭环 |
| P4 影子试水 | D+3~5 | 影子×1 切 shim 跑 2 个交易日,与 miniQMT 侧对照 | 撮合价/涨跌停判定无异常 |
| P5 全量 | D+5~8 | 8 影子全切 → 组合实盘逐个切(每切一个跑一日恒等式对账绿再切下一个);CTA/monitor/bridge 收尾 | 恒等式连续绿 |
| 回退 | 至 09-17 | miniQMT 在 09-18 前天然是回退路径(保留不卸载,env 切回即回退) | — |
## 五、开放项(按优先级)
1. **R1 模拟模式 go/no-go**(阻塞一切)
2. **R2 大QMT权限+安装**(用户动作,最长周期)
3. R4 四个 xtdata 接口验证清单
4. 策略 session 参与:P5 实盘切换涉及策略代码/调度,需策略 session 联合(三向一致性检查按项目 CLAUDE.md 流程走 Gitea Issue
5. xt_eod 若断供,数据 session 找替代源(独立工作流,不阻塞交易迁移)