🚀 AI 一键生成 qmt 策略代码

使用 account_callback 实时追踪融资融券账户风险度 (m_dRisk)

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

问题描述

如何实时监控两融账户的风险度并在风险过高时报警?

解决方案

在 QMT 中实时监控两融(信用)账户的风险度,主要通过 get_trade_detail_data 接口获取账户详情,并读取其中的 维持担保比例 (m_dPerAssurescaleValue)实时风险度 (m_dRealRiskDegree) 字段来实现。

通常情况下,券商关注的核心指标是 维持担保比例(例如低于 130% 会触发追保)。

实现思路

  1. 初始化 (init):设置两融账号 ID,并使用 set_account 绑定账号以接收推送。
  2. 实时监控 (handlebar)
    • 判断是否为最新 K 线(is_last_bar),确保只在实时行情下运行。
    • 调用 get_trade_detail_data 获取 'CREDIT' 类型的 'ACCOUNT' 数据。
    • 提取 m_dPerAssurescaleValue(维持担保比例)。
  3. 报警逻辑
    • 设定一个阈值(例如 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)

代码关键点说明

  1. get_trade_detail_data 参数
    • 第二个参数必须是 'CREDIT',表示信用账户。
    • 第三个参数是 'ACCOUNT',表示获取资金/账户层面的数据。
  2. 关键字段 m_dPerAssurescaleValue
    • 这是信用账户特有的字段,代表个人维持担保比例
    • 计算公式通常为:(现金 + 信用证券账户内证券市值总和) / (融资买入金额 + 融券卖出证券数量 × 当前市价 + 利息及费用)。
  3. 报警频率控制
    • handlebar 在实时行情下会随 Tick 数据高频触发。代码中增加了 last_alert_timealert_interval,确保报警不会刷屏(例如每 60 秒报一次)。
  4. 运行模式
    • 请在 “实盘” 模式下运行此策略。
    • 请确保 QMT 交易端已登录对应的两融账号。

常见问题 (Q&A)

Q: 为什么获取到的 weibao_ratio 是 0?
A: 如果账户没有负债(没有融资或融券),维持担保比例通常显示为 0 或一个极大的数值(取决于券商柜台系统)。代码中加入了 weibao_ratio > 0 的判断来过滤这种情况。

Q: 如何发送邮件或短信报警?
A: QMT 的 Python 环境支持标准库。你可以引入 smtplib 发送邮件,或者使用 requests 库调用第三方的短信/钉钉/飞书 Webhook 接口。将发送逻辑放在代码中 # 1. 输出到日志 的位置即可。

Q: m_dRiskm_dPerAssurescaleValue 用哪个?
A: m_dRisk 是通用风险度(通常是 冻结/可用),而两融业务最核心的监管指标是 维持担保比例 (m_dPerAssurescaleValue)。建议优先使用维持担保比例。