🚀 AI 一键生成 qmt 策略代码

QMT 融资融券:使用 `query_credit_opvolume` 查询最大可买数量

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

问题描述

两融账号如何查询最大可买数量?

解决方案

在 QMT 平台中,查询两融(信用)账号的最大可买数量不能简单地通过资金除以价格计算,因为涉及到保证金比例、授信额度等复杂因素。

QMT 提供了专门的异步查询函数 query_credit_opvolume 配合回调函数 credit_opvolume_callback 来实现这一功能。

核心步骤

  1. 发起查询:在 handlebar 或其他逻辑中调用 query_credit_opvolume 发送查询请求。
  2. 接收结果:必须在策略代码中定义 credit_opvolume_callback 函数,服务器返回数据后会自动触发该函数,结果包含在 result 参数中。

代码实现

以下是一个完整的策略示例,展示如何查询“融资买入”的最大可买数量。

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

def init(ContextInfo):
    # 1. 设置两融账号
    # 请将此处替换为您实际的信用资金账号
    ContextInfo.accid = '8800000000' 
    ContextInfo.set_account(ContextInfo.accid)
    
    # 定义一个全局变量用于控制查询频率,避免频繁请求
    ContextInfo.last_query_time = 0
    print("策略初始化完成,账号已设置")

def handlebar(ContextInfo):
    # 只在实时行情的最后一根K线运行,避免回测历史数据时重复触发
    if not ContextInfo.is_last_bar():
        return

    # 限制查询频率,建议间隔30秒以上,避免被服务器拒绝
    current_time = time.time()
    if current_time - ContextInfo.last_query_time < 30:
        return
    ContextInfo.last_query_time = current_time

    # 2. 准备查询参数
    stock_code = '600000.SH'  # 查询标的:浦发银行
    
    # opType 操作类型:
    # 27: 融资买入
    # 33: 担保品买入 (使用自有资金买入)
    # 28: 融券卖出
    op_type = 27 
    
    # prType 报价类型 (同 passorder): 
    # 11: 限价 (通常计算最大可买需指定价格)
    # 5: 最新价
    pr_type = 11 
    
    # 委托价格 (如果是限价单,此价格影响最大可买数量)
    # 这里简单取当前最新价
    last_price = ContextInfo.get_market_data(['close'], stock_code=[stock_code], count=1, period='1d')
    if last_price is None or len(last_price) == 0:
        return
    price = last_price['close'][0]
    
    # 生成唯一序列号,用于在回调中区分是哪次查询
    seq = int(current_time)

    print(f"发起查询: 股票={stock_code}, 价格={price}, 操作类型={op_type}, 序列号={seq}")

    # 3. 调用异步查询函数
    # query_credit_opvolume(accountId, stockCode, opType, prType, price, seq, ContextInfo)
    query_credit_opvolume(ContextInfo.accid, stock_code, op_type, pr_type, price, seq, ContextInfo)

# 4. 定义回调函数接收结果
def credit_opvolume_callback(ContextInfo, accid, seq, ret, result):
    """
    查询两融最大可下单量的回调函数
    :param accid: 查询的账号
    :param seq: 发起查询时传入的序列号
    :param ret: 查询状态 (1: 正常返回, -1: 查询中, -2: 账号非法, -3: 参数非法, -4: 服务器报错)
    :param result: 查询到的最大可买数量 (如果ret!=1,这里可能是错误信息)
    """
    if ret == 1:
        print("=" * 30)
        print(f"【查询成功】")
        print(f"账号: {accid}")
        print(f"序列号: {seq}")
        print(f"最大可买数量: {result}")
        print("=" * 30)
    else:
        print(f"【查询异常】序列号: {seq}, 状态码: {ret}, 信息: {result}")

关键参数说明

1. query_credit_opvolume (发起查询)

  • accountId: 信用资金账号。
  • stockCode: 股票代码(支持单个字符串或 List 列表)。
  • opType: 交易类型,常用值如下:
    • 27: 融资买入(借钱买股)
    • 33: 担保品买入(用自有资金买股)
    • 28: 融券卖出
  • prType: 报价类型,通常填 11 (限价) 或 5 (最新价)。
  • price: 委托价格。对于限价单,价格越低,理论可买数量越多。
  • seq: 序列号(整数)。建议使用时间戳或自增ID,以便在回调函数中对应请求。

2. credit_opvolume_callback (接收结果)

  • ret: 状态码。只有当 ret == 1 时,result 才是有效的数量。
  • result: 返回的最大可下单数量(股数)。

注意事项

  1. 异步机制:该函数不是立即返回结果的。代码执行完 query_credit_opvolume 后会继续往下执行,直到服务器返回数据,才会跳转到 credit_opvolume_callback 中执行。
  2. 调用频率:文档建议平均查询时间间隔 30秒 一次,不可频繁调用,否则可能导致查询失败或被服务器限流。
  3. 并发限制:同时只能有一个查询在进行中。如果前一个查询未返回,新的查询可能会提前返回或覆盖。
  4. 批量查询stockCode 参数支持传入列表(List),例如 ['600000.SH', '000001.SZ'],此时 price 也必须是对应长度的价格列表。

Q&A

Q: 为什么我调用了函数但是没有打印结果?
A: 请检查两点:1. 是否在策略中正确定义了 credit_opvolume_callback 函数(拼写必须完全一致)。2. 策略是否处于“实盘”或“模拟交易”模式,回测模式下该函数通常无效或无意义。

Q: opType 填 23 (普通买入) 可以吗?
A: 不可以。query_credit_opvolume 是专门针对信用账户(两融)的接口。信用账户的买入分为“担保品买入”(33)和“融资买入”(27)。普通股票账户的买入才用 23,且普通账户通常直接用可用资金除以价格计算即可,不需要调用此接口。

Q: 返回的数量是“手”还是“股”?
A: 返回的 result 通常是 股数。下单时请注意是否需要取整为 100 的倍数。