057bc4493e
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>
2633 lines
100 KiB
YAML
2633 lines
100 KiB
YAML
---
|
||
# 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.
|