3 分钟快速生成代码
输入想法,AI 即刻生成可运行代码
在 QMT 或 miniqmt (xtquant) 的委托失败回调(如 on_order_error 或 orderError_callback)中,理论上是可以调用查询接口的,但强烈不建议直接在回调函数中进行同步的资产和持仓查询。这通常是你测试“没反应”或卡死的主要原因。
query_stock_asset),可能会阻塞该线程,甚至与底层通信机制产生死锁,导致程序无响应。为了避免阻塞回调线程,最佳实践是:在回调函数中仅记录失败的委托信息(放入队列),然后在主线程或专门的业务线程中消费这些信息,并进行资产查询和状态重置。
import time
import threading
import queue
from xtquant import xtdata
from xtquant.xttrader import XtQuantTrader, XtQuantTraderCallback
from xtquant.xttype import StockAccount
# 创建一个线程安全的队列,用于存放失败的委托
error_order_queue = queue.Queue()
class MyTraderCallback(XtQuantTraderCallback):
def on_order_error(self, error):
# 回调中只做最简单的操作:将错误信息放入队列
print(f"[回调] 收到委托失败回报: {error.order_remark}, 错误信息: {error.error_msg}")
error_order_queue.put(error)
def process_error_orders(trader, account):
"""
专门处理失败委托的线程函数
"""
while True:
try:
# 阻塞等待队列中的错误委托,超时时间1秒
error_order = error_order_queue.get(timeout=1.0)
print(f"[处理线程] 开始处理失败委托: {error_order.order_sysid}")
# 稍微等待一下,确保柜台资金已解冻
time.sleep(0.5)
# 在这里进行资产查询
asset = trader.query_stock_asset(account)
if asset:
print(f"[处理线程] 当前可用资金: {asset.cash}")
# 在这里执行你的资金重置或重新下单逻辑
# reset_my_strategy_fund(error_order, asset.cash)
except queue.Empty:
continue
except Exception as e:
print(f"[处理线程] 处理异常: {e}")
if __name__ == '__main__':
# 初始化 trader 和 account (此处省略具体的初始化路径和账号)
path = r'D:\国信证券QMT交易端\userdata_mini'
session_id = int(time.time())
trader = XtQuantTrader(path, session_id)
account = StockAccount('你的资金账号')
callback = MyTraderCallback()
trader.register_callback(callback)
trader.start()
trader.connect()
trader.subscribe(account)
# 启动专门处理错误委托的后台线程
processor_thread = threading.Thread(target=process_error_orders, args=(trader, account))
processor_thread.daemon = True
processor_thread.start()
# 保持主线程运行
while True:
time.sleep(1)
on_order_error 或 orderError_callback 中直接调用 query_stock_asset 或 get_trade_detail_data。queue.Queue 将回调数据传递给主线程或独立的工作线程。