🚀 AI 一键生成 joinquant 策略代码

JoinQuant 中 get_industry_stocks 获取历史行业成分股包含未上市股票怎么办?

joinquant | 发布时间: 2026/5/21
以下内容由 EasyQuant 生成。

问题描述

get_industry_stocks的date无效

df=get_industry_stocks('G55', date='2011-05-06')结果有'601975.XSHG'。
但是,该股票是2019年才上市。
get_industry_stocks在'2011-05-06'不应该取到这只2019年才上市的股票?

解决方案

问题解析

在 JoinQuant 平台上,使用 get_industry_stocks 获取历史某天的行业成分股时,确实偶尔会遇到返回了当时尚未上市的股票的情况。这通常是由以下几个原因造成的:

  1. 行业分类标准的历史快照缺失:某些行业分类标准(如证监会行业、某些自定义行业)在较早的年份(如 2011 年)可能尚未建立,或者平台底层数据库缺乏该分类在早期的精确每日快照。当查询一个没有历史快照的日期时,底层数据可能会默认返回该行业较新或当前的成分股列表。
  2. 数据回溯机制的瑕疵:部分行业数据的维护是基于“最新状态”向历史回溯的,如果在回溯处理时未能严格与股票的 start_date(上市日期)进行交叉校验,就会导致未来才上市的股票“穿越”到历史列表中。

这种现象在量化回测中是非常危险的,因为它引入了未来函数(使用了当时不可能知道的信息)。

解决方案:进行二次过滤

为了确保策略的严谨性,避免买入或处理当时还未上市的股票,我们可以在调用 get_industry_stocks 之后,结合 get_all_securities 函数进行一次简单的二次过滤

get_all_securities(date=...) 函数非常可靠,当传入 date 参数时,它只会返回在该日期已经上市且尚未退市的股票列表。

过滤代码示例

您可以将获取行业股票的逻辑封装成一个安全的自定义函数:

from jqdata import *

def get_safe_industry_stocks(industry_code, query_date):
    """
    安全获取指定日期的行业成分股,剔除未上市的股票
    :param industry_code: 行业代码,如 'G55'
    :param query_date: 查询日期,如 '2011-05-06'
    :return: 过滤后的股票代码列表
    """
    # 1. 获取原始的行业成分股列表(可能包含未上市股票)
    raw_stocks = get_industry_stocks(industry_code, date=query_date)
    
    # 2. 获取查询日期当天所有正常上市的股票列表
    # 传入 date 参数后,返回的 DataFrame 的 index 就是当天已上市的股票代码
    valid_securities = get_all_securities(types=['stock'], date=query_date).index.tolist()
    
    # 3. 取交集,过滤掉在 query_date 尚未上市的股票
    safe_stocks = [stock for stock in raw_stocks if stock in valid_securities]
    
    return safe_stocks

# 测试代码
query_date = '2011-05-06'
industry_code = 'G55'

# 使用安全函数获取
stocks = get_safe_industry_stocks(industry_code, query_date)

# 验证 601975.XSHG 是否被剔除
if '601975.XSHG' in stocks:
    print('警告:仍然包含未上市股票!')
else:
    print('成功:未上市股票已被剔除。')

总结

在处理较早历史区间的板块、行业、概念成分股时,养成**“获取成分股 -> 与当日全市场已上市股票池取交集”**的习惯,是规避此类底层数据瑕疵和未来函数的最佳实践。这不仅适用于 get_industry_stocks,同样适用于 get_concept_stocks 等其他成分股获取函数。