Guides

Migrating from yfinance to FinzData

FinzData provides a drop-in replacement for yfinance with the same Ticker().history() and download() interface. By changing only the import statement to import finzdata as yf, you gain access to delisted stock history, documented price adjustments, and additional datasets like COT reports and SEC fundamentals—all while keeping your existing code structure intact.

Updated 2026-10-11. Code on this page was run against live FinzData data before publishing.

Installation and Setup

Install the FinzData Python client using pip install finzdata. The package provides the same API structure as yfinance, allowing you to replace the import line directly.

Set your API key as an environment variable named FINZDATA_API_KEY. You can obtain a free key at api.finzdata.com. The client reads this variable automatically; never hardcode the key in your script.

After setup, the free tier provides the last 12 months of daily US stock bars, full COT history, SEC fundamentals as reported, latest values of 158 macro series, and 13F ownership for the latest quarter—subject to a daily limit of 1,000 API calls.

import finzdata as yf
# No API key in code; reads from FINZDATA_API_KEY environment variable

Core Functionality: Ticker and Download

The Ticker().history() method works identically to yfinance for supported periods and intervals. Use the same parameters: period options are '1mo', '1y', '5y', or 'max'; interval options are '1d', '1h', '5m', or '1m'.

The download() method also mirrors yfinance, accepting a list of tickers and returning a multi-level column DataFrame with fields like Open, High, Low, Close, Volume for each symbol.

Under the free plan, history() is limited to the last 12 months of daily data. For intraday data (1-minute, 5-minute, or hourly) or history beyond 12 months, a look-back bundle or Institutional plan is required.

import finzdata as yf
# Daily history for the last 12 months (free)
data = yf.Ticker('AAPL').history(period='1y')
# Intraday hourly data requires a look-back bundle
hourly = yf.Ticker('AAPL').history(period='5d', interval='1h')
# Multi-ticker download (free for last 12 months)
multi = yf.download(['SPY', 'QQQ'], period='1y')

Accessing Delisted Stocks

FinzData includes daily bars for delisted NYSE and Nasdaq stocks since January 2000, identified by the '-DELISTED' suffix (e.g., 'LEHMQ-DELISTED' for Lehman Brothers).

These symbols are not available in yfinance, which typically removes delisted names from its dataset. With FinzData, you can retrieve full historical data for delisted stocks using the same Ticker().history() method.

Access to delisted stock history requires a look-back bundle or Institutional plan, as it falls outside the free 12-month window.

import finzdata as yf
# Delisted stock history requires a look-back bundle
lehm = yf.Ticker('LEHMQ-DELISTED').history(period='max')
print(f'Lehman Brothers daily bars: {len(lehm)}')  # ~3,062 bars from 2000-2012

Price Adjustments: Transparent and Documented

FinzData provides explicit control over price adjustments through the adjust parameter: c.prices() accepts 'none' (unadjusted), 'splits' (split-adjusted only) or 'all' (split- and dividend-adjusted), and c.minutes() accepts 'none' or 'all'.

This contrasts with yfinance, where auto_adjust=True applies split- and dividend-adjusted prices by default, with less transparency about the adjustment logic.

The Ticker().history() method in FinzData uses auto_adjust=True by default, matching yfinance behavior, but you can bypass it by using the lower-level client methods when precise control is needed.

import finzdata as yf
c = yf.Client()
# Split- and dividend-adjusted daily bars (equivalent to auto_adjust=True)
adj_all = c.prices('AAPL', start='2025-01-01', adjust='all')
# Split-adjusted only
adj_splits = c.prices('AAPL', start='2025-01-01', adjust='splits')
# Unadjusted prices
unadj = c.prices('AAPL', start='2025-01-01', adjust='none')

When to Keep Using yfinance

yfinance remains a suitable choice if you only need the last 12 months of daily data for active US stocks, do not require delisted history, and prefer a completely free, open-source tool with no registration.

It is also useful for quick prototyping or educational purposes where API keys and environment variables add unnecessary complexity.

However, if your workflow benefits from consistent access to adjusted prices, delisted names, or alternative datasets like COT reports or SEC fundamentals, FinzData offers a more robust and transparent foundation.

# No code change needed if staying with yfinance
# import yfinance as yf  # Uncomment to use yfinance instead

Beyond Price Data: Additional Datasets

FinzData provides access to datasets not available in yfinance, including CFTC Commitments of Traders (COT) reports, SEC XBRL fundamentals, US macro series with vintage data, liquidity indicators, and 13F institutional holdings.

These can be accessed through the FinzData Client (c = yf.Client()) using methods like c.cot(), c.fundamentals(), c.macro(), c.liquidity(), and c.institutional_ownership().

While some of these datasets are available on the free plan (e.g., full COT history, latest macro values, latest 13F ownership), others—such as point-in-time fundamentals, macro vintages, and 13F history—require a look-back bundle or Institutional plan.

import finzdata as yf
c = yf.Client()
# COT report for gold futures (free)
gold_cot = c.cot(report='legacy_fo', code='088691', start='2020-01-01')
# SEC fundamentals as reported (free)
aapl_rev = c.fundamentals(ticker='AAPL', concept='Revenues')
# Latest CPI value (free)
cpi = c.macro('CPIAUCSL', start='2024-01-01')
# 13F ownership for latest quarter (free)
holdings = c.institutional_ownership(ticker='AAPL')

Questions

Do I need to change my existing yfinance code beyond the import statement?

No, Ticker().history() and download() take the same common arguments (period, interval, start, end) and return the same column layout. Only the import line changes from import yfinance as yf to import finzdata as yf. All other code remains unchanged for basic usage.

Is delisted stock data available on the free plan?

No, accessing delisted stock history requires a look-back bundle or Institutional plan, as it extends beyond the 12-month free window. The free plan covers only the last 12 months of daily data for active stocks.

How do FinzData's price adjustments compare to yfinance's?

FinzData mirrors yfinance's default behavior (auto_adjust=True in Ticker().history()) but provides transparent, explicit control via the adjust parameter in lower-level methods, allowing users to choose unadjusted, split-adjusted, or split- and dividend-adjusted prices.

When should I consider staying with yfinance instead of switching?

yfinance is still fine if you only need the last 12 months of daily data for active stocks, do not require delisted history, and prefer a zero-setup, open-source tool. For extended history, alternative datasets, or transparent adjustments, FinzData offers more capabilities.