Skip to content

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