🚀 AI 一键生成 qmt 策略代码

QMT 算法交易:使用 `pause_task` 与 `cancel_task` 管理运行中的任务

qmt | 发布时间: 2025/12/22
以下内容由 EasyQuant 生成。

问题描述

如何用代码暂停或撤销算法交易任务?

解决方案

在 QMT 平台中,暂停或撤销算法交易任务主要依赖于 pause_task(暂停)和 cancel_task(撤销)这两个 API 函数。

要操作一个任务,通常需要先获取当前账号下的任务列表,拿到具体的 任务编号 (m_nTaskId),然后针对该编号执行操作。

以下是详细的代码实现和说明。

核心步骤

  1. 获取任务列表:使用 get_trade_detail_data 函数,数据类型设为 'TASK',获取当前账号的所有任务对象。
  2. 提取任务 ID:遍历返回的任务对象列表,获取 m_nTaskId
  3. 执行操作:调用 pause_taskcancel_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_taskcancel 有什么区别?
A: cancel 是用于撤销普通的委托订单(Order),通常是针对具体的某一笔挂单。而 cancel_task 是用于撤销算法交易任务(Task),一个算法任务可能会生成多笔具体的委托订单。撤销任务通常意味着停止该算法策略的后续执行。

Q: 为什么调用了函数返回 True,但任务没有立即停止?
A: 函数返回 True 仅代表指令发送成功。服务器处理请求、更新状态以及回传信息需要极短的时间。建议在下一轮 handlebar 或通过 get_trade_detail_data 再次查询确认状态是否已变更。