回测站在过去某一天时,数据库里的财报是不是当时已经公开了?

Point-in-time 数据与前视偏差

约 11 分钟6 道自测更新于 2026-10-31

一句话记住Point-in-time 数据只允许回测使用当时已经可知的版本,关联财报要看公告时间而不是报告期。

01学完你能做到

  • 区分报告期、公告时间和入库时间。
  • 识别按报告期直接关联造成的前视偏差。
  • 设计保留多版本、按 as_of 查询的时点正确数据表。

02这课解决什么问题

回测“每月初买入上一季度利润增长最快的股票”时,如果数据库按报告期把半年报提前贴到报告期末,程序就会使用当时尚未公开的信息。怎样让回测只使用当时市场真正能看到的数据?

03三个时间和一个约束

  1. 报告期(period):数据描述的是哪段时间,例如半年报的报告期截止日。
  2. 公告时间(publish time):这份信息何时向市场公开。若公告在收盘后,严格回测通常从下一个交易日开始使用。
  3. 入库时间(knowledge time):自己的系统何时成功拿到并可用这条数据。系统漏采后补录时,入库时间可能晚于公告时间。

站在回测日 as_of 看数据,至少要满足:公告时间不晚于 as_of,入库时间也不晚于 as_of。因此不能只按报告期关联。

现行规则中,证监会《上市公司信息披露管理办法》(证监会令第 226 号)第十三条规定:年度报告应在会计年度结束之日起四个月内编制完成并披露;中期报告应在上半年结束之日起两个月内编制完成并披露。季度报告的披露期限由交易所上市规则规定:上交所、深交所现行主板规则均规定,第一季度和第三季度报告在相应季度结束之日起一个月内披露,且第一季度报告不得早于上一年度年度报告。具体公司还可能受预约披露、规则修订和特殊事项影响,使用时应以当时适用的监管规则和公司公告为准。

业绩预告、业绩快报和正式报告是不同的信息版本,可能在不同时间公开。回测不能把后来的正式值替换到更早日期,也不能把预告区间当成正式报告的精确值。

04追溯调整与双时间

公司后来可能因会计政策变化、合并范围变化或差错更正,重新列示以前期间数据。因此同一报告期可能有多个版本:首次公布值、更正值和后续报告中的重述值。

严谨的 PIT 表至少要保留:

entity_id       公司或证券
period_end      数据描述的报告期结束日
value           指标值
published_at    对市场公开的时间
ingested_at     系统可用的时间
version         版本或公告标识
valid_reason    首次披露 / 更正 / 重述等原因

查询时同时指定报告期和 as_of:先筛选 published_at <= as_of 且 ingested_at <= as_of 的版本,再按规则取截至该时点最新可用版本。只存当前最新值,会让历史回测看到后来才出现的修订数据。

05一个最小查询示例

import pandas as pd

facts = pd.DataFrame([
    # 同一报告期的首次披露和后续更正,是两个版本
    {"period_end": "2024-12-31", "value": 100,
     "published_at": "2025-03-28", "ingested_at": "2025-03-28",
     "version": "initial"},
    {"period_end": "2024-12-31", "value": 96,
     "published_at": "2025-08-15", "ingested_at": "2025-08-15",
     "version": "restated"},
])

facts["published_at"] = pd.to_datetime(facts["published_at"])
facts["ingested_at"] = pd.to_datetime(facts["ingested_at"])
as_of = pd.Timestamp("2025-04-01")

available = facts[
    (facts["published_at"] <= as_of) &
    (facts["ingested_at"] <= as_of)
]
point_in_time = available.sort_values("published_at").tail(1)

站在 2025-04-01,只能使用首发值 100;站在 2025-09-01,才可以使用 8 月 15 日公开的修订值 96。示例数字是教学假设。

把财务数据和行情对齐时,公告日还要经过交易日历处理:盘后公告不能假设当天收盘前已经可交易。股票池、指数成分、风险警示状态和行业分类也有同样的时点问题;使用今天的成分股回看过去,会产生幸存者偏差。

06常见误区

  1. 用报告期末作为数据可用日,直接造成前视偏差。
  2. 只存每个报告期的最新值,覆盖首次披露和历史更正。
  3. 忽略公告具体时刻,把盘后公告用于当天收盘前的交易决策。
  4. 只防财务数据前视,却使用今天的股票池、指数成分或分类回测过去。
  5. 不记录入库时间,假设公告一发布系统就已经拿到数据。
  6. 使用前复权价格做价格阈值判断时忽略未来公司行为带来的信息穿越。

07延伸阅读

08一分钟讲给别人

试着用自己的话讲一遍财报描述的是过去一段时间,但通常不会在那段时间结束时马上公开。回测站在 7 月 1 日,不能因为半年报报告期是 6 月 30 日就提前使用它;要看公告日,而且盘后公告通常从下一个交易日才有交易意义。公司后来还可能重述旧数据,所以要保存每个版本,用 `as_of` 查询当时可知的那一个。

想一想

6 道自测

先在心里答一遍,再展开对照。能说清理由,比答对数字更重要。

  1. 01报告期、公告时间和入库时间分别表示什么?

  2. 02为什么不能按报告期末关联财务数据?

  3. 03现行规则下,年报和中期报告的披露期限分别是什么?

  4. 04盘后发布的公告,回测通常最早从哪天使用?

  5. 05为什么只保存最新值会让回测失真?

  6. 06前视偏差和幸存者偏差有什么共同点?

已看 0/6 题

练动手练习

任务:为一份包含首次披露和后续重述的财务数据增加 published_at、ingested_at 和 version。分别用 2025-04-01、2025-09-01 查询,确认两次得到的版本不同;再加入一个收盘后公告,按交易日把最早可用日推到下一个交易日。

完成这一课

完成这一课

读完讲义、看完自测答案,这一课就算学完了。

  • 读完讲义
  • 看完全部自测

本课为投资者教育内容,案例数字均为示意,不构成任何投资建议,也不承诺收益。规则和费率会变,实际操作前请以交易所、监管机构和产品的最新公告为准。