API Integration

How to Use Binance API with Python: python-binance and ccxt Practical Guide

A complete comparison and practical guide to Binance Python SDKs: python-binance official library, ccxt multi-exchange library, and native aiohttp encapsulation. Includes installation, authentication, ordering, and WebSocket subscription code with performance benchmarks.

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.

Keep reading

Still have Binance questions? Head back to the category page for more tutorials on the same topic.

Categories

Related tutorials

How to Apply for Binance API? Common Guide for Key Generation and Signatures 2026-04-14 How to Use Binance Spot API? Executable Code from Zero to Your First Order 2026-04-14 What are the Differences Between Binance Futures and Spot APIs? Endpoint, Parameter, and Weight Comparison 2026-04-14 Will My IP Get Banned? Detailed Explanation of Binance API Rate Limits and Weights 2026-04-14