3 分钟快速生成代码
输入想法,AI 即刻生成可运行代码
这不是 BUG,而是为了严格规避未来函数以及反映真实的行业历史变迁而设计的机制。
申万行业分类在历史上发生过多次重大调整(例如 2014 年 2 月 21 日和 2021 年底)。
initialize 和 handle_data 返回结果不同?handle_data (或 handle_bar) 中:回测引擎已经进入了时间循环。为了防止策略在 2011 年“提前”看到 2014 年或 2021 年才设立的行业(这属于典型的未来函数),系统在底层会将未传入的 date 参数默认对齐到当前的回测逻辑时间 context.current_dt。因此,它准确地返回了 2011 年当时存在的 23 个行业。initialize 中:此时回测的时间循环尚未正式开始,API 按照文档默认的 date=None 逻辑,返回了历史上存在过的所有行业代码(包含了未来新增的行业)。强烈建议在回测中使用当时的行业分类。如果在 2011 年的策略中使用了 2014 年才有的行业代码去选股,会导致获取不到数据或产生逻辑错误。
如果您确实需要在盘中获取包含未来所有调整的行业列表(不推荐,存在未来函数风险),您可以通过以下两种方式实现:
方式一:在 initialize 中缓存数据
在初始化时获取并存入全局变量 g 中,后续直接使用:
def initialize(context):
# 获取所有历史行业并缓存
g.all_sw_l1 = get_industries(name='sw_l1').index.tolist()
def handle_data(context, data):
# 直接使用缓存的完整列表
industries = g.all_sw_l1
print(len(industries)) # 将输出 30+ 个
方式二:显式传入未来的日期(不推荐)
在 handle_data 中强制传入一个未来的日期(如今天),强制 API 返回最新的行业列表:
import datetime
def handle_data(context, data):
# 强制获取最新日期的行业分类(引入未来函数)
industries = get_industries(name='sw_l1', date=datetime.date.today()).index.tolist()
总结:量化回测的核心是“还原历史”。get_industries 在盘中返回 23 个行业,正是为了保证您的策略在 2011 年的环境下运行的是 2011 年的真实数据。