Back to Blog
ccxt · python · historical-data

Fetching Historical Trades with CCXT: Limits and Alternatives

CCXT is the standard Python library for connecting to crypto exchange APIs. When it comes to historical tick data, it has hard limits that most developers hit quickly.

What fetch_trades Actually Returns

import ccxt

exchange = ccxt.binance()
trades = exchange.fetch_trades("BTC/USDT", limit=1000)
print(f"Got {len(trades)} trades")
print(f"Oldest: {trades[0]['datetime']}")

Maximum 1,000 recent trades. For BTC/USDT on a busy exchange, that is roughly 10-30 seconds of activity. Most exchanges limit REST API historical access to 24-72 hours.

Paginating with since — The Practical Limit

import ccxt, time

exchange = ccxt.binance()
all_trades, since = [], exchange.parse8601("2026-01-01T00:00:00Z")

while True:
    trades = exchange.fetch_trades("BTC/USDT", since=since, limit=1000)
    if not trades: break
    all_trades.extend(trades)
    since = trades[-1]["timestamp"] + 1
    time.sleep(exchange.rateLimit / 1000)

Fetching one full year via this loop requires ~2-3 million API calls and takes weeks. Most exchanges cut off historical access after a certain date anyway.

The Alternative: Bulk Archives

For any project requiring more than a few days of data, bulk archives are the only practical option — complete history in compressed files, downloadable in hours, no rate limiting. The tradeoff: you need to verify data quality, or use a dataset that has already been audited.

Skip the API rate limits. Audited tick-level trade data for BTC, ETH and 8 more assets — ready to use. → Browse the catalog

Summary

CCXT's fetch_trades is excellent for live trading and very recent data. For historical research spanning months or years, bulk archives are the correct approach. Once you have the data in Parquet, converting it to any format your tools expect is a short script.