美股 10-K 财报文本与 SEC 公告怎么批量下载?免爬 EDGAR 的 FMP 原始文件检索与 CIK/CUSIP/ISIN 编码映射方案(SEC Filings API)
做美股基本面投研、大模型美股财报文本 RAG 问答或事件驱动量化回测时,团队迟早要直接调取美国证监会(SEC)的 10-K 年报、10-Q 季报、20-F 外国发行人年报与 8-K 重大事件公告原文,并将内部证券主表中的股票代码(Ticker)与 SEC 的 CIK 编号、彭博/13F 持仓的 CUSIP 以及跨国清算的 ISIN 编码对齐。如果直接去写爬虫抓 SEC EDGAR 官方目录,不仅要应对严格的请求频控、索引页跳转与复杂的 iXBRL 嵌套标签,还会频繁在“一企多股、一码多市场”的编码映射上踩坑。
本文基于 FMP数据源中文站 对 FMP 旗下 SecFilings(SEC 文件接口)、Search(证券搜索接口)、Directory(基础目录接口)、Company(公司资料接口) 与 Statements(财务报表接口) 五大模块的实盘采样(实盘数据快照截至 2026-11-10 14:59 UTC),梳理出一套免爬 EDGAR 的 SEC 原始文件检索与四码互查工程方案,并重点揭示三项实测排雷结论:
- 四码互查不能做简单的“1 对 1”字典映射:实测伯克希尔(CIK 为 0001067983)与 Alphabet(CIK 为 0001652044)在单一 CIK 下分别挂载多只不同股份类别代码,而单查英伟达 CUSIP(67066G104)会同时返回美股主板、法兰克福/德交所跨市场挂牌及 5 家伦敦/欧洲市场无关公司串码共 8 条记录;此外苹果(037833100)、微软(594918104)、伯克希尔 B(084670702)的 9 位 CUSIP 为纯数字,若路由层直接按“全数字即 CIK”分流会触发静默查空。
- 按股票代码拉取 SEC 申报流时,6 家样本中有 5 家高管内部交易 Form 4 占比高达 60%~92%(BRK-A 为 27%):实测
/stable/sec-filings-search/symbol单页(100 条)中,微软、Alphabet、台积电的 Form 4 记录分别占到 76 条、74 条与 92 条,导致 Alphabet 的 2025 财年 10-K 与台积电的 20-F 年报被挤到第 3 页(需翻页扫描 300 条);同时 Alphabet 在 2026 年内于美东时间 20:29~21:56 提交的 10-K 与 10-Q 样本,因突破 SEC 当日 17:30 截点,其filingDate均比接收时间acceptedDate顺延至下一个工作日。 - 10-K 原生全表 JSON 可免解析直取 70~112 张披露附注表,但需防范
period索引差异与二进制流响应头伪装:实测苹果 FY2026 的/stable/financial-reports-json直接返回 82 个顶层键(含 79 张主表与附注细分表),但英伟达 FY2026 的 10-K 年报在/stable/financial-reports-dates中并未挂载于period=FY,而是归入period=Q4;同时/stable/financial-reports-xlsx虽返回标准 ZIP/XLSX 二进制流,其 HTTP 响应头Content-Type却标记为application/json,客户端须直接按二进制流落盘。
直接去 SEC EDGAR 抓取美股 10-K 年报、10-Q 季报与 8-K 公告,为什么容易卡在限流与编码映射上?
许多量化与 AI 投研团队在起步阶段会尝试直接连接 SEC 官方的 data.sec.gov 或 sec.gov/Archives/edgar/data/ 抓取美股财报文本,但在生产环境跑批时通常会撞上四道工程墙:
- 强制请求头校验与 10 次/秒频控封禁:SEC 网关要求所有自动化请求必须携带特定格式的声明式
User-Agent(含机构名与联系邮箱),且单 IP 峰值严格限制在 10 req/s 以内,一旦并发超限即对源 IP 实施临时封禁。 - EDGAR 仅以 CIK 编号寻址,不支持直接用股票代码、CUSIP 或 ISIN 查询:SEC 底层归档目录与
submissions接口完全以发行人中央索引键(CIK 编号)组织。虽然 SEC 提供了一份静态company_tickers.json映射表,但该表仅提供 Ticker 到 CIK 的映射,完全不包含 CUSIP(9 位北美证券统一编码,13F 机构持仓报告的唯一证券标识)与 ISIN(12 位国际证券识别编码)。 - 索引页跳转与高管交易表单洪流:在 EDGAR 原始归档目录中,每次申报包含
-index.htm索引页与多个主附表文件;同时公司申报流中夹杂大量高管内部交易 Form 4 表单,按单股回溯定期报告需穿透大量非财务表单。 - iXBRL 附注表格解析成本高:现代美股 10-K 年报动辄上百页,内部嵌入数千个自定义 XBRL Taxonomy 轴(Axis/Member)。要想从原始 HTML 中完整拆出分产品营收、地区收入、租赁到期结构、递延税项与债务期限表,自研解析器的维护成本很高。
下表对比了自建 SEC EDGAR 抓取管线与调用 FMP SEC Filings 及配套接口的工程实现差异:
| 对比维度 | 自建 SEC EDGAR 抓取方案 | FMP SEC Filings 与编码映射方案 | 核心端点与字段支撑 |
|---|---|---|---|
| 证券编码寻址 | 仅支持 CIK 编号;缺 CUSIP / ISIN 互查 | 原生支持 Ticker、CIK、CUSIP、ISIN、名称互查 | /stable/profile、/stable/search-cik、/stable/search-cusip、/stable/search-isin |
| 原文与附件直链 | 需结合提交元数据或 -index.htm 拼装路径 | 同时返回索引页 link 与目标文件直链 finalLink(10-K 直达正文,财报 8-K 常直达 EX-99.1) | /stable/sec-filings-search/symbol、/stable/sec-filings-search/cik |
| 按表单类型检索 | 需下载全市场每日 Master Index 离线清洗 | 支持按 formType 跨市场拉取或直调最新 8-K 流 | /stable/sec-filings-search/form-type、/stable/sec-filings-8k |
| 财报事件过滤 | 需下载 8-K 正文正则匹配 Item 2.02 | 原生提供布尔字段 hasFinancials 标记含财报公告 | /stable/sec-filings-8k、/stable/sec-filings-financials |
| 10-K 全表结构化 | 需自研 iXBRL 解析器拆解数十张附注表 | 一键拉取 10-K 全表 JSON 或下载原生 XLSX | /stable/financial-reports-dates、/stable/financial-reports-json、/stable/financial-reports-xlsx |
| SIC 行业与监管归属 | 需从提交头部文本提取 4 位 SIC 编码 | 直接返回 4 位 sicCode、行业名称及 SEC 审查办公室 | /stable/sec-profile、/stable/standard-industrial-classification-list |
跨数据库关联美股证券时,如何用 API 一键打通 Ticker、CIK、CUSIP 与 ISIN 四套编码互查?
在构建多源融合的金融数据库时,开发者经常遇到“如何查询 CUSIP”、“ISIN 有没有 API 可以查询”以及“如何把 13F 持仓表里的 CUSIP 或 SEC 的 CIK 编号批量映射回美股行情代码(Ticker)”等工程问题:行情系统通常用 Ticker(股票代码),SEC 财报与 13D/13G 公告用 10 位 CIK 编号(Central Index Key),13F 机构持仓与北美清算系统用 9 位 CUSIP,而全球多市场组合管理则用 12 位 ISIN(美股通常为 US + 9 位 CUSIP + 1 位校验码)。
在 FMP 的 Company(公司资料接口)、Search(证券搜索接口) 与 Directory(基础目录接口) 下,共有 8 个核心端点协同完成四码映射:
- 单股全景四码快照:Company Profile Data(公司概况接口,
/stable/profile?symbol=AAPL)与 Company Profile by CIK(按 CIK 查公司概况接口,/stable/profile-cik?cik=0000320193),单次请求即可在返回对象中同时拿到symbol、cik、cusip、isin、exchange与isAdr。 - 单维编码反查与模糊检索:Search Cik(CIK 检索接口,
/stable/search-cik)、CUSIP(CUSIP 检索接口,/stable/search-cusip)、Search Isin(ISIN 检索接口,/stable/search-isin)、Stock Symbol Search(股票代码检索接口,/stable/search-symbol)、Company Name Search(公司名称检索接口,/stable/search-name),以及全量枚举字典 CIK List(CIK 编号清单接口,/stable/cik-list?page=0&limit=1000)。
我们对苹果(AAPL)、英伟达(NVDA)、微软(MSFT)、伯克希尔 A/B 股(BRK-A / BRK-B)、Alphabet A/C 股(GOOGL / GOOG)与台积电 ADR(TSM)共 8 只代表性标的进行了四码映射与反查实测,结果汇总如下(数据快照截至 2026-11-10 14:59 UTC,对应字段为 symbol、cik、cusip、isin、exchange 与 isAdr):
| 股票代码 | 发行人名称 | 10 位 CIK 编号 | 9 位 CUSIP 编码 | 12 位 ISIN 编码 | 主板与 ADR 属性 | 反查接口实测命中数与排雷特征 |
|---|---|---|---|---|---|---|
| AAPL | Apple Inc. | 0000320193 | 037833100 | US0378331005 | NASDAQ / 非 ADR | search-cik 命中 2 条(含多伦多 AAPL.TO);search-cusip 命中 4 条;search-isin 命中 5 条 |
| NVDA | NVIDIA Corporation | 0001045810 | 67066G104 | US67066G1040 | NASDAQ / 非 ADR | search-cusip 命中 8 条(除美股 NVDA 与德交所 NVD.F/NVD.DE 外,混入 0QOJ.L 等 5 家欧洲无关公司串码) |
| MSFT | Microsoft Corporation | 0000789019 | 594918104 | US5949181045 | NASDAQ / 非 ADR | 9 位 CUSIP(594918104)为纯数字,切勿当作未补零 CIK 传给 profile-cik |
| BRK-A | Berkshire Hathaway Inc. | 0001067983 | 084670108 | US0846701086 | NYSE / 非 ADR | 与 BRK-B 共享同一 CIK(0001067983),但拥有独立的 CUSIP 与 ISIN |
| BRK-B | Berkshire Hathaway Inc. | 0001067983 | 084670702 | US0846707026 | NYSE / 非 ADR | 调 profile-cik?cik=0001067983 仅返回单条默认记录 BRK-B,需用 search-cik 拿全双股 |
| GOOGL | Alphabet Inc. | 0001652044 | 02079K305 | US02079K3059 | NASDAQ / 非 ADR | search-cik?cik=0001652044 命中 4 条(GOOG、GOOGL、GOOGM、GOOGN) |
| GOOG | Alphabet Inc. | 0001652044 | 02079K107 | US02079K1079 | NASDAQ / 非 ADR | 与 GOOGL 共享 CIK(0001652044),靠 CUSIP 末三位 107 与 305 精准区分 C 股与 A 股 |
| TSM | Taiwan Semiconductor Mfg. | 0001046179 | 874039100 | US8740391003 | NYSE / ADR(true) | 虽为中国台湾企业,美股 ADR 仍分配 US 开头 ISIN 与 10 位 SEC CIK,年报走 20-F |
在将上述接口接入生产证券主表(Security Master)时,必须重点处理以下四项实测边界:
- CIK 补零兼容性(Unpadded vs 10-Digit Zero-Padded):SEC 规范的 CIK 为 10 位定长前导零字符串(如苹果为 0000320193),而不少外部 CSV 表在经过 Excel 保存后会丢失前导零变成整数 320193。实测表明,FMP 的
/stable/search-cik、/stable/profile-cik、/stable/sec-filings-company-search/cik与/stable/sec-filings-search/cik四个端点同时兼容不补零(cik=320193)与 10 位补零(cik=0000320193)传参,且返回报文中的cik字段统一标准化为 10 位前导零格式。 - “一企多股”陷阱:单调
profile-cik会漏掉同发行人下的其他股份类别:CIK 标识的是法律申报主体(Entity),而 CUSIP 与 ISIN 标识的是具体证券(Issue)。如上表所示,伯克希尔 A 股(BRK-A)与 B 股(BRK-B)共用 CIK 0001067983;如果直接调用/stable/profile-cik?cik=0001067983,接口仅返回单元素数组(默认取 BRK-B),导致 BRK-A 被静默丢弃。正确做法是先调/stable/search-cik?cik=0001067983获取该主体下的全部挂牌代码(返回 BRK-A 与 BRK-B 共 2 条;Alphabet 的 0001652044 则返回 GOOG、GOOGL、GOOGM、GOOGN 共 4 条),再按目标symbol调/stable/profile补齐各自的cusip与isin。 - “一码多市场”与跨库串码清洗:调
search-cusip与search-isin后必须过滤海外挂牌与错误映射:同一只美股的 CUSIP 或 ISIN 常被法兰克福(.F)、德意志交易所(.DE)、墨西哥(.MX)、维也纳(.VI)等海外市场直接沿用。例如实测/stable/search-cusip?cusip=037833100返回 AAPL.MX、AAPL、APC.F、APC.DE 共 4 条记录,且美股主场 AAPL 排在数组第 2 位;更典型的是查询英伟达/stable/search-cusip?cusip=67066G104时,返回的 8 条记录中除美股 NVDA 及德交所 NVD.F、NVD.DE 共 3 条确属英伟达外,还混入了 0QOJ.L(Peach Property Group AG)、0A0L.IL(Sectra AB)、0QDX.IL(AB Sagax)、0QN1.L(Santhera Pharmaceuticals)、0QQN.L(Bucher Industries)共 5 家伦敦/欧洲市场无关公司的错误映射记录。因此,拿到search-cusip或search-isin的返回数组后,绝不能盲取res[0],必须优先筛选不含.后缀的美股原生代码,并回查/stable/profile校验exchange与目标标识是否吻合。 - 9 位纯数字 CUSIP 与未补零 CIK 的路由冲突:英伟达(67066G104)与 Alphabet(02079K305)的 CUSIP 含英文字母,很容易识别;但苹果(037833100)、微软(594918104)、伯克希尔 A/B(084670108 / 084670702)和台积电(874039100)的 9 位 CUSIP 全部由纯数字组成。如果自动转换函数简单写成
if token.isdigit(): call_profile_cik(token),传入伯克希尔 B 的 CUSIP(084670702)就会被误判为 CIK 0084670702 并返回空数组[]。工程上遇到长度为 9 且含数字的编码时,应优先走/stable/search-cusip试探,未命中时再回退至 CIK 分支。
免爬 EDGAR 索引库:如何按股票代码、CIK 或表格类型(Form Type)批量获取 SEC 原始申报链接与接收时间戳?
完成编码对齐后,即可通过 SecFilings(SEC 文件接口) 下的 5 个检索端点直接获取 SEC 原始申报元数据与文档直链:
- 按单股或发行人回溯历史申报流:SEC Filings By Symbol(按代码查 SEC 申报接口,
/stable/sec-filings-search/symbol)与 SEC Filings By CIK(按 CIK 查 SEC 申报接口,/stable/sec-filings-search/cik),必传from、to日期窗口,并支持page与limit(单页最大 100 条)分页。 - 按表单类型或全市场实时流批量扫描:SEC Filings By Form Type(按表格类型查 SEC 申报接口,
/stable/sec-filings-search/form-type?formType=10-K)、Latest 8-K SEC Filings(最新8-K申报文件接口,/stable/sec-filings-8k)与 Latest SEC Filings(最新SEC申报接口,/stable/sec-filings-financials)。
我们以 from=2025-01-01&to=2026-11-10 窗口对 6 家代表性公司进行了实盘拉取(数据快照截至 2026-11-10 14:59 UTC;注:BRK-A 与 BRK-B 共享同一 CIK 0001067983,二者底层 SEC 申报流完全一致),下表展示了各标的在首页(page=0&limit=100)的表单分布结构,以及定位到的最新年报(10-K / 20-F)与最新当期报告(8-K / 6-K)实测时间戳(对应字段为 formType、filingDate、acceptedDate 与 finalLink):
| 股票代码 | 首页 100 条中 Form 4 占比 | 查到最新年报所需扫描页数 | 最新年报类型与归档日期 | 最新年报精确接收时间 | 最新 8-K/6-K 接收时间 | SEC 年报主文档直链(finalLink 尾部文件名) |
|---|---|---|---|---|---|---|
| AAPL | 60 / 100(60.0%) | 1 页(100 条) | 10-K / 2026-11-03 | 2026-11-03 08:05:15 | 2026-11-09 16:30:40 | .../000032019326000026/aapl-20260926.htm |
| NVDA | 64 / 100(64.0%,含 1 条 4/A) | 1 页(100 条) | 10-K / 2026-02-25 | 2026-02-25 16:42:19 | 2026-09-03 08:03:56 | .../000104581026000021/nvda-20260125.htm |
| MSFT | 76 / 100(76.0%) | 1 页(100 条) | 10-K / 2026-07-29 | 2026-07-29 16:08:01 | 2026-11-05 06:01:52 | .../000119312526323660/msft-20260630.htm |
| BRK-A | 27 / 100(27.0%) | 1 页(100 条) | 10-K / 2026-03-02 | 2026-03-02 06:02:28 | 2026-11-09 06:10:14 | .../000119312526083899/brka-20251231.htm |
| GOOGL | 74 / 100(74.0%,300 条中占 167 条) | 3 页(300 条) | 10-K / 2026-02-05 | 2026-02-04 21:56:03 | 2026-11-05 16:10:44 | .../000165204426000018/goog-20251231.htm |
| TSM | 92 / 100(92.0%,300 条中占 261 条) | 3 页(300 条) | 20-F / 2026-04-16 | 2026-04-16 06:05:49 | 2026-11-10 08:41:38 | .../000162828026025362/tsm-20251231.htm |
从上表与底层报文对账中,可以提炼出四条直接决定下载管线稳定性的核心机制:
- 区分
link索引页与finalLink目标文件(10-K 直达主表正文,财报日 8-K 常直达 EX-99.1 业绩公报):每条申报记录均包含两个 URL 字段——link指向 SEC 申报目录索引页(如苹果 FY2026 年报的0000320193-26-000026-index.htm),而finalLink则直接指向接口选出的核心目标文件,省去每次先请求-index.htm索引页的二次跳转。但实测需要注意两类表单的落点差异:对于 10-K、10-Q 与 20-F,finalLink均指向完整的财报主文档正文(如aapl-20260926.htm);而对于财报日提交的 8-K(如苹果 2026-11-02 的a8-kex991q4202609262026.htm、微软 2026-10-28 的msft-ex99_1.htm、Alphabet 2026-10-28 的googexhibit991q32026.htm),FMP 的finalLink会直接指向最具信息密度的 Exhibit 99.1 业绩新闻稿附件(若需 8-K 封面主表壳,可通过同条记录的link索引页获取)。 - Form 4 内部人交易挤占单页容量,单股查年报必须实现
page自动翻页:由于/stable/sec-filings-search/symbol接口不支持传入formType参数在服务端过滤,返回结果包含了该公司的全部 SEC 表单(Form 4、Form 3、Form 144、8-K、10-Q、10-K、DEF 14A、424B2 等)。对于高管期权行权与减持频繁的科技股(如 GOOGL 首页 100 条中有 74 条 Form 4 与 9 条 Form 144;TSM 首页 100 条中有 92 条 Form 4),仅查page=0只能覆盖最近 1~5 个月,导致年初披露的 10-K 或 20-F 年报在首页完全不可见(GOOGL 与 TSM 均需翻到page=2即第 3 页才扫出年报)。若业务目标是跨公司拉取某段时间内的全部 10-K,直接调用/stable/sec-filings-search/form-type?formType=10-K效率更高;但需注意,若同一 CIK 下挂载了普通股、权证(Warrant)、配股权(Right)与单元(Unit)(如实测 2026-11-10 披露 10-K 的 SPAC 公司 AlphaTime Acquisition Corp,CIK 为 0001889106),该接口会为 ATMC、ATMCR、ATMCU、ATMCW 返回 4 条指向同一个finalLink的记录,入库前务必按(cik, finalLink)联合主键去重。 - SEC 17:30 ET 截点顺延机制:
filingDate与acceptedDate跨日错位及回测时间对齐边界:根据 SEC EDGAR 规则,常规 10-K、10-Q 与 8-K 若在美东时间工作日 17:30 之后提交(不同于截点为 22:00 的高管交易 Form 3/4/5),系统会将法定归档日filingDate顺延记作下一个工作日(例如苹果于 2026-04-20 17:29:51 提交的 8-K 卡在 17:30 前 9 秒,filingDate仍保持 2026-04-20 当天;同类顺延亦见于 FWP 等表单,如苹果 2026-11-05 21:54:06 提交的 FWP 归档日顺延为 2026-11-06)。实测 Alphabet(GOOGL)在 2026 年内的以下三份定期报告样本均因晚于 17:30 提交而触发了跨日顺延:
- FY2025 10-K 年报:
acceptedDate为 2026-02-04 21:56:03,而filingDate被记为 2026-02-05 00:00:00; - 2026 Q2 10-Q 季报:
acceptedDate为 2026-07-22 21:15:54,而filingDate被记为 2026-07-23 00:00:00; - 2026 Q3 10-Q 季报:
acceptedDate为 2026-10-28 20:29:06,而filingDate被记为 2026-10-29 00:00:00。
在量化回测中需注意:filingDate 顺延属于法定归档日口径,而盘后核心财务数字往往已先通过业绩新闻稿(或附带 EX-99.1 的 8-K)释放;因此数据管线应同时记录 SEC 接收时间 acceptedDate、归档日 filingDate 与本地管线首次观测时间,严格按当时市场实际可得的信息时点对齐交易信号。
- 外国私人发行人(FPI / ADR)表单体系与
hasFinancials精准降噪:像台积电(TSM)等在美挂牌的外国私人发行人(/stable/profile中isAdr: true),通常豁免提交美股常规的 10-K、10-Q 与 8-K,其年度报告主要采用 Form 20-F(如台积电于 2026-04-16 06:05:49 提交的tsm-20251231.htm;部分加拿大发行人采用 Form 40-F,亦有少数外国发行人自愿采用 10-K),月度营收通报、法说会简报与季度财务摘要则装入 Form 6-K(台积电在 400 条记录中共有 64 份 6-K)。此外,在监控全市场实时公告时,调用/stable/sec-filings-8k与/stable/sec-filings-financials会额外返回布尔字段hasFinancials——例如 2026-11-10 当日最新 8-K 流中,Alpha Pro Tech(APT,09:41:00)的hasFinancials为true(附带财报数据),而 Allison Transmission(ALSN,09:00:39)等不含财务报表的 8-K 公告其hasFinancials为false,可直接用该字段过滤掉非财报类公告。
不想自己解析 HTML 表格?如何直接拉取结构化的 10-K 年报全表数据(Form 10-K JSON / XLSX)与 SIC 行业分类?
如果投研场景不仅需要 10-K 原文链接,还希望直接把 10-K 年报里的所有财务主表与附注细分表(如按产品线拆分的营收、租赁负债到期日结构、递延税项调节表、期权激励汇总表)提取为结构化数据,无需自己写 BeautifulSoup 或 XBRL 解析器,可以直接调用 Statements(财务报表接口) 下的三件套:
- Financial Reports Dates(财报披露日期接口,
/stable/financial-reports-dates?symbol=AAPL):查询目标公司已收录的全部结构化财报年份(fiscalYear)与周期(period)。 - Financial Reports Form 10-K JSON(10-K年报数据(JSON)接口,
/stable/financial-reports-json?symbol=AAPL&year=2026&period=FY):将整份 10-K 年报中的所有 XBRL 披露表格一次性按章节键名以 JSON 字典返回。 - Financial Reports Form 10-K XLSX(10-K年报下载(XLSX)接口,
/stable/financial-reports-xlsx?symbol=AAPL&year=2026&period=FY):将整份 10-K 的全部工作表打包导出为原生 Excel(.xlsx)二进制文件。
同时,配合 SecFilings(SEC 文件接口) 下的 SEC Company Full Profile(SEC 公司完整档案接口,/stable/sec-profile)、Industry Classification List(行业分类清单接口,/stable/standard-industrial-classification-list)、Industry Classification Search(行业分类检索接口,/stable/industry-classification-search)与 All Industry Classification(全行业分类数据接口,/stable/all-industry-classification),还能直接获取 SEC 官方的 4 位标准产业分类(SIC Code)与所属审查办公室。
我们对苹果(AAPL)、微软(MSFT)与英伟达(NVDA)的最新年度 10-K 结构化报表及 SIC 档案进行了实测对账,核心指标汇总如下:
| 股票代码 | SIC 编码与官方行业名称 | financial-reports-dates 收录期数 | 最新年报调用参数(year / period) | 10-K JSON 顶层键总数(含披露表数) | 核心主表与附注细分表实测抽样对账(单位:百万美元) |
|---|---|---|---|---|---|
| AAPL | 3571 / Electronic Computers | 67 期(含 14 个 FY) | year=2026 / period=FY | 82 个键(79 张表,XLSX 为 1.62 MB) | 主表 CONSOLIDATED STATEMENTS OF OPER:总营收 478,834(产品 355,533 + 服务 123,301),净利润 132,175,稀释 EPS 8.98;附注表 Revenue - Disaggregated Net Sal:iPhone 254,098 + Mac 37,929 + iPad 27,929 + 可穿戴与配件 35,577 + 服务 123,301 = 478,834(另有期初递延收入本期确认说明项 8,717,属总营收子集不参与加总) |
| MSFT | 7372 / Services-Prepackaged Software | 76 期(含 16 个 FY) | year=2026 / period=FY | 115 个键(112 张表) | 含 INCOME STATEMENTS、BALANCE SHEETS、CASH FLOWS STATEMENTS、Pay vs Performance Disclosure、Cybersecurity Risk Management 等 112 张披露节点 |
| NVDA | 3674 / Semiconductors & Related Devices | 64 期(仅 2025 及以前标 FY) | year=2026 / period=Q4(传 FY 报错) | 92 个键(89 张表,FY2025 为 94 个键) | 封面表 Cover Page 明确标注 Document Type 为 10-K、Document Period End Date 为 Jan. 25, 2026、Document Fiscal Period Focus 为 FY;含 Groq、Stock-Based Compensation 等专题附注表 |
在实际调用这组高阶结构化接口时,有三个极具价值的工程细节需要注意:
- 绝不能盲目硬编码
period=FY,必须先用financial-reports-dates探路:实测苹果(FY2026 截至 2026-09-26)与微软(FY2026 截至 2026-06-30)在/stable/financial-reports-dates中同时存在period="FY"与period="Q4"两条记录,传year=2026&period=FY可正常拉回全量 10-K JSON;但对于英伟达(FY2026 截至 2026-01-25),如果你直接请求/stable/financial-reports-json?symbol=NVDA&year=2026&period=FY,接口会返回无数据错误提示!回查/stable/financial-reports-dates?symbol=NVDA可见,英伟达 2025 财年及以前的年报归在period="FY"下,唯独最新的 2026 财年 10-K 年报被归档在fiscalYear=2026与period="Q4"名下(打开该 Q4 JSON 的封面表 Cover Page 可证实其 Document Type 确为 10-K 且 Document Fiscal Period Focus 为 FY)。因此,自动化脚本应先拉取financial-reports-dates,优先匹配目标财年的 FY,若该财年无 FY 则自动回退读取 Q4。 financial-reports-xlsx的二进制流落盘防呆:实测调用/stable/financial-reports-xlsx?symbol=AAPL&year=2026&period=FY(返回 1,618,958 字节)与year=2025&period=FY(返回 1,399,564 字节)时,虽然 HTTP 状态码为 200 且前 8 字节魔数(Magic Number)为标准的 ZIP/XLSX 文件头504b030414000000(即PK\x03\x04),但服务端返回的 HTTP 响应头Content-Type却被标记为application/json。在 Python 中切勿对其调用resp.json()或.decode("utf-8")(会直接抛出UnicodeDecodeError),而应直接将原始bytes以"wb"模式写入.xlsx文件。- 444 个 SEC 标准 SIC 行业与 9 大审查办公室(Review Office)映射:实测
/stable/standard-industrial-classification-list共返回 444 个 SEC 官方标准产业分类编码(SIC Code),并明确标注了每个行业在 SEC 公司金融部(Division of Corporation Finance)下属 9 个专业审查办公室的归属分布:其中制造业办公室(Office of Manufacturing)辖 153 个 SIC 行业,贸易与服务办公室(Office of Trade & Services)辖 106 个,生命科学办公室(Office of Life Sciences)辖 47 个,科技办公室(Office of Technology)与能源交通办公室(Office of Energy & Transportation)各辖 42 个,金融办公室(Office of Finance)辖 26 个,地产建筑办公室(Office of Real Estate & Construction)辖 24 个,国际公司金融办公室(Office of International Corp Fin)辖 3 个,结构化金融办公室(Office of Structured Finance)辖 1 个。在研究 SEC 问询函(Comment Letters)风格或按监管口径做同业可比筛选时(例如调用/stable/industry-classification-search?sicCode=3571一键筛出苹果 AAPL 与戴尔 DELL 等全部电子计算机硬件申报主体),SIC 体系比商业 GICS 分类更贴合 SEC 原始监管边界。
如何用 Python 构建“四码自动转换 + 8-K/10-K 最新申报实时监控”自动化管线?
下面我们将前文验证过的四项核心逻辑——① 兼容 Ticker / CIK / 纯数字 9 位 CUSIP / 12 位 ISIN 的智能四码路由与跨市场除噪(含查空防崩保护)、② 按实际申报流自动识别年报(10-K / 20-F / 40-F)与当期报告(8-K / 6-K)并翻页穿透 Form 4 噪音(最多扫 4 页 400 条)、③ 定位最新年报与当期公告的 acceptedDate 与 finalLink,以及 ④ 自动探测 financial-reports-dates 中的 FY / Q4 结构化 10-K 入口——封装为一段零外部依赖、可直接复制运行的固定窗口检索示例脚本(注:本函数面向“给定标识→单一证券”场景;若输入为挂有多只股份类别的发行人 CIK 且用于构建证券主表,请先按第 2 节方法调用 search-cik 枚举全部股类;若仅查发行人公告则可直接调 sec-filings-search/cik)。
运行前请先在终端设置环境变量 export FMP_API_KEY="你的密钥"(Windows PowerShell 使用 $env:FMP_API_KEY="你的密钥"):
import json, os, urllib.request
BASE_URL, API_KEY = "https://quote-fmp.com/stable", os.environ["FMP_API_KEY"]
def fmp_get(path, params):
q = "&".join(f"{k}={v}" for k, v in {**params, "apikey": API_KEY}.items())
req = urllib.request.Request(f"{BASE_URL}/{path}?{q}", headers={"User-Agent": "Mozilla/5.0"})
with urllib.request.urlopen(req, timeout=20) as resp:
return json.loads(resp.read().decode("utf-8"))
def resolve_security_id(raw_id):
token = raw_id.strip().upper()
if len(token) == 12 and token[:2].isalpha():
hits = fmp_get("search-isin", {"isin": token})
us_sym = next((h["symbol"] for h in hits if "." not in h["symbol"]), hits[0]["symbol"]) if hits else None
prof = fmp_get("profile", {"symbol": us_sym}) if us_sym else []
elif len(token) == 9 and any(c.isdigit() for c in token):
hits = fmp_get("search-cusip", {"cusip": token})
us_sym = next((h["symbol"] for h in hits if "." not in h["symbol"]), hits[0]["symbol"]) if hits else None
prof = fmp_get("profile", {"symbol": us_sym}) if us_sym else fmp_get("profile-cik", {"cik": token.zfill(10)})
else:
prof = fmp_get("profile-cik", {"cik": token.zfill(10)}) if token.isdigit() else fmp_get("profile", {"symbol": token})
if not isinstance(prof, list) or not prof: return {"input_id": raw_id, "error": "NOT_FOUND"}
p, sec_p = prof[0], fmp_get("sec-profile", {"symbol": prof[0]["symbol"]})
sp = sec_p[0] if isinstance(sec_p, list) and sec_p else {}
return {"input_id": raw_id, "symbol": p["symbol"], "cik": p["cik"], "cusip": p["cusip"], "isin": p["isin"],
"exchange": p["exchange"], "isAdr": p["isAdr"], "sicCode": sp.get("sicCode"), "sicDescription": sp.get("sicDescription")}
def audit_company_filings(raw_id, from_date="2025-01-01", to_date="2026-11-10"):
meta = resolve_security_id(raw_id)
if "error" in meta: return meta
sym, ann_set, cur_set = meta["symbol"], {"10-K", "20-F", "40-F"}, {"8-K", "6-K"}
ann, cur, pages, scanned, f4_cnt = None, None, 0, 0, 0
for page in range(4):
rows = fmp_get("sec-filings-search/symbol", {"symbol": sym, "from": from_date, "to": to_date, "page": page, "limit": 100})
if not rows: break
pages, scanned, f4_cnt = pages + 1, scanned + len(rows), f4_cnt + sum(1 for r in rows if r.get("formType") in ("4", "4/A"))
ann = ann or next((r for r in rows if r.get("formType") in ann_set), None)
cur = cur or next((r for r in rows if r.get("formType") in cur_set), None)
if ann and cur: break
dates = fmp_get("financial-reports-dates", {"symbol": sym}) or []
fy_set = {d["fiscalYear"] for d in dates if d.get("period") == "FY"}
rep = next((d for d in dates if d.get("period") == "FY" or (d.get("period") == "Q4" and d.get("fiscalYear") not in fy_set)), None)
return {**meta, "scanned_pages": pages, "total_scanned": scanned, "form4_Count": f4_cnt,
"latest_annual_form": ann["formType"] if ann else None, "annual_filingDate": ann["filingDate"][:10] if ann else None,
"annual_acceptedDate": ann["acceptedDate"] if ann else None, "annual_finalLink": ann["finalLink"] if ann else None,
"latest_current_form": cur["formType"] if cur else None, "current_filingDate": cur["filingDate"][:10] if cur else None,
"current_acceptedDate": cur["acceptedDate"] if cur else None, "structured_10k_entry": f"{rep['fiscalYear']}-{rep['period']}" if rep else None}
for uid in ["AAPL", "1045810", "MSFT", "084670702", "US02079K3059", "US8740391003"]:
print(json.dumps(audit_company_filings(uid), ensure_ascii=False))
向上述管线同时传入股票代码(AAPL、MSFT)、未补零 CIK(1045810,对应 NVDA)、9 位纯数字 CUSIP(084670702,对应 BRK-B)以及 12 位 ISIN(US02079K3059 对应 GOOGL、US8740391003 对应台积电 TSM),实盘运行输出的 6 条 JSON 结果如下(日常巡检时可将 to_date 设为运行当日;若出现 latest_annual_form: null 且 scanned_pages == 4,代表前 400 条申报已被 Form 4 等高频表单占满、扫描尚未触达年报披露日,可继续增大分页上限或改调 sec-filings-search/form-type):
{"input_id": "AAPL", "symbol": "AAPL", "cik": "0000320193", "cusip": "037833100", "isin": "US0378331005", "exchange": "NASDAQ", "isAdr": false, "sicCode": "3571", "sicDescription": "Electronic Computers", "scanned_pages": 1, "total_scanned": 100, "form4_Count": 60, "latest_annual_form": "10-K", "annual_filingDate": "2026-11-03", "annual_acceptedDate": "2026-11-03 08:05:15", "annual_finalLink": "https://www.sec.gov/Archives/edgar/data/320193/000032019326000026/aapl-20260926.htm", "latest_current_form": "8-K", "current_filingDate": "2026-11-09", "current_acceptedDate": "2026-11-09 16:30:40", "structured_10k_entry": "2026-FY"}
{"input_id": "1045810", "symbol": "NVDA", "cik": "0001045810", "cusip": "67066G104", "isin": "US67066G1040", "exchange": "NASDAQ", "isAdr": false, "sicCode": "3674", "sicDescription": "Semiconductors & Related Devices", "scanned_pages": 1, "total_scanned": 100, "form4_Count": 64, "latest_annual_form": "10-K", "annual_filingDate": "2026-02-25", "annual_acceptedDate": "2026-02-25 16:42:19", "annual_finalLink": "https://www.sec.gov/Archives/edgar/data/1045810/000104581026000021/nvda-20260125.htm", "latest_current_form": "8-K", "current_filingDate": "2026-09-03", "current_acceptedDate": "2026-09-03 08:03:56", "structured_10k_entry": "2026-Q4"}
{"input_id": "MSFT", "symbol": "MSFT", "cik": "0000789019", "cusip": "594918104", "isin": "US5949181045", "exchange": "NASDAQ", "isAdr": false, "sicCode": "7372", "sicDescription": "Services-Prepackaged Software", "scanned_pages": 1, "total_scanned": 100, "form4_Count": 76, "latest_annual_form": "10-K", "annual_filingDate": "2026-07-29", "annual_acceptedDate": "2026-07-29 16:08:01", "annual_finalLink": "https://www.sec.gov/Archives/edgar/data/789019/000119312526323660/msft-20260630.htm", "latest_current_form": "8-K", "current_filingDate": "2026-11-05", "current_acceptedDate": "2026-11-05 06:01:52", "structured_10k_entry": "2026-FY"}
{"input_id": "084670702", "symbol": "BRK-B", "cik": "0001067983", "cusip": "084670702", "isin": "US0846707026", "exchange": "NYSE", "isAdr": false, "sicCode": "6331", "sicDescription": "Fire, Marine & Casualty Insurance", "scanned_pages": 1, "total_scanned": 100, "form4_Count": 27, "latest_annual_form": "10-K", "annual_filingDate": "2026-03-02", "annual_acceptedDate": "2026-03-02 06:02:28", "annual_finalLink": "https://www.sec.gov/Archives/edgar/data/1067983/000119312526083899/brka-20251231.htm", "latest_current_form": "8-K", "current_filingDate": "2026-11-09", "current_acceptedDate": "2026-11-09 06:10:14", "structured_10k_entry": "2025-FY"}
{"input_id": "US02079K3059", "symbol": "GOOGL", "cik": "0001652044", "cusip": "02079K305", "isin": "US02079K3059", "exchange": "NASDAQ", "isAdr": false, "sicCode": "7370", "sicDescription": "Services-Computer Programming, Data Processing, Etc.", "scanned_pages": 3, "total_scanned": 300, "form4_Count": 167, "latest_annual_form": "10-K", "annual_filingDate": "2026-02-05", "annual_acceptedDate": "2026-02-04 21:56:03", "annual_finalLink": "https://www.sec.gov/Archives/edgar/data/1652044/000165204426000018/goog-20251231.htm", "latest_current_form": "8-K", "current_filingDate": "2026-11-05", "current_acceptedDate": "2026-11-05 16:10:44", "structured_10k_entry": "2025-FY"}
{"input_id": "US8740391003", "symbol": "TSM", "cik": "0001046179", "cusip": "874039100", "isin": "US8740391003", "exchange": "NYSE", "isAdr": true, "sicCode": "3674", "sicDescription": "Semiconductors & Related Devices", "scanned_pages": 3, "total_scanned": 300, "form4_Count": 261, "latest_annual_form": "20-F", "annual_filingDate": "2026-04-16", "annual_acceptedDate": "2026-04-16 06:05:49", "annual_finalLink": "https://www.sec.gov/Archives/edgar/data/1046179/000162828026025362/tsm-20251231.htm", "latest_current_form": "6-K", "current_filingDate": "2026-11-10", "current_acceptedDate": "2026-11-10 08:41:38", "structured_10k_entry": "2025-FY"}
如果希望在本地或云服务器立即复现上述四码对齐与 SEC 10-K/8-K 监控流水线,可前往 快速接入指南 免费申领 Ultimate 全接口试用密钥,或查阅 定价与会员套餐 了解国内直连与微信支付方案。
常见问题(FAQ):使用 SEC 申报文件与证券编码映射接口时最容易踩哪些坑?
Q1:为什么用 /stable/sec-filings-company-search/name 按公司名模糊搜索(如 company=Berkshire)会返回上百条 symbol 为 "None" 的记录?
因为 SEC Filings By Name(按名称查 SEC 申报接口,/stable/sec-filings-company-search/name)检索的是 SEC EDGAR 全量注册申报实体库,不仅包含二级市场上市公司,还包含大量需要在 SEC 备案 Form D 或 13F 的私募股权基金、有限合伙(LP)与资产管理机构。例如实测传入 company=Berkshire 共返回 104 个 SEC 申报主体,排在前面的 BERKSHIRE MULTIFAMILY VALUE FUND II LP(CIK 为 0001418405)与 BERKSHIRE PARTNERS(CIK 为 0001461632)均为非上市私募主体,其返回对象中的 symbol 字段为字符串字面量 "None"(注意不是 JSON 的 null)。如果只需要检索二级市场挂牌股票,建议优先使用 Company Name Search(公司名称检索接口,/stable/search-name),或在遍历结果时显式过滤 row.get("symbol") not in (None, "", "None")。
Q2:10-K 全表 JSON 接口(/stable/financial-reports-json)与标准化三大报表(/stable/income-statement 等)以及原始口径三大报表(As Reported)有什么区别?
三者服务于完全不同的投研颗粒度:
- 标准化三大报表(如 Income Statement(利润表接口,
/stable/income-statement)):将全市场不同行业的会计科目映射为约 30~40 个统一标准字段(如revenue、operatingIncome、netIncome),最适合做跨公司横截面多因子选股与财务比率计算。 - 原始口径三大报表(如 As Reported Income Statements(原始申报利润表接口,
/stable/income-statement-as-reported)):仅保留三大主表(利润表、资产负债表、现金流量表)的原始 XBRL 标签,不包含报表附注(Footnotes)中的拆分表格。 - 10-K 年报全表 JSON / XLSX(
/stable/financial-reports-json与/stable/financial-reports-xlsx):把整份 10-K 或 10-Q 中披露的所有主表 + 几十张附注细分表(如分产品线收入、分地区资产、债务到期日结构、税务调节表、高管薪酬与绩效披露表)按章节完整还原,最适合深度基本面建模与投研 Agent 精确检索附注表格。