Migrate from yfinance

Port yfinance code to the Massive API

This guide is for Python developers who use yfinance and want a supported market data API. It maps each common yfinance method to the Massive endpoint that replaces it, shows how to rebuild the DataFrame your code expects, and lists the differences that change your results. To compare the two before you switch, see Massive vs yfinance.

yfinance is an open source library that is not affiliated with Yahoo. It reads Yahoo Finance endpoints that Yahoo does not document, and its README says it is for research and educational use. Yahoo's API terms say Yahoo may change or stop its APIs at any time. When Yahoo changes them, yfinance calls fail until the library is updated.

Before you start

  • Sign up and copy your API key from the dashboard. yfinance has no key, so this is a new step.
  • Pick a plan for each market you use on the pricing page.
  • Install the client with pip install -U massive.

Using AI?

Paste this into Claude Code, Cursor, Codex, or any coding agent that can read files and fetch a URL:

Find every place my project uses yfinance.
Switch those calls to the Massive Python client.
Read https://massive.com/docs/migration/guides/yfinance.md for the method map and the differences to handle.
Read https://massive.com/docs/llms.txt for the rest of the API.
Read the API key from the MASSIVE_API_KEY environment variable.
Keep my function signatures and DataFrame shapes the same, and list anything Massive does not cover.

To let the agent check real responses while it works, connect the Massive MCP server. Massive also publishes skills and plugins for coding agents.

The request

yfinance has no key. Massive needs one, so pass it to RESTClient.

yfinance end is exclusive, so a range that ends on October 3 sets end="2025-10-04":

import yfinance as yf

df = yf.Ticker("AAPL").history(start="2025-10-01", end="2025-10-04")

Massive's to is inclusive, so the range ends on October 3. The client returns a list of bars, and the last three lines build the DataFrame your yfinance code expects:

import pandas as pd
from massive import RESTClient

client = RESTClient("YOUR_API_KEY")
bars = client.list_aggs("AAPL", 1, "day", "2025-10-01", "2025-10-03")

df = pd.DataFrame(bars)
df.index = pd.to_datetime(df["timestamp"], unit="ms", utc=True).dt.tz_convert("America/New_York")
df = df.rename(columns={"open": "Open", "high": "High", "low": "Low", "close": "Close", "volume": "Volume"})
  • Many tickers. yf.download() fetches many tickers at once and returns MultiIndex columns, even for one ticker. Massive returns one ticker per call, so you build the frame you need. For every US stock on one day, use Daily Market Summary.
  • Intraday history. yfinance returns 1-minute bars for recent days only. Massive minute bars go back as far as your plan allows, up to 2003. See pricing.
  • Extended hours. yfinance leaves out pre-market and after-hours bars unless you pass prepost=True. Massive intraday bars include them. To match the default, keep bars from 9:30 a.m. to 4:00 p.m. ET.
  • Use list_aggs. It follows next_url until the range is complete. get_aggs returns one page, so a long minute range comes back short with no error.

The response

yfinanceMassive Python clientMassive JSONNote
Date indextimestamptUnix milliseconds at the bar start. Convert it as in the example above
Openopeno
Highhighh
Lowlowl
Closeclosec
Volumevolumev
Dividends, Stock SplitsNoneNoneUse Dividends and Splits
NonevwapvwVolume-weighted average price
NonetransactionsnNumber of trades

history() gives an index in exchange time. download() daily bars have no time zone. The example above converts Massive timestamps to US/Eastern, which matches history().

Symbols

yfinanceMassive
AAPLAAPL
BRK-BBRK.B
^GSPCI:SPX
EURUSD=XC:EURUSD
BTC-USDX:BTCUSD
AAPL251219C00200000O:AAPL251219C00200000
ES=FA contract ticker, such as ESZ5. Massive has no continuous front-month symbol, so pick the contract from Futures Contracts
A non-US listing, such as BP.LNot covered. Massive stocks are US listings only

Prices

  • yfinance adjusts Open, High, Low, and Close for splits and dividends by default. Massive adjusts for splits only, so values differ before every ex-dividend date.
  • With auto_adjust=False, yfinance returns prices as traded plus an Adj Close column. Set adjusted=false on Massive for the prices as traded.
  • To rebuild dividend-adjusted prices or Adj Close, use the historical adjustment factor from Dividends.

Errors

yfinance logs failures and returns an empty DataFrame. The Massive client raises an exception with the HTTP status, so code that checks df.empty should catch the exception instead.

Sources: yfinance README, yfinance price adjustment, Yahoo API terms.

Method map

This map covers the most common calls. It is not a full list. To find the Massive endpoint for another call, search these docs.

yfinanceMassive endpoint
Ticker.history(), yf.download()Custom Bars, with list_aggs in the Python client
yf.download(many_tickers, period="1d")Daily Market Summary, one call for every US stock
Ticker.fast_infoSingle Ticker Snapshot, Previous Day Bar
Ticker.infoTicker Overview, Ratios
Ticker.options, Ticker.option_chain()Option Chain Snapshot, All Contracts
Ticker.dividendsDividends
Ticker.splitsSplits
Ticker.income_stmt, Ticker.quarterly_income_stmtIncome Statements
Ticker.balance_sheetBalance Sheets
Ticker.cash_flowCash Flow Statements
Ticker.newsNews
Ticker.insider_transactionsForm 4
Ticker.institutional_holders13-F Filings
Ticker.recommendations, Ticker.analyst_price_targetsBenzinga Analyst Ratings, Consensus Ratings, paid add-ons
Ticker.earnings_datesBenzinga Earnings, a paid add-on
yf.SearchAll Tickers with search
History for ^GSPC, BTC-USD, EURUSD=XIndices, Crypto, and Forex Custom Bars

Massive currently doesn't have an equivalent for the yfinance screener, sector and industry data, ESG scores, fund holdings, or non-US listings. New data and features ship often, so check the product roadmap for what's planned. Massive adds options history. option_chain() returns today's chain only, and Options Custom Bars return past prices for any contract.

Streaming

yf.WebSocket reads Yahoo's price stream. Yahoo delays some of that data, such as options by 15 minutes. Massive streams over WebSockets with one connection per asset class. Subscribe to trades or minute bars on wss://socket.massive.com/stocks, or use the WebSocketClient in the Python client. See the WebSocket quickstart.

Bulk history

yf.download() fetches many tickers by looping over them in threads, which is where rate limits hit. Massive flat files hold one day per file across every US stock. Download daily bars or minute bars over S3, then load them with pd.read_csv.

Sources

yfinance details were checked against the yfinance repository at version 1.7.0 and the Yahoo API terms on October 29, 2026. Yahoo is a trademark of its owner. Massive is not affiliated with Yahoo or the yfinance project.

Did you find this page helpful?
Do you still need help with something?