Binance API Documentation Futures: Complete Trading Guide
Master the Binance Futures API with practical Python examples. Learn authentication, order placement, position management, and real-time market data streaming for algorithmic trading.
Table of Contents
The Binance Futures API opens the door to programmatic trading on one of the largest derivatives exchanges in crypto. Whether you're building a trading bot, backtesting strategies, or pulling market data into your own analytics pipeline, understanding the binance api documentation futures is the first real step toward serious algorithmic trading.
I've spent years working with exchange APIs, and Binance's futures endpoints are among the most comprehensive available. But the official docs can feel overwhelming โ hundreds of endpoints, rate limits, signature requirements, and edge cases buried in footnotes. This guide cuts through the noise and gets you trading programmatically with working code you can run today.
Getting Started: API Keys and Authentication
Before touching any code, you need API credentials. Head to your Binance account, navigate to API Management, and create a new key. For futures trading, you must explicitly enable "Futures" permissions on the key. If you're just experimenting, start with the binance futures testnet api documentation at testnet.binancefuture.com โ it gives you free test funds and identical endpoints without risking real capital.
Every authenticated request to the Binance Futures API requires an HMAC SHA256 signature. The signature is computed over the query string parameters using your secret key. Here's the foundation you'll build everything else on:
import os
import time
import hmac
import hashlib
import requests
from urllib.parse import urlencode
API_KEY = os.environ['BINANCE_API_KEY']
API_SECRET = os.environ['BINANCE_API_SECRET']
# Use testnet for development
BASE_URL = 'https://testnet.binancefuture.com' # Production: https://fapi.binance.com
def signed_request(method, endpoint, params=None):
if params is None:
params = {}
params['timestamp'] = int(time.time() * 1000)
params['recvWindow'] = 5000
query_string = urlencode(params)
signature = hmac.new(
API_SECRET.encode('utf-8'),
query_string.encode('utf-8'),
hashlib.sha256
).hexdigest()
params['signature'] = signature
headers = {'X-MBX-APIKEY': API_KEY}
if method == 'GET':
response = requests.get(f'{BASE_URL}{endpoint}', params=params, headers=headers)
else:
response = requests.post(f'{BASE_URL}{endpoint}', params=params, headers=headers)
if response.status_code != 200:
raise Exception(f'API Error {response.status_code}: {response.json()}')
return response.json()
# Test: fetch account info
account = signed_request('GET', '/fapi/v2/account')
print(f"Total Wallet Balance: {account['totalWalletBalance']} USDT")
print(f"Available Balance: {account['availableBalance']} USDT")
This helper function handles timestamp injection, signature generation, and error checking. Every authenticated call in the rest of this guide builds on it. The recvWindow parameter gives you a 5-second tolerance for clock drift between your server and Binance โ increase it if you're running on hardware with unreliable time sync.
Core Endpoints: Market Data and Order Placement
The binance futures api docs organize endpoints into three categories: market data (public, no auth needed), account/trade (requires signature), and WebSocket streams (real-time). Let's hit the ones you'll use daily.
Market data endpoints don't require authentication. You can pull order books, recent trades, klines, and ticker data without any API key at all:
# Public market data โ no authentication required
def get_klines(symbol, interval='1h', limit=100):
"""Fetch candlestick data for backtesting or analysis."""
response = requests.get(f'{BASE_URL}/fapi/v1/klines', params={
'symbol': symbol,
'interval': interval,
'limit': limit
})
return response.json()
def get_orderbook(symbol, limit=20):
"""Fetch current order book depth."""
response = requests.get(f'{BASE_URL}/fapi/v1/depth', params={
'symbol': symbol,
'limit': limit
})
return response.json()
# Fetch 4-hour candles for BTCUSDT
candles = get_klines('BTCUSDT', '4h', 500)
for c in candles[-3:]:
open_time, o, h, l, close, volume = c[0], c[1], c[2], c[3], c[4], c[5]
print(f"O: {o} | H: {h} | L: {l} | C: {close} | Vol: {volume}")
# Fetch top of book
book = get_orderbook('ETHUSDT', 5)
print(f"Best bid: {book['bids'][0][0]} | Best ask: {book['asks'][0][0]}")
For placing orders, you need the signed request function from earlier. Binance Futures supports market, limit, stop-market, stop-limit, trailing stop, and take-profit orders. Here's how to place the most common types:
def place_order(symbol, side, order_type, quantity, price=None, stop_price=None):
params = {
'symbol': symbol,
'side': side, # BUY or SELL
'type': order_type, # MARKET, LIMIT, STOP_MARKET, TAKE_PROFIT_MARKET
'quantity': quantity,
}
if price:
params['price'] = price
params['timeInForce'] = 'GTC'
if stop_price:
params['stopPrice'] = stop_price
return signed_request('POST', '/fapi/v1/order', params)
# Market order โ immediate execution
order = place_order('BTCUSDT', 'BUY', 'MARKET', 0.01)
print(f"Filled at avg price: {order['avgPrice']}")
# Limit order โ passive, waits for price
order = place_order('BTCUSDT', 'BUY', 'LIMIT', 0.01, price='60000.00')
print(f"Limit order placed: {order['orderId']}")
# Stop-loss โ triggers when price drops to stop level
order = place_order('BTCUSDT', 'SELL', 'STOP_MARKET', 0.01, stop_price='58000.00')
print(f"Stop-loss set: {order['orderId']}")
# Cancel an open order
def cancel_order(symbol, order_id):
return signed_request('DELETE', '/fapi/v1/order', {
'symbol': symbol,
'orderId': order_id
})
result = cancel_order('BTCUSDT', order['orderId'])
print(f"Cancelled: {result['status']}")
Position Management and Leverage Control
Managing positions properly is what separates a working bot from a margin-call generator. The binance api documentation futures covers leverage, margin type, and position mode endpoints that you need to configure before your first trade.
| Endpoint | Method | Purpose |
|---|---|---|
| /fapi/v1/leverage | POST | Set leverage (1-125x) per symbol |
| /fapi/v1/marginType | POST | Switch ISOLATED / CROSSED margin |
| /fapi/v2/positionRisk | GET | Current open positions and unrealized PnL |
| /fapi/v1/positionSide/dual | POST | Enable/disable hedge mode |
| /fapi/v1/allOpenOrders | DELETE | Cancel all open orders for a symbol |
# Set leverage before opening a position
def set_leverage(symbol, leverage):
return signed_request('POST', '/fapi/v1/leverage', {
'symbol': symbol,
'leverage': leverage
})
# Set margin type (do this once per symbol)
def set_margin_type(symbol, margin_type='ISOLATED'):
try:
return signed_request('POST', '/fapi/v1/marginType', {
'symbol': symbol,
'marginType': margin_type # ISOLATED or CROSSED
})
except Exception as e:
# Returns error if already set to this type โ safe to ignore
if 'No need to change' in str(e):
return None
raise
# Get all open positions with PnL
def get_positions():
positions = signed_request('GET', '/fapi/v2/positionRisk')
# Filter to only positions with non-zero quantity
return [p for p in positions if float(p['positionAmt']) != 0]
# Setup and check
set_leverage('ETHUSDT', 10)
set_margin_type('ETHUSDT', 'ISOLATED')
for pos in get_positions():
symbol = pos['symbol']
size = pos['positionAmt']
pnl = pos['unRealizedProfit']
entry = pos['entryPrice']
print(f"{symbol}: size={size} entry={entry} uPnL={pnl} USDT")
Real-Time Data with WebSocket Streams
REST endpoints are fine for placing orders and checking state, but for real-time price feeds and order updates, you need WebSocket streams. Binance Futures offers individual streams and a combined stream endpoint. The most useful ones for trading bots are the mark price stream, kline stream, and the user data stream for order/position updates.
import json
import websocket
import threading
WS_BASE = 'wss://fstream.binance.com' # Testnet: wss://stream.binancefuture.com
def on_message(ws, message):
data = json.loads(message)
event = data.get('e', '')
if event == 'kline':
k = data['k']
if k['x']: # Candle closed
print(f"[{k['s']}] {k['i']} candle closed: O={k['o']} H={k['h']} L={k['l']} C={k['c']}")
elif event == 'markPriceUpdate':
print(f"[{data['s']}] Mark: {data['p']} | Funding: {data['r']}")
def start_stream(streams):
"""Connect to combined WebSocket stream."""
stream_path = '/'.join(streams)
url = f"{WS_BASE}/stream?streams={stream_path}"
ws = websocket.WebSocketApp(
url,
on_message=on_message,
on_error=lambda ws, e: print(f"WS Error: {e}"),
on_close=lambda ws, code, msg: print("WS Closed โ reconnecting...")
)
thread = threading.Thread(target=ws.run_forever, daemon=True)
thread.start()
return ws
# Subscribe to BTC 1m candles and ETH mark price
ws = start_stream([
'btcusdt@kline_1m',
'ethusdt@markPrice@1s'
])
For private account updates (fills, position changes, margin calls), you need a listenKey from the user data stream endpoint. This key expires every 60 minutes, so your bot needs to send a keepalive PUT request periodically โ miss it and you'll stop getting fill notifications silently.
Rate Limits and Error Handling
This is where most beginners get burned. Binance enforces strict rate limits on the Futures API, and exceeding them results in IP bans ranging from minutes to days. The binance futures api docs specify weight-based limits: each endpoint costs a certain number of weight units, and you get 2400 weight per minute for most endpoints.
| Endpoint | Weight | Notes |
|---|---|---|
| /fapi/v1/klines | 5-10 | Depends on limit param |
| /fapi/v1/depth | 5-20 | Depends on limit param |
| /fapi/v1/order (POST) | 1 | Order placement is cheap |
| /fapi/v2/account | 5 | Full account snapshot |
| /fapi/v2/positionRisk | 5 | All positions |
Check the X-MBX-USED-WEIGHT-1M response header after every request to track your usage. Build rate limiting into your request layer from day one โ retrofitting it after your first IP ban is painful:
- Monitor X-MBX-USED-WEIGHT-1M header on every response
- Back off exponentially when you hit 80% of the limit
- Use WebSocket streams instead of polling REST endpoints for real-time data
- Cache market data responses โ order book snapshots don't need refreshing every 100ms
- Handle HTTP 429 (rate limited) and 418 (IP ban) gracefully with automatic backoff
- Implement request queues with per-second throttling for burst protection
From API Calls to Trading Strategy
Having working API code is step one. The harder part is deciding when to call it. Raw market data from the Binance Futures API gives you the building blocks, but profitable trading requires signal generation, risk management, and execution logic on top.
Platforms like VoiceOfChain can complement your API-based setup by providing real-time trading signals that you can feed directly into your bot's decision engine. Instead of building signal generation from scratch โ which requires significant backtesting and validation โ you can use external signal sources as one input alongside your own technical indicators. The API handles execution; the signal source handles when to execute.
- Start on the testnet โ the binance futures testnet api documentation covers identical endpoints with zero financial risk
- Build and test one strategy at a time; don't parallelize until your core execution loop is bulletproof
- Log every API response, not just errors โ you'll need the data for debugging edge cases at 3 AM
- Implement a kill switch: a simple way to cancel all orders and close all positions immediately
- Monitor funding rates via the API โ they're a cost that erodes returns on positions held across funding intervals
- Always calculate position size from your account balance, never hardcode quantities
Conclusion
The Binance Futures API is one of the most powerful tools available to crypto traders who want to go beyond manual chart-watching. The binance api documentation futures covers everything from basic market data to complex order types, but the real learning happens when you start writing code against it.
Start with the testnet, nail your authentication and error handling, respect rate limits religiously, and build up from simple market orders to full strategy execution. The code examples in this guide are production-ready foundations โ extend them, break them on the testnet, and iterate. That's how every successful trading bot starts.