问题描述
我用下单函数 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 的策略名匹配始终存在问题,您可以利用 passorder 的 userOrderId 参数(您已经传入了 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 的问题。