Binance Examples¶
Binance-specific patterns and examples.
Market Types¶
Binance offers multiple market categories:
| Category | API Type | Description |
|---|---|---|
"spot" | Spot | Spot market trading |
"usdm" | USD-M Futures | USDT-margined perpetual futures |
import qldata as qd
# Spot market
spot_df = qd.data("BTCUSDT", source="binance", category="spot") \
.last(7).resolution("1h").get()
# USD-M Futures
futures_df = qd.data("BTCUSDT", source="binance", category="usdm") \
.last(7).resolution("1h").get()
Spot Market¶
Fetch Spot Data¶
import qldata as qd
# Daily OHLCV
df = qd.data("BTCUSDT", source="binance", category="spot") \
.last(365) \
.resolution("1d") \
.clean() \
.get()
print(f"BTC spot: {len(df)} daily bars")
print(f"Date range: {df.index[0].date()} to {df.index[-1].date()}")
List Spot Pairs¶
import qldata as qd
# All active USDT pairs
usdt_pairs = qd.list_symbols(
source="binance",
category="spot",
quote_asset="USDT",
active_only=True
)
print(f"USDT pairs: {len(usdt_pairs)}")
# All BTC pairs
btc_pairs = qd.list_symbols(
source="binance",
category="spot",
quote_asset="BTC",
active_only=True
)
print(f"BTC pairs: {len(btc_pairs)}")
Spot Symbol Info¶
import qldata as qd
from decimal import Decimal
info = qd.get_symbol_info("BTCUSDT", source="binance", category="spot")
print(f"Symbol: {info.symbol}")
print(f"Base/Quote: {info.base_asset}/{info.quote_asset}")
print(f"Tick Size: {info.filters.tick_size}")
print(f"Min Quantity: {info.filters.min_quantity}")
# Validate order parameters
price = Decimal("50000.50")
quantity = Decimal("0.001")
print(f"Price valid: {info.validate_price(price)}")
print(f"Qty valid: {info.validate_quantity(quantity)}")
USD-M Futures¶
Fetch Futures Data¶
import qldata as qd
# BTCUSDT perpetual
df = qd.data("BTCUSDT", source="binance", category="usdm") \
.last(30) \
.resolution("1h") \
.clean() \
.get()
print(f"Futures bars: {len(df)}")
Funding Rates¶
import qldata as qd
# Current funding rate
rate = qd.current_funding_rate("BTCUSDT", source="binance", category="usdm")
print(f"Current rate: {rate:.6f}")
print(f"8h rate: {rate * 100:.4f}%")
print(f"Annualized: {rate * 3 * 365 * 100:.2f}%")
Basis Calculation¶
import qldata as qd
# Fetch spot and futures
spot = qd.data("BTCUSDT", source="binance", category="spot") \
.last(7).resolution("1h").clean().get()
futures = qd.data("BTCUSDT", source="binance", category="usdm") \
.last(7).resolution("1h").clean().get()
# Align indices
aligned = spot.join(futures, lsuffix="_spot", rsuffix="_futures", how="inner")
# Calculate basis
aligned["basis"] = aligned["close_futures"] - aligned["close_spot"]
aligned["basis_pct"] = aligned["basis"] / aligned["close_spot"] * 100
print(f"Current basis: ${aligned['basis'].iloc[-1]:.2f}")
print(f"Basis %: {aligned['basis_pct'].iloc[-1]:.4f}%")
print(f"Avg basis %: {aligned['basis_pct'].mean():.4f}%")
Live Streaming¶
Spot Trades¶
import qldata as qd
import time
def on_trade(df):
for _, row in df.iterrows():
side = "🟢" if row.get("side") == "buy" else "🔴"
print(f"{side} {row['symbol']}: ${row['price']:.2f} x {row['quantity']}")
stream = qd.stream(["BTCUSDT", "ETHUSDT"], source="binance", category="spot") \
.resolution("tick") \
.on_data(on_trade) \
.get(start=True)
time.sleep(60)
stream.stop()
Futures Trades¶
import qldata as qd
stream = qd.stream(["BTCUSDT"], source="binance", category="usdm") \
.resolution("tick") \
.on_data(lambda df: print(df["price"].iloc[-1] if not df.empty else "")) \
.get(start=True)
Rate Limits¶
Binance has the following rate limits:
| Type | Limit | Notes |
|---|---|---|
| REST API | 1200 req/min | Per IP |
| WebSocket | 5 connections/IP | Per IP |
| Order Rate | 10 orders/sec | Per account |
qldata handles rate limits automatically:
# This works even with many symbols
symbols = qd.list_symbols(source="binance", category="spot", quote_asset="USDT")[:100]
# Rate limiting handled automatically
data = qd.data(symbols, source="binance") \
.last(7) \
.resolution("1d") \
.get(parallel=True, workers=4)
Multi-Symbol Comparison¶
import qldata as qd
import pandas as pd
symbols = ["BTCUSDT", "ETHUSDT", "BNBUSDT", "SOLUSDT", "XRPUSDT"]
# Fetch all
data = qd.data(symbols, source="binance", category="spot") \
.last(30) \
.resolution("1d") \
.clean() \
.get(parallel=True)
# Compare returns
print("\n30-Day Returns Analysis")
print("-" * 40)
for symbol, df in data.items():
returns = (df["close"].iloc[-1] / df["close"].iloc[0] - 1) * 100
volatility = df["close"].pct_change().std() * (365 ** 0.5) * 100
print(f"{symbol}: {returns:+.2f}% return, {volatility:.1f}% vol")
Production Example¶
import qldata as qd
from qldata.monitoring import DataQualityMonitor
import logging
import time
logging.basicConfig(level=logging.INFO)
logger = logging.getLogger("binance")
monitor = DataQualityMonitor(stale_threshold_seconds=5)
def process(df):
if df.empty:
return
monitor.record_message(df.index[-1])
for _, row in df.iterrows():
# Your trading logic here
logger.debug(f"{row['symbol']}: ${row['price']:.2f}")
stream = qd.stream(["BTCUSDT", "ETHUSDT"], source="binance", category="spot") \
.resolution("tick") \
.on_data(process) \
.on_error(lambda e: logger.error(f"Error: {e}")) \
.on_reconnect(lambda n: logger.warning(f"Reconnect: {n}")) \
.get(start=True)
try:
while True:
m = monitor.get_metrics()
logger.info(f"TPS: {m['throughput']:.1f} | P95: {m['latency_p95']:.1f}ms")
time.sleep(30)
except KeyboardInterrupt:
stream.stop()
See Also¶
- Bybit Examples - Bybit patterns
- Streaming API - Full streaming docs
- Historical Data - Full historical docs