Khi tôi bắt tay vào dự án backtest chiến lược grid trading cho cặp BTCUSDT trên Binance, tôi đã tải về khoảng 47GB dữ liệu CSV thô. Máy tính của tôi treo liên tục, mỗi lần mở file là RAM 32GB kêu cứu. Sau ba tuần vật lộn, tôi chuyển sang pipeline Tardis → Parquet với ZSTD: kích thước giảm xuống còn 8,2GB, truy vấn nhanh hơn 18 lần so với CSV. Bài viết này là kinh nghiệm thực chiến của tôi, viết lại từng bước cho bạn nào mới bắt đầu — không cần biết API, không cần thuật ngữ nâng cao, cứ copy và chạy theo là được.
1. Tardis là gì và normalized_book_L2 hoạt động ra sao?
Tardis (tardis.dev) là dịch vụ cung cấp dữ liệu thị trường tiền mã hóa lịch sử, lưu trữ tick-by-tick. Trong rất nhiều loại dữ liệu, Tardis có một loại đặc biệt tên là normalized_book_L2 — tức sổ lệnh cấp 2 (top 20 mức giá mua/bán) đã được chuẩn hóa về cùng một định dạng cho mọi sàn.
Mỗi tin nhắn trong normalized_book_L2 là một bản cập nhật tăng dần (incremental update) chứ không phải ảnh chụp toàn bộ sổ lệnh. Cấu trúc một dòng tin nhắn trông như sau:
- exchange: tên sàn (binance, bybit, coinbase…)
- symbol: cặp giao dịch (BTCUSDT, ETHUSDT…)
- timestamp: thời gian phía sàn (UTC)
- local_timestamp: thời gian máy thu nhận
- side: "bid" (mua) hoặc "ask" (bán)
- price: mức giá
- amount: khối lượng (nếu bằng 0 nghĩa là mức giá đó bị xóa)
Để dựng lại sổ lệnh tại một thời điểm bất kỳ, bạn chỉ cần áp dụng tuần tự các bản cập nhật từ trước đó. Đây chính là lý do gọi là incremental.
📸 Gợi ý ảnh: chụp màn hình trang chủ tardis.dev hiển thị bảng giá các gói dữ liệu.
2. Chuẩn bị môi trường và lấy API key
Trước tiên bạn cần tạo tài khoản Tardis, vào mục API Keys để lấy key. Tài khoản miễn phí cho phép xem 30 ngày dữ liệu gần nhất, đủ để thử nghiệm.
📸 Ảnh minh họa: bảng điều khiển sau khi tạo API key thành công, có dòng chữ "Your API key: td_xxxxxxxx".
Trên máy tính, mở Terminal (macOS/Linux) hoặc PowerShell (Windows) và chạy:
# Tạo môi trường ảo để khỏi lẫn thư viện với dự án khác
python -m venv tardis_env
source tardis_env/bin/activate # macOS / Linux
tardis_env\Scripts\activate # Windows
Cài đặt các thư viện cần thiết
pip install tardis-client pandas pyarrow pyarrow==15.0.0 requests
📸 Ảnh minh họa: cửa sổ Terminal hiển thị dòng "Successfully installed tardis-client-X.X.X".
3. Tải dữ liệu normalized_book_L2 từ Tardis
Tardis cung cấp gói tardis-client giúp tải dữ liệu replay trực tiếp về máy. Bạn chỉ cần cho biết sàn, ngày, cặp giao dịch và loại dữ liệu.
import os
from tardis_client import TardisClient
Khai báo API key, nên để trong biến môi trường để bảo mật
os.environ["TARDIS_API_KEY"] = "TDxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
tardis = TardisClient(api_key=os.environ["TARDIS_API_KEY"])
Tải dữ liệu L2 của BTCUSDT trên Binance trong 1 giờ
messages = tardis.replays(
exchange="binance",
from_date="2024-01-01",
to_date="2024-01-01",
data_type="normalized_book_L2",
symbols=["btcusdt"],
)
In thử 3 dòng đầu tiên để xem cấu trúc
for i, msg in enumerate(messages):
if i >= 3:
break
print(msg)
📸 Ảnh minh họa: Terminal in ra 3 dòng JSON, mỗi dòng có exchange, symbol, timestamp, side, price, amount.
4. Chuẩn hóa dữ liệu thành bảng và ghi ra Parquet
Đây là phần quan trọng nhất. Tôi từng để dữ liệu nằm trong danh sách Python, mỗi lần truy vấn phải duyệt vòng lặp — chậm kinh khủng. Cách đúng là đổ sang Apache Parquet, định dạng lưu trữ cột, nén rất tốt và truy vấn cực nhanh.
import pyarrow as pa
import pyarrow.parquet as pq
from datetime import datetime
1. Gom toàn bộ message về dạng danh sách dict
rows = []
for msg in messages:
rows.append({
"exchange": msg.exchange,
"symbol": msg.symbol,
"timestamp": datetime.fromisoformat(msg.timestamp.replace("Z", "+00:00")),
"local_timestamp": datetime.fromisoformat(msg.local_timestamp.replace("Z", "+00:00")),
"side": msg.side,
"price": float(msg.price),
"amount": float(msg.amount),
})
2. Định nghĩa schema chuẩn để Parquet ghi nhanh và đồng nhất kiểu dữ liệu
schema = pa.schema([
("exchange", pa.string()),
("symbol", pa.string()),
("timestamp", pa.timestamp("us")),
("local_timestamp", pa.timestamp("us")),
("side", pa.string()),
("price", pa.float64()),
("amount", pa.float64()),
])
3. Tạo Arrow Table rồi ghi ra file Parquet với nén ZSTD
table = pa.Table.from_pylist(rows, schema=schema)
output_path = "data/binance/btcusdt/2024-01-01.parquet"
os.makedirs(os.path.dirname(output_path), exist_ok=True)
pq.write_table(
table,
output_path,
compression="zstd",
compression_level=15,
use_dictionary=True,
)
print(f"Đã ghi {len(rows):,} dòng vào {output_path}")
print(f"Kích thước file: {os.path.getsize(output_path) / 1024 / 1024:.2f} MB")
📸 Ảnh minh họa: thư mục data/binance/btcusdt/ trong VS Code hiển thị file 2024-01-01.parquet ~ 42MB thay vì 380MB CSV.
5. Đọc lại Parquet và truy vấn nhanh bằng Pandas
Sau khi ghi xong, việc đọc lại và lọc dữ liệu cực kỳ nhanh vì Parquet lưu cột — chỉ cần đọc đúng cột cần thiết.
import pandas as pd
Đọc toàn bộ file Parquet vào DataFrame
df = pd.read_parquet("data/binance/btcusdt/2024-01-01.parquet")
print(f"Số dòng: {len(df):,}")
print(df.head())
Lọc nhanh: chỉ lấy lệnh mua (bid) trong 5 phút đầu
mask = (df["side"] == "bid") & (df["timestamp"] < "2024-01-01 00:05:00")
bids_first_5min = df[mask]
Tính tổng khối lượng bid trong 5 phút
total_bid_volume = bids_first_5min["amount"].sum()
print(f"Tổng khối lượng bid 5 phút đầu: {total_bid_volume:,.4f} BTC")
📸 Ảnh minh họa: Jupyter Notebook hiển thị bảng 5 dòng đầu với các cột exchange, symbol, timestamp, side, price, amount.
6. Dùng HolySheep AI để phân tích sổ lệnh thông minh
Sau khi đã có dữ liệu sạch, tôi thường nhờ AI phân tích các mẫu hình bất thường. Ở đây tôi dùng HolySheep AI — nền tảng tổng hợp nhiều mô hình lớn với giá rất rẻ, hỗ trợ thanh toán WeChat/Alipay và độ trễ dưới 50ms.
import requests
Lấy 50 mẫu cập nhật gần nhất để gửi cho AI
sample = df.tail(50).to_csv(index=False)
url = "https://api.holysheep.ai/v1/chat/completions"
headers = {
"Authorization": "Bearer YOUR_HOLYSHEEP_API_KEY",
"Content-Type": "application/json",
}
payload = {
"model": "deepseek-v3.2", # model rẻ nhất, chỉ $0.42/MTok
"messages": [
{"role": "system", "content": "Bạn là chuyên gia phân tích sổ lệnh tiền mã hóa."},
{"role": "user", "content": f"Phân tích các bản cập nhật L2 sau, tìm dấu hiệu whale:\n{sample}"}
],
"temperature": 0.2,
}
resp = requests.post(url, json=payload, headers=headers, timeout=30)
result = resp.json()
print(result["choices"][0]["message"]["content"])
📸 Ảnh minh họa: phản hồi từ HolySheep AI in ra nhận định "phát hiện 3 lệnh bid khối lượng lớn trên 50 BTC quanh mức 42.000 USDT, có thể là whale đang gom hàng".