🚀 AI 一键生成 qmt 策略代码
立即体验

QMT 平台如何配置毫秒级与秒级定时任务?run_time 定时器高频监控详解

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

问题描述

QMT 毫秒级定时任务:run_time 函数的高频监控与配置
QMT的run_time定时器可以支持毫秒级的时间间隔吗?如何配置秒级或更小周期的定时任务?

解决方案

QMT 毫秒级定时任务:run_time 函数的高频监控与配置详解

在量化交易中,高频监控和定时任务是实现算法交易、盘口监控以及快速撤单重开等逻辑的核心。QMT 平台提供了强大的定时器函数 ContextInfo.run_time(),支持毫秒级秒级以及天级的时间间隔配置。本文将详细介绍如何使用该函数配置高频定时任务。


1. run_time 函数基础语法

ContextInfo.run_time 用于在策略运行期间注册自定义的回调函数,使其按照设定的时间间隔循环执行。

接口定义

ContextInfo.run_time(funcName, period, startTime, market)

参数说明

  • funcName (string): 注册的回调函数名称(需以字符串形式传入)。
  • period (string): 重复调用的时间间隔。格式为 "数值n单位"。支持的单位包括:
    • nMilliSecond: 毫秒(例如 "500nMilliSecond" 表示每 500 毫秒执行一次)。
    • nSecond: 秒(例如 "5nSecond" 表示每 5 秒执行一次)。
    • nDay: 天(例如 "1nDay" 表示每 1 天执行一次)。
  • startTime (string): 定时器第一次启动的时间,格式为 "YYYY-MM-DD HH:MM:SS"。如果希望定时器立刻启动,可以设置一个历史时间(如 "2019-10-14 13:20:00")。
  • market (string): 市场简称代码(如 "SH""SZ"),用于对齐交易日历。

注意:在回测模式下,run_time() 定时器没有实际意义,该函数主要用于实盘/模拟盘运行模式


2. 如何配置不同周期的定时任务?

2.1 毫秒级定时任务(高频监控)

若需要进行盘口毫秒级监控,可以将单位设置为 nMilliSecond。例如,每 500 毫秒执行一次回调:

ContextInfo.run_time("my_callback", "500nMilliSecond", "2020-01-01 00:00:00", "SH")

2.2 秒级定时任务

若需要进行秒级轮询(如每 5 秒检查一次未成交委托),可以将单位设置为 nSecond

ContextInfo.run_time("my_callback", "5nSecond", "2020-01-01 00:00:00", "SH")

2.3 天级定时任务

若需要每日定时执行(如每日收盘后清理变量或初始化),可以使用 nDay

ContextInfo.run_time("my_callback", "1nDay", "2020-01-01 15:30:00", "SH")

3. Python 策略源码示例

以下是一个完整的 QMT 策略示例。该策略在初始化时注册了一个每 500 毫秒执行一次的高频监控任务,以及一个每 5 秒执行一次的资金账户检查任务。

#coding:gbk
import time

def init(ContextInfo):
    # 设定交易账号
    ContextInfo.account_id = "6000000248"
    ContextInfo.set_account(ContextInfo.account_id)
    
    # 1. 注册毫秒级定时器:每 500 毫秒执行一次盘口监控
    ContextInfo.run_time("high_frequency_monitor", "500nMilliSecond", "2020-01-01 09:30:00", "SH")
    
    # 2. 注册秒级定时器:每 5 秒检查一次账户资金与持仓
    ContextInfo.run_time("account_check", "5nSecond", "2020-01-01 09:30:00", "SH")
    
    print("策略初始化完成,定时器已注册。")

def handlebar(ContextInfo):
    # 主图 K 线驱动逻辑(如日线或分钟线)
    pass

# 毫秒级回调函数:高频监控盘口
def high_frequency_monitor(ContextInfo):
    # 获取最新分笔数据
    tick_data = ContextInfo.get_full_tick(['600000.SH'])
    if '600000.SH' in tick_data:
        data = tick_data['600000.SH']
        # 打印最新价与买一/卖一价
        print(f"[高频监控 500ms] 浦发银行最新价: {data['lastPrice']}, 买一: {data['bidPrice'][0]}, 卖一: {data['askPrice'][0]}")

# 秒级回调函数:检查账户可用资金
def account_check(ContextInfo):
    acct_info = get_trade_detail_data(ContextInfo.account_id, 'STOCK', 'ACCOUNT')
    if acct_info:
        for acc in acct_info:
            print(f"[账户检查 5s] 账号: {acc.m_strAccountID}, 可用资金: {acc.m_dAvailable:.2f} 元")

4. 核心注意事项

  1. 避免阻塞:由于定时器(尤其是毫秒级高频定时器)执行频率极高,回调函数内部的代码必须保持极度轻量。避免在回调中进行复杂的循环计算、大批量历史数据请求或同步网络 I/O 操作,否则会导致界面卡顿或信号延迟。
  2. 实盘有效性run_time 定时器仅在实盘运行模拟盘运行模式下生效。在历史 K 线回测中,定时器不会被触发。
  3. 多线程安全:QMT 的 Python 引擎在执行回调时,需注意全局变量的读写保护,避免高频并发写入导致数据冲突。