mcpField
F
findata

findata

github.com/monotykamary数据与数据库456 次安装今天更新
代码仓库

关于 findata

findata 是通过浏览器从 Yahoo Finance 和 SEC EDGAR 获取股价与财务报表的命令行技能。它提供无需密钥的结构化数据,并支持 JSON 输出及 SEC 文件溯源。

主要功能

  1. 01查询当前股价快照
  2. 02获取历史 OHLCV 价格
  3. 03查看年度及季度报表
  4. 04输出 JSON 或格式化表格
  5. 05追溯 SEC 文件来源

适用场景

  1. 01查看股票代码的最新价格
  2. 02查询指定区间的历史价格
  3. 03获取损益表、资产负债表或现金流量表

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/monotykamary/browser-harness-js --skill findata

安装后在 Claude Code 中输入/findata确认已加载。

包含的文件

除 SKILL.md 外,安装时一起下载的参考资料和脚本。

scripts/
findata
setup
test

详细介绍

findata — 通过 CDP 获取免费的金融数据

通过 CDP 使用真实浏览器抓取/获取免费、无需密钥的金融数据——与付费的 financialdatasets.ai API 售卖的数据相同,但直接取自免费的公开来源(财务报表来自 SEC EDGAR,价格来自 Yahoo Finance)。每次调用都会打开自己的标签页和 WebSocket 会话,支持安全并行使用。

命令

findata price    <ticker>                                          # live/last price snapshot
findata prices   <ticker> [--range 1mo|--start S --end E] [--interval 1d] [--limit N]
findata income   <ticker> [--period annual|quarterly] [--limit N]  # income statement
findata balance  <ticker> [--period annual|quarterly] [--limit N]  # balance sheet
findata cashflow <ticker> [--period annual|quarterly] [--limit N]  # cash flow statement
findata --json   <command> ...                                     # raw JSON instead of pretty table
标志适用于含义
--json全部输出原始 JSON,而非格式化文本
--period annual|quarterly财务报表报告周期(默认 annual)
--limit N财务报表/价格财务报表:显示的周期数(默认 4,0 = 最多 40)。价格:最近 N 条数据(默认全部)
--range R价格Yahoo 时间范围:1d 5d 1mo 3mo 6mo 1y 2y 5y 10y ytd max(默认 1mo)
--start/--end YYYY-MM-DD价格精确日期范围(可替代 --range;需要 node)
--interval R价格数据间隔:1m 2m 5m 15m 30m 60m 1d 5d 1wk 1mo(默认 1d)
示例
findata price AAPL
findata prices TSLA --range 3mo --interval 1wk
findata prices MSFT --start 2025-01-01 --end 2025-06-30 --limit 5
findata income AAPL --period quarterly --limit 4 --json
findata balance NVDA --limit 2
findata cashflow AAPL

# Parallel — each call uses its own tab
findata price AAPL &  findata price MSFT &  wait

返回结果结构

price(快照):

{"ticker":"AAPL","name":"Apple Inc.","price":310.05,"previous_close":308.63,
 "change":1.42,"change_percent":0.46,"currency":"USD","exchange":"NMS",
 "time":"2026-07-06T14:16:41Z"}

previous_close 是前一个交易日的收盘价(根据倒数第二条日线数据推导),而非时间范围起始日的收盘价,因此 change 表示真实的日间变动。price 是实时/最近成交价(regularMarketPrice)。

prices(历史 OHLCV):

{"ticker":"AAPL","name":"Apple Inc.","currency":"USD","interval":"1d","prices":[
  {"date":"2026-07-02","open":294.12,"high":309.42,"low":293.68,"close":308.63,"volume":75352800,"adj_close":308.63}
]}

income / balance / cashflow(财务报表):

{"ticker":"AAPL","name":"Apple Inc.","cik":320193,"period":"annual","statement":"income",
 "statements":[{
   "period_end":"2025-09-27","fiscal_year":2025,"fiscal_period":"FY","form":"10-K",
   "filed":"2025-10-31","accession":"0000320193-25-000079",
   "filing_url":"https://www.sec.gov/Archives/edgar/data/320193/000032019325000079/0000320193-25-000079-index.htm",
   "revenue":416161000000,"cost_of_revenue":220960000000,"gross_profit":195201000000,
   "operating_income":133050000000,"net_income":112010000000,
   "eps_basic":7.49,"eps_diluted":7.46,"shares_basic":14948500000,"shares_diluted":15004697000
 }]}

每个财务报表对象都包含 period_end、fiscal_year、fiscal_period、form、filed、accession、filing_url,用于追溯到 SEC 文件,还包含各项明细字段。cashflow 会添加推导得出的 free_cash_flow = operating_cf + capex。

财务报表字段
  • income:revenue, cost_of_revenue, gross_profit, operating_expenses, sgna, rnd, operating_income, interest_expense, income_tax, net_income, eps_basic, eps_diluted, shares_basic, shares_diluted, dividends_per_share
  • balance:total_assets, current_assets, cash, inventory, investments, total_liabilities, current_liabilities, long_term_debt, total_debt, equity, retained_earnings, shares_outstanding
  • cashflow:net_income, operating_cf, capex, investing_cf, financing_cf, dividends_paid, share_repurchases, debt_repayment, free_cash_flow

每个字段都映射到一个或多个候选 US-GAAP XBRL 概念(按优先顺序排列);以最近期间日期最晚的概念为准,因此过时的旧概念(例如公司改用 RevenueFromContractWithCustomerExcludingAssessedTax 后仍存在的 Revenues)不会覆盖当前概念。

工作原理

数据来源CDP 技术
价格query1.finance.yahoo.com/v8/finance/chart/<ticker>?interval=&range=&period1=&period2=事件驱动抓取:导航到 JSON URL,等待 Page.frameNavigated 提交事件(application/json 会触发此事件,而 loadEventFired/networkIdle 不会),然后通过同源 fetch(window.location.href) 返回原始响应正文,无需等待 Chrome 的 JSON 查看器将其渲染到 DOM 中。异步投影 IIFE 通过 awaitPromise 运行。Yahoo 的图表端点以 JSON 格式返回干净的 OHLCV 数据和 regularMarketPrice,无需抓取 DOM。通过浏览器访问可绕过阻止 curl 的 crumb/同意提示拦截。
Ticker→CIKwww.sec.gov/files/company_tickers.json同样采用事件驱动抓取;解析为映射并缓存在 globalThis.__secTickerMap 中,供服务在整个生命周期内使用(每个会话只抓取一次)。
报表data.sec.gov/api/xbrl/companyfacts/CIK<padded>.json(SEC EDGAR XBRL)就绪状态轮询(不是抓取路径——见下文)。导航到 JSON URL,然后每隔约 80 毫秒轮询页面内的投影 IIFE,直到其报告 {ready:true}。顶层导航绕过 CORS;只有小型投影会经过 CDP,因此多 MB 的 companyfacts 对象始终留在页面中。

为何采用两种捕获策略。 JSON 导航既不会触发 Page.loadEventFired,也不会触发 networkIdle(已验证),因此 gsearch/xsearch 使用的事件驱动等待方式无法直接套用。Page.frameNavigated 会在提交时触发,而之后进行的同源 fetch 会在下载完成的瞬间返回原始响应正文,完全跳过 JSON 查看器的渲染。对于小型端点,这显然更有优势(价格约 0.3 秒,ticker 映射约 0.25 秒),因为查看器渲染只是纯粹的额外开销,几乎没有可复用的解析结果。

对于多 MB 的 companyfacts,情况正好相反:等到 document.body.innerText 就绪时,Chrome 的 JSON 查看器已经解析了 3.7 MB 的响应正文,因此投影自身的 JSON.parse 几乎不耗时(约 16 毫秒)。冷缓存下,fetch 加解析约需 800 毫秒,因此轮询(总计约 1.1 秒)比抓取路径(约 1.5 秒)更快。要跳过这里的查看器渲染,最干净的方法是在 loadingFinished 时调用 Network.getResponseBody(约 0.56 秒),但多 MB 响应正文会导致测试框架的 WebSocket 崩溃,因此 companyfacts 仍使用轮询。

每次调用:Target.createTarget(about:blank, background) → Target.attachToTarget → 每次调用使用单独的 sessionId → 导航 +(抓取 | 轮询)→ 在 finally 中以即发即弃方式调用 closeTab。与 gsearch/xsearch 使用相同模式,可安全并行使用,不会相互覆盖 activeSessionId。

典型延迟(服务已预热,HTTP 缓存未命中):price/prices 约 0.3 秒,报表约 1.1–1.4 秒(主要耗时在 companyfacts 的下载和解析上;每个会话首次调用报表时,还会因首次抓取 ticker 映射而额外耗时约 0.25 秒)。HTTP 缓存命中时,价格查询可缩短至约 0.25 秒。

为何选择这些来源

  • 报表使用 SEC EDGAR:它是权威来源——financialdatasets.ai 的报表源自 SEC EDGAR(其 JSON 中甚至带有相同的 SEC accession_number 和 filing_url)。免费、无需密钥、结构化 JSON,同时支持年报(10-K)和季报(10-Q)。没有理由另寻来源。
  • 价格使用 Yahoo Finance v8 图表:唯一免费且以结构化 JSON(而非 HTML 表格)返回 OHLCV 数据的来源,并且通过一个端点覆盖快照、历史数据和日内数据。所有免费的价格网站都通过机器人防护阻止 curl;浏览器则可以绕过拦截。(stockanalysis.com 会对 curl 返回 403,即使使用真实浏览器也会显示 Cloudflare 的“Just a moment…”拦截页面;由于欧盟同意提示重定向,Yahoo 的报价页面表现不一致——但通过浏览器访问其 JSON 图表端点则运行正常。)

注意事项

  • 季度报表是年初至今的累计值,而非单季度值。 SEC 10-Q 中的事实数据按财年年初至今报告(Q3 数值是 9 个月累计值)。findata 返回的是报告原值,不会将其相减转换为 3 个月的单季度值。这与申报文件一致;如果需要单季度值,请自行减去相邻期间的数值。资产负债表项目是时点值(不累计),符合预期。
  • 现金流项目的符号经过标准化。 SEC 申报者的报告方式不一致:有些将 capex/dividends_paid/share_repurchases/debt_repayment 报为正数,有些报为负数。这四项始终是现金流出,因此 findata 会将它们标准化为负数。净额小计(operating_cf、investing_cf、financing_cf)保留报告中的方向符号。free_cash_flow 的计算方式为 operating_cf + capex(其中 capex 已标准化为负数),无论申报者采用哪种符号约定,结果都等于 operating_cf − |capex|。
  • period_end 事实数据重复。 companyfacts 通常同时包含原始 10-K 中的事实数据,以及后续 10-K 中比较列重述的数据(end 相同、数值相同,后者带有类似 CY2024 的 frame)。findata 会按 period_end 去重,并优先选择最早提交的 10-K 事实数据,因此每列都指向原始申报文件,而非后续的比较数据。
  • 不同申报者的概念覆盖范围各不相同。 如果公司使用候选列表中未包含的概念报告某个项目,字段会显示 -/null(例如,Apple 使用 PaymentsOfDividends 报告股息,使用 PaymentsForRepurchaseOfCommonStock 报告回购)。候选列表涵盖常见概念;少数特殊申报者的部分字段可能为空。
  • price 的 previous_close 是前一个交易日的收盘价(5 天窗口中的倒数第二根日线),因此 change 表示日变化。Yahoo 的 meta 中的 chartPreviousClose 是区间开始前的收盘价(约 5 天前),而非昨天的收盘价,因此不会使用它。
  • Yahoo 速率限制。 使用量较大时,Yahoo 可能返回 429 或非 JSON 页面;findata 会将其显示为 Yahoo Finance error … non-JSON response (possibly rate-limited)。请等待一段时间后重试。Yahoo 对盘中间隔数据限制了可查询的近期时间范围(例如,1 分钟线仅提供最近约 7 天的数据)。
  • SEC 速率限制和 User-Agent。 SEC 要求请求速率低于每秒 10 次,并设置具有描述性的 User-Agent;浏览器会自动提供。正常情况下每次调用会发送 1–2 个请求(股票代码映射表会缓存),远低于限制。
  • 股票代码映射表会缓存在服务器进程的整个生命周期内的 globalThis.__secTickerMap 中,因此新近上市的股票代码要等到执行 browser-harness-js --restart 后才会显示。
  • 不同股类的股票代码使用连字符。 SEC EDGAR 的 company_tickers.json 和 Yahoo 的 chart 端点都使用 -(BRK-B、BF-B)作为不同股类股票代码的分隔符,而非 .。findata 会将股票代码转为大写,并将 . 规范化为 -,因此 BRK.B、brk.b 和 BRK-B 都能解析。否则,BRK.B 会报错:Ticker not found in SEC EDGAR。
  • 两种捕获路径。 对于价格和股票代码映射表,使用 Page.frameNavigated + 同源 fetch(跳过 JSON 查看器的渲染过程,小型响应体处理更快);对于数 MB 大小的 companyfacts,则通过轮询就绪状态来处理,此时查看器预先解析数据所需的额外开销几乎为零(冷启动时获取并解析数据会更慢)。请参阅 工作原理。
  • JSON 页面不会触发生命周期事件。 Chrome 在 application/json 导航中既不会触发 Page.loadEventFired,也不会触发 networkIdle。fetch 路径以 Page.frameNavigated 为依据(提交导航时会触发);轮询路径则根据 document.body.innerText 是否可解析来判断,并在 content-type 不是 JSON 时立即退出,而不继续等待超时。
  • 不依赖 jq——JSON 会在页面内解析并投影为精确的输出结构;格式化由 JS 完成。日期到 unix 时间的转换使用 node(browser-harness-js 已需要它)。

评论

支持 Markdown