前言
在上一篇文章中,我们介绍了用 get_etf_stock_list 一键获取 ETF 全量成分股列表,完成了基础的持仓穿透。但在 ETF 申赎套利、实物申购、成分股风险排查等实际量化场景中,仅知道成分股名单远远不够:我们还需要知道单只成分股的持仓数量、申购时能否现金替代、个股是否停牌等关键信息。
本文就带大家完整学习 PTrade 平台的 get_etf_stock_info 函数,从功能定义、参数语法、返回字段到实战代码、避坑指南,全面掌握 ETF 成分股明细查询方法。
一、函数功能概述
get_etf_stock_info 的核心功能是:根据指定的 ETF 代码与成分股代码,返回该成分股在对应 ETF 中的持仓数量、现金替代标志、交易状态等详细信息。
如果说 get_etf_stock_list 是 ETF 的「配料清单」,那 get_etf_stock_info 就是每一味配料的「详情说明书」—— 不仅知道 ETF 持有哪些股票,还能知道每只股票持有多少、申购时能不能用现金代替、当前能不能正常交易。
二、函数语法与参数说明
2.1 调用格式
# 查询单只成分股详情
get_etf_stock_info(etf_code, stock_code)
# 批量查询多只成分股详情
get_etf_stock_info(etf_code, [stock_code1, stock_code2, ...])
2.2 参数说明
表格
| 参数名 | 数据类型 | 必填 | 说明 |
|---|---|---|---|
| etf_code | str | 是 | 单只 ETF 的证券代码,必须带市场后缀,例如 510300.SS、159915.SZ |
| stock_code | str / list | 是 | 待查询的成分股代码,支持单个字符串或代码列表,均需附带市场后缀 |
2.3 使用环境限制
该函数为 PTrade 股票交易模块专属 API,仅可在 PTrade 客户端的股票交易环境中调用,回测环境或其他第三方环境无法正常运行。
三、返回值核心字段详解
函数返回嵌套字典结构:外层字典的键为成分股代码,内层字典存储该股票的各项明细信息。高频实用的核心字段如下表:
| 字段名 | 数据类型 | 字段含义 | 取值说明 |
|---|---|---|---|
| code_num | float | ETF 对该成分股的持仓数量 | 单位为股,例如 4700.0 代表 ETF 持有 4700 股该股票 |
| cash_replace_flag | int | ETF 申购时是否支持现金替代 | 1 = 支持现金替代;0 = 不支持现金替代 |
| is_open | int | 成分股当前交易状态 | 1 = 正常交易;0 = 停牌,不可买卖 |
四、实战代码示例
4.1 示例 1:查询单只成分股持仓细节
场景说明:查询沪深 300ETF(510300.SS)中贵州茅台(600519.SS)的持仓数量、现金替代权限及当前交易状态。
def initialize(context):
print("策略启动:查询沪深300ETF中贵州茅台的持仓细节")
g.etf_code = "510300.SS" # 沪深300ETF代码
g.stock_code = "600519.SS" # 贵州茅台代码
def before_trading_start(context, data):
# 1. 调用函数获取单只成分股详情
stock_detail = get_etf_stock_info(g.etf_code, g.stock_code)
# 2. 提取核心字段并格式化
hold_num = stock_detail[g.stock_code]["code_num"]
can_replace = "可以" if stock_detail[g.stock_code]["cash_replace_flag"] == 1 else "不可以"
is_trading = "正常交易" if stock_detail[g.stock_code]["is_open"] == 1 else "已停牌"
# 3. 打印结果
print(f"{g.etf_code}(沪深300ETF)中 {g.stock_code}(贵州茅台)的详情:")
print(f"1. ETF持仓数量:{hold_num} 股")
print(f"2. 申购时能否现金替代:{can_replace}")
print(f"3. 股票当前状态:{is_trading}")
def handle_data(context, data):
pass
运行输出示例:
策略启动:查询沪深300ETF中贵州茅台的持仓细节
510300.SS(沪深300ETF)中 600519.SS(贵州茅台)的详情:
1. ETF持仓数量:100.0 股
2. 申购时能否现金替代:可以
3. 股票当前状态:正常交易
4.2 示例 2:批量查询多只成分股并对比
场景说明:同时查询沪深 300ETF 中贵州茅台、工商银行两只成分股的信息,对比持仓数量与现金替代规则。
def initialize(context):
print("策略启动:对比沪深300ETF中两支成分股的持仓细节")
g.etf_code = "510300.SS" # 沪深300ETF代码
g.stock_codes = ["600519.SS", "601398.SS"] # 贵州茅台、工商银行
def before_trading_start(context, data):
# 1. 批量查询多只成分股详情
stocks_detail = get_etf_stock_info(g.etf_code, g.stock_codes)
# 2. 循环遍历输出每只股票信息
for code in g.stock_codes:
stock_name = "贵州茅台" if code == "600519.SS" else "工商银行"
hold_num = stocks_detail[code]["code_num"]
can_replace = "可以" if stocks_detail[code]["cash_replace_flag"] == 1 else "不可以"
print(f"\n{stock_name}({code})详情:")
print(f"- ETF持仓数量:{hold_num} 股")
print(f"- 能否现金替代:{can_replace}")
def handle_data(context, data):
pass
运行输出示例:
策略启动:对比沪深300ETF中两支成分股的持仓细节
贵州茅台(600519.SS)详情:
- ETF持仓数量:100.0 股
- 能否现金替代:可以
工商银行(601398.SS)详情:
- ETF持仓数量:6100.0 股
- 能否现金替代:可以
五、使用注意事项(避坑指南)
-
双参数必填,代码必须带市场后缀 ETF 代码与成分股代码均为必传参数,且必须附带
.SS(沪市)或.SZ(深市)后缀;缺少参数、漏写后缀或代码格式错误,都会返回空字典。 -
仅支持查询 ETF 自有成分股 只能查询目标 ETF 实际包含的成分股。若查询的股票不在该 ETF 成分股列表中(例如在上证 50ETF 中查询宁德时代),会返回空信息,并非函数调用失败。
-
批量查询需传入列表格式 查询多只成分股时,需将股票代码放入 Python 列表中统一传入,而非多个独立参数;单只查询直接传入字符串即可。
-
运行环境限制 与
get_etf_stock_list一致,该函数仅在 PTrade 股票交易模块可用,使用前请确认当前运行环境。
六、总结
get_etf_stock_info 是 ETF 精细化量化策略的核心底层工具,尤其适用于 ETF 实物申赎套利、停牌成分股风险排查、申赎成本估算等场景。配合 get_etf_stock_list 函数,可以完整实现「获取全量成分股 → 批量查询持仓细节」的全流程,为 ETF 相关量化策略提供完整的数据支撑。
风险提示:
本文只做技术教学,不做任何投资建议,本文举例上市公司名称 仅仅用作举例说明,不具有任何其他含义,投资有风险,入市需谨慎