Binance Python SDK
Project description
binance-sdk
binance-sdk is an unofficial async Binance SDK for Python 3.11+, supporting three markets: Spot, USDⓈ-M Futures (UMFuturesClient), and COIN-M Futures (CMFuturesClient). It:
- Routes every Spot request/response call over the Binance WebSocket API (
wss://ws-api.binance.com) for low latency, while keeping a genericget/post/put/deleteREST escape hatch for arbitrary endpoints. - Provides full-surface USDⓈ-M Futures (
UMFuturesClient) and COIN-M Futures (CMFuturesClient) clients: market-data (open interest, funding rates, mark price), trading (orders, batch orders, position config), account management, WebSocket market-data streams (mark price, liquidations), and futures user-data streams. - Futures trading endpoints route over the Futures WebSocket API (ws-fapi / ws-dapi) where available; REST otherwise. All signed endpoints require
Credentials. - Returns
volas.DataFrame(fromvolas) for stream payloads with renamed columns. - Uses a first-class
Credentialsobject (SpotClient,UMFuturesClient,CMFuturesClientall accept the sameCredentialsinstance). - Based on Python
async/await. - Manages the order book for you (via
OrderBookHandlerBase), handling WebSocket reconnection and message losses automatically. - Supports changing API endpoints (e.g. for faster regional hosts).
Prices and quantities must be strings. The SDK rejects
floatparams at the API boundary because Python'sstr(float)can produce scientific notation (1e-08) or imprecise decimal representations that silently corrupt price/quantity fields. Pass strings (e.g.price='0.00000001') or format withDecimal.
Install
pip install binance-sdk
Credentials
Credentials is a standalone object that holds an API key plus optional signing material. A single instance may be shared across multiple market clients:
from binance import Credentials, SpotClient, UMFuturesClient, CMFuturesClient
# HMAC (deprecated by Binance; prefer asymmetric keys):
creds = Credentials(api_key='KEY', api_secret='SECRET')
# Asymmetric key (recommended — Ed25519 enables session.logon for zero
# per-request signing overhead):
creds = Credentials(api_key='KEY', private_key='/path/to/ed25519.pem')
# or: private_key=<PEM string or bytes>
# optional: private_key_pass=<bytes> for encrypted PEM
# Share the same creds across markets, or pass different creds per market,
# or pass no creds for public-data-only access:
spot = SpotClient(creds)
um = UMFuturesClient(creds) # USDⓈ-M Futures: trading + account + streams
cm = CMFuturesClient(creds) # COIN-M Futures: trading + account + streams
um_public = UMFuturesClient() # no creds — public market data only
SpotClient
SpotClient provides the full Spot trading surface over the Binance WebSocket API.
Basic usage
import asyncio
from binance import Credentials, SpotClient
creds = Credentials(api_key='KEY', api_secret='SECRET')
spot = SpotClient(creds)
async def main():
print(await spot.get_exchange_info())
asyncio.run(main())
SpotClient(**kwargs)
All arguments are keyword arguments; the first positional argument is an optional Credentials:
- credentials?
Credentials=None— API credentials.Nonecreates an unauthenticated client (public endpoints only). - request_params?
dict=None— global request params for aiohttp (REST escape hatch). - rest_host?
str— REST host for the generic escape hatch. Defaults to'https://api.binance.com'. - stream_host?
str— host for the market-data stream connection. Defaults to'wss://stream.binance.com'. - ws_api_host?
str— host for the shared WS-API connection. Defaults to'wss://ws-api.binance.com/ws-api/v3'. - stream_retry_policy?
RetryPolicy— retry policy for WebSocket streams. See RetryPolicy. - stream_timeout?
int=30— seconds of stream silence before the SDK pings to probe the connection. - rate_limit_guard?
bool=True— whenTrue, proactively throttle requests. WhenFalse, usage is still tracked but requests are never delayed. - rate_limiter?
RateLimiter=None— inject a sharedRateLimiterso multiple clients on the same IP share one IP-level pool. Never share a limiter across markets. - request_timeout?
float=10— total seconds before an aiohttp REST request is abandoned. - recv_window?
int=None— defaultrecvWindow(ms) for signed WS-API requests. Clamped to 60000.Noneuses Binance's server-side default (5000 ms). - time_unit?
str=None— WS-API timestamp unit.Noneor'millisecond'keeps ms default;'microsecond'opts into microsecond precision.
WS-API request methods
Every method is an await-able coroutine. All take keyword arguments matching the Binance WebSocket API parameters and return the parsed result.
General / market-data (public, no credentials):
ping()/get_server_time()/get_exchange_info()get_orderbook(**kwargs)/get_klines(**kwargs)/get_ui_klines(**kwargs)/get_average_price(**kwargs)get_recent_trades(**kwargs)/get_historical_trades(**kwargs)/get_aggregate_trades(**kwargs)get_historical_block_trades(**kwargs)— historical block trades for a symbolget_ticker(**kwargs)/get_ticker_price(**kwargs)/get_orderbook_ticker(**kwargs)get_rolling_window_ticker(**kwargs)— rolling-window price statistics (1m–7d window)get_trading_day_ticker(**kwargs)— trading-day price statistics for a symbol or listget_execution_rules(**kwargs)— per-symbol execution rules (price bands, order limits)get_reference_price(**kwargs)— current reference price for a symbolget_reference_price_calculation(**kwargs)— methodology used to compute the reference price
Account (signed):
get_account(**kwargs)/get_trades(**kwargs)get_commission(**kwargs)— current account commission ratesget_order_rate_limit(**kwargs)— current unfilled order count per order rate limitget_prevented_matches(**kwargs)— orders expired by self-trade preventionget_allocations(**kwargs)— allocations resulting from SOR order placementget_order_amendments(**kwargs)— amendment history for a single orderget_my_filters(**kwargs)— account-relevant filters including MAX_ASSET limits
Trading (signed):
create_order(**kwargs)/create_test_order(**kwargs)get_order(**kwargs)/get_open_orders(**kwargs)/get_all_orders(**kwargs)cancel_order(**kwargs)/cancel_all_orders(**kwargs)cancel_replace_order(**kwargs)— cancel an order and place a new one atomicallyamend_order(**kwargs)— reduce an open order's quantity, keeping its prioritycreate_sor_order(**kwargs)/create_test_sor_order(**kwargs)— Smart Order Routing (live and test)create_oco(**kwargs)/create_oto(**kwargs)/create_otoco(**kwargs)create_opo(**kwargs)— One-Pending-the-Other order listcreate_opoco(**kwargs)— One-Pending-One-Cancels-the-Other order listcancel_oco(**kwargs)/get_oco(**kwargs)/get_all_oco(**kwargs)/get_open_oco(**kwargs)
Session management (the SDK normally manages the session automatically):
get_session_status()— reports which API key is authorizing the current connectionget_session_subscriptions()— lists active user-data subscriptions on the connectionsession_logout()— sendssession.logoutand clears the local auth flag
from binance import (
Credentials, SpotClient,
OrderSide, OrderType, TimeInForce
)
creds = Credentials(api_key='KEY', private_key='/path/to/ed25519.pem')
spot = SpotClient(creds)
# All arguments are keyword arguments.
await spot.create_order(
symbol='BTCUSDT',
side=OrderSide.BUY,
type=OrderType.LIMIT,
timeInForce=TimeInForce.GTC,
# Pass prices and quantities as strings, not Python floats.
quantity='10',
price='7000.1'
)
The client automatically keeps the server-time offset in sync internally — it syncs before the first signed request and re-syncs after any -1021 response — so users never need to manage it.
spot.rate_limit_snapshot() -> RateLimitSnapshot
Returns a read-only, local (no network) RateLimitSnapshot. See Rate Limits.
await spot.get(uri, **kwargs) / post / put / delete
Generic REST escape hatch for arbitrary endpoints not yet covered by the named WS-API methods (e.g. /sapi/ paths). Raises RateLimitException (HTTP 429), IPBannedException (HTTP 418), or StatusException (other non-2xx).
await spot.subscribe(subtype, *subtype_params) / subscribe(*subscriptions)
Subscribe to market-data or user-data WebSocket streams. See SubType (Spot).
spot.handler(*handlers) -> self
Register message handlers for streams. See Handling messages.
spot.start() / spot.stop()
Start or stop receiving stream messages.
await spot.close(code=4999)
Close all stream connections and the shared REST session.
UMFuturesClient (USDⓈ-M Futures)
UMFuturesClient provides the full USDⓈ-M Perpetual Futures surface: market-data, trading, account management, market-data streams, and a futures user-data stream.
from binance import UMFuturesClient, Credentials, SubType
from binance.futures.enums import FuturesOrderType, FuturesTimeInForce
# Public market data — no credentials needed:
um = UMFuturesClient()
oi = await um.get_open_interest(symbol='BTCUSDT')
fr = await um.get_funding_rate(symbol='BTCUSDT', limit=10)
mp = await um.get_premium_index(symbol='BTCUSDT')
# Trading and account — credentials required:
um = UMFuturesClient(Credentials(api_key='KEY', api_secret='SECRET'))
order = await um.create_order(
symbol='BTCUSDT',
side='BUY',
type=FuturesOrderType.LIMIT,
timeInForce=FuturesTimeInForce.GTC,
quantity='0.001',
price='30000',
)
balance = await um.get_balance()
REST market-data methods
All are public (SecurityType.NONE), no credentials required:
get_open_interest(**kwargs)— present open interest for a symbol (weight 1). Required:symbol.get_open_interest_hist(**kwargs)— historical open interest stats (weight 1). Required:symbol,period(one of'5m'/'15m'/'30m'/'1h'/'2h'/'4h'/'6h'/'12h'/'1d'). Optional:limit(default 30, max 500),startTime,endTime.get_funding_rate(**kwargs)— historical funding rate data (weight 1). Optional:symbol,startTime,endTime,limit(default 100, max 1000).get_funding_info(**kwargs)— funding rate cap/floor and interval for all symbols (weight 1).get_premium_index(**kwargs)— mark price, index price, and funding rate (weight 1 withsymbol; 10 for all symbols). Optional:symbol.
Trading & account methods
All signed endpoints require Credentials. Order endpoints (create_order, modify_order, cancel_order, get_order, get_account, get_balance) route over the Futures WebSocket API (wss://ws-fapi.binance.com/ws-fapi/v1). The remaining trading/account/position endpoints use REST (https://fapi.binance.com).
v1 → v2 upgrade:
get_account/get_balancenow use the v2 WS-API methods (v2/account.status,v2/account.balance) which return a richer field set. The v1 methods have been dropped.
Orders:
create_order(**kwargs)— place a new order (WS-API, weight 1).create_test_order(**kwargs)— test-place an order without submitting it (REST, weight 1).modify_order(**kwargs)— modify an existing order (WS-API, weight 1).cancel_order(**kwargs)— cancel an active order (WS-API, weight 1).cancel_all_orders(**kwargs)— cancel all open orders for a symbol (REST, weight 1). Required:symbol.get_order(**kwargs)— check order status (WS-API, weight 1).get_open_orders(**kwargs)— list open orders (REST, weight 1 withsymbol, 40 without).get_all_orders(**kwargs)— list all orders (active, cancelled, filled) for a symbol (REST, weight 5). Required:symbol.create_batch_orders(**kwargs)— place multiple orders in one request (REST, weight 5). Required:batchOrderslist.cancel_batch_orders(**kwargs)— cancel multiple orders in one request (REST, weight 5). Required:symbol, plusorderIdListororigClientOrderIdList.
Account:
get_account(**kwargs)— account status including balances and positions (WS-APIv2/account.status, weight 5).get_balance(**kwargs)— per-asset balance records (WS-APIv2/account.balance, weight 5).get_position(**kwargs)— position information (WS-APIaccount.position, weight 5).get_position_risk(**kwargs)— position risk information (REST, weight 5). Optional:symbol.get_user_trades(**kwargs)— trade history for a symbol (REST, weight 5). Required:symbol.get_commission(**kwargs)— commission rates for a symbol (REST, weight 20). Required:symbol.get_income(**kwargs)— income history (REST, weight 30). Optional:symbol,incomeType,startTime,endTime,limit.get_leverage_bracket(**kwargs)— leverage bracket info (REST, weight 1). Optional:symbol.
Position configuration:
set_leverage(**kwargs)— change initial leverage (REST, weight 1). Required:symbol,leverage.set_margin_type(**kwargs)— change margin type (ISOLATED/CROSSED) for a symbol (REST, weight 1). Required:symbol,marginType.set_position_margin(**kwargs)— adjust isolated position margin (REST, weight 1). Required:symbol,amount,type(1=add, 2=reduce).get_position_mode(**kwargs)— get current position mode (one-way vs hedge) (WS-APIpositionSide.dual.get, weight 30).set_position_mode(**kwargs)— change position mode (REST, weight 1). Required:dualSidePositionbool.get_multi_assets_mode(**kwargs)— get multi-assets margin mode (REST, weight 30). USDⓈ-M only.set_multi_assets_mode(**kwargs)— change multi-assets margin mode (REST, weight 1). USDⓈ-M only.
Algo orders (USDⓈ-M only):
create_algo_order(**kwargs)— place a TWAP or VP algo order (WS-APIalgoOrder.place, weight 0).cancel_algo_order(**kwargs)— cancel an active algo order (WS-APIalgoOrder.cancel, weight 0).
Futures user-data stream
Subscribe to account events (fills, balance changes, margin calls, config changes):
from binance import (
UMFuturesClient, Credentials, SubType,
FuturesAccountUpdateHandlerBase,
FuturesOrderUpdateHandlerBase,
FuturesMarginCallHandlerBase,
FuturesAccountConfigUpdateHandlerBase,
FuturesListenKeyExpiredHandlerBase,
)
um = UMFuturesClient(Credentials(api_key='KEY', api_secret='SECRET'))
class MyOrderUpdate(FuturesOrderUpdateHandlerBase):
def receive(self, payload):
# payload is the raw Binance ORDER_TRADE_UPDATE dict
print(payload['o']['s'], payload['o']['X'])
um.handler(MyOrderUpdate())
await um.subscribe(SubType.USER)
The futures user-data stream uses the listenKey flow: the SDK calls userDataStream.start over the WS-API connection to obtain a listenKey, then opens a dedicated fstream connection for the events (USDⓈ-M: wss://fstream.binance.com/private/ws/<listenKey>; COIN-M: wss://dstream.binance.com/ws/<listenKey>), sends periodic userDataStream.ping keepalives (every 50 min), and automatically re-obtains the key and reconnects on listenKeyExpired. All of this is managed internally. USDⓈ-M's per-category URL split (/public/stream for depth/bookTicker, /market/stream for everything else, /private/ws/<listenKey> for user-data) was mandated by Binance's 2026-04-23 decommission of the legacy /ws and /stream paths and is fully transparent to client code.
Handler bases to subclass (from binance):
FuturesAccountUpdateHandlerBase—ACCOUNT_UPDATE(balance + position snapshot on order/transfer)FuturesOrderUpdateHandlerBase—ORDER_TRADE_UPDATE(order lifecycle: new/partial/filled/cancelled)FuturesMarginCallHandlerBase—MARGIN_CALL(position risk ratio exceeds maintenance margin)FuturesAccountConfigUpdateHandlerBase—ACCOUNT_CONFIG_UPDATE(leverage or multi-assets mode change)FuturesListenKeyExpiredHandlerBase—listenKeyExpired(key expired; SDK auto-recovers)FuturesTradeLiteHandlerBase—TRADE_LITE(low-latency fill; fewer fields thanORDER_TRADE_UPDATE; UM only)FuturesStrategyUpdateHandlerBase—STRATEGY_UPDATE(algo/TWAP strategy lifecycle; UM + CM)FuturesAlgoUpdateHandlerBase—ALGO_UPDATE(algo order status change; UM only; carries conditional-order rejection reasons ino.rmsince 2025-12-10)
Removed (2025-12-10):
FuturesConditionalOrderTriggerRejectHandlerBase/CONDITIONAL_ORDER_TRIGGER_REJECT. Binance migrated conditional orders to the Algo Service; rejection reasons now arrive insideALGO_UPDATE'so.rm(reject_message) field. No backward-compatibility shim — the class is gone frombinance.futures.user_handlersand the top-levelbinancepackage. See the derivatives change-log.
Removed (Round-8 M-5, 2026-05-30):
FuturesGridUpdateHandlerBase/GRID_UPDATE. The Binance docs explicitly mark the event as Deprecated on both UM and CM pages (UM Event-GRID-UPDATE, CM Event-GRID-UPDATE). Per the zero-backward-compatibility policy the class is gone frombinance.futures.user_handlersand the top-levelbinancepackage. Callers that still need grid-strategy lifecycle visibility should subscribe toSTRATEGY_UPDATE(FuturesStrategyUpdateHandlerBase) instead — that event remains documented and live on both UM and CM.
Removed (Round-8 L-2, 2026-05-30):
FuturesEventStreamTerminatedHandlerBase/eventStreamTerminated. The futures user-data-streams docs do NOT list this event — only the Spot user-data-stream docs do (UM user-data-streams index, CM user-data-streams index). Per the strict docs-only policy the class is gone frombinance.futures.user_handlersand the top-levelbinancepackage. The SpotEventStreamTerminatedHandlerBaseis unaffected (Spot docs DO list the event). For the dedicated futures user-data fstream,listenKeyExpiredremains the documented recovery channel — subscribe toFuturesListenKeyExpiredHandlerBaseto observe it.
Futures market-data streams
Both UMFuturesClient and CMFuturesClient support a full set of market-data streams. All handler bases are importable from binance.
Quick example — UM kline stream:
from binance import (
UMFuturesClient, SubType,
FuturesKlineHandlerBase
)
um = UMFuturesClient()
class MyKline(FuturesKlineHandlerBase):
def receive(self, payload):
df = super().receive(payload)
# df columns: type, event_time, open_time, close_time, symbol, interval,
# open, high, low, close, volume, quote_volume,
# taker_volume, taker_quote_volume, total_trades, is_closed
if df['is_closed']:
print(df['symbol'], df['close'])
um.handler(MyKline())
await um.subscribe(SubType.KLINE, 'btcusdt', '1m')
Shared streams (available on both UM and CM):
| SubType | Wire stream | Handler base | Notes |
|---|---|---|---|
SubType.MARK_PRICE |
<symbol>@markPrice[@1s] |
MarkPriceHandlerBase |
Columns: mark_price, mark_price_avg (UM only), index_price, funding_rate, next_funding_time |
SubType.FORCE_ORDER |
<symbol>@forceOrder |
ForceOrderHandlerBase |
Liquidation orders; CM adds pair column |
SubType.AGG_TRADE |
<symbol>@aggTrade |
FuturesAggTradeHandlerBase |
No buyer/seller order IDs (unlike Spot) |
SubType.KLINE |
<symbol>@kline_<interval> |
FuturesKlineHandlerBase |
Accepts TimeFrame or interval string |
SubType.CONTINUOUS_KLINE |
<pair>_<ct>@continuousKline_<interval> |
FuturesContinuousKlineHandlerBase |
Requires pair, contract_type, interval params |
SubType.MINI_TICKER |
<symbol>@miniTicker |
FuturesMiniTickerHandlerBase |
|
SubType.TICKER |
<symbol>@ticker |
FuturesTickerHandlerBase |
|
SubType.BOOK_TICKER |
<symbol>@bookTicker |
FuturesBookTickerHandlerBase |
No e event field; routing by stream name |
SubType.PARTIAL_ORDER_BOOK |
<symbol>@depth<N>[@speed] |
FuturesPartialOrderBookHandlerBase |
Levels: 5/10/20; speed: 100/500 ms; receive returns (bids_df, asks_df) |
SubType.ORDER_BOOK |
<symbol>@depth[@speed] |
FuturesOrderBookHandlerBase |
Diff depth; speed: 100/500 ms |
SubType.CONTRACT_INFO |
!contractInfo |
FuturesContractInfoHandlerBase |
No params; contract spec changes |
SubType.ALL_MARKET_MARK_PRICE |
!markPrice@arr[@1s] |
FuturesAllMarketMarkPriceHandlerBase |
Optional '1s' param; UM subclass adds mark_price_avg |
SubType.ALL_MARKET_LIQUIDATION |
!forceOrder@arr |
FuturesAllMarketLiquidationHandlerBase |
All-market liquidation array; no params |
SubType.ALL_MARKET_MINI_TICKERS |
!miniTicker@arr |
FuturesAllMarketMiniTickersHandlerBase |
No params |
SubType.ALL_MARKET_TICKERS |
!ticker@arr |
FuturesAllMarketTickersHandlerBase |
No params |
SubType.ALL_MARKET_BOOK_TICKER |
!bookTicker |
FuturesAllMarketBookTickerHandlerBase |
No @arr suffix (unlike Spot); no params |
UM-only streams:
| SubType | Wire stream | Handler base | Notes |
|---|---|---|---|
SubType.COMPOSITE_INDEX |
<symbol>@compositeIndex |
CompositeIndexHandlerBase |
Index composition for composite-index symbols |
SubType.ASSET_INDEX |
<asset>@assetIndex or !assetIndex@arr |
AssetIndexHandlerBase / AllAssetIndexHandlerBase |
Multi-assets mode; no params for !assetIndex@arr |
SubType.TRADING_SESSION |
tradingSession |
TradingSessionHandlerBase |
US equity/commodity session events; no params |
CM-only streams:
| SubType | Wire stream | Handler base | Notes |
|---|---|---|---|
SubType.INDEX_PRICE |
<pair>@indexPrice[@1s] |
IndexPriceHandlerBase |
Spot index price for the underlying pair |
SubType.INDEX_PRICE_KLINE |
<pair>@indexPriceKline_<interval> |
IndexPriceKlineHandlerBase |
Index price klines |
SubType.MARK_PRICE_KLINE |
<symbol>@markPriceKline_<interval> |
MarkPriceKlineHandlerBase |
Mark price klines |
Note: COIN-M symbols contain underscores (e.g. 'btcusd_perp'); pass them lowercase to subscribe calls.
UMFuturesClient accepts the same constructor kwargs as SpotClient (see above), plus an optional Credentials first argument.
CMFuturesClient (COIN-M Futures)
CMFuturesClient provides the full COIN-M (coin-margined) Futures surface. The API surface mirrors UMFuturesClient exactly — same method names, same enums — with the following market-specific differences:
- REST host:
https://dapi.binance.com(dapi, not fapi). - Stream host:
wss://dstream.binance.com(dstream, not fstream). - WS-API host:
wss://ws-dapi.binance.com/ws-dapi/v1. - Symbols are contract codes like
'BTCUSD_PERP'(not'BTCUSDT'). get_open_interest_histusespair+contractTypeinstead ofsymbol.get_funding_raterequiressymbol(UM treats it as optional).get_premium_indexacceptssymbolorpair; always returns a list.get_position_riskfilters bymarginAssetorpair(notsymbol).- No
get_multi_assets_mode/set_multi_assets_mode— USDⓈ-M only. - No
create_test_order— COIN-M does not document a "Test New Order" endpoint; that endpoint is UM-Futures-only and Spot-only. - No 10-second ORDERS pool (only 1-minute ORDERS pool).
from binance import CMFuturesClient, Credentials, SubType
from binance.futures.enums import FuturesOrderType, FuturesTimeInForce
# Public market data — no credentials needed:
cm = CMFuturesClient()
oi = await cm.get_open_interest(symbol='BTCUSD_PERP')
fr = await cm.get_funding_rate(symbol='BTCUSD_PERP', limit=10)
oih = await cm.get_open_interest_hist(
pair='BTCUSD', contractType='PERPETUAL', period='1h'
)
mp = await cm.get_premium_index(symbol='BTCUSD_PERP')
# Trading and account — credentials required:
cm = CMFuturesClient(Credentials(api_key='KEY', api_secret='SECRET'))
order = await cm.create_order(
symbol='BTCUSD_PERP',
side='BUY',
type=FuturesOrderType.LIMIT,
timeInForce=FuturesTimeInForce.GTC,
quantity='1', # number of contracts, not base-asset quantity
price='30000',
)
balance = await cm.get_balance()
position = await cm.get_position_risk(pair='BTCUSD')
COIN-M trading & account methods
Same method names as USDⓈ-M (see above). Key differences:
- Order endpoints route over
wss://ws-dapi.binance.com/ws-dapi/v1. - REST endpoints use
https://dapi.binance.com/dapi/v1/…. quantitycounts contracts, not base-asset units.get_account/get_balanceuse v1 WS-API methods (account.status,account.balance) — COIN-M does not have the v2 variants.get_positionis available via WS-APIaccount.position.get_position_modeuses REST (nopositionSide.dual.getWS-API equivalent on COIN-M).- No
create_algo_order/cancel_algo_order(algo orders are USDⓈ-M only). - No
get_multi_assets_mode/set_multi_assets_mode(USDⓈ-M only).
COIN-M user-data stream
from binance import (
CMFuturesClient, Credentials, SubType,
FuturesAccountUpdateHandlerBase,
FuturesOrderUpdateHandlerBase,
FuturesMarginCallHandlerBase,
FuturesAccountConfigUpdateHandlerBase,
FuturesListenKeyExpiredHandlerBase,
)
cm = CMFuturesClient(Credentials(api_key='KEY', api_secret='SECRET'))
class MyCMOrderUpdate(FuturesOrderUpdateHandlerBase):
def receive(self, payload):
print(payload['o']['s'], payload['o']['X'])
cm.handler(MyCMOrderUpdate())
await cm.subscribe(SubType.USER)
Same handler bases and same listenKey flow as USDⓈ-M; events arrive on wss://dstream.binance.com/ws/<listenKey>.
CMFuturesClient accepts the same constructor kwargs as SpotClient.
See the Futures market-data streams table in the USDⓈ-M section for the full stream list; all shared streams and CM-only streams apply. The CM-only streams (SubType.INDEX_PRICE, SubType.INDEX_PRICE_KLINE, SubType.MARK_PRICE_KLINE) are available exclusively on CMFuturesClient.
Futures enums
Import from binance or binance.futures.enums. Use these for futures order parameters. The shared OrderSide (BUY/SELL) is at the top level (from binance import OrderSide).
PositionSide
Position direction for futures orders and positions.
PositionSide.BOTH— one-way (non-hedge) mode: the single net position.PositionSide.LONG— hedge mode long position.PositionSide.SHORT— hedge mode short position.
FuturesOrderType
Futures order execution type (extends Spot OrderType).
FuturesOrderType.LIMITFuturesOrderType.MARKETFuturesOrderType.STOP— stop-limit (triggered bystopPrice; requiresprice)FuturesOrderType.STOP_MARKET— stop-market (triggered bystopPrice)FuturesOrderType.TAKE_PROFIT— take-profit limit (triggered bystopPrice; requiresprice)FuturesOrderType.TAKE_PROFIT_MARKET— take-profit market (triggered bystopPrice)FuturesOrderType.TRAILING_STOP_MARKET— trailing-stop market (activated bycallbackRate)
FuturesTimeInForce
Time-in-force values for futures orders (extends Spot TimeInForce).
FuturesTimeInForce.GTC— Good Till CancelledFuturesTimeInForce.IOC— Immediate Or CancelFuturesTimeInForce.FOK— Fill Or KillFuturesTimeInForce.GTX— Good Till Crossing (post-only)FuturesTimeInForce.GTD— Good Till Date (expires atgoodTillDate)FuturesTimeInForce.RPI— Retail Price Improvement
WorkingType
Price type used to trigger conditional (stop/take-profit) orders.
WorkingType.MARK_PRICE— use the mark price (default for most stop orders)WorkingType.CONTRACT_PRICE— use the last traded price
MarginType
Margin mode for a futures position.
MarginType.ISOLATED— each position has its own isolated marginMarginType.CROSSED— all available balance is used as shared margin
Handling messages
binance-sdk provides handler-based APIs for all WebSocket messages.
from binance import SpotClient, Credentials, TickerHandlerBase, SubType
creds = Credentials(api_key='KEY')
spot = SpotClient(creds)
async def main():
class TickerPrinter(TickerHandlerBase):
async def receive(self, payload):
# `ticker_df` is a volas.DataFrame with columns renamed
ticker_df = super().receive(payload)
print(ticker_df)
spot.handler(TickerPrinter())
await spot.subscribe(SubType.TICKER, 'BTCUSDT')
loop = asyncio.get_event_loop()
loop.run_until_complete(main())
loop.run_forever()
Subscribe to more symbol pairs and types
# Subscribe to bnbusdt@aggTrade, bnbusdt@depth, bnbbtc@aggTrade, bnbbtc@depth
await spot.subscribe(
[SubType.AGG_TRADE, SubType.ORDER_BOOK],
['BNB_USDT', 'BNBBTC']
)
Subscribe to user streams
# Credentials must include api_key; asymmetric key enables session.logon.
await spot.subscribe(SubType.USER)
Subscribe to handler exceptions
from binance import HandlerExceptionHandlerBase, KlineHandlerBase
class KlineHandler(KlineHandlerBase):
def receive(self, payload):
raise RuntimeError('this will ruin my day')
class HandlerExceptionHandler(HandlerExceptionHandlerBase):
async def receive(self, exception):
super().receive(exception) # prints the stack
await send_to_monitor(exception)
spot.handler(KlineHandler())
spot.handler(HandlerExceptionHandler())
# Or just print error stacks with the default:
spot.handler(HandlerExceptionHandlerBase())
Handle stream-control errors (resubscribe / logon failures)
After a WebSocket reconnect the SDK automatically replays all subscriptions. If that replay (or session.logon) fails, the SDK logs it, calls receive on every registered StreamErrorHandlerBase, and schedules a recycle() on the affected stream.
from binance import StreamErrorHandlerBase
class MyStreamErrors(StreamErrorHandlerBase):
async def receive(self, error):
# error.stream -> 'data' | 'user'
# error.phase -> 'resubscribe' | 'logon'
# error.exception -> the underlying exception
# error.recovering -> True (SDK is recycling the stream)
await alert_ops_team(
f"Stream {error.stream!r} {error.phase} failed: {error.exception}"
)
spot.handler(MyStreamErrors())
APIs
SubType (Spot)
Spot SpotClient streams. Pass as the first argument to client.subscribe(subtype, ...).
SubType with parameters symbol and interval
SubType.KLINESubType.KLINE_UTC8
And interval should be one of the TimeFrame enumerables.
SubTypes with a param symbol
SubType.TRADESubType.AGG_TRADESubType.BLOCK_TRADESubType.REFERENCE_PRICESubType.BOOK_TICKERSubType.AVG_PRICESubType.MINI_TICKERSubType.TICKERSubType.ORDER_BOOK
SubTypes with params symbol and level
SubType.PARTIAL_ORDER_BOOK(levelshould be one of5,10,20)
SubTypes with an optional param updateInterval=1000 (ms)
SubType.ORDER_BOOK(1000or100)SubType.PARTIAL_ORDER_BOOK(symbol,level, optionalinterval:1000or100)
SubTypes with an optional param window=TimeFrame.H1
SubType.WINDOW_TICKER(withsymbol; one ofTimeFrame.H1/H4/D1)SubType.ALL_MARKET_WINDOW_TICKERS(one ofTimeFrame.H1/H4/D1)
SubTypes with no param
SubType.ALL_MARKET_MINI_TICKERSSubType.USER
!ticker@arr(SubType.ALL_MARKET_TICKERS) is not supported on Spot. The Binance Spot WebSocket Streams docs do NOT document a standalone!ticker@arr(only!miniTicker@arrand!ticker_<window-size>@arr). UseSubType.ALL_MARKET_WINDOW_TICKERSfor the documented all-market full-ticker variant on Spot. The same SubType is supported on Futures (see the Futures all-market streams section), where Binance documents!ticker@arrfor both USDⓈ-M and COIN-M.
!bookTicker@arris not supported. Binance has deprecated this stream; use per-symbolSubType.BOOK_TICKERinstead.
Full multi-subscribe example
from binance import SubType, TimeFrame
await spot.subscribe(SubType.TICKER, 'BNBUSDT')
await spot.subscribe(SubType.BOOK_TICKER, 'BNBUSDT')
await spot.subscribe(SubType.AVG_PRICE, 'BNBUSDT')
await spot.subscribe(SubType.WINDOW_TICKER, 'BNBUSDT', TimeFrame.H1)
await spot.subscribe(SubType.PARTIAL_ORDER_BOOK, 'BNBUSDT', 20)
await spot.subscribe(SubType.ALL_MARKET_MINI_TICKERS)
await spot.subscribe(SubType.ALL_MARKET_WINDOW_TICKERS, TimeFrame.H4)
# Multiple at once
await spot.subscribe(
(SubType.KLINE, 'BTC_USDT', TimeFrame.D1),
(SubType.KLINE_UTC8, 'BTC_USDT', TimeFrame.D1),
(SubType.TICKER, 'BNBUSDT'),
(
[SubType.ORDER_BOOK, SubType.TRADE],
['BNBUSDT', 'BTCUSDT']
),
(SubType.ALL_MARKET_MINI_TICKERS,) # <-- note the trailing comma
)
Spot stream handler bases:
TradeHandlerBaseAggTradeHandlerBaseBlockTradeHandlerBaseReferencePriceHandlerBaseBookTickerHandlerBasePartialOrderBookHandlerBaseAvgPriceHandlerBaseWindowTickerHandlerBaseOrderBookHandlerBaseKlineHandlerBaseMiniTickerHandlerBaseTickerHandlerBaseAllMarketMiniTickersHandlerBaseAllMarketWindowTickersHandlerBaseAccountPositionHandlerBaseBalanceUpdateHandlerBaseOrderUpdateHandlerBaseOrderListStatusHandlerBaseExternalLockUpdateHandlerBaseEventStreamTerminatedHandlerBaseHandlerExceptionHandlerBase— handles exceptions raised inside other handlersStreamErrorHandlerBase— handles resubscribe/logon failures after reconnect
SubType (Futures)
Futures streams are available on both UMFuturesClient and CMFuturesClient.
Per-symbol streams (UM + CM)
SubType.MARK_PRICE—<symbol>@markPrice[@1s]; optional'1s'param; handler:MarkPriceHandlerBase(addsmark_price_avgon UM)SubType.FORCE_ORDER—<symbol>@forceOrder; handler:ForceOrderHandlerBase(addspairon CM)SubType.AGG_TRADE—<symbol>@aggTrade; handler:FuturesAggTradeHandlerBaseSubType.KLINE—<symbol>@kline_<interval>; params:symbol,interval; handler:FuturesKlineHandlerBaseSubType.CONTINUOUS_KLINE—<pair>_<ct>@continuousKline_<interval>; params:pair,contract_type,interval; handler:FuturesContinuousKlineHandlerBaseSubType.MINI_TICKER—<symbol>@miniTicker; handler:FuturesMiniTickerHandlerBaseSubType.TICKER—<symbol>@ticker; handler:FuturesTickerHandlerBaseSubType.BOOK_TICKER—<symbol>@bookTicker; handler:FuturesBookTickerHandlerBase(noefield)SubType.PARTIAL_ORDER_BOOK—<symbol>@depth<N>[@<speed>ms]; params:symbol,level(5/10/20), optionalspeed(100/500); handler:FuturesPartialOrderBookHandlerBaseSubType.ORDER_BOOK—<symbol>@depth[@<speed>ms]; params:symbol, optionalspeed(100/500); handler:FuturesOrderBookHandlerBase
All-market streams (UM + CM, no params)
SubType.ALL_MARKET_MARK_PRICE—!markPrice@arr[@1s]; optional'1s'param; handler:FuturesAllMarketMarkPriceHandlerBaseSubType.ALL_MARKET_LIQUIDATION—!forceOrder@arr; handler:FuturesAllMarketLiquidationHandlerBaseSubType.ALL_MARKET_MINI_TICKERS—!miniTicker@arr; handler:FuturesAllMarketMiniTickersHandlerBaseSubType.ALL_MARKET_TICKERS—!ticker@arr; handler:FuturesAllMarketTickersHandlerBaseSubType.ALL_MARKET_BOOK_TICKER—!bookTicker(no@arrsuffix); handler:FuturesAllMarketBookTickerHandlerBaseSubType.CONTRACT_INFO—!contractInfo; handler:FuturesContractInfoHandlerBase
UM-only streams
SubType.COMPOSITE_INDEX—<symbol>@compositeIndex; handler:CompositeIndexHandlerBaseSubType.ASSET_INDEX—<asset>@assetIndexor!assetIndex@arr; handlers:AssetIndexHandlerBase/AllAssetIndexHandlerBaseSubType.TRADING_SESSION—tradingSession; no params; handler:TradingSessionHandlerBase
CM-only streams
SubType.INDEX_PRICE—<pair>@indexPrice[@1s]; handler:IndexPriceHandlerBaseSubType.INDEX_PRICE_KLINE—<pair>@indexPriceKline_<interval>; handler:IndexPriceKlineHandlerBaseSubType.MARK_PRICE_KLINE—<symbol>@markPriceKline_<interval>; handler:MarkPriceKlineHandlerBase
SubType.USER — futures user-data stream
- No params required.
- Available on
UMFuturesClientandCMFuturesClientwhenCredentialsare provided. - Uses the listenKey flow (see Futures user-data stream above); not the Spot
userDataStream.subscribeflow.
Possible subscribe exceptions (both markets):
InvalidSubParamsExceptionUnsupportedSubTypeExceptionInvalidSubTypeParamExceptionStreamAbandonedException
RetryPolicy
Retry policy determines what to do after a stream connection failure.
abandon, delay = stream_retry_policy(info)
# `info.fails` — how many times the stream has failed (1 on first failure)
# `info.exception` — the exception that caused the failure
# If abandon is True, the client gives up reconnecting.
# Otherwise, the client waits `delay` seconds before reconnecting.
Since 3.2.0 the default policy is a bounded, jittered exponential backoff (≈0.5 s → 30 s, never abandoning).
Rate Limits
binance-sdk tracks and respects Binance's documented rate limits to avoid the 429 → 418 IP-ban escalation.
Each client has its own per-market rate limiter. Spot and Futures rate limits are independent server-side. A shared RateLimiter may be injected via the rate_limiter= constructor argument only within the same market (never across Spot and Futures).
The pools
| Pool | Scope | Default budget | On exceed (guard on) |
|---|---|---|---|
| Request weight | IP | 6000 / 1m (used at 90% → 5400) | sleep until headroom |
| Raw requests | IP | 300000 / 5m | sleep until headroom |
| Orders | account | 100 / 10s and 200000 / 1d | raise RateLimitReachedException |
| WS connections | IP | 290 / 5m | sleep until headroom |
| WS messages | per connection | 5 / 1s | sleep until headroom |
| WS streams | per connection | 1024 (cap) | raise TooManyStreamsException |
Orders never sleep — delaying an order can be worse than not sending it, so an over-budget order fails fast with RateLimitReachedException (carrying retry_after) and lets your strategy decide. Usage is always accounted (even with the guard off), so monitoring stays accurate.
WS-API: typed errors from trading/account/market-data calls
StreamSubscribeException— any server-side error (code/msgfields match the Binance WS-API error object).StreamRateLimitException(subclass ofStreamSubscribeException) — rate-limit rejection (code-1003, status429/418); carriesretry_afterin milliseconds.
from binance import StreamSubscribeException, StreamRateLimitException
try:
await spot.create_order(symbol='BTCUSDT', side='BUY', ...)
except StreamRateLimitException as e:
await asyncio.sleep(e.retry_after / 1000)
except StreamSubscribeException as e:
print(f'WS-API error {e.code}: {e.msg}')
REST escape hatch: typed errors
from binance import RateLimitException, IPBannedException, StatusException
try:
await spot.get('https://api.binance.com/sapi/v1/...')
except IPBannedException as e:
await asyncio.sleep(e.retry_after)
except RateLimitException as e:
await asyncio.sleep(e.retry_after)
except StatusException as e:
print(f'HTTP {e.status_code}: {e.response}')
Both RateLimitException and IPBannedException subclass StatusException. The client never auto-retries — it surfaces retry_after and lets your strategy decide.
REST: used-weight visibility
await spot.get('https://api.binance.com/api/v3/exchangeInfo')
spot.used_weight # e.g. {'1m': 20} (from X-MBX-USED-WEIGHT-*)
spot.order_count # e.g. {'10s': 3} (from X-MBX-ORDER-COUNT-*)
Monitoring: client.rate_limit_snapshot()
rate_limit_snapshot() returns a read-only, local (no network) RateLimitSnapshot:
snap = spot.rate_limit_snapshot()
snap.max_utilization # 0.0–1.0+, the busiest pool right now
snap.throttled # True if anything is queued/sleeping or a retry-after is active
snap.retry_after # seconds remaining on a 429/418 ban, or None
snap.pending # total calls currently waiting on a pool
for w in snap.windows:
print(w.scope, w.type, w.interval, f'{w.used}/{w.limit}', w.utilization, w.source)
# e.g. ip request_weight 1m 5400/5400 1.0 header
A RateLimitWindow describes one pool: scope (ip/account/connection), type (request_weight/raw_requests/orders/ws_connections/ws_messages/ws_streams), interval (1m, 10s, …), used, limit (the effective, safety-adjusted cap), remaining, utilization (used/limit), pending, and source — header when reconciled from an authoritative Binance header, otherwise client. RateLimitSnapshot exposes windows, pending, retry_after, throttled, at (epoch seconds), and max_utilization. Both types are importable from binance.
WebSocket: connection, message, and stream limits
- Connections are gated to stay under Binance's 300 attempts / 5 min / IP limit (default cap 290/5 min).
- Outgoing messages are limited to 5/second (including subscribe/unsubscribe and ping/pong).
- Streams per connection are capped at 1024; exceeding it raises
TooManyStreamsException(carryingrequested/limit). serverShutdownevents trigger a proactive reconnect ~10 min before Binance's 24 h forced disconnect.
OrderBookHandlerBase(**kwargs)
- kwargs
- limit?
int=1000— snapshot depth (default 1000, max 5000) - retry_policy?
RetryPolicy
- limit?
OrderBookHandlerBase maintains the order book according to the official documentation, handling reconnection and message-loss automatically.
async def main():
spot = SpotClient(Credentials(api_key='KEY'))
handler = OrderBookHandlerBase()
spot.handler(handler)
await spot.subscribe(SubType.ORDER_BOOK, 'BTCUSDT')
# Get the reference of the managed OrderBook for 'BTCUSDT'
orderbook = handler.orderbook('BTCUSDT')
while True:
try:
await orderbook.updated()
except Exception as e:
print('exception occurred')
else:
await doSomethingWith(orderbook.asks, orderbook.bids)
handler.orderbook(symbol, limit=...) returns (and optionally configures the snapshot depth for) the OrderBook object for a symbol. Per-symbol override defaults to the handler-level limit.
OrderBook(symbol, **kwargs)
- symbol
str - kwargs
- limit?
int=1000 - client
SpotClient=None - retry_policy?
RetryPolicy
- limit?
async def main():
orderbook = OrderBook('BTCUSDT', client=spot)
await orderbook.updated()
print(orderbook.asks)
orderbook.set_client(client) / set_limit(limit) / set_retry_policy(retry_policy)
Configure the orderbook after construction.
property orderbook.ready -> bool
False while a new snapshot is being fetched after a detected gap.
property orderbook.asks / orderbook.bids -> list
Ask and bid levels in ascending order.
await orderbook.updated()
Wait for the next update. Raises an aiohttp exception if the snapshot fetch is abandoned by the retry_policy.
Upgrading from v3.x
Breaking change: from binance import Client has been removed. Replace it with SpotClient + Credentials:
# Before (v3.x):
from binance import Client
client = Client(api_key='KEY', api_secret='SECRET')
# After (v4.0):
from binance import Credentials, SpotClient
creds = Credentials(api_key='KEY', api_secret='SECRET')
client = SpotClient(creds)
Constructor kwargs api_key, api_secret, private_key, and private_key_pass have moved into Credentials. All other constructor kwargs (stream_retry_policy, rate_limit_guard, rate_limiter, etc.) remain on the client constructor, unchanged.
Testing
The default pytest test/ suite is fully hermetic — it only talks to local mock servers and never reaches the real Binance endpoints, so it is safe to run on any network (including CI) without credentials.
Live smoke tests
A small opt-in suite at test/test_live.py exercises real Binance endpoints (Spot / UM / CM stream + WS-API time, plus a Spot get_account if API_KEY / API_SECRET are configured in .env / .env.*). All live tests are skipped by default — set BINANCE_LIVE=1 to enable:
BINANCE_LIVE=1 pytest test/test_live.py -v
Live tests do NOT place orders or modify any account state. Binance geo-blocks some regions / cloud-provider IPs (HTTP 451) — the suite fails fast on unreachable hosts so you can diagnose connectivity early. On a network that requires an HTTP/SOCKS proxy to reach Binance, also set BINANCE_LIVE_TEST=1 so the test session preserves your proxy environment variables (see test/conftest.py).
License
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file binance_sdk-7.0.1.tar.gz.
File metadata
- Download URL: binance_sdk-7.0.1.tar.gz
- Upload date:
- Size: 373.2 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.12.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
1dbd07dceab45b8fee9399816f4e09167f45f381ea47e77f1b9080df0f827947
|
|
| MD5 |
66d6655a6fbcded0eeaf5156596aeab1
|
|
| BLAKE2b-256 |
8d8f99824e555d98459492a548d1b8d6d06cf7cae8363ff4cfbe43bc41a0edaa
|
File details
Details for the file binance_sdk-7.0.1-py3-none-any.whl.
File metadata
- Download URL: binance_sdk-7.0.1-py3-none-any.whl
- Upload date:
- Size: 240.1 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.12.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
9594167dc4a2bc65c4d52448c08a7f5e2581afe77215207866097d12c327ccce
|
|
| MD5 |
d586d0f63b1cf05dbd2913098a3b5cb7
|
|
| BLAKE2b-256 |
2a73d49acf2e94aeaf5a848c3f6d697f8c0a656e166c36dd550d1bfb09028892
|