3 分钟快速生成代码
输入想法,AI 即刻生成可运行代码
在 QMT 量化交易平台中,获取财务数据时 announce_time(公告日期)和 report_time(报告期)的区别主要体现在数据的生效时间点和回测时的未来函数风险上。
以下是详细的对比解析:
公告日期 (announce_time)
ContextInfo.get_financial_data 接口默认使用此模式。报告期 (report_time)
假设某上市公司 A股票 的财务披露时间轴如下:
如果您在策略中请求 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日 才发布的数据,会导致回测结果虚高。 |
在调用 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)
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']。