🚀 AI 一键生成 joinquant 策略代码
立即体验

joinquant 开启 avoid_future_data 后触发 FutureDataError 如何排查与修复?

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

问题描述

请根据以下 SEO 主题生成完整页面内容:

Title: joinquant 防未来函数实战:FutureDataError 异常处理与规范

Question: 开启 set_option('avoid_future_data', True) 后遇到 FutureDataError 该如何排查和修改代码?

解决方案

joinquant 防未来函数实战:FutureDataError 异常处理与规范

在量化回测中,**未来函数(Future Data)**是导致回测业绩虚高、实盘大幅亏损的罪魁祸首。为了帮助开发者彻底杜绝未来数据,JoinQuant(聚宽)提供了防未来函数机制。


一、开启防未来函数模式

在策略初始化函数 initialize 中添加以下设置:

def initialize(context):
    # 开启避免未来数据模式
    set_option('avoid_future_data', True)
    # 强烈建议同时开启动态复权(真实价格)模式
    set_option('use_real_price', True)

当开启 avoid_future_data=True 后,如果策略在运行过程中尝试通过 API 获取当前逻辑时间(context.current_dt)之后的数据,系统就会抛出 FutureDataError 异常并中断运行。


二、引发 FutureDataError 的常见场景与排查方法

1. get_price 参数设置错误(最常见)

  • 典型错误:在盘中或开盘时,直接获取当日或含未来时间点的价格数据。
  • 示例场景:在 9:30 执行策略时,调用 get_price(..., end_date=context.current_dt) 或使用了未限制的 end_date(默认获取到较晚的时间)。
  • 排查与修改
    • 按天获取历史行情:若需获取昨日及之前的日线,应确保 end_date 为上一个交易日,或者使用 attribute_history / get_bars
    • 错误写法
      # 在 9:30 获取今天的收盘价,导致 FutureDataError
      df = get_price(g.security, end_date=context.current_dt, frequency='daily', fields=['close'])
      
    • 正确写法
      # 使用 history/attribute_history 获取过去N天数据(不包含当天)
      df = attribute_history(g.security, 5, '1d', ['close'])
      

2. get_barsend_dt 传入未来时刻

  • 排查与修改:在使用 get_bars 时,确保 end_dt 不超过当前策略运行的时间 context.current_dt,且 include_now 属性设置符合预期。

3. 财务数据 get_fundamentals 盘中调用限制

  • 原因:为了避免未来数据,get_fundamentals 在盘后(15:00之后)才能获取当天交易日披露/更新的数据;如果在盘中交易时间内(如 9:30)获取,只能获取到此前已发布的数据。
  • 规范做法:如果策略依赖最新财务数据进行选股,建议将选股逻辑放在开盘前(09:00)或盘后(15:30),或使用 context.previous_date 作为查询基准日期。

三、不触发 FutureDataError 但仍需注意的未来数据隐患

  1. 时间过滤 API 的自动剔除
    对于某些无法通过时间参数主动避免的函数(例如 get_call_auction),开启 avoid_future_data=True 后,系统会自动剔除未来数据部分,而不会直接抛出异常。
  2. 外部数据引入
    使用 read_file 读取自定义 CSV 或外部网络请求获取的数据,JoinQuant 引擎无法进行未来数据检测,需开发者自行保证数据无未来偏差。
  3. 硬编码(Hardcoding)幸存者股票池
    使用固定股票池(如用现在的眼光挑选历史上暴涨的股票)也会引入隐性未来数据,建议使用 get_index_stocks 动态获取历史任意时刻的成分股。