关于 findata
findata 是通过浏览器从 Yahoo Finance 和 SEC EDGAR 获取股价与财务报表的命令行技能。它提供无需密钥的结构化数据,并支持 JSON 输出及 SEC 文件溯源。
主要功能
- 01查询当前股价快照
- 02获取历史 OHLCV 价格
- 03查看年度及季度报表
- 04输出 JSON 或格式化表格
- 05追溯 SEC 文件来源
适用场景
- 01查看股票代码的最新价格
- 02查询指定区间的历史价格
- 03获取损益表、资产负债表或现金流量表
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ monotykamary/ browser-harness-js --skill findata安装后在 Claude Code 中输入/findata确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
scripts/findatasetuptest详细介绍
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→CIK | www.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 中甚至带有相同的 SECaccession_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已需要它)。