Chuyển tới nội dung chính

🐍 Ngày 42 - Python hằng ngày 365 ngày - Khám phá Order Book với API Binance

Hôm nay, chúng ta sẽ cùng tìm hiểu Order Book là gì và cách lấy dữ liệu Order Book từ API Binance bằng Python.


📚 Order Book là gì?​

Order Book (Sổ Lệnh) là nơi lưu trữ tất cả các lệnh mua và lệnh bán của một tài sản (ví dụ Bitcoin) trên sàn giao dịch, được sắp xếp theo thứ tự giá.

🔹 Cấu trúc:​

  • Lệnh mua (Bid): Người mua đề nghị mua tài sản với một mức giá cụ thể.
  • Lệnh bán (Ask): Người bán đề nghị bán tài sản với một mức giá cụ thể.

✅ Khi giá mua cao nhất khớp với giá bán thấp nhất, giao dịch sẽ được thực hiện.


📈 Ví dụ Order Book BTC/USDT:​

Giá mua (Bid)Khối lượng (BTC)Giá bán (Ask)Khối lượng (BTC)
93,0000.563,1000.3
92,9001.063,2000.4
92,8002.063,3000.6

🛠 Bài tập thực hành​

Bước 1: Cài đặt thư viện​

pip install python-binance

Bước 2: Kết nối API Binance và lấy Order Book​

from binance import Client

# Thay bằng API Key và Secret Key của bạn
api_key = 'YOUR_API_KEY'
api_secret = 'YOUR_API_SECRET'

client = Client(api_key, api_secret)

# Lấy Order Book cho cặp BTCUSDT
order_book = client.get_order_book(symbol='BTCUSDT')

# In ra top 5 lệnh mua và bán
print("Top 5 lệnh mua (Bids):")
for bid in order_book['bids'][:5]:
price, quantity = bid
print(f"Giá: {price}, Khối lượng: {quantity}")

print("\nTop 5 lệnh bán (Asks):")
for ask in order_book['asks'][:5]:
price, quantity = ask
print(f"Giá: {price}, Khối lượng: {quantity}")

Video hướng dẫn Docusaurus

Đây là video hướng dẫn chi tiết:


📊 Đọc và phân tích order book thực tế​

import urllib.request
import json
import pandas as pd


def lay_order_book(symbol: str = "BTCUSDT", gioi_han: int = 20) -> tuple[pd.DataFrame, pd.DataFrame]:
"""Lấy order book, trả về (bids, asks) dưới dạng DataFrame."""
url = ("https://api.binance.com/api/v3/depth"
f"?symbol={symbol}&limit={gioi_han}")

with urllib.request.urlopen(url, timeout=15) as r:
du_lieu = json.loads(r.read().decode())

bids = pd.DataFrame(du_lieu["bids"], columns=["gia", "khoi_luong"], dtype=float)
asks = pd.DataFrame(du_lieu["asks"], columns=["gia", "khoi_luong"], dtype=float)

# Tính giá trị từng mức (USDT)
for df in (bids, asks):
df["gia_tri"] = df["gia"] * df["khoi_luong"]

return bids, asks


bids, asks = lay_order_book("BTCUSDT", 20)

best_bid = bids["gia"].iloc[0]
best_ask = asks["gia"].iloc[0]
spread = best_ask - best_bid
spread_pct = spread / best_bid * 100

print(f"Best bid: {best_bid:,.2f}")
print(f"Best ask: {best_ask:,.2f}")
print(f"Spread: {spread:,.2f} ({spread_pct:.4f}%)")
print(f"\nTổng khối lượng mua (20 mức đầu): {bids['khoi_luong'].sum():,.4f} BTC")
print(f"Tổng khối lượng bán (20 mức đầu): {asks['khoi_luong'].sum():,.4f} BTC")

⚖️ Mất cân bằng sổ lệnh — chỉ báo quan trọng nhất từ order book​

Order book imbalance đo lực mua so với lực bán. Đây là thông tin mà biểu đồ giá không cho bạn biết.

import numpy as np


def mat_can_bang(bids: pd.DataFrame, asks: pd.DataFrame) -> dict:
"""Tính các chỉ số mất cân bằng của sổ lệnh."""
khoi_luong_mua = bids["khoi_luong"].sum()
khoi_luong_ban = asks["khoi_luong"].sum()
tong = khoi_luong_mua + khoi_luong_ban

if tong == 0:
return {"loi": "Sổ lệnh rỗng"}

return {
"ty_le_mua": round(khoi_luong_mua / tong * 100, 2),
"ty_le_ban": round(khoi_luong_ban / tong * 100, 2),
"chenh_lech": round((khoi_luong_mua - khoi_luong_ban) / tong * 100, 2),
"gia_tri_mua_usdt": round(bids["gia_tri"].sum(), 2),
"gia_tri_ban_usdt": round(asks["gia_tri"].sum(), 2),
}


tt = mat_can_bang(bids, asks)
for k, v in tt.items():
print(f"{k:<22} {v}")

chenh = tt["chenh_lech"]
if chenh > 20:
print("\n🟢 Áp lực MUA chiếm ư ưu thế rõ rệt")
elif chenh < -20:
print("\n🔴 Áp lực BÁN chiếm ưu thế rõ rệt")
else:
print("\n➖ Cân bằng — không có bên nào chiếm ưu thế")
Chỉ sốÝ nghĩa
Chênh lệch > +20%Áp lực mua mạnh — hỗ trợ bên dưới dày
Chênh lệch < −20%Áp lực bán mạnh — kháng cự bên trên dày
Chênh lệch ≈ 0Thị trường cân bằng, chờ tín hiệu khác
Spread rộngThanh khoản kém — cẩn thận trượt giá

⚠️ Giới hạn quan trọng: tường mua/bán trong order book có thể là lệnh ảo — được đặt rồi huỷ ngay trước khi giá chạm tới (spoofing). Đừng bao giờ vào lệnh chỉ dựa vào imbalance. Hãy dùng nó như một yếu tố phụ.

🧱 Phát hiện tường mua/bán (walls)​

import pandas as pd


def tim_tuong(df: pd.DataFrame, so_lan_tb: float = 3.0) -> pd.DataFrame:
"""Tìm các mức giá có khối lượng lớn bất thường."""
nguong = df["khoi_luong"].mean() * so_lan_tb
tuong = df[df["khoi_luong"] > nguong].copy()
tuong["gap_so_lan"] = (tuong["khoi_luong"] / df["khoi_luong"].mean()).round(1)
return tuong.sort_values("khoi_luong", ascending=False)


tuong_mua = tim_tuong(bids)
tuong_ban = tim_tuong(asks)

print("🧱 Tường MUA (hỗ trợ tiềm năng):")
for _, r in tuong_mua.head(3).iterrows():
print(f" {r['gia']:>12,.2f} {r['khoi_luong']:>10,.3f} BTC (gấp {r['gap_so_lan']}x)")

print("\n🧱 Tường BÁN (kháng cự tiềm năng):")
for _, r in asks.nlargest(3, "khoi_luong").iterrows():
print(f" {r['gia']:>12,.2f} {r['khoi_luong']:>10,.3f} BTC")

🔴 WebSocket — theo dõi order book theo thời gian thực​

REST API chỉ cho bạn ảnh chụp tại một thời điểm. WebSocket cho bạn dòng dữ liệu liên tục.

# pip install websocket-client
import json
import websocket


def theo_doi_order_book(symbol: str = "btcusdt", so_cap_nhat: int = 10):
"""Theo dõi order book realtime qua WebSocket Binance."""
url = f"wss://stream.binance.com:9443/ws/{symbol}@depth20@100ms"
dem = 0

def khi_nhan(ws, thong_diep):
nonlocal dem
du_lieu = json.loads(thong_diep)

bids = [(float(p), float(q)) for p, q in du_lieu.get("bids", [])]
asks = [(float(p), float(q)) for p, q in du_lieu.get("asks", [])]

if not bids or not asks:
return

kl_mua = sum(q for _, q in bids)
kl_ban = sum(q for _, q in asks)
chenh = (kl_mua - kl_ban) / (kl_mua + kl_ban) * 100

dem += 1
print(f"[{dem:>3}] Bid {bids[0][0]:,.2f} | Ask {asks[0][0]:,.2f} | "
f"Imbalance {chenh:+.1f}%")

if dem >= so_cap_nhat:
ws.close()

websocket.WebSocketApp(url, on_message=khi_nhan).run_forever()


# theo_doi_order_book()
Tiêu chíREST APIWebSocket
Cách hoạt độngGọi → nhận → kết thúcKết nối mở liên tục
Độ trễ100–500ms10–100ms
Số requestMỗi lần gọi là 1 request1 kết nối cho hàng nghìn cập nhật
Rate limitCóHầu như không
Phù hợpKiểm tra định kỳBot realtime

📝 Bài tập mở rộng​

Bài 1: So sánh imbalance giữa các cặp​

Lấy order book của BTC, ETH, SOL và so sánh chỉ số imbalance. Cặp nào đang có áp lực mua mạnh nhất?

Bài 2: Cảnh báo spread rộng​

Viết script kiểm tra spread mỗi 10 giây, in cảnh báo khi spread > 0,1%.

Bài 3: Vẽ biểu đồ sổ lệnh​

Dùng matplotlib vẽ biểu đồ cột ngang thể hiện khối lượng ở mỗi mức giá (bids một màu, asks màu khác).

Bài 4: Theo dõi imbalance theo thời gian​

Dùng WebSocket ghi lại imbalance mỗi 5 giây trong 2 phút, vẽ biểu đồ đường.

🎯 Tóm tắt ngày 42​

✅ Lấy và chuẩn hoá order book thành DataFrame ✅ Tính spread, tổng khối lượng, và imbalance ✅ Phát hiện tường mua/bán bất thường ✅ Hiểu giới hạn: tường có thể là lệnh ảo (spoofing) ✅ Biết khi nào dùng REST API vs WebSocket


🎯 Ghi chú​

  • Dữ liệu Order Book có thể cập nhật cực kỳ nhanh theo thời gian thực.
  • Bạn có thể dùng WebSocket để theo dõi biến động trực tiếp của Order Book nếu muốn nâng cao.