🚀 AI 一键生成 qmt 策略代码

get_financial_data 进阶:如何正确处理财报公告日与报告期回测?

qmt | 发布时间: 2025/12/23
以下内容由 EasyQuant 生成。

问题描述

获取财务数据时,公告日期 (announce_time) 和报告期 (report_time) 有什么区别?

解决方案

在 QMT 量化交易平台中,获取财务数据时 announce_time(公告日期)和 report_time(报告期)的区别主要体现在数据的生效时间点回测时的未来函数风险上。

以下是详细的对比解析:

1. 核心定义区别

  • 公告日期 (announce_time)

    • 定义:指上市公司正式对外发布财务报告的实际日期。
    • 逻辑:这是市场真正获知该数据的时刻。例如,某公司 2023 年的年报(截止 2023-12-31 的数据)可能直到 2024 年 4 月 26 日才发布。
    • QMT 默认行为ContextInfo.get_financial_data 接口默认使用此模式。
  • 报告期 (report_time)

    • 定义:指财务报表所覆盖的会计期间截止日期。
    • 逻辑:这是数据在财务会计上所属的时间段。例如,2023 年年报的报告期通常是 2023-12-31,2024 年一季报的报告期是 2024-03-31。

2. 举例说明

假设某上市公司 A股票 的财务披露时间轴如下:

  • 2022年年报(报告期:2022-12-31)于 2023年4月25日 发布。
  • 2023年一季报(报告期:2023-03-31)于 2023年4月28日 发布。

如果您在策略中请求 2023年4月26日 的财务数据:

模式 report_type='announce_time' (默认) report_type='report_time'
获取到的数据 2022年年报数据 2023年一季报数据 (取决于查询范围)
逻辑解释 在 4月26日 这一天,2023年一季报(4月28日发)尚未公布,市场上能看到的最新数据只有 2022年年报(4月25日发)。 该模式关注的是“该时间段属于哪个报告期”。虽然 4月26日 还没发一季报,但按报告期逻辑,该时间点已过 3月31日,系统可能会返回该季度的数据用于分析历史趋势。
回测影响 无未来函数。模拟了真实的交易环境,只能用到当时已公开的信息。 存在未来函数。在 4月26日 就用到了 4月28日 才发布的数据,会导致回测结果虚高。

3. 在 QMT 代码中的应用

在调用 ContextInfo.get_financial_data 时,通过 report_type 参数进行控制。

场景一:回测或实盘交易(推荐)

为了防止利用未来数据进行交易,必须使用 announce_time。这是 QMT 的默认设置。

# -*- coding: gbk -*-
def handlebar(ContextInfo):
    # 获取净利润,默认 report_type='announce_time'
    # 此时获取的是当前时刻市场上已公开的最新数据
    fieldList = ['ASHAREINCOME.net_profit_incl_min_int_inc']
    stockList = ['600000.SH']
    startDate = '20230401'
    endDate = '20230501'
    
    # 显式指定为公告日期模式(虽然缺省也是这个)
    df = ContextInfo.get_financial_data(
        fieldList, 
        stockList, 
        startDate, 
        endDate, 
        report_type='announce_time'
    )
    print(df)

场景二:历史基本面研究/因子分析

如果您不进行模拟交易,而是想分析公司财务指标的历史变化趋势(例如计算过去5年的同比增长率),不关心数据何时发布,只关心数据属于哪一年,可以使用 report_time

# -*- coding: gbk -*-
def init(ContextInfo):
    # 获取按报告期排列的数据,用于分析财务趋势
    fieldList = ['ASHAREINCOME.net_profit_incl_min_int_inc']
    stockList = ['600000.SH']
    startDate = '20220101'
    endDate = '20230101'
    
    # 指定为报告期模式
    df = ContextInfo.get_financial_data(
        fieldList, 
        stockList, 
        startDate, 
        endDate, 
        report_type='report_time'
    )
    print(df)

4. 总结

  1. Announce_time (公告日期)模拟真实。数据按“发布日”对齐。在发布日之前,取不到该期数据。用于回测和实盘,避免未来函数。
  2. Report_time (报告期)财务归档。数据按“会计截止日”对齐。不管何时发布的,数据都归属于那个季度/年份。用于纯财务分析或训练模型时的标签生成,回测慎用。

Q&A

Q: 如果我在回测中错误地使用了 report_time 会发生什么?
A: 您的策略表现可能会异常优秀,因为您在财报发布之前(例如股价上涨前)就已经“提前”知道了公司的业绩大增。这被称为“前视偏差”(Look-ahead Bias),会导致实盘时策略失效。

Q: get_financial_data 返回的数据索引(Index)在两种模式下有何不同?
A:

  • 使用 announce_time 时,返回的 DataFrame 索引通常是数据的公告日期或您查询的时间序列。
  • 使用 report_time 时,返回的数据通常会对应到具体的报告期截止日(如 20221231, 20230331 等)。

Q: QMT 中如何获取某条财务数据的具体公告日期?
A: 在财务数据表中,通常包含 m_anntime(公告日)字段。您可以将其作为字段之一请求出来,例如 fieldList = ['ASHAREINCOME.net_profit_incl_min_int_inc', 'ASHAREINCOME.m_anntime']