问题描述
解决方案
在 QMT 中监控资金账号是否断线(或连接状态异常),主要有两种方式:
- 主动查询(轮询):在
handlebar或定时器中调用get_trade_detail_data获取账号对象,检查其m_strStatus属性。 - 事件驱动(回调):使用
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"【严重警告】检测到账号断线或异常!")
# 在这里添加报警逻辑
代码核心解析
-
ContextInfo.set_account(account):- 这是最关键的一步。在
init中必须调用,否则get_trade_detail_data查不到数据,且account_callback不会生效。
- 这是最关键的一步。在
-
get_trade_detail_data(..., 'account'):- 该函数返回一个列表,包含
Account对象。 - 对象中的
m_strStatus属性存储了当前的连接状态。 - 注意:不同券商柜台返回的“正常”状态字符串可能不同(常见的有
"ok","0","连接成功","登录成功")。建议首次运行时先打印该字段,确认您所在环境的正常状态值。
- 该函数返回一个列表,包含
-
account_callback(ContextInfo, accountInfo):- 这是 QMT 的标准回调接口。只要账号登录、断开、重连,该函数都会被立即调用,是监控断线最及时的手段。
-
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: 是的。您可以将此逻辑集成到您的主交易策略中,或者单独新建一个策略专门用于监控账号状态。如果是单独策略,建议使用“实盘模式”运行。