🚀 AI 一键生成 qmt 策略代码

QMT 调用 get_last_order_id() 带策略名参数返回 -1 怎么办?

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

问题描述

我想用get_last_order_id()获取某个策略的最后一笔委托号,却返回-1

我用下单函数 passorder(23, 1102, C.account, i, 3, 0, 1000, f'趋势_{name}', 2, f'趋势_{name}', C)成交了一笔(其中:i 是的值'159915.SZ',name 的值是'创业板 ETF')

用 orderid = get_last_order_id(C.accid, 'stock', 'order')能正确返回委托号

但加上策略名参数后,orderid = get_last_order_id(C.accid, 'stock', 'order', '趋势_创业板 ETF'),就返回-1,不能正确返回委托号了,是哪里的问题呢?

解决方案

在 QMT 平台中,get_last_order_id() 返回 -1 代表没有找到符合条件的委托记录。既然您不带策略名参数时能正确返回委托号,说明委托本身是成功生成的,问题出在 strategyName(策略名)的字符串匹配上。

导致加上策略名后返回 -1 的原因通常有以下几点,请逐一排查:

1. 全角符号、空格与底层 GBK 编码问题(最可能的原因)

QMT 的底层是 C++,且 Python 策略脚本默认要求使用 #coding:gbk 编码。在您的代码中,策略名是 f'趋势_{name}'(即 '趋势_创业板 ETF')。

  • 全角下划线:您使用的是全角下划线 _ 而不是半角下划线 _
  • 空格创业板 ETF 中间包含了一个空格。

原因:中文字符、全角符号以及空格在 Python 传递给 QMT 底层 C++ 接口时,可能会因为 GBK 编码转换或底层字符串截断机制导致实际存储的 strategyName 发生了变化。当您用 '趋势_创业板 ETF' 去查询时,底层匹配不上,从而返回 -1

解决方法:强烈建议 strategyName 只使用纯英文、数字和半角下划线。例如:

# 下单时
strategy_name = 'trend_159915'
passorder(23, 1102, C.account, i, 3, 0, 1000, strategy_name, 2, strategy_name, C)

# 查询时
orderid = get_last_order_id(C.accid, 'stock', 'order', strategy_name)

2. 字符串不完全一致

请检查 name 变量的实际值。如果 name 的值带有不可见字符(如换行符 \n、首尾多余的空格等),f'趋势_{name}' 格式化出来的结果可能并不是您手动输入的 '趋势_创业板 ETF'。可以使用 print(repr(f'趋势_{name}')) 打印出来确认一下。

3. 本地客户端生命周期限制

根据 QMT 官方 API 文档说明:

strategyName 只对同账号本地客户端有效,即 strategyName 只对当前客户端下的单进行策略区分,且该策略区分只能当前客户端使用。

如果您在下单后重启了 QMT 客户端,或者在另一个独立的策略进程中去查询,strategyName 的映射关系可能会丢失,导致查询不到返回 -1


💡 终极替代方案:通过 userOrderId (投资备注) 遍历获取

如果您必须使用中文作为标识,或者 get_last_order_id 的策略名匹配始终存在问题,您可以利用 passorderuserOrderId 参数(您已经传入了 f'趋势_{name}')。

userOrderId 会被记录在委托对象的 m_strRemark(投资备注)属性中。您可以通过 get_trade_detail_data 获取所有委托,然后自行过滤:

def get_my_last_order_id(ContextInfo, account, target_remark):
    # 获取该账号的所有委托记录
    order_list = get_trade_detail_data(account, 'stock', 'order')
    
    # 倒序遍历(从最新委托开始找)
    for order in reversed(order_list):
        # 匹配投资备注 (m_strRemark 对应 passorder 的 userOrderId)
        if order.m_strRemark == target_remark:
            return order.m_strOrderSysID # 返回委托号
            
    return '-1'

# 使用示例
def handlebar(ContextInfo):
    target_name = '趋势_创业板 ETF'
    # 假设已经下单...
    
    # 自定义函数获取
    orderid = get_my_last_order_id(ContextInfo, ContextInfo.accid, target_name)
    print(f"获取到的委托号: {orderid}")

总结建议:先尝试将 strategyName 改为纯英文+半角下划线测试,通常能直接解决返回 -1 的问题。