Binance SDK
Complete reference for ctx.binance — programmatic trading on Binance from worker code.
Binance APIs
This SDK wraps the Binance Spot v3 and USDⓈ-M Futures v1 REST APIs through one unified ctx.binance adapter. Live, demo, and testnet environments all supported.
Setup
- Add a Binance trading block to your workspace canvas.
- Open the inspector → API Keys → pick a key (Settings → API Keys → Binance to add new).
- Choose Market Type:
spotorfutures(USDⓈ-M). - Connect the block to your Worker block via an edge.
ctx.binanceis now available in the worker.
def tick(ctx):
px = float(ctx.binance.get_ticker("BTCUSDT")["lastPrice"])
ctx.log.info(f"BTC: {px}")If no Binance block is connected:
RuntimeError: No trading block connected. Connect a Binance block to this worker.Markets & Modes
The market_type is configured on the block (and stored on the API key); methods that don't take an explicit override use it. Override per call where indicated.
market_type | Endpoint host | Description |
|---|---|---|
spot | api.binance.com | Spot trading |
futures | fapi.binance.com | USDⓈ-M perpetuals & futures |
Account modes (api_mode on key):
| Mode | Endpoint | Notes |
|---|---|---|
live | production | Real funds |
demo | demo-api.binance.com / demo-fapi.binance.com | Paper-trading, real prices |
testnet | testnet.binance.vision / testnet.binancefuture.com | Sandbox, synthetic data |
Market Data
get_ticker
24-hour ticker (last price, bid, ask, change, volume).
ctx.binance.get_ticker(symbol: str = "BTCUSDT") -> dictReturns: {"symbol", "lastPrice", "bidPrice", "askPrice", "priceChange", "priceChangePercent", "volume", "quoteVolume", ...}
t = ctx.binance.get_ticker("BTCUSDT")
last = float(t["lastPrice"])
change_pct = float(t["priceChangePercent"])WebSocket cache
PRO/MAX plans return cached ticker data at 0ms latency from the live WS stream — no REST call.
get_klines
OHLCV candlestick data.
ctx.binance.get_klines(
symbol: str = "BTCUSDT",
interval: str = "1h",
limit: int = 500,
start_time: int = None,
end_time: int = None,
market_type: str = None,
) -> listinterval | Values |
|---|---|
| Minutes | "1m", "3m", "5m", "15m", "30m" |
| Hours | "1h", "2h", "4h", "6h", "8h", "12h" |
| Larger | "1d", "3d", "1w", "1M" |
Returns: [[open_time, open, high, low, close, volume, close_time, quote_volume, trades, ...]] — 12 fields per candle.
candles = ctx.binance.get_klines("BTCUSDT", interval="1h", limit=24)
closes = [float(c[4]) for c in candles]
sma_24h = sum(closes) / len(closes)get_orderbook
Order book depth.
ctx.binance.get_orderbook(
symbol: str = "BTCUSDT",
limit: int = 20, # 5 / 10 / 20 / 50 / 100 / 500 / 1000
market_type: str = None,
) -> dictReturns: {"lastUpdateId", "bids": [[price, size]], "asks": [[price, size]]}
ob = ctx.binance.get_orderbook("BTCUSDT", limit=20)
best_bid = float(ob["bids"][0][0])
best_ask = float(ob["asks"][0][0])
spread_bps = (best_ask - best_bid) / best_bid * 10000get_recent_trades
Last public trades.
ctx.binance.get_recent_trades(symbol: str = "BTCUSDT", limit: int = 100, market_type: str = None) -> listget_book_ticker
Best bid + ask (single symbol or all).
ctx.binance.get_book_ticker(symbol: str = None, market_type: str = None) -> dictget_avg_price
5-minute volume-weighted average price (spot only). Useful for slippage calculations.
ctx.binance.get_avg_price(symbol: str = "BTCUSDT") -> dictReturns: {"mins": 5, "price": "67234.12"}
get_mark_price
Mark price + funding (futures).
ctx.binance.get_mark_price(symbol: str = None) -> dict | listReturns (single symbol): {"symbol", "markPrice", "indexPrice", "estimatedSettlePrice", "lastFundingRate", "interestRate", "nextFundingTime", "time"}
get_funding_rate
Historical funding rate for perpetuals.
ctx.binance.get_funding_rate(
symbol: str = "BTCUSDT",
limit: int = 100,
start_time: int = None,
end_time: int = None,
market_type: str = None,
) -> listget_funding_info
Current funding rate info for all symbols.
ctx.binance.get_funding_info() -> listget_open_interest
Current open interest for a symbol.
ctx.binance.get_open_interest(symbol: str = "BTCUSDT") -> dictget_long_short_ratio
Long/short ratio across all accounts.
ctx.binance.get_long_short_ratio(
symbol: str = "BTCUSDT",
period: str = "5m", # "5m" | "15m" | "30m" | "1h" | "2h" | "4h" | "6h" | "12h" | "1d"
limit: int = 30,
) -> listget_top_trader_ratio
Long/short ratio specifically for top traders (more predictive).
ctx.binance.get_top_trader_ratio(symbol, period, limit) -> listget_taker_volume
Buy vs sell taker volume — short-term flow direction.
ctx.binance.get_taker_volume(symbol, period, limit) -> listget_basis
Futures basis (premium / discount vs spot).
ctx.binance.get_basis(
pair: str = "BTCUSDT",
contract_type: str = "PERPETUAL", # "PERPETUAL" | "CURRENT_QUARTER" | "NEXT_QUARTER"
period: str = "5m",
limit: int = 30,
) -> listget_liquidation_orders
Recent forced liquidations on the futures market.
ctx.binance.get_liquidation_orders(symbol: str = None, limit: int = 50) -> listAccount & Wallet
get_account
Account info (balances + permissions for spot, balances + positions for futures).
ctx.binance.get_account() -> dictTIP
Auto-routes to /api/v3/account (spot) or /fapi/v2/account (futures) based on the block's market type.
get_futures_balance
Balances on the USDⓈ-M Futures wallet (always futures, even if block is spot).
ctx.binance.get_futures_balance() -> listget_account_snapshot
Daily account snapshots — last 30 days. Useful for plotting equity curves.
ctx.binance.get_account_snapshot(
account_type: str = "SPOT", # "SPOT" | "MARGIN" | "FUTURES"
limit: int = 7,
start_time: int = None,
end_time: int = None,
) -> dictget_commission_rate
Maker/taker commission for your tier on a symbol.
ctx.binance.get_commission_rate(symbol: str = "BTCUSDT") -> dictget_income_history
Realized PnL, funding, fees, transfers (futures account ledger).
ctx.binance.get_income_history(
symbol: str = None,
income_type: str = None, # TRANSFER | WELCOME_BONUS | REALIZED_PNL | FUNDING_FEE | COMMISSION | …
start_time: int = None,
end_time: int = None,
limit: int = 100,
) -> listPositions & Risk
get_positions
Open futures positions (auto-filtered to non-zero size).
ctx.binance.get_positions(symbol: str = None) -> dictWebSocket cache
PRO/MAX: cached from private WS stream at 0ms.
get_position_mode
Returns whether the account is in one-way or hedge (dual-side) mode.
ctx.binance.get_position_mode() -> dictset_position_mode
Switch between one-way and hedge mode (requires no open positions).
ctx.binance.set_position_mode(dual_side: bool = False) -> dictset_leverage
Set leverage (1-125x depending on symbol).
ctx.binance.set_leverage(symbol: str, leverage: int) -> dictset_margin_type
Switch isolated ↔ cross margin.
ctx.binance.set_margin_type(symbol: str, margin_type: str = "CROSSED") -> dict
# margin_type: "CROSSED" | "ISOLATED"get_leverage_brackets
Notional-tier brackets that determine max leverage at each position size.
ctx.binance.get_leverage_brackets(symbol: str = None) -> listadjust_isolated_margin
Add or remove margin from an isolated position.
ctx.binance.adjust_isolated_margin(
symbol: str,
amount: str,
type: int, # 1 = ADD, 2 = REDUCE
position_side: str = "BOTH", # "BOTH" | "LONG" | "SHORT"
) -> dictOrders
place_order
Place a spot or futures order (auto-routes by block's market type).
ctx.binance.place_order(
symbol: str,
side: str, # "BUY" | "SELL"
qty: str, # quantity as string
order_type: str = "MARKET", # "MARKET" | "LIMIT" | "STOP" | "TAKE_PROFIT" | "STOP_MARKET" | "TAKE_PROFIT_MARKET"
price: str = None, # required for LIMIT
) -> dict# Spot market buy
r = ctx.binance.place_order("BTCUSDT", "BUY", "0.001", "MARKET")
# Futures limit short with TP/SL via subsequent calls
ctx.binance.set_leverage("BTCUSDT", 5)
r = ctx.binance.place_order("BTCUSDT", "SELL", "0.01", "LIMIT", "70000")spot_oco_order
Spot OCO (One-Cancels-Other): atomically place a take-profit limit + stop-loss stop-limit. When one fills, the other is auto-cancelled.
ctx.binance.spot_oco_order(
symbol: str,
side: str, # "BUY" | "SELL"
quantity,
price, # take-profit limit price
stop_price, # stop trigger price
stop_limit_price, # limit price after stop trigger
stop_limit_time_in_force: str = "GTC",
list_client_order_id: str = None,
limit_client_order_id: str = None,
stop_client_order_id: str = None,
) -> dict# After buying 0.01 BTC at 65000, set OCO: TP at 70000, SL at 63000 (limit 62800)
ctx.binance.spot_oco_order(
symbol="BTCUSDT", side="SELL", quantity="0.01",
price="70000",
stop_price="63000", stop_limit_price="62800",
)cancel_order
Cancel a single order by ID.
ctx.binance.cancel_order(symbol: str, order_id: int) -> dictfutures_modify_order
Modify an unfilled futures order (qty + price).
ctx.binance.futures_modify_order(
symbol: str,
order_id: int,
quantity: str = None,
price: str = None,
) -> dictfutures_batch_orders
Place up to 5 futures orders atomically.
ctx.binance.futures_batch_orders(orders: list) -> listfutures_cancel_all
Cancel ALL open futures orders for a symbol.
ctx.binance.futures_cancel_all(symbol: str) -> dictspot_cancel_all
Cancel ALL open spot orders for a symbol.
ctx.binance.spot_cancel_all(symbol: str) -> listcountdown_cancel_all
Dead-man's switch — auto-cancel all orders for a symbol if not refreshed within countdown_time ms. Set to 0 to disable.
ctx.binance.countdown_cancel_all(symbol: str, countdown_time: int = 10000) -> dict# Refresh every tick — if worker stops, orders auto-cancel after 30 seconds
def tick(ctx):
ctx.binance.countdown_cancel_all("BTCUSDT", countdown_time=30000)
# … rest of strategyget_orders
Active (unfilled) orders.
ctx.binance.get_orders(symbol: str = None) -> dictWebSocket cache
PRO/MAX: cached from private WS stream at 0ms.
get_query_order
Status of a single order.
ctx.binance.get_query_order(symbol: str, order_id: int, market_type: str = None) -> dictget_all_orders
Full order history (active + filled + cancelled + rejected).
ctx.binance.get_all_orders(symbol: str = "BTCUSDT", limit: int = 100, market_type: str = None) -> listget_trade_history
Filled trades with fees (the actual transactions).
ctx.binance.get_trade_history(symbol: str = "BTCUSDT", limit: int = 100, market_type: str = None) -> listCommon Patterns
Demo / testnet
Set the API-key mode in Settings → API Keys → Binance to demo or testnet. All calls auto-route to the right environment. Note: Binance demo (paper-trading) has more realistic data than testnet.
Error handling
def tick(ctx):
try:
positions = ctx.binance.get_positions()
except Exception as e:
ctx.log.error(f"Binance unreachable: {e}")
returnBinanceAPIError (extends ExchangeAPIError) is raised for API errors with code and msg attributes. Network failures raise httpx.HTTPStatusError.
Cloud-Run proxy
PRO+ workers route Binance traffic through a Cloud Run proxy with rotating exit IPs to dodge rate-limit concentration. Transparent — no code changes.
WebSocket caching
PRO+ subscribes to public + private streams in the background. Methods get_ticker, get_account, get_positions, get_orders auto-prefer the cache when fresh.
Recipes
DCA on hourly close
def setup(ctx):
ctx.state.set("last_buy_hour", -1)
def tick(ctx):
import time
hour = int(time.time() // 3600)
if hour == ctx.state.get("last_buy_hour", -1):
return
# Use 5-min VWAP for slippage-aware sizing
avg = float(ctx.binance.get_avg_price("BTCUSDT")["price"])
qty = round(50 / avg, 5) # $50 worth
r = ctx.binance.place_order("BTCUSDT", "BUY", str(qty), "MARKET")
ctx.state.set("last_buy_hour", hour)
ctx.log.info(f"DCA: {qty} BTC at ~{avg} → {r}")Spot entry with auto OCO exit
def tick(ctx):
# Only enter when not already holding
acct = ctx.binance.get_account()
btc = next((b for b in acct.get("balances", []) if b["asset"] == "BTC"), None)
if btc and float(btc["free"]) >= 0.001:
return
px = float(ctx.binance.get_ticker("BTCUSDT")["lastPrice"])
# Buy 0.001 BTC at market
ctx.binance.place_order("BTCUSDT", "BUY", "0.001", "MARKET")
# Set OCO: +5% take-profit, -2% stop-loss (limit 0.5% beyond)
ctx.binance.spot_oco_order(
symbol="BTCUSDT", side="SELL", quantity="0.001",
price=str(round(px * 1.05, 2)),
stop_price=str(round(px * 0.98, 2)),
stop_limit_price=str(round(px * 0.975, 2)),
)
ctx.log.info(f"Entered at {px} with OCO exit")Futures momentum with countdown safety
def setup(ctx):
ctx.binance.set_leverage("BTCUSDT", 5)
def tick(ctx):
# Activate dead-man switch — orders cancel if worker dies for 30s
ctx.binance.countdown_cancel_all("BTCUSDT", countdown_time=30000)
# Check 1h trend via SMA
candles = ctx.binance.get_klines("BTCUSDT", interval="1h", limit=24)
closes = [float(c[4]) for c in candles]
sma = sum(closes) / len(closes)
last = closes[-1]
pos = ctx.binance.get_positions("BTCUSDT")
has_long = any(float(p.get("positionAmt", 0)) > 0 for p in pos)
if last > sma * 1.005 and not has_long:
ctx.binance.place_order("BTCUSDT", "BUY", "0.01", "MARKET")
ctx.log.info(f"Long entry: {last} > SMA {sma:.2f}")
elif last < sma * 0.995 and has_long:
ctx.binance.place_order("BTCUSDT", "SELL", "0.01", "MARKET")
ctx.log.info(f"Exit: {last} < SMA {sma:.2f}")Reference
| Binance endpoint | SDK method | Market |
|---|---|---|
GET /api/v3/ticker/24hr /fapi/v1/ticker/24hr | get_ticker | both |
GET /api/v3/avgPrice | get_avg_price | spot |
GET /api/v3/depth /fapi/v1/depth | get_orderbook | both |
GET /api/v3/klines /fapi/v1/klines | get_klines | both |
GET /api/v3/trades /fapi/v1/trades | get_recent_trades | both |
GET /api/v3/ticker/bookTicker /fapi/v1/ticker/bookTicker | get_book_ticker | both |
GET /fapi/v1/premiumIndex | get_mark_price | futures |
GET /fapi/v1/fundingRate | get_funding_rate | futures |
GET /fapi/v1/fundingInfo | get_funding_info | futures |
GET /fapi/v1/openInterest | get_open_interest | futures |
GET /futures/data/globalLongShortAccountRatio | get_long_short_ratio | futures |
GET /futures/data/topLongShortPositionRatio | get_top_trader_ratio | futures |
GET /futures/data/takerlongshortRatio | get_taker_volume | futures |
GET /futures/data/basis | get_basis | futures |
GET /fapi/v1/forceOrders | get_liquidation_orders | futures |
GET /api/v3/account /fapi/v2/account | get_account | both |
GET /fapi/v2/balance | get_futures_balance | futures |
GET /sapi/v1/accountSnapshot | get_account_snapshot | spot/margin/futures |
GET /fapi/v1/commissionRate | get_commission_rate | futures |
GET /fapi/v1/income | get_income_history | futures |
GET /fapi/v2/positionRisk | get_positions | futures |
GET /fapi/v1/positionSide/dual | get_position_mode | futures |
POST /fapi/v1/positionSide/dual | set_position_mode | futures |
POST /fapi/v1/leverage | set_leverage | futures |
POST /fapi/v1/marginType | set_margin_type | futures |
GET /fapi/v1/leverageBracket | get_leverage_brackets | futures |
POST /fapi/v1/positionMargin | adjust_isolated_margin | futures |
POST /api/v3/order /fapi/v1/order | place_order | both |
POST /api/v3/order/oco | spot_oco_order | spot |
DELETE /api/v3/order /fapi/v1/order | cancel_order | both |
PUT /fapi/v1/order | futures_modify_order | futures |
POST /fapi/v1/batchOrders | futures_batch_orders | futures |
DELETE /fapi/v1/allOpenOrders | futures_cancel_all | futures |
DELETE /api/v3/openOrders | spot_cancel_all | spot |
POST /fapi/v1/countdownCancelAll | countdown_cancel_all | futures |
GET /api/v3/openOrders /fapi/v1/openOrders | get_orders | both |
GET /api/v3/order /fapi/v1/order | get_query_order | both |
GET /api/v3/allOrders /fapi/v1/allOrders | get_all_orders | both |
GET /api/v3/myTrades /fapi/v1/userTrades | get_trade_history | both |