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

joinquant 平台如何开启 avoid_future_data 模式排查未来函数?(量化回测避坑指南)

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

问题描述

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

Title: joinquant 量化回测避坑:avoid_future_data 模式与未来函数排查

Question: 在 joinquant 中如何开启 avoid_future_data 并排查策略中的未来函数?

解决方案

joinquant 量化回测避坑:avoid_future_data 模式与未来函数排查

在量化回测中,**未来函数(Future Data)**是导致回测实盘收益差异巨大的“罪魁祸首”。未来函数指在历史回测时使用了当时时间点无法获取的未来信息(例如:在盘中获取当天的收盘价或尚未披露的财务数据)。

为了帮助开发者发现并剔除未来函数,JoinQuant(聚宽)平台提供了 avoid_future_data 机制。


一、如何开启 avoid_future_data 模式?

在 JoinQuant 策略代码的 initialize(context) 函数中调用 set_option API,即可开启避免未来数据模式:

def initialize(context):
    # 开启避免未来数据模式
    set_option('avoid_future_data', True)
    
    # 开启动态复权模式(建议同时开启以防复权未来函数)
    set_option('use_real_price', True)

开启后的系统处理机制:

  1. 时间可规避的未来数据:如使用包含时间参数的 API(如 get_bars)请求 current_dt 之后的数据时,系统会直接抛出 FutureDataError 异常提示报错位置。
  2. 无法通过时间参数规避的数据:如 get_call_auction(集合竞价数据),开启模式后,系统会自动过滤并剔除其中的未来数据,而不抛出异常。

二、常见的未来函数场景与排查方案

1. 盘中获取当天未收盘的行情数据(如收盘价)

  • 错误示例:在盘中(如 10:00)调用 get_price 获取当天的 close 价格。
  • 正确做法
    • 获取历史收盘价应使用 historyattribute_history(默认不包含当天数据)。
    • 获取盘中实时价格应使用 get_current_data() API 或通过 get_bars 取截至当前的 Bar。
# 正确获取盘中实时数据
current_data = get_current_data()
price = current_data['000001.XSHE'].last_price

2. 财报数据的未来函数

  • 错误示例:使用 get_fundamentals 传入 statDate(如 '2023q1')去取财报。因为财报发布有滞后性,在季度结束时(如 3月31日)财报往往尚未披露。
  • 正确做法:使用 date 参数(回测中默认取 context.current_dt 的前一天),系统会自动查找该日期前已发布的最新财报数据,避免未来函数:
# 正确查询财务数据
q = query(valuation.code, valuation.pe_ratio)
df = get_fundamentals(q, date=context.previous_date)

3. 复权因子带来的未来数据

  • 错误示例:使用传统静态前复权价格回测。因为前复权是基于未来(甚至今天)的复权因子重新计算历史价格,导致历史下单量计算不准确。
  • 正确做法:在 initialize 中开启动态复权(真实价格)模式:
set_option('use_real_price', True)

三、注意事项

  1. 局限性avoid_future_data 可以拦截平台标准 API 引入的未来数据,但无法拦截用户自己从外部网络/本地读取的自定义数据,也无法拦截通过硬编码特定股票未来大涨日期等逻辑性未来信息。
  2. 跨日数据缓存:不要在全局变量 g 中跨交易日缓存数据获取 API 的结果(如价格或复权因子),因为不同交易日看历史的前复权价格可能会有变动。