---
title: "这些数字从哪来：申报文件，以及它们何时公开"
description: "站内每个数字都始于一份申报。EDGAR 给什么、回退源补什么、为什么每一行都要存下它公开的那一刻，以及会让八年表格出错的两件事。"
date: 2026-09-21
updated: 2026-09-21
tags: [filings, methodology, basics]
author: "Allen Yan"
image: https://sweetvaluelab.com/blog/img/ba95d0567743879c.png
lang: zh-Hans
canonical: https://sweetvaluelab.com/blog/zh/where-the-numbers-come-from
---

估值模型是容易的那一半。本站每晚在 518 家公司上跑十二个模型，算术从来不是出问题的地方。出问题的是：一个拆股之前的股数被摆在今天的股价旁边；同一个财年在一张表里出现两次，因为两个数据源给它起了不一样的名字；一个二月才公布的数字，被当成一月就能知道的东西展示出来。

这篇讲的就是那另一半：站内每个数字从哪来，在送到你屏幕之前被做了什么，哪些部分是尽力而为。它是[十二个模型那篇](https://sweetvaluelab.com/blog/zh/how-we-value-a-stock)的配套，而且里面的例子全是真实的代码、真实的日期——因为每一个都先是一个 bug。

## 两个数据源，有固定的先后

财务报表读的是公司自己在 SEC EDGAR 上的 XBRL 申报。这是首选源：10-K 和 10-Q，按公司自己打的标签，跟一个人翻文件看到的数字是同一个。EDGAR 覆盖不到的申报人，以及某些更早的年份，缺口由 Financial Modeling Prep 补上。

这两个源交回来的东西并不一样，而其中一处差别大到需要一个专门的函数。EDGAR 给你的是**申报原值**。FMP 给你的是已经按此后所有拆股复原过的值。英伟达 FY2019 那一行，FMP 读出来是 250 亿股上每股 $0.17；公司 2019 年真正申报的是 6.25 亿股上每股 $6.63。两个说的是同一年。如果把 FMP 那一行再按拆股调整一次（代码对 EDGAR 行就是这么做的），就会再除一遍 4，得到一个哪里都不存在的数字。所以代码靠「EDGAR 映射器从不产出的字段」把两类行分开，只有原值那一类会被调整。

## 每一行都知道自己是什么时候公开的

每一行入库都带一个 `known_at`：它来自的那份申报被受理的时间戳。绝不是我们抓取它的时刻。

这是一行代码，它决定了历史视图有没有意义。一个季度在 6 月 30 日结束。10-Q 在 8 月 5 日被受理。这五个星期里，那些数字在公司外面并不存在，而一个把它们摆在 7 月股价旁边的页面，描述的是一个谁也没法交易的世界。

![一个季度结束，五周后申报被受理，13F 则在它所描述的季度之后 45 天才到](https://sweetvaluelab.com/blog/img/4436b38508a6f209.svg "示意图。季报在它覆盖的期间结束之后数周才被受理；13F 持仓报告的截止期是季末后 45 天，所以投资人页上最新的持仓，可能描述的是六周前的组合。入库的每一行都带着受理时间戳，所以任何一个过去日期的视图，只会显示那时已经申报过的东西。")

最极端的是 13F。一位管理人的持仓报告在它所描述的季度结束后 45 天才到期，也就是说，任何人手上关于伯克希尔或桥水最新的持仓，在它出现的那天就已经可以是六周前的了。这是披露制度本身的事实。在把某个仓位的变动当成新闻之前，值得先知道这一点。

## 拆股在读出来的时候才调整

苹果 FY2019 申报的每股盈利是 $11.89。它 FY2020 的申报写的是 $3.28。中间没发生什么坏事：2020 年 8 月有一次一拆四，两行的分母是不同的股。

入库的行严格保持申报原样，所以复原发生在读取的时候。每股类字段被除以「该行财年日期之后所有拆股的累乘比例」，股数类字段乘以同一个比例。被动过的行会带一个标记说明倍数是多少，页面因此可以把这件事讲出来。

这样修掉两件事。一是八年 EPS 走势图上不再有一个从未发生过的断崖。二是模型不会再拿申报股数去配今天的股价——Booking Holdings 那次一拆二十五，当时页面上每个模型印出来的都是股价的 25 倍。

## 表里的八年应该真的是八年

这一个我事先没想到。报表缓存以「代码 + 期间 + 财年日期」为键，而同一个财年会以不止一个日期到达。

52/53 周财年的公司，年度结束在月末附近的某个周六。开市客（Costco）FY2019 结束在 9 月 1 日，FMP 把这一年标成 2019-08-31，EDGAR 标成 2019-09-01。Ciena 的 FY2019 从一个源来是 2019-10-31，从后来一份 10-K 的比较列来是 2019-11-02。安捷伦（Agilent）采用了一项会计准则变更，把一个期初余额打在年末的第二天，于是 2018-10-31 和 2018-11-01 同时存在。没有谁是错的。一个想看「最近八年」的读者拿到的是十行，其中两行是重复，而跨着一行重复算出来的增速是垃圾。

![三行日期相差一两天的记录收敛成一个财年，留下字段最多的那一行](https://sweetvaluelab.com/blog/img/63b1e68806d5b90b.svg "财年日期相差在 14 天以内的行视为同一期间。开市客 FY2019 以 2019-08-31 和 2019-09-01 两个日期到达；胜出的是数值字段最多的那一行——一个老年份的 EDGAR 副本可能只有寥寥几个标签，开市客 2019 年的现金流量表只有六个，引擎吃到那一行就彻底失去自由现金流和资本开支。打平时，先申报的那一行胜出。")

所以在读取时，财年日期相差 14 天以内的行被当作同一个期间。一个季度大约 90 天，所以这个窗口不可能把两个真正相邻的期间并掉。胜出的是数值字段最多的那一行，打平则取先申报的那一行，也就是原始的时点申报优先于后来的比较列。

## 投资人页背后的四种申报

[投资人页](https://sweetvaluelab.com/investors)和每支股票的内部人标签页，是由四种申报建起来的，全部直接读 EDGAR。每一种都有自己的口径，也都有自己说不了的事。

**13F 持仓。** 读每位管理人的 13F-HR，作为不可变的季度快照存下来。季度环比的变化（新建、加仓、减仓、清仓）是在这里由相邻两个快照算出来的。13F 只覆盖美股多头：没有空头、没有债券、没有海外上市、没有现金。报告用 CUSIP 标识证券，而 CUSIP 到股票代码的映射是本站手工维护的一张表；映射不到的就按申报里的发行人名称显示。

**13D 与 13G。** 受益所有权申报，按标的公司读。13D 意味着带意图的主动持股，13G 意味着被动持股。持股百分比取自封面页上申报人写的那个数，这件事天然就是尽力而为。

**8-K。** 重大事件。条目代码取自 EDGAR 的申报索引，不从文档正文里解析。这样枯燥得多，也可靠得多：不管正文那段话是谁写的，条目 5.02 就是董事或高管发生了变动。

**Form 4。** 内部人交易，从所有权文档本身解析。这比读一个汇总接口费事，换来的是大多数免费数据源会丢掉的两个字段：SEC 交易代码，于是公开市场买入能跟期权行权、代扣税股区分开；以及 10b5-1 标记，它说明这笔交易是按事先设立的计划执行的。一笔按八个月前就定好的计划卖出的股票，和一笔上周二临时决定卖出的股票，是两件不同的事。

## 金额按原始数字存

金额就按它本来的数字入库，格式化留到浏览器里最后一刻。任何东西在被计算之前都不会先被四舍五入。估值、行业体检板、情绪读数这些快照是不可变的，并且盖上产生它的代码版本号，所以站内在某个过去日期显示过的任何数字都可以重新跑出来。

这就是全部的约定。原始申报、按公开时刻打上时间戳、只在讲明白的地方做调整、存成可以再跑一遍的样子。[十二个模型](https://sweetvaluelab.com/blog/zh/how-we-value-a-stock)坐在这一层上面，它们的上限就是这一层的质量。
