核心思想与流程总览
这种架构的核心是 “产销分离” 模型:
- 聚宽(JoinQuant) 作为信号生产者,专注于策略逻辑运算和信号生成。
- QMT(迅投) 作为信号消费者,专注于接收信号并执行极速交易。
- 两者通过一个中间桥梁进行通信,实现解耦。
整个流程的本质是:聚宽“投递”信号,QMT“领取”并执行信号。作者微信:xms_quants1
作者微信:xms_quants1
作者微信:xms_quants1

使用的教程https://gitee.com/quants/big_qmt_joinquant_trader
方案一:服务器API方式 (推荐用于生产环境)
核心原理
此方式引入一个自建的信号中继服务器作为“调度中心”。聚宽和QMT不直接对话,而是通过这个中心服务器进行标准的HTTP请求和响应。这是一种服务化的架构,定义了清晰的接口。
详细流程与角色分工
第一步:信号投递 (聚宽 → 服务器)
信号生成:聚宽平台的策略在满足条件时,在内存中生成一个结构化的交易信号对象。
- 信号封装:聚宽将此信号对象封装成一个标准的HTTP POST请求的载荷(通常是JSON格式)。这个载荷包含了所有必要的交易指令信息。
- 发送请求:聚宽作为一个HTTP客户端,将这个请求发送到您预先部署好的信号服务器的特定API地址(例如
/api/v1/signal)。
- 服务器处理:
- 接收与验证:信号服务器接收到请求后,首先会验证数据的完整性和合法性。
- 风控拦截(可选):服务器可以内置简单的风控逻辑,对信号进行初步过滤(如单笔金额过大、频率过高等),若触犯规则则拒绝接收并返回错误。
- 持久化存储:验证通过后,服务器将这个信号存入后端数据库的一个表中,并将该信号的初始状态标记为“待处理”。
第二步:信号领取与执行 (QMT → 服务器)
- 定时轮询:在您本地运行的QMT程序中,一个专门的执行脚本会启动一个无限循环,以很高的频率(如每秒一次)向信号服务器的另一个API地址(例如
/api/v1/pending_signals)发送HTTP GET请求,询问是否有状态为“待处理”的新信号。
- 服务器响应:服务器接收到QMT的查询请求后,会从数据库查询所有“待处理”的信号,并将其打包返回给QMT。
- QMT解析与执行:QMT收到响应后,解析出信号列表。然后,它遍历这个列表,对于每一个信号,调用QMT内置的、与券商柜台直连的交易API,将信号转化为真实的委托订单发送至交易所。
- 状态更新与确认:
- 一旦QMT确认订单已成功发送(并非完全成交),它会立即再次调用服务器的另一个API(例如
PATCH /api/v1/signal/{id}),将对应信号的状态从“待处理”更新为“已执行”或“已发送”。
- 这个状态更新机制至关重要,它确保了同一个信号不会被QMT重复领取和执行,实现了信号的一次性消费。
方案二:数据库直连方式 (简单直接)
核心原理
此方式省去了中间的API服务器,让聚宽和QMT直接操作同一个共享数据库。这个数据库表充当了一个“公告板”或“任务队列”。聚宽向公告板上“贴任务”(写入记录),QMT从公告板上“撕任务”(读取并更新记录)。
详细流程与角色分工
第一步:信号投递 (聚宽 → 数据库)
- 信号生成:同API方式,聚宽策略生成交易信号。
- 直接连接:聚宽通过数据库驱动程序(如pymysql)直接连接到位于云上的共享数据库。
- 插入记录:聚宽执行一条SQL
INSERT 语句,将信号作为一条新记录直接写入数据库的指定信号表中。在插入时,会显式地将该记录的状态字段设置为“pending”(待处理)。
第二步:信号领取与执行 (QMT → 数据库)
- 定时轮询:QMT的执行脚本同样启动一个循环,但它是通过数据库驱动程序直接连接到共享数据库。
- 查询与锁定:在每一次循环中,QMT执行一条SQL
SELECT 语句,查询所有状态为“pending”的信号。这里存在一个技术关键点:为了防止多个消费者(如果有)同时处理同一个信号,高级的实现会使用数据库的行锁或“乐观锁”机制。一个简单实用的方法是,QMT在查询后立即执行一条 UPDATE 语句,将查到的信号状态立刻改为“processing”(处理中),然后再执行下单动作。
- 执行下单:QMT调用其交易API进行下单。
- 最终状态确认:下单操作完成后(无论成功或失败),QMT会再次执行
UPDATE 语句,将信号状态最终更新为“executed”(已执行)或“failed”(失败),并可能记录失败原因。
两种方案对比总结
服务器API方式:
对于大多数严肃的量化交易应用,推荐使用服务器API方式,因为它提供了更好的可控性、安全性和可维护性。数据库直连方式则适用于对延迟极度敏感、且技术团队能够妥善处理并发问题的场景。 |