mcpField
S
Sec 13f

Sec 13f

远程服务
pipeworx.io金融数据05 周前更新

关于 Sec 13f

Sec 13f 面向关注机构持仓的研究者和 AI Agent,基于 SEC Form 13F 数据查询管理人及证券持仓。除静态组合外,还提供季度变动和证券资金流向,并明确说明数据覆盖范围与限制。

主要功能

  1. 01按证券查询机构持有人并排序
  2. 02查看管理人的当前季度组合
  3. 03比较管理人季度持仓变动
  4. 04汇总证券季度持仓与买卖变化
  5. 05查看集中度、换手率和数据覆盖

适用场景

  1. 01查找持有某证券的机构管理人
  2. 02追踪管理人新增、退出或调整的仓位
  3. 03比较某证券各季度的持有人与持仓价值
  4. 04评估管理人组合集中度和换手情况

MCP 相关

作为 MCP 服务,Sec 13f 向客户端提供证券持有人、管理人组合、季度变动和持仓流向等工具。它通过 Pipeworx 远程服务提供,也支持本地运行的 stdio MCP 服务。

配置

远程服务无需本地安装。选择你使用的客户端,复制配置或使用一键安装。

服务地址https://gateway.pipeworx.io/sec-13f/mcp
一键复制安装命令
Claude CodeTerminal
Cursor.cursor/mcp.json
VS Code.vscode/mcp.json
Claude Desktopclaude_desktop_config.json
Windsurf~/.codeium/windsurf/mcp_config.json

命令在终端中运行;JSON 粘贴到对应客户端的 MCP 配置后重启。需要授权的服务会在首次连接时提示登录。

工具

详细介绍

@pipeworx/sec-13f

以证券为先的 SEC Form 13F 机构持仓数据。托管服务,调用方无需密钥。 变动在这里是核心功能,而非事后补充:manager_changes 和 security_flows 直接回答“发生了什么变化”,因为静态持仓快照不是简报——变化才是。

属于 Pipeworx — 一个将 AI Agent 连接到 1683+ 个实时数据源的 MCP 网关。

工具

  • who_owns(security, limit?) — 持有某证券的管理人,按持仓规模排序。接受公司名称、股票代码(通过 OpenFIGI 实时解析 — 见下文“股票代码解析”)或 9 位 CUSIP。
  • manager_portfolio(manager, limit?) — 某位管理人申报的所有持仓,按规模从大到小排列(仅当前季度 — 变动情况见 manager_changes)。
  • manager_changes(manager, quarter?, compare_to?, limit?) — 某位管理人在两个已加载季度之间新增、退出、增持或减持了什么。默认比较该管理人最近两个已加载季度。
  • security_flows(security, limit?) — 某证券在每个已加载季度的总持仓价值和持有者数量,以及最近两个季度之间哪些管理人买入、卖出、增持或减持。
  • manager_profile(manager) — 集中度(投资组合中前 5 大/前 10 大持仓占比)、最近两个已加载季度之间的换手率,以及主要持仓。不包含行业暴露 — 13F 没有行业/板块字段,本工具包不会捏造此类数据。
  • holdings_coverage() — 已加载的 SEC 发布窗口和季度、每季度的申报/持仓数量,以及已加载数据是否足以进行差异比较(can_diff_quarters)。

股票代码解析 — 有意不建立 CUSIP↔股票代码对照表

13F 按 CUSIP 报告持仓;数据集中没有任何股票代码列。CUSIP 标识符归 CUSIP Global Services 所有,因此本工具包不会构建、缓存或再分发批量 CUSIP↔股票代码对照表(遵循与付费标准规则相同的原则)。相反,形似股票代码的输入(例如 "NVDA")会通过 OpenFIGI 的公开映射 API 按调用实时解析 — 获取开放许可的 Bloomberg FIGI — 以取得该证券的规范名称,然后再与我们已摄取持仓数据中的 issuer_name 匹配,并优先选择汇总价值最大的候选项(真实运营公司的最小机构持仓规模,仍远超主题型/杠杆型 ETF 的最大持仓)。每个使用此路径的响应都会报告 matched_on: "ticker_via_openfigi" 以及解析结果(resolved_via.cusip、.figi、.issuer_name)——绝不会悄无声息地进行。此前,who_owns("NVDA") 会按 ILIKE '%NVDA%' 匹配发行人名称,并将“Direxion Daily NVDA Bull 2X ETF”与真实的 NVIDIA CORPORATION 持仓一同列出——这是悄无声息的错误答案,而非功能缺失。

为什么采用托管服务,而非代理

摄取程序只会在本地构建能够实现上游无法回答的问题时接受它。这是一个典型案例:SEC 按管理人优先发布 13F,每个基于其数据的 API 也是如此。 我们自己的 edgar_institutional_holdings 描述也说明了这一点——回答“哪些基金持有 $TICKER”,意味着要针对每位管理人各运行一次,也就是遍历约 8,000 家申报机构。这是数据形态问题,而非速率限制问题,上游服务无法解决。对扁平表进行一次索引查询即可反转这一查询方式。

13F 不会告诉你的信息

这里以及每条回复中都会说明这一点,因为人们经常过度解读 13F:

  • 仅限美国上市股票多头持仓。 按规定,空头、现金、债券和非美国持仓均不包括在内。“X 持有多少”这个问题,只能在这个范围内回答。
  • 按季度提交,且有延迟。 可在报告期结束后最多 45 天内提交。这是滞后的快照,绝不是当前持仓。
  • 1 亿美元门槛。 低于这一门槛的管理人无需提交报告,因此未出现并不能说明什么。
  • 没有股票代码列。 CUSIP 是唯一的正式标识符;发行人名称采用申报人输入的名称(“NVIDIA CORP”)。按股票代码搜索时,会退回到按发行人名称匹配,并在 matched_on 中注明。

数字所依赖的一件事

同一管理人可能在多行中报告同一证券——因为投资裁量权不同,或者普通股之外还持有看跌期权和看涨期权。who_owns 会在排名前按管理人合并多行。 否则得到的就是持仓行最多的对象,而不是持有人最多的对象;这会产生一个看起来同样合理、但完全不同的列表。

数据与刷新

来源:https://www.sec.gov/data-research/sec-markets-data/form-13f-data-sets — 一个滚动的 3 个月 ZIP 文件,包含 7 个 TSV 文件。其中使用了 3 个:SUBMISSION(accession → CIK)、COVERPAGE(accession → 管理人)和 INFOTABLE(持仓数据,每次发布约 380 万行,未压缩时为 396MB)。

文件名中编码了时间范围(01mar2026-31may2026_form13f.zip),且无法推导得出——发布并不按日历季度进行。worker 配置和脚本都会读取 SEC 的索引页,获取最新链接;如果硬编码季度,数据只会导入一次,之后永远都是过时数据。

  • 常规路径:workers/data-pipeline(sec-13f-submissions、sec-13f-managers、sec-13f-holdings)。
  • 回填/恢复(需要 Supabase service key 或已关联的 supabase CLI): node scripts/ingest-sec-13f.mjs --only holdings。
  • 通过网关的管理路由回填(只需 PIPEWORX_INTERNAL_SECRET,每个 fleet 会话都已携带此凭据——无需原始数据库密钥):node scripts/ingest-sec-13f-admin.mjs --url https://www.sec.gov/files/structureddata/data/form-13f-data-sets/<window>_form13f.zip。通过网关上的 POST /admin/sec13f_load 提交(仅允许指定表,每次调用最多 3,000 行,与此处其他托管导入的上限相同)。第二季度数据就是通过这种方式加载的(fleet #339;需要它,才能让 manager_changes/security_flows 有真实数据可供比较)。
  • 时效性:在 shared/src/freshness.ts 中注册,SLA 为 200 天——这考虑了发布周期和约 45 天的申报延迟,因此如果错过一次发布,会在一个季度内触发告警。

架构和索引:supabase/migrations/061_sec_13f.sql。(cusip, value_usd DESC) 索引是实现反向查询的关键;没有它,这就会变成对 380 万行进行顺序扫描,构建速度会比它取代的 API 还慢。

多季度回填——吞吐量、续传,以及数据深入后性能如何下降

2026-09-04 加载第 3 至第 8 季度时的测量结果(fleet #1245,从 2 个季度增至 8 个季度,让 manager_changes/security_flows 能展示真实趋势):

  • 通过管理路由约 870 行/秒,因此一个季度约 280 万至 380 万条持仓记录需要 约 1 至 2 小时,而不是几分钟。请据此为 8 个季度安排足够的实际运行时间。
  • 加载器支持断点续传,不是非成即败。 每次写入都使用 Prefer: resolution=merge-duplicates,并以表中真实的唯一 ID 为键(持仓表使用 infotable_sk,管理人/提交记录使用 accession_number);scripts/ingest-sec-13f-admin.mjs 提供了专门用于此目的的 --skip-rows N。如果加载在某个季度中途失败,不要删除后重新加载——获取准确的已提交行数(count(*),而不是 pg_class.reltuples,后者在下次自动清理前会过时),减去加载前的基准值,再用 --skip-rows <delta> 恢复。每个 POST 的批次都是原子操作(≤3,000 行),因此差值始终是批次大小的整数倍——不会出现需要清理的部分行损坏。 不要在没有 Monitor/日志尾随工具监控的情况下运行此加载器,因为你之后可能会关闭该工具。 在运行环境中,Monitor 和通过 run_in_background 启动的加载器可能共用一个进程组,因此对 Monitor 调用 TaskStop 可能会连带杀死加载器,且不会输出任何错误——日志只会在半行处停止。如果发生这种情况,看起来就和静默崩溃完全一样;在认定是数据库端故障之前,请先检查这一点。
  • 整个服务器集群的 sec.gov 共用一个出口 IP,并按 IP 限流。 在运行此加载器下载 ZIP 的同时,如果其他通道也在批量拉取 SEC 数据(Form 4/内幕交易、EDGAR 全文、XBRL),就会触发 SEC 的 Akamai 前端返回 429,并施加可延长的 10 分钟超时。开始批量抓取 sec.gov 前请先协调——参见 CLAUDE.md 中的 Cross-Project Rules。
  • 数据深度会拖慢 who_owns 的 ILIKE/股票代码查询路径——问题不在索引,而在堆表。 resolveTicker() 的 issuer_name ILIKE '%name%' ORDER BY value_usd DESC LIMIT 50(每次普通股票代码调用都会在任何 CUSIP 查询前运行)确实使用了 sec_13f_holdings_issuer_trgm_idx GIN 三元组索引——在约 1,010 万行/1.8GB 堆表上运行 EXPLAIN (ANALYZE, BUFFERS) 显示索引步骤耗时 87ms。一次耗时 5.27 秒的冷执行中,其余 5.16 秒都花在位图堆扫描上,用于获取约 28,000 条匹配记录所在的表页,而这些页面大多不在 Supabase 的 512MB shared_buffers 中。对同一谓词进行热缓存重跑后,耗时为 107ms。这项开销随表大小增长,而非取决于索引的处理能力——扩展到 8 个季度(约 9.7GB 堆表)时,冷缓存股票代码查询的耗时预计会超过第 3 个季度测得的约 5 至 20 秒;每增加一个未来季度,耗时还会继续增长。后续改进将单独跟进解析器表(缓存股票代码→CUSIP,使 resolveTicker() 对每个证券只扫描一次,而不是每次冷调用都扫描),不会因此阻塞本次回填。 (已解决:迁移 154 构建了该解析器表——耗时从 8,510ms 降至 2.1ms。)
  • who_owns 在数据库中求和,原因是往返请求计数,而不是某个单独的查询计划(fleet #1254,迁移 156)。 先后落地了两项查询计划修复——上文的 154,以及针对 windowQuarterMap 的 155——但都没有改善 who_owns,大型市值公司的耗时仍为 28 至 30 秒。实际开销在于:MSFT 在最新时间窗口中有 10,729 条持仓记录和 6,801 个提交记录,因此一次调用会发出103 个串行 PostgREST 请求——先发 11 个 Range 分页请求,再发 46+46 个每批 150 条的请求来关联提交记录和管理人——最终返回 25 位管理人。修复方案是 sec_13f_who_owns(),它在服务器端完成时间窗口筛选、修正案去重、管理人关联和分组,只需一个请求:MSFT 从 29.81s 降至 11.75s,AAPL 从 27.78s 降至 9.68s,且每位管理人的总额均保持不变。 它特意没有减少获取的数据量——参见上文的拆分行说明;限制行数会导致 #427 错误,即管理人自己的总额会悄然缩小。请使用 node scripts/sec13f-who-owns-bench.mjs before|after|--diff 验证;如果任一管理人的总额发生变化,该脚本就会失败,而不只是依据运行时间判断。 响应中包含 aggregated_in_db。如果其值为 false,表示 RPC 返回了 404,数据包回退到了旧的 103 次往返路径——也就是说,部署先于迁移 156 落地。这种情况没有问题,但速度较慢;从头排查 who_owns 变慢的问题前,应先检查这一点。

快速开始

添加到你的 MCP 客户端(Claude Desktop、Cursor、Windsurf 等):

{
  "mcpServers": {
    "sec-13f": {
      "url": "https://gateway.pipeworx.io/sec-13f/mcp"
    }
  }
}
此端点实际提供的内容

https://gateway.pipeworx.io/sec-13f/mcp 上的 tools/list 会返回上表中的工具,以及共享的 Pipeworx 元工具——ask_pipeworx、 discover_tools、search_within、remember/recall 和其他整个网关通用的工具。因此,你看到的工具数量会多于此表:单个工具包端点目前会列出约 30 个共享工具,以及该工具包自身的工具。连接的 initialize 响应会说明其准确范围,是当天情况的权威答案。

这是有意为之,并非意外的多路复用。元工具可以让范围受限的连接回答此工具包未涵盖的问题——通过 ask_pipeworx 在整个目录中进行路由——而无需添加第二个 MCP 服务。目前无法在不包含这些工具的情况下挂载工具包端点;如果额外的架构占用的上下文比路由带来的价值更多,请连接一次完整网关,而不是连接多个工具包端点。

也可以连接完整的 Pipeworx 网关,直接获取所有工具包的工具列表,而不只是此工具包的工具:

{
  "mcpServers": {
    "pipeworx": {
      "url": "https://gateway.pipeworx.io/mcp"
    }
  }
}

两个 URL 都会连接到同一个网关和相同的 1683+ 个数据源。唯一的区别是直接列出哪个工具包的工具;ask_pipeworx 可从任一端点访问所有工具包的工具。

没有 MCP 客户端?通过 HTTP 调用

curl -X POST https://gateway.pipeworx.io/v1/tools/who_owns \
  -H 'Content-Type: application/json' \
  -d '{"security":"NVIDIA","limit":25}'

首次调用无需账户。查看任意工具:GET https://gateway.pipeworx.io/v1/tools/who_owns。查找工具包:使用 {"query":"..."} 调用 POST https://gateway.pipeworx.io/v1/tools/search_packs。

独立运行(无需网关账户)

此软件包也可以作为本地 stdio MCP 服务运行——无需 Pipeworx 账户,也无需往返网关:

{
  "mcpServers": {
    "sec-13f": {
      "command": "npx",
      "args": ["-y", "@pipeworx/mcp-sec-13f"]
    }
  }
}

或者直接运行,以确认它能够启动:

npx -y @pipeworx/mcp-sec-13f

它通过 stdin/stdout 使用 MCP 协议,并为仅此工具包的工具响应 initialize/tools/list/tools/call——不包含上文网关连接额外提供的共享元工具。源代码相同,工具相同,但没有 ask_pipeworx 路由。

使用 ask_pipeworx

你也可以用通俗的英语提问,而不是直接调用工具——上述工具包端点和完整网关都支持此功能:

ask_pipeworx({ question: "your question about Sec 13f data" })

网关会选择合适的工具并自动填充参数。

更多信息

许可证

MIT

评论

支持 Markdown

第一次接触 MCP?

从协议是什么,到在客户端里装上第一个服务,这几条回答覆盖了大多数入门问题。

一个开放协议,规定了 AI 应用如何以统一方式连接外部工具与数据源。客户端负责与模型对话,MCP 服务负责提供工具、资源和提示模板,两者通过标准消息通信,同一个服务可以被不同客户端复用。