🚀 AI 一键生成 joinquant 策略代码

JoinQuant量化策略中如何识别和避免未来函数?

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

问题描述

怎么识别代码里有未来函数?

解决方案

在量化交易回测中,“未来函数”(或未来数据)是策略开发者最大的敌人之一。它指的是在历史回测时,使用了当时时间点无法获取到的未来信息(例如在今天开盘时获取了今天的收盘价),从而导致回测收益虚高,实盘却表现惨淡。

在 JoinQuant(聚宽)平台上,识别和避免代码中的未来函数主要有以下几种方法:

1. 开启官方提供的“避免未来数据模式”

JoinQuant 提供了一个实验性的设置项,可以帮助开发者在代码运行层面自动检测和处理部分未来数据。你只需要在策略的 initialize 函数中加入以下代码:

def initialize(context):
    # 开启避免未来数据模式
    set_option("avoid_future_data", True)

开启后的处理机制:

  • 抛出异常(FutureDataError): 对于可以通过时间参数避免的未来数据(例如在回测中使用包含时间参数的 API 如 get_bars 去取 current_dt 之后的数据),系统会直接抛出 FutureDataError 异常,强制中断回测,提醒你修改代码。
  • 自动剔除: 对于用户没法通过函数参数主动避免的未来数据(例如 get_call_auction),系统会将返回结果中的未来数据自动剔除掉,而不会抛出异常。

2. 审查常见的未来函数调用场景

虽然 avoid_future_data 能拦截很多问题,但它不是万能的。你需要人工审查代码中是否出现了以下常见错误:

  • 盘前获取盘后数据:before_trading_start (开盘前 9:00) 或 market_open (开盘 9:30) 中,调用 get_price 获取了当天的 close (收盘价)、high (最高价) 或 low (最低价)。
  • 财务数据的提前使用: 财务报表通常在季度结束后的一个月内发布。如果在回测中直接按季度末日期(如 3月31日)去取一季报数据,就引入了未来函数。应使用 get_fundamentals 并传入 date 参数(系统会自动取该日期前已发布的最新财报),而不是直接传入 statDate(除非你明确知道发布日期)。
  • 动态复权(真实价格)模式未开启: 如果使用传统的前复权模式回测,历史时刻拿到的数据是基于未来某一天的前复权因子计算的,这本身就存在未来函数。强烈建议在 initialize 中开启真实价格模式:set_option('use_real_price', True)

3. 警惕外部数据和固定规则

  • 引入外部数据: 如果你的策略读取了本地文件或网络数据,而这些数据在生成时包含了未来信息,平台是无法检测到的。
  • 固定股票池/时间点: 在代码中硬编码了“历史上某段时间大涨的股票代码”并在低点买入,这种“上帝视角”也是一种隐性的未来函数。

总结

要彻底识别和消除未来函数,最佳实践是:

  1. 必须在 initialize 中设置 set_option("avoid_future_data", True)set_option('use_real_price', True)
  2. 严格区分策略运行的逻辑时间(context.current_dt),确保任何数据获取 API 的 end_date 都不超过当前逻辑时间。
  3. 仔细检查财务数据和宏观数据的发布滞后性。