问题描述
解决方案
在 QMT (Quantitative Trading Platform) 中,获取沪深300成分股主要使用 ContextInfo.get_sector 函数。
以下是详细的获取方法、代码示例及参数说明。
核心函数说明
ContextInfo.get_sector(sector, realtime)
- 功能:获取指数成分股列表。
- 参数:
sector(string): 指数代码,格式为'stockcode.market'。沪深300的指数代码为'000300.SH'。realtime(number, 可选): 毫秒级时间戳。- 如果不填,默认获取当前最新的成分股。
- 如果填写时间戳,则获取该历史时刻的成分股(常用于回测中获取当时生效的成分股)。
- 返回值:返回一个包含股票代码的列表 (
list),代码格式如'000001.SZ'。
代码实现示例
以下代码展示了两种场景:
- 在策略初始化时获取最新的成分股。
- 在回测过程中获取历史某一时刻的成分股。
# -*- coding: gbk -*-
def init(ContextInfo):
"""
策略初始化函数
"""
print("正在获取沪深300最新成分股...")
# 方法1:获取当前最新的沪深300成分股(不传时间参数)
# 指数代码:000300.SH
hs300_list = ContextInfo.get_sector('000300.SH')
print(f"沪深300成分股数量: {len(hs300_list)}")
print(f"前10只成分股: {hs300_list[:10]}")
# 将成分股设置为本策略的股票池(可选操作)
ContextInfo.set_universe(hs300_list)
def handlebar(ContextInfo):
"""
K线周期运行函数
"""
# 方法2:在回测中获取历史时刻的成分股
# 获取当前K线的时间戳
index = ContextInfo.barpos
realtime = ContextInfo.get_bar_timetag(index)
# 仅在最后一根K线打印演示,避免日志过多
if ContextInfo.is_last_bar():
# 传入时间戳,获取该时刻的成分股
# 注意:指数成分股是随时间调整的,回测时建议传入时间戳
historical_constituents = ContextInfo.get_sector('000300.SH', realtime)
# 将时间戳转换为可读日期字符串
import datetime
date_str = datetime.datetime.fromtimestamp(realtime / 1000).strftime('%Y-%m-%d')
print(f"日期 {date_str} 时的沪深300成分股数量: {len(historical_constituents)}")
注意事项
- 指数代码:沪深300在 QMT 中的标准代码是
000300.SH,请勿混淆为399300.SZ(这是深证的沪深300代码,通常使用上海的000300.SH数据更全)。 - 历史回测:在进行历史回测时,务必传入
realtime参数。因为指数成分股会定期调整(通常是每半年),如果不传时间,系统会默认返回今天的最新成分股,导致回测产生“未来函数”偏差。 - 板块名称获取:除了使用代码,也可以使用
ContextInfo.get_stock_list_in_sector('沪深300')通过中文名称获取,但使用get_sector('000300.SH')更加精确和规范。
Q&A
Q: ContextInfo.get_sector 和 ContextInfo.get_stock_list_in_sector 有什么区别?
A: get_sector 主要用于获取指数的历史成分股,需要传入标准的指数代码(如 000300.SH)。get_stock_list_in_sector 支持通过板块名称(如 '沪深300'、'我的自选'、'上证50')获取成分股,使用范围更广,包含自定义板块。
Q: 获取到的成分股列表包含什么内容?
A: 返回的是一个 Python 列表 (list),包含字符串格式的股票代码,例如 ['600519.SH', '000858.SZ', ...]。
Q: 为什么回测时获取的成分股数量不是严格的300只?
A: 在指数调整生效日附近,或者某些特殊停牌、换股期间,成分股数量可能会有微小的波动,或者数据源本身包含了一些临时调整的记录,通常数量会在300左右。