关于 Sec 13f
Sec 13f 面向关注机构持仓的研究者和 AI Agent,基于 SEC Form 13F 数据查询管理人及证券持仓。除静态组合外,还提供季度变动和证券资金流向,并明确说明数据覆盖范围与限制。
主要功能
- 01按证券查询机构持有人并排序
- 02查看管理人的当前季度组合
- 03比较管理人季度持仓变动
- 04汇总证券季度持仓与买卖变化
- 05查看集中度、换手率和数据覆盖
适用场景
- 01查找持有某证券的机构管理人
- 02追踪管理人新增、退出或调整的仓位
- 03比较某证券各季度的持有人与持仓价值
- 04评估管理人组合集中度和换手情况
MCP 相关
作为 MCP 服务,Sec 13f 向客户端提供证券持有人、管理人组合、季度变动和持仓流向等工具。它通过 Pipeworx 远程服务提供,也支持本地运行的 stdio MCP 服务。
配置
远程服务无需本地安装。选择你使用的客户端,复制配置或使用一键安装。
https://gateway.pipeworx.io/sec-13f/mcpclaude mcp add --transport http pipeworx-io-sec-13f https://gateway.pipeworx.io/sec-13f/mcp{"mcpServers":{"pipeworx-io-sec-13f":{"type":"http","url":"https://gateway.pipeworx.io/sec-13f/mcp"}}}在 Cursor 中打开{"servers":{"pipeworx-io-sec-13f":{"type":"http","url":"https://gateway.pipeworx.io/sec-13f/mcp"}}}在 VS Code 中打开{"mcpServers":{"pipeworx-io-sec-13f":{"type":"http","url":"https://gateway.pipeworx.io/sec-13f/mcp"}}}{"mcpServers":{"pipeworx-io-sec-13f":{"serverUrl":"https://gateway.pipeworx.io/sec-13f/mcp"}}}命令在终端中运行;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 或已关联的
supabaseCLI):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_idxGIN 三元组索引——在约 1,010 万行/1.8GB 堆表上运行EXPLAIN (ANALYZE, BUFFERS)显示索引步骤耗时 87ms。一次耗时 5.27 秒的冷执行中,其余 5.16 秒都花在位图堆扫描上,用于获取约 28,000 条匹配记录所在的表页,而这些页面大多不在 Supabase 的 512MBshared_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
评论
一个开放协议,规定了 AI 应用如何以统一方式连接外部工具与数据源。客户端负责与模型对话,MCP 服务负责提供工具、资源和提示模板,两者通过标准消息通信,同一个服务可以被不同客户端复用。