🚀 AI 一键生成 qmt 策略代码

QMT量化平台如何正确获取委托号?get_last_order_id与passorder深度解析

qmt | 发布时间: 2026/5/27
以下内容由 EasyQuant 生成。

问题描述

请问get_last_order_id的使用场景是什么?

我用passorder下单后,立即使用get_last_order_id,获取到的一定就是当前订单的委托号吗?如果是,为什么不在passorder直接返回?还可以减少一次请求互动,如果不一定。那么该如何正确的使用get_last_order_id?
还请赐教,谢谢。

解决方案

这是一个非常深入且切中QMT交易机制核心的问题。要理解这个问题,首先需要明白QMT底层的异步交易架构

1. 为什么 passorder 不直接返回委托号?

QMT 的下单指令发送是**异步(Asynchronous)**的。当你调用 passorder 时,Python 策略只是将“下单请求”发送给了 QMT 的底层 C++ 交易引擎,交易引擎再将请求发送给券商柜台或交易所。

在这个瞬间,柜台还没有处理这笔订单,真实的委托号(OrderSysID)还没有生成。因此,passorder 无法在调用的那一刻同步返回一个还不存在的委托号。它只能返回“无”(或者说执行完毕),代表请求已成功发出。

2. 下单后立即调用 get_last_order_id,获取的一定是当前订单吗?

不一定。 存在以下两种风险:

  1. 时间差(延迟)风险:因为是异步的,你刚执行完 passorder,下一行代码立刻执行 get_last_order_id,此时柜台可能还没返回委托号。你获取到的可能是上一次下单的旧委托号,或者是 -1(未找到)。
  2. 并发风险:如果你同时运行了多个策略,或者进行了批量下单,多个订单几乎同时发出。你获取到的“最新委托号”可能是其他策略刚刚生成的委托号,导致订单错乱。

3. 如何正确使用 get_last_order_id

为了解决上述问题,QMT 提供了两种正确获取委托号的机制:

方法一:使用 strategyName 参数进行策略隔离(主动轮询法)

passorderget_last_order_id 中,都有一个可选参数 strategyName(策略名)。通过指定一个唯一的策略名,你可以过滤掉其他策略的干扰。

正确用法示例:

def init(ContextInfo):
    ContextInfo.accid = '6000000248'
    ContextInfo.my_strategy_name = 'MyMACD_Strategy_001'

def handlebar(ContextInfo):
    # 1. 下单时传入自定义的 strategyName
    passorder(23, 1101, ContextInfo.accid, '000001.SZ', 5, -1, 100, ContextInfo.my_strategy_name, 1, 'user_order_id_123', ContextInfo)
    
    # 2. 获取时,同样传入这个 strategyName
    # 注意:由于异步,最好在后续的逻辑中(或稍微等待后)去获取,而不是紧挨着下一行
    order_id = get_last_order_id(ContextInfo.accid, 'stock', 'order', ContextInfo.my_strategy_name)
    if order_id != '-1':
        print(f"获取到策略 {ContextInfo.my_strategy_name} 的最新委托号: {order_id}")

方法二:使用交易回报实时主推函数(最佳实践)

在实盘/模拟环境中,最推荐、最稳妥的做法是不去主动调用 get_last_order_id,而是利用 QMT 的事件驱动回调机制。当订单在柜台生成委托号或状态发生变化时,系统会自动调用 order_callback

正确用法示例:

def init(ContextInfo):
    ContextInfo.set_account('6000000248')
    ContextInfo.my_strategy_name = 'MyMACD_Strategy_001'

def handlebar(ContextInfo):
    # 下单时带上 strategyName 和 userOrderId(投资备注)
    passorder(23, 1101, '6000000248', '000001.SZ', 5, -1, 100, ContextInfo.my_strategy_name, 1, 'order_001', ContextInfo)

# 当委托状态变化时,系统自动触发此函数
def order_callback(ContextInfo, orderInfo):
    # orderInfo.m_strRemark 中包含了你下单时传入的 strategyName 和 userOrderId
    if ContextInfo.my_strategy_name in orderInfo.m_strRemark:
        # 直接从回调对象中获取真实的委托号
        real_order_id = orderInfo.m_strOrderSysID
        status = orderInfo.m_nOrderStatus
        print(f"收到属于本策略的委托回报!委托号: {real_order_id}, 状态: {status}")

总结

  • get_last_order_id 的使用场景主要是在简单的单策略环境中,或者在需要主动查询最新一笔订单状态时使用,必须配合 strategyName 参数以防串单。
  • 因为 QMT 是异步交易passorder 无法同步返回委托号。
  • 强烈建议在实盘中使用 order_callbackdeal_callback 来被动接收委托号和成交信息,这是最严谨、最高效的量化工程实践。