问题描述
解决方案
在 QMT 平台中,暂停或撤销算法交易任务主要依赖于 pause_task(暂停)和 cancel_task(撤销)这两个 API 函数。
要操作一个任务,通常需要先获取当前账号下的任务列表,拿到具体的 任务编号 (m_nTaskId),然后针对该编号执行操作。
以下是详细的代码实现和说明。
核心步骤
- 获取任务列表:使用
get_trade_detail_data函数,数据类型设为'TASK',获取当前账号的所有任务对象。 - 提取任务 ID:遍历返回的任务对象列表,获取
m_nTaskId。 - 执行操作:调用
pause_task或cancel_task。
完整策略代码示例
# -*- coding: gbk -*-
def init(ContextInfo):
# 设置资金账号,请修改为您实际的资金账号
ContextInfo.accid = '6000000248'
# 设置账号类型,如 'STOCK' (股票), 'FUTURE' (期货)
ContextInfo.accType = 'STOCK'
print("策略初始化完成,准备检查任务状态...")
def handlebar(ContextInfo):
# 获取当前账号下的所有任务信息
# 参数说明:账号ID, 账号类型, 数据类型('TASK')
task_list = get_trade_detail_data(ContextInfo.accid, ContextInfo.accType, 'TASK')
if not task_list:
print("当前没有查询到任何算法任务。")
return
for task_obj in task_list:
# 获取任务 ID
task_id = task_obj.m_nTaskId
# 获取任务状态 (具体状态码定义见文档附录)
task_status = task_obj.m_eStatus
# 获取任务备注/消息
task_msg = task_obj.m_strMsg
print(f"发现任务 -> ID: {task_id}, 状态: {task_status}, 说明: {task_msg}")
# ==============================================================================
# 场景 1: 暂停任务
# ==============================================================================
# 假设我们要暂停所有正在运行的任务 (TASK_STATUS_RUNNING 通常对应状态码,需根据实际情况判断)
# 这里演示无条件暂停所有任务
is_paused = pause_task(task_id, ContextInfo.accid, ContextInfo.accType, ContextInfo)
if is_paused:
print(f"任务 {task_id} 暂停指令发送成功")
else:
print(f"任务 {task_id} 暂停指令发送失败")
# ==============================================================================
# 场景 2: 撤销任务
# ==============================================================================
# 如果需要撤销任务,使用 cancel_task
# 注意:通常暂停和撤销不会同时对同一个任务执行,这里仅作代码演示
# is_cancelled = cancel_task(task_id, ContextInfo.accid, ContextInfo.accType, ContextInfo)
# if is_cancelled:
# print(f"任务 {task_id} 撤销指令发送成功")
# ==============================================================================
# 场景 3: 批量操作 (快捷方式)
# ==============================================================================
# 如果 taskId 传入空字符串 '',则表示对该账号下所有可操作的任务进行批量操作
# 批量暂停所有任务
# pause_task('', ContextInfo.accid, ContextInfo.accType, ContextInfo)
# 批量撤销所有任务
# cancel_task('', ContextInfo.accid, ContextInfo.accType, ContextInfo)
函数详解
1. 暂停任务 pause_task
- 用法:
pause_task(taskId, accountId, accountType, ContextInfo) - 参数:
taskId: 任务编号。如果传入空字符串'',表示暂停该账号下所有可暂停的任务。accountId: 资金账号。accountType: 账号类型(如'STOCK','FUTURE')。ContextInfo: 全局对象。
- 返回:
bool(True 表示发送成功,False 表示失败)。
2. 撤销任务 cancel_task
- 用法:
cancel_task(taskId, accountId, accountType, ContextInfo) - 参数:
taskId: 任务编号。如果传入空字符串'',表示撤销该账号下所有可撤销的任务。accountId: 资金账号。accountType: 账号类型。ContextInfo: 全局对象。
- 返回:
bool(True 表示发送成功,False 表示失败)。
3. 继续任务 resume_task
如果任务被暂停后需要恢复,可以使用此函数。
- 用法:
resume_task(taskId, accountId, accountType, ContextInfo) - 逻辑: 与暂停类似,传入空字符串可批量恢复。
Q&A
Q: 如何判断任务当前的状态(是运行中还是已暂停)?
A: 通过 get_trade_detail_data 获取任务对象后,访问 m_eStatus 属性。虽然文档中未直接列出所有枚举值的数字对应关系,但通常可以通过打印该值观察。一般情况下,运行中、暂停、已完成等状态会有不同的整数值。
Q: cancel_task 和 cancel 有什么区别?
A: cancel 是用于撤销普通的委托订单(Order),通常是针对具体的某一笔挂单。而 cancel_task 是用于撤销算法交易任务(Task),一个算法任务可能会生成多笔具体的委托订单。撤销任务通常意味着停止该算法策略的后续执行。
Q: 为什么调用了函数返回 True,但任务没有立即停止?
A: 函数返回 True 仅代表指令发送成功。服务器处理请求、更新状态以及回传信息需要极短的时间。建议在下一轮 handlebar 或通过 get_trade_detail_data 再次查询确认状态是否已变更。