问题描述
解决方案
在 QMT 中,查询信用账户(两融账户)的详细情况,主要使用以下两个专用 API 函数:
get_debt_contract(accId):用于获取负债合约明细。通过这个函数,你可以遍历每一笔负债,获取其对应的证券代码、合约开仓日期(借款时间)、未还金额等详细信息。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
代码关键点解析
-
get_debt_contract(account_id):- 这是查询负债的核心函数。
- 返回的是一个对象列表,每个对象代表一笔合约。
- 关键属性:
m_strInstrumentID: 股票代码(如 '600000.SH')。m_nOpenDate: 借款时间(合约开仓日期),格式为整数YYYYMMDD。m_dUnRepayBalance: 未还金额(负债金额)。m_eCompactType: 合约类型,48代表融资(借钱买股),49代表融券(借股卖出)。
-
get_assure_contract(account_id):- 这是官方提供的获取担保合约明细的接口。
- 它返回的是担保品对象列表。
-
get_trade_detail_data(..., 'POSITION'):- 在实际交易中,查询“担保品”通常等同于查询“信用账户里有哪些持仓”。
- 使用通用的交易明细接口查询
POSITION(持仓),可以获得更详细的数据,如持仓数量、当前市值、浮动盈亏等,这通常是投资者更关心的数据。
如何运行
- 打开 QMT 的“模型研究”或“策略编辑器”。
- 新建一个 Python 策略。
- 将上述代码复制进去。
- 重要:将代码中的
'YOUR_CREDIT_ACCOUNT'替换为你真实的信用资金账号(字符串格式)。 - 点击“运行”或“编译运行”。
- 在下方的“日志”或“输出”窗口中查看查询结果。
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,则是融券合约。