yfinance
yfinance is a Python client for market and company data exposed by Yahoo Finance. It returns pandas objects for price history, corporate actions, financial statements, holders, analyst estimates, options, funds, sectors, industries, news, and more, with Ticker for one symbol, Tickers or download for batches, and synchronous or asynchronous WebSocket classes for live prices. It needs no API key because it uses Yahoo's public-facing endpoints. That convenience is also the central risk: the project is neither affiliated with nor vetted by Yahoo, and the README says the data is intended for research, education, and personal use.
yfinance is hard to beat for notebooks and low-stakes research because its breadth arrives with no credential ceremony. Do not make it an unverified production market-data feed or assume that free access grants commercial usage rights.
Use it if
- You need quick exploratory price history in pandas without creating an API account
- You want dividends, splits, options, statements, holders, or analyst data behind one Ticker object
- You need to prototype research across several symbols with threaded batch downloads
- You can cache results, tolerate upstream changes, and verify important values elsewhere
- You are building a commercial redistribution or customer-facing data product: the README says Yahoo data is intended for personal use and points readers to Yahoo's terms
- You need an official SLA, stable schema, or support contract: yfinance is not affiliated with, endorsed by, or vetted by Yahoo
- You need deep intraday history: the download reference says intraday data cannot extend beyond the last 60 days
- You want a light dependency: 1.5.2 declares pandas, NumPy, requests, peewee, Beautiful Soup, curl_cffi, protobuf, websockets, and several support packages
- You will trade or report from unverified results: repair is optional, adjustments default on, and undocumented upstream changes can alter or remove fields
Setup reality
pip install yfinance currently brings a broad data-and-network stack: pandas, NumPy, requests, multitasking, platformdirs, pytz, peewee, Beautiful Soup, curl_cffi, protobuf, and websockets. There is no API key setup, but that is not the same as a supported API. Yahoo can throttle, change cookies or crumbs, rename JSON fields, return partial tables, or block an address, and community releases must catch up. Version 1.5.2 uses curl_cffi by default; the docs provide a separate install path for requests fallback when curl_cffi is unsuitable. yfinance stores timezone and cookie data in a local cache, normally under the user's cache directory on Linux. Containers, read-only homes, and serverless functions should call set_tz_cache_location with a writable persistent path before requests. Price defaults are easy to misread. download uses period='1mo' when no dates are supplied, auto_adjust=True, progress=True, threads=True, actions=False, and multi_level_index=True. start is inclusive while end is exclusive. Intraday intervals are restricted to the latest 60 days, and combining exchanges can produce timezone differences; ignore_tz defaults differently for intraday and daily data. Batch output commonly has MultiIndex columns, so do not write code that assumes Close is a flat column without fixing group_by and multi_level_index. Ticker.info is comprehensive but can be slow and brittle; fast_info is the narrower price-oriented path. repair=True attempts to detect 100x currency-unit errors, which is useful but changes data rather than merely fetching it. Cache raw responses or normalized datasets with retrieval time, package version, symbol, interval, adjustment flags, and timezone. Add retries with backoff at the job layer, avoid large concurrent scraping bursts, and cross-check prices, splits, and statements before financial decisions. The README's personal-use warning and Yahoo terms should be reviewed by whoever owns legal and data licensing.
Patterns
Download adjusted daily historydownload-history
import yfinance as yf
prices = yf.download(
'AAPL',
period='1y',
interval='1d',
auto_adjust=True,
progress=False,
multi_level_index=False,
)
print(prices.tail())auto_adjust defaults to True in the current reference. Set it explicitly so later default changes cannot silently alter OHLC values.
Fetch an explicit date rangedownload-date-range
import yfinance as yf
prices = yf.download(
'MSFT',
start='2025-01-01',
end='2026-01-01',
actions=True,
progress=False,
)start is inclusive and end is exclusive. The final possible observation is the session before the end date.
Batch several symbolsdownload-multiple-tickers
import yfinance as yf
panel = yf.download(
['AAPL', 'MSFT', 'NVDA'],
period='6mo',
group_by='ticker',
threads=4,
progress=False,
)
aapl_close = panel['AAPL']['Close']Batch output normally uses MultiIndex columns. Inspect panel.columns before selecting data, especially when changing group_by.
Fetch recent intraday barsfetch-intraday
import yfinance as yf
bars = yf.download(
'SPY',
period='5d',
interval='5m',
prepost=False,
progress=False,
)The reference limits intraday history to the latest 60 days. Timezone handling also differs from daily downloads.
Read one ticker with actionsuse-ticker-history
import yfinance as yf
apple = yf.Ticker('AAPL')
history = apple.history(period='1y', actions=True, auto_adjust=False)
print(history[['Close', 'Dividends', 'Stock Splits']])With auto_adjust=False, Close is not automatically adjusted. Record the flag whenever persisting or comparing price series.
Read the narrower fast quote fieldsread-fast-quote-info
import yfinance as yf
quote = yf.Ticker('AAPL').fast_info
print(quote['last_price'], quote['market_cap'])fast_info is narrower than info and is preferable when you only need common price-oriented fields. Keys can still depend on Yahoo.
Fetch broad company metadataread-company-info
ticker = yf.Ticker('MSFT')
info = ticker.get_info()
name = info.get('longName')
sector = info.get('sector')Use .get for optional fields. Yahoo can omit or rename keys, and broad info calls are more failure-prone than price history.
Retrieve income statementsread-financial-statements
ticker = yf.Ticker('MSFT')
annual = ticker.get_income_stmt(freq='yearly')
quarterly = ticker.get_income_stmt(freq='quarterly')Statement labels and availability vary by company and upstream response. Preserve source timestamps and validate units before analysis.
Inspect an option expirationread-option-chain
ticker = yf.Ticker('AAPL')
expirations = ticker.options
if expirations:
chain = ticker.option_chain(expirations[0])
calls = chain.calls
puts = chain.putsExpiration lists can be empty or change between calls. Option quotes may be delayed or incomplete and should not drive execution without verification.
Request currency-unit repairrepair-price-anomalies
prices = yf.download(
'VOD.L',
period='5y',
repair=True,
progress=False,
)repair attempts to detect 100x unit mixups. It modifies returned data, so compare and log repaired results instead of enabling it invisibly.
Move cache files to writable storageconfigure-cache
import yfinance as yf
yf.set_tz_cache_location('/var/tmp/my-app-yfinance-cache')
prices = yf.download('AAPL', period='1mo', progress=False)Call this before fetching. Ensure the directory is writable and persistent enough for your container or serverless runtime.
Alternatives
| Package | Registry | Pick it when |
|---|---|---|
| yahooquery | PyPI | You want another unofficial Yahoo client with an API shaped around batch quote-summary requests |
| pandas-datareader | PyPI | You want a pandas interface across several documented public data sources rather than Yahoo-only coverage |
| alpha-vantage | PyPI | You prefer a vendor API key and published service limits for prices, fundamentals, forex, or technical indicators |