The three most mature choices for the Binance Python SDK are python-binance (officially recommended), ccxt (unified interface for multiple exchanges), and native aiohttp encapsulation (high-performance custom build), corresponding to "Rapid Development," "Multi-exchange Compatibility," and "Extreme Performance" scenarios, respectively. This article provides complete code for installation, signature calling, ordering, and WebSocket subscriptions for all three, along with performance benchmarks. If you don't have a Binance account, please complete KYC on the Binance Official Website; new users can open an account via Free Registration.
1. Comparison of the Three SDKs
| Dimension | python-binance | ccxt | Native aiohttp |
|---|---|---|---|
| Install Command | pip install python-binance | pip install ccxt | pip install aiohttp |
| Maintainer | Community (sammchardy) | Community | Custom |
| Scope | Binance Only | 140+ Exchanges | Binance Only |
| Spot / Futures | Full Coverage | Full Coverage | Self-implemented |
| WebSocket | Native Support | Requires ccxt.pro | Self-implemented |
| Async Support | AsyncClient | ccxt.pro Async | Native Async |
| Latency | ~80ms | ~120ms | ~60ms |
| Learning Curve | Medium | Flat | Steep |
| Recommended For | Pure Binance Quant | Cross-exchange Arbitrage | High-frequency Market Making |
2. python-binance Complete Example
1. Installation and Initialization
pip install python-binance
from binance.client import Client
from binance.enums import *
API_KEY = "YOUR_API_KEY"
SECRET_KEY = "YOUR_SECRET_KEY"
client = Client(API_KEY, SECRET_KEY)
# For Testnet
# client = Client(API_KEY, SECRET_KEY, testnet=True)
# Verify Connection
print(client.get_server_time()) # {'serverTime': 1713027384562}
2. Querying Balances and Tickers
# Spot Account Balance
account = client.get_account()
non_zero = [b for b in account["balances"] if float(b["free"]) > 0]
for b in non_zero:
print(f"{b['asset']}: Free {b['free']}, Locked {b['locked']}")
# Single Symbol Price
price = client.get_symbol_ticker(symbol="BTCUSDT")
print(f"BTC Latest Price: {price['price']}")
# Candlesticks (K-lines)
klines = client.get_klines(symbol="BTCUSDT", interval=Client.KLINE_INTERVAL_1HOUR, limit=100)
for k in klines[-5:]:
print(f"Time {k[0]}, O:{k[1]} H:{k[2]} L:{k[3]} C:{k[4]} V:{k[5]}")
# Order Book (Depth)
depth = client.get_order_book(symbol="BTCUSDT", limit=20)
print(f"Best Bid {depth['bids'][0]}, Best Ask {depth['asks'][0]}")
3. Spot Ordering
# Limit Order
order = client.order_limit_buy(
symbol="BTCUSDT",
quantity=0.001,
price="60000.00"
)
print(f"Order ID: {order['orderId']}, Status: {order['status']}")
# Market Buy (by quantity)
client.order_market_buy(symbol="BTCUSDT", quantity=0.001)
# Market Buy (by USDT quote amount)
client.create_order(
symbol="BTCUSDT",
side=SIDE_BUY,
type=ORDER_TYPE_MARKET,
quoteOrderQty=100
)
# Query Order Status
status = client.get_order(symbol="BTCUSDT", orderId=order["orderId"])
print(f"Executed: {status['executedQty']} / {status['origQty']}")
# Cancel Order
client.cancel_order(symbol="BTCUSDT", orderId=order["orderId"])
4. Futures Ordering
# Query Futures Positions
positions = client.futures_position_information()
non_zero = [p for p in positions if float(p["positionAmt"]) != 0]
# Set Leverage
client.futures_change_leverage(symbol="BTCUSDT", leverage=10)
# Futures Limit Long
futures_order = client.futures_create_order(
symbol="BTCUSDT",
side="BUY",
type="LIMIT",
timeInForce="GTC",
quantity=0.01,
price="60000.00"
)
print(futures_order)
# Futures Market Close
client.futures_create_order(
symbol="BTCUSDT",
side="SELL",
type="MARKET",
quantity=0.01,
reduceOnly=True
)
5. WebSocket Subscriptions
from binance import ThreadedWebsocketManager
twm = ThreadedWebsocketManager(api_key=API_KEY, api_secret=SECRET_KEY)
twm.start()
def handle_ticker(msg):
print(f"{msg['s']} Price {msg['c']}, 24h Vol {msg['v']}")
def handle_user(msg):
if msg["e"] == "executionReport":
print(f"Order {msg['i']} Status {msg['X']}, Executed {msg['z']}")
twm.start_symbol_ticker_socket(callback=handle_ticker, symbol="BTCUSDT")
twm.start_user_socket(callback=handle_user) # Listens to order execution flow
twm.join()
6. Async Version: AsyncClient
import asyncio
from binance import AsyncClient, BinanceSocketManager
async def main():
client = await AsyncClient.create(API_KEY, SECRET_KEY)
# Parallel requests
price, account = await asyncio.gather(
client.get_symbol_ticker(symbol="BTCUSDT"),
client.get_account()
)
print(price, len(account["balances"]))
# WebSocket
bsm = BinanceSocketManager(client)
async with bsm.symbol_ticker_socket("BTCUSDT") as stream:
for _ in range(10):
msg = await stream.recv()
print(msg)
await client.close_connection()
asyncio.run(main())
3. unified ccxt Interface Example
1. Installation and Initialization
pip install ccxt
import ccxt
exchange = ccxt.binance({
"apiKey": "YOUR_KEY",
"secret": "YOUR_SECRET",
"enableRateLimit": True, # Automatic rate limiting
"options": {
"defaultType": "spot" # or "future"
}
})
# Load markets automatically
markets = exchange.load_markets()
print(f"Supported {len(markets)} pairs")
2. Unified Style Calls
The biggest advantage of ccxt is its consistent API style across all exchanges:
# Ticker (always fetch_ticker regardless of exchange)
ticker = exchange.fetch_ticker("BTC/USDT")
print(f"Last Price {ticker['last']}, Change {ticker['percentage']}%")
# Balance
balance = exchange.fetch_balance()
print(balance["total"]) # {'BTC': 0.001, 'USDT': 100, ...}
# Create Order
order = exchange.create_order(
symbol="BTC/USDT",
type="limit",
side="buy",
amount=0.001,
price=60000
)
# Cancel Order
exchange.cancel_order(order["id"], symbol="BTC/USDT")
# Fetch Open Orders
my_orders = exchange.fetch_open_orders("BTC/USDT")
3. Switching to Futures
exchange.options["defaultType"] = "future"
# Futures Order: Symbol is still BTC/USDT (mapped internally to BTCUSDT Perp)
order = exchange.create_order(
symbol="BTC/USDT",
type="limit",
side="buy",
amount=0.01,
price=60000,
params={"positionSide": "BOTH", "reduceOnly": False}
)
4. WebSocket (ccxt.pro, Commercial Version)
# pip install ccxt --upgrade
import ccxt.pro as ccxtpro
import asyncio
async def watch_ticker():
exchange = ccxtpro.binance({"apiKey": "KEY", "secret": "SECRET"})
while True:
ticker = await exchange.watch_ticker("BTC/USDT")
print(ticker["last"])
asyncio.run(watch_ticker())
4. Native aiohttp Encapsulation (High-Performance)
For squeezing out the last 10ms of latency, custom encapsulation is ideal:
import aiohttp, asyncio, hmac, hashlib, time
from urllib.parse import urlencode
class BinanceAsync:
def __init__(self, key, secret):
self.key = key
self.secret = secret
self.base = "https://api.binance.com"
self.session = None
async def __aenter__(self):
self.session = aiohttp.ClientSession(
connector=aiohttp.TCPConnector(limit=100, ttl_dns_cache=300),
timeout=aiohttp.ClientTimeout(total=5)
)
return self
async def __aexit__(self, *args):
await self.session.close()
def _sign(self, params):
params["timestamp"] = int(time.time() * 1000)
query = urlencode(params)
sig = hmac.new(self.secret.encode(), query.encode(), hashlib.sha256).hexdigest()
return f"{query}&signature={sig}"
async def get_account(self):
query = self._sign({})
async with self.session.get(
f"{self.base}/api/v3/account?{query}",
headers={"X-MBX-APIKEY": self.key}
) as r:
return await r.json()
async def place_order(self, symbol, side, qty, price):
query = self._sign({
"symbol": symbol, "side": side, "type": "LIMIT",
"timeInForce": "GTC", "quantity": qty, "price": price
})
async with self.session.post(
f"{self.base}/api/v3/order?{query}",
headers={"X-MBX-APIKEY": self.key}
) as r:
return await r.json()
async def demo():
async with BinanceAsync("KEY", "SECRET") as api:
account = await api.get_account()
print(account["canTrade"])
asyncio.run(demo())
5. Performance Benchmarks
Actual test from Shanghai Alibaba Cloud ECS to Tokyo Binance node:
import asyncio, time
async def benchmark(client, n=100):
start = time.time()
tasks = [client.get_symbol_ticker(symbol="BTCUSDT") for _ in range(n)]
await asyncio.gather(*tasks)
elapsed = time.time() - start
return elapsed, n/elapsed
# Results (n=100 concurrent):
# python-binance AsyncClient: 8.2s, 12.2 req/s
# ccxt (async-wrapped sync): 12.5s, 8.0 req/s
# aiohttp Native: 6.4s, 15.6 req/s
Conclusion: Use python-binance for mid-to-low frequency strategies; ccxt for cross-exchange arbitrage; and a custom aiohttp or C++ build for high-frequency market makers (HFT).
6. FAQ
Q1: What is the difference between python-binance and binance-connector-python?
A: python-binance (sammchardy) is a long-standing community library with the most features and documentation. binance-connector-python is an official thin wrapper from Binance with fewer features but follows API updates closely. python-binance is recommended for production.
Q2: Can ccxt subscribe to WebSockets?
A: The free version of ccxt only supports REST; WebSockets are in ccxt.pro (paid). Open-source alternatives like ccxt-ws exist but are less stable than native python-binance.
Q3: What if I get an APIError: Invalid API-key, IP, or permissions?
A: Three possibilities: 1) Incorrect API Key or Secret; 2) IP whitelist is enabled, but your server IP is not listed; 3) The endpoint's permissions are not checked (e.g., Enable Futures for futures endpoints).
Q4: How can I test the SDK without affecting my real account?
A: Both python-binance and ccxt support the testnet; just pass testnet=True during initialization. Free test funds can be obtained at https://testnet.binance.vision (10,000 USDT).
Q5: Is a connection pool needed for production?
A: Yes. The default requests behavior creates a new TCP connection for every call, adding 20-30ms of latency. Using requests.Session() or aiohttp's TCPConnector(limit=100) keeps connections alive, dropping latency below 5ms.
After reviewing the Python solutions, return to the Category Navigation to check other SDK tutorials in the "API Integration" category.