问题描述
解决方案
在 QMT 中实时监控两融(信用)账户的风险度,主要通过 get_trade_detail_data 接口获取账户详情,并读取其中的 维持担保比例 (m_dPerAssurescaleValue) 或 实时风险度 (m_dRealRiskDegree) 字段来实现。
通常情况下,券商关注的核心指标是 维持担保比例(例如低于 130% 会触发追保)。
实现思路
- 初始化 (
init):设置两融账号 ID,并使用set_account绑定账号以接收推送。 - 实时监控 (
handlebar):- 判断是否为最新 K 线(
is_last_bar),确保只在实时行情下运行。 - 调用
get_trade_detail_data获取'CREDIT'类型的'ACCOUNT'数据。 - 提取
m_dPerAssurescaleValue(维持担保比例)。
- 判断是否为最新 K 线(
- 报警逻辑:
- 设定一个阈值(例如 1.4,即 140%)。
- 如果当前比例低于阈值,触发报警(打印日志、在图表上显示文字,或者通过 Python 的
winsound发出声音)。
策略代码
# -*- coding: gbk -*-
import time
def init(ContextInfo):
# 1. 设置两融账号 (请替换为您实际的信用账号)
ContextInfo.accid = '8800000001'
# 2. 绑定账号,确保能获取到实时交易数据
ContextInfo.set_account(ContextInfo.accid)
# 3. 设置风险阈值
# 维持担保比例阈值,例如 1.4 代表 140%
# 通常 150% 为警戒线,130% 为追保线
ContextInfo.risk_threshold = 1.4
# 设置报警冷却时间(秒),防止每个tick都报警
ContextInfo.last_alert_time = 0
ContextInfo.alert_interval = 60
print("两融风险监控策略已启动,监控账号:{}".format(ContextInfo.accid))
def handlebar(ContextInfo):
# 只在实时行情(最后一根K线)运行,避免回测历史数据时触发
if not ContextInfo.is_last_bar():
return
# 获取信用账户详情
# 参数:账号ID, 账号类型('CREDIT'), 数据类型('ACCOUNT')
acct_info_list = get_trade_detail_data(ContextInfo.accid, 'CREDIT', 'ACCOUNT')
if not acct_info_list:
print("未获取到账户信息,请检查账号是否登录或类型是否正确")
return
# 取第一个账户对象 (通常只有一个)
account = acct_info_list[0]
# 获取维持担保比例
# 注意:不同券商返回的数值单位可能不同,有的是百分比(1.5),有的是数值(150)
# 请根据实际返回值调整 ContextInfo.risk_threshold
weibao_ratio = account.m_dPerAssurescaleValue
# 获取总资产和总负债(用于辅助显示)
total_asset = account.m_dAssureAsset # 净资产
total_debit = account.m_dTotalDebit # 总负债
# --- 监控逻辑 ---
# 打印当前状态 (可选,用于调试)
# print(f"当前维保比例: {weibao_ratio:.2f}, 净资产: {total_asset}, 总负债: {total_debit}")
# 检查是否低于阈值
if weibao_ratio > 0 and weibao_ratio < ContextInfo.risk_threshold:
current_time = time.time()
# 检查冷却时间
if current_time - ContextInfo.last_alert_time > ContextInfo.alert_interval:
msg = "【风险报警】账号 {} 维持担保比例过低!当前值: {:.2f}% (阈值: {:.2f}%)".format(
ContextInfo.accid, weibao_ratio * 100, ContextInfo.risk_threshold * 100
)
# 1. 输出到日志
print(msg)
# 2. 在图表左上角显示红色报警文字
ContextInfo.draw_text(True, 0, msg)
# 3. (可选) 发出系统蜂鸣声报警 (仅限Windows本地运行)
try:
import winsound
winsound.Beep(1000, 1000) # 频率1000Hz,持续1秒
except:
pass
ContextInfo.last_alert_time = current_time
else:
# 风险正常时,在图表显示绿色状态
info_str = "两融监控运行中 | 维保比例: {:.2f}%".format(weibao_ratio * 100)
ContextInfo.draw_text(True, 0, info_str)
代码关键点说明
get_trade_detail_data参数:- 第二个参数必须是
'CREDIT',表示信用账户。 - 第三个参数是
'ACCOUNT',表示获取资金/账户层面的数据。
- 第二个参数必须是
- 关键字段
m_dPerAssurescaleValue:- 这是信用账户特有的字段,代表个人维持担保比例。
- 计算公式通常为:(现金 + 信用证券账户内证券市值总和) / (融资买入金额 + 融券卖出证券数量 × 当前市价 + 利息及费用)。
- 报警频率控制:
handlebar在实时行情下会随 Tick 数据高频触发。代码中增加了last_alert_time和alert_interval,确保报警不会刷屏(例如每 60 秒报一次)。
- 运行模式:
- 请在 “实盘” 模式下运行此策略。
- 请确保 QMT 交易端已登录对应的两融账号。
常见问题 (Q&A)
Q: 为什么获取到的 weibao_ratio 是 0?
A: 如果账户没有负债(没有融资或融券),维持担保比例通常显示为 0 或一个极大的数值(取决于券商柜台系统)。代码中加入了 weibao_ratio > 0 的判断来过滤这种情况。
Q: 如何发送邮件或短信报警?
A: QMT 的 Python 环境支持标准库。你可以引入 smtplib 发送邮件,或者使用 requests 库调用第三方的短信/钉钉/飞书 Webhook 接口。将发送逻辑放在代码中 # 1. 输出到日志 的位置即可。
Q: m_dRisk 和 m_dPerAssurescaleValue 用哪个?
A: m_dRisk 是通用风险度(通常是 冻结/可用),而两融业务最核心的监管指标是 维持担保比例 (m_dPerAssurescaleValue)。建议优先使用维持担保比例。