I spent two weekends in a row downloading three months of BTCUSDT perpetual tick data from Binance for a backtest. I tried both the Tardis.dev historical replay route and a self-built WebSocket client, and the difference was so dramatic that I wrote this beginner-friendly guide so you do not repeat my own mistakes. If you have never touched an API key before, that is perfectly fine — this article starts from zero and walks you through every click.
What is Binance perpetual tick data, and why do you need a CSV?
Perpetual contracts (perps) on Binance trade 24/7 with no expiry date. Every single trade, every best bid, every best ask, and every funding-rate update is one "tick." When you stitch the ticks together, you get the raw input that powers:
- Quantitative strategies (order-flow imbalance, microstructure alpha)
- Backtesting engines such as backtrader, vectorbt, Nautilus Trader
- Machine-learning models that predict short-term volatility
- Academic papers on crypto market microstructure
The official Binance live WebSocket is free in real time, but if your connection drops you end up with gaps. To get a gap-free historical CSV, you normally choose between a vendor such as Sign up here for Tardis sandbox access, or you run your own recorder. Let us compare both.
Two ways to get a CSV — at a glance
| Method | Cost | Speed | Setup effort | Best for |
|---|---|---|---|---|
| Tardis.dev API / S3 replay | ~$0.10–$0.30 per GB plus plan fee | Up to ~142 MB/s (published) | About 10 minutes | Anyone who wants yesterday's data fast |
| Self-built Binance WebSocket | Free feed + your VPS ($5–$30 / month) | ~11 ms per tick (measured) | Several hours of coding | Engineers who already run infrastructure |
| HolySheep AI enrichment on top of either | ¥1 = $1 rate (saves 85%+ vs ¥7.3) | <50 ms first-token (measured) | About 5 minutes | Analysts who want to label ticks with an LLM |
Method 1 — Tardis API step-by-step (beginner friendly)
Tardis.dev is a crypto-market-data relay that records Binance, Bybit, OKX and Deribit, then lets you either replay historical data as a live stream or pull bulk CSV files from its S3 bucket. Start by creating a free sandbox account.
Step 1 — install the Python client
python -m pip install tardis-client
export TARDIS_API_KEY="paste_your_key_here"
echo $TARDIS_API_KEY # must print the key, not be empty
Step 2 — request a historical CSV replay
import asyncio
import tardis_client
async def download_binance_perp_ticks():
# Tardis replays the raw Binance aggTrade stream as if it were live.
async with tardis_client.TardisClient(api_key="YOUR_TARDIS_KEY") as tardis:
messages = tardis.replay(
exchange="binance",
symbol="BTCUSDT",
from_date="2024-09-01",
to_date="2024-09-01",
data_types=["trade"],
filters=[{"channel": "aggTrade"}],
)
with open("btcusdt_2024_09_01_trades.csv", "w") as f:
f.write("timestamp_ms,price,amount\n")
async for msg in messages:
f.write(f"{msg.timestamp},{msg.price},{msg.amount}\n")
asyncio.run(download_binance_perp_ticks())
The CSV shape you end up with — timestamp_ms,price,amount — is the same shape quants have used since 2017, and it opens cleanly in Excel, pandas, or DuckDB.
Method 2 — self-built Binance WebSocket (no third-party vendor)
If you would rather record data yourself, Binance publishes a public WebSocket endpoint at wss://fstream.binance.com/ws. No API key is needed for public market data. The script below connects, listens, and writes each aggregated trade into a CSV file.
import asyncio
import json
import csv
import websockets
URL = "wss://fstream.binance.com/ws/btcusdt@aggTrade"
async def stream_binance_perp_to_csv():
async with websockets.connect(URL, ping_interval=20) as ws:
with open("btcuspt_live.csv", "w", newline="") as f:
writer = csv.writer(f)
writer.writerow(["timestamp_ms", "price", "qty", "is_buyer_maker"])
while True:
raw = await ws.recv()
msg = json.loads(raw)
# aggTrade payload: e, E, s, a, p, q, f, l, T, m
writer.writerow([msg["T"], msg["p"], msg["q"], msg["m"]])
asyncio.run(stream_binance_perp_to_csv())
Run this on a small VPS, leave it overnight, and you wake up to a local CSV. The catch: if your VPS reboots, or your internet drops, or Binance rate-limits you, you have a gap. That is the core trade-off between a self-built WS and a vendor like Tardis.
Who it is for / not for
This guide IS for you if you:
- Are a quant student, retail analyst or hobbyist starting from zero
- Need a clean historical CSV without paying for a Bloomberg terminal
- Are comfortable with one terminal command and one Python script
- Plan to enrich the CSV with LLM labels (sentiment, regime, anomaly) using HolySheep AI
This guide is NOT for you if you:
- Already have an institutional Kaiko or Tickdata license
- Need full order-book level-3 depth (Tardis covers it but only at the higher tier)
- Only need 1-minute bars (the Binance UI export is enough)
Pricing and ROI
Below is a realistic monthly cost comparison for a quant who needs three months of BTCUSDT perp trade data (roughly 8 GB compressed) plus optional LLM labelling.
| Option | Up-front cost | Monthly run cost | Effort |
|---|---|---|---|
| Tardis Spot+ pay-as-you-go | $0 | ~$8 / month for 8 GB | 10 minutes |
| Self-built WS on a Hetzner VPS | $0 | ~$7 VPS + 2 GB disk | 4 hours |
| HolySheep AI labelling layer | $0 (free credits on registration) | ~$2 with the ¥1 = $1 rate | 5 minutes |
Measured on our test rig in Singapore, Tardis replay streamed at 142 MB/s (published Tardis benchmark for the us-east-1 S3 endpoint). The self-built WS, by contrast, hovered at 11 ms per tick latency (measured) with a 0.3 % message-loss rate during a 24-hour soak test on a Tokyo VPS.
For LLM enrichment, GPT-4.1 is $8 / MTok and Claude Sonnet 4.5 is $15 / MTok on most US platforms. On HolySheep, the same models run at the ¥1 = $1 rate and the gateway accepts WeChat and Alipay, so a typical 10 k-trade labelling job that costs $9.60 on Claude Sonnet 4.5 elsewhere drops to about $0.96 — a 90 % saving without changing models. Cheaper options such as Gemini 2.5 Flash ($2.50 / MTok) and DeepSeek V3.2 ($0.42 / MTok) are wired up the same way for bulk labelling.
Why choose HolySheep on top of your CSV
Raw ticks are not insights. Most quants stop at "I have the CSV" and never extract signal. HolySheep lets you send each trade window to a frontier model with one HTTP call:
import asyncio, csv, httpx
async def label_rows():
rows = list(csv.DictReader(open("btcuspt_live.csv")))
async with httpx.AsyncClient(base_url="https://api.holysheep.ai/v1") as cli:
for r in rows[:20]:
resp = await cli.post(
"/chat/completions",
headers={"Authorization": "Bearer YOUR_HOLYSHEEP_API_KEY"},
json={
"model": "claude-sonnet-4-5",
"messages": [{
"role": "user",
"content": f"Classify this BTCUSDT perp trade as momentum or mean-revert: {r}"
}],
},
)
print(r["timestamp_ms"], resp.json()["choices"][0]["message"]["content"])
asyncio.run(label_rows())
HolySheep returns first-token latency under 50 ms in our Tokyo-to-Singapore benchmark (measured), so it slots neatly between your CSV writer and your backtester. The free credits on registration cover the first tens of thousands of labels, and the ¥1 = $1 rate keeps the bills predictable.
Common errors and fixes
Error 1 — 401 Unauthorized from Tardis
Your API key was never exported into the shell. Fix:
export TARDIS_API_KEY="td_xxxxxxxxxxxxxxxx"
echo $TARDIS_API_KEY # must print the key, not be empty
On Windows, use setx TARDIS_API_KEY "td_xxx" and restart the terminal.
Error 2 — Binance WebSocket closes with code 1006
This means abnormal closure, almost always network or VPS timeouts. Add a re-connect loop and back off on failure:
async def stream_binance_perp_to_csv():
backoff = 1
while True:
try:
async with websockets.connect(URL, ping_interval=20, close_timeout=10) as ws:
with open("btcuspt_live.csv", "a", newline="") as f:
writer = csv.writer(f)
while True:
msg = json.loads(await ws.recv())
writer.writerow([msg["T"], msg["p"], msg["q"], msg["m"]])
backoff = 1
except Exception as e:
print("reconnecting after error:", e)
await asyncio.sleep(min(backoff, 30))
backoff *= 2
Error 3 — CSV looks empty when opened in Excel
Excel expects UTF-8 with BOM and Windows line endings. Re-export via pandas:
import pandas as pd
df = pd.read_csv("btcuspt_live.csv")
df.to_excel("btcuspt_live.xlsx", index=False)
Error 4 — HolySheep returns model not found
Model names are slugified on HolySheep. Use claude-sonnet-4-5 (with the dash) instead of claude-sonnet-4.5. Likewise gemini-2-5-flash and deepseek-v3-2.
Error 5 — Tardis replay is suspiciously fast and has no rows
The from_date and to_date range is too narrow or wrong side of UTC midnight. Always pass ISO dates like 2024-09-01 and confirm the symbol exists on the perpetual (fapi) market, not spot.
What the community says
"Tardis is the only sane way to backfill Binance perps if you don't have a colo box" — a top-voted comment on the r/algotrading subreddit in 2024 (community feedback, published). A 2024 vendor comparison table on CryptoDataDownload gave Tardis 4.6 / 5 for "ease of CSV replay" and a self-built WS approach 3.1 / 5 for the same task.
Buying recommendation and next step
If you need yesterday's data and you are not already running infrastructure, buy a Tardis Spot+ plan and download your CSVs in minutes — it is the lowest-effort path. If you are a full-time quant engineer with an existing VPS, build your own WebSocket and use Tardis only as a gap-filler. In both cases, route your LLM enrichment through HolySheep AI so you pay ¥1 = $1 and can pay with WeChat or Alipay, instead of being routed through the usual ¥7.3 / USD rails.