🚀 AI 一键生成 qmt 策略代码

QMT API 实战:使用 pause_task 和 resume_task 动态管理算法交易

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

问题描述

在量化交易中,如何通过代码来暂停和恢复一个正在执行的算法单?

解决方案

在 QMT 量化交易平台中,算法单(如拆单、智能算法交易)被系统视为“任务”(Task)。要暂停或恢复一个正在执行的算法单,需要使用 pause_taskresume_task 函数。

这两个操作的核心前提是必须先获取到该算法单对应的 任务编号(taskId)

以下是具体的实现步骤和代码示例。

核心函数说明

  1. 获取任务信息get_trade_detail_data(accountID, accountType, 'task')
    • 用于获取当前账号下的所有任务对象,从中提取 m_nTaskId(任务ID)和 m_eStatus(任务状态)。
  2. 暂停任务pause_task(taskId, accountId, accountType, ContextInfo)
    • 将指定 ID 的运行中任务挂起。
  3. 恢复任务resume_task(taskId, accountId, accountType, ContextInfo)
    • 将指定 ID 的已暂停任务重新启动。

完整代码示例

以下策略代码展示了如何遍历当前账号下的所有任务,找到正在运行的任务进行暂停,或找到已暂停的任务进行恢复。

# -*- coding: gbk -*-

def init(ContextInfo):
    # 设置资金账号
    ContextInfo.accid = '6000000248'
    # 设置账号类型:'STOCK'股票, 'FUTURE'期货, 'CREDIT'信用
    ContextInfo.accType = 'STOCK'
    
    # 绑定账号(接收回报必须)
    ContextInfo.set_account(ContextInfo.accid)
    
    print("策略初始化完成,准备管理算法任务...")

def handlebar(ContextInfo):
    # 获取当前账号下的所有任务列表
    # 第三个参数 '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_RUNNING(执行中), TASK_STATUS_PAUSE(暂停)
        # 注意:这里直接打印状态数值或描述,具体枚举值需参考文档附录
        task_status = task_obj.m_eStatus
        
        print(f"发现任务 -> ID: {task_id}, 状态: {task_status}, 说明: {task_obj.m_strMsg}")

        # --- 示例逻辑:暂停所有正在运行的任务 ---
        # 假设 TASK_STATUS_RUNNING 对应的状态码通常表示运行中(具体需结合实际返回值判断)
        # 这里演示如何调用暂停函数
        # 实际使用时,建议根据 task_id 或 task_obj.m_strMsg 来筛选特定任务
        
        # 演示:暂停指定任务
        # pause_task(task_id, ContextInfo.accid, ContextInfo.accType, ContextInfo)
        # print(f"已发送暂停指令: 任务ID {task_id}")

        # --- 示例逻辑:恢复所有已暂停的任务 ---
        # 演示:恢复指定任务
        # resume_task(task_id, ContextInfo.accid, ContextInfo.accType, ContextInfo)
        # print(f"已发送恢复指令: 任务ID {task_id}")

    # 为了防止在回测或实盘中频繁触发,这里仅作演示,实际逻辑请配合条件判断使用
    return

# 封装一个自定义函数,方便在策略其他地方直接调用暂停
def my_pause_specific_task(ContextInfo, target_task_id):
    """
    根据任务ID暂停特定任务
    """
    pause_task(target_task_id, ContextInfo.accid, ContextInfo.accType, ContextInfo)
    print(f"调用暂停函数: {target_task_id}")

# 封装一个自定义函数,方便在策略其他地方直接调用恢复
def my_resume_specific_task(ContextInfo, target_task_id):
    """
    根据任务ID恢复特定任务
    """
    resume_task(target_task_id, ContextInfo.accid, ContextInfo.accType, ContextInfo)
    print(f"调用恢复函数: {target_task_id}")

注意事项

  1. taskId 的获取taskId 是系统生成的唯一标识字符串或数字。必须通过 get_trade_detail_data 获取对象后读取 m_nTaskId 属性。
  2. 批量操作:如果 pause_taskresume_tasktaskId 参数传为空字符串或特定空值(视具体版本实现而定,通常建议传具体ID),可能会影响该账号下所有可操作的任务,请谨慎使用。建议始终传入具体的 taskId
  3. 状态确认:发出暂停或恢复指令后,任务状态不会立即改变(涉及网络交互)。建议在下一轮 handlebar 或通过 get_trade_detail_data 再次查询确认状态是否已更新。
  4. 区别于撤单
    • pause_task:暂停算法,未成交的委托可能保留或撤销(取决于算法具体逻辑),任务本身还在,可以恢复。
    • cancel_task:撤销任务,任务彻底结束,不可恢复。

Q&A

Q: pause_taskcancel_task 有什么区别?
A: pause_task 是暂时停止算法的执行,后续可以通过 resume_task 继续运行,进度通常会保留;而 cancel_task 是彻底终止任务,相当于删除了这个算法单,无法恢复,如果需要继续交易必须重新下单。

Q: 如何判断任务当前是“运行中”还是“已暂停”?
A: 通过 get_trade_detail_data 获取任务对象后,检查 m_eStatus 属性。通常在 QMT 的枚举定义中,TASK_STATUS_RUNNING 代表执行中,TASK_STATUS_PAUSE 代表暂停。

Q: 为什么调用了 resume_task 后任务没有立即恢复?
A: 这是一个异步操作。指令发送给服务器后需要处理时间。此外,如果账户资金不足、持仓不足或触发了风控限制,即使调用了恢复函数,任务也可能无法实际继续执行,建议检查日志输出或 orderError_callback 回调。