🚀 AI 一键生成 qmt 策略代码

QMT API 进阶:如何精细化管理两融账户的负债与担保品?

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

问题描述

怎样才能查询到我信用账户里每一笔融资负债的具体情况,比如是哪只股票,什么时候借的?还有担保品有哪些?

解决方案

在 QMT 中,查询信用账户(两融账户)的详细情况,主要使用以下两个专用 API 函数:

  1. get_debt_contract(accId):用于获取负债合约明细。通过这个函数,你可以遍历每一笔负债,获取其对应的证券代码、合约开仓日期(借款时间)、未还金额等详细信息。
  2. get_assure_contract(accId):用于获取担保品明细
    • 注意:通常用户的“担保品”指的是信用账户中持有的股票持仓。虽然 get_assure_contract 是专门的担保品接口,但有时使用 get_trade_detail_data 查询 'POSITION'(持仓)能获得更直观的持仓数量和市值信息。我在代码中会同时演示这两种方式。

核心代码实现

以下是一个完整的 Python 策略代码示例,它会在策略初始化时(init)查询并打印出你信用账户的所有负债详情和担保品持仓情况。

# -*- coding: gbk -*-
from PythonApi import *

def init(ContextInfo):
    # ---------------------------------------------------------
    # 1. 设置账户信息
    # 请将下面的 'YOUR_CREDIT_ACCOUNT' 替换为您实际的信用资金账号
    # ---------------------------------------------------------
    account_id = 'YOUR_CREDIT_ACCOUNT'
    account_type = 'CREDIT' # 账户类型:信用账户
    
    # 设置当前交易账号,用于后续交互
    ContextInfo.set_account(account_id)
    
    print("=" * 50)
    print(f"开始查询信用账户: {account_id}")
    print("=" * 50)

    # ---------------------------------------------------------
    # 2. 查询融资负债明细 (每一笔借款详情)
    # 使用接口: get_debt_contract
    # ---------------------------------------------------------
    print("【负债合约明细 (融资/融券详情)】")
    
    # 获取负债合约列表,返回的是 StkCompacts 对象列表
    debt_contracts = get_debt_contract(account_id)
    
    if not debt_contracts:
        print("当前无负债合约。")
    else:
        # 打印表头
        print(f"{'合约编号':<15} {'证券代码':<10} {'证券名称':<10} {'开仓日期':<10} {'合约类型':<10} {'未还金额':<12} {'未还数量':<10}")
        
        for debt in debt_contracts:
            # 提取对象属性 (参考 API 文档附录 6.4.7 StkCompacts)
            contract_id = debt.m_strCompactId       # 合约编号
            code = debt.m_strInstrumentID           # 证券代码
            name = debt.m_strInstrumentName         # 证券名称
            open_date = str(debt.m_nOpenDate)       # 开仓日期 (YYYYMMDD)
            unrepay_balance = debt.m_dUnRepayBalance # 未还金额
            unrepay_vol = debt.m_nRealCompactVol    # 未还数量
            
            # 判断合约类型 (48:融资, 49:融券)
            c_type_code = debt.m_eCompactType
            c_type_str = "融资" if c_type_code == 48 else ("融券" if c_type_code == 49 else str(c_type_code))

            print(f"{contract_id:<15} {code:<10} {name:<10} {open_date:<10} {c_type_str:<10} {unrepay_balance:<12.2f} {unrepay_vol:<10}")

    print("-" * 50)

    # ---------------------------------------------------------
    # 3. 查询担保品情况
    # 方式 A: 使用 get_assure_contract (获取担保合约明细)
    # ---------------------------------------------------------
    print("【担保品明细 (方式A: get_assure_contract)】")
    assure_contracts = get_assure_contract(account_id)
    
    if not assure_contracts:
        print("未查询到担保合约明细。")
    else:
        for assure in assure_contracts:
            # 参考 API 文档附录 6.4.8 StkSubjects
            print(f"代码: {assure.m_strInstrumentID}, 名称: {assure.m_strInstrumentName}")

    print("-" * 50)

    # ---------------------------------------------------------
    # 3. 查询担保品情况
    # 方式 B: 使用 get_trade_detail_data 查询持仓 (更常用,显示持仓量)
    # 信用账户里的持仓即为担保品
    # ---------------------------------------------------------
    print("【信用账户持仓 (方式B: 实际持仓作为担保品)】")
    positions = get_trade_detail_data(account_id, account_type, 'POSITION')
    
    if not positions:
        print("信用账户当前无持仓。")
    else:
        print(f"{'证券代码':<10} {'证券名称':<10} {'持仓数量':<10} {'最新市值':<12} {'持仓盈亏':<12}")
        for pos in positions:
            # 参考 API 文档附录 6.4.4 position 对象
            code = pos.m_strInstrumentID
            name = pos.m_strInstrumentName
            volume = pos.m_nVolume              # 当前持仓量
            market_value = pos.m_dMarketValue   # 市值
            profit = pos.m_dPositionProfit      # 持仓盈亏
            
            print(f"{code:<10} {name:<10} {volume:<10} {market_value:<12.2f} {profit:<12.2f}")

    print("=" * 50)

def handlebar(ContextInfo):
    # 本策略主要用于查询,逻辑写在 init 中运行一次即可
    pass

代码关键点解析

  1. get_debt_contract(account_id):

    • 这是查询负债的核心函数。
    • 返回的是一个对象列表,每个对象代表一笔合约。
    • 关键属性:
      • m_strInstrumentID: 股票代码(如 '600000.SH')。
      • m_nOpenDate: 借款时间(合约开仓日期),格式为整数 YYYYMMDD
      • m_dUnRepayBalance: 未还金额(负债金额)。
      • m_eCompactType: 合约类型,48 代表融资(借钱买股),49 代表融券(借股卖出)。
  2. get_assure_contract(account_id):

    • 这是官方提供的获取担保合约明细的接口。
    • 它返回的是担保品对象列表。
  3. get_trade_detail_data(..., 'POSITION'):

    • 在实际交易中,查询“担保品”通常等同于查询“信用账户里有哪些持仓”。
    • 使用通用的交易明细接口查询 POSITION(持仓),可以获得更详细的数据,如持仓数量、当前市值、浮动盈亏等,这通常是投资者更关心的数据。

如何运行

  1. 打开 QMT 的“模型研究”或“策略编辑器”。
  2. 新建一个 Python 策略。
  3. 将上述代码复制进去。
  4. 重要:将代码中的 'YOUR_CREDIT_ACCOUNT' 替换为你真实的信用资金账号(字符串格式)。
  5. 点击“运行”或“编译运行”。
  6. 在下方的“日志”或“输出”窗口中查看查询结果。

Q&A

Q: 为什么 get_debt_contract 返回的日期是数字?
A: QMT 底层 C++ 接口通常使用 int 类型(如 20231027)来表示日期。如果需要日期格式(如 2023-10-27),可以使用 Python 的字符串切片进行转换,例如 str(date)[:4] + '-' + str(date)[4:6] + '-' + str(date)[6:]

Q: 担保品和持仓有什么区别?
A: 在信用账户中,你买入的股票或转入的股票都充当担保品。因此,查询信用账户的持仓 (POSITION) 实际上就是在查询你当前拥有的担保品资产。

Q: 如何区分融资合约和融券合约?
A: 在 get_debt_contract 返回的对象中,检查 m_eCompactType 属性。如果是 48,则是融资合约;如果是 49,则是融券合约。