Binance Futures Backtest: Historical Perp Order Books & Trades
Backtest Binance USDⓈ-M perpetuals with tick-level depth and trades from AymarData — starting with BTCUSDT perps over REST.
Futures backtests need depth updates and aggressive flow, not only 1m candles. AymarData records Binance perps (~74.0M messages since 2025-06-01) alongside spot for basis work.
Market ids use the compact form BTCUSDT with source=binance-perps.
Inputs
What you need to backtest Binance futures properly
What a serious backtest needs beyond candles.
L2 depth at decision time
Call /v1/book with source=binance-perps and market=BTCUSDT (or another listed perp).
Trade tape for flow
Aggregate buy/sell notional from /v1/trades over short intervals to build pressure features.
Funding / mark when your strategy needs them
Perp instrument pages document mark and funding fields in the event stream; join on timestamp when carry matters.
Spot hedge reference
For basis, pair with binance-spot BTCUSDT books from the same clock.
Coverage
Live Binance futures coverage
Per-symbol weights appear on /data/binance/*-perp pages.
Perps messages
~74.0M
From 2025-06-01
Spot messages (hedge)
~28.0M
From 2025-06-01
Avg perps events/day
144,531
Platform-wide
As of
2026-10-25
Code
End-to-end Binance futures backtest (REST + requests)
Pulls a BTCUSDT perp book and five minutes of trades, then emits a buy-pressure signal.
import os
import requests
API = "https://api.aymardata.com/v1"
KEY = os.environ["AYMARDATA_API_KEY"] # export AYMARDATA_API_KEY=ad_live_…
H = {"Authorization": f"Bearer {KEY}", "User-Agent": "aymardata-backtest/1.0"}
def book(market: str, at: str):
r = requests.get(
f"{API}/book",
headers=H,
params={"source": "binance-perps", "market": market, "at": at, "depth": 10},
timeout=30,
)
r.raise_for_status()
return r.json()
def trades(market: str, start: str, end: str):
r = requests.get(
f"{API}/trades",
headers=H,
params={
"source": "binance-perps",
"market": market,
"start": start,
"end": end,
"limit": 500,
},
timeout=30,
)
r.raise_for_status()
return r.json()["data"]
MARKET = "BTCUSDT" # USDⓈ-M perpetual id on AymarData
AT = "2026-10-23T10:00:00Z"
START, END = "2026-10-23T10:00:00Z", "2026-10-23T10:05:00Z"
snap = book(MARKET, AT)
tape = trades(MARKET, START, END)
bids, asks = snap.get("bids") or [], snap.get("asks") or []
mid = (bids[0]["price"] + asks[0]["price"]) / 2 if bids and asks else None
buys = [t for t in tape if t.get("side") == "buy"]
sells = [t for t in tape if t.get("side") == "sell"]
buy_notional = sum((t["price"] or 0) * (t["size"] or 0) for t in buys)
sell_notional = sum((t["price"] or 0) * (t["size"] or 0) for t in sells)
# Simple flow signal: buy-pressure → lean long next minute (research sketch)
signal = "long" if buy_notional > sell_notional * 1.05 else "flat"
print({
"market": MARKET,
"mid": mid,
"spread": snap.get("spread"),
"n_trades": len(tape),
"buy_notional": round(buy_notional, 2),
"sell_notional": round(sell_notional, 2),
"signal": signal,
})
API base https://api.aymardata.com. Set AYMARDATA_API_KEY from your dashboard. Examples use requests. Any P&L, win-rate, or edge figure derived from these snippets is illustrative output — not a real result.
Free samples
Download sample CSV / Parquet
No key required — small files for schema and local smoke tests.
FAQ
Common questions
Is this Binance futures or spot?
This page targets USDⓈ-M perpetuals (source=binance-perps). Spot lives under /data/binance/*-spot and the Bitcoin backtest page for cross-venue work.
Which symbol works in the live API today?
BTCUSDT is the primary example. List others with GET /v1/markets?source=binance-perps.
Related
Data pages and guides
Catalog leaves for schema and samples; guides for longer walkthroughs.
Run your first backtest with real ticks
Get a key, paste the snippet above, then expand to the full catalog.
Educational content, not trading or investment advice. Past data doesn't predict future results.