master
QMT Bridge — 大 QMT 薄桥(HTTP + WebSocket)
将大 QMT(国金 GJQMT_BIG)内置 Python 的行情/交易能力,通过 HTTP RESTful + WebSocket 推送暴露为开放数据服务。接口规范由本地维护的 OpenAPI 文档驱动,可同步 Apifox 管理。
⚠️ 新会话启动 · 首要参考
- 本文件(README.md) — 项目概览、结构、接口、部署、约束速查
docs/项目规范.md— 详细规范(设计约束/部署/接口文档/迭代规范),项目的"宪法"docs/设计/整体设计方案_v3.md— 唯一设计依据(架构决策/环境调研/性能实测)docs/迭代记录/index.md— 迭代索引(每次迭代的记录)
架构一句话
薄桥:跑在 QMT 策略进程内(Python 3.6.8,纯标准库),HTTP 做请求,WS 做推送,所有业务逻辑由 QMT 统一处理,桥只做协议转换。
外部客户端 ── HTTP(8610): 查询/订阅 ──► 大QMT策略进程
◄── WS(8610): 行情推送 ── bridge_main.py
- 端口: 8610(HTTP + WS 共端口)
- 账号: 单账号(桥绑定),从
bridge_local_config.py读 ACCOUNT_ID
目录结构
qmt_bridge/
├── README.md ← 本文件(会话启动参考)
├── docs/
│ ├── 项目规范.md ← 项目规范(宪法,详细约束)
│ ├── api_spec/openapi.yaml ← 接口规范(唯一事实来源,中文,主动维护)
│ ├── 设计/整体设计方案_v3.md ← 主设计文档(唯一设计依据)
│ ├── 研究/ ← 调研类文档(xtquant_big_convert调研、官方接口核实)
│ ├── 迭代记录/index.md ← 迭代索引(每次迭代登记)
│ ├── 桥接口清单与sfgrid满足度对照.md
│ └── ...
├── src/ ← 桥源码(部署时复制到 QMT python 目录)
│ ├── bridge_main.py ← QMT 生命周期入口
│ ├── bridge_http_server.py ← HTTP server + 路由(含 /mcp 路由)
│ ├── bridge_ws_server.py ← WebSocket(心跳 + broadcast_all 推送)
│ ├── bridge_data_adapter.py ← QMT API 透传适配层
│ ├── bridge_subscription.py ← 订阅管理(snowflake sub_id + QMT 回调→WS 推送)
│ ├── bridge_mcp_server.py ← MCP 端点(JSON-RPC tools,POST /mcp)
│ ├── bridge_util.py ← 共享状态 + 工具
│ └── qmt_strategy_entry.py ← QMT 策略入口(粘贴进 QMT 编辑器,含热重载)
├── tools/
│ ├── push_apifox.py ← 生成 openapi.json + Apifox 手动导入指引
│ ├── fetch_apifox_doc.ps1 ← 沙箱外抓取 Apifox 文档(UAC 提权)
│ └── fetch_qmt_docs.ps1 ← 沙箱外抓取 QMT 官方文档(UAC 提权)
├── tests/
│ ├── test_trade.py ← 交易接口 mock 测试
│ ├── test_subscription.py ← 订阅/退订/tick mock 测试
│ ├── test_ws_push.py ← WS 推送链路 mock 测试
│ ├── test_ws_real.py ← 真实 QMT WS 推送验证
│ ├── test_sub_no_ws.py ← 无 WS 连接时订阅行为测试
│ └── test_mcp.py ← MCP 端点 mock 测试(纯标准库,无需 pandas)
├── reference/ ← 参考材料(xtquant_big_convert 等,只读)
└── deploy_elevated.bat ← 部署脚本(自动提权)
模块职责与依赖
bridge_main.py ──import──► bridge_http_server.py, bridge_ws_server.py, bridge_data_adapter.py, bridge_subscription.py
bridge_http_server.py ──import──► bridge_data_adapter.py, bridge_util.py, bridge_ws_server.py, bridge_subscription.py
bridge_ws_server.py ──import──► bridge_util.py
bridge_data_adapter.py ──import──► bridge_util.py
bridge_subscription.py ──import──► bridge_util.py, bridge_ws_server.py
| 模块 | 职责 |
|---|---|
| bridge_main.py | QMT 生命周期,启动/停止服务器,绑定 QMT API,刷新交易缓存,清理订阅 |
| bridge_http_server.py | HTTP 服务,路由(含订阅/退订/tick/MCP),WS Upgrade 分流,openapi 端点 |
| bridge_ws_server.py | WS 握手/帧编解码/心跳,broadcast_all 推送 |
| bridge_data_adapter.py | 调 QMT API(get_market_data_ex/get_full_tick/get_instrument_detail/get_trading_dates/get_trade_data) |
| bridge_subscription.py | 订阅管理: snowflake sub_id、订阅表、QMT 订阅回调→WS 推送 |
| bridge_mcp_server.py | MCP 端点: JSON-RPC 2.0(initialize/ping/tools/list/tools/call),9 个工具 |
| bridge_util.py | 日志、工具、共享状态(CTX/QMT_API/交易缓存) |
| qmt_strategy_entry.py | QMT 策略入口(热重载: 重跑时清模块缓存+释放端口) |
当前接口(12 个 HTTP + WS + MCP,详见 docs/api_spec/openapi.yaml)
- GET
/health— 健康检查 - GET
/data/kline— K线(先下载后查询,fields 可筛选,默认完整 OHLCV) - GET
/data/quote— 实时快照(单票 full tick,含五档) - GET
/data/tick— 全推 tick 快照(批量,透传 get_full_tick)【订阅体系】 - GET
/data/instrument— 合约详情(涨跌停价/名称) - GET
/data/calendar/trading_dates— 交易日历 - POST
/data/subscribe— 订阅数据(当前支持 whole 全量tick)【订阅体系】 - POST
/data/unsubscribe— 退订数据【订阅体系】 - GET
/trade/positions— 持仓(全部持仓,语义化字段 + m_* 超集 + summary) - GET
/trade/asset— 资金资产 - GET
/trade/orders— 委托(code/status/strategy_name 过滤) - GET
/trade/trades— 成交 - WS
/ws— 单通道推送(接收{"type":"whole","data":{code:tick_dict}}增量) - POST
/mcp— MCP 端点(JSON-RPC 2.0,9 个工具与 HTTP 接口 1:1),详见下文「MCP 服务」章节
待实现: /trade/order(下单)、/trade/cancel(撤单)、/trade/order/status、WS 账号交易通知(trade_result 等)、MCP qmt_order/qmt_cancel/SSE 流式。
部署到 QMT
- 双击
deploy_elevated.bat(自动提权,复制 src 下 7 个 .py 到C:\Programs\GJQMT_BIG\python\) - QMT 策略编辑器新建策略,粘贴
qmt_strategy_entry.py内容(含热重载) - 配置
C:\Programs\GJQMT_BIG\python\bridge_local_config.py的ACCOUNT_ID - 运行 → 日志
[qmt_bridge] HTTP+WS server started on 0.0.0.0:8610
热重载: 改代码后 QMT 里 停止→运行 即可(入口自动清模块缓存+释放端口)。
⚠️ 若端口被残留占用(监听但不响应),需重启 QMT 进程彻底释放。
验证: http://127.0.0.1:8610/health 返回 ok 即正常。
接口规范同步(Apifox)
- 桥提供
GET /openapi.yaml/GET /openapi.json(从 QMT 目录读取,Apifox URL 同步用) - 手动导入: Apifox → 导入数据 → OpenAPI/Swagger → 文件导入
docs/api_spec/openapi.yaml - 辅助:
python tools/push_apifox.py(生成 json + 打印步骤) - 开放 API 自动推送未打通(沙箱代理伪造 201 / PowerShell 422)
MCP 服务(AI 助手接入)
桥在 8610 端口提供 MCP(Model Context Protocol)端点,AI 助手(Claude Desktop / Cursor / 支持 MCP 的客户端)可通过 tools/call 直接调用桥的行情/交易能力,无需自己解析 HTTP。
端点与接入
URL: http://127.0.0.1:8610/mcp (Streamable HTTP,非流式)
鉴权: X-Token header 或 ?token=(与桥 TOKEN 一致;未设 TOKEN 时无需)
方法: initialize → notifications/initialized → ping → tools/list → tools/call
Claude Desktop 配置示例(claude_desktop_config.json):
{
"mcpServers": {
"qmt_bridge": {
"type": "http",
"url": "http://127.0.0.1:8610/mcp",
"headers": { "X-Token": "<桥 TOKEN,如有>" }
}
}
}
工具清单(9 个,与 HTTP 接口 1:1)
| 工具 | 对应 HTTP | 说明 |
|---|---|---|
qmt_kline |
GET /data/kline | K线(先下载后查询,fields 可筛选) |
qmt_quote |
GET /data/quote | 实时快照(单票 full tick,含五档) |
qmt_tick |
GET /data/tick | 批量 tick 快照(codes 逗号分隔) |
qmt_instrument |
GET /data/instrument | 合约详情(涨跌停价/名称) |
qmt_trading_dates |
GET /data/calendar/trading_dates | 交易日历 |
qmt_positions |
GET /trade/positions | 全部持仓(语义化字段 + summary) |
qmt_asset |
GET /trade/asset | 资金资产 |
qmt_orders |
GET /trade/orders | 委托(code/status/strategy_name 过滤) |
qmt_trades |
GET /trade/trades | 成交 |
实现要点
- 为什么桥内嵌: QMT 内置 Python 3.6.8 纯标准库,官方 mcp SDK 要求 Python ≥ 3.10;桥手写 JSON-RPC 2.0(仅 json/socket/threading),零依赖
- 线程约束一致: 全部工具复用
bridge_data_adapter→ 与 HTTP 接口同模式(行情 worker 直调,交易读缓存),不违反 QMT 线程约束 - 错误语义: JSON-RPC 错误走 HTTP 200(parse -32700 / invalid request -32600 / method not found -32601 / invalid params -32602 / internal -32603);非法 body 走 400
- CORS: 响应带
Access-Control-Allow-Origin: *,OPTIONS /mcp预检 204 - 不做订阅/长连接: MCP 仅查询(请求-响应);实时数据走 HTTP 订阅 + WS
/ws推送 - 详细设计见
docs/迭代记录/MCP服务.md
本地测试
python tests/test_trade.py # 交易接口 mock 测试
python tests/test_subscription.py # 订阅/退订/tick mock 测试
python tests/test_ws_push.py # WS 推送链路 mock 测试
python tests/test_mcp.py # MCP 端点 mock 测试(纯标准库,无需 pandas)
关键约束(硬性,详见 docs/项目规范.md)
- 源码编码: 文件头
# coding:gbk,内容必须纯 ASCII(UTF-8 中文会 SyntaxError) - QMT 函数线程约束:
get_trade_detail_data/passorder/cancel只能在策略线程调(缓存/队列方案);get_full_tick/subscribe_whole_quote/download_history_data可在 HTTP 线程调(实测) - 单账号: 桥天然单账号(QMT 一个策略=一个账号),HTTP 接口无 account 参数
- 字段差异: 大 QMT 订单行无
m_strStrategyName;m_strInstrumentID不带后缀 - K线: 查询前必须先下载;fields 传完整列表;DataFrame 用 iat 取值
- 错误格式:
{"detail":"..."}+ 4xx/5xx
迭代规范
每次迭代在 docs/迭代记录/ 定义设计文档,在 index.md 登记索引,记录完成情况。详见 docs/项目规范.md 第九节。
文档导航
| 文档 | 用途 |
|---|---|
docs/项目规范.md |
项目宪法: 结构/约束/部署/接口文档/迭代规范 |
docs/设计/整体设计方案_v3.md |
唯一设计依据(架构/环境调研/性能实测/变更记录) |
docs/api_spec/openapi.yaml |
接口规范唯一事实来源 |
docs/桥接口清单与sfgrid满足度对照.md |
sfgrid 需求 vs 桥能力 |
docs/迭代记录/index.md |
迭代索引 |
docs/研究/ |
调研文档 |
Description
Languages
Python
95.8%
PowerShell
3%
Batchfile
1.2%