问题描述
请问下 内置qmt中
smart_algo_passorder 和algo_passorder 这两种下单模式 会设置时间区间, 当触发这种下单函数,
比如用的smart_algo_passorder[size=1.35] 中的VWAP算法, 开始时间10点25,结束时间14点25,请问下 这样整个程序在这个时间段还能往下执行吗,这个下单函数会占用线程么 谢谢前辈们 帮回答下
解决方案
明确的回答是:不会占用(阻塞)线程,您的程序在这个时间段内会继续往下执行。
原理解析
在 QMT 平台中,所有的下单函数(包括普通的 passorder,以及算法交易的 algo_passorder 和 smart_algo_passorder)都是异步非阻塞的。
当您在 Python 策略代码中调用 smart_algo_passorder 并设置了 VWAP 算法及时间区间(如 10:25 到 14:25)时,实际发生的过程如下:
- 提交任务:Python 层面只是将这个“算法交易任务”及其参数(算法类型、时间区间、总量等)打包,发送给 QMT 底层的 C++ 算法交易引擎。
- 立即返回:任务提交成功后,该函数会立即返回,Python 线程不会停留在该函数上等待订单执行完毕。您的代码会立刻执行该函数后面的下一行代码。
- 底层独立执行:QMT 底层的算法交易引擎会在后台接管这个任务,并在您设定的时间区间(10:25 - 14:25)内,根据 VWAP 逻辑自动进行拆单、挂单、撤单等操作。这个过程与您的 Python 策略运行是完全分离的。
- 策略继续驱动:您的 Python 策略依然会随着行情的 tick 或 bar 的推送,继续正常触发
handlebar函数。
注意事项与建议
正因为它是非阻塞且立即返回的,您在编写策略时必须特别注意防止重复下单。
如果您的下单逻辑写在 handlebar 中,且没有状态控制,那么在 10:25 到 14:25 期间,每一个 tick 行情到来都会触发一次 handlebar,从而导致您向底层发送了无数个 VWAP 算法任务,这会造成严重的重复下单甚至爆仓。
正确的做法是使用全局变量(如 ContextInfo 的自定义属性)来记录是否已经下过单:
def init(ContextInfo):
# 初始化一个标志位,记录今天是否已经提交过算法任务
ContextInfo.has_ordered = False
def handlebar(ContextInfo):
# 只在最新行情下运行
if not ContextInfo.is_last_bar():
return
# 获取当前时间
tick_time = ContextInfo.get_tick_timetag()
current_time = timetag_to_datetime(tick_time, '%H%M%S')
# 假设触发条件:时间到达 10:25 且尚未下单
if current_time >= '102500' and not ContextInfo.has_ordered:
# 提交 VWAP 算法任务
smart_algo_passorder(
23, 1101, '您的资金账号', '000001.SZ', 5, -1, 10000,
'my_vwap_strategy', 1, 'vwap_order_01',
'VWAP', 20, 0, 0, '10:25:00', '14:25:00', ContextInfo
)
print("已提交 VWAP 算法任务,底层引擎开始执行...")
# 标记为已下单,防止后续 tick 重复提交
ContextInfo.has_ordered = True
# 这里的代码会立刻执行,不会被 smart_algo_passorder 阻塞
# print("程序继续执行...")
总结:您可以放心地使用算法下单函数,它们只是向系统派发了一个定时/定量的任务,完全不会卡住您的 Python 策略线程。