一、背景:MiniQMT 退出舞台,旧策略怎么办?
在上一篇 《网传 MiniQMT 将被关闭?事实核查与应对指南(2026 版)》 里已经说过:自 2026 年 7 月起,多家券商已陆续收紧 MiniQMT 权限,存量客户大概率会在 1~2 个月内被清退,本地原生 Python + xtquant 直连模式即将成为历史。
但现实是:大多数个人量化的策略代码已经跑了很多年——指标计算、信号判断、行情订阅都依赖 xtquant,迁移成本极高。重写一遍不仅费时,还容易把原本稳定的策略写崩。
那有没有办法既不放弃 MiniQMT 端成熟的策略代码,又能把”真实下单”放到合规的大 QMT 里跑?答案是:HTTP 桥接。
二、方案核心思想:分析在 miniQMT,下单在大 QMT
把整个交易流程拆成两段:
| 角色 | 职责 | 运行环境 |
|---|---|---|
| QMT 外 python端 | 用python 代码计算指标、产生信号、通过 HTTP 发起下单 | Python |
| 大 QMT 端 | 起一个 HTTP 服务,接收下单/撤单/查询请求,在 QMT 主线程通过 passorder 执行 |
大 QMT 模型交易沙箱 |
这样做的好处非常明显:
- ✅ 策略代码 90% 不用动:指标、信号、风控逻辑继续留在 python 跑
- ✅ 下单走合规通道:所有
passorder都在大 QMT 内执行,不触碰”外接系统”红线 - ✅ 行情双通道:miniQMT 本地
xtdata仍可作主源,大 QMT HTTP 作 fallback - ✅ 平滑过渡:MiniQMT 真正停用那天,只需把”分析”也迁到大 QMT,桥接代码可保留复用
三、架构总览
1 | +----------------------+ +----------------------+ |
关键设计点:
- 下单/撤单走任务队列 + 200ms 定时器消费:避免 HTTP 线程直接调
passorder的多线程风险(QMT 交易 API 不保证线程安全) - 查询/行情直接在 HTTP 线程读取本地缓存:
get_full_tick/get_trade_detail_data是只读本地缓存,可安全跨线程调用 - HTTP 服务用 daemon 线程:策略停止时自动退出,不留僵尸进程
四、部署步骤
4.1 大 QMT 端(qmt_http_server.py)
- 打开大 QMT 客户端 → 模型交易 → 新建策略,把
qmt_http_server.py内容粘贴进去 - 在右侧设置:
- 资金账号:选择已登录的实盘/模拟账号(先用模拟账号验证!)
- 运行模式:实盘模式
- 周期:随意(本策略不依赖 K 线)
- 启动策略,输出框看到以下两行即服务就绪:
1 | [Bridge] HTTP server started on 0.0.0.0:8899 |
4.2 外部 python 端(miniqmt_client.py)
- 编辑
miniqmt_client.py,确认QMT_HTTP_HOST指向大 QMT 所在机器:
1 | QMT_HTTP_HOST = 'http://127.0.0.1:8899' # 跨机时改大 QMT 的实际 IP |
- 把
miniqmt_client.py复制到策略目录 - python 客户端 → 策略列表 → 新建策略 → 选择本文件 → 运行
- 看到以下输出即桥接打通:
1 | [Bridge] 大 QMT 已连接,account=XXX |
五、代码详解
5.1 大 QMT 端:HTTP 服务 + 任务队列
qmt_http_server.py 的核心是三件事:
- 在
init钩子里启动 daemon HTTP 线程 + 注册 200ms 定时器 - HTTP Handler 接收请求:下单/撤单进队列,查询/行情直接返回
consume_tasks定时器回调:在策略主线程从队列取出任务调passorder
下面是关键代码片段:
启动 HTTP 服务 + 定时器(init 钩子)
1 | def init(ContextInfo): |
下单入队(HTTP 线程,不做真实下单)
1 | def _handle_order(self, body): |
定时器消费任务(主线程,安全调 passorder)
1 | def consume_tasks(ContextInfo): |
为什么必须用队列 + 定时器,不能直接在 HTTP 线程里调 passorder?
passorder 是 QMT 客户端交易主线程的同步调用,从其他线程直接调可能导致:
- 委托号错乱
- 客户端崩溃
- 柜台连接断开
QMT 官方文档明确要求:所有交易相关 API 必须在策略主线程调用。所以最稳的做法是 HTTP 线程只入队,主线程定时器出队执行。
5.2 miniQMT 端:策略 + HTTP 客户端封装
miniqmt_client.py 提供了一个 QMTClient 类,把所有 HTTP 调用封装成 Python 方法,使用起来就像本地 API:
1 | class QMTClient: |
策略主循环(miniQMT 端演示)
1 | def on_strategy_tick(ContextInfo): |
行情双通道(重点)
miniQMT 端取行情有两种方式,互为补充:
1 | def _get_ticks(codes): |
策略代码里这一段是迁移的核心红利——MiniQMT 真正停用后,把方式 A 注释掉,方式 B 自动接管,几乎零修改就能继续跑。
六、HTTP 接口文档
所有响应均为 JSON。
| 路径 | 方法 | 用途 |
|---|---|---|
/ping |
GET | 健康检查,返回 account / accountType |
/quote?code=A,B,C |
GET | 取最新 tick 快照(多码逗号分隔) |
/quote |
POST | body: {"codes": ["A","B"]},同上 |
/position |
GET | 查询持仓(get_trade_detail_data) |
/order |
GET | 查询当日委托 |
/deal |
GET | 查询当日成交 |
/account |
GET | 查询账号资金 |
/query |
POST | body: {"type":"position|order|deal|account"} |
/order |
POST | 下单(入队,200ms 内消费) |
/cancel |
POST | 撤单(入队,200ms 内消费) |
下单 /order 的 body 字段
必填:
| 字段 | 类型 | 说明 |
|---|---|---|
opType |
int | 23=股票买 24=股票卖 0=期货开多 …(见枚举速查) |
orderType |
int | 1101=按数量 1102=按金额 |
orderCode |
str | '000001.SZ' / 'rb2401.SF' 等 |
prType |
int | 5=最新价 11=指定价 14=对手价 42=市价 |
price |
float | prType=11/49 时填具体价格,其余填 0 |
volume |
float | 股数 / 手数 / 金额(视 orderType 而定) |
可选:
| 字段 | 类型 | 说明 |
|---|---|---|
accountid |
str | 不填则用策略配置的账号 |
strategyName |
str | 策略名,用于区分不同来源的委托 |
quickTrade |
int | 默认 2(立即下单,定时器场景必须用 2);0=K 线结束触发 1=最新 K 线触发 2=立即触发 |
userOrderId |
str | 投资备注,用于后续查询/匹配委托 |
下单响应:
1 | {"ok": true, "msg": "order queued", "queued": 3} |
queued = 当前队列里还没消费的任务数。
撤单 /cancel 的 body 字段
| 字段 | 类型 | 说明 |
|---|---|---|
orderId |
str | 必填,委托号 |
accountid |
str | 可选,不填用默认账号 |
accountType |
str | 可选,'STOCK'/'FUTURE'/'CREDIT' 等 |
行情 /quote 响应字段(get_full_tick 返回)
1 | { |
持仓 /position 字段(节选)
| 字段 | 含义 |
|---|---|
m_strInstrumentID |
证券代码 |
m_strExchangeID |
市场 |
m_nVolume |
持仓量 |
m_nCanUseVolume |
可用数量 |
m_dOpenPrice |
成本价 |
m_dInstrumentValue |
市值 |
m_dPositionCost |
持仓成本 |
m_dPositionProfit |
持仓盈亏 |
账号 /account 字段(节选)
| 字段 | 含义 |
|---|---|
m_dBalance |
总资产 |
m_dAssureAsset |
净资产 |
m_dInstrumentValue |
总市值 |
m_dTotalDebit |
总负债 |
m_dAvailable |
可用金额 |
m_dPositionProfit |
持仓盈亏 |
七、常用枚举速查
opType(操作类型)
| 值 | 含义 | 值 | 含义 |
|---|---|---|---|
| 23 | 股票买入 | 24 | 股票卖出 |
| 0 | 期货开多 | 3 | 期货开空 |
| 2 | 期货平今多 | 5 | 期货平今空 |
| 33 | 两融担保品买入 | 34 | 两融担保品卖出 |
| 27 | 融资买入 | 28 | 融券卖出 |
| 50 | 期权买入开仓 | 51 | 期权卖出平仓 |
| 60 | ETF 申购 | 61 | ETF 赎回 |
prType(价格类型)
| 值 | 含义 |
|---|---|
| 5 | 最新价 |
| 11 | 指定价(必须填 price) |
| 14 | 对手价 |
| 42 | 市价(沪市有保护限价) |
| 49 | 五档即时剩转限 |
八、可调参数(qmt_http_server.py 顶部)
| 参数 | 默认值 | 说明 |
|---|---|---|
HTTP_HOST |
'0.0.0.0' |
监听网卡;只本机访问改 '127.0.0.1' |
HTTP_PORT |
8899 |
HTTP 端口 |
CONSUME_INTERVAL_MS |
200 |
任务消费周期(毫秒),越小越实时 |
MAX_BATCH_PER_TICK |
20 |
定时器单次最多消费任务数 |
九、安全 / 风险注意事项
9.1 务必先用模拟账号验证
qmt_http_server.py 默认 quickTrade=2(立即下单),任何能访问该端口的请求都会真实下单。生产环境务必:
- (a)
HTTP_HOST改成'127.0.0.1',只允许本机访问 - (b) 或在内网用 nginx + basic auth 反代
- (c) 或在 miniQMT 端的
QMTClient里统一加X-Token鉴权 header
9.2 价格笼子(2% 规则)
沪深主板/创业板委托价超出基准价 ±2% 会废单,下单前最好自查 price 是否在笼子内。
9.3 委托数量上限
| 板块 | 限价单上限 |
|---|---|
| 主板 | 100 万股 |
| 创业板 | 30 万股 |
| 科创板 | 10 万股 |
超量会产生废单。
9.4 废单查询延迟
下单后约 50ms~6s 才能通过 /order 接口查到(柜台推送周期),不要在 200ms 内反复查询。
9.5 策略阻塞
qmt_http_server.py 的 HTTP 线程是 daemon,策略停止时自动退出;定时器 200ms 周期不会阻塞其他策略。
9.6 GBK 编码
三个 .py 文件本身是 GBK 编码(QMT 内置 Python 3.6 的硬性要求)。如果在 macOS/Linux 编辑器里中文乱码,请用支持 GBK 的编辑器(VS Code、Notepad++)打开。
十、常见问题 FAQ
Q1:启动报 Address already in use?
A:端口 8899 被占。改 HTTP_PORT 或杀掉占用进程。
Q2:miniQMT 端 ping 返回 error?
A:大 QMT 端策略未启动 / 防火墙拦截 / IP 错。先在大 QMT 本机跑 test_client.py 验证本地服务。
Q3:行情返回空 / lastPrice=0?
A:大 QMT 客户端右下角行情源未选「五档」级别;或非交易时段。
Q4:下单后 /position 查不到新持仓?
A:柜台推送有 50ms~6s 延迟,等几秒再查;委托状态先查 /order。
Q5:想做鉴权?
A:在 qmt_http_server.py 的 QMTHandler.do_GET/do_POST 里加 header 校验(如 X-Token),或者在 miniQMT 端的 QMTClient 里统一加 header。
十一、源代码下载
完整源代码(含 qmt_http_server.py、miniqmt_client.py、README.py)已打包上传至夸克网盘:
下载后按本文第四节的部署步骤操作即可。三个文件均为 GBK 编码,可直接在 QMT 编辑器中打开。
十二、写在最后:迁移路径建议
这套 HTTP 桥接方案的本质,是给老策略争取了一段**”过渡期”**:
1 | [阶段 1] miniQMT 还能用 → 分析 + 下单都在 miniQMT(旧代码不动) |
到了阶段 3,QMTClient 这个类仍然有用——把它的 _post 方法替换成对大 QMT 本地 passorder 的直接调用,上层策略代码(信号、风控、订单管理)一行都不用改。
这才是这套设计真正的价值:让迁移成本分摊到多年,而不是被迫在一个周末里全部重写。
⚠️ 风险提醒与免责声明
量化交易涉及真实资金风险。本文仅提供 MiniQMT 到大 QMT 迁移的代码方案与技术分享:
- 文中代码仅供学习参考,不构成任何投资建议
- 任何策略在实盘前必须先在 QMT「模拟信号模式」或「模拟柜台」中充分验证
quickTrade=2是立即下单模式,端口暴露在公网会导致真实资金损失- 因使用本文代码、文档或建议造成的任何盈亏,由使用者自行承担全部责任
- QMT、迅投 为迅投公司或其关联公司的商标
本文更新于2026年8月16日