🚀 AI 一键生成 qmt 策略代码

QMT 异常监控:如何通过代码判断资金账号是否断线并发送报警?

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

问题描述

如何监控 QMT 资金账号是否断线?

解决方案

在 QMT 中监控资金账号是否断线(或连接状态异常),主要有两种方式:

  1. 主动查询(轮询):在 handlebar 或定时器中调用 get_trade_detail_data 获取账号对象,检查其 m_strStatus 属性。
  2. 事件驱动(回调):使用 account_callback 回调函数,当账号状态发生变更时,系统会自动触发该函数。

通常建议结合使用这两种方式:使用回调函数实时捕获状态变化,同时在 handlebar 中定期检查以防止回调丢失或初始化时的状态确认。

以下是具体的实现代码示例:

QMT 资金账号断线监控策略代码

# -*- coding: gbk -*-
import time

def init(ContextInfo):
    # 1. 设置需要监控的资金账号和类型
    # 请将下面的账号替换为您实际的资金账号
    ContextInfo.accID = '6000000000' 
    # 账号类型:'STOCK' (股票), 'FUTURE' (期货), 'CREDIT' (两融), 'STOCK_OPTION' (期权)
    ContextInfo.accType = 'STOCK'
    
    # 2. 绑定账号,必须调用此函数才能接收回调和查询数据
    ContextInfo.set_account(ContextInfo.accID)
    
    # 设置一个定时器,每隔10秒检查一次账号状态(可选,作为双重保障)
    ContextInfo.run_time("check_account_status", "10nSecond", "2023-01-01 00:00:00", "SH")
    
    print(f"监控策略已启动,正在监控账号: {ContextInfo.accID}")

def handlebar(ContextInfo):
    # 可以在这里写策略逻辑,或者单纯用于驱动
    pass

def check_account_status(ContextInfo):
    """
    自定义函数:主动查询账号状态
    """
    # 获取账号详情数据
    # 参数:账号ID, 账号类型, 数据类型('account'代表查询账号资金/状态信息)
    account_list = get_trade_detail_data(ContextInfo.accID, ContextInfo.accType, 'account')
    
    if not account_list:
        print(f"警告:无法获取账号 {ContextInfo.accID} 的信息,可能已完全断开或未登录!")
        return

    for account_obj in account_list:
        # m_strStatus 是账号的状态字段
        status = account_obj.m_strStatus
        
        # 打印当前状态用于调试
        # 注意:不同券商返回的正常状态字符串可能不同,通常为 "ok", "0", "连接成功" 等
        # 建议先运行一次查看您的正常状态是什么
        # print(f"当前账号状态轮询: {status}")
        
        # 简单的异常判断逻辑 (根据实际情况调整判断条件)
        # 假设非 'ok' 且非 '连接成功' 即为异常
        if status not in ["ok", "连接成功", "0"]:
            print(f"【报警】账号 {ContextInfo.accID} 状态异常,当前状态: {status}")
            # 在这里可以添加发送邮件、微信推送或短信报警的逻辑
        else:
            # 状态正常,通常不需要频繁打印
            pass

def account_callback(ContextInfo, accountInfo):
    """
    系统回调函数:当资金账号状态发生变化时自动触发
    """
    # accountInfo 即为变化的账号对象
    new_status = accountInfo.m_strStatus
    acc_id = accountInfo.m_strAccountID
    
    print(f"【状态变更通知】账号 {acc_id} 状态发生变化 -> {new_status}")
    
    if new_status not in ["ok", "连接成功", "0"]:
        print(f"【严重警告】检测到账号断线或异常!")
        # 在这里添加报警逻辑

代码核心解析

  1. ContextInfo.set_account(account)

    • 这是最关键的一步。在 init 中必须调用,否则 get_trade_detail_data 查不到数据,且 account_callback 不会生效。
  2. get_trade_detail_data(..., 'account')

    • 该函数返回一个列表,包含 Account 对象。
    • 对象中的 m_strStatus 属性存储了当前的连接状态。
    • 注意:不同券商柜台返回的“正常”状态字符串可能不同(常见的有 "ok", "0", "连接成功", "登录成功")。建议首次运行时先打印该字段,确认您所在环境的正常状态值。
  3. account_callback(ContextInfo, accountInfo)

    • 这是 QMT 的标准回调接口。只要账号登录、断开、重连,该函数都会被立即调用,是监控断线最及时的手段。
  4. ContextInfo.run_time

    • 设置了一个定时任务(每10秒),用于主动轮询。这是一种防御性编程,防止回调函数因极端情况未触发,或者用于定期输出心跳日志。

常见问题 Q&A

Q: m_strStatus 返回的具体值有哪些?
A: 这取决于底层的柜台系统(CTP, O32, 恒生等)。

  • 正常情况:通常是 "ok", "0", "连接成功", "就绪"
  • 异常情况:通常是 "-1", "断开", "连接失败", "未登录", "error"
    建议:在代码中打印 print(account_obj.m_strStatus) 来观察实际返回值。

Q: 监控到断线后,我能在策略里自动重连吗?
A: 不能。QMT 的 Python API 主要用于策略逻辑和交易,资金账号的登录和连接通常由 QMT 客户端(底层 C++)管理。如果断线,通常需要人工检查网络或重新登录客户端。API 层面能做的是及时报警(如打印日志、发送通知),让交易员尽快介入。

Q: 这个策略需要一直开着吗?
A: 是的。您可以将此逻辑集成到您的主交易策略中,或者单独新建一个策略专门用于监控账号状态。如果是单独策略,建议使用“实盘模式”运行。