🚀 AI 一键生成 qmt 策略代码

QMT 策略技巧:如何动态获取沪深300等指数成分股?

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

问题描述

如何在策略中获取某个时间点的指数成分股列表?

解决方案

在 QMT 策略中,获取某个特定时间点的指数成分股列表,主要使用 ContextInfo.get_sector 函数。

核心函数说明

ContextInfo.get_sector(sector, realtime)

  • 功能:获取指定指数在指定时刻的成分股列表。
  • 参数
    • sector (string): 指数代码,格式为 'code.market',例如 '000300.SH'(沪深300)、'000905.SH'(中证500)。
    • realtime (string/number): 指定的时间点。通常传入毫秒级时间戳。如果不填,默认获取当前最新时刻的成分股。
  • 返回值list,包含成分股代码的列表(如 ['000001.SZ', '600000.SH', ...])。

代码示例

以下代码展示了如何在回测或实盘的 handlebar 周期中,动态获取当前 K 线时间点对应的沪深 300 成分股列表。

# -*- coding: gbk -*-

def init(ContextInfo):
    # 可以在初始化中设置一些变量,这里暂时不需要
    pass

def handlebar(ContextInfo):
    # 1. 获取当前 K 线的索引位置
    index = ContextInfo.barpos
    
    # 2. 获取当前 K 线对应的时间戳(毫秒级)
    # get_bar_timetag 返回的是毫秒时间戳,可以直接传给 get_sector
    realtime = ContextInfo.get_bar_timetag(index)
    
    # 3. 定义指数代码 (例如:沪深300)
    index_code = '000300.SH'
    
    # 4. 调用接口获取该时间点的成分股
    # 注意:如果是回测模式,传入 realtime 非常重要,否则会取到最新日期的成分股导致未来函数
    stock_list = ContextInfo.get_sector(index_code, realtime)
    
    # 5. 打印结果验证
    # 将时间戳转换为可读日期格式方便查看
    date_str = timetag_to_datetime(realtime, '%Y-%m-%d')
    print(f"日期: {date_str}, 指数: {index_code}, 成分股数量: {len(stock_list)}")
    
    # 打印前5只成分股示例
    if len(stock_list) > 0:
        print(f"前5只成分股: {stock_list[:5]}")

注意事项

  1. 时间戳格式realtime 参数至关重要。在回测模式下,必须传入历史时间戳(如上例中的 ContextInfo.get_bar_timetag(index)),否则系统会默认返回当前最新的成分股列表,导致策略用到“未来数据”,回测结果失真。
  2. 板块名称 vs 代码
    • 如果使用指数代码(如 '000300.SH'),请使用 ContextInfo.get_sector
    • 如果想使用板块名称(如 '沪深300''我的自选'),可以使用 ContextInfo.get_stock_list_in_sector(sectorname, realtime)。用法类似,但第一个参数传中文名称。
  3. 数据补充:在进行回测前,请确保在 QMT 客户端的【数据管理】中下载了对应指数的历史行情数据,以确保成分股历史变动记录是完整的。

Q&A

Q: ContextInfo.get_sectorContextInfo.get_stock_list_in_sector 有什么区别?
A: get_sector 主要用于通过标准的指数代码(如 000300.SH)获取成分股,通常用于标准指数;get_stock_list_in_sector 通过板块名称(如 沪深300 或用户自定义板块名)获取,支持范围更广(包括行业、概念、自选股),但使用名称可能存在重名或歧义风险,标准指数建议优先使用代码。

Q: 如果 realtime 参数传空会怎样?
A: 如果 realtime 缺省或传空,函数会返回当前时刻(最新)的成分股列表。在实盘交易中这是正确的,但在历史回测中这会导致“未来函数”错误。

Q: 如何将毫秒时间戳转换为可读的日期字符串?
A: 可以使用 QMT 内置的 timetag_to_datetime(timetag, format) 函数。例如:timetag_to_datetime(1640995200000, '%Y-%m-%d %H:%M:%S')