问题描述
解决方案
在 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. 总结
- Announce_time (公告日期):模拟真实。数据按“发布日”对齐。在发布日之前,取不到该期数据。用于回测和实盘,避免未来函数。
- 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']。