问题描述
我今天没法查询成交信息,每次运行 xt_trader.query_stock_trades(ID)都会卡住,xt_trader.query_stock_orders(ID) 查委托信息就没有问题
解决方案
在 QMT (迅投) 平台中使用 xt_trader.query_stock_trades(ID) 查询成交信息时遇到卡住(阻塞)的情况,而 query_stock_orders 正常,通常是由以下几个原因引起的。以下是详细的排查步骤和解决方案:
1. 检查是否在回调函数中调用了同步查询(最常见原因)
原因分析:QMT 的底层 C++ 接口在处理回调(如 on_stock_trade, on_stock_order 等)时,通常是在一个独立的底层线程中运行的。如果你在这些回调函数内部直接调用了同步查询接口(如 query_stock_trades),极易引发线程死锁,导致程序完全卡住。
解决方案:
- 绝对不要在任何
on_xxx回调函数中调用同步查询接口。 - 如果必须在回调中处理数据,请将数据推送到一个队列(如 Python 的
queue.Queue)中,由主线程或其他独立线程去消费队列并执行查询。
2. 改用异步查询接口 (Async Query)
原因分析:同步查询接口会阻塞当前线程直到服务器返回数据。如果当天成交数据量极大,或者券商柜台响应缓慢,同步接口可能会长时间阻塞甚至假死。
解决方案:使用异步查询接口 query_stock_trades_async,该接口会立即返回一个请求序号(seq),当数据准备好后,会通过回调函数 on_query_trades_async_response 返回结果,从而避免阻塞主线程。
异步查询代码示例:
from xtquant import xttrader
from xtquant.xttype import StockAccount
import time
class MyXtQuantTraderCallback(xttrader.XtQuantTraderCallback):
def on_query_trades_async_response(self, data):
print("异步查询成交返回:")
for trade in data:
print(f"成交编号: {trade.traded_id}, 证券代码: {trade.stock_code}, 成交数量: {trade.traded_volume}")
# 初始化 trader
path = r'D:\国信证券QMT交易端\userdata_mini'
session_id = int(time.time())
xt_trader = xttrader.XtQuantTrader(path, session_id)
# 注册回调
callback = MyXtQuantTraderCallback()
xt_trader.register_callback(callback)
# 启动并连接
xt_trader.start()
xt_trader.connect()
acc = StockAccount('你的资金账号')
# 发起异步查询
seq = xt_trader.query_stock_trades_async(acc)
print(f"已发起异步查询,请求序号: {seq}")
# 保持主线程存活等待回调
time.sleep(5)
3. 券商柜台或 QMT 客户端异常
原因分析:由于 query_stock_orders 正常,说明连接是通的。但有时券商柜台的特定查询接口(如成交查询)可能会因为日内结算、系统压力等原因出现短暂的无响应。
解决方案:
- 重启 QMT 客户端:关闭 QMT 终端并重新登录,清理底层可能卡死的连接状态。
- 重启 Python 脚本:终止当前 Python 进程,重新建立 Session 连接。
- 避开高峰期:如果在刚开盘或收盘结算期间频繁查询,可能会遇到阻塞,建议增加查询间隔。
4. 检查 QMT 终端日志
如果上述方法无效,建议打开 QMT 客户端的安装目录,进入 userdata_mini\log 或 userdata\log 文件夹,查看最新的 xttrader.log 或客户端日志,搜索是否有 timeout 或 error 相关的报错信息,这有助于定位是否是底层网络请求超时。