# Bitrue Exchange Specification # # Auto-generated by: mix ccxt.extract bitrue # CCXT version: 4.5.34 # Spec format version: 1 # # Review before use: # - signing: Detected from sign() method, verify with testnet # - endpoints: Raw paths extracted, map to unified API as needed # - exceptions: Extracted (exact, broad, HTTP status codes) # - features/options: Extracted from describe() # - classification: Set to :supported initially, promote after validation # %{ api_param_requirements: nil, certified: false, classification: :pro, comment: nil, countries: [ "SG" ], currencies: %{}, currency_aliases: %{ "BCHSV" => "BSV", "MIM" => "MIM Swarm", "XBT" => "BTC" }, dex: false, enable_rate_limit: true, endpoint_extraction_stats: %{ "capturedMethods" => 30, "coveragePercent" => 100, "enabledMethods" => 36, "excluded" => [ %{ "method" => "setMargin", "reason" => "symbol.endsWith is not a function" }, %{ "method" => "editOrder", "reason" => "emulated (returns cached data, no HTTP call)" }, %{ "method" => "fetchDepositWithdrawFee", "reason" => "emulated (returns cached data, no HTTP call)" } ], "excludedMethods" => 3, "extractableMethods" => 33, "failures" => [ %{ "error" => "bitrue cancelAllOrders only support future markets", "method" => "cancelAllOrders" }, %{ "error" => "bitrue createMarketBuyOrderWithCost() supports swap orders only", "method" => "createMarketBuyOrderWithCost" }, %{ "error" => "bitrue createOrder() requires the price argument with swap market buy orders to calculate total order cost (amount to spend), where cost = amount * price. Supply a price argument to createOrder() call if you want the cost to be calculated for you from price and amount, or, alternatively, add .options[\"createMarketBuyOrderRequiresPrice\"] = false to supply the cost in the amount argument (the exchange-specific behaviour)", "method" => "createStopMarketOrder" } ] }, endpoints: [ %{ api_section: "spot/v1/private", auth: true, cost: 5, market_type: :spot, method: :delete, name: :cancel_order, param_mappings: %{ "id" => "orderId" }, params: [ :id, :symbol ], path: "/order", response_transformer: {:extract_path, ["data"]}, source: :intercepted }, %{ api_section: "spot/v1/private", auth: true, cost: 5, default_params: %{ "type" => "LIMIT" }, market_type: :spot, method: :post, name: :create_limit_order, param_mappings: %{ "amount" => "quantity" }, params: [ :symbol, :side, :amount, :price ], path: "/order", response_transformer: {:extract_path, ["data"]}, source: :intercepted }, %{ api_section: "spot/v1/private", auth: true, cost: 5, default_params: %{ "type" => "MARKET" }, market_type: :spot, method: :post, name: :create_market_order, param_mappings: %{ "amount" => "quantity" }, params: [ :symbol, :side, :amount, :price ], path: "/order", response_transformer: {:extract_path, ["data"]}, source: :intercepted }, %{ api_section: "spot/v1/private", auth: true, cost: 5, market_type: :spot, method: :post, name: :create_order, param_mappings: %{ "amount" => "quantity" }, params: [ :symbol, :type, :side, :amount, :price ], path: "/order", response_transformer: {:extract_path, ["data"]}, source: :intercepted }, %{ api_section: "fapi/v2/private", auth: true, cost: 25, default_params: %{ "contractName" => "BTCUSDT", "leverage" => 1, "open" => "CLOSE", "positionType" => 1 }, market_type: :swap, method: :post, name: :create_reduce_only_order, param_mappings: %{ "amount" => "volume" }, params: [ :symbol, :type, :side, :amount, :price ], path: "/order", response_transformer: {:extract_path, ["data"]}, source: :intercepted }, %{ api_section: "fapi/v2/private", auth: true, cost: 25, default_params: %{ "contractName" => "BTCUSDT", "leverage" => 1, "open" => "OPEN", "positionType" => 1, "triggerDirection" => "below", "type" => "LIMIT" }, market_type: :swap, method: :post, name: :create_stop_limit_order, param_mappings: %{ "amount" => "volume", "triggerPrice" => "stopPrice" }, params: [ :symbol, :side, :amount, :price, :triggerPrice ], path: "/order", response_transformer: {:extract_path, ["data"]}, source: :intercepted }, %{ api_section: "fapi/v2/private", auth: true, cost: 25, default_params: %{ "contractName" => "BTCUSDT", "leverage" => 1, "open" => "OPEN", "positionType" => 1, "triggerDirection" => "below" }, market_type: :swap, method: :post, name: :create_stop_order, param_mappings: %{ "amount" => "volume", "triggerPrice" => "stopPrice" }, params: [ :symbol, :type, :side, :amount, :price, :triggerPrice ], path: "/order", response_transformer: {:extract_path, ["data"]}, source: :intercepted }, %{ api_section: "spot/v1/private", auth: true, cost: 25, market_type: :spot, method: :get, name: :fetch_balance, param_mappings: %{}, params: [], path: "/account", response_transformer: {:extract_path, ["data"]}, source: :intercepted }, %{ api_section: "spot/v1/public", auth: false, cost: 0.24, default_params: %{ "symbol" => "BTCUSDT" }, market_type: :spot, method: :get, name: :fetch_bids_asks, param_mappings: %{}, params: [ :symbols ], path: "/ticker/bookTicker", response_transformer: {:extract_path, ["data"]}, source: :intercepted }, %{ api_section: "spot/v1/private", auth: true, cost: 25, market_type: :spot, method: :get, name: :fetch_closed_orders, param_mappings: %{}, params: [ :symbol, :since, :limit ], path: "/allOrders", response_transformer: {:extract_path, ["data"]}, source: :intercepted }, %{ api_section: "spot/v1/public", auth: false, cost: 0.24, market_type: :spot, method: :get, name: :fetch_currencies, param_mappings: %{}, params: [], path: "/exchangeInfo", response_transformer: {:extract_path, ["coins"]}, source: :intercepted }, %{ api_section: "spot/v1/public", auth: false, cost: 0.24, market_type: :spot, method: :get, name: :fetch_deposit_withdraw_fees, param_mappings: %{}, params: [ :codes ], path: "/exchangeInfo", response_transformer: {:extract_path, ["coins"]}, source: :intercepted }, %{ api_section: "spot/v1/private", auth: true, cost: 120, default_params: %{ "status" => 1 }, market_type: :spot, method: :get, name: :fetch_deposits, param_mappings: %{ "code" => "coin" }, params: [ :code, :since, :limit ], path: "/deposit/history", response_transformer: {:extract_path, ["data"]}, source: :intercepted }, %{ api_section: "spot/v1/public", auth: false, cost: 1, market_type: :spot, method: :get, name: :fetch_l2_order_book, param_mappings: %{}, params: [ :symbol, :limit ], path: "/depth", response_transformer: {:extract_path, ["data"]}, source: :intercepted }, %{ api_section: "spot/v1/public", auth: false, cost: 0.24, market_type: :spot, method: :get, name: :fetch_markets, param_mappings: %{}, params: [], path: "/exchangeInfo", response_transformer: {:extract_path, ["data"]}, source: :intercepted }, %{ api_section: "spot/v2/private", auth: true, cost: 1.2, market_type: :spot, method: :get, name: :fetch_my_trades, param_mappings: %{}, params: [ :symbol, :since, :limit ], path: "/myTrades", response_transformer: {:extract_path, ["data"]}, source: :intercepted }, %{ api_section: "spot/v1/public", auth: false, cost: 0.24, market_type: :spot, method: :get, name: :fetch_ohlcv, param_mappings: %{ "timeframe" => "scale" }, params: [ :symbol, :timeframe, :since, :limit ], path: "/market/kline", response_transformer: {:extract_path, ["data"]}, source: :intercepted }, %{ api_section: "spot/v1/private", auth: true, cost: 5, market_type: :spot, method: :get, name: :fetch_open_orders, param_mappings: %{}, params: [ :symbol, :since, :limit ], path: "/openOrders", response_transformer: {:extract_path, ["data"]}, source: :intercepted }, %{ api_section: "spot/v1/private", auth: true, cost: 5, market_type: :spot, method: :get, name: :fetch_order, param_mappings: %{ "id" => "orderId" }, params: [ :id, :symbol ], path: "/order", response_transformer: {:extract_path_unwrap, ["data"]}, source: :intercepted }, %{ api_section: "spot/v1/public", auth: false, cost: 1, market_type: :spot, method: :get, name: :fetch_order_book, param_mappings: %{}, params: [ :symbol, :limit ], path: "/depth", response_transformer: {:extract_path_unwrap, ["data"]}, source: :intercepted }, %{ api_section: "spot/v1/public", auth: false, cost: 0.24, market_type: :spot, method: :get, name: :fetch_status, param_mappings: %{}, params: [], path: "/ping", response_transformer: {:extract_path, ["data"]}, source: :intercepted }, %{ api_section: "spot/v1/public", auth: false, cost: 0.24, market_type: :spot, method: :get, name: :fetch_ticker, param_mappings: %{}, params: [ :symbol ], path: "/ticker/24hr", response_transformer: {:extract_path_unwrap, ["data"]}, source: :intercepted }, %{ api_section: "spot/v1/public", auth: false, cost: 0.24, market_type: :spot, method: :get, name: :fetch_tickers, param_mappings: %{}, params: [ :symbols ], path: "/ticker/24hr", response_transformer: {:extract_path, ["data"]}, source: :intercepted }, %{ api_section: "spot/v1/public", auth: false, cost: 0.24, market_type: :spot, method: :get, name: :fetch_time, param_mappings: %{}, params: [], path: "/time", response_transformer: {:extract_path, ["serverTime"]}, source: :intercepted }, %{ api_section: "spot/v1/public", auth: false, cost: 0.24, market_type: :spot, method: :get, name: :fetch_trades, param_mappings: %{}, params: [ :symbol, :since, :limit ], path: "/trades", response_transformer: {:extract_path, ["data"]}, source: :intercepted }, %{ api_section: "fapi/v2/private", auth: true, cost: 5, market_type: :spot, method: :get, name: :fetch_transfers, param_mappings: %{ "code" => "coinSymbol" }, params: [ :code, :since, :limit ], path: "/futures_transfer_history", response_transformer: {:extract_path, ["data"]}, source: :intercepted }, %{ api_section: "spot/v1/private", auth: true, cost: 120, default_params: %{ "status" => 5 }, market_type: :spot, method: :get, name: :fetch_withdrawals, param_mappings: %{ "code" => "coin" }, params: [ :code, :since, :limit ], path: "/withdraw/history", response_transformer: {:extract_path, ["data"]}, source: :intercepted }, %{ api_section: "fapi/v2/private", auth: true, cost: 5, default_params: %{ "contractName" => "BTCUSDT" }, market_type: :swap, method: :post, name: :set_leverage, param_mappings: %{}, params: [ :leverage, :symbol ], path: "/level_edit", response_transformer: {:extract_path, ["data"]}, source: :intercepted }, %{ api_section: "fapi/v2/private", auth: true, cost: 5, default_params: %{ "transferType" => "wallet_to_contract" }, market_type: :spot, method: :post, name: :transfer, param_mappings: %{ "code" => "coinSymbol" }, params: [ :code, :amount, :fromAccount, :toAccount ], path: "/futures_transfer", response_transformer: {:extract_path, ["data"]}, source: :intercepted }, %{ api_section: "spot/v1/private", auth: true, cost: 120, market_type: :spot, method: :post, name: :withdraw, param_mappings: %{ "address" => "addressTo", "code" => "coin" }, params: [ :code, :amount, :address, :tag ], path: "/withdraw/commit", response_transformer: {:extract_path, ["data"]}, source: :intercepted } ], error_code_details: %{ -1000 => %{ description: "An unknown error occured while processing the request.", type: :network_error }, -1001 => %{ description: "'Internal error; unable to process your request. Please try again.'", type: :network_error }, -1002 => %{ description: "'You are not authorized to execute this request.'", type: :invalid_credentials }, -1003 => %{ description: "Too much request weight used, current limit is 1200 request weight per 1 MINUTE. Please use the websocket for live updates to avoid polling the API.", type: :rate_limited }, -1013 => %{ description: "createOrder -> 'invalid quantity'/'invalid price'/MIN_NOTIONAL", type: :invalid_order }, -1015 => %{ description: "'Too many new orders; current limit is %s orders per %s.'", type: :rate_limited }, -1016 => %{ description: "'This service is no longer available.',", type: :network_error }, -1020 => %{ description: "'This operation is not supported.'", type: :invalid_parameters }, -1021 => %{ description: "'your time is ahead of server'", type: :invalid_credentials }, -1022 => %{ description: "Signature for this request is not valid.", type: :invalid_credentials }, -1100 => %{ description: "createOrder(symbol, 1, asdf) -> 'Illegal characters found in parameter 'price'", type: :invalid_parameters }, -11008 => %{ description: "Exceeding the account's maximum borrowable limit.", type: :insufficient_balance }, -1101 => %{ description: "Too many parameters; expected %s and received %s.", type: :invalid_parameters }, -1102 => %{ description: "Param %s or %s must be sent, but both were empty // {\"code\":-1102,\"msg\":\"timestamp IllegalArgumentException.\",\"data\":null}", type: :invalid_parameters }, -1103 => %{ description: "An unknown parameter was sent.", type: :invalid_parameters }, -1104 => %{ description: "Not all sent parameters were read, read 8 parameters but was sent 9", type: :invalid_parameters }, -1105 => %{ description: "Parameter %s was empty.", type: :invalid_parameters }, -1106 => %{ description: "Parameter %s sent when not required.", type: :invalid_parameters }, -1111 => %{ description: "Precision is over the maximum defined for this asset.", type: :invalid_parameters }, -1112 => %{ description: "No orders on book for symbol.", type: :invalid_order }, -1114 => %{ description: "TimeInForce parameter sent when not required.", type: :invalid_parameters }, -1115 => %{ description: "Invalid timeInForce.", type: :invalid_parameters }, -1116 => %{ description: "Invalid orderType.", type: :invalid_parameters }, -1117 => %{ description: "Invalid side.", type: :invalid_parameters }, -1118 => %{ description: "New client order ID was empty.", type: :invalid_parameters }, -1119 => %{ description: "Original client order ID was empty.", type: :invalid_parameters }, -1120 => %{ description: "Invalid interval.", type: :invalid_parameters }, -1121 => %{ description: "Invalid symbol.", type: :invalid_order }, -1125 => %{ description: "This listenKey does not exist.", type: :invalid_credentials }, -1127 => %{ description: "More than %s hours between startTime and endTime.", type: :invalid_parameters }, -1128 => %{ description: "Combination of optional parameters invalid.", type: :invalid_parameters }, -1130 => %{ description: "Data sent for paramter %s is not valid.", type: :invalid_parameters }, -1131 => %{ description: "recvWindow must be less than 60000", type: :invalid_parameters }, -1156 => %{ description: "The number of closed positions exceeds the total number of positions", type: :invalid_order }, -1160 => %{ description: "Minimum order amount 10", type: :invalid_order }, -1166 => %{ description: "The leverage value of the order is inconsistent with the user contract configuration 5", type: :invalid_order }, -2008 => %{ description: "Invalid Api-Key ID.", type: :invalid_credentials }, -2010 => %{ description: "generic error code for createOrder -> 'Account has insufficient balance for requested action.', {\"code\":-2010,\"msg\":\"Rest API trading is not enabled.\"}, etc...", type: :exchange_error }, -2011 => %{ description: "cancelOrder(1, 'BTC/USDT') -> 'UNKNOWN_ORDER'", type: :order_not_found }, -2013 => %{ description: "fetchOrder (1, 'BTC/USDT') -> 'Order does not exist'", type: :order_not_found }, -2014 => %{ description: "API-key format invalid.", type: :invalid_credentials }, -2015 => %{ description: "\"Invalid API-key, IP, or permissions for action.\"", type: :invalid_credentials }, -2017 => %{ description: "{code\":\"-2017\",\"msg\":\"Insufficient balance\",\"data\":null}", type: :insufficient_balance }, -2019 => %{ description: "Margin is insufficient.", type: :insufficient_balance }, -3005 => %{ description: "Transferring out not allowed. Transfer out amount exceeds max amount.", type: :insufficient_balance }, -3006 => %{ description: "Your borrow amount has exceed maximum borrow amount.", type: :insufficient_balance }, -3008 => %{ description: "Borrow not allowed. Your borrow amount has exceed maximum borrow amount.", type: :insufficient_balance }, -3010 => %{ description: "Repay not allowed. Repay amount exceeds borrow amount.", type: :exchange_error }, -3015 => %{ description: "Repay amount exceeds borrow amount.", type: :exchange_error }, -3020 => %{ description: "Transfer out amount exceeds max amount.", type: :insufficient_balance }, -3022 => %{ description: "You account's trading is banned.", type: :access_restricted }, -3041 => %{ description: "Balance is not enough", type: :insufficient_balance }, -4028 => %{ description: "Leverage 100 is not valid", type: :invalid_parameters }, -4051 => %{ description: "Isolated balance insufficient.", type: :insufficient_balance }, -5013 => %{ description: "Asset transfer failed: insufficient balance\"", type: :insufficient_balance }, "API key does not exist" => %{ description: nil, type: :invalid_credentials }, "Account has insufficient balance for requested action." => %{ description: nil, type: :insufficient_balance }, "Insufficient account balance" => %{ description: "Insufficient account balance.", type: :insufficient_balance }, "MAX_POSITION" => %{ description: "Filter failure: MAX_POSITION", type: :invalid_order }, "Market is closed." => %{ description: "Market is closed.", type: :network_error }, "Order would immediately match and take." => %{ description: "Order would immediately match and take.", type: :invalid_order }, "Order would trigger immediately." => %{ description: nil, type: :invalid_order }, "Rest API trading is not enabled." => %{ description: nil, type: :network_error }, "Stop price would trigger immediately." => %{ description: "Stop price would trigger immediately.", type: :invalid_order }, "System abnormality" => %{ description: "System abnormality", type: :exchange_error }, "System is under maintenance." => %{ description: "System is under maintenance.", type: :network_error }, "Too many requests. Please try again later." => %{ description: "Too many requests. Please try again later.", type: :rate_limited }, "You are not authorized to execute this request." => %{ description: "You are not authorized to execute this request.", type: :access_restricted }, "You don't have permission." => %{ description: "You don't have permission.", type: :access_restricted }, "has no operation privilege" => %{ description: nil, type: :access_restricted } }, error_codes: %{ -1000 => :network_error, -1001 => :network_error, -1002 => :invalid_credentials, -1003 => :rate_limited, -1013 => :invalid_order, -1015 => :rate_limited, -1016 => :network_error, -1020 => :invalid_parameters, -1021 => :invalid_credentials, -1022 => :invalid_credentials, -1100 => :invalid_parameters, -11008 => :insufficient_balance, -1101 => :invalid_parameters, -1102 => :invalid_parameters, -1103 => :invalid_parameters, -1104 => :invalid_parameters, -1105 => :invalid_parameters, -1106 => :invalid_parameters, -1111 => :invalid_parameters, -1112 => :invalid_order, -1114 => :invalid_parameters, -1115 => :invalid_parameters, -1116 => :invalid_parameters, -1117 => :invalid_parameters, -1118 => :invalid_parameters, -1119 => :invalid_parameters, -1120 => :invalid_parameters, -1121 => :invalid_order, -1125 => :invalid_credentials, -1127 => :invalid_parameters, -1128 => :invalid_parameters, -1130 => :invalid_parameters, -1131 => :invalid_parameters, -1156 => :invalid_order, -1160 => :invalid_order, -1166 => :invalid_order, -2008 => :invalid_credentials, -2010 => :exchange_error, -2011 => :order_not_found, -2013 => :order_not_found, -2014 => :invalid_credentials, -2015 => :invalid_credentials, -2017 => :insufficient_balance, -2019 => :insufficient_balance, -3005 => :insufficient_balance, -3006 => :insufficient_balance, -3008 => :insufficient_balance, -3010 => :exchange_error, -3015 => :exchange_error, -3020 => :insufficient_balance, -3022 => :access_restricted, -3041 => :insufficient_balance, -4028 => :invalid_parameters, -4051 => :insufficient_balance, -5013 => :insufficient_balance, "API key does not exist" => :invalid_credentials, "Account has insufficient balance for requested action." => :insufficient_balance, "Insufficient account balance" => :insufficient_balance, "MAX_POSITION" => :invalid_order, "Market is closed." => :network_error, "Order would immediately match and take." => :invalid_order, "Order would trigger immediately." => :invalid_order, "Rest API trading is not enabled." => :network_error, "Stop price would trigger immediately." => :invalid_order, "System abnormality" => :exchange_error, "System is under maintenance." => :network_error, "Too many requests. Please try again later." => :rate_limited, "You are not authorized to execute this request." => :access_restricted, "You don't have permission." => :access_restricted, "has no operation privilege" => :access_restricted }, exceptions: %{ broad: %{ "Insufficient account balance" => :insufficient_funds, "MAX_POSITION" => :invalid_order, "has no operation privilege" => :permission_denied }, exact: %{ "-1000" => :exchange_not_available, "-1001" => :exchange_not_available, "-1002" => :authentication_error, "-1003" => :rate_limit_exceeded, "-1013" => :invalid_order, "-1015" => :rate_limit_exceeded, "-1016" => :exchange_not_available, "-1020" => :bad_request, "-1021" => :invalid_nonce, "-1022" => :authentication_error, "-1100" => :bad_request, "-11008" => :insufficient_funds, "-1101" => :bad_request, "-1102" => :bad_request, "-1103" => :bad_request, "-1104" => :bad_request, "-1105" => :bad_request, "-1106" => :bad_request, "-1111" => :bad_request, "-1112" => :invalid_order, "-1114" => :bad_request, "-1115" => :bad_request, "-1116" => :bad_request, "-1117" => :bad_request, "-1118" => :bad_request, "-1119" => :bad_request, "-1120" => :bad_request, "-1121" => :bad_symbol, "-1125" => :authentication_error, "-1127" => :bad_request, "-1128" => :bad_request, "-1130" => :bad_request, "-1131" => :bad_request, "-1156" => :invalid_order, "-1160" => :invalid_order, "-1166" => :invalid_order, "-2008" => :authentication_error, "-2010" => :exchange_error, "-2011" => :order_not_found, "-2013" => :order_not_found, "-2014" => :authentication_error, "-2015" => :authentication_error, "-2017" => :insufficient_funds, "-2019" => :insufficient_funds, "-3005" => :insufficient_funds, "-3006" => :insufficient_funds, "-3008" => :insufficient_funds, "-3010" => :exchange_error, "-3015" => :exchange_error, "-3020" => :insufficient_funds, "-3022" => :account_suspended, "-3041" => :insufficient_funds, "-4028" => :bad_request, "-4051" => :insufficient_funds, "-5013" => :insufficient_funds, "API key does not exist" => :authentication_error, "Account has insufficient balance for requested action." => :insufficient_funds, "Market is closed." => :exchange_not_available, "Order would immediately match and take." => :order_immediately_fillable, "Order would trigger immediately." => :order_immediately_fillable, "Rest API trading is not enabled." => :exchange_not_available, "Stop price would trigger immediately." => :order_immediately_fillable, "System abnormality" => :exchange_error, "System is under maintenance." => :on_maintenance, "Too many requests. Please try again later." => :ddos_protection, "You are not authorized to execute this request." => :permission_denied, "You don't have permission." => :permission_denied } }, exchange_options: %{ "accountsByType" => %{ "contract" => "contract", "fund" => "wallet", "funding" => "wallet", "future" => "contract", "spot" => "wallet", "swap" => "contract" }, "adjustForTimeDifference" => false, "createMarketBuyOrderRequiresPrice" => true, "currencyToPrecisionRoundingMode" => 0, "defaultNetworkCodeReplacements" => %{ "BRC20" => %{ "BRC20" => "BTC" }, "CRO" => %{ "CRC20" => "CRONOS" }, "ETH" => %{ "ERC20" => "ETH" }, "TRX" => %{ "TRC20" => "TRX" } }, "defaultType" => "spot", "fetchMarkets" => %{ "types" => [ "spot", "linear", "inverse" ] }, "fetchMyTradesMethod" => "v2PrivateGetMyTrades", "hasAlreadyAuthenticatedSuccessfully" => false, "networks" => %{ "ADA" => "Cardano", "AETERNITY" => "Aeternity", "AION" => "AION", "ALGO" => "Algorand", "ASK" => "ASK", "ATOM" => "ATOM", "AVAXC" => "AVAX C-Chain", "BCH" => "BCH", "BEP2" => "BEP2", "BEP20" => "BEP20", "BRP20" => "BRP20", "Bitcoin" => "Bitcoin", "CASINOCOIN" => "CasinoCoin", "CASINOCOIN-XRPL" => "CasinoCoin XRPL", "CONTENTOS" => "Contentos", "DASH" => "Dash", "DECOIN" => "Decoin", "DFI" => "DeFiChain", "DGB" => "DGB", "DIVI" => "Divi", "DOGE" => "dogecoin", "DOT" => "Polkadot", "EOS" => "EOS", "ERC20" => "ETH", "ETC" => "ETC", "FILECOIN" => "Filecoin", "FREETON" => "FREETON", "HBAR" => "HBAR", "HEDERA" => "Hedera Hashgraph", "HRC20" => "HRC20", "ICON" => "ICON", "ICP" => "ICP", "IGNIS" => "Ignis", "INTERNETCOMPUTER" => "Internet Computer", "IOTA" => "IOTA", "KAVA" => "KAVA", "KSM" => "KSM", "LTC" => "LiteCoin", "LUNA" => "Luna", "MATIC" => "MATIC", "MOBILECOIN" => "Mobile Coin", "MONACOIN" => "MonaCoin", "NEM" => "NEM", "NEP5" => "NEP5", "OMNI" => "OMNI", "PAC" => "PAC", "RAVEN" => "Ravencoin", "SAFEX" => "Safex", "SGB" => "Songbird", "SOL" => "SOLANA", "THETA" => "THETA", "TRC20" => "TRX", "VECHAIN" => "VeChain", "WANCHAIN" => "Wanchain", "XINFIN" => "XinFin Network", "XML" => "Stellar Lumens", "XMR" => "Monero", "XRP" => "XRP", "XRPL" => "XRPL", "XTZ" => "Tezos", "XYM" => "Symbol", "ZIL" => "ZIL", "theta" => "theta" }, "networksById" => %{ "AION" => "AION", "ASK" => "ASK", "ATOM" => "ATOM", "AVAX C-Chain" => "AVAXC", "Aeternity" => "AETERNITY", "Algorand" => "ALGO", "BCH" => "BCH", "BEP2" => "BEP2", "BEP20" => "BEP20", "BRP20" => "BRP20", "Bitcoin" => "Bitcoin", "Cardano" => "ADA", "CasinoCoin" => "CASINOCOIN", "CasinoCoin XRPL" => "CASINOCOIN-XRPL", "Contentos" => "CONTENTOS", "DGB" => "DGB", "Dash" => "DASH", "DeFiChain" => "DFI", "Decoin" => "DECOIN", "Divi" => "DIVI", "EOS" => "EOS", "ETC" => "ETC", "ETH" => "ERC20", "FREETON" => "FREETON", "Filecoin" => "FILECOIN", "HBAR" => "HBAR", "HRC20" => "HRC20", "Hedera Hashgraph" => "HEDERA", "ICON" => "ICON", "ICP" => "ICP", "IOTA" => "IOTA", "Ignis" => "IGNIS", "Internet Computer" => "INTERNETCOMPUTER", "KAVA" => "KAVA", "KSM" => "KSM", "LiteCoin" => "LTC", "Luna" => "LUNA", "MATIC" => "MATIC", "Mobile Coin" => "MOBILECOIN", "MonaCoin" => "MONACOIN", "Monero" => "XMR", "NEM" => "NEM", "NEP5" => "NEP5", "OMNI" => "OMNI", "PAC" => "PAC", "Polkadot" => "DOT", "Ravencoin" => "RAVEN", "SOLANA" => "SOL", "Safex" => "SAFEX", "Songbird" => "SGB", "Stellar Lumens" => "XML", "Symbol" => "XYM", "THETA" => "THETA", "TRX" => "TRC20", "Tezos" => "XTZ", "VeChain" => "VECHAIN", "Wanchain" => "WANCHAIN", "XRP" => "XRP", "XRPL" => "XRPL", "XinFin Network" => "XINFIN", "ZIL" => "ZIL", "dogecoin" => "DOGE", "theta" => "theta" }, "newOrderRespType" => %{ "limit" => "FULL", "market" => "FULL" }, "parseOrderToPrecision" => false, "recvWindow" => 5000, "timeDifference" => 0, "timeframes" => %{ "future" => %{ "15m" => "15min", "1M" => "1month", "1d" => "1day", "1h" => "1h", "1m" => "1min", "1w" => "1week", "30m" => "30min", "5m" => "5min" }, "spot" => %{ "12h" => "12H", "15m" => "15m", "1d" => "1D", "1h" => "1H", "1m" => "1m", "1w" => "1W", "2h" => "2H", "30m" => "30m", "4h" => "4H", "5m" => "5m" } } }, extended_metadata: %{ fees_url: "https://bitrue.zendesk.com/hc/en-001/articles/4405479952537", limits: %{ "amount" => %{}, "cost" => %{}, "leverage" => %{}, "price" => %{} }, logo_url: "https://github.com/user-attachments/assets/67abe346-1273-461a-bd7c-42fa32907c8e", referral_url: "https://www.bitrue.com/affiliate/landing?cn=600000&inviteCode=EZWETQE" }, extracted_metadata: %{ ccxt_version: "4.5.34" }, features: %{ default: %{ create_order: %{ hedged: false, iceberg: true, leverage: false, margin_mode: false, market_buy_by_cost: true, market_buy_requires_price: true, self_trade_prevention: false, stop_loss_price: false, take_profit_price: false, time_in_force: %{ fok: true, gtd: false, ioc: true, po: true }, trailing: false, trigger_price: true }, fetch_closed_orders: %{ days_back: 90, days_back_canceled: 1, limit: 1000, margin_mode: false, symbol_required: true, trailing: false, trigger: false, until_days: 90 }, fetch_my_trades: %{ days_back: 100000, limit: 1000, margin_mode: false, symbol_required: true, until_days: 100000 }, fetch_ohlcv: %{ limit: 1440 }, fetch_open_orders: %{ margin_mode: false, symbol_required: true, trailing: false, trigger: false }, fetch_order: %{ margin_mode: false, symbol_required: true, trailing: false, trigger: false }, sandbox: false }, for_derivatives: %{ create_order: %{ leverage: true, margin_mode: true, market_buy_by_cost: false, market_buy_requires_price: false }, extends: "default", fetch_ohlcv: %{ limit: 300 } }, future: %{}, spot: %{ extends: "default" }, swap: %{ inverse: %{ extends: "forDerivatives" }, linear: %{ extends: "forDerivatives" } } }, fees: %{ future: %{ trading: %{ fee_side: "quote", maker: 0.0002, percentage: true, taker: 0.0004, tier_based: true, tiers: %{ maker: [ %{ fee: 0.0002, volume: 0 }, %{ fee: 1.6e-4, volume: 250 }, %{ fee: 1.4e-4, volume: 2500 }, %{ fee: 1.2e-4, volume: 7500 }, %{ fee: 0.0001, volume: 22500 }, %{ fee: 8.0e-5, volume: 50000 }, %{ fee: 6.0e-5, volume: 100000 }, %{ fee: 4.0e-5, volume: 200000 }, %{ fee: 2.0e-5, volume: 400000 }, %{ fee: 0, volume: 750000 } ], taker: [ %{ fee: 0.0004, volume: 0 }, %{ fee: 0.0004, volume: 250 }, %{ fee: 3.5e-4, volume: 2500 }, %{ fee: 3.2e-4, volume: 7500 }, %{ fee: 0.0003, volume: 22500 }, %{ fee: 2.7e-4, volume: 50000 }, %{ fee: 2.5e-4, volume: 100000 }, %{ fee: 2.2e-4, volume: 200000 }, %{ fee: 0.0002, volume: 400000 }, %{ fee: 1.7e-4, volume: 750000 } ] } } }, trading: %{ fee_side: "get", maker: 9.8e-4, percentage: true, taker: 9.8e-4, tier_based: false } }, handle_content_type_application_zip: nil, handle_errors_source: "handleErrors(code, reason, url, method, headers, body, response, requestHeaders, requestBody) {\n if ((code === 418) || (code === 429)) {\n throw new errors.DDoSProtection(this.id + ' ' + code.toString() + ' ' + reason + ' ' + body);\n }\n // error response in a form: { \"code\": -1013, \"msg\": \"Invalid quantity.\" }\n // following block cointains legacy checks against message patterns in \"msg\" property\n // will switch \"code\" checks eventually, when we know all of them\n if (code >= 400) {\n if (body.indexOf('Price * QTY is zero or less') >= 0) {\n throw new errors.InvalidOrder(this.id + ' order cost = amount * price is zero or less ' + body);\n }\n if (body.indexOf('LOT_SIZE') >= 0) {\n throw new errors.InvalidOrder(this.id + ' order amount should be evenly divisible by lot size ' + body);\n }\n if (body.indexOf('PRICE_FILTER') >= 0) {\n throw new errors.InvalidOrder(this.id + ' order price is invalid, i.e. exceeds allowed price precision, exceeds min price or max price limits or is invalid float value in general, use this.priceToPrecision (symbol, amount) ' + body);\n }\n }\n if (response === undefined) {\n return undefined; // fallback to default error handler\n }\n // check success value for wapi endpoints\n // response in format {'msg': 'The coin does not exist.', 'success': true/false}\n const success = this.safeBool(response, 'success', true);\n if (!success) {\n const messageInner = this.safeString(response, 'msg');\n let parsedMessage = undefined;\n if (messageInner !== undefined) {\n try {\n parsedMessage = JSON.parse(messageInner);\n }\n catch (e) {\n // do nothing\n parsedMessage = undefined;\n }\n if (parsedMessage !== undefined) {\n response = parsedMessage;\n }\n }\n }\n const message = this.safeString(response, 'msg');\n if (message !== undefined) {\n this.throwExactlyMatchedException(this.exceptions['exact'], message, this.id + ' ' + message);\n this.throwBroadlyMatchedException(this.exceptions['broad'], message, this.id + ' ' + message);\n }\n // checks against error codes\n const error = this.safeString(response, 'code');\n if (error !== undefined) {\n // https://github.com/ccxt/ccxt/issues/6501\n // https://github.com/ccxt/ccxt/issues/7742\n if ((error === '200') || Precise[\"default\"].stringEquals(error, '0')) {\n return undefined;\n }\n // a workaround for {\"code\":-2015,\"msg\":\"Invalid API-key, IP, or permissions for action.\"}\n // despite that their message is very confusing, it is raised by Binance\n // on a temporary ban, the API key is valid, but disabled for a while\n if ((error === '-2015') && this.options['hasAlreadyAuthenticatedSuccessfully']) {\n throw new errors.DDoSProtection(this.id + ' temporary banned: ' + body);\n }\n const feedback = this.id + ' ' + body;\n this.throwExactlyMatchedException(this.exceptions['exact'], error, feedback);\n throw new errors.ExchangeError(feedback);\n }\n if (!success) {\n throw new errors.ExchangeError(this.id + ' ' + body);\n }\n return undefined;\n }", has: %{ add_margin: false, borrow_cross_margin: false, borrow_isolated_margin: false, borrow_margin: false, c_o_r_s: false, cancel_all_orders: true, cancel_all_orders_ws: false, cancel_order: true, cancel_order_with_client_order_id: false, cancel_order_ws: false, cancel_orders: false, cancel_orders_with_client_order_id: false, cancel_orders_ws: false, close_all_positions: false, close_position: false, create_deposit_address: false, create_limit_buy_order: false, create_limit_buy_order_ws: false, create_limit_order: true, create_limit_order_ws: false, create_limit_sell_order: false, create_limit_sell_order_ws: false, create_market_buy_order: false, create_market_buy_order_with_cost: true, create_market_buy_order_with_cost_ws: false, create_market_buy_order_ws: false, create_market_order: true, create_market_order_with_cost: false, create_market_order_with_cost_ws: false, create_market_order_ws: true, create_market_sell_order: false, create_market_sell_order_with_cost: false, create_market_sell_order_with_cost_ws: false, create_market_sell_order_ws: false, create_order: true, create_order_with_take_profit_and_stop_loss: false, create_order_with_take_profit_and_stop_loss_ws: false, create_order_ws: false, create_orders: false, create_post_only_order: false, create_post_only_order_ws: false, create_reduce_only_order: true, create_reduce_only_order_ws: false, create_stop_limit_order: true, create_stop_limit_order_ws: false, create_stop_loss_order: false, create_stop_loss_order_ws: false, create_stop_market_order: true, create_stop_market_order_ws: false, create_stop_order: true, create_stop_order_ws: false, create_take_profit_order: false, create_take_profit_order_ws: false, create_trailing_amount_order: false, create_trailing_amount_order_ws: false, create_trailing_percent_order: false, create_trailing_percent_order_ws: false, create_trigger_order: false, create_trigger_order_ws: false, deposit: false, edit_order: true, edit_order_with_client_order_id: false, edit_order_ws: false, edit_orders: false, fetch_accounts: false, fetch_balance: true, fetch_balance_ws: false, fetch_bids_asks: true, fetch_borrow_interest: false, fetch_borrow_rate: false, fetch_borrow_rate_histories: false, fetch_borrow_rate_history: false, fetch_borrow_rates: false, fetch_borrow_rates_per_symbol: false, fetch_canceled_and_closed_orders: false, fetch_canceled_orders: false, fetch_closed_order: false, fetch_closed_orders: true, fetch_closed_orders_ws: false, fetch_convert_currencies: false, fetch_convert_quote: false, fetch_convert_trade: false, fetch_convert_trade_history: false, fetch_cross_borrow_rate: false, fetch_cross_borrow_rates: false, fetch_currencies: true, fetch_currencies_ws: true, fetch_deposit: false, fetch_deposit_address: false, fetch_deposit_addresses: false, fetch_deposit_addresses_by_network: false, fetch_deposit_withdraw_fee: true, fetch_deposit_withdraw_fees: true, fetch_deposits: true, fetch_deposits_withdrawals: false, fetch_deposits_ws: false, fetch_funding_history: false, fetch_funding_interval: false, fetch_funding_intervals: false, fetch_funding_rate: false, fetch_funding_rate_history: false, fetch_funding_rates: false, fetch_greeks: false, fetch_index_ohlcv: false, fetch_isolated_borrow_rate: false, fetch_isolated_borrow_rates: false, fetch_isolated_positions: false, fetch_l2_order_book: true, fetch_l3_order_book: false, fetch_last_prices: false, fetch_ledger: false, fetch_ledger_entry: false, fetch_leverage: false, fetch_leverage_tiers: false, fetch_leverages: false, fetch_liquidations: false, fetch_long_short_ratio: false, fetch_long_short_ratio_history: false, fetch_margin_adjustment_history: false, fetch_margin_mode: false, fetch_margin_modes: false, fetch_mark_ohlcv: false, fetch_mark_prices: false, fetch_market_leverage_tiers: false, fetch_markets: true, fetch_markets_ws: false, fetch_my_liquidations: false, fetch_my_settlement_history: false, fetch_my_trades: true, fetch_my_trades_ws: false, fetch_ohlcv: true, fetch_ohlcv_ws: false, fetch_open_interest: false, fetch_open_interest_history: false, fetch_open_interests: false, fetch_open_order: false, fetch_open_orders: true, fetch_open_orders_ws: false, fetch_option: false, fetch_option_chain: false, fetch_order: true, fetch_order_book: true, fetch_order_book_ws: false, fetch_order_books: false, fetch_order_trades: false, fetch_order_with_client_order_id: false, fetch_order_ws: false, fetch_orders: false, fetch_orders_by_status: false, fetch_orders_ws: false, fetch_position: false, fetch_position_history: false, fetch_position_mode: false, fetch_position_ws: false, fetch_positions: false, fetch_positions_for_symbol: false, fetch_positions_for_symbol_ws: false, fetch_positions_history: false, fetch_positions_risk: false, fetch_positions_ws: false, fetch_premium_index_ohlcv: false, fetch_settlement_history: false, fetch_status: true, fetch_ticker: true, fetch_ticker_ws: false, fetch_tickers: true, fetch_tickers_ws: false, fetch_time: true, fetch_trades: true, fetch_trades_ws: false, fetch_trading_fee: false, fetch_trading_fees: false, fetch_trading_fees_ws: false, fetch_trading_limits: false, fetch_transaction_fee: false, fetch_transaction_fees: false, fetch_transactions: false, fetch_transfer: false, fetch_transfers: true, fetch_underlying_assets: false, fetch_volatility_history: false, fetch_withdraw_addresses: false, fetch_withdrawal: false, fetch_withdrawal_whitelist: false, fetch_withdrawals: true, fetch_withdrawals_ws: false, future: false, margin: false, option: false, private_api: true, public_api: true, reduce_margin: false, repay_cross_margin: false, repay_isolated_margin: false, sandbox: false, set_leverage: true, set_margin: true, set_margin_mode: false, set_position_mode: false, sign_in: false, spot: true, swap: true, transfer: true, un_watch_my_trades: false, un_watch_ohlcv: false, un_watch_ohlcv_for_symbols: false, un_watch_order_book: false, un_watch_order_book_for_symbols: false, un_watch_orders: false, un_watch_positions: false, un_watch_ticker: false, un_watch_tickers: false, un_watch_trades: false, un_watch_trades_for_symbols: false, watch_balance: true, watch_bids_asks: false, watch_liquidations: false, watch_liquidations_for_symbols: false, watch_my_liquidations: false, watch_my_liquidations_for_symbols: false, watch_my_trades: false, watch_ohlcv: false, watch_ohlcv_for_symbols: false, watch_order_book: true, watch_order_book_for_symbols: false, watch_orders: true, watch_orders_for_symbols: false, watch_position: false, watch_positions: false, watch_status: false, watch_ticker: false, watch_tickers: false, watch_trades: false, watch_trades_for_symbols: false, withdraw: true, ws: false }, http_config: nil, id: "bitrue", markets: nil, name: "Bitrue", ohlcv_timestamp_resolution: :unknown, options: %{ accounts_by_type: %{ "contract" => "contract", "fund" => "wallet", "funding" => "wallet", "future" => "contract", "spot" => "wallet", "swap" => "contract" }, adjust_for_time_difference: false, create_market_buy_order_requires_price: true, currency_to_precision_rounding_mode: 0, default_account_type: "spot", default_type: "spot", fetch_markets: %{ "types" => [ "spot", "linear", "inverse" ] }, fetch_my_trades_method: "v2PrivateGetMyTrades", has_already_authenticated_successfully: false, networks: %{ "ADA" => "Cardano", "AETERNITY" => "Aeternity", "AION" => "AION", "ALGO" => "Algorand", "ASK" => "ASK", "ATOM" => "ATOM", "AVAXC" => "AVAX C-Chain", "BCH" => "BCH", "BEP2" => "BEP2", "BEP20" => "BEP20", "BRP20" => "BRP20", "Bitcoin" => "Bitcoin", "CASINOCOIN" => "CasinoCoin", "CASINOCOIN-XRPL" => "CasinoCoin XRPL", "CONTENTOS" => "Contentos", "DASH" => "Dash", "DECOIN" => "Decoin", "DFI" => "DeFiChain", "DGB" => "DGB", "DIVI" => "Divi", "DOGE" => "dogecoin", "DOT" => "Polkadot", "EOS" => "EOS", "ERC20" => "ETH", "ETC" => "ETC", "FILECOIN" => "Filecoin", "FREETON" => "FREETON", "HBAR" => "HBAR", "HEDERA" => "Hedera Hashgraph", "HRC20" => "HRC20", "ICON" => "ICON", "ICP" => "ICP", "IGNIS" => "Ignis", "INTERNETCOMPUTER" => "Internet Computer", "IOTA" => "IOTA", "KAVA" => "KAVA", "KSM" => "KSM", "LTC" => "LiteCoin", "LUNA" => "Luna", "MATIC" => "MATIC", "MOBILECOIN" => "Mobile Coin", "MONACOIN" => "MonaCoin", "NEM" => "NEM", "NEP5" => "NEP5", "OMNI" => "OMNI", "PAC" => "PAC", "RAVEN" => "Ravencoin", "SAFEX" => "Safex", "SGB" => "Songbird", "SOL" => "SOLANA", "THETA" => "THETA", "TRC20" => "TRX", "VECHAIN" => "VeChain", "WANCHAIN" => "Wanchain", "XINFIN" => "XinFin Network", "XML" => "Stellar Lumens", "XMR" => "Monero", "XRP" => "XRP", "XRPL" => "XRPL", "XTZ" => "Tezos", "XYM" => "Symbol", "ZIL" => "ZIL", "theta" => "theta" }, new_order_resp_type: %{ "limit" => "FULL", "market" => "FULL" }, parse_order_to_precision: false, recv_window: 5000, time_difference: 0, timeframes: %{ "future" => %{ "15m" => "15min", "1M" => "1month", "1d" => "1day", "1h" => "1h", "1m" => "1min", "1w" => "1week", "30m" => "30min", "5m" => "5min" }, "spot" => %{ "12h" => "12H", "15m" => "15m", "1d" => "1D", "1h" => "1H", "1m" => "1m", "1w" => "1W", "2h" => "2H", "30m" => "30m", "4h" => "4H", "5m" => "5m" } } }, order_mappings: %{ side_format: :uppercase, side_key: "side", type_format: :uppercase, type_key: "type" }, param_mappings: %{ "address" => "addressTo", "amount" => "volume", "code" => "coin", "id" => "orderId", "timeframe" => "scale", "triggerPrice" => "stopPrice" }, parse_methods: [ %{ "comment" => nil, "examples" => [ "{\n \"makerCommission\":0,\n \"takerCommission\":0,\n \"buyerCommission\":0,\n \"sellerCommission\":0,\n \"updateTime\":null,\n \"balances\":[\n {\"asset\":\"sbr\",\"free\":\"0\",\"locked\":\"0\"},\n {\"asset\":\"ksm\",\"free\":\"0\",\"locked\":\"0\"},\n {\"asset\":\"neo3s\",\"free\":\"0\",\"locked\":\"0\"},\n ],\n \"canTrade\":false,\n \"canWithdraw\":false,\n \"canDeposit\":false\n }", "{\n \"account\":[\n {\n \"marginCoin\":\"USDT\",\n \"coinPrecious\":4,\n \"accountNormal\":1010.4043400372839856,\n \"accountLock\":2.9827889600000006,\n \"partPositionNormal\":0,\n \"totalPositionNormal\":0,\n \"achievedAmount\":0,\n \"unrealizedAmount\":0,\n \"totalMarginRate\":0,\n \"totalEquity\":1010.4043400372839856,\n \"partEquity\":0,\n \"totalCost\":0,\n \"sumMarginRate\":0,\n \"sumOpenRealizedAmount\":0,\n \"canUseTrialFund\":0,\n \"sumMaintenanceMargin\":null,\n \"futureModel\":null,\n \"positionVos\":[]\n }\n ]\n }" ], "line_end" => 1104, "line_start" => 1040, "mappings" => [], "name" => "parseBalance", "signature" => "parseBalance (response): Balances", "source" => "parseBalance (response): Balances {\n //\n // spot\n //\n // {\n // \"makerCommission\":0,\n // \"takerCommission\":0,\n // \"buyerCommission\":0,\n // \"sellerCommission\":0,\n // \"updateTime\":null,\n // \"balances\":[\n // {\"asset\":\"sbr\",\"free\":\"0\",\"locked\":\"0\"},\n // {\"asset\":\"ksm\",\"free\":\"0\",\"locked\":\"0\"},\n // {\"asset\":\"neo3s\",\"free\":\"0\",\"locked\":\"0\"},\n // ],\n // \"canTrade\":false,\n // \"canWithdraw\":false,\n // \"canDeposit\":false\n // }\n //\n // swap\n //\n // {\n // \"account\":[\n // {\n // \"marginCoin\":\"USDT\",\n // \"coinPrecious\":4,\n // \"accountNormal\":1010.4043400372839856,\n // \"accountLock\":2.9827889600000006,\n // \"partPositionNormal\":0,\n // \"totalPositionNormal\":0,\n // \"achievedAmount\":0,\n // \"unrealizedAmount\":0,\n // \"totalMarginRate\":0,\n // \"totalEquity\":1010.4043400372839856,\n // \"partEquity\":0,\n // \"totalCost\":0,\n // \"sumMarginRate\":0,\n // \"sumOpenRealizedAmount\":0,\n // \"canUseTrialFund\":0,\n // \"sumMaintenanceMargin\":null,\n // \"futureModel\":null,\n // \"positionVos\":[]\n // }\n // ]\n // }\n //\n const result: Dict = {\n 'info': response,\n };\n const timestamp = this.safeInteger (response, 'updateTime');\n const balances = this.safeValue2 (response, 'balances', 'account', []);\n for (let i = 0; i < balances.length; i++) {\n const balance = balances[i];\n const currencyId = this.safeString2 (balance, 'asset', 'marginCoin');\n const code = this.safeCurrencyCode (currencyId);\n const account = this.account ();\n account['free'] = this.safeString2 (balance, 'free', 'accountNormal');\n account['used'] = this.safeString2 (balance, 'locked', 'accountLock');\n result[code] = account;\n }\n result['timestamp'] = timestamp;\n result['datetime'] = this.iso8601 (timestamp);\n return this.safeBalance (result);\n }" }, %{ "comment" => nil, "examples" => [ "{\n \"coin\": \"adx\",\n \"coinFulName\": \"Ambire AdEx\",\n \"chains\": [ \"BSC\" ],\n \"chainDetail\": [ [Object] ]\n }" ], "line_end" => 2955, "line_start" => 2915, "mappings" => [ %{ "comment" => nil, "key" => "info", "value" => "fee" }, %{ "comment" => nil, "key" => "withdraw", "value" => "{\n 'fee': undefined,\n 'percentage': undefined,\n }" }, %{ "comment" => nil, "key" => "deposit", "value" => "{\n 'fee': undefined,\n 'percentage': undefined,\n }" }, %{ "comment" => nil, "key" => "networks", "value" => "{}" }, %{ "comment" => nil, "key" => "deposit", "value" => "{ 'fee': undefined, 'percentage': undefined }" }, %{ "comment" => nil, "key" => "withdraw", "value" => "{ 'fee': this.safeNumber (chainDetail, 'withdrawFee'), 'percentage': false }" } ], "name" => "parseDepositWithdrawFee", "signature" => "parseDepositWithdrawFee (fee, currency: Currency = undefined)", "source" => "parseDepositWithdrawFee (fee, currency: Currency = undefined) {\n //\n // {\n // \"coin\": \"adx\",\n // \"coinFulName\": \"Ambire AdEx\",\n // \"chains\": [ \"BSC\" ],\n // \"chainDetail\": [ [Object] ]\n // }\n //\n const chainDetails = this.safeList (fee, 'chainDetail', []);\n const chainDetailLength = chainDetails.length;\n const result: Dict = {\n 'info': fee,\n 'withdraw': {\n 'fee': undefined,\n 'percentage': undefined,\n },\n 'deposit': {\n 'fee': undefined,\n 'percentage': undefined,\n },\n 'networks': {},\n };\n if (chainDetailLength !== 0) {\n for (let i = 0; i < chainDetailLength; i++) {\n const chainDetail = chainDetails[i];\n const networkId = this.safeString (chainDetail, 'chain');\n const currencyCode = this.safeString (currency, 'code');\n const networkCode = this.networkIdToCode (networkId, currencyCode);\n result['networks'][networkCode] = {\n 'deposit': { 'fee': undefined, 'percentage': undefined },\n 'withdraw': { 'fee': this.safeNumber (chainDetail, 'withdrawFee'), 'percentage': false },\n };\n if (chainDetailLength === 1) {\n result['withdraw']['fee'] = this.safeNumber (chainDetail, 'withdrawFee');\n result['withdraw']['percentage'] = false;\n }\n }\n }\n return result;\n }" }, %{ "comment" => nil, "examples" => [ "{\n \"code\": 0,\n \"msg\": \"success\"\n \"data\": null\n }" ], "line_end" => 3162, "line_start" => 3140, "mappings" => [ %{ "comment" => nil, "key" => "info", "value" => "data" }, %{ "comment" => nil, "key" => "symbol", "value" => "market['symbol']" }, %{ "comment" => nil, "key" => "type", "value" => "undefined" }, %{ "comment" => nil, "key" => "marginMode", "value" => "'isolated'" }, %{ "comment" => nil, "key" => "amount", "value" => "undefined" }, %{ "comment" => nil, "key" => "total", "value" => "undefined" }, %{ "comment" => nil, "key" => "code", "value" => "undefined" }, %{ "comment" => nil, "key" => "status", "value" => "undefined" }, %{ "comment" => nil, "key" => "timestamp", "value" => "undefined" }, %{ "comment" => nil, "key" => "datetime", "value" => "undefined" } ], "name" => "parseMarginModification", "signature" => "parseMarginModification (data, market = undefined): MarginModification", "source" => "parseMarginModification (data, market = undefined): MarginModification {\n //\n // setMargin\n //\n // {\n // \"code\": 0,\n // \"msg\": \"success\"\n // \"data\": null\n // }\n //\n return {\n 'info': data,\n 'symbol': market['symbol'],\n 'type': undefined,\n 'marginMode': 'isolated',\n 'amount': undefined,\n 'total': undefined,\n 'code': undefined,\n 'status': undefined,\n 'timestamp': undefined,\n 'datetime': undefined,\n };\n }" }, %{ "comment" => nil, "examples" => [], "line_end" => 1038, "line_start" => 934, "mappings" => [ %{ "comment" => nil, "key" => "id", "value" => "id" }, %{ "comment" => nil, "key" => "lowercaseId", "value" => "lowercaseId" }, %{ "comment" => nil, "key" => "symbol", "value" => "symbol" }, %{ "comment" => nil, "key" => "base", "value" => "base" }, %{ "comment" => nil, "key" => "quote", "value" => "quote" }, %{ "comment" => nil, "key" => "settle", "value" => "settle" }, %{ "comment" => nil, "key" => "baseId", "value" => "baseId" }, %{ "comment" => nil, "key" => "quoteId", "value" => "quoteId" }, %{ "comment" => nil, "key" => "settleId", "value" => "settleId" }, %{ "comment" => nil, "key" => "type", "value" => "type" }, %{ "comment" => nil, "key" => "spot", "value" => "(type === 'spot')" }, %{ "comment" => nil, "key" => "margin", "value" => "false" }, %{ "comment" => nil, "key" => "swap", "value" => "isContract" }, %{ "comment" => nil, "key" => "future", "value" => "false" }, %{ "comment" => nil, "key" => "option", "value" => "false" }, %{ "comment" => nil, "key" => "active", "value" => "(status === 'TRADING')" }, %{ "comment" => nil, "key" => "contract", "value" => "isContract" }, %{ "comment" => nil, "key" => "linear", "value" => "isLinear" }, %{ "comment" => nil, "key" => "inverse", "value" => "isInverse" }, %{ "comment" => nil, "key" => "contractSize", "value" => "this.parseNumber (Precise.stringAbs (multiplier))" }, %{ "comment" => nil, "key" => "expiry", "value" => "undefined" }, %{ "comment" => nil, "key" => "expiryDatetime", "value" => "undefined" }, %{ "comment" => nil, "key" => "strike", "value" => "undefined" }, %{ "comment" => nil, "key" => "optionType", "value" => "undefined" }, %{ "comment" => nil, "key" => "precision", "value" => "{\n 'amount': this.parseNumber (this.parsePrecision (amountPrecision)),\n 'price': this.parseNumber (this.parsePrecision (pricePrecision)),\n }" }, %{ "comment" => nil, "key" => "limits", "value" => "{\n 'leverage': {\n 'min': undefined,\n 'max': undefined,\n },\n 'amount': {\n 'min': this.safeNumber (amountFilter, 'minQty'),\n 'max': maxQuantity,\n },\n 'price': {\n 'min': this.safeNumber (priceFilter, 'minPrice'),\n 'max': this.safeNumber (priceFilter, 'maxPrice'),\n },\n 'cost': {\n 'min': minCost,\n 'max': undefined,\n },\n }" }, %{ "comment" => nil, "key" => "created", "value" => "undefined" }, %{ "comment" => nil, "key" => "info", "value" => "market" }, %{ "comment" => nil, "key" => "min", "value" => "this.safeNumber (priceFilter, 'minPrice')" }, %{ "comment" => nil, "key" => "max", "value" => "this.safeNumber (priceFilter, 'maxPrice')" }, %{ "comment" => nil, "key" => "min", "value" => "minCost" }, %{ "comment" => nil, "key" => "max", "value" => "undefined" } ], "name" => "parseMarket", "signature" => "parseMarket (market: Dict): Market", "source" => "parseMarket (market: Dict): Market {\n const id = this.safeString (market, 'symbol');\n const lowercaseId = this.safeStringLower (market, 'symbol');\n const side = this.safeInteger (market, 'side'); // 1 linear, 0 inverse, undefined spot\n let type = undefined;\n let isLinear = undefined;\n let isInverse = undefined;\n if (side === undefined) {\n type = 'spot';\n } else {\n type = 'swap';\n isLinear = (side === 1);\n isInverse = (side === 0);\n }\n const isContract = (type !== 'spot');\n let baseId = this.safeString (market, 'baseAsset');\n let quoteId = this.safeString (market, 'quoteAsset');\n let settleId = undefined;\n let settle = undefined;\n if (isContract) {\n const symbolSplit = id.split ('-');\n baseId = this.safeString (symbolSplit, 1);\n quoteId = this.safeString (symbolSplit, 2);\n if (isLinear) {\n settleId = quoteId;\n } else {\n settleId = baseId;\n }\n settle = this.safeCurrencyCode (settleId);\n }\n const base = this.safeCurrencyCode (baseId);\n const quote = this.safeCurrencyCode (quoteId);\n let symbol = base + '/' + quote;\n if (settle !== undefined) {\n symbol += ':' + settle;\n }\n const filters = this.safeList (market, 'filters', []);\n const filtersByType = this.indexBy (filters, 'filterType');\n const status = this.safeString (market, 'status');\n const priceFilter = this.safeDict (filtersByType, 'PRICE_FILTER', {});\n const amountFilter = this.safeDict (filtersByType, 'LOT_SIZE', {});\n const defaultPricePrecision = this.safeString (market, 'pricePrecision');\n const defaultAmountPrecision = this.safeString (market, 'quantityPrecision');\n const pricePrecision = this.safeString (priceFilter, 'priceScale', defaultPricePrecision);\n const amountPrecision = this.safeString (amountFilter, 'volumeScale', defaultAmountPrecision);\n const multiplier = this.safeString (market, 'multiplier');\n let maxQuantity = this.safeNumber (amountFilter, 'maxQty');\n if (maxQuantity === undefined) {\n maxQuantity = this.safeNumber (market, 'maxValidOrder');\n }\n let minCost = this.safeNumber (amountFilter, 'minVal');\n if (minCost === undefined) {\n minCost = this.safeNumber (market, 'minOrderMoney');\n }\n return {\n 'id': id,\n 'lowercaseId': lowercaseId,\n 'symbol': symbol,\n 'base': base,\n 'quote': quote,\n 'settle': settle,\n 'baseId': baseId,\n 'quoteId': quoteId,\n 'settleId': settleId,\n 'type': type,\n 'spot': (type === 'spot'),\n 'margin': false,\n 'swap': isContract,\n 'future': false,\n 'option': false,\n 'active': (status === 'TRADING'),\n 'contract': isContract,\n 'linear': isLinear,\n 'inverse': isInverse,\n 'contractSize': this.parseNumber (Precise.stringAbs (multiplier)),\n 'expiry': undefined,\n 'expiryDatetime': undefined,\n 'strike': undefined,\n 'optionType': undefined,\n 'precision': {\n 'amount': this.parseNumber (this.parsePrecision (amountPrecision)),\n 'price': this.parseNumber (this.parsePrecision (pricePrecision)),\n },\n 'limits': {\n 'leverage': {\n 'min': undefined,\n 'max': undefined,\n },\n 'amount': {\n 'min': this.safeNumber (amountFilter, 'minQty'),\n 'max': maxQuantity,\n },\n 'price': {\n 'min': this.safeNumber (priceFilter, 'minPrice'),\n 'max': this.safeNumber (priceFilter, 'maxPrice'),\n },\n 'cost': {\n 'min': minCost,\n 'max': undefined,\n },\n },\n 'created': undefined,\n 'info': market,\n };\n }" }, %{ "comment" => nil, "examples" => [ "{\n \"i\":\"1660825020\",\n \"a\":\"93458.778\",\n \"v\":\"3.9774\",\n \"c\":\"23494.99\",\n \"h\":\"23509.63\",\n \"l\":\"23491.93\",\n \"o\":\"23508.34\"\n }", "{\n \"high\": \"35360.7\",\n \"vol\": \"110288\",\n \"low\": \"35347.9\",\n \"idx\": 1699411680000,\n \"close\": \"35347.9\",\n \"open\": \"35349.4\"\n }" ], "line_end" => 1567, "line_start" => 1530, "mappings" => [], "name" => "parseOHLCV", "signature" => "parseOHLCV (ohlcv, market: Market = undefined): OHLCV", "source" => "parseOHLCV (ohlcv, market: Market = undefined): OHLCV {\n //\n // spot\n //\n // {\n // \"i\":\"1660825020\",\n // \"a\":\"93458.778\",\n // \"v\":\"3.9774\",\n // \"c\":\"23494.99\",\n // \"h\":\"23509.63\",\n // \"l\":\"23491.93\",\n // \"o\":\"23508.34\"\n // }\n //\n // swap\n //\n // {\n // \"high\": \"35360.7\",\n // \"vol\": \"110288\",\n // \"low\": \"35347.9\",\n // \"idx\": 1699411680000,\n // \"close\": \"35347.9\",\n // \"open\": \"35349.4\"\n // }\n //\n let timestamp = this.safeTimestamp (ohlcv, 'i');\n if (timestamp === undefined) {\n timestamp = this.safeInteger (ohlcv, 'idx');\n }\n return [\n timestamp,\n this.safeNumber2 (ohlcv, 'o', 'open'),\n this.safeNumber2 (ohlcv, 'h', 'high'),\n this.safeNumber2 (ohlcv, 'l', 'low'),\n this.safeNumber2 (ohlcv, 'c', 'close'),\n this.safeNumber2 (ohlcv, 'v', 'vol'),\n ];\n }" }, %{ "comment" => nil, "examples" => [ "{\n \"symbol\":\"USDCUSDT\",\n \"orderId\":2878854881,\n \"clientOrderId\":\"\",\n \"transactTime\":1635551031276\n }", "{\n \"orderId\":1690615676032452985,\n }", "{\n \"symbol\":\"USDCUSDT\",\n \"orderId\":\"2878854881\",\n \"clientOrderId\":\"\",\n \"price\":\"1.1000000000000000\",\n \"origQty\":\"100.0000000000000000\",\n \"executedQty\":\"0.0000000000000000\",\n \"cummulativeQuoteQty\":\"0.0000000000000000\",\n \"status\":\"NEW\",\n \"timeInForce\":\"\",\n \"type\":\"LIMIT\",\n \"side\":\"SELL\",\n \"stopPrice\":\"\",\n \"icebergQty\":\"\",\n \"time\":1635551031000,\n \"updateTime\":1635551031000,\n \"isWorking\":false\n }", "{\n \"orderId\":1917641,\n \"price\":100,\n \"origQty\":10,\n \"origAmount\":10,\n \"executedQty\":1,\n \"avgPrice\":10000,\n \"status\":\"INIT\",\n \"type\":\"LIMIT\",\n \"side\":\"BUY\",\n \"action\":\"OPEN\",\n \"transactTime\":1686716571425\n \"clientOrderId\":4949299210\n }" ], "line_end" => 1987, "line_start" => 1872, "mappings" => [ %{ "comment" => nil, "key" => "info", "value" => "order" }, %{ "comment" => nil, "key" => "id", "value" => "id" }, %{ "comment" => nil, "key" => "clientOrderId", "value" => "clientOrderId" }, %{ "comment" => nil, "key" => "timestamp", "value" => "timestamp" }, %{ "comment" => nil, "key" => "datetime", "value" => "this.iso8601 (timestamp)" }, %{ "comment" => nil, "key" => "lastTradeTimestamp", "value" => "lastTradeTimestamp" }, %{ "comment" => nil, "key" => "symbol", "value" => "symbol" }, %{ "comment" => nil, "key" => "type", "value" => "type" }, %{ "comment" => nil, "key" => "timeInForce", "value" => "timeInForce" }, %{ "comment" => nil, "key" => "postOnly", "value" => "postOnly" }, %{ "comment" => nil, "key" => "side", "value" => "side" }, %{ "comment" => nil, "key" => "price", "value" => "price" }, %{ "comment" => nil, "key" => "triggerPrice", "value" => "triggerPrice" }, %{ "comment" => nil, "key" => "amount", "value" => "amount" }, %{ "comment" => nil, "key" => "cost", "value" => "cost" }, %{ "comment" => nil, "key" => "average", "value" => "average" }, %{ "comment" => nil, "key" => "filled", "value" => "filled" }, %{ "comment" => nil, "key" => "remaining", "value" => "undefined" }, %{ "comment" => nil, "key" => "status", "value" => "status" }, %{ "comment" => nil, "key" => "fee", "value" => "undefined" }, %{ "comment" => nil, "key" => "trades", "value" => "fills" } ], "name" => "parseOrder", "signature" => "parseOrder (order: Dict, market: Market = undefined): Order", "source" => "parseOrder (order: Dict, market: Market = undefined): Order {\n //\n // createOrder - spot\n //\n // {\n // \"symbol\":\"USDCUSDT\",\n // \"orderId\":2878854881,\n // \"clientOrderId\":\"\",\n // \"transactTime\":1635551031276\n // }\n //\n // createOrder - future\n //\n // {\n // \"orderId\":1690615676032452985,\n // }\n //\n // fetchOrders - spot\n //\n // {\n // \"symbol\":\"USDCUSDT\",\n // \"orderId\":\"2878854881\",\n // \"clientOrderId\":\"\",\n // \"price\":\"1.1000000000000000\",\n // \"origQty\":\"100.0000000000000000\",\n // \"executedQty\":\"0.0000000000000000\",\n // \"cummulativeQuoteQty\":\"0.0000000000000000\",\n // \"status\":\"NEW\",\n // \"timeInForce\":\"\",\n // \"type\":\"LIMIT\",\n // \"side\":\"SELL\",\n // \"stopPrice\":\"\",\n // \"icebergQty\":\"\",\n // \"time\":1635551031000,\n // \"updateTime\":1635551031000,\n // \"isWorking\":false\n // }\n //\n // fetchOrders - future\n //\n // {\n // \"orderId\":1917641,\n // \"price\":100,\n // \"origQty\":10,\n // \"origAmount\":10,\n // \"executedQty\":1,\n // \"avgPrice\":10000,\n // \"status\":\"INIT\",\n // \"type\":\"LIMIT\",\n // \"side\":\"BUY\",\n // \"action\":\"OPEN\",\n // \"transactTime\":1686716571425\n // \"clientOrderId\":4949299210\n // }\n //\n const status = this.parseOrderStatus (this.safeString2 (order, 'status', 'orderStatus'));\n const marketId = this.safeString (order, 'symbol');\n const symbol = this.safeSymbol (marketId, market);\n const filled = this.safeString (order, 'executedQty');\n let timestamp = undefined;\n let lastTradeTimestamp = undefined;\n if ('time' in order) {\n timestamp = this.safeInteger (order, 'time');\n } else if ('transactTime' in order) {\n timestamp = this.safeInteger (order, 'transactTime');\n } else if ('updateTime' in order) {\n if (status === 'open') {\n if (Precise.stringGt (filled, '0')) {\n lastTradeTimestamp = this.safeInteger (order, 'updateTime');\n } else {\n timestamp = this.safeInteger (order, 'updateTime');\n }\n }\n }\n const average = this.safeString (order, 'avgPrice');\n const price = this.safeString (order, 'price');\n const amount = this.safeString (order, 'origQty');\n // - Spot/Margin market: cummulativeQuoteQty\n // - Futures market: cumQuote.\n // Note this is not the actual cost, since Binance futures uses leverage to calculate margins.\n const cost = this.safeString2 (order, 'cummulativeQuoteQty', 'cumQuote');\n const id = this.safeString (order, 'orderId');\n let type = this.safeStringLower (order, 'type');\n const side = this.safeStringLower (order, 'side');\n const fills = this.safeList (order, 'fills', []);\n const clientOrderId = this.safeString (order, 'clientOrderId');\n const timeInForce = this.safeString (order, 'timeInForce');\n const postOnly = (type === 'limit_maker') || (timeInForce === 'GTX') || (type === 'post_only');\n if (type === 'limit_maker') {\n type = 'limit';\n }\n const triggerPrice = this.parseNumber (this.omitZero (this.safeString (order, 'stopPrice')));\n return this.safeOrder ({\n 'info': order,\n 'id': id,\n 'clientOrderId': clientOrderId,\n 'timestamp': timestamp,\n 'datetime': this.iso8601 (timestamp),\n 'lastTradeTimestamp': lastTradeTimestamp,\n 'symbol': symbol,\n 'type': type,\n 'timeInForce': timeInForce,\n 'postOnly': postOnly,\n 'side': side,\n 'price': price,\n 'triggerPrice': triggerPrice,\n 'amount': amount,\n 'cost': cost,\n 'average': average,\n 'filled': filled,\n 'remaining': undefined,\n 'status': status,\n 'fee': undefined,\n 'trades': fills,\n }, market);\n }" }, %{ "comment" => nil, "examples" => [], "line_end" => 1870, "line_start" => 1857, "mappings" => [], "name" => "parseOrderStatus", "signature" => "parseOrderStatus (status: Str)", "source" => "parseOrderStatus (status: Str) {\n const statuses: Dict = {\n 'INIT': 'open',\n 'PENDING_CREATE': 'open',\n 'NEW': 'open',\n 'PARTIALLY_FILLED': 'open',\n 'FILLED': 'closed',\n 'CANCELED': 'canceled',\n 'PENDING_CANCEL': 'canceling', // currently unused\n 'REJECTED': 'rejected',\n 'EXPIRED': 'expired',\n };\n return this.safeString (statuses, status, status);\n }" }, %{ "comment" => nil, "examples" => [ "{\n \"symbol\": \"LTCBTC\",\n \"bidPrice\": \"4.00000000\",\n \"bidQty\": \"431.00000000\",\n \"askPrice\": \"4.00000200\",\n \"askQty\": \"9.00000000\"\n }", "{\n \"symbol\": \"BNBBTC\",\n \"priceChange\": \"0.000248\",\n \"priceChangePercent\": \"3.5500\",\n \"weightedAvgPrice\": null,\n \"prevClosePrice\": null,\n \"lastPrice\": \"0.007226\",\n \"lastQty\": null,\n \"bidPrice\": \"0.007208\",\n \"askPrice\": \"0.007240\",\n \"openPrice\": \"0.006978\",\n \"highPrice\": \"0.007295\",\n \"lowPrice\": \"0.006935\",\n \"volume\": \"11749.86\",\n \"quoteVolume\": \"84.1066211\",\n \"openTime\": 0,\n \"closeTime\": 0,\n \"firstId\": 0,\n \"lastId\": 0,\n \"count\": 0\n }" ], "line_end" => 1361, "line_start" => 1294, "mappings" => [ %{ "comment" => nil, "key" => "symbol", "value" => "symbol" }, %{ "comment" => nil, "key" => "timestamp", "value" => "timestamp" }, %{ "comment" => nil, "key" => "datetime", "value" => "this.iso8601 (timestamp)" }, %{ "comment" => nil, "key" => "high", "value" => "this.safeString2 (ticker, 'highPrice', 'high')" }, %{ "comment" => nil, "key" => "low", "value" => "this.safeString2 (ticker, 'lowPrice', 'low')" }, %{ "comment" => nil, "key" => "bid", "value" => "this.safeString2 (ticker, 'bidPrice', 'buy')" }, %{ "comment" => nil, "key" => "bidVolume", "value" => "this.safeString (ticker, 'bidQty')" }, %{ "comment" => nil, "key" => "ask", "value" => "this.safeString2 (ticker, 'askPrice', 'sell')" }, %{ "comment" => nil, "key" => "askVolume", "value" => "this.safeString (ticker, 'askQty')" }, %{ "comment" => nil, "key" => "vwap", "value" => "this.safeString (ticker, 'weightedAvgPrice')" }, %{ "comment" => nil, "key" => "open", "value" => "this.safeString (ticker, 'openPrice')" }, %{ "comment" => nil, "key" => "close", "value" => "last" }, %{ "comment" => nil, "key" => "last", "value" => "last" }, %{ "comment" => nil, "key" => "previousClose", "value" => "undefined" }, %{ "comment" => nil, "key" => "change", "value" => "this.safeString (ticker, 'priceChange')" }, %{ "comment" => nil, "key" => "percentage", "value" => "percentage" }, %{ "comment" => nil, "key" => "average", "value" => "undefined" }, %{ "comment" => nil, "key" => "baseVolume", "value" => "this.safeString2 (ticker, 'volume', 'vol')" }, %{ "comment" => nil, "key" => "quoteVolume", "value" => "this.safeString (ticker, 'quoteVolume')" }, %{ "comment" => nil, "key" => "info", "value" => "ticker" } ], "name" => "parseTicker", "signature" => "parseTicker (ticker: Dict, market: Market = undefined): Ticker", "source" => "parseTicker (ticker: Dict, market: Market = undefined): Ticker {\n //\n // fetchBidsAsks\n //\n // {\n // \"symbol\": \"LTCBTC\",\n // \"bidPrice\": \"4.00000000\",\n // \"bidQty\": \"431.00000000\",\n // \"askPrice\": \"4.00000200\",\n // \"askQty\": \"9.00000000\"\n // }\n //\n // fetchTicker\n //\n // {\n // \"symbol\": \"BNBBTC\",\n // \"priceChange\": \"0.000248\",\n // \"priceChangePercent\": \"3.5500\",\n // \"weightedAvgPrice\": null,\n // \"prevClosePrice\": null,\n // \"lastPrice\": \"0.007226\",\n // \"lastQty\": null,\n // \"bidPrice\": \"0.007208\",\n // \"askPrice\": \"0.007240\",\n // \"openPrice\": \"0.006978\",\n // \"highPrice\": \"0.007295\",\n // \"lowPrice\": \"0.006935\",\n // \"volume\": \"11749.86\",\n // \"quoteVolume\": \"84.1066211\",\n // \"openTime\": 0,\n // \"closeTime\": 0,\n // \"firstId\": 0,\n // \"lastId\": 0,\n // \"count\": 0\n // }\n //\n const symbol = this.safeSymbol (undefined, market);\n const last = this.safeString2 (ticker, 'lastPrice', 'last');\n const timestamp = this.safeInteger (ticker, 'time');\n let percentage = undefined;\n if (market['swap']) {\n percentage = Precise.stringMul (this.safeString (ticker, 'rose'), '100');\n } else {\n percentage = this.safeString (ticker, 'priceChangePercent');\n }\n return this.safeTicker ({\n 'symbol': symbol,\n 'timestamp': timestamp,\n 'datetime': this.iso8601 (timestamp),\n 'high': this.safeString2 (ticker, 'highPrice', 'high'),\n 'low': this.safeString2 (ticker, 'lowPrice', 'low'),\n 'bid': this.safeString2 (ticker, 'bidPrice', 'buy'),\n 'bidVolume': this.safeString (ticker, 'bidQty'),\n 'ask': this.safeString2 (ticker, 'askPrice', 'sell'),\n 'askVolume': this.safeString (ticker, 'askQty'),\n 'vwap': this.safeString (ticker, 'weightedAvgPrice'),\n 'open': this.safeString (ticker, 'openPrice'),\n 'close': last,\n 'last': last,\n 'previousClose': undefined,\n 'change': this.safeString (ticker, 'priceChange'),\n 'percentage': percentage,\n 'average': undefined,\n 'baseVolume': this.safeString2 (ticker, 'volume', 'vol'),\n 'quoteVolume': this.safeString (ticker, 'quoteVolume'),\n 'info': ticker,\n }, market);\n }" }, %{ "comment" => nil, "examples" => [ "{\n \"id\": 28457,\n \"price\": \"4.00000100\",\n \"qty\": \"12.00000000\",\n \"time\": 1499865549590, // Actual timestamp of trade\n \"isBuyerMaker\": true,\n \"isBestMatch\": true\n }", "{\n \"symbol\":\"USDCUSDT\",\n \"id\":20725156,\n \"orderId\":2880918576,\n \"origClientOrderId\":null,\n \"price\":\"0.9996000000000000\",\n \"qty\":\"100.0000000000000000\",\n \"commission\":null,\n \"commissionAssert\":null,\n \"time\":1635558511000,\n \"isBuyer\":false,\n \"isMaker\":false,\n \"isBestMatch\":true\n }", "{\n \"tradeId\":12,\n \"price\":0.9,\n \"qty\":1,\n \"amount\":9,\n \"contractName\":\"E-SAND-USDT\",\n \"side\":\"BUY\",\n \"fee\":\"0.0018\",\n \"bidId\":1558124009467904992,\n \"askId\":1558124043827644908,\n \"bidUserId\":10294,\n \"askUserId\":10467,\n \"isBuyer\":true,\n \"isMaker\":true,\n \"ctime\":1678426306000\n }" ], "line_end" => 1811, "line_start" => 1719, "mappings" => [ %{ "comment" => nil, "key" => "info", "value" => "trade" }, %{ "comment" => nil, "key" => "timestamp", "value" => "timestamp" }, %{ "comment" => nil, "key" => "datetime", "value" => "this.iso8601 (timestamp)" }, %{ "comment" => nil, "key" => "symbol", "value" => "symbol" }, %{ "comment" => nil, "key" => "id", "value" => "id" }, %{ "comment" => nil, "key" => "order", "value" => "orderId" }, %{ "comment" => nil, "key" => "type", "value" => "undefined" }, %{ "comment" => nil, "key" => "side", "value" => "side" }, %{ "comment" => nil, "key" => "takerOrMaker", "value" => "takerOrMaker" }, %{ "comment" => nil, "key" => "price", "value" => "priceString" }, %{ "comment" => nil, "key" => "amount", "value" => "amountString" }, %{ "comment" => nil, "key" => "cost", "value" => "undefined" }, %{ "comment" => nil, "key" => "fee", "value" => "fee" } ], "name" => "parseTrade", "signature" => "parseTrade (trade: Dict, market: Market = undefined): Trade", "source" => "parseTrade (trade: Dict, market: Market = undefined): Trade {\n //\n // fetchTrades\n //\n // {\n // \"id\": 28457,\n // \"price\": \"4.00000100\",\n // \"qty\": \"12.00000000\",\n // \"time\": 1499865549590, // Actual timestamp of trade\n // \"isBuyerMaker\": true,\n // \"isBestMatch\": true\n // }\n //\n // fetchTrades - spot\n //\n // {\n // \"symbol\":\"USDCUSDT\",\n // \"id\":20725156,\n // \"orderId\":2880918576,\n // \"origClientOrderId\":null,\n // \"price\":\"0.9996000000000000\",\n // \"qty\":\"100.0000000000000000\",\n // \"commission\":null,\n // \"commissionAssert\":null,\n // \"time\":1635558511000,\n // \"isBuyer\":false,\n // \"isMaker\":false,\n // \"isBestMatch\":true\n // }\n //\n // fetchTrades - future\n //\n // {\n // \"tradeId\":12,\n // \"price\":0.9,\n // \"qty\":1,\n // \"amount\":9,\n // \"contractName\":\"E-SAND-USDT\",\n // \"side\":\"BUY\",\n // \"fee\":\"0.0018\",\n // \"bidId\":1558124009467904992,\n // \"askId\":1558124043827644908,\n // \"bidUserId\":10294,\n // \"askUserId\":10467,\n // \"isBuyer\":true,\n // \"isMaker\":true,\n // \"ctime\":1678426306000\n // }\n //\n const timestamp = this.safeInteger2 (trade, 'ctime', 'time');\n const priceString = this.safeString (trade, 'price');\n const amountString = this.safeString (trade, 'qty');\n const marketId = this.safeString2 (trade, 'symbol', 'contractName');\n const symbol = this.safeSymbol (marketId, market);\n const orderId = this.safeString (trade, 'orderId');\n const id = this.safeString2 (trade, 'id', 'tradeId');\n let side = undefined;\n const buyerMaker = this.safeBool (trade, 'isBuyerMaker'); // ignore \"m\" until Bitrue fixes api\n const isBuyer = this.safeBool (trade, 'isBuyer');\n if (buyerMaker !== undefined) {\n side = buyerMaker ? 'sell' : 'buy';\n }\n if (isBuyer !== undefined) {\n side = isBuyer ? 'buy' : 'sell'; // this is a true side\n }\n let fee = undefined;\n if ('commission' in trade) {\n fee = {\n 'cost': this.safeString2 (trade, 'commission', 'fee'),\n 'currency': this.safeCurrencyCode (this.safeString (trade, 'commissionAssert')),\n };\n }\n let takerOrMaker = undefined;\n const isMaker = this.safeBool (trade, 'isMaker');\n if (isMaker !== undefined) {\n takerOrMaker = isMaker ? 'maker' : 'taker';\n }\n return this.safeTrade ({\n 'info': trade,\n 'timestamp': timestamp,\n 'datetime': this.iso8601 (timestamp),\n 'symbol': symbol,\n 'id': id,\n 'order': orderId,\n 'type': undefined,\n 'side': side,\n 'takerOrMaker': takerOrMaker,\n 'price': priceString,\n 'amount': amountString,\n 'cost': undefined,\n 'fee': fee,\n }, market);\n }" }, %{ "comment" => nil, "examples" => [ "{\n \"symbol\": \"XRP\",\n \"amount\": \"261.3361000000000000\",\n \"fee\": \"0.0E-15\",\n \"createdAt\": 1548816979000,\n \"updatedAt\": 1548816999000,\n \"addressFrom\": \"\",\n \"addressTo\": \"raLPjTYeGezfdb6crXZzcC8RkLBEwbBHJ5_18113641\",\n \"txid\": \"86D6EB68A7A28938BCE06BD348F8C07DEF500C5F7FE92069EF8C0551CE0F2C7D\",\n \"confirmations\": 8,\n \"status\": 1,\n \"tagType\": \"Tag\"\n },", "{\n \"symbol\": \"XRP\",\n \"amount\": \"20.0000000000000000\",\n \"fee\": \"0.0E-15\",\n \"createdAt\": 1544669393000,\n \"updatedAt\": 1544669413000,\n \"addressFrom\": \"\",\n \"addressTo\": \"raLPjTYeGezfdb6crXZzcC8RkLBEwbBHJ5_18113641\",\n \"txid\": \"515B23E1F9864D3AF7F5B4C4FCBED784BAE861854FAB95F4031922B6AAEFC7AC\",\n \"confirmations\": 7,\n \"status\": 1,\n \"tagType\": \"Tag\"\n }", "{\n \"id\": 183745,\n \"symbol\": \"usdt_erc20\",\n \"amount\": \"8.4000000000000000\",\n \"fee\": \"1.6000000000000000\",\n \"payAmount\": \"0.0000000000000000\",\n \"createdAt\": 1595336441000,\n \"updatedAt\": 1595336576000,\n \"addressFrom\": \"\",\n \"addressTo\": \"0x2edfae3878d7b6db70ce4abed177ab2636f60c83\",\n \"txid\": \"\",\n \"confirmations\": 0,\n \"status\": 6,\n \"tagType\": null\n }", "{\n \"msg\": null,\n \"amount\": 1000,\n \"fee\": 1,\n \"ctime\": null,\n \"coin\": \"usdt_erc20\",\n \"withdrawId\": 1156423,\n \"addressTo\": \"0x2edfae3878d7b6db70ce4abed177ab2636f60c83\"\n }" ], "line_end" => 2859, "line_start" => 2734, "mappings" => [ %{ "comment" => nil, "key" => "info", "value" => "transaction" }, %{ "comment" => nil, "key" => "id", "value" => "id" }, %{ "comment" => nil, "key" => "txid", "value" => "txid" }, %{ "comment" => nil, "key" => "timestamp", "value" => "timestamp" }, %{ "comment" => nil, "key" => "datetime", "value" => "this.iso8601 (timestamp)" }, %{ "comment" => nil, "key" => "network", "value" => "network" }, %{ "comment" => nil, "key" => "address", "value" => "addressTo" }, %{ "comment" => nil, "key" => "addressTo", "value" => "addressTo" }, %{ "comment" => nil, "key" => "addressFrom", "value" => "addressFrom" }, %{ "comment" => nil, "key" => "tag", "value" => "tagTo" }, %{ "comment" => nil, "key" => "tagTo", "value" => "tagTo" }, %{ "comment" => nil, "key" => "tagFrom", "value" => "tagFrom" }, %{ "comment" => nil, "key" => "type", "value" => "type" }, %{ "comment" => nil, "key" => "amount", "value" => "amount" }, %{ "comment" => nil, "key" => "currency", "value" => "code" }, %{ "comment" => nil, "key" => "status", "value" => "status" }, %{ "comment" => nil, "key" => "updated", "value" => "updated" }, %{ "comment" => nil, "key" => "internal", "value" => "false" }, %{ "comment" => nil, "key" => "comment", "value" => "undefined" }, %{ "comment" => nil, "key" => "fee", "value" => "fee" } ], "name" => "parseTransaction", "signature" => "parseTransaction (transaction: Dict, currency: Currency = undefined): Transaction", "source" => "parseTransaction (transaction: Dict, currency: Currency = undefined): Transaction {\n //\n // fetchDeposits\n //\n // {\n // \"symbol\": \"XRP\",\n // \"amount\": \"261.3361000000000000\",\n // \"fee\": \"0.0E-15\",\n // \"createdAt\": 1548816979000,\n // \"updatedAt\": 1548816999000,\n // \"addressFrom\": \"\",\n // \"addressTo\": \"raLPjTYeGezfdb6crXZzcC8RkLBEwbBHJ5_18113641\",\n // \"txid\": \"86D6EB68A7A28938BCE06BD348F8C07DEF500C5F7FE92069EF8C0551CE0F2C7D\",\n // \"confirmations\": 8,\n // \"status\": 1,\n // \"tagType\": \"Tag\"\n // },\n // {\n // \"symbol\": \"XRP\",\n // \"amount\": \"20.0000000000000000\",\n // \"fee\": \"0.0E-15\",\n // \"createdAt\": 1544669393000,\n // \"updatedAt\": 1544669413000,\n // \"addressFrom\": \"\",\n // \"addressTo\": \"raLPjTYeGezfdb6crXZzcC8RkLBEwbBHJ5_18113641\",\n // \"txid\": \"515B23E1F9864D3AF7F5B4C4FCBED784BAE861854FAB95F4031922B6AAEFC7AC\",\n // \"confirmations\": 7,\n // \"status\": 1,\n // \"tagType\": \"Tag\"\n // }\n //\n // fetchWithdrawals\n //\n // {\n // \"id\": 183745,\n // \"symbol\": \"usdt_erc20\",\n // \"amount\": \"8.4000000000000000\",\n // \"fee\": \"1.6000000000000000\",\n // \"payAmount\": \"0.0000000000000000\",\n // \"createdAt\": 1595336441000,\n // \"updatedAt\": 1595336576000,\n // \"addressFrom\": \"\",\n // \"addressTo\": \"0x2edfae3878d7b6db70ce4abed177ab2636f60c83\",\n // \"txid\": \"\",\n // \"confirmations\": 0,\n // \"status\": 6,\n // \"tagType\": null\n // }\n //\n // withdraw\n //\n // {\n // \"msg\": null,\n // \"amount\": 1000,\n // \"fee\": 1,\n // \"ctime\": null,\n // \"coin\": \"usdt_erc20\",\n // \"withdrawId\": 1156423,\n // \"addressTo\": \"0x2edfae3878d7b6db70ce4abed177ab2636f60c83\"\n // }\n //\n const id = this.safeString2 (transaction, 'id', 'withdrawId');\n const tagType = this.safeString (transaction, 'tagType');\n let addressTo = this.safeString (transaction, 'addressTo');\n let addressFrom = this.safeString (transaction, 'addressFrom');\n let tagTo = undefined;\n let tagFrom = undefined;\n if (tagType !== undefined) {\n if (addressTo !== undefined) {\n const parts = addressTo.split ('_');\n addressTo = this.safeString (parts, 0);\n tagTo = this.safeString (parts, 1);\n }\n if (addressFrom !== undefined) {\n const parts = addressFrom.split ('_');\n addressFrom = this.safeString (parts, 0);\n tagFrom = this.safeString (parts, 1);\n }\n }\n const txid = this.safeString (transaction, 'txid');\n const timestamp = this.safeInteger (transaction, 'createdAt');\n const updated = this.safeInteger (transaction, 'updatedAt');\n const payAmount = ('payAmount' in transaction);\n const ctime = ('ctime' in transaction);\n const type = (payAmount || ctime) ? 'withdrawal' : 'deposit';\n const status = this.parseTransactionStatusByType (this.safeString (transaction, 'status'), type);\n const amount = this.safeNumber (transaction, 'amount');\n let network = undefined;\n let currencyId = this.safeString2 (transaction, 'symbol', 'coin');\n if (currencyId !== undefined) {\n const parts = currencyId.split ('_');\n currencyId = this.safeString (parts, 0);\n const networkId = this.safeString (parts, 1);\n if (networkId !== undefined) {\n network = networkId.toUpperCase ();\n }\n }\n const code = this.safeCurrencyCode (currencyId, currency);\n const feeCost = this.safeNumber (transaction, 'fee');\n let fee = undefined;\n if (feeCost !== undefined) {\n fee = { 'currency': code, 'cost': feeCost };\n }\n return {\n 'info': transaction,\n 'id': id,\n 'txid': txid,\n 'timestamp': timestamp,\n 'datetime': this.iso8601 (timestamp),\n 'network': network,\n 'address': addressTo,\n 'addressTo': addressTo,\n 'addressFrom': addressFrom,\n 'tag': tagTo,\n 'tagTo': tagTo,\n 'tagFrom': tagFrom,\n 'type': type,\n 'amount': amount,\n 'currency': code,\n 'status': status,\n 'updated': updated,\n 'internal': false,\n 'comment': undefined,\n 'fee': fee,\n } as Transaction;\n }" }, %{ "comment" => nil, "examples" => [], "line_end" => 2732, "line_start" => 2718, "mappings" => [], "name" => "parseTransactionStatusByType", "signature" => "parseTransactionStatusByType (status, type = undefined)", "source" => "parseTransactionStatusByType (status, type = undefined) {\n const statusesByType: Dict = {\n 'deposit': {\n '0': 'pending',\n '1': 'ok',\n },\n 'withdrawal': {\n '0': 'pending', // Email Sent\n '5': 'ok', // Failure\n '6': 'canceled',\n },\n };\n const statuses = this.safeDict (statusesByType, type, {});\n return this.safeString (statuses, status, status);\n }" }, %{ "comment" => nil, "examples" => [ "{\n 'transferType': 'wallet_to_contract',\n 'symbol': 'USDT',\n 'amount': 1.0,\n 'status': 1,\n 'ctime': 1685404575000\n }" ], "line_end" => 3009, "line_start" => 2973, "mappings" => [ %{ "comment" => nil, "key" => "info", "value" => "transfer" }, %{ "comment" => nil, "key" => "id", "value" => "undefined" }, %{ "comment" => nil, "key" => "timestamp", "value" => "timestamp" }, %{ "comment" => nil, "key" => "datetime", "value" => "this.iso8601 (timestamp)" }, %{ "comment" => nil, "key" => "currency", "value" => "this.safeString (currency, 'code')" }, %{ "comment" => nil, "key" => "amount", "value" => "this.safeNumber (transfer, 'amount')" }, %{ "comment" => nil, "key" => "fromAccount", "value" => "fromAccount" }, %{ "comment" => nil, "key" => "toAccount", "value" => "toAccount" }, %{ "comment" => nil, "key" => "status", "value" => "'ok'" } ], "name" => "parseTransfer", "signature" => "parseTransfer (transfer, currency = undefined)", "source" => "parseTransfer (transfer, currency = undefined) {\n //\n // fetchTransfers\n //\n // {\n // 'transferType': 'wallet_to_contract',\n // 'symbol': 'USDT',\n // 'amount': 1.0,\n // 'status': 1,\n // 'ctime': 1685404575000\n // }\n //\n // transfer\n //\n // {}\n //\n const transferType = this.safeString (transfer, 'transferType');\n let fromAccount = undefined;\n let toAccount = undefined;\n if (transferType !== undefined) {\n const accountSplit = transferType.split ('_to_');\n fromAccount = this.safeString (accountSplit, 0);\n toAccount = this.safeString (accountSplit, 1);\n }\n const timestamp = this.safeInteger (transfer, 'ctime');\n return {\n 'info': transfer,\n 'id': undefined,\n 'timestamp': timestamp,\n 'datetime': this.iso8601 (timestamp),\n 'currency': this.safeString (currency, 'code'),\n 'amount': this.safeNumber (transfer, 'amount'),\n 'fromAccount': fromAccount,\n 'toAccount': toAccount,\n 'status': 'ok',\n };\n }" } ], path_prefix: "", pro: true, quote_json_numbers: nil, rate_limits: %{ interval_ms: 10, period: 1000, requests: 100, rolling_window_size: 60000 }, raw_endpoints: %{ private: [], public: [] }, required_credentials: %{ api_key: true, password: false, secret: true, uid: false }, requires_eddsa: false, response_error: %{ code_field: "code", field: "code", message_field: "msg", success_values: [ "200", "0" ], type: :error_field_present }, signing: %{ api_key_header: "X-MBX-APIKEY", confidence: :high, pattern: :hmac_sha256_query, recv_window: 5000, uses_recv_window: true }, spec_format_version: 1, status: %{ "eta" => nil, "status" => "ok", "updated" => nil, "url" => nil }, symbol_format: nil, symbol_formats: %{ precision_mode: 4, sample_limits: %{ "amount" => %{ "max" => 999999999999, "min" => 48.6901257 }, "cost" => %{ "min" => 1 }, "price" => %{ "max" => 0.145830979, "min" => 0.00145830979 } }, sample_precision: %{ "amount" => 1.0e-7, "price" => 1.0e-10 }, spot: %{ base: "LQTY3S", base_id: "lqty3s", case: :upper, contract: false, id: "LQTY3SUSDT", limits: %{ "amount" => %{ "max" => 999999999999, "min" => 48.6901257 }, "cost" => %{ "min" => 1 }, "leverage" => %{}, "price" => %{ "max" => 0.145830979, "min" => 0.00145830979 } }, maker: 9.8e-4, precision: %{ "amount" => 1.0e-7, "price" => 1.0e-10 }, quote: "USDT", quote_id: "usdt", separator: "", symbol: "LQTY3S/USDT", taker: 9.8e-4 } }, symbol_patterns: %{ spot: %{ case: :upper, component_order: nil, date_format: nil, pattern: :no_separator_upper, separator: "", suffix: nil } }, timeframes: %{ "15m" => "15m", "1d" => "1D", "1h" => "1H", "1m" => "1m", "1w" => "1W", "2h" => "2H", "30m" => "30m", "4h" => "4H", "5m" => "5m" }, url_strategy: %{ detected_from: "fallback", pattern: :no_prefix, prefix: nil }, urls: %{ api: "https://www.bitrue.com/api", api_sections: %{ "dapi" => "https://fapi.bitrue.com/dapi", "fapi" => "https://fapi.bitrue.com/fapi", "kline" => "https://www.bitrue.com/kline-api", "spot" => "https://www.bitrue.com/api" }, doc: [ "https://github.com/Bitrue-exchange/bitrue-official-api-docs", "https://www.bitrue.com/api-docs" ], other: nil, sandbox: nil, www: "https://www.bitrue.com" }, version: "v1", ws: %{ channel_templates: %{ watch_balance: %{ auth_required: true, market_id_format: :native, params: [], pattern: :event_sub }, watch_order_book: %{ channel_name: "market_", market_id_format: :native, params: [], pattern: :event_sub }, watch_orders: %{ auth_required: true, market_id_format: :native, params: [ %{ "default" => nil, "name" => "limit" } ], pattern: :event_sub } }, has: %{ watch_balance: true, watch_bids_asks: nil, watch_liquidations: nil, watch_liquidations_for_symbols: nil, watch_my_liquidations: nil, watch_my_liquidations_for_symbols: nil, watch_my_trades: false, watch_ohlcv: false, watch_ohlcv_for_symbols: nil, watch_order_book: true, watch_order_book_for_symbols: nil, watch_orders: true, watch_orders_for_symbols: nil, watch_position: nil, watch_positions: nil, watch_status: nil, watch_ticker: false, watch_tickers: false, watch_trades: false, watch_trades_for_symbols: nil }, message_patterns: [ %{ args_field: "params", format: :event, keys: [ "event", "params" ], kind_field: "event", kind_value: "sub", sources: [ :send, :watch ] } ], options: %{ "ws" => %{ "gunzip" => true } }, subscription_config: %{ args_field: "topic", args_format: :string, market_id_format: :native, op_field: "event" }, subscription_pattern: :event_subscribe, urls: %{ "private" => "wss://wsapi.bitrue.com", "public" => "wss://ws.bitrue.com/market/ws" }, watch_methods: [ "watchBalance", "watchOrderBook", "watchOrders" ] } }