经常被问同一件事:券商那边只给了大 QMT,没有 miniQMT / XtQuantServer,我原来写好的外部 Python 脚本还能不能跑?
能跑。但要先分清你缺的到底是哪一样东西 —— 是「本机调不通接口」,还是「策略想继续留在聚宽」。这两个问题的答案完全不一样,选错路会白折腾一两周。这篇是工程选型记录,不构成投资建议,也不代操盘。
一、先说结论:三条路各自适合谁
- 路一 · 自建本机 HTTP 桥:只要几个接口(查行情、对持仓、看资金),代码面想自己控。最轻,半小时能起。
- 路二 · 用 cfquant 这类开源桥:你已经有成套的
xtquant 写法,想尽量不改代码就接到大 QMT。功能全,但要接受它的模式约束。
- 路三 · 策略不搬,只把信号接到本机:策略仍在聚宽模拟盘跑,只有委托指令落到本机 QMT。适合不想重写策略的人。
三条路不互斥。很多人是先用路三把链路跑通,再按需要补路一或路二。
二、为什么「把策略全塞回编辑器」往往不是答案
最直觉的做法是把外部脚本整段搬进 QMT 自带的编辑器。但 QMT 内置 Python 大约是 3.6.8,你研究环境里的依赖(新版 pandas、各种第三方包)大多装不进去,还有券商侧的包白名单。
于是真正的问题变成:怎么让「编辑器里那份能跑的代码」和「你熟悉的外部 Python」只交换数据,而不是交换代码。三条路都是在回答这个问题。
三、路一:在大 QMT 里起本机 HTTP 桥(最小可跑)
QMT 内置 Python 自带 tornado,不用再装 FastAPI。监听地址固定 127.0.0.1,令牌写文件、不要写进策略正文。
路由别一次铺几十个,先三个就够对账:健康检查、分笔、资金持仓。
POST /health —— 确认桥还活着
POST /v1/quote/tick —— 包一层 get_full_tick
POST /v1/account/book —— 包一层 get_trade_detail_data(POSITION / ACCOUNT)
取分笔时代码后缀上交所用 .SH。如果返回空 dict,先查后缀和全推权限,别急着怀疑桥写错了 —— 这类空值多数是权限或后缀问题,排查顺序见 https://www.kimiquant.cn/problems/qmt-no-realtime-tick
持仓字段仍是 m_dAvailable、m_nVolume 那一套。打印出来对账用,不要直接当调仓指令。完整写法(含 tornado 路由、token 校验、外部客户端)在这页:https://www.kimiquant.cn/problems/qmt-local-http-bridge
四、那个必踩的坑:init 里 IOLoop.start() 会卡死 handlebar
这是自建桥最常见的翻车点,而且现象很迷惑人:桥起来了、HTTP 也能访问,但策略日志再也不刷新,像死了一样。
原因:有人在 init 里直接写 IOLoop.current().start()。这一句会占住当前线程,handlebar 再也不进。
正确做法是把 IOLoop 丢到后台线程跑:
t = threading.Thread(target=start_bridge, args=(C,))
t.daemon = True
t.start()
然后留一句心跳日志,比如在 handlebar 里 print("[bridge] handlebar still alive")。以后只要看到这句还在刷,就说明桥没有阻塞策略主循环 —— 这个自检比任何文档都管用。
五、路二:cfquant —— 把大 QMT 桥成接近 miniQMT 的写法
如果你手上已经是一整套 xtquant.xtdata / XtQuantTrader 的代码,只想「换个执行端、代码尽量不动」,那就该看开源桥而不是自己手搓。
cfquant(MIT,GitHub 95ge/cfquant)做的就是这件事:大 QMT 里加载桥接入口,外面继续按接近 miniQMT 的习惯调行情、查询、下单。它自带一个本机 Web 控制台,用来做通道检测、绑定、调试和版本回滚。
它有三种模式,选择逻辑很简单:
- 通用模式(
CFQUANT_CTYPE_ALL_LOWLAT.py):默认。单账号、常规环境先跑通它。
- 极致模式(
CFQUANT_LITE.py):券商 QMT 有包导入白名单、通用入口导不进去时用(例如部分君弘君智环境)。
- 高级模式:要再压下单延迟,且你能开两个不同的 QMT。注意它不能在同一个 QMT 里和普通桥同时挂。
不确定就先通用模式。别一上来冲高级模式 —— 模式互斥这条踩了会白忙。
选型对比(cfquant / 本站信号同步 / 自建桥三者的差别)在这页:https://www.kimiquant.cn/notes/cfquant-miniqmt-bridge
六、路三:策略不搬,只把信号接到本机
如果你的策略在聚宽上已经调好、不想重写,那真正要搬的只有委托指令:聚宽模拟盘里发出的 order 系列调用,转成你本机 QMT 的 passorder。
这条路的代价最小 —— 研究代码一行不改,只多一层中转。但要接受两个前提:
- 本机得有一台常开的机器挂着执行端,关机就断。
- 中转的延迟取决于档位。免费档是约 5 秒一轮的轮询(每天 20 条、1 个策略);付费档才是约 0.05 秒一轮,发信号到下单常见落在几十到一百多毫秒。想要秒级以内就必须用付费档,这点别搞混。
入口和档位说明:https://www.kimiquant.cn/tools/signal
七、怎么选:先问自己三个问题
- 我的策略代码在哪?在聚宽 → 路三;在自己机器上 → 路一或路二。
- 我要的是几个接口,还是一整套 xtquant 兼容?几个 → 路一;一整套 → 路二。
- 我能不能开第二个 QMT / 有没有包白名单?会决定路二里你能用哪个模式。
三个问题答完,路基本就定了。剩下的都是工程细节。
八、边界(务必看)
(整理这些接口笔记时我常用 WorkBuddy 辅助,贴报错、对着 API 排错比翻手册快,有兴趣可以看看:https://workbuddy.ai/invite?code=66L9RNCT )