trading4 Min Read

Market Data: Types & Where to Download It (Free and Paid)

Gorav Singal

October 30, 2026

TL;DR

Market data comes in levels: OHLCV bars (free, tiny, enough for most research), L1 top-of-book + ticks, L2 depth (for execution and imbalance signals), and L3 the full order book (HFT, expensive). Pick the lowest level that answers your question. FREE sources to start: yfinance and Stooq (bars), crypto exchange APIs like Binance (full tick & L2, genuinely free), NSE/BSE bhavcopy (official India EOD), Alpha Vantage, Nasdaq Data Link, Dukascopy, Kaggle. PAID when it's real money: Polygon.io and Databento (US tick/L2/L3), IEX/Tiingo, TrueData/GFDL (India), Kite Connect (your broker's live feed), Refinitiv/Bloomberg (institutional). Two traps bite everyone: SURVIVORSHIP BIAS (free data lists only stocks that still exist, so a backtest assumes you dodged every failure) and CORPORATE ACTIONS (use split/dividend-ADJUSTED prices or a 2:1 split looks like a 50% crash).

Market Data: Types & Where to Download It (Free and Paid)

Data is the raw material of every strategy, and getting the right data is the first real hurdle in algo trading — before any clever model. The questions are always: what kind of data do I need, where do I get it, and what will quietly ruin my backtest if I’m careless? This article answers all three, with Python you can run today.

A note up front: educational material, not financial advice. Nothing here is a recommendation to trade.

The levels of market data

“Market data” isn’t one thing — it’s a ladder from a coarse daily summary to every individual order. More detail means more cost, more storage, and more engineering.

The levels of market data as a pyramid: OHLCV bars at the base (free, tiny, for backtesting), L1 top-of-book plus ticks, L2 market depth (aggregated size per level), L3 the full order book (every order, huge volume, for HFT). Pick the lowest level that answers your question.

  • Bars (OHLCV) — Open/High/Low/Close/Volume per minute or day. Tiny, free, and enough for most research and backtesting. Start here.
  • L1 — top of book + ticks — the best bid/ask and every individual trade (a “tick”). Most strategies live here.
  • L2 — market depth — aggregated size at several price levels on each side. You need this for execution algorithms and order-book imbalance signals.
  • L3 — full order book — every individual order (add/modify/cancel). Enormous volume (millions of messages a day for one liquid stock), and the domain of HFT and market making.

The rule: pick the lowest level that answers your question. Researching a daily strategy? Bars. Building an execution algo? L2. Going deeper than you need just multiplies cost and storage for nothing.

Where to get it

Where to get market data: free sources (yfinance, Stooq, Alpha Vantage, crypto exchange APIs, NSE/BSE bhavcopy, Nasdaq Data Link, Dukascopy, Kaggle, FRED, GDELT) for learning and backtesting, and paid sources (Polygon, Databento, IEX, Tiingo, TrueData, Kite Connect, Refinitiv, Bloomberg) for production. Two traps: survivorship bias and corporate actions.

Free — to learn, research and backtest

  • yfinance — the easiest start: daily and intraday bars for equities, FX and crypto, free.
  • Stooq — free daily history, good for quick CSV pulls (works via pandas-datareader).
  • Crypto exchange APIs (Binance, etc.) — the best free deal in the business: full tick and L2 depth, no paywall, clean REST/WebSocket APIs. If you want real microstructure data to learn on, crypto is where to go.
  • NSE / BSE bhavcopy — official Indian end-of-day data, free to download.
  • Alpha Vantage — bars plus fundamentals with a free (rate-limited) API key.
  • Nasdaq Data Link (formerly Quandl), Dukascopy (historical tick FX), Kaggle (curated datasets), FRED (macro/rates), GDELT (news/sentiment).

A few lines gets you going. Equities/crypto bars with yfinance:

import yfinance as yf

# daily, split/dividend-ADJUSTED prices (important — see the traps below)
df = yf.download("RELIANCE.NS", start="2020-01-01", auto_adjust=True)
print(df[["Open", "High", "Low", "Close", "Volume"]].tail())

Free crypto tick-level data straight from an exchange, via the ccxt library (one interface for 100+ exchanges):

import ccxt, pandas as pd

ex = ccxt.binance()
ohlcv = ex.fetch_ohlcv("BTC/USDT", timeframe="1m", limit=1000)
df = pd.DataFrame(ohlcv, columns=["ts", "open", "high", "low", "close", "vol"])
df["ts"] = pd.to_datetime(df["ts"], unit="ms")
print(df.tail())

When real money is involved, you pay for clean, point-in-time, survivorship-free data and reliable live feeds:

  • Polygon.io — US equities and options, REST + WebSocket, hobby-friendly pricing.
  • Databento — tick, L2 and L3, pay-as-you-go, genuinely quant-grade.
  • IEX Cloud, Tiingo — affordable US market data.
  • TrueData / GFDL — Indian intraday and tick data aimed at retail.
  • Kite Connect (Zerodha) — your broker’s live feed and order API; this is what you actually trade through in India.
  • Refinitiv, Bloomberg — institutional, expensive, and they have everything.

Live data you’ll actually trade on usually comes from your broker. A Kite Connect historical pull looks like:

from kiteconnect import KiteConnect

kite = KiteConnect(api_key="your_key")
kite.set_access_token("your_token")
# instrument_token from kite.instruments(); 'minute' bars for one day
candles = kite.historical_data(instrument_token=408065,
                               from_date="2026-10-29 09:15:00",
                               to_date="2026-10-29 15:30:00",
                               interval="minute")

The two traps that will bite you (free or paid)

More backtests are ruined by data problems than by bad strategies. Two in particular:

  1. Survivorship bias. Most free datasets only list securities that still exist. Every company that went to zero, got delisted, or was acquired is simply missing. So a backtest over “today’s stocks” quietly assumes you’d have owned only the survivors — that you’d have dodged every failure in advance. This makes almost any strategy look good and is one of the most common ways people fool themselves. Point-in-time, survivorship-free data (paid) is the fix when it matters.

  2. Corporate actions. Splits and dividends make raw prices jump discontinuously — a 2-for-1 split halves the price overnight, which a naive backtest reads as a −50% crash. Always use adjusted (or “back-adjusted”) prices (auto_adjust=True in yfinance), or handle the actions yourself.

Two more to check every time: timezones (is that timestamp exchange-local or UTC?) and delay (a lot of “free” intraday data is delayed 15 minutes, which is fine for research and useless for live trading).

Rule of thumb

Learn and backtest on free daily or crypto data — it’s plenty to understand every strategy in this series. Pay for clean, point-in-time, survivorship-free data only when you’re about to risk real money, and get your live feed from the broker you’ll actually trade through.

Next, put this data to work: the moving-average crossover — the “hello world” strategy — backtested honestly in Python. For the full systems view (building and maintaining a live data feed, L2 book from a WebSocket, reconnection and sequence gaps), see the Low-Latency Trading Systems course.

Share

Related Posts

The Moving-Average Crossover, Backtested Honestly in Python

The Moving-Average Crossover, Backtested Honestly in Python

If algo trading has a “hello world,” it’s the moving-average crossover. Every…

Execution Algorithms: VWAP & TWAP in Python

Execution Algorithms: VWAP & TWAP in Python

Every strategy so far produced signals — when to be long, short, or flat. But a…

Position Sizing & the Kelly Criterion in Python

Position Sizing & the Kelly Criterion in Python

Every strategy article so far asked ”what should I trade?” This one asks the…

Momentum & Trend Following in Python

Momentum & Trend Following in Python

Momentum is, along with value, one of the most robust and widely-documented…

Mean Reversion & Pairs Trading in Python

Mean Reversion & Pairs Trading in Python

The moving-average crossover bet on direction and lost. Here’s a strategy with a…

Market Making Basics: Spread Capture vs Inventory Risk (in Python)

Market Making Basics: Spread Capture vs Inventory Risk (in Python)

So far you’ve been a taker — crossing the spread to get filled. A market maker…

Latest Posts

Execution Algorithms: VWAP & TWAP in Python

Execution Algorithms: VWAP & TWAP in Python

Every strategy so far produced signals — when to be long, short, or flat. But a…

Position Sizing & the Kelly Criterion in Python

Position Sizing & the Kelly Criterion in Python

Every strategy article so far asked ”what should I trade?” This one asks the…

Momentum & Trend Following in Python

Momentum & Trend Following in Python

Momentum is, along with value, one of the most robust and widely-documented…

Mean Reversion & Pairs Trading in Python

Mean Reversion & Pairs Trading in Python

The moving-average crossover bet on direction and lost. Here’s a strategy with a…

The Moving-Average Crossover, Backtested Honestly in Python

The Moving-Average Crossover, Backtested Honestly in Python

If algo trading has a “hello world,” it’s the moving-average crossover. Every…

Market Making Basics: Spread Capture vs Inventory Risk (in Python)

Market Making Basics: Spread Capture vs Inventory Risk (in Python)

So far you’ve been a taker — crossing the spread to get filled. A market maker…