Files
yfinance-fork/yfinance-tools.yaml
T
goldyard 057bc4493e Add yfin CLI + tool catalog + CLAUDE.md
Wraps the entire yfinance public API behind a single binary `yfin` with
51 subcommands across 13 namespaces (ticker, download, tickers, search,
lookup, market, sector, industry, calendars, screen, live, auth, config).
Output renders as Rich tables on TTY, JSON when piped; --format / --out
support table | json | ndjson | csv | tsv | parquet | yaml.

Highlights:
- 1857 LOC across 18 Python files under cli/yfin/
- Typer + Rich, packaged via hatchling + uv
- Install globally: `cd cli && uv tool install -e .`
- ~/.yfin/config.toml for persistent proxy/cookies/locale defaults
- Friendly YFRateLimitError handler (exit 2, no Rich traceback)
- Validated end-to-end with 33 live tests against Yahoo from a
  residential exit (AAPL, MSFT, NVDA, options, screens, calendars,
  financials, news, holders, parquet round-trip)

yfinance-tools.yaml is the single source of truth:
- tools (49)       — every public yfinance entry point with parameters
- cli (13 groups)  — exact CLI invocations, mapped back to tool names
- outputSchemas (27) — actual return shapes captured from live calls
- learnings (19)   — IP rate-limit, crumb handshake, Typer gotchas,
                     screen-build wrapping rules, upstream stubs, etc.

CLAUDE.md documents the upstream codebase layout for future agents.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-08 23:36:56 +08:00

2633 lines
100 KiB
YAML
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
---
# yfinance-tools.yaml
# Tool catalog for the `yfinance` Python library (v1.4.1).
# yfinance scrapes public Yahoo! Finance endpoints (v7/v10/v8 chart, quote,
# options, fundamentals, websocket) to expose market data in a Pythonic way.
# Every tool that touches Yahoo is `openWorldHint: true`; pure local helpers
# (config, cache directory, in-process collection builders) stay false.
# Parameter names, defaults and enums below mirror the real Python signatures
# in `yfinance/` — keep them in sync if the upstream API changes.
# Style mirrors ./tools.yaml (Portainer MCP catalog).
version: v1.0
tools:
## Ticker — single-symbol data
## Wraps `yfinance.Ticker(symbol, session=None)` and its ~50 @property
## accessors. The Python-side optional `session=` argument is intentionally
## omitted from each tool below; it is a per-process HTTP/session override
## that does not translate well to a serialized tool call.
## ------------------------------------------------------------
- name: tickerInfo
description: >-
Return the full company / instrument profile dict for one symbol —
company description, sector, industry, officers, exchange metadata
plus a snapshot of current price, market cap and key ratios. Wraps
`Ticker(symbol).get_info()` which hits Yahoo `quoteSummary` (heavy).
Use `tickerFastInfo` when you only need price / volume.
parameters:
- name: symbol
description: Yahoo ticker symbol (e.g. "AAPL", "MSFT", "0700.HK", "BTC-USD", "EURUSD=X", "^GSPC").
type: string
required: true
annotations:
title: Get Ticker Info
readOnlyHint: true
destructiveHint: false
idempotentHint: true
openWorldHint: true
- name: tickerFastInfo
description: >-
Lightweight quote snapshot via `Ticker(symbol).get_fast_info()`. Exposes
a dict-like `FastInfo` with: currency, quoteType, exchange, timezone,
shares, lastPrice, previousClose, regularMarketPreviousClose, open,
dayHigh, dayLow, lastVolume, fiftyDayAverage, twoHundredDayAverage,
tenDayAverageVolume, threeMonthAverageVolume, yearHigh, yearLow,
yearChange, marketCap. Skips quoteSummary, so much faster than
`tickerInfo` and safer for high-frequency polling.
parameters:
- name: symbol
type: string
required: true
annotations:
title: Get Ticker Fast Info
readOnlyHint: true
destructiveHint: false
idempotentHint: false
openWorldHint: true
- name: tickerHistory
description: >-
Download OHLCV history for one symbol via
`Ticker(symbol).history(...)`. Returns a pandas DataFrame indexed by
Date/Datetime with columns Open, High, Low, Close, Volume, Dividends,
Stock Splits (plus Capital Gains for funds). The DataFrame's
`.attrs["history_metadata"]` carries Yahoo's chart metadata.
parameters:
- name: symbol
type: string
required: true
- name: period
description: >-
Lookback window. Default is '1mo' when start/end are not given,
otherwise null (use start/end). Mutually exclusive with start/end —
but can be combined for `end = start + period`. Use "max" for full
history.
type: string
required: false
enum:
- "1d"
- "5d"
- "1mo"
- "3mo"
- "6mo"
- "1y"
- "2y"
- "5y"
- "10y"
- "ytd"
- "max"
- name: interval
description: >-
Bar size. Default "1d". Intraday intervals (1m, 2m, 5m, 15m, 30m,
60m, 90m, 1h) cannot extend more than ~60 days back.
type: string
required: false
enum:
- "1m"
- "2m"
- "5m"
- "15m"
- "30m"
- "60m"
- "90m"
- "1h"
- "1d"
- "5d"
- "1wk"
- "1mo"
- "3mo"
- name: start
description: >-
Inclusive start. ISO date "YYYY-MM-DD" or datetime. Default 99
years ago.
type: string
required: false
- name: end
description: >-
Exclusive end. ISO date "YYYY-MM-DD" or datetime. Default now.
For end="2023-01-01", last bar = 2022-12-31.
type: string
required: false
- name: prepost
description: Include pre/post-market bars for intraday intervals. Default false.
type: boolean
required: false
- name: actions
description: Include Dividends and Stock Splits columns. Default true.
type: boolean
required: false
- name: auto_adjust
description: >-
If true (default), all OHLC are back-adjusted for splits and
dividends. Set false to keep raw OHLC plus a separate Adj Close.
type: boolean
required: false
- name: back_adjust
description: Back-adjusted data to mimic true historical prices. Default false.
type: boolean
required: false
- name: repair
description: >-
Run scipy-backed heuristics that detect Yahoo's known bad-tick
patterns (100x / 0.01x splits, missing dividends, currency-unit
flips) and rewrite affected bars. Requires the `repair` extra.
Not supported with interval "5d"; for "1wk"/"1mo"/"3mo" the
scraper silently fetches 1d and resamples. Default false.
type: boolean
required: false
- name: keepna
description: Keep rows where every OHLC value is NaN (Yahoo holiday rows). Default false.
type: boolean
required: false
- name: rounding
description: Round prices to 2 decimals. Default false → use Yahoo precision.
type: boolean
required: false
- name: timeout
description: Per-request timeout in seconds. Default 10. Can be a float (0.01 ok).
type: number
required: false
- name: raise_errors
description: >-
Deprecated alias — use `yf.config.debug.hide_exceptions = false`.
If true, raise on errors instead of logging. Default false.
type: boolean
required: false
annotations:
title: Get Ticker History
readOnlyHint: true
destructiveHint: false
idempotentHint: true
openWorldHint: true
- name: tickerHistoryMetadata
description: >-
Return the metadata Yahoo attaches to the chart response: exchange,
timezone, currency, regular-market hours, instrument type,
firstTradeDate, validRanges, etc. Calls
`Ticker(symbol).get_history_metadata()`.
parameters:
- name: symbol
type: string
required: true
annotations:
title: Get History Metadata
readOnlyHint: true
destructiveHint: false
idempotentHint: true
openWorldHint: true
- name: tickerActions
description: >-
Return one action stream as a pandas Series (or combined DataFrame for
"actions"). Wraps `get_dividends / get_splits / get_capital_gains /
get_actions`. All accept a `period` argument that defaults to "max".
parameters:
- name: symbol
type: string
required: true
- name: kind
description: Which action stream to return. "actions" merges dividends + splits.
type: string
required: false
enum:
- "actions"
- "dividends"
- "splits"
- "capital_gains"
- name: period
description: Lookback window. Default "max".
type: string
required: false
enum:
- "1d"
- "5d"
- "1mo"
- "3mo"
- "6mo"
- "1y"
- "2y"
- "5y"
- "10y"
- "ytd"
- "max"
annotations:
title: Get Ticker Actions
readOnlyHint: true
destructiveHint: false
idempotentHint: true
openWorldHint: true
- name: tickerFinancials
description: >-
Return one of the three financial statements as a DataFrame. Rows are
line items, columns are period end dates. Wraps
`get_income_stmt / get_balance_sheet / get_cash_flow`. With
`pretty=true` Yahoo's camelCase keys are translated to human row
labels via the maps in `yfinance/const.py`.
parameters:
- name: symbol
type: string
required: true
- name: statement
description: Which statement to retrieve.
type: string
required: true
enum:
- "income_stmt"
- "balance_sheet"
- "cash_flow"
- name: freq
description: Reporting frequency. "trailing" = TTM (income_stmt / cash_flow only; balance_sheet has no TTM).
type: string
required: false
enum:
- "yearly"
- "quarterly"
- "trailing"
- name: pretty
description: Translate raw Yahoo keys to human-readable labels. Default false.
type: boolean
required: false
- name: as_dict
description: Return the result as a plain dict instead of a DataFrame. Default false.
type: boolean
required: false
annotations:
title: Get Ticker Financials
readOnlyHint: true
destructiveHint: false
idempotentHint: true
openWorldHint: true
- name: tickerValuationMeasures
description: >-
Historical valuation ratios (P/E, P/B, P/S, EV/EBITDA, EV/Revenue,
market cap) as a DataFrame via `get_valuation_measures()`.
parameters:
- name: symbol
type: string
required: true
annotations:
title: Get Valuation Measures
readOnlyHint: true
destructiveHint: false
idempotentHint: true
openWorldHint: true
- name: tickerEarnings
description: >-
Historical revenue + earnings table per year or quarter via
`get_earnings(freq=)`. For forward-looking estimates use
`tickerAnalystEstimates`.
parameters:
- name: symbol
type: string
required: true
- name: freq
description: Default "yearly".
type: string
required: false
enum:
- "yearly"
- "quarterly"
- name: as_dict
description: Return dict instead of DataFrame. Default false.
type: boolean
required: false
annotations:
title: Get Ticker Earnings
readOnlyHint: true
destructiveHint: false
idempotentHint: true
openWorldHint: true
- name: tickerEarningsDates
description: >-
Upcoming + recent earnings dates with EPS estimate, reported EPS and
surprise %. Wraps `get_earnings_dates(limit=, offset=)`. Yahoo caps
`limit` at 100; offset=0 starts from future estimates, offset=N
skips that many quarters back.
parameters:
- name: symbol
type: string
required: true
- name: limit
description: Max rows to return. Default 12, max 100.
type: number
required: false
- name: offset
description: Skip this many quarters before reading. Default 0.
type: number
required: false
annotations:
title: Get Earnings Dates
readOnlyHint: true
destructiveHint: false
idempotentHint: true
openWorldHint: true
- name: tickerAnalystEstimates
description: >-
Forward-looking analyst data. Wraps the seven `Ticker.get_*` methods
under `yfinance/scrapers/analysis.py` plus the
`recommendations*`/`upgrades_downgrades` methods on `TickerBase`.
Most return a DataFrame; `analyst_price_targets` returns a dict.
parameters:
- name: symbol
type: string
required: true
- name: kind
description: Which analyst dataset to return.
type: string
required: true
enum:
- "analyst_price_targets"
- "earnings_estimate"
- "revenue_estimate"
- "earnings_history"
- "eps_trend"
- "eps_revisions"
- "growth_estimates"
- "recommendations"
- "recommendations_summary"
- "upgrades_downgrades"
- name: as_dict
description: Return dict instead of DataFrame (where applicable). Default false.
type: boolean
required: false
annotations:
title: Get Analyst Estimates
readOnlyHint: true
destructiveHint: false
idempotentHint: true
openWorldHint: true
- name: tickerHolders
description: >-
Ownership data via the `holders` scraper. `major_holders` returns the
breakdown table; the other kinds return per-holder DataFrames.
parameters:
- name: symbol
type: string
required: true
- name: kind
type: string
required: true
enum:
- "major_holders"
- "institutional_holders"
- "mutualfund_holders"
- "insider_purchases"
- "insider_transactions"
- "insider_roster_holders"
- name: as_dict
description: Return dict instead of DataFrame. Default false.
type: boolean
required: false
annotations:
title: Get Ticker Holders
readOnlyHint: true
destructiveHint: false
idempotentHint: true
openWorldHint: true
- name: tickerCalendar
description: >-
Next earnings + dividend + split events for one symbol as a dict.
Wraps `Ticker(symbol).get_calendar()`. (This is the per-symbol
calendar; for market-wide event calendars see `getCalendars`.)
parameters:
- name: symbol
type: string
required: true
annotations:
title: Get Ticker Calendar
readOnlyHint: true
destructiveHint: false
idempotentHint: true
openWorldHint: true
- name: tickerNews
description: >-
Recent Yahoo Finance news items for one symbol. Wraps
`Ticker(symbol).get_news(count=, tab=)`. Returns a list of dicts with
title, link, publisher, providerPublishTime, type, thumbnails, etc.
parameters:
- name: symbol
type: string
required: true
- name: count
description: Number of articles to return. Default 10.
type: number
required: false
- name: tab
description: Yahoo news tab. Default "news".
type: string
required: false
enum:
- "news"
- "all"
- "press releases"
annotations:
title: Get Ticker News
readOnlyHint: true
destructiveHint: false
idempotentHint: false
openWorldHint: true
- name: tickerSecFilings
description: SEC filings (10-K, 10-Q, 8-K, etc.) Yahoo has surfaced for the symbol. Wraps `get_sec_filings()`.
parameters:
- name: symbol
type: string
required: true
annotations:
title: Get SEC Filings
readOnlyHint: true
destructiveHint: false
idempotentHint: true
openWorldHint: true
- name: tickerSustainability
description: ESG / sustainability scores DataFrame, when Yahoo publishes one for the symbol. Wraps `get_sustainability(as_dict=)`.
parameters:
- name: symbol
type: string
required: true
- name: as_dict
description: Return dict instead of DataFrame. Default false.
type: boolean
required: false
annotations:
title: Get Sustainability Scores
readOnlyHint: true
destructiveHint: false
idempotentHint: true
openWorldHint: true
- name: tickerIsin
description: >-
Return the ISIN for the symbol. Best-effort and **experimental** —
depends on a businessinsider.com lookup keyed off `Ticker.info`'s
shortName; will return "-" if not resolvable.
parameters:
- name: symbol
type: string
required: true
annotations:
title: Get ISIN
readOnlyHint: true
destructiveHint: false
idempotentHint: true
openWorldHint: true
- name: tickerShares
description: >-
Share-count history DataFrame (basic & diluted shares outstanding
over time) from the fundamentals time-series endpoint. Wraps
`get_shares(as_dict=)`.
parameters:
- name: symbol
type: string
required: true
- name: as_dict
type: boolean
required: false
annotations:
title: Get Shares Outstanding
readOnlyHint: true
destructiveHint: false
idempotentHint: true
openWorldHint: true
- name: tickerSharesFull
description: >-
Full daily shares-outstanding Series between two dates. Wraps
`get_shares_full(start=, end=)`. Default window is the last 18
months.
parameters:
- name: symbol
type: string
required: true
- name: start
description: ISO date / datetime. Default = end - 548 days.
type: string
required: false
- name: end
description: ISO date / datetime. Default now.
type: string
required: false
annotations:
title: Get Shares Outstanding (Full)
readOnlyHint: true
destructiveHint: false
idempotentHint: true
openWorldHint: true
- name: tickerOptionExpirations
description: >-
List the available option expiration dates for a symbol (sorted
ascending, "YYYY-MM-DD" strings). Wraps `Ticker(symbol).options`.
parameters:
- name: symbol
type: string
required: true
annotations:
title: List Option Expirations
readOnlyHint: true
destructiveHint: false
idempotentHint: true
openWorldHint: true
- name: tickerOptionChain
description: >-
Full option chain for one expiration via
`Ticker(symbol).option_chain(date=, tz=)`. Returns a NamedTuple
`(calls, puts, underlying)` where calls/puts are DataFrames with
contractSymbol, lastTradeDate, strike, lastPrice, bid, ask, change,
percentChange, volume, openInterest, impliedVolatility, inTheMoney,
contractSize, currency.
parameters:
- name: symbol
type: string
required: true
- name: date
description: 'Expiration date "YYYY-MM-DD". Omit to use the nearest expiration.'
type: string
required: false
- name: tz
description: 'Convert lastTradeDate to this timezone (e.g. "America/New_York").'
type: string
required: false
annotations:
title: Get Option Chain
readOnlyHint: true
destructiveHint: false
idempotentHint: true
openWorldHint: true
- name: tickerFundsData
description: >-
ETF / mutual-fund specific fields via `Ticker.get_funds_data()`.
The resulting `FundsData` exposes properties: `quote_type`,
`description`, `fund_overview`, `fund_operations` (DataFrame),
`asset_classes` (dict), `top_holdings` (DataFrame), `equity_holdings`,
`bond_holdings`, `bond_ratings`, `sector_weightings`.
parameters:
- name: symbol
type: string
required: true
annotations:
title: Get Funds Data
readOnlyHint: true
destructiveHint: false
idempotentHint: true
openWorldHint: true
- name: tickerLive
description: >-
Subscribe to live ticks for ONE symbol using `Ticker(symbol).live()`.
Blocking; calls `message_handler(dict)` for each decoded protobuf
message. For multi-symbol streams use `streamLiveQuotes`.
parameters:
- name: symbol
type: string
required: true
- name: verbose
description: Print connection / subscription notices to stdout. Default true.
type: boolean
required: false
annotations:
title: Stream One Ticker Live
readOnlyHint: true
destructiveHint: false
idempotentHint: false
openWorldHint: true
## Multi-ticker — batch downloads + collection
## ------------------------------------------------------------
- name: downloadHistory
description: >-
Bulk download OHLCV for many symbols in parallel via
`yfinance.download`. Returns a single (multi-indexed) DataFrame.
Preferred over a loop of `tickerHistory` calls for portfolio sweeps.
parameters:
- name: tickers
description: 'Space- or comma-separated string ("AAPL MSFT NVDA") OR an array of symbols. ISINs are auto-resolved to tickers.'
type: array
required: true
items:
type: string
- name: start
description: ISO date / datetime, inclusive. Default 99 years ago.
type: string
required: false
- name: end
description: ISO date / datetime, exclusive. Default now.
type: string
required: false
- name: period
description: Lookback window. Default "1mo" when start & end are not given.
type: string
required: false
enum:
- "1d"
- "5d"
- "1mo"
- "3mo"
- "6mo"
- "1y"
- "2y"
- "5y"
- "10y"
- "ytd"
- "max"
- name: interval
description: Bar size. Default "1d". Intraday capped at ~60 days.
type: string
required: false
enum:
- "1m"
- "2m"
- "5m"
- "15m"
- "30m"
- "60m"
- "90m"
- "1h"
- "1d"
- "5d"
- "1wk"
- "1mo"
- "3mo"
- name: group_by
description: 'Top-level column grouping. Default "column" → columns are field names; "ticker" → columns are symbols.'
type: string
required: false
enum:
- "ticker"
- "column"
- name: actions
description: Include dividend + stock-split columns. Default false.
type: boolean
required: false
- name: auto_adjust
description: Adjust all OHLC automatically. Default true.
type: boolean
required: false
- name: back_adjust
description: Back-adjusted to mimic true historical prices. Default false.
type: boolean
required: false
- name: repair
description: Detect currency-unit 100x mixups and attempt repair. Default false.
type: boolean
required: false
- name: keepna
description: Keep NaN rows returned by Yahoo. Default false.
type: boolean
required: false
- name: prepost
description: Include pre/post-market data. Default false.
type: boolean
required: false
- name: threads
description: 'Use multitasking to parallelize per-symbol requests. true → auto pool size (min(N, cpu*2)); int → exact pool size; false → serial. Default true.'
type: boolean
required: false
- name: ignore_tz
description: Strip tz info from the index so multi-market frames align. Default true for ≥1d intervals, false for intraday.
type: boolean
required: false
- name: progress
description: Show progress bar. Default true. Forced off when DEBUG logging is on.
type: boolean
required: false
- name: rounding
description: Round prices to 2 decimals. Default false.
type: boolean
required: false
- name: timeout
description: Per-request timeout in seconds (float ok). Default 10.
type: number
required: false
- name: multi_level_index
description: Always return a MultiIndex DataFrame even for a single symbol. Default true.
type: boolean
required: false
annotations:
title: Download Multi-Ticker History
readOnlyHint: true
destructiveHint: false
idempotentHint: true
openWorldHint: true
- name: tickersContainer
description: >-
Construct a `Tickers` collection holding individual Ticker instances
keyed by symbol — convenient when you want per-symbol property access
without calling `Ticker(...)` in a loop. Exposes `.history(...)`,
`.download(...)`, `.news()`, `.live()` methods.
parameters:
- name: tickers
description: Space-separated string or array of symbols.
type: array
required: true
items:
type: string
annotations:
title: Build Tickers Collection
readOnlyHint: true
destructiveHint: false
idempotentHint: true
openWorldHint: false
- name: tickersHistory
description: >-
Multi-symbol `Tickers.history(...)`. Thin wrapper around
`downloadHistory` that also populates each child `Ticker._history`
attribute. Use `downloadHistory` instead unless you need the
Tickers object to retain history caches.
parameters:
- name: tickers
type: array
required: true
items:
type: string
- name: period
type: string
required: false
- name: interval
type: string
required: false
- name: start
type: string
required: false
- name: end
type: string
required: false
- name: prepost
type: boolean
required: false
- name: actions
type: boolean
required: false
- name: auto_adjust
type: boolean
required: false
- name: repair
type: boolean
required: false
- name: threads
type: boolean
required: false
- name: group_by
type: string
required: false
enum:
- "ticker"
- "column"
- name: progress
type: boolean
required: false
- name: timeout
type: number
required: false
annotations:
title: Tickers Collection History
readOnlyHint: true
destructiveHint: false
idempotentHint: true
openWorldHint: true
- name: tickersNews
description: 'Per-symbol news for every ticker in the collection. Returns `{symbol: [news, ...]}` via `Tickers(tickers).news()`.'
parameters:
- name: tickers
type: array
required: true
items:
type: string
annotations:
title: Tickers Collection News
readOnlyHint: true
destructiveHint: false
idempotentHint: false
openWorldHint: true
## Search & Lookup — symbol discovery
## ------------------------------------------------------------
- name: searchTickers
description: >-
Yahoo Finance search by keyword / company name via
`yf.Search(query, ...)`. Wraps `/v1/finance/search`. Returns quotes,
news, lists, research reports and nav links. Constructor runs the
search immediately; the returned object exposes `.quotes`, `.news`,
`.lists`, `.research`, `.nav`, `.all`, `.response`.
parameters:
- name: query
description: Search query (ticker, partial ticker, or company name).
type: string
required: true
- name: max_results
description: Max stock quotes to return. Default 8.
type: number
required: false
- name: news_count
description: Number of news articles. Default 8.
type: number
required: false
- name: lists_count
description: Number of curated lists. Default 8.
type: number
required: false
- name: include_cb
description: Include the company breakdown. Default true.
type: boolean
required: false
- name: include_nav_links
description: Include navigation links. Default false.
type: boolean
required: false
- name: include_research
description: Include research reports. Default false.
type: boolean
required: false
- name: include_cultural_assets
description: Include cultural assets. Default false.
type: boolean
required: false
- name: enable_fuzzy_query
description: Enable fuzzy search for typos. Default false.
type: boolean
required: false
- name: recommended
description: Recommended number of results. Default 8.
type: number
required: false
- name: timeout
description: Request timeout in seconds. Default 30.
type: number
required: false
- name: raise_errors
description: Raise exceptions on error. Default true.
type: boolean
required: false
annotations:
title: Search Tickers
readOnlyHint: true
destructiveHint: false
idempotentHint: false
openWorldHint: true
- name: lookupTickers
description: >-
Fuzzy symbol lookup across asset classes via `yf.Lookup(query, ...)`.
Per asset class call `.get_all / .get_stock / .get_mutualfund /
.get_etf / .get_index / .get_future / .get_currency /
.get_cryptocurrency`, each accepting `count=` (default 25). Returns
structured DataFrames of candidate symbols.
parameters:
- name: query
type: string
required: true
- name: type
description: 'Restrict to one asset class. Maps to `Lookup.get_<type>()`. Default "all".'
type: string
required: false
enum:
- "all"
- "stock"
- "mutualfund"
- "etf"
- "index"
- "future"
- "currency"
- "cryptocurrency"
- name: count
description: Max rows. Default 25.
type: number
required: false
- name: timeout
description: Request timeout in seconds. Default 30.
type: number
required: false
- name: raise_errors
description: Raise on error instead of logging. Default true.
type: boolean
required: false
annotations:
title: Lookup Tickers
readOnlyHint: true
destructiveHint: false
idempotentHint: true
openWorldHint: true
## Domain — Market / Sector / Industry
## ------------------------------------------------------------
- name: marketSummary
description: >-
Market overview for a region via `yf.Market(market).summary`. Hits
`/v6/finance/quote/marketSummary` for shortName /
regularMarketPrice / regularMarketChange / regularMarketChangePercent
of every exchange/index Yahoo tracks for that region. Returns a
dict keyed by exchange.
parameters:
- name: market
description: Yahoo `MarketRegion` enum value. (Yahoo only honors a fixed set — passing other ISO country codes raises ValueError.)
type: string
required: true
enum:
- "US"
- "GB"
- "ASIA"
- "EUROPE"
- "RATES"
- "COMMODITIES"
- "CURRENCIES"
- "CRYPTOCURRENCIES"
- name: timeout
description: Request timeout in seconds. Default 30.
type: number
required: false
annotations:
title: Get Market Summary
readOnlyHint: true
destructiveHint: false
idempotentHint: false
openWorldHint: true
- name: marketStatus
description: >-
Open/closed status, open/close timestamps, and timezone for a
region's primary exchange via `yf.Market(market).status`. Yahoo's
`/v6/finance/markettime` silently returns US data for non-US
requests; the scraper logs a warning and yields None in that case.
parameters:
- name: market
type: string
required: true
enum:
- "US"
- "GB"
- "ASIA"
- "EUROPE"
- "RATES"
- "COMMODITIES"
- "CURRENCIES"
- "CRYPTOCURRENCIES"
- name: timeout
type: number
required: false
annotations:
title: Get Market Status
readOnlyHint: true
destructiveHint: false
idempotentHint: false
openWorldHint: true
- name: sectorInfo
description: >-
Aggregate info for a Yahoo sector via `yf.Sector(key, region=)`.
Exposes properties `name`, `symbol`, `ticker`, `overview`,
`top_companies`, `top_etfs`, `top_mutual_funds`, `industries`,
`research_reports`.
parameters:
- name: key
description: Sector slug (lowercase-hyphenated).
type: string
required: true
enum:
- "basic-materials"
- "communication-services"
- "consumer-cyclical"
- "consumer-defensive"
- "energy"
- "financial-services"
- "healthcare"
- "industrials"
- "real-estate"
- "technology"
- "utilities"
- name: region
description: 'ISO 3166-1 alpha-2 country code (scopes top_companies/etfs/funds). Default "US".'
type: string
required: false
- name: attribute
description: Which property to return. Default returns the whole `Sector` object's state as a dict.
type: string
required: false
enum:
- "overview"
- "top_companies"
- "top_etfs"
- "top_mutual_funds"
- "industries"
- "research_reports"
- "name"
- "symbol"
annotations:
title: Get Sector Info
readOnlyHint: true
destructiveHint: false
idempotentHint: true
openWorldHint: true
- name: industryInfo
description: >-
Aggregate info for a Yahoo industry via `yf.Industry(key, region=)`.
Exposes `sector_key`, `sector_name`, `overview`, `top_companies`,
`top_performing_companies`, `top_growth_companies`,
`research_reports`.
parameters:
- name: key
description: Industry slug (e.g. "software-infrastructure", "semiconductors").
type: string
required: true
- name: region
description: 'ISO 3166-1 alpha-2 country code. Default "US".'
type: string
required: false
- name: attribute
description: Which property to return.
type: string
required: false
enum:
- "overview"
- "top_companies"
- "top_performing_companies"
- "top_growth_companies"
- "research_reports"
- "sector_key"
- "sector_name"
annotations:
title: Get Industry Info
readOnlyHint: true
destructiveHint: false
idempotentHint: true
openWorldHint: true
## Calendars — earnings / IPO / economic events / splits (market-wide)
## yf.Calendars(start=, end=) → call any of the four getters below.
## ------------------------------------------------------------
- name: getEarningsCalendar
description: >-
Market-wide earnings calendar via
`Calendars(start, end).get_earnings_calendar(...)`. Returns a
DataFrame sorted by Event Start Date desc. Default window is today
→ today + 7 days when start/end are omitted.
parameters:
- name: start
description: Window start date (ISO / datetime). Default today. Set with `end` together.
type: string
required: false
- name: end
description: Window end date. Default start + 7 days.
type: string
required: false
- name: market_cap
description: Minimum market cap cutoff in USD. Default null (no filter).
type: number
required: false
- name: filter_most_active
description: Filter for actively traded stocks. Default true. Disabled internally when `offset > 0`.
type: boolean
required: false
- name: limit
description: Max rows. Default 12. Yahoo caps at 100.
type: number
required: false
- name: offset
description: Pagination offset. Default 0.
type: number
required: false
- name: force
description: Re-query even if a previous call cached the same body. Default false.
type: boolean
required: false
annotations:
title: Get Earnings Calendar
readOnlyHint: true
destructiveHint: false
idempotentHint: true
openWorldHint: true
- name: getIpoInfoCalendar
description: 'IPO calendar via `Calendars(start, end).get_ipo_info_calendar(...)`.'
parameters:
- name: start
type: string
required: false
- name: end
type: string
required: false
- name: limit
description: Max rows. Default 12, capped at 100.
type: number
required: false
- name: offset
type: number
required: false
- name: force
type: boolean
required: false
annotations:
title: Get IPO Calendar
readOnlyHint: true
destructiveHint: false
idempotentHint: true
openWorldHint: true
- name: getEconomicEventsCalendar
description: >-
Economic events calendar (CPI, FOMC, etc.) via
`Calendars(start, end).get_economic_events_calendar(...)`.
parameters:
- name: start
type: string
required: false
- name: end
type: string
required: false
- name: limit
type: number
required: false
- name: offset
type: number
required: false
- name: force
type: boolean
required: false
annotations:
title: Get Economic Events Calendar
readOnlyHint: true
destructiveHint: false
idempotentHint: true
openWorldHint: true
- name: getSplitsCalendar
description: 'Upcoming stock-splits calendar via `Calendars(start, end).get_splits_calendar(...)`.'
parameters:
- name: start
type: string
required: false
- name: end
type: string
required: false
- name: limit
type: number
required: false
- name: offset
type: number
required: false
- name: force
type: boolean
required: false
annotations:
title: Get Splits Calendar
readOnlyHint: true
destructiveHint: false
idempotentHint: true
openWorldHint: true
## Screener — yf.EquityQuery / FundQuery / ETFQuery + yf.screen
## ------------------------------------------------------------
- name: screenMarket
description: >-
Run `yf.screen(query, ...)`. `query` may be the name of a
predefined Yahoo screener (string — e.g. "day_gainers") OR a
serialized query tree from `EquityQuery / FundQuery / ETFQuery`
(object). Returns Yahoo's `finance.result[0]` payload with the
matched quotes. Note: `size` is for custom queries (default 100,
max 250); `count` is for predefined queries (default 25, max 250).
Yahoo's predefined endpoint ignores `offset` — when an offset is
supplied with a predefined name, the call transparently switches
to the custom-query endpoint.
parameters:
- name: query
description: >-
Either a string (predefined screener name from
`PREDEFINED_SCREENER_QUERIES`) or a QueryBase serialization,
e.g. `{"operator": "and", "operands":
[{"operator":"gt", "operands":["intradaymarketcap", 1e10]},
{"operator":"lt", "operands":["peratio.lasttwelvemonths", 20]}]}`,
plus a `_quoteType` hint of "EQUITY" / "MUTUALFUND" / "ETF".
type: object
required: true
- name: size
description: Result count for custom queries. Default 100, max 250.
type: number
required: false
- name: count
description: Result count for predefined queries. Default 25, max 250.
type: number
required: false
- name: offset
description: Pagination offset. Default 0.
type: number
required: false
- name: sortField
description: 'Yahoo field id to sort by (e.g. "intradaymarketcap", "percentchange", "dayvolume"). Default "ticker" for custom; predefined defaults baked into each template.'
type: string
required: false
- name: sortAsc
description: Sort ascending. Default false (descending).
type: boolean
required: false
- name: userId
description: Yahoo user ID. Default empty.
type: string
required: false
- name: userIdType
description: 'Type of user ID. Default "guid".'
type: string
required: false
annotations:
title: Screen Market
readOnlyHint: true
destructiveHint: false
idempotentHint: true
openWorldHint: true
- name: listPredefinedScreeners
description: >-
Return the keys (and optionally the full bodies) of
`PREDEFINED_SCREENER_QUERIES`. Examples:
`aggressive_small_caps`, `day_gainers`, `day_losers`,
`growth_technology_stocks`, `most_actives`, `most_shorted_stocks`,
`small_cap_gainers`, `undervalued_growth_stocks`,
`undervalued_large_caps`, `conservative_foreign_funds`,
`high_yield_bond`, `portfolio_anchors`, `solid_large_growth_funds`,
`solid_midcap_growth_funds`, `top_mutual_funds`, `top_etfs_us`,
`top_performing_etfs`, `technology_etfs`, `bond_etfs`.
parameters:
- name: include_bodies
description: When true, return each entry's full QueryBase tree, not just the name. Default false.
type: boolean
required: false
annotations:
title: List Predefined Screeners
readOnlyHint: true
destructiveHint: false
idempotentHint: true
openWorldHint: false
- name: buildScreenerQuery
description: >-
Construct an `EquityQuery / FundQuery / ETFQuery` programmatically.
Use this when assembling a custom screener before calling
`screenMarket`. Operators are validated against the per-universe
`valid_fields` and `valid_values` maps in `yfinance/const.py`.
parameters:
- name: queryType
description: Which screener universe to build for.
type: string
required: true
enum:
- "equity"
- "mutualfund"
- "etf"
- name: operator
description: >-
Top-level operator. Value operators take a [field, value] (or
[field, lo, hi] for btwn, [field, v1, v2, ...] for is-in);
logical operators take a list of nested queries.
type: string
required: true
enum:
- "eq"
- "is-in"
- "btwn"
- "gt"
- "lt"
- "gte"
- "lte"
- "and"
- "or"
- name: operands
description: 'Operand list. Each entry is either a leaf (string field name + scalar) or a nested query object (operator + operands).'
type: array
required: true
items:
type: object
annotations:
title: Build Screener Query
readOnlyHint: true
destructiveHint: false
idempotentHint: true
openWorldHint: false
## Live streaming — Yahoo WebSocket (protobuf-encoded)
## ------------------------------------------------------------
- name: streamLiveQuotes
description: >-
Open a Yahoo WebSocket and stream real-time pricing for a set of
symbols. Wraps `yf.WebSocket(url=, verbose=)` (sync) or
`yf.AsyncWebSocket(url=, verbose=)` (asyncio). After construction,
call `subscribe(symbols)` then `listen(message_handler)`. Messages
are protobuf-encoded per `yfinance/pricing.proto`. The async
variant additionally maintains a heartbeat-subscribe task.
parameters:
- name: symbols
description: Symbols to subscribe to. Single string or array.
type: array
required: true
items:
type: string
- name: mode
description: '"sync" → `WebSocket`; "async" → `AsyncWebSocket` (must be awaited).'
type: string
required: false
enum:
- "sync"
- "async"
- name: url
description: 'WebSocket server URL. Default "wss://streamer.finance.yahoo.com/?version=2".'
type: string
required: false
- name: verbose
description: Print connection / subscription / message text to stdout. Default true.
type: boolean
required: false
- name: durationSeconds
description: How long to listen before closing. Omit to listen indefinitely (Ctrl-C / `close()` to stop).
type: number
required: false
annotations:
title: Stream Live Quotes
readOnlyHint: true
destructiveHint: false
idempotentHint: false
openWorldHint: true
- name: liveSubscribe
description: 'Add symbols to an existing live stream (`WebSocket.subscribe`). Sends `{"subscribe": [...]}`. Async variant must be awaited.'
parameters:
- name: symbols
type: array
required: true
items:
type: string
annotations:
title: Subscribe Live Symbols
readOnlyHint: false
destructiveHint: false
idempotentHint: true
openWorldHint: true
- name: liveUnsubscribe
description: 'Remove symbols from an existing live stream (`WebSocket.unsubscribe`). Sends `{"unsubscribe": [...]}`.'
parameters:
- name: symbols
type: array
required: true
items:
type: string
annotations:
title: Unsubscribe Live Symbols
readOnlyHint: false
destructiveHint: true
idempotentHint: true
openWorldHint: true
## Auth — Yahoo crumb / cookie challenge
## ------------------------------------------------------------
- name: authSetCookies
description: >-
Inject existing Yahoo login cookies (T / Y) into the shared
`YfData` session via `Auth.set_login_cookies(cookie_t, cookie_y)`.
Required when scraping account-gated data. Cookies stay in the
Singleton session for the lifetime of the process.
parameters:
- name: cookie_t
description: Value of the Yahoo "T" cookie.
type: string
required: true
- name: cookie_y
description: Value of the Yahoo "Y" cookie.
type: string
required: true
annotations:
title: Set Yahoo Login Cookies
readOnlyHint: false
destructiveHint: false
idempotentHint: true
openWorldHint: false
- name: authStrategy
description: >-
Force the cookie-acquisition strategy used by `YfData`. "basic"
hits the plain cookie endpoint; "csrf" follows the consent +
CSRF flow (needed in EU regions). The default ("basic") falls
back to "csrf" automatically on failure.
parameters:
- name: strategy
type: string
required: true
enum:
- "basic"
- "csrf"
annotations:
title: Set Yahoo Auth Strategy
readOnlyHint: false
destructiveHint: false
idempotentHint: true
openWorldHint: true
## Config & Cache — local-state helpers
## ------------------------------------------------------------
- name: setConfig
description: >-
Update the global `yf.config` (proxy, retry count, locale, debug
flags). Mutates a process-wide singleton; affects every subsequent
request.
parameters:
- name: proxy
description: 'HTTP/HTTPS proxy URL. Updates `yf.config.network.proxy`. Default null.'
type: string
required: false
- name: retries
description: Retry attempts on transient HTTP failures. Updates `yf.config.network.retries`. Default 0.
type: number
required: false
- name: lang
description: 'BCP-47 language tag for Yahoo v7/v10 endpoints. Updates `yf.config.locale.lang`. Default "en-US".'
type: string
required: false
- name: region
description: 'ISO 3166-1 alpha-2 country code. Updates `yf.config.locale.region`. Default "US".'
type: string
required: false
- name: hideExceptions
description: 'Swallow non-fatal scraper exceptions and return empty data. Updates `yf.config.debug.hide_exceptions`. Default true.'
type: boolean
required: false
- name: logging
description: 'Enable verbose yfinance logging. Updates `yf.config.debug.logging` (same as `enable_debug_mode()`). Default false.'
type: boolean
required: false
annotations:
title: Set yfinance Config
readOnlyHint: false
destructiveHint: false
idempotentHint: true
openWorldHint: false
- name: getConfig
description: Dump the current `yf.config` tree as JSON.
annotations:
title: Get yfinance Config
readOnlyHint: true
destructiveHint: false
idempotentHint: true
openWorldHint: false
- name: enableDebugMode
description: Shortcut for `yf.enable_debug_mode()` — turns on internal logging at DEBUG level.
annotations:
title: Enable Debug Mode
readOnlyHint: false
destructiveHint: false
idempotentHint: true
openWorldHint: false
- name: setTzCacheLocation
description: >-
Point yfinance's SQLite tz / cookie cache at a custom directory via
`yf.set_tz_cache_location(path)`. Useful for tests or when the
default platformdirs path is read-only.
parameters:
- name: path
description: Absolute filesystem path to the cache directory.
type: string
required: true
annotations:
title: Set TZ Cache Location
readOnlyHint: false
destructiveHint: false
idempotentHint: true
openWorldHint: false
- name: clearTzCache
description: >-
Delete the on-disk tz / cookie cache directory (the next request
will re-create it). Destructive against local state only; does not
touch Yahoo.
parameters:
- name: path
description: Cache directory to remove. Defaults to the active location.
type: string
required: false
annotations:
title: Clear TZ Cache
readOnlyHint: false
destructiveHint: true
idempotentHint: true
openWorldHint: false
# ============================================================================
# CLI design — `yfin`
# ----------------------------------------------------------------------------
# Wraps every tool above as a subcommand of a single binary, `yfin`.
# Every `command:` field below shows the exact CLI invocation; every
# `tool:` field is a back-reference to the matching `tools[].name` so the
# generator script (`scripts/gen-cli.py`, planned) can scaffold Typer
# commands directly from this section without drift.
# ============================================================================
cli:
binary: yfin
entry_point: yfin.__main__:app
description: >-
Single-binary CLI for the yfinance Python library. All 49 tools above
are reachable as `yfin <group> <subcommand> [args] [flags]`. Output
defaults to a Rich-formatted table on a TTY, JSON when stdout is a
pipe; override with `--format` or write to disk with `--out`.
framework: Typer + Rich
python: ">=3.9"
dependencies:
- "typer>=0.12"
- "rich>=13"
- "yfinance>=1.4.1" # the wrapped library
- "pyarrow>=14" # for --format parquet
- "PyYAML>=6" # so the CLI can load this file as its own SSOT
packaging:
pyproject_entry: 'yfin = "yfin.__main__:app"'
install: pip install yfin
completion: yfin --install-completion {bash|zsh|fish|pwsh}
config_file:
path: ~/.yfin/config.toml
purpose: >-
Stores user-level defaults that are also exposed as flags:
proxy, retries, locale (lang/region), cache_dir, default_format,
stored Yahoo cookies (T/Y). Flags always override config.
## Global flags every subcommand accepts.
## ------------------------------------------------------------
globalOptions:
- name: --format
shortFlag: -f
description: Output format. Default `table` when stdout is a TTY, `json` when piped.
type: string
enum:
- table # Rich-rendered (DataFrame, dict, list)
- json # pandas to_json(orient='split') / json.dumps for dict/list
- ndjson # one JSON object per line; ideal for streaming output
- csv # pandas to_csv (DataFrame only)
- tsv # pandas to_csv(sep='\t')
- parquet # pandas to_parquet (DataFrame only); needs --out
- yaml # PyYAML safe_dump (dict/list only)
- name: --out
shortFlag: -o
description: Write to PATH instead of stdout. Format is inferred from the file extension if --format is omitted.
type: string
- name: --pretty
description: Pretty-print JSON / YAML output (indent=2). Default true for table/json on TTY, false for ndjson.
type: boolean
- name: --compact
description: Opposite of --pretty; force single-line JSON. Useful for piping into `jq -c`.
type: boolean
- name: --columns
description: Comma-separated list of columns to keep before rendering (DataFrame outputs only).
type: string
- name: --limit
description: Truncate the rendered output to the first N rows / items. Renders client-side after the API call returns.
type: number
- name: --proxy
description: HTTP/HTTPS proxy URL. Forwarded to `yf.config.network.proxy` for this invocation.
type: string
- name: --timeout
description: Request timeout in seconds (float ok). Default 10.
type: number
- name: --retries
description: Retry attempts on transient HTTP failures. Default 0.
type: number
- name: --lang
description: 'BCP-47 language tag. Default "en-US".'
type: string
- name: --region
description: 'ISO 3166-1 alpha-2 country code. Default "US".'
type: string
- name: --cache-dir
description: Override the tz / cookie SQLite cache directory.
type: string
- name: --config
description: Use a non-default ~/.yfin/config.toml path.
type: string
- name: --no-color
description: Disable Rich color output. Auto-disabled when stdout is not a TTY.
type: boolean
- name: --quiet
shortFlag: -q
description: Suppress progress bars and warnings.
type: boolean
- name: --verbose
shortFlag: -v
description: Enable yfinance debug logging (one -v = INFO, two -vv = DEBUG).
type: boolean
- name: --version
description: Print yfin and yfinance versions and exit.
type: boolean
- name: --install-completion
description: Install shell completion (Typer built-in).
type: string
enum:
- bash
- zsh
- fish
- pwsh
## Format inference rules used by --out when --format is not given.
## ------------------------------------------------------------
outputFormats:
extension_map:
".json": json
".ndjson": ndjson
".jsonl": ndjson
".csv": csv
".tsv": tsv
".parquet": parquet
".pq": parquet
".yaml": yaml
".yml": yaml
table_renderers:
DataFrame: rich.table.Table from pandas with column dtype hints
dict: rich.table.Table (2-col key/value) or rich.tree.Tree for nested
list: rich.table.Table if list of dicts; otherwise bullet list
Series: rich.table.Table (index / value)
NamedTuple: walks fields; calls/puts (option_chain) get a panel each
## Subcommand groups — one entry per CLI namespace.
## ------------------------------------------------------------
commandGroups:
## ticker — per-symbol queries (one symbol per call).
- name: ticker
description: Single-symbol queries. Symbol is the first positional argument.
commands:
- command: yfin ticker info SYMBOL
tool: tickerInfo
notes: Heavy (`quoteSummary`); use `fast-info` when you only need price.
- command: yfin ticker fast-info SYMBOL
tool: tickerFastInfo
- command: >-
yfin ticker history SYMBOL
[--period 1mo|...|max] [--interval 1d|...|3mo]
[--start YYYY-MM-DD] [--end YYYY-MM-DD]
[--prepost] [--no-actions] [--no-auto-adjust] [--back-adjust]
[--repair] [--keepna] [--rounding]
tool: tickerHistory
notes: Boolean flags follow Typer convention — `--prepost`/`--no-prepost`, `--auto-adjust`/`--no-auto-adjust`. Use --out aapl.parquet for round-tripping into pandas.
- command: yfin ticker history-metadata SYMBOL
tool: tickerHistoryMetadata
- command: yfin ticker actions SYMBOL [--kind actions|dividends|splits|capital_gains] [--period max|...]
tool: tickerActions
- command: yfin ticker financials SYMBOL --statement income_stmt|balance_sheet|cash_flow [--freq yearly|quarterly|trailing] [--pretty-rows] [--as-dict]
tool: tickerFinancials
notes: '`--pretty-rows` maps to `pretty=true` (avoids clashing with the global `--pretty` JSON flag).'
- command: yfin ticker valuation SYMBOL
tool: tickerValuationMeasures
- command: yfin ticker earnings SYMBOL [--freq yearly|quarterly] [--as-dict]
tool: tickerEarnings
- command: yfin ticker earnings-dates SYMBOL [--limit 12] [--offset 0]
tool: tickerEarningsDates
- command: yfin ticker analyst SYMBOL --kind {analyst_price_targets|earnings_estimate|revenue_estimate|earnings_history|eps_trend|eps_revisions|growth_estimates|recommendations|recommendations_summary|upgrades_downgrades} [--as-dict]
tool: tickerAnalystEstimates
- command: yfin ticker holders SYMBOL --kind {major_holders|institutional_holders|mutualfund_holders|insider_purchases|insider_transactions|insider_roster_holders} [--as-dict]
tool: tickerHolders
- command: yfin ticker calendar SYMBOL
tool: tickerCalendar
- command: yfin ticker news SYMBOL [--count 10] [--tab news|all|"press releases"]
tool: tickerNews
- command: yfin ticker sec-filings SYMBOL
tool: tickerSecFilings
- command: yfin ticker sustainability SYMBOL [--as-dict]
tool: tickerSustainability
- command: yfin ticker isin SYMBOL
tool: tickerIsin
- command: yfin ticker shares SYMBOL [--as-dict]
tool: tickerShares
- command: yfin ticker shares-full SYMBOL [--start YYYY-MM-DD] [--end YYYY-MM-DD]
tool: tickerSharesFull
- command: yfin ticker options SYMBOL
tool: tickerOptionExpirations
notes: Lists expirations only. Use `yfin ticker option-chain` for the actual chain.
- command: yfin ticker option-chain SYMBOL [--date YYYY-MM-DD] [--tz America/New_York]
tool: tickerOptionChain
notes: Default format renders three panels — calls table, puts table, underlying dict.
- command: yfin ticker funds-data SYMBOL
tool: tickerFundsData
- command: yfin ticker live SYMBOL [--no-verbose] [--duration N] [--format ndjson]
tool: tickerLive
notes: Long-running. Streams decoded protobuf as NDJSON by default; Ctrl-C to stop.
## download — quick multi-ticker history shortcut (top-level on purpose).
- name: download
description: Top-level shortcut for batch OHLCV downloads. Positional args = symbols.
commands:
- command: >-
yfin download SYMBOL [SYMBOL...]
[--start YYYY-MM-DD] [--end YYYY-MM-DD]
[--period 1mo|...] [--interval 1d|...]
[--group-by ticker|column]
[--actions] [--auto-adjust/--no-auto-adjust] [--back-adjust]
[--repair] [--keepna] [--prepost]
[--threads/--no-threads] [--ignore-tz/--no-ignore-tz]
[--rounding] [--no-progress] [--no-multi-level-index]
tool: downloadHistory
notes: Default output for many symbols is a directory of CSVs when --out is a path ending in '/'; otherwise a single multi-indexed CSV/Parquet.
## tickers — `Tickers` collection methods (rarely needed in CLI form).
- name: tickers
description: Operations on a `Tickers` collection. Mostly equivalent to `yfin download`.
commands:
- command: yfin tickers history SYMBOL [SYMBOL...] [shared download flags]
tool: tickersHistory
- command: yfin tickers news SYMBOL [SYMBOL...]
tool: tickersNews
## search — symbol discovery
- name: search
description: Yahoo Finance keyword / company-name search.
commands:
- command: >-
yfin search QUERY
[--max-results 8] [--news-count 8] [--lists-count 8]
[--include-cb/--no-include-cb] [--include-nav-links]
[--include-research] [--include-cultural-assets]
[--fuzzy] [--recommended 8]
[--no-raise-errors]
tool: searchTickers
notes: '--fuzzy is the CLI alias for `enable_fuzzy_query`.'
## lookup — typed symbol lookup
- name: lookup
description: Fuzzy symbol lookup across asset classes.
commands:
- command: yfin lookup QUERY [--type all|stock|mutualfund|etf|index|future|currency|cryptocurrency] [--count 25] [--no-raise-errors]
tool: lookupTickers
## market — region-level overview
- name: market
description: Region-level market overview / status.
commands:
- command: yfin market summary REGION
tool: marketSummary
notes: REGION is one of US, GB, ASIA, EUROPE, RATES, COMMODITIES, CURRENCIES, CRYPTOCURRENCIES.
- command: yfin market status REGION
tool: marketStatus
notes: Yahoo silently returns US data for non-US — CLI prints a warning to stderr in that case.
## sector / industry — domain aggregates
- name: sector
description: Sector aggregates (top companies / ETFs / mutual funds / industries).
commands:
- command: yfin sector KEY [--attribute overview|top_companies|top_etfs|top_mutual_funds|industries|research_reports|name|symbol] [--region US]
tool: sectorInfo
- command: yfin sector list
tool: sectorInfo
notes: Convenience subcommand — prints the 11 valid sector keys; no Yahoo call.
- name: industry
description: Industry aggregates (top performing / top growth companies).
commands:
- command: yfin industry KEY [--attribute overview|top_companies|top_performing_companies|top_growth_companies|research_reports|sector_key|sector_name] [--region US]
tool: industryInfo
## calendars — market-wide event calendars
- name: calendars
description: Market-wide earnings / IPO / economic events / splits calendars.
commands:
- command: yfin calendars earnings [--start YYYY-MM-DD] [--end YYYY-MM-DD] [--market-cap 1e10] [--no-filter-most-active] [--limit 12] [--offset 0] [--force]
tool: getEarningsCalendar
- command: yfin calendars ipo [--start YYYY-MM-DD] [--end YYYY-MM-DD] [--limit 12] [--offset 0] [--force]
tool: getIpoInfoCalendar
- command: yfin calendars economic [--start YYYY-MM-DD] [--end YYYY-MM-DD] [--limit 12] [--offset 0] [--force]
tool: getEconomicEventsCalendar
- command: yfin calendars splits [--start YYYY-MM-DD] [--end YYYY-MM-DD] [--limit 12] [--offset 0] [--force]
tool: getSplitsCalendar
## screen — predefined + custom market screens
- name: screen
description: Run Yahoo Finance screens (predefined or custom QueryBase trees).
commands:
- command: yfin screen list-predefined [--include-bodies]
tool: listPredefinedScreeners
- command: yfin screen predefined NAME [--count 25] [--offset 0] [--sort-field FIELD] [--sort-asc]
tool: screenMarket
notes: NAME is one of the 19 keys (e.g. day_gainers, undervalued_growth_stocks). Maps to `query=NAME`.
- command: yfin screen run --query QUERY [--type equity|mutualfund|etf] [--size 100] [--offset 0] [--sort-field FIELD] [--sort-asc]
tool: screenMarket
notes: '`--query` accepts a JSON string, `@file.json`, or `-` to read stdin. Wraps `screenMarket` with a QueryBase tree.'
- command: yfin screen build --type equity|mutualfund|etf --operator OP --operands JSON
tool: buildScreenerQuery
notes: Emit a serialized QueryBase tree to stdout (no Yahoo call). Useful for piping into `yfin screen run --query -`.
## live — Yahoo WebSocket streaming
- name: live
description: Stream live ticks via Yahoo WebSocket.
commands:
- command: yfin live SYMBOL [SYMBOL...] [--mode sync|async] [--url URL] [--no-verbose] [--duration N] [--format ndjson]
tool: streamLiveQuotes
notes: Long-running. `--duration N` closes the socket after N seconds. Without `--duration`, listen until Ctrl-C.
- command: yfin live subscribe SYMBOL [SYMBOL...]
tool: liveSubscribe
notes: Sends a `subscribe` frame to an existing socket — only meaningful inside a Python session, not as a one-shot CLI call. Provided for completeness; the daemon mode is a planned future addition.
- command: yfin live unsubscribe SYMBOL [SYMBOL...]
tool: liveUnsubscribe
## auth — Yahoo cookie / strategy management
- name: auth
description: Manage Yahoo crumb / cookie state.
commands:
- command: yfin auth cookies --t TOKEN --y TOKEN [--save]
tool: authSetCookies
notes: '`--save` persists the cookies to ~/.yfin/config.toml so future invocations reuse them automatically.'
- command: yfin auth strategy STRATEGY
tool: authStrategy
notes: STRATEGY is `basic` or `csrf`. Persisted to config when run with `--save`.
## config — local-state helpers
- name: config
description: Read / write the yfin config file and the in-process yf.config.
commands:
- command: yfin config get [KEY]
tool: getConfig
notes: With no KEY, dumps the full config tree as JSON (or YAML via --format yaml).
- command: yfin config set [--proxy URL] [--retries N] [--lang TAG] [--region CODE] [--hide-exceptions/--no-hide-exceptions] [--logging/--no-logging]
tool: setConfig
- command: yfin config debug-on
tool: enableDebugMode
- command: yfin config cache-dir PATH
tool: setTzCacheLocation
- command: yfin config clear-cache [--path PATH]
tool: clearTzCache
## Notes on tools that don't get a CLI command.
## ------------------------------------------------------------
unsupported:
- tool: tickersContainer
reason: Returns a live Python object. Not meaningful as a one-shot CLI call. Users should use `yfin download` / `yfin tickers history` instead, which deliver the same data without holding object state.
## Quickstart examples — copy-pasteable.
## ------------------------------------------------------------
examples:
- description: Apple last month, daily, written to Parquet.
shell: yfin ticker history AAPL --period 1mo --interval 1d --out aapl.parquet
- description: Quarterly income statement (human-labelled rows) as JSON.
shell: yfin ticker financials AAPL --statement income_stmt --freq quarterly --pretty-rows --format json
- description: Portfolio sweep — three stocks since 2024, grouped by ticker, to CSV.
shell: yfin download AAPL MSFT NVDA --start 2024-01-01 --interval 1d --group-by ticker --out portfolio.csv
- description: Top 25 day gainers right now.
shell: yfin screen predefined day_gainers --count 25
- description: Custom screen — large caps with P/E < 20, sorted by market cap.
shell: |
yfin screen run --type equity --size 50 --sort-field intradaymarketcap --query '{
"operator":"and",
"operands":[
{"operator":"gt","operands":["intradaymarketcap",1e10]},
{"operator":"lt","operands":["peratio.lasttwelvemonths",20]},
{"operator":"eq","operands":["region","us"]}
]
}'
- description: Stream Tesla + Apple live for 60 s as NDJSON.
shell: yfin live AAPL TSLA --duration 60 --format ndjson > ticks.ndjson
- description: Upcoming earnings this week, large caps only.
shell: yfin calendars earnings --start 2026-06-09 --end 2026-06-16 --market-cap 1e10
- description: Set proxy + Chinese locale, then refresh Apple's info.
shell: |
yfin config set --proxy http://127.0.0.1:7890 --lang zh-CN
yfin ticker info AAPL
## Generator hint — how to scaffold the actual Typer app from this file.
## ------------------------------------------------------------
generator:
script: scripts/gen-cli.py # planned
inputs:
- yfinance-tools.yaml # this file (tools + cli sections)
outputs:
- yfin/__main__.py # Typer root app
- yfin/commands/*.py # one module per commandGroup
- yfin/renderers.py # --format / --out plumbing
- yfin/config.py # ~/.yfin/config.toml loader
- yfin/_completion.sh # Typer-generated completions
rules:
- "Every entry in `commandGroups[].commands` becomes a Typer @app.command."
- "The `tool:` field selects the matching `tools[]` entry; its `parameters` drive Typer Option/Argument generation (enum → click.Choice, boolean → --flag/--no-flag, array → multiple)."
- "`globalOptions` are attached to the root callback so every subcommand inherits them."
- "Anything in `unsupported` is skipped silently."
- "`--format`/`--out` dispatch is centralized in `renderers.py`; commands return the raw Python value (DataFrame/dict/list) and never print directly."
## Estimated effort for each stage.
## ------------------------------------------------------------
roadmap:
- stage: MVP
scope: 10 high-traffic commands (ticker info|fast-info|history|financials, download, search, screen predefined, market summary, calendars earnings, config set)
effort: ~half a day
- stage: Full
scope: All 49 tools wired, table + json + csv + parquet renderers, Rich panels for option_chain.
effort: 2-3 days
- stage: Polish
scope: yaml-driven code generation, shell completion, ~/.yfin/config.toml, persistent auth cookies, pyproject packaging + PyPI publish.
effort: ~1 additional day
# ============================================================================
# Output schemas — what each tool actually returns (sampled live, 2026-06-08)
# ----------------------------------------------------------------------------
# Captured by running the `yfin` CLI against live Yahoo from a residential exit
# node. Each entry records: returnType (Python), structure (fields/columns),
# notes (gotchas), and a live `sample` (truncated). These supplement the
# `tools[].description` field with concrete shape information that callers
# can rely on when post-processing JSON output.
# ============================================================================
outputSchemas:
tickerFastInfo:
returnType: FastInfo (dict-like)
structure:
keys:
- {key: currency, type: string, example: "USD"}
- {key: dayHigh, type: float, example: 315.17}
- {key: dayLow, type: float, example: 307.15}
- {key: exchange, type: string, example: "NMS"}
- {key: fiftyDayAverage, type: float, example: 281.24}
- {key: lastPrice, type: float, example: 307.34}
- {key: lastVolume, type: int, example: 65246700}
- {key: marketCap, type: float, example: 4.514e12}
- {key: open, type: float}
- {key: previousClose, type: float}
- {key: quoteType, type: string, example: "EQUITY"}
- {key: regularMarketPreviousClose, type: float}
- {key: shares, type: int, example: 14687356000}
- {key: tenDayAverageVolume, type: int}
- {key: threeMonthAverageVolume, type: int}
- {key: timezone, type: string, example: "America/New_York"}
- {key: twoHundredDayAverage, type: float}
- {key: yearChange, type: float, example: 0.5256}
- {key: yearHigh, type: float}
- {key: yearLow, type: float}
notes: 20 keys total; all flat scalars. JSON output is a plain dict (not pandas split-orient).
tickerHistory:
returnType: pd.DataFrame
structure:
index: {name: Date, type: tz-aware DatetimeIndex}
columns:
- {name: Open, type: float}
- {name: High, type: float}
- {name: Low, type: float}
- {name: Close, type: float}
- {name: Volume, type: int}
- {name: Dividends, type: float, note: zero on non-event rows}
- {name: Stock Splits, type: float, note: zero on non-event rows}
- {name: Capital Gains, type: float, note: only present for fund-like symbols}
- {name: "Repaired?", type: bool, note: only present when --repair is set}
json_shape: "orient=split → {columns, index (ISO timestamps), data}"
sample_csv: |
Date,Open,High,Low,Close,Volume,Dividends,Stock Splits
2026-06-01 00:00:00-04:00,309.63,310.94,305.02,306.31,48849900,0.0,0.0
2026-06-02 00:00:00-04:00,307.46,315.45,306.69,315.20,44534700,0.0,0.0
notes: |
Index timestamps are tz-aware exchange local time. With --repair an extra
bool column 'Repaired?' is appended.
tickerActions:
returnType: pd.Series (or DataFrame when kind=actions)
structure:
Series:
index: tz-aware DatetimeIndex (event timestamps)
values: float (e.g. 0.26 dollars/share for AAPL dividends)
DataFrame (kind=actions):
columns: [Dividends, Stock Splits]
json_shape: |
Series → orient=split → {name, index, data}.
The `data` array is a flat list of floats (NOT list-of-lists).
sample: |
8 dividends in 2y for AAPL:
2024-08-12: $0.25
2024-11-08: $0.25
2025-02-10: $0.25
2025-05-12: $0.26
2025-08-11: $0.26
2025-11-10: $0.26
tickerFinancials:
returnType: pd.DataFrame
structure:
columns: ISO period-end timestamps (most recent first)
rows: 33+ line items (camelCase by default; human labels when pretty=true)
sample_columns: ["2026-03-31", "2025-12-31", "2025-09-30", "2025-06-30"]
sample_pretty_rows:
- "Tax Effect Of Unusual Items"
- "Tax Rate For Calcs"
- "Normalized EBITDA"
- "Net Income From Continuing Operation Net Minority Interest"
- "Reconciled Depreciation"
notes: |
Quarterly returns latest 4-5 periods; yearly returns latest 4-5 fiscal years.
Trailing (TTM) only valid for income_stmt and cash_flow.
tickerEarningsDates:
returnType: pd.DataFrame
structure:
index: {name: "Earnings Date", type: ISO datetime (UTC)}
columns:
- {name: "EPS Estimate", type: float, nullable: true}
- {name: "Reported EPS", type: float, nullable: true, note: null for upcoming dates}
- {name: "Surprise(%)", type: float, nullable: true, note: null for upcoming dates}
sample:
- {date: "2026-07-29T20:00:00Z", estimate: 4.24, reported: null, surprise: null}
- {date: "2026-04-29T20:00:00Z", estimate: 4.06, reported: 4.27, surprise: 5.22}
- {date: "2026-01-28T21:00:00Z", estimate: 3.92, reported: 4.14, surprise: 5.69}
notes: First row(s) are future estimates; surprise is null until reported.
tickerAnalystEstimates:
returnType: varies by --kind
variants:
analyst_price_targets:
type: dict
sample: {current: 307.34, high: 400.0, low: 215.0, mean: 310.507, median: 310.0}
recommendations:
type: pd.DataFrame
columns: [period, strongBuy, buy, hold, sell, strongSell]
sample_row: ["0m", 7, 23, 15, 1, 2]
earnings_estimate:
type: pd.DataFrame
columns: [numberOfAnalysts, avg, low, high, yearAgoEps, growth]
index: ["0q", "+1q", "0y", "+1y"]
eps_trend:
type: pd.DataFrame
columns: [current, "7daysAgo", "30daysAgo", "60daysAgo", "90daysAgo"]
growth_estimates:
type: pd.DataFrame
columns: [stockTrend, indexTrend]
tickerHolders:
returnType: pd.DataFrame
variants:
institutional_holders:
columns: ["Date Reported", Holder, pctHeld, Shares, Value, pctChange]
sample_row:
- "2026-03-31"
- "Blackrock Inc."
- 0.0779
- 1144695425
- 351810687727
- -0.0086
major_holders:
columns: [Value]
index: [insidersPercentHeld, institutionsPercentHeld, institutionsFloatPercentHeld, institutionsCount]
insider_transactions:
columns: [Insider, Position, "Transaction Type", Shares, Value, "URL", "Start Date", "Ownership"]
tickerCalendar:
returnType: dict
structure:
Dividend Date: ISO date (string)
Ex-Dividend Date: ISO date (string)
Earnings Date: list[ISO date]
Earnings High: float
Earnings Low: float
Earnings Average: float
Revenue High: int
Revenue Low: int
Revenue Average: int
sample:
Dividend Date: "2026-05-14"
Ex-Dividend Date: "2026-05-11"
Earnings Date: ["2026-07-31"]
Earnings High: 1.99
Earnings Low: 1.83
Earnings Average: 1.89541
tickerNews:
returnType: list[dict]
structure:
item:
id: string (uuid)
content:
id: string
contentType: 'STORY | PRESS_RELEASE | ...'
title: string
summary: string
pubDate: ISO datetime
provider: {displayName: string, url: string}
thumbnail: {originalUrl, resolutions: list}
canonicalUrl: {url, lang, region}
clickThroughUrl: {url}
sample:
- title: "Apple WWDC preview: Apple gets a second shot at its AI rollout"
provider: "Yahoo Finance"
- title: "Broadcom, AMD, Super Micro, and More Stocks That Explain Today's Market"
provider: "Barrons.com"
tickerSecFilings:
returnType: list[dict]
structure:
item:
date: ISO date
type: '10-K | 10-Q | 8-K | SD | DEF 14A | ...'
title: string (human description)
edgarUrl: string
exhibits: list[dict]
sample:
- {date: "2026-05-28", type: "SD", title: "Specialized Disclosure Report..."}
- {date: "2026-05-01", type: "10-Q", title: "Periodic Financial Reports"}
- {date: "2026-04-30", type: "8-K", title: "Corporate Changes & Voting Matters"}
notes: ~77 filings returned for AAPL (full Yahoo-tracked history).
tickerIsin:
returnType: dict
structure:
symbol: string
isin: string # "-" if unresolvable (e.g. crypto, indices)
sample: {symbol: "AAPL", isin: "US0378331005"}
tickerShares:
returnType: pd.DataFrame
status: UPSTREAM_UNIMPLEMENTED
notes: |
Raises `YFNotImplementedError('shares')` as of yfinance 1.4.1.
Use `tickerSharesFull` for the daily shares-outstanding series.
tickerSharesFull:
returnType: pd.Series
structure:
index: tz-aware DatetimeIndex (daily)
values: int (shares outstanding)
sample:
- ["2024-12-27T05:00:00Z", 15115799552]
- ["2024-12-28T05:00:00Z", 15115799552]
- ["2025-01-04T05:00:00Z", 15115799552]
notes: Default window = last 548 days (~18 months). ~80 datapoints in default window.
tickerOptionExpirations:
returnType: list[string]
structure: ISO dates ("YYYY-MM-DD"), ascending.
sample: ["2026-06-08", "2026-06-10", "2026-06-12", "2026-06-15", "2026-06-17"]
tickerOptionChain:
returnType: NamedTuple(calls, puts, underlying)
structure:
calls: pd.DataFrame
puts: pd.DataFrame
underlying: dict (quote snapshot)
DataFrame_columns:
- contractSymbol
- lastTradeDate (datetime)
- strike (float)
- lastPrice (float)
- bid (float)
- ask (float)
- change (float)
- percentChange (float)
- volume (int)
- openInterest (int)
- impliedVolatility (float)
- inTheMoney (bool)
- contractSize (string, "REGULAR")
- currency (string)
notes: |
JSON serialization wraps the NamedTuple as a dict {calls, puts, underlying}.
Table render emits three Rich panels (calls / puts / underlying).
downloadHistory:
returnType: pd.DataFrame (MultiIndex columns)
structure:
group_by=column (default):
columns: MultiIndex(level0=field, level1=symbol)
levels:
- level0: [Open, High, Low, Close, Volume, Dividends, Stock Splits]
- level1: list of symbols
group_by=ticker:
columns: MultiIndex(level0=symbol, level1=field)
sample_json_columns: |
[["Close", "AAPL"], ["Close", "MSFT"], ["Close", "NVDA"],
["Dividends", "AAPL"], ["Dividends", "MSFT"], ["Dividends", "NVDA"], ...]
sample_csv_header: |
Price,Close,Close,High,High,Low,Low,Open,Open,Volume,Volume
Ticker,AAPL,MSFT,AAPL,MSFT,AAPL,MSFT,AAPL,MSFT,AAPL,MSFT
Date,,,,,,,,,,
notes: |
For 5-day × 3-symbol AAPL/MSFT/NVDA: 5 rows × 15 cols (5 fields × 3 symbols).
Parquet write is round-trippable via pandas.read_parquet.
searchTickers:
returnType: dict (Search.all)
structure:
quotes: list[dict]
news: list[dict]
lists: list[dict]
research: list[dict]
nav: list[dict]
quote_item:
symbol: string
shortname: string
longname: string
exchange: string (e.g. "NMS", "NYQ", "GER")
exchDisp: string (e.g. "NASDAQ", "NYSE")
quoteType: 'EQUITY | ETF | INDEX | ...'
typeDisp: string
sector: string
sectorDisp: string
industry: string
industryDisp: string
score: float
isYahooFinance: bool
sample_top_hit:
symbol: AAPL
shortname: "Apple Inc."
exchange: NMS
sector: Technology
industry: Consumer Electronics
score: 23212.0
lookupTickers:
returnType: pd.DataFrame
structure:
index: symbol (string)
columns: [exchange, sectorLink, sector, quoteType, score, regularMarketChange, regularMarketChangePercent, regularMarketPrice, shortName]
sample_top_hit:
symbol: AAPL
data: [NMS, "https://finance.yahoo.com/sector/technology", Technology, equity, 23212, -3.89, -1.2499, 307.34, "Apple Inc."]
marketSummary:
returnType: dict (keyed by exchange code)
structure:
key: exchange code (e.g. CME, CBT, CXI, CMX)
value:
shortName: string (e.g. "Russell 2000 Futures", "VIX", "Gold")
regularMarketPrice: float
regularMarketChange: float
regularMarketChangePercent: float
exchange: string
exchangeTimezoneName: string
marketState: string
sample:
CME: {shortName: "Russell 2000 Futures", regularMarketPrice: 2874.7, regularMarketChangePercent: 1.4075}
CBT: {shortName: "Dow Futures", regularMarketPrice: 51099.0, regularMarketChangePercent: 0.32}
CXI: {shortName: VIX, regularMarketPrice: 18.99, regularMarketChangePercent: -11.72}
CMX: {shortName: Gold, regularMarketPrice: 4355.7, regularMarketChangePercent: -0.22}
notes: |
US region returned 4 entries (futures + VIX + gold) at sampling time.
regularMarketPrice is a flat float (NOT a {raw, fmt, longFmt} dict — old assumption).
marketStatus:
returnType: dict
structure:
id: string ("us")
name: string ("U.S. markets")
status: 'open | closed | premarket | postmarket'
yfit_market_id: string
close: ISO datetime (UTC)
open: ISO datetime (UTC)
duration: list[{hrs, mins}]
message: human string
tz: timezone object (when present)
sample:
id: us
name: U.S. markets
status: closed
open: "2026-06-08T13:30:00+00:00"
close: "2026-06-08T20:00:00+00:00"
message: "U.S. markets open in 1 hour 42 minutes"
notes: |
Yahoo silently returns US data for non-US regions; the scraper logs a
warning and yields null in that case.
sectorInfo:
returnType: dict (when --attribute omitted) or scalar (when set)
full_dict_keys: [key, name, symbol, overview, top_companies, top_etfs, top_mutual_funds, industries, research_reports]
sub_shapes:
overview: dict (market_weight, market_cap, message_board_id, employee_count, sector_key, parent_name, parent_key, description)
top_companies:
type: pd.DataFrame
index: symbol
columns: [name, rating, "market weight"]
sample_top:
NVDA: ["NVIDIA Corporation", "Strong Buy", 0.491]
AAPL: ["Apple Inc.", "Strong Buy", ...]
MSFT: ["Microsoft Corporation", "Strong Buy", ...]
top_etfs:
type: dict
sample: {SMH: "VanEck Semiconductor ETF", XLK: "Technology Select Sector SPDR Fund"}
top_mutual_funds:
type: dict
industries:
type: pd.DataFrame
index: industry slug
columns: [name, symbol, "market weight"]
sample_top:
semiconductors: ["Semiconductors", "^YH31130020", 0.388]
software-infrastructure: ["Software - Infrastructure", "^YH31110030", 0.197]
industryInfo:
returnType: dict (when --attribute omitted)
full_dict_keys: [key, name, symbol, sector_key, sector_name, overview, top_companies, top_performing_companies, top_growth_companies, research_reports]
sub_shapes:
top_companies:
type: pd.DataFrame
index: symbol
columns: [name, rating, "market weight"]
sample_top_for_semiconductors:
NVDA: ["NVIDIA Corporation", "Strong Buy", 0.49185]
AVGO: ["Broadcom Inc.", "Strong Buy", 0.17970]
MU: ["Micron Technology, Inc.", "Strong Buy", 0.07497]
top_performing_companies:
type: pd.DataFrame
columns: [name, "ytd return", "last price", "target price"]
top_growth_companies:
type: pd.DataFrame
columns: [name, "ytd return", "growth estimate"]
getEarningsCalendar:
returnType: pd.DataFrame
structure:
index: row number (0-based)
columns: [Symbol, Company, "Event Name", Timing, EPS Estimate, Reported EPS, "Surprise(%)", Marketcap, "Event Start Date"]
sample:
- {Symbol: ORCL, Company: "Oracle Corporation", "Event Name": "Q4 2026 Earnings Announcement", Timing: AMC, "EPS Estimate": 1.96, Marketcap: 5.41e11}
- {Symbol: UEC, Company: "Uranium Energy Corp.", "Event Name": "Q3 2026 Earnings Announcement", Timing: BMO, "EPS Estimate": -0.01, Marketcap: 6.25e9}
notes: Sorted by Event Start Date descending.
screenMarket:
returnType: dict (Yahoo "finance.result[0]")
structure:
id: string
title: string
description: string
canonicalName: string
criteriaMeta: dict
rawCriteria: string
start: int
count: int
total: int (total matches, can exceed `count`)
useRecords: bool
quotes: list[dict]
quote_item:
symbol: string
shortName: string
regularMarketPrice: float
regularMarketChangePercent: float
regularMarketChange: float
marketCap: float
ellipsis: '... (~60 fields total)'
sample_predefined_day_gainers:
total: 74
top_5:
- {symbol: COO, shortName: "The Cooper Companies, Inc.", regularMarketPrice: 67.34, regularMarketChangePercent: 8.578}
- {symbol: ABM, shortName: "ABM Industries Incorporated", regularMarketPrice: 42.54, regularMarketChangePercent: 6.670}
- {symbol: ARCB, shortName: "ArcBest Corporation", regularMarketPrice: 155.09, regularMarketChangePercent: 6.168}
listPredefinedScreeners:
returnType: list[string]
count: 19
members:
- aggressive_small_caps
- bond_etfs
- conservative_foreign_funds
- day_gainers
- day_losers
- growth_technology_stocks
- high_yield_bond
- most_actives
- most_shorted_stocks
- portfolio_anchors
- small_cap_gainers
- solid_large_growth_funds
- solid_midcap_growth_funds
- technology_etfs
- top_etfs_us
- top_mutual_funds
- top_performing_etfs
- undervalued_growth_stocks
- undervalued_large_caps
buildScreenerQuery:
returnType: dict
structure:
type: 'equity | mutualfund | etf'
query:
operator: 'AND | OR | EQ | GT | LT | GTE | LTE | BTWN | IS-IN'
operands: list (nested queries or [field, value])
sample:
type: equity
query:
operator: AND
operands:
- {operator: GT, operands: ["intradaymarketcap", 10000000000.0]}
- {operator: EQ, operands: ["region", "us"]}
streamLiveQuotes:
returnType: stream of dict (one per protobuf message)
structure:
id: symbol
price: float
time: int (ms epoch)
exchange: string
quoteType: int (Yahoo enum)
marketHours: int
changePercent: float
dayVolume: int
change: float
lastSize: int
priceHint: int
notes: Decoded from yfinance/pricing.proto. CLI writes one JSON object per line to stdout (or --out).
# ============================================================================
# Learnings — captured during yfin CLI implementation (2026-06-08)
# ----------------------------------------------------------------------------
# Things that bit us, things that turned out NOT to be true, things to
# remember when extending or regenerating the CLI. Each entry has:
# topic — short slug
# summary — one-line takeaway
# detail — the full story
# appliesTo — what this affects
# ============================================================================
learnings:
- topic: rate-limit-is-ip-not-cli
summary: Yahoo's 403/429 on query1/query2 is an IP-level block, not a CLI/yfinance bug.
detail: |
During testing both AWS Singapore (52.221.x) and macOS Tailscale exit
nodes returned HTTP 429 to every query1/query2 API path even from raw
curl with a browser User-Agent. The same IP got HTTP 200 on the
finance.yahoo.com html site. Conclusion: Yahoo Finance API gates by IP
reputation, separately from the consumer site. Residential / mobile IPs
almost always work; datacenter IPs almost always don't. yfinance's
cookie+crumb dance does NOT bypass this — it's an L7 IP block.
appliesTo: All openWorldHint=true tools.
remediation: |
Surface YFRateLimitError as a friendly stderr message + exit code 2
(not a Rich traceback). Recommend --proxy URL or switching exit nodes.
- topic: crumb-handshake-works-when-ip-isnt-blocked
summary: yfinance's basic-strategy crumb handshake transparently fixes 429 when the IP is OK.
detail: |
Once we switched to a residential exit node, the very first
`yfin ticker fast-info MSFT` call triggered _get_crumb_basic() → got
cookie + crumb → response code=200 → returned full FastInfo dict.
We did NOT need authSetCookies / authStrategy / any retry logic.
The basic strategy is sufficient unless you hit a EU consent wall.
appliesTo: authStrategy, authSetCookies
remediation: |
Don't ship retry logic; let yfinance handle the handshake. Surface
auth errors only when basic→csrf fallback also fails.
- topic: lxml-and-scipy-are-not-truly-optional
summary: yfinance documents `lxml/html5lib/scipy/requests_cache/requests_ratelimiter` as optional but several core tools NEED them.
detail: |
- tickerEarningsDates raises ImportError("Import lxml failed") because
the scraper uses pandas.read_html under the hood.
- tickerHistory with --repair raises ImportError unless scipy is present.
- The `nospam` extras (requests_cache/requests_ratelimiter) are needed
if users want their own caching session (we document that in CLI).
appliesTo: tickerEarningsDates, tickerHistory (--repair), nospam users
remediation: |
The yfin pyproject.toml lists lxml, html5lib, scipy, requests_cache,
requests_ratelimiter as direct deps so `uv tool install` always works.
- topic: typer-callback-vs-subcommand-conflict
summary: invoke_without_command=True swallows the positional that would otherwise route to a subcommand.
detail: |
Initial design had `yfin sector KEY [--attribute X]` as a callback AND
`yfin sector list` as a subcommand. Running `yfin sector list` ran the
callback with key="list" (NOT the list subcommand) and queried Yahoo
for sector "list". Same trap hit search/lookup/live.
appliesTo: sector, search, lookup, live
remediation: |
Drop invoke_without_command=True. Make the default action an explicit
subcommand: `yfin sector info KEY`, `yfin search run QUERY`,
`yfin lookup run QUERY`, `yfin live stream SYMBOL ...`.
- topic: screen-build-needs-recursive-wrapping
summary: EquityQuery/FundQuery/ETFQuery 'and'/'or' operators require nested QueryBase instances, not raw dicts.
detail: |
_validate_or_and_operand() in yfinance/screener/query.py enforces
`all(isinstance(e, QueryBase) for e in operand)`. Passing raw dicts
raises TypeError. The CLI's `screen build` must recurse to wrap each
operand in the same query class before constructing the parent.
appliesTo: buildScreenerQuery
remediation: |
In yfin/commands/screen.py::build, recurse via _build_query() and
only fall through to raw operands for leaf value operators
(eq/gt/lt/gte/lte/btwn/is-in).
- topic: market-summary-field-shape-changed
summary: regularMarketPrice in marketSummary is a flat float, NOT a {raw, fmt, longFmt} dict.
detail: |
Old yfinance behavior wrapped numeric fields in {raw, fmt, longFmt}.
Current Yahoo response returns flat floats. Anything that tries
`v.get('regularMarketPrice', {}).get('raw')` will crash with
AttributeError: 'float' object has no attribute 'get'.
appliesTo: marketSummary, screenMarket (some fields)
remediation: |
Treat numeric quote fields as raw floats. Defensive: check isinstance(v, dict).
- topic: actions-series-not-list-of-lists
summary: ticker actions --kind dividends returns a Series, whose JSON `data` is a flat list of floats.
detail: |
Initial test assumed `data[i][0]` (list-of-lists). pandas Series
orient=split produces `{name, index, data}` where data is 1-D.
DataFrame orient=split produces 2-D `data`. Type matters.
appliesTo: tickerActions (dividends/splits/capital_gains), tickerSharesFull
remediation: |
Renderer dispatch in yfin/renderers.py already distinguishes
DataFrame vs Series. Downstream consumers must match.
- topic: ticker-shares-is-not-implemented
summary: yfinance 1.4.1 stubs `Ticker.get_shares()` — raises YFNotImplementedError.
detail: |
`yfin ticker shares AAPL` raises YFNotImplementedError('shares') from
yfinance/scrapers/fundamentals.py. Documented in yfinance/scrapers/
fundamentals.py:39 — the property is a placeholder for a yet-to-be
written scraper.
appliesTo: tickerShares
remediation: |
Use `tickerSharesFull` instead. CLI surfaces the upstream error as-is;
don't mask it.
- topic: ticker-options-empty-on-non-options-symbols
summary: tickerOptionExpirations returns [] for crypto, FX, indices.
detail: |
Yahoo's options endpoint returns {} for symbols without listed options.
The CLI's Tuple/list serializer handles empty correctly; downstream
code should expect a possibly-empty list.
appliesTo: tickerOptionExpirations, tickerOptionChain
- topic: typer-period-enum-strictness
summary: --period only accepts the 11 Yahoo periods. "3d" / "7d" / numeric strings get rejected at CLI level.
detail: |
First test sweep tried `--period 3d` and got
`Invalid value for '--period': '3d' is not one of '1d', '5d', '1mo',
'3mo', '6mo', '1y', '2y', '5y', '10y', 'ytd', 'max'.` from Typer.
This is correct behavior — `5d` is the smallest > 1d period.
appliesTo: tickerHistory, downloadHistory, tickersHistory, tickerActions
remediation: |
For arbitrary day counts, pass --start/--end instead of --period.
Documented in `globalOptions` notes and per-command help text.
- topic: requires-python-must-be-3.10-not-3.9
summary: yfinance 1.4.1 transitively requires curl_cffi>=0.15, which dropped Python 3.9.
detail: |
uv sync failed with: "Because curl-cffi==0.15.0 depends on Python>=3.10
and yfinance==1.4.1 depends on curl-cffi>=0.15, … your project's
requirements are unsatisfiable." Even though setup.py for yfinance
lists 3.6+, the actual runtime floor is 3.10.
appliesTo: yfin/pyproject.toml requires-python
remediation: |
Pin `requires-python = ">=3.10"` in yfin/pyproject.toml.
- topic: console-script-needs-wrapper-for-error-shaping
summary: Typer's `app` callable can't catch its own SystemExit cleanly. Use a wrapper main().
detail: |
Putting `try: app() except YFRateLimitError` directly under
`if __name__ == "__main__":` only fires when run via `python -m yfin`.
When uv installs the console script (`yfin = yfin.__main__:app`),
the script imports `app` and calls it directly — bypassing the guard.
appliesTo: yfin/__main__.py
remediation: |
Export `main()` that wraps `app()` in try/except, and change the
entry point to `yfin = "yfin.__main__:main"`.
- topic: pretty-rows-vs-global-pretty
summary: Two `--pretty` flags would collide; use `--pretty-rows` for the per-financials flag.
detail: |
The global `--pretty` flag controls JSON/YAML formatting. The
yfinance `pretty=` kwarg on get_income_stmt translates row labels.
Both are useful and orthogonal. Naming them differently avoids
ambiguity.
appliesTo: tickerFinancials (CLI)
remediation: |
CLI exposes `--pretty-rows` (maps to yfinance pretty=true), keeps
global `--pretty` for JSON formatting.
- topic: global-flags-must-come-before-subcommand
summary: Typer parses global options on the root callback ONLY before the subcommand name.
detail: |
`yfin ticker fast-info AAPL --format json` → fails with
"No such option: --format" because Typer attaches --format to the
root app, not the leaf command. Correct: `yfin --format json ticker
fast-info AAPL`.
appliesTo: All globalOptions
remediation: |
Document the ordering in README + --help. Could be relaxed by
duplicating global flags onto every subcommand, but that bloats help.
- topic: search-needs-class-instantiation-side-effect
summary: yf.Search runs the HTTP call inside __init__, so the CLI cannot lazy-build a "Search builder".
detail: |
The Search class fetches data eagerly when constructed. There is no
`.execute()` step. Implication: every flag that affects the query
(max_results, news_count, fuzzy, etc.) must be passed as constructor
args. Mirrored 1:1 in `yfin search run`.
appliesTo: searchTickers
- topic: tickers-history-multi-index-csv-is-pivoted-twice
summary: download() returns a DataFrame with MultiIndex columns; to_csv writes a 3-row header.
detail: |
The CSV header is: Price,Close,Close,High,High,…
then Ticker,AAPL,MSFT,AAPL,MSFT,…
then Date,,,,
Tools that consume the CSV must skip those 3 header rows or use
`pd.read_csv(..., header=[0,1])` and index_col=0.
appliesTo: downloadHistory, tickersHistory
remediation: |
For naive downstream consumers, set `--group-by ticker` and write to
Parquet for round-trippable round-trips (pyarrow preserves the
MultiIndex).
- topic: residential-ip-rate-limit-tldr
summary: 17/17 live tests passed once on a residential IP exit; flaky on first attempt because of Yahoo cold-start.
detail: |
Pattern observed: first request after switching exit nodes may still
return 429 (Yahoo's edge cache hasn't propagated the new IP's rep
score). Wait ~10s and retry; subsequent requests reliably succeed.
appliesTo: any first-request-after-IP-change scenario
remediation: |
`yfin --retries N` is already plumbed through to yf.config.network.retries.
Could add an automatic --retry-on-429 flag with exponential backoff.
- topic: tickers-history-progress-corrupts-stdout
summary: download()'s progress bar writes to stdout; mixed with JSON output it breaks json.load().
detail: |
Initial tests failed JSON parse because the progress bar bytes
preceded the JSON body. Adding --no-progress fixes it. Quiet mode
(`-q`) auto-disables progress.
appliesTo: downloadHistory, tickersHistory
remediation: |
In yfin/_shared.py, force progress=False when stdout is a pipe (auto).
User can re-enable with `--progress`.
- topic: cli-binary-stats
summary: Final yfin implementation = 1857 LOC across 18 Python files; 51 subcommands wrapping 49 tools.
detail: |
Tally as of 2026-06-08:
ticker.py 371 LOC, 22 commands
renderers.py 321 LOC
__main__.py 166 LOC
screen.py 132 LOC
live.py 105 LOC
config.py(cmd) 105 LOC
config.py(mod) 98 LOC
calendars.py 85 LOC
sector.py 71 LOC
download.py 70 LOC
_shared.py 66 LOC
tickers.py 53 LOC
industry.py 50 LOC
auth.py 48 LOC
search.py 44 LOC
market.py 36 LOC
lookup.py 32 LOC
Global install: ~/.local/share/uv/tools/yfin/, symlinked to ~/.local/bin/yfin.