ZenCex.Adapters.Binance.Parser (zen_cex v0.2.1)
View SourceBinance response parser implementing the ZenCex.Behaviors.Parser contract.
Parses Binance-specific JSON responses and normalizes them to common formats used throughout the ZenCex library. Handles type conversions, null fields, and follows pure error pass-through philosophy.
Supported Response Types
- Positions: Spot and futures position data
- Balances: Account balance information
- Orders: Order placement and query responses
Error Handling
All errors are returned unchanged as {:error, raw_response} where raw_response
is the complete Binance response map. This preserves all original error context
including codes, messages, and any additional fields.
Common Error Codes (Reference Only)
Binance uses negative integer error codes. These are documented for reference - actual errors are passed through unchanged:
- -1121: Invalid symbol
- -2010: Insufficient balance
- -1013: Invalid quantity/precision
- -1022: Invalid signature
- -1102: Mandatory parameter missing
- 429: Rate limit exceeded
Response Normalization
The parser applies minimal transformation to exchange responses:
- Keys: Normalized to snake_case atoms (e.g.,
"orderId"→:order_id) - Values: Kept as-is from API (strings for numbers, integers for IDs, booleans)
- Enums: Status/side/type values converted to lowercase atoms (e.g.,
"BUY"→:buy)
Users are responsible for type conversions (e.g., Decimal.new(price) for calculations).
Summary
Functions
Parses account information from Binance Futures API.
Parses Binance balance responses into normalized format.
Parses batch cancel response from the Binance API.
Parses Binance error responses into normalized error atoms.
Parses commission/fee responses from the Binance API.
Generic parser for simple Binance API responses.
Parses income/transaction history from Binance Futures API.
Parses WebSocket market data (NOT IMPLEMENTED).
Parses market data API responses.
Parses One-Cancels-Other (OCO) order response from the Binance API.
Parses Binance order responses into normalized format.
Parses a list of orders from the Binance API.
Parses Binance position responses into normalized format.
Parses server time response from the Binance API.
Parses trade history responses from the Binance API.
Functions
Parses account information from Binance Futures API.
Handles both v2 and v3 account information responses which contain account balances, positions, and configuration.
Examples
response = %{
"feeTier" => 0,
"canTrade" => true,
"canDeposit" => true,
"canWithdraw" => true,
"updateTime" => 1234567890000,
"totalInitialMargin" => "0.00000000",
"totalMaintMargin" => "0.00000000",
"totalWalletBalance" => "10000.00000000",
"totalUnrealizedProfit" => "0.00000000",
"totalMarginBalance" => "10000.00000000",
"totalPositionInitialMargin" => "0.00000000",
"totalOpenOrderInitialMargin" => "0.00000000",
"totalCrossWalletBalance" => "10000.00000000",
"totalCrossUnPnl" => "0.00000000",
"availableBalance" => "10000.00000000",
"maxWithdrawAmount" => "10000.00000000",
"assets" => [
%{
"asset" => "USDT",
"walletBalance" => "10000.00000000",
"unrealizedProfit" => "0.00000000",
"marginBalance" => "10000.00000000",
"maintMargin" => "0.00000000",
"initialMargin" => "0.00000000",
"positionInitialMargin" => "0.00000000",
"openOrderInitialMargin" => "0.00000000",
"maxWithdrawAmount" => "10000.00000000",
"crossWalletBalance" => "10000.00000000",
"crossUnPnl" => "0.00000000",
"availableBalance" => "10000.00000000"
}
],
"positions" => []
}
{:ok, account} = parse_account(response)
Parses Binance balance responses into normalized format.
Examples
# Spot/Margin format with "balances" key
response = %{
"balances" => [
%{
"asset" => "BTC",
"free" => "0.5",
"locked" => "0.1"
},
%{
"asset" => "USDT",
"free" => "1000",
"locked" => "500"
}
]
}
{:ok, balances} = parse_balances(response)
# Futures V3 format - direct array
response = [
%{
"accountAlias" => "SgsR",
"asset" => "USDT",
"balance" => "122607.35137903",
"crossWalletBalance" => "23.72469206",
"crossUnPnl" => "0.00000000",
"availableBalance" => "23.72469206",
"maxWithdrawAmount" => "23.72469206",
"marginAvailable" => true,
"updateTime" => 1617939110373
}
]
{:ok, balances} = parse_balances(response)
Parses batch cancel response from the Binance API.
Returns a list of results where each element is either
{:ok, order} for successful cancellations or
{:error, error_info} for failed cancellations.
Examples
response = [
%{"orderId" => 123, "status" => "CANCELED"},
%{"code" => -2011, "msg" => "Unknown order"}
]
{:ok, results} = parse_batch_cancel_response(response)
Parses Binance error responses into normalized error atoms.
Examples
# Standard error format
response = %{"code" => -2010, "msg" => "Account has insufficient balance"}
{:error, {:binance_error, -2010, "Account has insufficient balance"}} = parse_error(response)
# Rate limit error (special case - still mapped for rate limiting logic)
response = %{"code" => 429, "msg" => "Too many requests"}
{:error, :rate_limited} = parse_error(response)
# Filter failure
response = %{"code" => -1013, "msg" => "Filter failure: PERCENT_PRICE_BY_SIDE"}
{:error, {:binance_error, -1013, "Filter failure: PERCENT_PRICE_BY_SIDE"}} = parse_error(response)
Parses commission/fee responses from the Binance API.
Handles both decimal strings and basis points formats:
- Decimal strings ("0.001"): Used in symbol-specific commission rates
- Basis points (10 = 0.001%): Used in account-wide commission settings where 1 basis point = 0.0001 (10 bps = 10/10000 = 0.001)
Examples
# Symbol-specific commission rates (decimal strings)
response = %{
"symbol" => "BTCUSDT",
"makerCommission" => "0.001",
"takerCommission" => "0.001"
}
{:ok, fees} = parse_fees(response)
# Account-wide commission rates (basis points)
response = %{
"makerCommission" => 10, # 10 basis points = 0.001
"takerCommission" => 10, # 10 basis points = 0.001
"buyerCommission" => 0,
"sellerCommission" => 0
}
{:ok, fees} = parse_fees(response)
Generic parser for simple Binance API responses.
Used for endpoints like ping, time, openOrders, and other endpoints that return simple data structures or lists that don't need special processing.
Examples
# Ping response (empty object)
response = %{}
{:ok, %{}} = parse_generic(response)
# Server time response
response = %{"serverTime" => 1234567890000}
{:ok, response} = parse_generic(response)
# List of orders
response = [%{"orderId" => 123, "symbol" => "BTCUSDT"}]
{:ok, response} = parse_generic(response)
Parses income/transaction history from Binance Futures API.
Returns a list of income records including trading fees, funding fees, realized PnL, and other transaction types.
Examples
response = [
%{
"symbol" => "BTCUSDT",
"incomeType" => "REALIZED_PNL",
"income" => "100.50000000",
"asset" => "USDT",
"time" => 1234567890000,
"info" => "trade id",
"tranId" => 987654321,
"tradeId" => "123456"
},
%{
"symbol" => "BTCUSDT",
"incomeType" => "FUNDING_FEE",
"income" => "-0.50000000",
"asset" => "USDT",
"time" => 1234567890000,
"info" => "",
"tranId" => 987654322,
"tradeId" => ""
}
]
{:ok, income_history} = parse_income(response)
Parses WebSocket market data (NOT IMPLEMENTED).
This function is part of the Parser behavior but WebSocket support is explicitly out of scope for this REST-only library.
Always returns {:error, :not_implemented}.
Parses market data API responses.
Market data responses from Binance can be:
- Single objects (ticker, average price)
- Arrays of objects (klines, trades, order book)
- Objects with nested arrays (exchange info)
Examples
iex> parse_market_data_response(%{"symbol" => "BTCUSDT", "price" => "50000.00"})
{:ok, %{"symbol" => "BTCUSDT", "price" => "50000.00"}}
iex> parse_market_data_response([%{"symbol" => "BTCUSDT", "price" => "50000.00"}])
{:ok, [%{"symbol" => "BTCUSDT", "price" => "50000.00"}]}
Parses One-Cancels-Other (OCO) order response from the Binance API.
Examples
response = %{
"orderListId" => 123,
"orders" => [
%{"orderId" => 456, "side" => "BUY", "type" => "LIMIT"},
%{"orderId" => 789, "side" => "BUY", "type" => "STOP_LOSS_LIMIT"}
],
"listOrderStatus" => "EXECUTING",
"transactionTime" => 1234567890000
}
{:ok, oco} = parse_oco_response(response)
Parses Binance order responses into normalized format.
Examples
response = %{
"symbol" => "BTCUSDT",
"orderId" => 123456,
"clientOrderId" => "my_order_1",
"side" => "BUY",
"type" => "LIMIT",
"price" => "50000",
"origQty" => "0.1",
"status" => "FILLED",
"transactTime" => 1234567890
}
{:ok, order} = parse_order(response)
Parses a list of orders from the Binance API.
Examples
response = [
%{
"symbol" => "BTCUSDT",
"orderId" => 123456,
"side" => "BUY",
"type" => "LIMIT",
"status" => "FILLED"
}
]
{:ok, orders} = parse_orders_list(response)
Parses Binance position responses into normalized format.
Supported Formats
- Spot account info with balances
- Futures position risk data
- Portfolio margin positions
Examples
# Spot balances (treated as positions)
response = %{
"balances" => [
%{
"asset" => "BTC",
"free" => "0.5",
"locked" => "0.1"
}
]
}
{:ok, positions} = parse_positions(response)
# Futures positions
response = [
%{
"symbol" => "BTCUSDT",
"positionSide" => "LONG",
"positionAmt" => "0.5",
"entryPrice" => "50000",
"markPrice" => "51000",
"unRealizedProfit" => "500",
"isolatedMargin" => "5000",
"updateTime" => 1234567890
}
]
{:ok, positions} = parse_positions(response)
Parses server time response from the Binance API.
Examples
response = %{"serverTime" => 1234567890000}
{:ok, %{server_time: 1234567890000}} = parse_server_time(response)
Parses trade history responses from the Binance API.
Examples
response = [
%{
"symbol" => "BTCUSDT",
"id" => 123456,
"orderId" => 789,
"price" => "50000.00",
"qty" => "0.1",
"quoteQty" => "5000.00",
"commission" => "0.001",
"commissionAsset" => "BTC",
"time" => 1234567890000,
"isBuyer" => true,
"isMaker" => false
}
]
{:ok, trades} = parse_trades(response)