问题描述
照着文档写了一个 passorder 下单函数。函数虽然能编译,跑策略实盘时,无法在持仓,委托里面找到它。
我面试过手动下单,它是可以成功的。
请问是哪里错了,还是受限了?
手动下单的记录,没有函数跑下单的记录。
#encoding:gbk
import pandas as pd
import numpy as np
import talib
def init(ContextInfo):
pass
def handlebar(ContextInfo):
'''passorder(23,1101,'2034878','002564.SZ',5,-1,100,ContextInfo)'''
order_lots('002564.SZ', 1, ContextInfo, '2034870')
print("已下单")
解决方案
你好!在 QMT 平台中,新手遇到 passorder 或 order_lots 函数调用后无反应(没有委托记录)是非常常见的情况。根据你提供的代码和 QMT 的运行机制,主要有以下几个原因导致了这个问题:
1. 致命原因:QMT 的“次日下单”机制(运行周期问题)
根据 QMT 官方文档,QMT 的模型是逐 K 线运行的。默认情况下,交易函数(如 order_lots 或默认参数的 passorder)在当前 K 线产生信号后,会在下一根 K 线的第一个 tick 才发出真实的下单指令。
如果你是在日线周期下运行这个策略,今天产生的信号,默认要等到明天开盘才会真正报单。这就是为什么你今天看不到任何委托记录的原因。
解决方法:
使用 passorder 函数,并将 quickTrade 参数设置为 1 或 2,强制立即下单。
2. 逻辑漏洞:缺少 is_last_bar 判断导致被风控拦截
在你的 handlebar 函数中,没有任何条件判断直接调用了下单函数。QMT 在启动时会先计算历史 K 线,然后再接收实时 tick。如果不加限制,你的策略会在每一根历史 K 线和盘中的每一个 tick 都疯狂发送下单指令。这极大概率会触发 QMT 或券商的风控系统,导致委托被直接拦截(废单或拒绝)。
3. 运行模式的区别:编辑器“运行” vs “模型交易”实盘
如果你只是在【策略编辑器】界面点击了“运行”按钮,这只是模拟运行模式,它只会在图表上画出信号,绝对不会向柜台发送真实的委托。要进行真实交易,必须将策略加入到【模型交易】面板,并将运行模式切换为“实盘”。
正确的代码示例
为了解决上述问题,请参考以下修改后的代码。我们使用了 passorder 并开启了 quickTrade=2(立即下单),同时加入了必要的条件判断:
#encoding:gbk
import pandas as pd
import numpy as np
# 增加一个全局变量,防止重复下单
has_ordered = False
def init(ContextInfo):
# 1. 建议在 init 中绑定资金账号
ContextInfo.set_account('2034870')
global has_ordered
has_ordered = False
def handlebar(ContextInfo):
global has_ordered
# 2. 必须加上 is_last_bar 判断,确保只在最新行情下触发,不在历史K线上疯狂下单
if not ContextInfo.is_last_bar():
return
# 3. 增加一个简单的防重发逻辑(实际策略中应替换为你的买卖条件,如均线金叉等)
if not has_ordered:
# 4. 使用 passorder,并设置 quickTrade 参数为 2 (立即触发下单)
# passorder 参数顺序: opType, orderType, accountid, orderCode, prType, price, volume, strategyName, quickTrade, userOrderId, ContextInfo
# 23: 股票买入, 1101: 单股单账号普通股/手下单, 5: 最新价
passorder(23, 1101, '2034870', '002564.SZ', 5, -1, 100, 'MyStrategy', 2, 'TestOrder', ContextInfo)
print("已发送立即下单指令")
has_ordered = True # 标记已下单,防止下一个 tick 再次买入
排查清单(Checklist)
如果使用上述代码仍然无法下单,请检查以下几点:
- 账号是否正确:确认
'2034870'是你当前登录且有资金的真实资金账号。 - 是否在实盘模块运行:确保你是在【模型交易】界面添加了该策略,并且状态是“运行中”,模式是“实盘”。
- 查看日志输出:在 QMT 底部的“日志输出”或“交易日志”中,查看是否有红色的报错信息(如“资金不足”、“不在交易时间”、“风控拦截”等)。
- 价格类型:代码中使用的是
5(最新价),如果当时该股票涨停或停牌,最新价下单可能会失败,可以尝试改为11(指定价)并传入具体价格测试。