🚀 AI 一键生成 qmt 策略代码

QMT API 教程:使用 get_etf_info 获取ETF申赎清单与IOPV

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

问题描述

如何用代码查询一只ETF基金的实时申赎清单(包含成分股列表和数量)和它的IOPV?

解决方案

在 QMT 平台中,查询 ETF 基金的实时申赎清单(PCF)和 IOPV(基金份额参考净值)主要依赖于以下两个 API 函数:

  1. get_etf_info(stockcode):用于获取 ETF 的申赎清单数据,返回结果包含现金差额、最小申赎单位、以及具体的成分股列表(包含代码和数量)。
  2. get_etf_iopv(stockcode):用于获取 ETF 当前的 IOPV 数值。

以下是完整的策略代码示例,展示了如何在 handlebar 中调用这两个接口并解析输出结果。

策略代码

# -*- coding: gbk -*-

def init(ContextInfo):
    # 在初始化中设置要查询的 ETF 代码
    # 例如:510050.SH (华夏上证50ETF)
    ContextInfo.etf_code = '510050.SH'
    print(f"策略初始化完成,准备查询 {ContextInfo.etf_code} 的 ETF 信息")

def handlebar(ContextInfo):
    # 为了避免在历史K线上重复打印,仅在最新的一根K线(实时行情)上执行查询
    if not ContextInfo.is_last_bar():
        return

    etf_code = ContextInfo.etf_code
    
    # ============================================================
    # 1. 获取 ETF 申赎清单 (包含成分股和数量)
    # ============================================================
    # get_etf_info 返回一个字典,Key 为时间戳,Value 为包含详细信息的字典
    etf_info_map = get_etf_info(etf_code)
    
    if etf_info_map:
        # 通常我们取最新的一个时间戳的数据
        # 注意:返回的数据可能包含多个时间点,这里演示遍历打印
        for timetag, info in etf_info_map.items():
            print("=" * 50)
            print(f"【ETF 申赎清单信息】 代码: {info.get('etfCode')} 时间戳: {timetag}")
            print(f"基金名称: {info.get('etfName')}")
            print(f"最小申赎单位: {info.get('reportUnit')} 份")
            print(f"现金差额: {info.get('cashBalance')} 元")
            print(f"预估现金差额: {info.get('ecc')} 元")
            print(f"是否允许申购: {'是' if info.get('enableCreation') == 1 else '否'}")
            print(f"是否允许赎回: {'是' if info.get('enableRedemption') == 1 else '否'}")
            
            # 获取成分股列表
            components = info.get('stocks', [])
            print(f"--- 成分股列表 (共 {len(components)} 只) ---")
            
            # 打印前 5 只成分股作为示例,避免日志过长
            for i, comp in enumerate(components):
                if i < 5: 
                    print(f"成分股代码: {comp['componentCode']}, "
                          f"名称: {comp['componentName']}, "
                          f"数量: {comp['componentVolume']}, "
                          f"替代标志: {comp['ReplaceFlag']}")
                else:
                    print(f"... 剩余 {len(components) - 5} 只成分股未显示 ...")
                    break
    else:
        print(f"未查询到 {etf_code} 的申赎清单数据,请检查代码或数据权限。")

    # ============================================================
    # 2. 获取 ETF 实时 IOPV (基金份额参考净值)
    # ============================================================
    iopv = get_etf_iopv(etf_code)
    print("-" * 50)
    print(f"【ETF IOPV】 {etf_code} 当前参考净值: {iopv}")
    print("=" * 50)

代码解析

  1. get_etf_info(stockcode) 返回结构

    • 该函数返回的是一个字典 {timetag: valuedict}
    • valuedict 中包含了 ETF 的基础信息(如 cashBalance 现金差额, reportUnit 最小申赎单位等)。
    • 关键字段 stocks 是一个列表,列表中的每个元素是一个字典,代表一只成分股。
    • 成分股字典包含:componentCode (代码), componentName (名称), componentVolume (数量/股数), ReplaceFlag (替代标记) 等。
  2. get_etf_iopv(stockcode) 返回结构

    • 直接返回一个浮点数(float),即当前的 IOPV 值。
  3. 运行环境

    • 请在 QMT 的“策略编辑器”中新建一个 Python 策略,将上述代码粘贴进去。
    • 点击“运行”即可在下方的日志窗口看到输出结果。
    • 注意get_etf_info 获取的是 ETF 的 PCF(申购赎回清单)文件数据,通常在交易日盘前更新;get_etf_iopv 是行情数据,盘中会实时变动。

常见问题 (Q&A)

Q: 为什么 get_etf_info 返回为空?
A: 可能原因有二:一是该 ETF 代码输入错误或该品种不支持申赎(非 ETF);二是本地缺少 ETF 申赎清单数据。请尝试在 QMT 客户端的【数据管理】中补充下载相关数据,或者确保连接的行情服务器正常。

Q: 成分股数量 componentVolume 是指什么?
A: 它指的是一个最小申赎单位(Basket)中,该成分股所需要的股票数量(股)。例如,如果最小申赎单位是 900,000 份,componentVolume 为 100,则表示申购 90 万份 ETF 需要 100 股该股票。

Q: get_etf_iopv 的更新频率是多少?
A: IOPV 通常由交易所每 15 秒计算并发布一次。QMT 获取的是交易所推送的最新快照值。

Q: 如何获取全部成分股而不是只打印前5个?
A: 代码示例中为了防止日志刷屏使用了 if i < 5 进行限制。如果您需要获取全部数据进行计算,直接遍历 components 列表即可,例如:all_stocks = [comp['componentCode'] for comp in components]