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

JoinQuant回测中如何使用date参数准确获取年报数据?

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

问题描述

回测中get_fundamentals不支持statDate

回测中get_fundamentals不支持statDate参数,请使用date参数

我希望在回测中获取某个季度的报表数据,如果使用date参数,获取的是最近的报表,那么如4月份有可能获取的是年报或者一季报,如何才能确保获取的是年报?

解决方案

在JoinQuant(聚宽)平台的回测中,强烈建议使用 date 参数而不是 statDate 参数来获取财务数据。这是因为使用 statDate(如指定获取去年的年报)时,如果该年报在当前回测日期尚未实际发布,系统仍会返回数据,从而引入未来函数,导致回测结果失真。

在4月份这种财报密集披露期,使用 date 参数确实会遇到获取到的是一季报还是去年年报的不确定性。为了确保在避免未来函数的前提下准确获取到年报数据,您可以采用以下两种方法:

方法一:使用 get_history_fundamentals 函数(推荐)

聚宽提供了专门用于获取历史多期财务数据的 API get_history_fundamentals。您可以使用 watch_date 参数(观察日期,即当前回测日期),并结合 stat_by_year=True 来严格获取该日期前已发布的最新年报数据。

from jqdata import *

def handle_data(context, data):
    # 假设我们要查询平安银行的年报营业收入
    security = ['000001.XSHE']
    
    # watch_date 设为当前回测日期,确保没有未来函数
    # stat_by_year=True 表示获取年度数据
    # interval='1y' 表示间隔为1年,count=1 表示获取最近1期
    df = get_history_fundamentals(security, 
                                  fields=[income.total_operating_revenue], 
                                  watch_date=context.current_dt.date(), 
                                  count=1, 
                                  interval='1y', 
                                  stat_by_year=True)
    
    if not df.empty:
        print("获取到的年报数据:\n", df)

方法二:使用 get_fundamentals 结合 statDate 字段进行逻辑判断

如果您坚持使用 get_fundamentals,可以在查询时将报表的统计日期字段(如 income.statDateindicator.statDate)一并查出。通过判断返回的报表是哪个季度的,来决定下一步操作。

from jqdata import *

def handle_data(context, data):
    # 1. 先用 date 参数获取当前能看到的最新财报
    q = query(
        valuation.code,
        income.statDate,
        income.total_operating_revenue
    ).filter(
        valuation.code == '000001.XSHE'
    )
    
    # 使用当前回测日期
    df_current = get_fundamentals(q, date=context.current_dt)
    
    if not df_current.empty:
        stat_date = df_current['statDate'][0]
        
        # 2. 判断获取到的是否是年报(年报的 statDate 通常以 '12-31' 结尾)
        if stat_date.endswith('12-31'):
            print("当前最新财报即为年报:", df_current)
        else:
            # 如果获取到的是一季报(例如 03-31),说明去年的年报肯定已经发布了!
            # 此时我们可以安全地使用 statDate 参数去获取去年的年报,而不会引入未来函数。
            last_year = str(context.current_dt.year - 1)
            df_annual = get_fundamentals(q, statDate=last_year)
            print("当前最新为一季报,已安全获取去年年报:", df_annual)

总结

  • 避免未来函数是量化回测的第一要务。直接使用 statDate 极易踩坑。
  • 推荐使用 get_history_fundamentals,它原生支持按 watch_date 视角获取年度数据,代码更简洁且绝对安全。
  • 如果使用 get_fundamentals,请务必先用 date 探路,确认年报已发布后,再定向获取。