# XT Exchange Specification # # Auto-generated by: mix ccxt.extract xt # 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: [ "SC" ], currencies: %{}, currency_aliases: %{ "BCHSV" => "BSV", "XBT" => "BTC" }, dex: false, enable_rate_limit: true, endpoint_extraction_stats: %{ "capturedMethods" => 37, "coveragePercent" => 100, "enabledMethods" => 43, "excluded" => [], "excludedMethods" => 0, "extractableMethods" => 43, "failures" => [ %{ "error" => "xt cancelOrders() does not support swap and future orders, only spot orders are accepted", "method" => "cancelOrders" }, %{ "error" => "xt createOrder() requires a price argument or cost in params for market buy orders on spot markets to calculate the total amount to spend (amount * price), alternatively set the createMarketBuyOrderRequiresPrice option to false and pass in the cost to spend into the amount parameter", "method" => "createMarketOrder" }, %{ "error" => "xt fetchDepositAddress() requires a network argument", "method" => "fetchDepositAddress" }, %{ "error" => "xt fetchLedger() does not support spot transactions, only swap and future wallet transactions are supported", "method" => "fetchLedger" }, %{ "error" => "xt setLeverage() requires a positionSide argument, one of (LONG, SHORT)", "method" => "setLeverage" }, %{ "error" => "xt setMarginMode() requires a positionSide parameter, either \"LONG\" or \"SHORT\"", "method" => "setMarginMode" } ] }, endpoints: [ %{ api_section: "private/spot", auth: true, cost: 1, default_params: %{ "bizType" => "SPOT" }, market_type: :spot, method: :delete, name: :cancel_all_orders, param_mappings: %{}, params: [ :symbol ], path: "/open-order", response_transformer: {:extract_path, ["result"]}, source: :intercepted }, %{ api_section: "private/spot", auth: true, cost: 1, market_type: :spot, method: :delete, name: :cancel_order, param_mappings: %{ "id" => "orderId" }, params: [ :id, :symbol ], path: "/order/{orderId}", response_transformer: {:extract_path, ["result"]}, source: :intercepted }, %{ api_section: "private/spot", auth: true, cost: 0.2, default_params: %{ "bizType" => "SPOT", "timeInForce" => "GTC", "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, ["result"]}, source: :intercepted }, %{ api_section: "private/spot", auth: true, cost: 0.2, default_params: %{ "bizType" => "SPOT", "side" => "BUY", "timeInForce" => "FOK", "type" => "MARKET" }, market_type: :spot, method: :post, name: :create_market_buy_order_with_cost, param_mappings: %{ "cost" => "quoteQty" }, params: [ :symbol, :cost ], path: "/order", response_transformer: {:extract_path, ["result"]}, source: :intercepted }, %{ api_section: "private/spot", auth: true, cost: 0.2, default_params: %{ "bizType" => "SPOT", "timeInForce" => "GTC" }, market_type: :spot, method: :post, name: :create_order, param_mappings: %{ "amount" => "quantity" }, params: [ :symbol, :type, :side, :amount, :price ], path: "/order", response_transformer: {:extract_path, ["result"]}, source: :intercepted }, %{ api_section: "private/linear", auth: true, cost: 1, default_params: %{ "positionSide" => "SHORT", "reduceOnly" => true, "symbol" => "BTCUSDT" }, market_type: :swap, method: :post, name: :create_reduce_only_order, param_mappings: %{ "amount" => "origQty", "side" => "orderSide", "type" => "orderType" }, params: [ :symbol, :type, :side, :amount, :price ], path: "/future/trade/v1/order/create", response_transformer: {:extract_path, ["result"]}, source: :intercepted }, %{ api_section: "private/spot", auth: true, cost: 1, market_type: :spot, method: :put, name: :edit_order, param_mappings: %{ "amount" => "quantity", "id" => "orderId" }, params: [ :id, :symbol, :type, :side, :amount, :price ], path: "/order/{orderId}", response_transformer: {:extract_path, ["result"]}, source: :intercepted }, %{ api_section: "private/spot", auth: true, cost: 1, market_type: :spot, method: :get, name: :fetch_balance, param_mappings: %{}, params: [], path: "/balances", response_transformer: {:extract_path, ["result", "assets"]}, source: :intercepted }, %{ api_section: "public/spot", auth: false, cost: 1, market_type: :spot, method: :get, name: :fetch_bids_asks, param_mappings: %{}, params: [ :symbols ], path: "/ticker/book", response_transformer: {:extract_path, ["result"]}, source: :intercepted }, %{ api_section: "private/spot", auth: true, cost: 1, default_params: %{ "bizType" => "SPOT", "state" => "CANCELED" }, market_type: :spot, method: :get, name: :fetch_canceled_orders, param_mappings: %{}, params: [ :symbol, :since, :limit ], path: "/history-order", response_transformer: {:extract_path, ["result", "items"]}, source: :intercepted }, %{ api_section: "private/spot", auth: true, cost: 1, default_params: %{ "bizType" => "SPOT", "state" => "FILLED" }, market_type: :spot, method: :get, name: :fetch_closed_orders, param_mappings: %{}, params: [ :symbol, :since, :limit ], path: "/history-order", response_transformer: {:extract_path, ["result", "items"]}, source: :intercepted }, %{ api_section: "public/spot", auth: false, cost: 1, market_type: :spot, method: :get, name: :fetch_currencies, param_mappings: %{}, params: [], path: "/wallet/support/currency", response_transformer: {:extract_path, ["result"]}, source: :intercepted }, %{ api_section: "private/spot", auth: true, cost: 1, market_type: :spot, method: :get, name: :fetch_deposits, param_mappings: %{ "code" => "currency" }, params: [ :code, :since, :limit ], path: "/deposit/history", response_transformer: {:extract_path, ["result", "items"]}, source: :intercepted }, %{ api_section: "private/linear", auth: true, cost: 1, default_params: %{ "symbol" => "BTCUSDT" }, market_type: :swap, method: :get, name: :fetch_funding_history, param_mappings: %{}, params: [ :symbol, :since, :limit ], path: "/future/user/v1/balance/funding-rate-list", response_transformer: {:extract_path, ["result", "items"]}, source: :intercepted }, %{ api_section: "public/linear", auth: false, cost: 1, default_params: %{ "symbol" => "BTCUSDT" }, market_type: :swap, method: :get, name: :fetch_funding_interval, param_mappings: %{}, params: [ :symbol ], path: "/future/market/v1/public/q/funding-rate", response_transformer: {:extract_path, ["result"]}, source: :intercepted }, %{ api_section: "public/linear", auth: false, cost: 1, default_params: %{ "symbol" => "BTCUSDT" }, market_type: :swap, method: :get, name: :fetch_funding_rate, param_mappings: %{}, params: [ :symbol ], path: "/future/market/v1/public/q/funding-rate", response_transformer: {:extract_path_unwrap, ["result"]}, source: :intercepted }, %{ api_section: "public/linear", auth: false, cost: 1, default_params: %{ "limit" => 200, "symbol" => "BTCUSDT" }, market_type: :swap, method: :get, name: :fetch_funding_rate_history, param_mappings: %{}, params: [ :symbol, :since, :limit ], path: "/future/market/v1/public/q/funding-rate-record", response_transformer: {:extract_path, ["result", "items"]}, source: :intercepted }, %{ api_section: "public/spot", auth: false, cost: 10, market_type: :spot, method: :get, name: :fetch_l2_order_book, param_mappings: %{}, params: [ :symbol, :limit ], path: "/depth", response_transformer: {:extract_path, ["result"]}, source: :intercepted }, %{ api_section: "public/linear", auth: false, cost: 1, market_type: :swap, method: :get, name: :fetch_leverage_tiers, param_mappings: %{}, params: [ :symbols ], path: "/future/market/v1/public/leverage/bracket/list", response_transformer: {:extract_path, ["result"]}, source: :intercepted }, %{ api_section: "public/linear", auth: false, cost: 1, default_params: %{ "symbol" => "BTCUSDT" }, market_type: :swap, method: :get, name: :fetch_market_leverage_tiers, param_mappings: %{}, params: [ :symbol ], path: "/future/market/v1/public/leverage/bracket/detail", response_transformer: {:extract_path, ["result"]}, source: :intercepted }, %{ api_section: "public/spot", auth: false, cost: 1, market_type: :spot, method: :get, name: :fetch_markets, param_mappings: %{}, params: [], path: "/symbol", response_transformer: {:extract_path, ["result", "symbols"]}, source: :intercepted }, %{ api_section: "private/spot", auth: true, cost: 1, default_params: %{ "bizType" => "SPOT" }, market_type: :spot, method: :get, name: :fetch_my_trades, param_mappings: %{}, params: [ :symbol, :since, :limit ], path: "/trade", response_transformer: {:extract_path, ["result", "items"]}, source: :intercepted }, %{ api_section: "public/spot", auth: false, cost: 1, market_type: :spot, method: :get, name: :fetch_ohlcv, param_mappings: %{ "since" => "startTime", "timeframe" => "interval" }, params: [ :symbol, :timeframe, :since, :limit ], path: "/kline", response_transformer: {:extract_path, ["result"]}, source: :intercepted }, %{ api_section: "private/spot", auth: true, cost: 1, default_params: %{ "bizType" => "SPOT" }, market_type: :spot, method: :get, name: :fetch_open_orders, param_mappings: %{}, params: [ :symbol, :since, :limit ], path: "/open-order", response_transformer: {:extract_path, ["result", "items"]}, source: :intercepted }, %{ api_section: "private/spot", auth: true, cost: 1, market_type: :spot, method: :get, name: :fetch_order, param_mappings: %{ "id" => "orderId" }, params: [ :id, :symbol ], path: "/order/{orderId}", response_transformer: {:extract_path_unwrap, ["result"]}, source: :intercepted }, %{ api_section: "public/spot", auth: false, cost: 10, market_type: :spot, method: :get, name: :fetch_order_book, param_mappings: %{}, params: [ :symbol, :limit ], path: "/depth", response_transformer: {:extract_path_unwrap, ["result"]}, source: :intercepted }, %{ api_section: "private/spot", auth: true, cost: 1, default_params: %{ "bizType" => "SPOT" }, market_type: :spot, method: :get, name: :fetch_orders, param_mappings: %{}, params: [ :symbol, :since, :limit ], path: "/history-order", response_transformer: {:extract_path, ["result", "items"]}, source: :intercepted }, %{ api_section: "private/spot", auth: true, cost: 1, default_params: %{ "bizType" => "SPOT" }, market_type: :spot, method: :get, name: :fetch_orders_by_status, param_mappings: %{ "arg1" => "symbol" }, params: [], path: "/open-order", response_transformer: {:extract_path, ["result", "items"]}, source: :intercepted }, %{ api_section: "private/linear", auth: true, cost: 1, default_params: %{ "symbol" => "BTCUSDT" }, market_type: :swap, method: :get, name: :fetch_position, param_mappings: %{}, params: [ :symbol ], path: "/future/user/v1/position/list", response_transformer: {:extract_path_unwrap, ["result"]}, source: :intercepted }, %{ api_section: "private/linear", auth: true, cost: 1, market_type: :swap, method: :get, name: :fetch_positions, param_mappings: %{}, params: [ :symbols ], path: "/future/user/v1/position/list", response_transformer: {:extract_path, ["result"]}, source: :intercepted }, %{ api_section: "public/spot", auth: false, cost: 1, market_type: :spot, method: :get, name: :fetch_ticker, param_mappings: %{}, params: [ :symbol ], path: "/ticker/24h", response_transformer: {:extract_path_unwrap, ["result"]}, source: :intercepted }, %{ api_section: "public/spot", auth: false, cost: 1, market_type: :spot, method: :get, name: :fetch_tickers, param_mappings: %{}, params: [ :symbols ], path: "/ticker/24h", response_transformer: {:extract_path, ["result"]}, source: :intercepted }, %{ api_section: "public/spot", auth: false, cost: 1, market_type: :spot, method: :get, name: :fetch_time, param_mappings: %{}, params: [], path: "/time", response_transformer: {:extract_path, ["result", "serverTime"]}, source: :intercepted }, %{ api_section: "public/spot", auth: false, cost: 1, market_type: :spot, method: :get, name: :fetch_trades, param_mappings: %{}, params: [ :symbol, :since, :limit ], path: "/trade/recent", response_transformer: {:extract_path, ["result"]}, source: :intercepted }, %{ api_section: "private/spot", auth: true, cost: 1, market_type: :spot, method: :get, name: :fetch_withdrawals, param_mappings: %{ "code" => "currency" }, params: [ :code, :since, :limit ], path: "/withdraw/history", response_transformer: {:extract_path, ["result", "items"]}, source: :intercepted }, %{ api_section: "private/spot", auth: true, cost: 1, default_params: %{ "bizId" => "", "to" => "" }, market_type: :spot, method: :post, name: :transfer, param_mappings: %{ "code" => "currency", "fromAccount" => "from" }, params: [ :code, :amount, :fromAccount, :toAccount ], path: "/balance/transfer", response_transformer: {:extract_path, ["result"]}, source: :intercepted }, %{ api_section: "private/spot", auth: true, cost: 10, default_params: %{ "chain" => "Bitcoin" }, market_type: :spot, method: :post, name: :withdraw, param_mappings: %{ "code" => "currency" }, params: [ :code, :amount, :address, :tag ], path: "/withdraw", response_transformer: {:extract_path, ["result"]}, source: :intercepted } ], error_code_details: %{ 400 => %{ description: "{\"returnCode\":1,\"msgInfo\":\"failure\",\"error\":{\"code\":\"400\",\"msg\":\"Connection refused: /10.0.26.71:8080\"},\"result\":null}", type: :network_error }, 404 => %{ description: "interface does not exist", type: :exchange_error }, 429 => %{ description: "The request is too frequent, please control the request rate according to the speed limit requirement", type: :rate_limited }, 500 => %{ description: "Service exception", type: :exchange_error }, 502 => %{ description: "Gateway exception", type: :exchange_error }, 503 => %{ description: "Service unavailable, please try again later", type: :network_error }, "AUTH_001" => %{ description: "missing request header xt-validate-appkey", type: :invalid_credentials }, "AUTH_002" => %{ description: "missing request header xt-validate-timestamp", type: :invalid_credentials }, "AUTH_003" => %{ description: "missing request header xt-validate-recvwindow", type: :invalid_credentials }, "AUTH_004" => %{ description: "bad request header xt-validate-recvwindow", type: :invalid_credentials }, "AUTH_005" => %{ description: "missing request header xt-validate-algorithms", type: :invalid_credentials }, "AUTH_006" => %{ description: "bad request header xt-validate-algorithms", type: :invalid_credentials }, "AUTH_007" => %{ description: "missing request header xt-validate-signature", type: :invalid_credentials }, "AUTH_101" => %{ description: "ApiKey does not exist", type: :invalid_credentials }, "AUTH_102" => %{ description: "ApiKey is not activated", type: :invalid_credentials }, "AUTH_103" => %{ description: "Signature error, {\"rc\":1,\"mc\":\"AUTH_103\",\"ma\":[],\"result\":null}", type: :invalid_credentials }, "AUTH_104" => %{ description: "Unbound IP request", type: :invalid_credentials }, "AUTH_105" => %{ description: "outdated message", type: :invalid_credentials }, "AUTH_106" => %{ description: "Exceeded apikey permission", type: :access_restricted }, "COMMON_001" => %{ description: "The user does not exist", type: :exchange_error }, "COMMON_002" => %{ description: "System busy, please try it later", type: :exchange_error }, "COMMON_003" => %{ description: "Operation failed, please try it later", type: :invalid_parameters }, "CURRENCY_001" => %{ description: "Information of currency is abnormal", type: :invalid_parameters }, "DEPOSIT_001" => %{ description: "Deposit is not open", type: :invalid_parameters }, "DEPOSIT_002" => %{ description: "The current account security level is low, please bind any two security verifications in mobile phone/email/Google Authenticator before deposit", type: :access_restricted }, "DEPOSIT_003" => %{ description: "The format of address is incorrect, please enter again", type: :invalid_parameters }, "DEPOSIT_004" => %{ description: "The address is already exists, please enter again", type: :invalid_parameters }, "DEPOSIT_005" => %{ description: "Can not find the address of offline wallet", type: :invalid_parameters }, "DEPOSIT_006" => %{ description: "No deposit address, please try it later", type: :invalid_parameters }, "DEPOSIT_007" => %{ description: "Address is being generated, please try it later", type: :invalid_parameters }, "DEPOSIT_008" => %{ description: "Deposit is not available", type: :invalid_parameters }, "Exceeds the minimum notional value of a single order" => %{ description: "{\"returnCode\":1,\"msgInfo\":\"failure\",\"error\":{\"code\":\"open_order_min_nominal_value_limit\",\"msg\":\"Exceeds the minimum notional value of a single order\"},\"result\":null}", type: :invalid_order }, "FUND_001" => %{ description: "Duplicate request (a bizId can only be requested once)", type: :invalid_parameters }, "FUND_002" => %{ description: "Insufficient account balance", type: :insufficient_balance }, "FUND_003" => %{ description: "Transfer operations are not supported (for example, sub-accounts do not support financial transfers)", type: :invalid_parameters }, "FUND_004" => %{ description: "Unfreeze failed", type: :exchange_error }, "FUND_005" => %{ description: "Transfer prohibited", type: :access_restricted }, "FUND_014" => %{ description: "The transfer-in account id and transfer-out account ID cannot be the same", type: :invalid_parameters }, "FUND_015" => %{ description: "From and to business types cannot be the same", type: :invalid_parameters }, "FUND_016" => %{ description: "Leverage transfer, symbol cannot be empty", type: :invalid_parameters }, "FUND_017" => %{ description: "Parameter error", type: :invalid_parameters }, "FUND_018" => %{ description: "Invalid freeze record", type: :invalid_parameters }, "FUND_019" => %{ description: "Freeze users not equal", type: :invalid_parameters }, "FUND_020" => %{ description: "Freeze currency are not equal", type: :invalid_parameters }, "FUND_021" => %{ description: "Operation not supported", type: :invalid_parameters }, "FUND_022" => %{ description: "Freeze record does not exist", type: :invalid_parameters }, "FUND_044" => %{ description: "The maximum length of the amount is 113 and cannot exceed the limit", type: :invalid_parameters }, "ORDER_001" => %{ description: "Platform rejection", type: :invalid_order }, "ORDER_002" => %{ description: "insufficient funds", type: :insufficient_balance }, "ORDER_003" => %{ description: "Trading Pair Suspended", type: :invalid_order }, "ORDER_004" => %{ description: "no transaction", type: :invalid_order }, "ORDER_005" => %{ description: "Order not exist", type: :invalid_order }, "ORDER_006" => %{ description: "Too many open orders", type: :invalid_order }, "ORDER_007" => %{ description: "The sub-account has no transaction authority", type: :access_restricted }, "ORDER_F0101" => %{ description: "Trigger Price Filter - Min", type: :invalid_order }, "ORDER_F0102" => %{ description: "Trigger Price Filter - Max", type: :invalid_order }, "ORDER_F0103" => %{ description: "Trigger Price Filter - Step Value", type: :invalid_order }, "ORDER_F0201" => %{ description: "Trigger Quantity Filter - Min", type: :invalid_order }, "ORDER_F0202" => %{ description: "Trigger Quantity Filter - Max", type: :invalid_order }, "ORDER_F0203" => %{ description: "Trigger Quantity Filter - Step Value", type: :invalid_order }, "ORDER_F0301" => %{ description: "Trigger QUOTE_QTY Filter - Min Value", type: :invalid_order }, "ORDER_F0401" => %{ description: "Trigger PROTECTION_ONLINE Filter", type: :invalid_order }, "ORDER_F0501" => %{ description: "Trigger PROTECTION_LIMIT Filter - Buy Max Deviation", type: :invalid_order }, "ORDER_F0502" => %{ description: "Trigger PROTECTION_LIMIT Filter - Sell Max Deviation", type: :invalid_order }, "ORDER_F0601" => %{ description: "Trigger PROTECTION_MARKET Filter", type: :invalid_order }, "SYMBOL_001" => %{ description: "Symbol not exist", type: :invalid_order }, "SYMBOL_002" => %{ description: "Symbol offline", type: :invalid_order }, "SYMBOL_003" => %{ description: "Symbol suspend trading", type: :invalid_order }, "SYMBOL_004" => %{ description: "Symbol country disallow trading", type: :invalid_order }, "SYMBOL_005" => %{ description: "The symbol does not support trading via API", type: :invalid_order }, "TRANSFER_001" => %{ description: "Duplicate request (a bizId can only be requested once)", type: :invalid_parameters }, "TRANSFER_002" => %{ description: "Insufficient account balance", type: :insufficient_balance }, "TRANSFER_003" => %{ description: "User not registered", type: :invalid_parameters }, "TRANSFER_004" => %{ description: "The currency is not allowed to be transferred", type: :access_restricted }, "TRANSFER_005" => %{ description: "The user’s currency is not allowed to be transferred", type: :access_restricted }, "TRANSFER_006" => %{ description: "Transfer prohibited", type: :access_restricted }, "TRANSFER_007" => %{ description: "Request timed out", type: :network_error }, "TRANSFER_008" => %{ description: "Transferring to a leveraged account is abnormal", type: :invalid_parameters }, "TRANSFER_009" => %{ description: "Departing from a leveraged account is abnormal", type: :invalid_parameters }, "TRANSFER_010" => %{ description: "Leverage cleared, transfer prohibited", type: :access_restricted }, "TRANSFER_011" => %{ description: "Leverage with borrowing, transfer prohibited", type: :access_restricted }, "TRANSFER_012" => %{ description: "Currency transfer prohibited", type: :access_restricted }, "The symbol does not support trading via API" => %{ description: "{\"returnCode\":1,\"msgInfo\":\"failure\",\"error\":{\"code\":\"symbol_not_support_trading_via_api\",\"msg\":\"The symbol does not support trading via API\"},\"result\":null}", type: :invalid_order }, "WITHDRAW_001" => %{ description: "Withdraw is not open", type: :invalid_parameters }, "WITHDRAW_002" => %{ description: "The withdrawal address is invalid", type: :invalid_parameters }, "WITHDRAW_003" => %{ description: "The current account security level is low, please bind any two security verifications in mobile phone/email/Google Authenticator before withdraw", type: :access_restricted }, "WITHDRAW_004" => %{ description: "The withdrawal address is not added", type: :invalid_parameters }, "WITHDRAW_005" => %{ description: "The withdrawal address cannot be empty", type: :invalid_parameters }, "WITHDRAW_006" => %{ description: "Memo cannot be empty", type: :invalid_parameters }, "WITHDRAW_008" => %{ description: "Risk control is triggered, withdraw of this currency is not currently supported", type: :access_restricted }, "WITHDRAW_009" => %{ description: "Withdraw failed, some assets in this withdraw are restricted by T+1 withdraw", type: :access_restricted }, "WITHDRAW_010" => %{ description: "The precision of withdrawal is invalid", type: :invalid_parameters }, "WITHDRAW_011" => %{ description: "free balance is not enough", type: :insufficient_balance }, "WITHDRAW_012" => %{ description: "Withdraw failed, your remaining withdrawal limit today is not enough", type: :access_restricted }, "WITHDRAW_013" => %{ description: "Withdraw failed, your remaining withdrawal limit today is not enough, the withdrawal amount can be increased by completing a higher level of real-name authentication", type: :access_restricted }, "WITHDRAW_014" => %{ description: "This withdrawal address cannot be used in the internal transfer function, please cancel the internal transfer function before submitting", type: :invalid_parameters }, "WITHDRAW_015" => %{ description: "The withdrawal amount is not enough to deduct the handling fee", type: :invalid_parameters }, "WITHDRAW_016" => %{ description: "This withdrawal address is already exists", type: :invalid_parameters }, "WITHDRAW_017" => %{ description: "This withdrawal has been processed and cannot be canceled", type: :invalid_parameters }, "WITHDRAW_018" => %{ description: "Memo must be a number", type: :invalid_parameters }, "WITHDRAW_019" => %{ description: "Memo is incorrect, please enter again", type: :invalid_parameters }, "WITHDRAW_020" => %{ description: "Your withdrawal amount has reached the upper limit for today, please try it tomorrow", type: :access_restricted }, "WITHDRAW_021" => %{ description: "Your withdrawal amount has reached the upper limit for today, you can only withdraw up to {0} this time", type: :access_restricted }, "WITHDRAW_022" => %{ description: "Withdrawal amount must be greater than {0}", type: :invalid_parameters }, "WITHDRAW_023" => %{ description: "Withdrawal amount must be less than {0}", type: :invalid_parameters }, "WITHDRAW_024" => %{ description: "Withdraw is not supported", type: :invalid_parameters }, "WITHDRAW_025" => %{ description: "Please create a FIO address in the deposit page", type: :invalid_parameters }, "insufficient balance" => %{ description: nil, type: :insufficient_balance }, "insufficient_balance" => %{ description: nil, type: :insufficient_balance }, "open_order_min_nominal_value_limit" => %{ description: "{\"returnCode\":1,\"msgInfo\":\"failure\",\"error\":{\"code\":\"open_order_min_nominal_value_limit\",\"msg\":\"Exceeds the minimum notional value of a single order\"},\"result\":null}", type: :invalid_order }, "symbol_not_support_trading_via_api" => %{ description: "{\"returnCode\":1,\"msgInfo\":\"failure\",\"error\":{\"code\":\"symbol_not_support_trading_via_api\",\"msg\":\"The symbol does not support trading via API\"},\"result\":null}", type: :invalid_order } }, error_codes: %{ 400 => :network_error, 404 => :exchange_error, 429 => :rate_limited, 500 => :exchange_error, 502 => :exchange_error, 503 => :network_error, "AUTH_001" => :invalid_credentials, "AUTH_002" => :invalid_credentials, "AUTH_003" => :invalid_credentials, "AUTH_004" => :invalid_credentials, "AUTH_005" => :invalid_credentials, "AUTH_006" => :invalid_credentials, "AUTH_007" => :invalid_credentials, "AUTH_101" => :invalid_credentials, "AUTH_102" => :invalid_credentials, "AUTH_103" => :invalid_credentials, "AUTH_104" => :invalid_credentials, "AUTH_105" => :invalid_credentials, "AUTH_106" => :access_restricted, "COMMON_001" => :exchange_error, "COMMON_002" => :exchange_error, "COMMON_003" => :invalid_parameters, "CURRENCY_001" => :invalid_parameters, "DEPOSIT_001" => :invalid_parameters, "DEPOSIT_002" => :access_restricted, "DEPOSIT_003" => :invalid_parameters, "DEPOSIT_004" => :invalid_parameters, "DEPOSIT_005" => :invalid_parameters, "DEPOSIT_006" => :invalid_parameters, "DEPOSIT_007" => :invalid_parameters, "DEPOSIT_008" => :invalid_parameters, "Exceeds the minimum notional value of a single order" => :invalid_order, "FUND_001" => :invalid_parameters, "FUND_002" => :insufficient_balance, "FUND_003" => :invalid_parameters, "FUND_004" => :exchange_error, "FUND_005" => :access_restricted, "FUND_014" => :invalid_parameters, "FUND_015" => :invalid_parameters, "FUND_016" => :invalid_parameters, "FUND_017" => :invalid_parameters, "FUND_018" => :invalid_parameters, "FUND_019" => :invalid_parameters, "FUND_020" => :invalid_parameters, "FUND_021" => :invalid_parameters, "FUND_022" => :invalid_parameters, "FUND_044" => :invalid_parameters, "ORDER_001" => :invalid_order, "ORDER_002" => :insufficient_balance, "ORDER_003" => :invalid_order, "ORDER_004" => :invalid_order, "ORDER_005" => :invalid_order, "ORDER_006" => :invalid_order, "ORDER_007" => :access_restricted, "ORDER_F0101" => :invalid_order, "ORDER_F0102" => :invalid_order, "ORDER_F0103" => :invalid_order, "ORDER_F0201" => :invalid_order, "ORDER_F0202" => :invalid_order, "ORDER_F0203" => :invalid_order, "ORDER_F0301" => :invalid_order, "ORDER_F0401" => :invalid_order, "ORDER_F0501" => :invalid_order, "ORDER_F0502" => :invalid_order, "ORDER_F0601" => :invalid_order, "SYMBOL_001" => :invalid_order, "SYMBOL_002" => :invalid_order, "SYMBOL_003" => :invalid_order, "SYMBOL_004" => :invalid_order, "SYMBOL_005" => :invalid_order, "TRANSFER_001" => :invalid_parameters, "TRANSFER_002" => :insufficient_balance, "TRANSFER_003" => :invalid_parameters, "TRANSFER_004" => :access_restricted, "TRANSFER_005" => :access_restricted, "TRANSFER_006" => :access_restricted, "TRANSFER_007" => :network_error, "TRANSFER_008" => :invalid_parameters, "TRANSFER_009" => :invalid_parameters, "TRANSFER_010" => :access_restricted, "TRANSFER_011" => :access_restricted, "TRANSFER_012" => :access_restricted, "The symbol does not support trading via API" => :invalid_order, "WITHDRAW_001" => :invalid_parameters, "WITHDRAW_002" => :invalid_parameters, "WITHDRAW_003" => :access_restricted, "WITHDRAW_004" => :invalid_parameters, "WITHDRAW_005" => :invalid_parameters, "WITHDRAW_006" => :invalid_parameters, "WITHDRAW_008" => :access_restricted, "WITHDRAW_009" => :access_restricted, "WITHDRAW_010" => :invalid_parameters, "WITHDRAW_011" => :insufficient_balance, "WITHDRAW_012" => :access_restricted, "WITHDRAW_013" => :access_restricted, "WITHDRAW_014" => :invalid_parameters, "WITHDRAW_015" => :invalid_parameters, "WITHDRAW_016" => :invalid_parameters, "WITHDRAW_017" => :invalid_parameters, "WITHDRAW_018" => :invalid_parameters, "WITHDRAW_019" => :invalid_parameters, "WITHDRAW_020" => :access_restricted, "WITHDRAW_021" => :access_restricted, "WITHDRAW_022" => :invalid_parameters, "WITHDRAW_023" => :invalid_parameters, "WITHDRAW_024" => :invalid_parameters, "WITHDRAW_025" => :invalid_parameters, "insufficient balance" => :insufficient_balance, "insufficient_balance" => :insufficient_balance, "open_order_min_nominal_value_limit" => :invalid_order, "symbol_not_support_trading_via_api" => :invalid_order }, exceptions: %{ broad: %{ "Exceeds the minimum notional value of a single order" => :invalid_order, "The symbol does not support trading via API" => :bad_symbol, "insufficient balance" => :insufficient_funds }, exact: %{ "400" => :network_error, "404" => :exchange_error, "429" => :rate_limit_exceeded, "500" => :exchange_error, "502" => :exchange_error, "503" => :on_maintenance, "AUTH_001" => :authentication_error, "AUTH_002" => :authentication_error, "AUTH_003" => :authentication_error, "AUTH_004" => :authentication_error, "AUTH_005" => :authentication_error, "AUTH_006" => :authentication_error, "AUTH_007" => :authentication_error, "AUTH_101" => :authentication_error, "AUTH_102" => :authentication_error, "AUTH_103" => :authentication_error, "AUTH_104" => :authentication_error, "AUTH_105" => :authentication_error, "AUTH_106" => :permission_denied, "COMMON_001" => :exchange_error, "COMMON_002" => :exchange_error, "COMMON_003" => :bad_request, "CURRENCY_001" => :bad_request, "DEPOSIT_001" => :bad_request, "DEPOSIT_002" => :permission_denied, "DEPOSIT_003" => :bad_request, "DEPOSIT_004" => :bad_request, "DEPOSIT_005" => :bad_request, "DEPOSIT_006" => :bad_request, "DEPOSIT_007" => :bad_request, "DEPOSIT_008" => :bad_request, "FUND_001" => :bad_request, "FUND_002" => :insufficient_funds, "FUND_003" => :bad_request, "FUND_004" => :exchange_error, "FUND_005" => :permission_denied, "FUND_014" => :bad_request, "FUND_015" => :bad_request, "FUND_016" => :bad_request, "FUND_017" => :bad_request, "FUND_018" => :bad_request, "FUND_019" => :bad_request, "FUND_020" => :bad_request, "FUND_021" => :bad_request, "FUND_022" => :bad_request, "FUND_044" => :bad_request, "ORDER_001" => :invalid_order, "ORDER_002" => :insufficient_funds, "ORDER_003" => :invalid_order, "ORDER_004" => :invalid_order, "ORDER_005" => :invalid_order, "ORDER_006" => :invalid_order, "ORDER_007" => :permission_denied, "ORDER_F0101" => :invalid_order, "ORDER_F0102" => :invalid_order, "ORDER_F0103" => :invalid_order, "ORDER_F0201" => :invalid_order, "ORDER_F0202" => :invalid_order, "ORDER_F0203" => :invalid_order, "ORDER_F0301" => :invalid_order, "ORDER_F0401" => :invalid_order, "ORDER_F0501" => :invalid_order, "ORDER_F0502" => :invalid_order, "ORDER_F0601" => :invalid_order, "SYMBOL_001" => :bad_symbol, "SYMBOL_002" => :bad_symbol, "SYMBOL_003" => :bad_symbol, "SYMBOL_004" => :bad_symbol, "SYMBOL_005" => :bad_symbol, "TRANSFER_001" => :bad_request, "TRANSFER_002" => :insufficient_funds, "TRANSFER_003" => :bad_request, "TRANSFER_004" => :permission_denied, "TRANSFER_005" => :permission_denied, "TRANSFER_006" => :permission_denied, "TRANSFER_007" => :request_timeout, "TRANSFER_008" => :bad_request, "TRANSFER_009" => :bad_request, "TRANSFER_010" => :permission_denied, "TRANSFER_011" => :permission_denied, "TRANSFER_012" => :permission_denied, "WITHDRAW_001" => :bad_request, "WITHDRAW_002" => :bad_request, "WITHDRAW_003" => :permission_denied, "WITHDRAW_004" => :bad_request, "WITHDRAW_005" => :bad_request, "WITHDRAW_006" => :bad_request, "WITHDRAW_008" => :permission_denied, "WITHDRAW_009" => :permission_denied, "WITHDRAW_010" => :bad_request, "WITHDRAW_011" => :insufficient_funds, "WITHDRAW_012" => :permission_denied, "WITHDRAW_013" => :permission_denied, "WITHDRAW_014" => :bad_request, "WITHDRAW_015" => :bad_request, "WITHDRAW_016" => :bad_request, "WITHDRAW_017" => :bad_request, "WITHDRAW_018" => :bad_request, "WITHDRAW_019" => :bad_request, "WITHDRAW_020" => :permission_denied, "WITHDRAW_021" => :permission_denied, "WITHDRAW_022" => :bad_request, "WITHDRAW_023" => :bad_request, "WITHDRAW_024" => :bad_request, "WITHDRAW_025" => :bad_request, "insufficient_balance" => :insufficient_funds, "open_order_min_nominal_value_limit" => :invalid_order, "symbol_not_support_trading_via_api" => :bad_symbol } }, exchange_options: %{ "accountsById" => %{ "finance" => "FINANCE", "future" => "FUTURES_U", "inverse" => "FUTURES_C", "leverage" => "LEVER", "linear" => "FUTURES_U", "spot" => "SPOT", "swap" => "FUTURES_U" }, "adjustForTimeDifference" => false, "createMarketBuyOrderRequiresPrice" => true, "defaultNetworkCodeReplacements" => %{ "BRC20" => %{ "BRC20" => "BTC" }, "CRO" => %{ "CRC20" => "CRONOS" }, "ETH" => %{ "ERC20" => "ETH" }, "TRX" => %{ "TRC20" => "TRX" } }, "networks" => %{ "ADA" => "Cardano", "ALEO" => "ALEO(IOU)", "ALGO" => "Algorand", "AR" => "Arweave", "ASTR" => "Astar Network", "ATOM" => "Cosmos", "AVAX" => "AVAX C-Chain", "BCH" => "Bitcoin Cash", "BEP2" => "BNB-BEP2", "BEP20" => "BNB Smart Chain", "BNB" => "BNB Smart Chain", "BTC" => "Bitcoin", "BTS" => "BitShares", "CELT" => "OKT", "CHZ" => "chz", "CRO" => "CRO-CRONOS", "DCR" => "Decred", "DOGE" => "dogecoin", "DOT" => "Polkadot", "EGLD" => "Elrond eGold", "ERC20" => "Ethereum", "ETC" => "Ethereum Classic", "ETH" => "Ethereum", "FIL" => "Filecoin", "FTM" => "Fantom", "GAL" => "GAL(FT)", "GLMR" => "Moonbeam", "GMMT" => "GMMT chain", "ICP" => "Internet Computer", "KLAY" => "Klaytn", "KSM" => "Kusama", "LOOP" => "LOOP-LRC", "LSK" => "Lisk", "LTC" => "Litecoin", "LUNA" => "Terra", "MATIC" => "Polygon", "MMT" => "MMT-MMT", "NEAR" => "NEAR Protocol", "OMAX" => "OMAX-OMAX CHAIN", "ONE" => "Harmony", "ONT" => "Ontology", "OP" => "OPT", "REI" => "REI Network", "SC" => "Siacoin", "SOL" => "SOL-SOL", "TBC" => "TBC-TBC", "THETA" => "Theta Token", "TRC20" => "Tron", "TRON" => "Tron", "VET" => "VeChain", "XLM" => "Stellar Network", "XMR" => "Monero", "XRP" => "Ripple", "XT" => "XT Smart Chain", "XTZ" => "Tezos", "XWC" => "XWC-XWC", "ZEC" => "Zcash", "ZEN" => "Horizen", "ZIL" => "Zilliqa" }, "networksById" => %{ "ALEO(IOU)" => "ALEO", "AVAX C-Chain" => "AVAX", "Algorand" => "ALGO", "Arweave" => "AR", "Astar Network" => "ASTR", "BNB Smart Chain" => "BEP20", "BNB-BEP2" => "BEP2", "BitShares" => "BTS", "Bitcoin" => "BTC", "Bitcoin Cash" => "BCH", "CRO-CRONOS" => "CRO", "Cardano" => "ADA", "Cosmos" => "ATOM", "Decred" => "DCR", "Elrond eGold" => "EGLD", "Ethereum" => "ERC20", "Ethereum Classic" => "ETC", "Fantom" => "FTM", "Filecoin" => "FIL", "GAL(FT)" => "GAL", "GMMT chain" => "GMMT", "Harmony" => "ONE", "Horizen" => "ZEN", "Internet Computer" => "ICP", "Klaytn" => "KLAY", "Kusama" => "KSM", "LOOP-LRC" => "LOOP", "Lisk" => "LSK", "Litecoin" => "LTC", "MMT-MMT" => "MMT", "Monero" => "XMR", "Moonbeam" => "GLMR", "NEAR Protocol" => "NEAR", "OKT" => "CELT", "OMAX-OMAX CHAIN" => "OMAX", "OPT" => "OP", "Ontology" => "ONT", "Polkadot" => "DOT", "Polygon" => "MATIC", "REI Network" => "REI", "Ripple" => "XRP", "SOL-SOL" => "SOL", "Siacoin" => "SC", "Stellar Network" => "XLM", "TBC-TBC" => "TBC", "Terra" => "LUNA", "Tezos" => "XTZ", "Theta Token" => "THETA", "Tron" => "TRC20", "VeChain" => "VET", "XT Smart Chain" => "XT", "XWC-XWC" => "XWC", "Zcash" => "ZEC", "Zilliqa" => "ZIL", "chz" => "CHZ", "dogecoin" => "DOGE" }, "recvWindow" => "5000", "timeDifference" => 0 }, extended_metadata: %{ fees_url: "https://www.xt.com/en/rate", limits: %{ "amount" => %{}, "cost" => %{}, "leverage" => %{}, "price" => %{} }, logo_url: "https://user-images.githubusercontent.com/14319357/232636712-466df2fc-560a-4ca4-aab2-b1d954a58e24.jpg", referral_url: "https://www.xt.com/en/accounts/register?ref=9PTM9VW" }, extracted_metadata: %{ ccxt_version: "4.5.34" }, features: %{ default: %{ create_order: %{ hedged: false, iceberg: false, leverage: false, margin_mode: false, market_buy_by_cost: true, market_buy_requires_price: false, 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_direction: false, trigger_price: false }, fetch_closed_orders: %{ days_back: 100000, days_back_canceled: 1, limit: 100, margin_mode: true, market_type: true, sub_type: true, symbol_required: false, trailing: false, trigger: true, until_days: 100000 }, fetch_my_trades: %{ days_back: 100000, limit: 100, margin_mode: true, market_type: true, sub_type: true, symbol_required: false, until_days: 100000 }, fetch_ohlcv: %{ limit: 1000 }, fetch_open_orders: %{ limit: 100, margin_mode: true, market_type: true, sub_type: true, symbol_required: false, trailing: false, trigger: true }, fetch_order: %{ margin_mode: false, market_type: true, sub_type: true, symbol_required: false, trailing: false, trigger: true }, fetch_orders: %{ days_back: 100000, limit: 100, margin_mode: true, market_type: true, sub_type: true, symbol_required: false, trailing: false, trigger: true, until_days: 100000 }, sandbox: false }, for_derivatives: %{ create_order: %{ stop_loss_price: true, take_profit_price: true, trigger_price: true, trigger_price_type: %{ index: true, last: true, mark: true } }, extends: "default", fetch_my_trades: %{} }, future: %{ inverse: %{ extends: "forDerivatives" }, linear: %{ extends: "forDerivatives" } }, spot: %{ extends: "default" }, swap: %{ inverse: %{ extends: "forDerivatives" }, linear: %{ extends: "forDerivatives" } } }, fees: %{ spot: %{ maker: 0.002, percentage: true, taker: 0.002, tier_based: true, tiers: %{ maker: [ %{ fee: 0.002, volume: 0 }, %{ fee: 0.0018, volume: 5000 }, %{ fee: 0.0016, volume: 10000 }, %{ fee: 0.0014, volume: 20000 }, %{ fee: 0.0012, volume: 50000 }, %{ fee: 0.001, volume: 150000 }, %{ fee: 0.0008, volume: 300000 }, %{ fee: 0.0007, volume: 600000 }, %{ fee: 0.0006, volume: 1200000 }, %{ fee: 0.0005, volume: 2500000 }, %{ fee: 0.0004, volume: 6000000 }, %{ fee: 0.0003, volume: 15000000 }, %{ fee: 0.0002, volume: 30000000 } ], taker: [ %{ fee: 0.002, volume: 0 }, %{ fee: 0.0018, volume: 5000 }, %{ fee: 0.0016, volume: 10000 }, %{ fee: 0.0014, volume: 20000 }, %{ fee: 0.0012, volume: 50000 }, %{ fee: 0.001, volume: 150000 }, %{ fee: 0.0008, volume: 300000 }, %{ fee: 0.0007, volume: 600000 }, %{ fee: 0.0006, volume: 1200000 }, %{ fee: 0.0005, volume: 2500000 }, %{ fee: 0.0004, volume: 6000000 }, %{ fee: 0.0003, volume: 15000000 }, %{ fee: 0.0002, volume: 30000000 } ] } } }, handle_content_type_application_zip: nil, handle_errors_source: "handleErrors(code, reason, url, method, headers, body, response, requestHeaders, requestBody) {\n //\n // spot: error\n //\n // {\n // \"rc\": 1,\n // \"mc\": \"AUTH_103\",\n // \"ma\": [],\n // \"result\": null\n // }\n //\n // spot: success\n //\n // {\n // \"returnCode\": 0,\n // \"msgInfo\": \"success\",\n // \"error\": null,\n // \"result\": []\n // }\n //\n // swap and future: error\n //\n // {\n // \"returnCode\": 1,\n // \"msgInfo\": \"failure\",\n // \"error\": {\n // \"code\": \"403\",\n // \"msg\": \"invalid signature\"\n // },\n // \"result\": null\n // }\n //\n // swap and future: success\n //\n // {\n // \"returnCode\": 0,\n // \"msgInfo\": \"success\",\n // \"error\": null,\n // \"result\": null\n // }\n //\n // other:\n //\n // {\n // \"rc\": 0,\n // \"mc\": \"SUCCESS\",\n // \"ma\": [],\n // \"result\": {}\n // }\n //\n // {\"returnCode\":1,\"msgInfo\":\"failure\",\"error\":{\"code\":\"insufficient_balance\",\"msg\":\"insufficient balance\",\"args\":[]},\"result\":null}\n //\n //\n const status = this.safeStringUpper2(response, 'msgInfo', 'mc');\n if (status !== undefined && status !== 'SUCCESS') {\n const feedback = this.id + ' ' + body;\n const error = this.safeValue(response, 'error', {});\n const spotErrorCode = this.safeString(response, 'mc');\n const errorCode = this.safeString(error, 'code', spotErrorCode);\n const spotMessage = this.safeString(response, 'msgInfo');\n const message = this.safeString(error, 'msg', spotMessage);\n this.throwExactlyMatchedException(this.exceptions['exact'], errorCode, feedback);\n this.throwBroadlyMatchedException(this.exceptions['broad'], message, feedback);\n throw new errors.ExchangeError(feedback);\n }\n return undefined;\n }", has: %{ add_margin: true, 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: true, 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: false, create_stop_limit_order_ws: false, create_stop_loss_order: false, create_stop_loss_order_ws: false, create_stop_market_order: false, create_stop_market_order_ws: false, create_stop_order: false, 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_all_greeks: 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: true, 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: true, fetch_deposit_addresses: false, fetch_deposit_addresses_by_network: false, fetch_deposit_withdraw_fee: false, fetch_deposit_withdraw_fees: false, fetch_deposit_withdrawals: false, fetch_deposits: true, fetch_deposits_withdrawals: false, fetch_deposits_ws: false, fetch_funding_history: true, fetch_funding_interval: true, fetch_funding_intervals: false, fetch_funding_rate: true, fetch_funding_rate_history: true, 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: true, fetch_ledger_entry: false, fetch_leverage: false, fetch_leverage_tiers: true, 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: true, 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: true, fetch_orders_by_status: true, fetch_orders_ws: false, fetch_position: true, fetch_position_history: false, fetch_position_mode: false, fetch_position_ws: false, fetch_positions: true, 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: false, 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: false, 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: true, margin: true, option: false, private_api: true, public_api: true, reduce_margin: true, repay_cross_margin: false, repay_isolated_margin: false, repay_margin: false, sandbox: false, set_leverage: true, set_margin: false, set_margin_mode: true, 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: true, watch_ohlcv: true, 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: true, watch_status: false, watch_ticker: true, watch_tickers: true, watch_trades: true, watch_trades_for_symbols: false, withdraw: true, ws: false }, http_config: nil, id: "xt", markets: nil, name: "XT", ohlcv_timestamp_resolution: :milliseconds, options: %{ accounts_by_id: %{ "finance" => "FINANCE", "future" => "FUTURES_U", "inverse" => "FUTURES_C", "leverage" => "LEVER", "linear" => "FUTURES_U", "spot" => "SPOT", "swap" => "FUTURES_U" }, adjust_for_time_difference: false, create_market_buy_order_requires_price: true, networks: %{ "ADA" => "Cardano", "ALEO" => "ALEO(IOU)", "ALGO" => "Algorand", "AR" => "Arweave", "ASTR" => "Astar Network", "ATOM" => "Cosmos", "AVAX" => "AVAX C-Chain", "BCH" => "Bitcoin Cash", "BEP2" => "BNB-BEP2", "BEP20" => "BNB Smart Chain", "BNB" => "BNB Smart Chain", "BTC" => "Bitcoin", "BTS" => "BitShares", "CELT" => "OKT", "CHZ" => "chz", "CRO" => "CRO-CRONOS", "DCR" => "Decred", "DOGE" => "dogecoin", "DOT" => "Polkadot", "EGLD" => "Elrond eGold", "ERC20" => "Ethereum", "ETC" => "Ethereum Classic", "ETH" => "Ethereum", "FIL" => "Filecoin", "FTM" => "Fantom", "GAL" => "GAL(FT)", "GLMR" => "Moonbeam", "GMMT" => "GMMT chain", "ICP" => "Internet Computer", "KLAY" => "Klaytn", "KSM" => "Kusama", "LOOP" => "LOOP-LRC", "LSK" => "Lisk", "LTC" => "Litecoin", "LUNA" => "Terra", "MATIC" => "Polygon", "MMT" => "MMT-MMT", "NEAR" => "NEAR Protocol", "OMAX" => "OMAX-OMAX CHAIN", "ONE" => "Harmony", "ONT" => "Ontology", "OP" => "OPT", "REI" => "REI Network", "SC" => "Siacoin", "SOL" => "SOL-SOL", "TBC" => "TBC-TBC", "THETA" => "Theta Token", "TRC20" => "Tron", "TRON" => "Tron", "VET" => "VeChain", "XLM" => "Stellar Network", "XMR" => "Monero", "XRP" => "Ripple", "XT" => "XT Smart Chain", "XTZ" => "Tezos", "XWC" => "XWC-XWC", "ZEC" => "Zcash", "ZEN" => "Horizen", "ZIL" => "Zilliqa" }, networks_by_id: %{ "ALEO(IOU)" => "ALEO", "AVAX C-Chain" => "AVAX", "Algorand" => "ALGO", "Arweave" => "AR", "Astar Network" => "ASTR", "BNB Smart Chain" => "BEP20", "BNB-BEP2" => "BEP2", "BitShares" => "BTS", "Bitcoin" => "BTC", "Bitcoin Cash" => "BCH", "CRO-CRONOS" => "CRO", "Cardano" => "ADA", "Cosmos" => "ATOM", "Decred" => "DCR", "Elrond eGold" => "EGLD", "Ethereum" => "ERC20", "Ethereum Classic" => "ETC", "Fantom" => "FTM", "Filecoin" => "FIL", "GAL(FT)" => "GAL", "GMMT chain" => "GMMT", "Harmony" => "ONE", "Horizen" => "ZEN", "Internet Computer" => "ICP", "Klaytn" => "KLAY", "Kusama" => "KSM", "LOOP-LRC" => "LOOP", "Lisk" => "LSK", "Litecoin" => "LTC", "MMT-MMT" => "MMT", "Monero" => "XMR", "Moonbeam" => "GLMR", "NEAR Protocol" => "NEAR", "OKT" => "CELT", "OMAX-OMAX CHAIN" => "OMAX", "OPT" => "OP", "Ontology" => "ONT", "Polkadot" => "DOT", "Polygon" => "MATIC", "REI Network" => "REI", "Ripple" => "XRP", "SOL-SOL" => "SOL", "Siacoin" => "SC", "Stellar Network" => "XLM", "TBC-TBC" => "TBC", "Terra" => "LUNA", "Tezos" => "XTZ", "Theta Token" => "THETA", "Tron" => "TRC20", "VeChain" => "VET", "XT Smart Chain" => "XT", "XWC-XWC" => "XWC", "Zcash" => "ZEC", "Zilliqa" => "ZIL", "chz" => "CHZ", "dogecoin" => "DOGE" }, recv_window: "5000", time_difference: 0 }, order_mappings: %{ side_format: :uppercase, side_key: "side", type_format: :uppercase, type_key: "type" }, param_mappings: %{ "amount" => "quantity", "arg1" => "symbol", "code" => "currency", "cost" => "quoteQty", "fromAccount" => "from", "id" => "orderId", "side" => "orderSide", "since" => "startTime", "timeframe" => "interval", "type" => "orderType" }, parse_methods: [ %{ "comment" => nil, "examples" => [ "{\n \"currency\": \"usdt\",\n \"currencyId\": 11,\n \"frozenAmount\": \"0.03834082\",\n \"availableAmount\": \"31.70995965\",\n \"totalAmount\": \"31.74830047\",\n \"convertBtcAmount\": \"0.00115911\",\n \"convertUsdtAmount\": \"31.74830047\"\n }", "{\n \"coin\": \"usdt\",\n \"walletBalance\": \"19.29849875\",\n \"openOrderMarginFrozen\": \"0\",\n \"isolatedMargin\": \"0.709475\",\n \"crossedMargin\": \"0\",\n \"availableBalance\": \"18.58902375\",\n \"bonus\": \"0\",\n \"coupon\":\"0\"\n }" ], "line_end" => 2393, "line_start" => 2347, "mappings" => [ %{ "comment" => nil, "key" => "info", "value" => "response" } ], "name" => "parseBalance", "signature" => "parseBalance (response)", "source" => "parseBalance (response) {\n //\n // spot\n //\n // {\n // \"currency\": \"usdt\",\n // \"currencyId\": 11,\n // \"frozenAmount\": \"0.03834082\",\n // \"availableAmount\": \"31.70995965\",\n // \"totalAmount\": \"31.74830047\",\n // \"convertBtcAmount\": \"0.00115911\",\n // \"convertUsdtAmount\": \"31.74830047\"\n // }\n //\n // swap and future\n //\n // {\n // \"coin\": \"usdt\",\n // \"walletBalance\": \"19.29849875\",\n // \"openOrderMarginFrozen\": \"0\",\n // \"isolatedMargin\": \"0.709475\",\n // \"crossedMargin\": \"0\",\n // \"availableBalance\": \"18.58902375\",\n // \"bonus\": \"0\",\n // \"coupon\":\"0\"\n // }\n //\n const result = { 'info': response };\n for (let i = 0; i < response.length; i++) {\n const balance = response[i];\n const currencyId = this.safeString2 (balance, 'currency', 'coin');\n const code = this.safeCurrencyCode (currencyId);\n const account = this.account ();\n const free = this.safeString2 (balance, 'availableAmount', 'availableBalance');\n let used = this.safeString (balance, 'frozenAmount');\n const total = this.safeString2 (balance, 'totalAmount', 'walletBalance');\n if (used === undefined) {\n const crossedAndIsolatedMargin = Precise.stringAdd (this.safeString (balance, 'crossedMargin'), this.safeString (balance, 'isolatedMargin'));\n used = Precise.stringAdd (this.safeString (balance, 'openOrderMarginFrozen'), crossedAndIsolatedMargin);\n }\n account['free'] = free;\n account['used'] = used;\n account['total'] = total;\n result[code] = account;\n }\n return this.safeBalance (result);\n }" }, %{ "comment" => nil, "examples" => [ "{\n \"address\": \"0x7f7173cf29d3846d20ca5a3aec1120b93dbd157a\",\n \"memo\": \"\"\n }" ], "line_end" => 3825, "line_start" => 3809, "mappings" => [ %{ "comment" => nil, "key" => "info", "value" => "depositAddress" }, %{ "comment" => nil, "key" => "currency", "value" => "this.safeCurrencyCode (undefined, currency)" }, %{ "comment" => nil, "key" => "network", "value" => "undefined" }, %{ "comment" => nil, "key" => "address", "value" => "address" }, %{ "comment" => nil, "key" => "tag", "value" => "this.safeString (depositAddress, 'memo')" } ], "name" => "parseDepositAddress", "signature" => "parseDepositAddress (depositAddress, currency = undefined): DepositAddress", "source" => "parseDepositAddress (depositAddress, currency = undefined): DepositAddress {\n //\n // {\n // \"address\": \"0x7f7173cf29d3846d20ca5a3aec1120b93dbd157a\",\n // \"memo\": \"\"\n // }\n //\n const address = this.safeString (depositAddress, 'address');\n this.checkAddress (address);\n return {\n 'info': depositAddress,\n 'currency': this.safeCurrencyCode (undefined, currency),\n 'network': undefined,\n 'address': address,\n 'tag': this.safeString (depositAddress, 'memo'),\n } as DepositAddress;\n }" }, %{ "comment" => nil, "examples" => [ "{\n \"id\": \"210804044057280512\",\n \"symbol\": \"btc_usdt\",\n \"cast\": \"-0.0013\",\n \"coin\": \"usdt\",\n \"positionSide\": \"SHORT\",\n \"createdTime\": 1679961600653\n }" ], "line_end" => 4636, "line_start" => 4611, "mappings" => [ %{ "comment" => nil, "key" => "info", "value" => "contract" }, %{ "comment" => nil, "key" => "symbol", "value" => "symbol" }, %{ "comment" => nil, "key" => "code", "value" => "code" }, %{ "comment" => nil, "key" => "timestamp", "value" => "timestamp" }, %{ "comment" => nil, "key" => "datetime", "value" => "this.iso8601 (timestamp)" }, %{ "comment" => nil, "key" => "id", "value" => "this.safeString (contract, 'id')" }, %{ "comment" => nil, "key" => "amount", "value" => "this.safeNumber (contract, 'cast')" } ], "name" => "parseFundingHistory", "signature" => "parseFundingHistory (contract, market = undefined)", "source" => "parseFundingHistory (contract, market = undefined) {\n //\n // {\n // \"id\": \"210804044057280512\",\n // \"symbol\": \"btc_usdt\",\n // \"cast\": \"-0.0013\",\n // \"coin\": \"usdt\",\n // \"positionSide\": \"SHORT\",\n // \"createdTime\": 1679961600653\n // }\n //\n const marketId = this.safeString (contract, 'symbol');\n const symbol = this.safeSymbol (marketId, market, '_', 'swap');\n const currencyId = this.safeString (contract, 'coin');\n const code = this.safeCurrencyCode (currencyId);\n const timestamp = this.safeInteger (contract, 'createdTime');\n return {\n 'info': contract,\n 'symbol': symbol,\n 'code': code,\n 'timestamp': timestamp,\n 'datetime': this.iso8601 (timestamp),\n 'id': this.safeString (contract, 'id'),\n 'amount': this.safeNumber (contract, 'cast'),\n };\n }" }, %{ "comment" => nil, "examples" => [ "{\n \"symbol\": \"btc_usdt\",\n \"fundingRate\": \"0.000086\",\n \"nextCollectionTime\": 1680307200000,\n \"collectionInternal\": 8\n }" ], "line_end" => 4543, "line_start" => 4507, "mappings" => [ %{ "comment" => nil, "key" => "info", "value" => "contract" }, %{ "comment" => nil, "key" => "symbol", "value" => "symbol" }, %{ "comment" => nil, "key" => "markPrice", "value" => "undefined" }, %{ "comment" => nil, "key" => "indexPrice", "value" => "undefined" }, %{ "comment" => nil, "key" => "interestRate", "value" => "undefined" }, %{ "comment" => nil, "key" => "estimatedSettlePrice", "value" => "undefined" }, %{ "comment" => nil, "key" => "timestamp", "value" => "undefined" }, %{ "comment" => nil, "key" => "datetime", "value" => "undefined" }, %{ "comment" => nil, "key" => "fundingRate", "value" => "this.safeNumber (contract, 'fundingRate')" }, %{ "comment" => nil, "key" => "fundingTimestamp", "value" => "timestamp" }, %{ "comment" => nil, "key" => "fundingDatetime", "value" => "this.iso8601 (timestamp)" }, %{ "comment" => nil, "key" => "nextFundingRate", "value" => "undefined" }, %{ "comment" => nil, "key" => "nextFundingTimestamp", "value" => "undefined" }, %{ "comment" => nil, "key" => "nextFundingDatetime", "value" => "undefined" }, %{ "comment" => nil, "key" => "previousFundingRate", "value" => "undefined" }, %{ "comment" => nil, "key" => "previousFundingTimestamp", "value" => "undefined" }, %{ "comment" => nil, "key" => "previousFundingDatetime", "value" => "undefined" }, %{ "comment" => nil, "key" => "interval", "value" => "interval" } ], "name" => "parseFundingRate", "signature" => "parseFundingRate (contract, market = undefined): FundingRate", "source" => "parseFundingRate (contract, market = undefined): FundingRate {\n //\n // {\n // \"symbol\": \"btc_usdt\",\n // \"fundingRate\": \"0.000086\",\n // \"nextCollectionTime\": 1680307200000,\n // \"collectionInternal\": 8\n // }\n //\n const marketId = this.safeString (contract, 'symbol');\n const symbol = this.safeSymbol (marketId, market, '_', 'swap');\n const timestamp = this.safeInteger (contract, 'nextCollectionTime');\n let interval = this.safeString (contract, 'collectionInternal');\n if (interval !== undefined) {\n interval = interval + 'h';\n }\n return {\n 'info': contract,\n 'symbol': symbol,\n 'markPrice': undefined,\n 'indexPrice': undefined,\n 'interestRate': undefined,\n 'estimatedSettlePrice': undefined,\n 'timestamp': undefined,\n 'datetime': undefined,\n 'fundingRate': this.safeNumber (contract, 'fundingRate'),\n 'fundingTimestamp': timestamp,\n 'fundingDatetime': this.iso8601 (timestamp),\n 'nextFundingRate': undefined,\n 'nextFundingTimestamp': undefined,\n 'nextFundingDatetime': undefined,\n 'previousFundingRate': undefined,\n 'previousFundingTimestamp': undefined,\n 'previousFundingDatetime': undefined,\n 'interval': interval,\n } as FundingRate;\n }" }, %{ "comment" => nil, "examples" => [ "{\n \"id\": \"207260567109387524\",\n \"coin\": \"usdt\",\n \"symbol\": \"btc_usdt\",\n \"type\": \"FEE\",\n \"amount\": \"-0.0213\",\n \"side\": \"SUB\",\n \"afterAmount\": null,\n \"createdTime\": 1679116769914\n }" ], "line_end" => 3756, "line_start" => 3718, "mappings" => [ %{ "comment" => nil, "key" => "info", "value" => "item" }, %{ "comment" => nil, "key" => "id", "value" => "this.safeString (item, 'id')" }, %{ "comment" => nil, "key" => "direction", "value" => "direction" }, %{ "comment" => nil, "key" => "account", "value" => "undefined" }, %{ "comment" => nil, "key" => "referenceId", "value" => "undefined" }, %{ "comment" => nil, "key" => "referenceAccount", "value" => "undefined" }, %{ "comment" => nil, "key" => "type", "value" => "this.parseLedgerEntryType (this.safeString (item, 'type'))" }, %{ "comment" => nil, "key" => "currency", "value" => "this.safeCurrencyCode (currencyId, currency)" }, %{ "comment" => nil, "key" => "amount", "value" => "this.safeNumber (item, 'amount')" }, %{ "comment" => nil, "key" => "timestamp", "value" => "timestamp" }, %{ "comment" => nil, "key" => "datetime", "value" => "this.iso8601 (timestamp)" }, %{ "comment" => nil, "key" => "before", "value" => "undefined" }, %{ "comment" => nil, "key" => "after", "value" => "this.safeNumber (item, 'afterAmount')" }, %{ "comment" => nil, "key" => "status", "value" => "undefined" }, %{ "comment" => nil, "key" => "fee", "value" => "{\n 'currency': undefined,\n 'cost': undefined,\n }" }, %{ "comment" => nil, "key" => "currency", "value" => "undefined" }, %{ "comment" => nil, "key" => "cost", "value" => "undefined" } ], "name" => "parseLedgerEntry", "signature" => "parseLedgerEntry (item, currency = undefined): LedgerEntry", "source" => "parseLedgerEntry (item, currency = undefined): LedgerEntry {\n //\n // {\n // \"id\": \"207260567109387524\",\n // \"coin\": \"usdt\",\n // \"symbol\": \"btc_usdt\",\n // \"type\": \"FEE\",\n // \"amount\": \"-0.0213\",\n // \"side\": \"SUB\",\n // \"afterAmount\": null,\n // \"createdTime\": 1679116769914\n // }\n //\n const side = this.safeString (item, 'side');\n const direction = (side === 'ADD') ? 'in' : 'out';\n const currencyId = this.safeString (item, 'coin');\n currency = this.safeCurrency (currencyId, currency);\n const timestamp = this.safeInteger (item, 'createdTime');\n return this.safeLedgerEntry ({\n 'info': item,\n 'id': this.safeString (item, 'id'),\n 'direction': direction,\n 'account': undefined,\n 'referenceId': undefined,\n 'referenceAccount': undefined,\n 'type': this.parseLedgerEntryType (this.safeString (item, 'type')),\n 'currency': this.safeCurrencyCode (currencyId, currency),\n 'amount': this.safeNumber (item, 'amount'),\n 'timestamp': timestamp,\n 'datetime': this.iso8601 (timestamp),\n 'before': undefined,\n 'after': this.safeNumber (item, 'afterAmount'),\n 'status': undefined,\n 'fee': {\n 'currency': undefined,\n 'cost': undefined,\n },\n }, currency) as LedgerEntry;\n }" }, %{ "comment" => nil, "examples" => [], "line_end" => 3770, "line_start" => 3758, "mappings" => [ %{ "comment" => nil, "key" => "EXCHANGE", "value" => "'transfer'" }, %{ "comment" => nil, "key" => "CLOSE_POSITION", "value" => "'trade'" }, %{ "comment" => nil, "key" => "TAKE_OVER", "value" => "'trade'" }, %{ "comment" => nil, "key" => "MERGE", "value" => "'trade'" }, %{ "comment" => nil, "key" => "QIANG_PING_MANAGER", "value" => "'fee'" }, %{ "comment" => nil, "key" => "FUND", "value" => "'fee'" }, %{ "comment" => nil, "key" => "FEE", "value" => "'fee'" }, %{ "comment" => nil, "key" => "ADL", "value" => "'auto-deleveraging'" } ], "name" => "parseLedgerEntryType", "signature" => "parseLedgerEntryType (type)", "source" => "parseLedgerEntryType (type) {\n const ledgerType = {\n 'EXCHANGE': 'transfer',\n 'CLOSE_POSITION': 'trade',\n 'TAKE_OVER': 'trade',\n 'MERGE': 'trade',\n 'QIANG_PING_MANAGER': 'fee',\n 'FUND': 'fee',\n 'FEE': 'fee',\n 'ADL': 'auto-deleveraging',\n };\n return this.safeString (ledgerType, type, type);\n }" }, %{ "comment" => nil, "examples" => [ "{\n \"symbol\": \"rad_usdt\",\n \"leverageBrackets\": [\n {\n \"symbol\": \"rad_usdt\",\n \"bracket\": 1,\n \"maxNominalValue\": \"5000\",\n \"maintMarginRate\": \"0.025\",\n \"startMarginRate\": \"0.05\",\n \"maxStartMarginRate\": null,\n \"maxLeverage\": \"20\",\n \"minLeverage\": \"1\"\n },\n ]\n }" ], "line_end" => 4280, "line_start" => 4247, "mappings" => [], "name" => "parseLeverageTiers", "signature" => "parseLeverageTiers (response, symbols = undefined, marketIdKey = undefined): LeverageTiers", "source" => "parseLeverageTiers (response, symbols = undefined, marketIdKey = undefined): LeverageTiers {\n //\n // {\n // \"symbol\": \"rad_usdt\",\n // \"leverageBrackets\": [\n // {\n // \"symbol\": \"rad_usdt\",\n // \"bracket\": 1,\n // \"maxNominalValue\": \"5000\",\n // \"maintMarginRate\": \"0.025\",\n // \"startMarginRate\": \"0.05\",\n // \"maxStartMarginRate\": null,\n // \"maxLeverage\": \"20\",\n // \"minLeverage\": \"1\"\n // },\n // ]\n // }\n //\n const result = {};\n for (let i = 0; i < response.length; i++) {\n const entry = response[i];\n const marketId = this.safeString (entry, 'symbol');\n const market = this.safeMarket (marketId, undefined, '_', 'contract');\n const symbol = this.safeSymbol (marketId, market);\n if (symbols !== undefined) {\n if (this.inArray (symbol, symbols)) {\n result[symbol] = this.parseMarketLeverageTiers (entry, market);\n }\n } else {\n result[symbol] = this.parseMarketLeverageTiers (response[i], market);\n }\n }\n return result as LeverageTiers;\n }" }, %{ "comment" => nil, "examples" => [], "line_end" => 4197, "line_start" => 4184, "mappings" => [ %{ "comment" => nil, "key" => "info", "value" => "data" }, %{ "comment" => nil, "key" => "type", "value" => "undefined" }, %{ "comment" => nil, "key" => "amount", "value" => "undefined" }, %{ "comment" => nil, "key" => "code", "value" => "undefined" }, %{ "comment" => nil, "key" => "symbol", "value" => "this.safeSymbol (undefined, market)" }, %{ "comment" => nil, "key" => "status", "value" => "undefined" }, %{ "comment" => nil, "key" => "marginMode", "value" => "undefined" }, %{ "comment" => nil, "key" => "total", "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 return {\n 'info': data,\n 'type': undefined,\n 'amount': undefined,\n 'code': undefined,\n 'symbol': this.safeSymbol (undefined, market),\n 'status': undefined,\n 'marginMode': undefined,\n 'total': undefined,\n 'timestamp': undefined,\n 'datetime': undefined,\n };\n }" }, %{ "comment" => nil, "examples" => [ "{\n \"id\": 640,\n \"symbol\": \"xt_usdt\",\n \"state\": \"ONLINE\",\n \"stateTime\": 1554048000000,\n \"tradingEnabled\": true,\n \"openapiEnabled\": true,\n \"nextStateTime\": null,\n \"nextState\": null,\n \"depthMergePrecision\": 5,\n \"baseCurrency\": \"xt\",\n \"baseCurrencyPrecision\": 8,\n \"baseCurrencyId\": 128,\n \"quoteCurrency\": \"usdt\",\n \"quoteCurrencyPrecision\": 8,\n \"quoteCurrencyId\": 11,\n \"pricePrecision\": 4,\n \"quantityPrecision\": 2,\n \"orderTypes\": [\"LIMIT\",\"MARKET\"],\n \"timeInForces\": [\"GTC\",\"IOC\"],\n \"displayWeight\": 10002,\n \"displayLevel\": \"FULL\",\n \"plates\": [],\n \"filters\":[\n {\n \"filter\": \"QUOTE_QTY\",\n \"min\": \"1\"\n },\n {\n \"filter\": \"PRICE\",\n \"min\": null,\n \"max\": null,\n \"tickSize\": null\n },\n {\n \"filter\": \"QUANTITY\",\n \"min\": null,\n \"max\": null,\n \"tickSize\": null\n },\n {\n \"filter\": \"PROTECTION_LIMIT\",\n \"buyMaxDeviation\": \"0.8\",\n \"sellMaxDeviation\": \"4\"\n },\n {\n \"filter\": \"PROTECTION_MARKET\",\n \"maxDeviation\": \"0.02\"\n },\n {\n \"filter\": \"PROTECTION_ONLINE\",\n \"durationSeconds\": \"300\",\n \"maxPriceMultiple\": \"5\"\n },\n ]\n }", "{\n \"id\": 52,\n \"symbolGroupId\": 71,\n \"symbol\": \"xt_usdt\",\n \"pair\": \"xt_usdt\",\n \"contractType\": \"PERPETUAL\",\n \"productType\": \"perpetual\",\n \"predictEventType\": null,\n \"underlyingType\": \"U_BASED\",\n \"contractSize\": \"1\",\n \"tradeSwitch\": true,\n \"isDisplay\": true,\n \"isOpenApi\": false,\n \"state\": 0,\n \"initLeverage\": 20,\n \"initPositionType\": \"CROSSED\",\n \"baseCoin\": \"xt\",\n \"quoteCoin\": \"usdt\",\n \"baseCoinPrecision\": 8,\n \"baseCoinDisplayPrecision\": 4,\n \"quoteCoinPrecision\": 8,\n \"quoteCoinDisplayPrecision\": 4,\n \"quantityPrecision\": 0,\n \"pricePrecision\": 4,\n \"supportOrderType\": \"LIMIT,MARKET\",\n \"supportTimeInForce\": \"GTC,FOK,IOC,GTX\",\n \"supportEntrustType\": \"TAKE_PROFIT,STOP,TAKE_PROFIT_MARKET,STOP_MARKET,TRAILING_STOP_MARKET\",\n \"supportPositionType\": \"CROSSED,ISOLATED\",\n \"minQty\": \"1\",\n \"minNotional\": \"5\",\n \"maxNotional\": \"20000000\",\n \"multiplierDown\": \"0.1\",\n \"multiplierUp\": \"0.1\",\n \"maxOpenOrders\": 200,\n \"maxEntrusts\": 200,\n \"makerFee\": \"0.0004\",\n \"takerFee\": \"0.0006\",\n \"liquidationFee\": \"0.01\",\n \"marketTakeBound\": \"0.1\",\n \"depthPrecisionMerge\": 5,\n \"labels\": [\"HOT\"],\n \"onboardDate\": 1657101601000,\n \"enName\": \"XTUSDT \",\n \"cnName\": \"XTUSDT\",\n \"minStepPrice\": \"0.0001\",\n \"minPrice\": null,\n \"maxPrice\": null,\n \"deliveryDate\": 1669879634000,\n \"deliveryPrice\": null,\n \"deliveryCompletion\": false,\n \"cnDesc\": null,\n \"enDesc\": null\n }" ], "line_end" => 1393, "line_start" => 1139, "mappings" => [ %{ "comment" => nil, "key" => "id", "value" => "id" }, %{ "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" => "spot" }, %{ "comment" => nil, "key" => "margin", "value" => "undefined" }, %{ "comment" => nil, "key" => "swap", "value" => "swap" }, %{ "comment" => nil, "key" => "future", "value" => "future" }, %{ "comment" => nil, "key" => "option", "value" => "false" }, %{ "comment" => nil, "key" => "active", "value" => "isActive" }, %{ "comment" => nil, "key" => "contract", "value" => "contract" }, %{ "comment" => nil, "key" => "linear", "value" => "linear" }, %{ "comment" => nil, "key" => "inverse", "value" => "inverse" }, %{ "comment" => nil, "key" => "taker", "value" => "this.safeNumber (market, 'takerFee')" }, %{ "comment" => nil, "key" => "maker", "value" => "this.safeNumber (market, 'makerFee')" }, %{ "comment" => nil, "key" => "contractSize", "value" => "this.safeNumber (market, 'contractSize')" }, %{ "comment" => nil, "key" => "expiry", "value" => "expiry" }, %{ "comment" => nil, "key" => "expiryDatetime", "value" => "this.iso8601 (expiry)" }, %{ "comment" => nil, "key" => "strike", "value" => "undefined" }, %{ "comment" => nil, "key" => "optionType", "value" => "undefined" }, %{ "comment" => nil, "key" => "precision", "value" => "{\n 'price': this.parseNumber (this.parsePrecision (this.safeString (market, 'pricePrecision'))),\n 'amount': amountPrecision,\n 'base': this.parseNumber (this.parsePrecision (this.safeString (market, 'baseCoinPrecision'))),\n 'quote': this.parseNumber (this.parsePrecision (this.safeString (market, 'quoteCoinPrecision'))),\n }" }, %{ "comment" => nil, "key" => "limits", "value" => "{\n 'leverage': {\n 'min': this.parseNumber ('1'),\n 'max': undefined,\n },\n 'amount': {\n 'min': minAmount,\n 'max': maxAmount,\n },\n 'price': {\n 'min': minPrice,\n 'max': maxPrice,\n },\n 'cost': {\n 'min': minCost,\n 'max': maxCost,\n },\n }" }, %{ "comment" => nil, "key" => "info", "value" => "market" }, %{ "comment" => nil, "key" => "price", "value" => "this.parseNumber (this.parsePrecision (this.safeString (market, 'pricePrecision')))" }, %{ "comment" => nil, "key" => "amount", "value" => "amountPrecision" }, %{ "comment" => nil, "key" => "base", "value" => "this.parseNumber (this.parsePrecision (this.safeString (market, 'baseCoinPrecision')))" }, %{ "comment" => nil, "key" => "quote", "value" => "this.parseNumber (this.parsePrecision (this.safeString (market, 'quoteCoinPrecision')))" }, %{ "comment" => nil, "key" => "leverage", "value" => "{\n 'min': this.parseNumber ('1'),\n 'max': undefined,\n }" }, %{ "comment" => nil, "key" => "amount", "value" => "{\n 'min': minAmount,\n 'max': maxAmount,\n }" }, %{ "comment" => nil, "key" => "price", "value" => "{\n 'min': minPrice,\n 'max': maxPrice,\n }" }, %{ "comment" => nil, "key" => "cost", "value" => "{\n 'min': minCost,\n 'max': maxCost,\n }" } ], "name" => "parseMarket", "signature" => "parseMarket (market: Dict): Market", "source" => "parseMarket (market: Dict): Market {\n //\n // spot\n //\n // {\n // \"id\": 640,\n // \"symbol\": \"xt_usdt\",\n // \"state\": \"ONLINE\",\n // \"stateTime\": 1554048000000,\n // \"tradingEnabled\": true,\n // \"openapiEnabled\": true,\n // \"nextStateTime\": null,\n // \"nextState\": null,\n // \"depthMergePrecision\": 5,\n // \"baseCurrency\": \"xt\",\n // \"baseCurrencyPrecision\": 8,\n // \"baseCurrencyId\": 128,\n // \"quoteCurrency\": \"usdt\",\n // \"quoteCurrencyPrecision\": 8,\n // \"quoteCurrencyId\": 11,\n // \"pricePrecision\": 4,\n // \"quantityPrecision\": 2,\n // \"orderTypes\": [\"LIMIT\",\"MARKET\"],\n // \"timeInForces\": [\"GTC\",\"IOC\"],\n // \"displayWeight\": 10002,\n // \"displayLevel\": \"FULL\",\n // \"plates\": [],\n // \"filters\":[\n // {\n // \"filter\": \"QUOTE_QTY\",\n // \"min\": \"1\"\n // },\n // {\n // \"filter\": \"PRICE\",\n // \"min\": null,\n // \"max\": null,\n // \"tickSize\": null\n // },\n // {\n // \"filter\": \"QUANTITY\",\n // \"min\": null,\n // \"max\": null,\n // \"tickSize\": null\n // },\n // {\n // \"filter\": \"PROTECTION_LIMIT\",\n // \"buyMaxDeviation\": \"0.8\",\n // \"sellMaxDeviation\": \"4\"\n // },\n // {\n // \"filter\": \"PROTECTION_MARKET\",\n // \"maxDeviation\": \"0.02\"\n // },\n // {\n // \"filter\": \"PROTECTION_ONLINE\",\n // \"durationSeconds\": \"300\",\n // \"maxPriceMultiple\": \"5\"\n // },\n // ]\n // }\n //\n // swap and future\n //\n // {\n // \"id\": 52,\n // \"symbolGroupId\": 71,\n // \"symbol\": \"xt_usdt\",\n // \"pair\": \"xt_usdt\",\n // \"contractType\": \"PERPETUAL\",\n // \"productType\": \"perpetual\",\n // \"predictEventType\": null,\n // \"underlyingType\": \"U_BASED\",\n // \"contractSize\": \"1\",\n // \"tradeSwitch\": true,\n // \"isDisplay\": true,\n // \"isOpenApi\": false,\n // \"state\": 0,\n // \"initLeverage\": 20,\n // \"initPositionType\": \"CROSSED\",\n // \"baseCoin\": \"xt\",\n // \"quoteCoin\": \"usdt\",\n // \"baseCoinPrecision\": 8,\n // \"baseCoinDisplayPrecision\": 4,\n // \"quoteCoinPrecision\": 8,\n // \"quoteCoinDisplayPrecision\": 4,\n // \"quantityPrecision\": 0,\n // \"pricePrecision\": 4,\n // \"supportOrderType\": \"LIMIT,MARKET\",\n // \"supportTimeInForce\": \"GTC,FOK,IOC,GTX\",\n // \"supportEntrustType\": \"TAKE_PROFIT,STOP,TAKE_PROFIT_MARKET,STOP_MARKET,TRAILING_STOP_MARKET\",\n // \"supportPositionType\": \"CROSSED,ISOLATED\",\n // \"minQty\": \"1\",\n // \"minNotional\": \"5\",\n // \"maxNotional\": \"20000000\",\n // \"multiplierDown\": \"0.1\",\n // \"multiplierUp\": \"0.1\",\n // \"maxOpenOrders\": 200,\n // \"maxEntrusts\": 200,\n // \"makerFee\": \"0.0004\",\n // \"takerFee\": \"0.0006\",\n // \"liquidationFee\": \"0.01\",\n // \"marketTakeBound\": \"0.1\",\n // \"depthPrecisionMerge\": 5,\n // \"labels\": [\"HOT\"],\n // \"onboardDate\": 1657101601000,\n // \"enName\": \"XTUSDT \",\n // \"cnName\": \"XTUSDT\",\n // \"minStepPrice\": \"0.0001\",\n // \"minPrice\": null,\n // \"maxPrice\": null,\n // \"deliveryDate\": 1669879634000,\n // \"deliveryPrice\": null,\n // \"deliveryCompletion\": false,\n // \"cnDesc\": null,\n // \"enDesc\": null\n // }\n //\n const id = this.safeString (market, 'symbol');\n const baseId = this.safeString2 (market, 'baseCurrency', 'baseCoin');\n const quoteId = this.safeString2 (market, 'quoteCurrency', 'quoteCoin');\n const base = this.safeCurrencyCode (baseId);\n const quote = this.safeCurrencyCode (quoteId);\n const state = this.safeString (market, 'state');\n let symbol = base + '/' + quote;\n const filters = this.safeValue (market, 'filters', []);\n let minAmount = undefined;\n let maxAmount = undefined;\n let minCost = undefined;\n let maxCost = undefined;\n let minPrice = undefined;\n let maxPrice = undefined;\n let amountPrecision = undefined;\n for (let i = 0; i < filters.length; i++) {\n const entry = filters[i];\n const filter = this.safeString (entry, 'filter');\n if (filter === 'QUANTITY') {\n minAmount = this.safeNumber (entry, 'min');\n maxAmount = this.safeNumber (entry, 'max');\n amountPrecision = this.safeNumber (entry, 'tickSize');\n }\n if (filter === 'QUOTE_QTY') {\n minCost = this.safeNumber (entry, 'min');\n }\n if (filter === 'PRICE') {\n minPrice = this.safeNumber (entry, 'min');\n maxPrice = this.safeNumber (entry, 'max');\n }\n }\n if (amountPrecision === undefined) {\n amountPrecision = this.parseNumber (this.parsePrecision (this.safeString (market, 'quantityPrecision')));\n }\n const underlyingType = this.safeString (market, 'underlyingType');\n let linear = undefined;\n let inverse = undefined;\n let settleId = undefined;\n let settle = undefined;\n let expiry = undefined;\n let future = false;\n let swap = false;\n let contract = false;\n let spot = true;\n let type = 'spot';\n if (underlyingType === 'U_BASED') {\n symbol = symbol + ':' + quote;\n settleId = baseId;\n settle = quote;\n linear = true;\n inverse = false;\n } else if (underlyingType === 'COIN_BASED') {\n symbol = symbol + ':' + base;\n settleId = baseId;\n settle = base;\n linear = false;\n inverse = true;\n }\n if (underlyingType !== undefined) {\n expiry = this.safeInteger (market, 'deliveryDate');\n const productType = this.safeString (market, 'productType');\n if (productType !== 'perpetual') {\n symbol = symbol + '-' + this.yymmdd (expiry);\n type = 'future';\n future = true;\n } else {\n type = 'swap';\n swap = true;\n }\n minAmount = this.safeNumber (market, 'minQty');\n minCost = this.safeNumber (market, 'minNotional');\n maxCost = this.safeNumber (market, 'maxNotional');\n minPrice = this.safeNumber (market, 'minPrice');\n maxPrice = this.safeNumber (market, 'maxPrice');\n contract = true;\n spot = false;\n }\n let isActive = false;\n if (contract) {\n isActive = this.safeValue (market, 'isOpenApi', false);\n } else {\n if ((state === 'ONLINE') && (this.safeValue (market, 'tradingEnabled')) && (this.safeValue (market, 'openapiEnabled'))) {\n isActive = true;\n }\n }\n return this.safeMarketStructure ({\n 'id': id,\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': spot,\n 'margin': undefined,\n 'swap': swap,\n 'future': future,\n 'option': false,\n 'active': isActive,\n 'contract': contract,\n 'linear': linear,\n 'inverse': inverse,\n 'taker': this.safeNumber (market, 'takerFee'),\n 'maker': this.safeNumber (market, 'makerFee'),\n 'contractSize': this.safeNumber (market, 'contractSize'),\n 'expiry': expiry,\n 'expiryDatetime': this.iso8601 (expiry),\n 'strike': undefined,\n 'optionType': undefined,\n 'precision': {\n 'price': this.parseNumber (this.parsePrecision (this.safeString (market, 'pricePrecision'))),\n 'amount': amountPrecision,\n 'base': this.parseNumber (this.parsePrecision (this.safeString (market, 'baseCoinPrecision'))),\n 'quote': this.parseNumber (this.parsePrecision (this.safeString (market, 'quoteCoinPrecision'))),\n },\n 'limits': {\n 'leverage': {\n 'min': this.parseNumber ('1'),\n 'max': undefined,\n },\n 'amount': {\n 'min': minAmount,\n 'max': maxAmount,\n },\n 'price': {\n 'min': minPrice,\n 'max': maxPrice,\n },\n 'cost': {\n 'min': minCost,\n 'max': maxCost,\n },\n },\n 'info': market,\n });\n }" }, %{ "comment" => nil, "examples" => [ "{\n \"symbol\": \"rad_usdt\",\n \"leverageBrackets\": [\n {\n \"symbol\": \"rad_usdt\",\n \"bracket\": 1,\n \"maxNominalValue\": \"5000\",\n \"maintMarginRate\": \"0.025\",\n \"startMarginRate\": \"0.05\",\n \"maxStartMarginRate\": null,\n \"maxLeverage\": \"20\",\n \"minLeverage\": \"1\"\n },\n ]\n }" ], "line_end" => 4367, "line_start" => 4331, "mappings" => [ %{ "comment" => nil, "key" => "tier", "value" => "this.safeInteger (tier, 'bracket')" }, %{ "comment" => nil, "key" => "symbol", "value" => "this.safeSymbol (marketId, market, '_', 'contract')" }, %{ "comment" => nil, "key" => "currency", "value" => "market['settle']" }, %{ "comment" => nil, "key" => "minNotional", "value" => "this.safeNumber (brackets[i - 1], 'maxNominalValue', 0)" }, %{ "comment" => nil, "key" => "maxNotional", "value" => "this.safeNumber (tier, 'maxNominalValue')" }, %{ "comment" => nil, "key" => "maintenanceMarginRate", "value" => "this.safeNumber (tier, 'maintMarginRate')" }, %{ "comment" => nil, "key" => "maxLeverage", "value" => "this.safeNumber (tier, 'maxLeverage')" }, %{ "comment" => nil, "key" => "info", "value" => "tier" } ], "name" => "parseMarketLeverageTiers", "signature" => "parseMarketLeverageTiers (info, market = undefined): LeverageTier[]", "source" => "parseMarketLeverageTiers (info, market = undefined): LeverageTier[] {\n //\n // {\n // \"symbol\": \"rad_usdt\",\n // \"leverageBrackets\": [\n // {\n // \"symbol\": \"rad_usdt\",\n // \"bracket\": 1,\n // \"maxNominalValue\": \"5000\",\n // \"maintMarginRate\": \"0.025\",\n // \"startMarginRate\": \"0.05\",\n // \"maxStartMarginRate\": null,\n // \"maxLeverage\": \"20\",\n // \"minLeverage\": \"1\"\n // },\n // ]\n // }\n //\n const tiers = [];\n const brackets = this.safeValue (info, 'leverageBrackets', []);\n for (let i = 0; i < brackets.length; i++) {\n const tier = brackets[i];\n const marketId = this.safeString (info, 'symbol');\n market = this.safeMarket (marketId, market, '_', 'contract');\n tiers.push ({\n 'tier': this.safeInteger (tier, 'bracket'),\n 'symbol': this.safeSymbol (marketId, market, '_', 'contract'),\n 'currency': market['settle'],\n 'minNotional': this.safeNumber (brackets[i - 1], 'maxNominalValue', 0),\n 'maxNotional': this.safeNumber (tier, 'maxNominalValue'),\n 'maintenanceMarginRate': this.safeNumber (tier, 'maintMarginRate'),\n 'maxLeverage': this.safeNumber (tier, 'maxLeverage'),\n 'info': tier,\n });\n }\n return tiers as LeverageTier[];\n }" }, %{ "comment" => nil, "examples" => [], "line_end" => 1137, "line_start" => 1131, "mappings" => [], "name" => "parseMarkets", "signature" => "parseMarkets (markets)", "source" => "parseMarkets (markets) {\n const result = [];\n for (let i = 0; i < markets.length; i++) {\n result.push (this.parseMarket (markets[i]));\n }\n return result;\n }" }, %{ "comment" => nil, "examples" => [ "{\n \"t\": 1678167720000,\n \"o\": \"22467.85\",\n \"c\": \"22465.87\",\n \"h\": \"22468.86\",\n \"l\": \"22465.21\",\n \"q\": \"1.316656\",\n \"v\": \"29582.73018498\"\n }", "{\n \"s\": \"btc_usdt\",\n \"p\": \"btc_usdt\",\n \"t\": 1678168020000,\n \"o\": \"22450.0\",\n \"c\": \"22441.5\",\n \"h\": \"22450.0\",\n \"l\": \"22441.5\",\n \"a\": \"312931\",\n \"v\": \"702461.58895\"\n }" ], "line_end" => 1525, "line_start" => 1488, "mappings" => [], "name" => "parseOHLCV", "signature" => "parseOHLCV (ohlcv, market: Market = undefined): OHLCV", "source" => "parseOHLCV (ohlcv, market: Market = undefined): OHLCV {\n //\n // spot\n //\n // {\n // \"t\": 1678167720000,\n // \"o\": \"22467.85\",\n // \"c\": \"22465.87\",\n // \"h\": \"22468.86\",\n // \"l\": \"22465.21\",\n // \"q\": \"1.316656\",\n // \"v\": \"29582.73018498\"\n // }\n //\n // swap and future\n //\n // {\n // \"s\": \"btc_usdt\",\n // \"p\": \"btc_usdt\",\n // \"t\": 1678168020000,\n // \"o\": \"22450.0\",\n // \"c\": \"22441.5\",\n // \"h\": \"22450.0\",\n // \"l\": \"22441.5\",\n // \"a\": \"312931\",\n // \"v\": \"702461.58895\"\n // }\n //\n const volumeIndex = (market['inverse']) ? 'v' : 'a';\n return [\n this.safeInteger (ohlcv, 't'),\n this.safeNumber (ohlcv, 'o'),\n this.safeNumber (ohlcv, 'h'),\n this.safeNumber (ohlcv, 'l'),\n this.safeNumber (ohlcv, 'c'),\n this.safeNumber2 (ohlcv, 'q', volumeIndex),\n ];\n }" }, %{ "comment" => nil, "examples" => [ "{\n \"orderId\": \"204371980095156544\"\n }", "{\n \"cancelId\": \"208322474307982720\"\n }", "{\n \"returnCode\": 0,\n \"msgInfo\": \"success\",\n \"error\": null,\n \"result\": \"206410760006650176\"\n }", "{\n \"symbol\": \"btc_usdt\",\n \"orderId\": \"207505997850909952\",\n \"clientOrderId\": null,\n \"baseCurrency\": \"btc\",\n \"quoteCurrency\": \"usdt\",\n \"side\": \"BUY\",\n \"type\": \"LIMIT\",\n \"timeInForce\": \"GTC\",\n \"price\": \"20000.00\",\n \"origQty\": \"0.001000\",\n \"origQuoteQty\": \"20.00\",\n \"executedQty\": \"0.000000\",\n \"leavingQty\": \"0.001000\",\n \"tradeBase\": \"0.000000\",\n \"tradeQuote\": \"0.00\",\n \"avgPrice\": null,\n \"fee\": null,\n \"feeCurrency\": null,\n \"closed\": false,\n \"state\": \"NEW\",\n \"time\": 1679175285162,\n \"updatedTime\": 1679175285255\n }", "{\n \"orderId\": \"207519546930995456\",\n \"clientOrderId\": null,\n \"symbol\": \"btc_usdt\",\n \"orderType\": \"LIMIT\",\n \"orderSide\": \"BUY\",\n \"positionSide\": \"LONG\",\n \"timeInForce\": \"GTC\",\n \"closePosition\": false,\n \"price\": \"20000\",\n \"origQty\": \"100\",\n \"avgPrice\": \"0\",\n \"executedQty\": \"0\",\n \"marginFrozen\": \"4.12\",\n \"remark\": null,\n \"triggerProfitPrice\": null,\n \"triggerStopPrice\": null,\n \"sourceId\": null,\n \"sourceType\": \"DEFAULT\",\n \"forceClose\": false,\n \"closeProfit\": null,\n \"state\": \"CANCELED\",\n \"createdTime\": 1679178515689,\n \"updatedTime\": 1679180096172\n }" ], "line_end" => 3633, "line_start" => 3467, "mappings" => [ %{ "comment" => nil, "key" => "info", "value" => "order" }, %{ "comment" => nil, "key" => "id", "value" => "this.safeStringN (order, [ 'orderId', 'result', 'cancelId', 'entrustId', 'profitId' ])" }, %{ "comment" => nil, "key" => "clientOrderId", "value" => "this.safeString2 (order, 'clientOrderId', 'clientModifyId')" }, %{ "comment" => nil, "key" => "timestamp", "value" => "timestamp" }, %{ "comment" => nil, "key" => "datetime", "value" => "this.iso8601 (timestamp)" }, %{ "comment" => nil, "key" => "lastTradeTimestamp", "value" => "lastUpdatedTimestamp" }, %{ "comment" => nil, "key" => "lastUpdateTimestamp", "value" => "lastUpdatedTimestamp" }, %{ "comment" => nil, "key" => "symbol", "value" => "symbol" }, %{ "comment" => nil, "key" => "type", "value" => "this.safeStringLower2 (order, 'type', 'orderType')" }, %{ "comment" => nil, "key" => "timeInForce", "value" => "this.safeString (order, 'timeInForce')" }, %{ "comment" => nil, "key" => "postOnly", "value" => "undefined" }, %{ "comment" => nil, "key" => "side", "value" => "this.safeStringLower2 (order, 'side', 'orderSide')" }, %{ "comment" => nil, "key" => "price", "value" => "this.safeNumber (order, 'price')" }, %{ "comment" => nil, "key" => "triggerPrice", "value" => "this.safeNumber (order, 'stopPrice')" }, %{ "comment" => nil, "key" => "stopLoss", "value" => "this.safeNumber (order, 'triggerStopPrice')" }, %{ "comment" => nil, "key" => "takeProfit", "value" => "this.safeNumber (order, 'triggerProfitPrice')" }, %{ "comment" => nil, "key" => "amount", "value" => "amount" }, %{ "comment" => nil, "key" => "filled", "value" => "filled" }, %{ "comment" => nil, "key" => "remaining", "value" => "this.safeNumber (order, 'leavingQty')" }, %{ "comment" => nil, "key" => "cost", "value" => "undefined" }, %{ "comment" => nil, "key" => "average", "value" => "this.safeNumber (order, 'avgPrice')" }, %{ "comment" => nil, "key" => "status", "value" => "this.parseOrderStatus (this.safeString (order, 'state'))" }, %{ "comment" => nil, "key" => "fee", "value" => "{\n 'currency': this.safeCurrencyCode (this.safeString (order, 'feeCurrency')),\n 'cost': this.safeNumber (order, 'fee'),\n }" }, %{ "comment" => nil, "key" => "trades", "value" => "undefined" }, %{ "comment" => nil, "key" => "currency", "value" => "this.safeCurrencyCode (this.safeString (order, 'feeCurrency'))" }, %{ "comment" => nil, "key" => "cost", "value" => "this.safeNumber (order, 'fee')" } ], "name" => "parseOrder", "signature" => "parseOrder (order, market = undefined)", "source" => "parseOrder (order, market = undefined) {\n //\n // spot: createOrder\n //\n // {\n // \"orderId\": \"204371980095156544\"\n // }\n //\n // spot: cancelOrder\n //\n // {\n // \"cancelId\": \"208322474307982720\"\n // }\n //\n // swap and future: createOrder, cancelOrder, editOrder\n //\n // {\n // \"returnCode\": 0,\n // \"msgInfo\": \"success\",\n // \"error\": null,\n // \"result\": \"206410760006650176\"\n // }\n //\n // spot: fetchOrder, fetchOrders, fetchOpenOrders, fetchClosedOrders, fetchCanceledOrders, fetchOrdersByStatus\n //\n // {\n // \"symbol\": \"btc_usdt\",\n // \"orderId\": \"207505997850909952\",\n // \"clientOrderId\": null,\n // \"baseCurrency\": \"btc\",\n // \"quoteCurrency\": \"usdt\",\n // \"side\": \"BUY\",\n // \"type\": \"LIMIT\",\n // \"timeInForce\": \"GTC\",\n // \"price\": \"20000.00\",\n // \"origQty\": \"0.001000\",\n // \"origQuoteQty\": \"20.00\",\n // \"executedQty\": \"0.000000\",\n // \"leavingQty\": \"0.001000\",\n // \"tradeBase\": \"0.000000\",\n // \"tradeQuote\": \"0.00\",\n // \"avgPrice\": null,\n // \"fee\": null,\n // \"feeCurrency\": null,\n // \"closed\": false,\n // \"state\": \"NEW\",\n // \"time\": 1679175285162,\n // \"updatedTime\": 1679175285255\n // }\n //\n // swap and future: fetchOrder, fetchOrders, fetchOpenOrders, fetchClosedOrders, fetchCanceledOrders, fetchOrdersByStatus\n //\n // {\n // \"orderId\": \"207519546930995456\",\n // \"clientOrderId\": null,\n // \"symbol\": \"btc_usdt\",\n // \"orderType\": \"LIMIT\",\n // \"orderSide\": \"BUY\",\n // \"positionSide\": \"LONG\",\n // \"timeInForce\": \"GTC\",\n // \"closePosition\": false,\n // \"price\": \"20000\",\n // \"origQty\": \"100\",\n // \"avgPrice\": \"0\",\n // \"executedQty\": \"0\",\n // \"marginFrozen\": \"4.12\",\n // \"remark\": null,\n // \"triggerProfitPrice\": null,\n // \"triggerStopPrice\": null,\n // \"sourceId\": null,\n // \"sourceType\": \"DEFAULT\",\n // \"forceClose\": false,\n // \"closeProfit\": null,\n // \"state\": \"CANCELED\",\n // \"createdTime\": 1679178515689,\n // \"updatedTime\": 1679180096172\n // }\n //\n // trigger: fetchOrder, fetchOrders, fetchOpenOrders, fetchClosedOrders, fetchCanceledOrders, fetchOrdersByStatus\n //\n // {\n // \"entrustId\": \"216300248132756992\",\n // \"symbol\": \"btc_usdt\",\n // \"entrustType\": \"STOP\",\n // \"orderSide\": \"SELL\",\n // \"positionSide\": \"SHORT\",\n // \"timeInForce\": \"GTC\",\n // \"closePosition\": null,\n // \"price\": \"20000\",\n // \"origQty\": \"1\",\n // \"stopPrice\": \"19000\",\n // \"triggerPriceType\": \"LATEST_PRICE\",\n // \"state\": \"NOT_TRIGGERED\",\n // \"marketOrderLevel\": null,\n // \"createdTime\": 1681271998064,\n // \"updatedTime\": 1681271998064,\n // \"ordinary\": false\n // }\n //\n // stop-loss and take-profit: fetchOrder, fetchOpenOrders, fetchClosedOrders, fetchCanceledOrders, fetchOrdersByStatus\n //\n // {\n // \"profitId\": \"216306213226230400\",\n // \"symbol\": \"btc_usdt\",\n // \"positionSide\": \"LONG\",\n // \"origQty\": \"1\",\n // \"triggerPriceType\": \"LATEST_PRICE\",\n // \"triggerProfitPrice\": null,\n // \"triggerStopPrice\": \"20000\",\n // \"entryPrice\": null,\n // \"positionSize\": null,\n // \"isolatedMargin\": null,\n // \"executedQty\": null,\n // \"avgPrice\": null,\n // \"positionType\": \"ISOLATED\",\n // \"state\": \"NOT_TRIGGERED\",\n // \"createdTime\": 1681273420039\n // }\n //\n // spot editOrder\n //\n // {\n // \"orderId\": \"484203027161892224\",\n // \"modifyId\": \"484203544105344000\",\n // \"clientModifyId\": null\n // }\n //\n const marketId = this.safeString (order, 'symbol');\n const marketType = ('result' in order) || ('positionSide' in order) ? 'contract' : 'spot';\n market = this.safeMarket (marketId, market, undefined, marketType);\n const symbol = this.safeSymbol (marketId, market, undefined, marketType);\n const timestamp = this.safeInteger2 (order, 'time', 'createdTime');\n const quantity = this.safeNumber (order, 'origQty');\n const amount = (marketType === 'spot') ? quantity : Precise.stringMul (this.numberToString (quantity), this.numberToString (market['contractSize']));\n const filledQuantity = this.safeNumber (order, 'executedQty');\n const filled = (marketType === 'spot') ? filledQuantity : Precise.stringMul (this.numberToString (filledQuantity), this.numberToString (market['contractSize']));\n const lastUpdatedTimestamp = this.safeInteger (order, 'updatedTime');\n return this.safeOrder ({\n 'info': order,\n 'id': this.safeStringN (order, [ 'orderId', 'result', 'cancelId', 'entrustId', 'profitId' ]),\n 'clientOrderId': this.safeString2 (order, 'clientOrderId', 'clientModifyId'),\n 'timestamp': timestamp,\n 'datetime': this.iso8601 (timestamp),\n 'lastTradeTimestamp': lastUpdatedTimestamp,\n 'lastUpdateTimestamp': lastUpdatedTimestamp,\n 'symbol': symbol,\n 'type': this.safeStringLower2 (order, 'type', 'orderType'),\n 'timeInForce': this.safeString (order, 'timeInForce'),\n 'postOnly': undefined,\n 'side': this.safeStringLower2 (order, 'side', 'orderSide'),\n 'price': this.safeNumber (order, 'price'),\n 'triggerPrice': this.safeNumber (order, 'stopPrice'),\n 'stopLoss': this.safeNumber (order, 'triggerStopPrice'),\n 'takeProfit': this.safeNumber (order, 'triggerProfitPrice'),\n 'amount': amount,\n 'filled': filled,\n 'remaining': this.safeNumber (order, 'leavingQty'),\n 'cost': undefined,\n 'average': this.safeNumber (order, 'avgPrice'),\n 'status': this.parseOrderStatus (this.safeString (order, 'state')),\n 'fee': {\n 'currency': this.safeCurrencyCode (this.safeString (order, 'feeCurrency')),\n 'cost': this.safeNumber (order, 'fee'),\n },\n 'trades': undefined,\n }, market);\n }" }, %{ "comment" => nil, "examples" => [], "line_end" => 3652, "line_start" => 3635, "mappings" => [ %{ "comment" => nil, "key" => "NEW", "value" => "'open'" }, %{ "comment" => nil, "key" => "PARTIALLY_FILLED", "value" => "'open'" }, %{ "comment" => nil, "key" => "FILLED", "value" => "'closed'" }, %{ "comment" => nil, "key" => "CANCELED", "value" => "'canceled'" }, %{ "comment" => nil, "key" => "REJECTED", "value" => "'rejected'" }, %{ "comment" => nil, "key" => "EXPIRED", "value" => "'expired'" }, %{ "comment" => nil, "key" => "UNFINISHED", "value" => "'open'" }, %{ "comment" => nil, "key" => "NOT_TRIGGERED", "value" => "'open'" }, %{ "comment" => nil, "key" => "TRIGGERING", "value" => "'open'" }, %{ "comment" => nil, "key" => "TRIGGERED", "value" => "'closed'" }, %{ "comment" => nil, "key" => "USER_REVOCATION", "value" => "'canceled'" }, %{ "comment" => nil, "key" => "PLATFORM_REVOCATION", "value" => "'rejected'" }, %{ "comment" => nil, "key" => "HISTORY", "value" => "'expired'" } ], "name" => "parseOrderStatus", "signature" => "parseOrderStatus (status)", "source" => "parseOrderStatus (status) {\n const statuses = {\n 'NEW': 'open',\n 'PARTIALLY_FILLED': 'open',\n 'FILLED': 'closed',\n 'CANCELED': 'canceled',\n 'REJECTED': 'rejected',\n 'EXPIRED': 'expired',\n 'UNFINISHED': 'open',\n 'NOT_TRIGGERED': 'open',\n 'TRIGGERING': 'open',\n 'TRIGGERED': 'closed',\n 'USER_REVOCATION': 'canceled',\n 'PLATFORM_REVOCATION': 'rejected',\n 'HISTORY': 'expired',\n };\n return this.safeString (statuses, status, status);\n }" }, %{ "comment" => nil, "examples" => [ "{\n \"symbol\": \"btc_usdt\",\n \"positionType\": \"ISOLATED\",\n \"positionSide\": \"SHORT\",\n \"contractType\": \"PERPETUAL\",\n \"positionSize\": \"10\",\n \"closeOrderSize\": \"0\",\n \"availableCloseSize\": \"10\",\n \"entryPrice\": \"27060\",\n \"openOrderSize\": \"0\",\n \"isolatedMargin\": \"1.0824\",\n \"openOrderMarginFrozen\": \"0\",\n \"realizedProfit\": \"-0.00130138\",\n \"autoMargin\": false,\n \"leverage\": 25\n }" ], "line_end" => 4804, "line_start" => 4754, "mappings" => [ %{ "comment" => nil, "key" => "info", "value" => "position" }, %{ "comment" => nil, "key" => "id", "value" => "undefined" }, %{ "comment" => nil, "key" => "symbol", "value" => "symbol" }, %{ "comment" => nil, "key" => "timestamp", "value" => "undefined" }, %{ "comment" => nil, "key" => "datetime", "value" => "undefined" }, %{ "comment" => nil, "key" => "hedged", "value" => "undefined" }, %{ "comment" => nil, "key" => "side", "value" => "this.safeStringLower (position, 'positionSide')" }, %{ "comment" => nil, "key" => "contracts", "value" => "this.safeNumber (position, 'positionSize')" }, %{ "comment" => nil, "key" => "contractSize", "value" => "market['contractSize']" }, %{ "comment" => nil, "key" => "entryPrice", "value" => "this.safeNumber (position, 'entryPrice')" }, %{ "comment" => nil, "key" => "markPrice", "value" => "undefined" }, %{ "comment" => nil, "key" => "notional", "value" => "undefined" }, %{ "comment" => nil, "key" => "leverage", "value" => "this.safeInteger (position, 'leverage')" }, %{ "comment" => nil, "key" => "collateral", "value" => "collateral" }, %{ "comment" => nil, "key" => "initialMargin", "value" => "collateral" }, %{ "comment" => nil, "key" => "maintenanceMargin", "value" => "undefined" }, %{ "comment" => nil, "key" => "initialMarginPercentage", "value" => "undefined" }, %{ "comment" => nil, "key" => "maintenanceMarginPercentage", "value" => "undefined" }, %{ "comment" => nil, "key" => "unrealizedPnl", "value" => "undefined" }, %{ "comment" => nil, "key" => "liquidationPrice", "value" => "undefined" }, %{ "comment" => nil, "key" => "marginMode", "value" => "marginMode" }, %{ "comment" => nil, "key" => "percentage", "value" => "undefined" }, %{ "comment" => nil, "key" => "marginRatio", "value" => "undefined" } ], "name" => "parsePosition", "signature" => "parsePosition (position, market = undefined)", "source" => "parsePosition (position, market = undefined) {\n //\n // {\n // \"symbol\": \"btc_usdt\",\n // \"positionType\": \"ISOLATED\",\n // \"positionSide\": \"SHORT\",\n // \"contractType\": \"PERPETUAL\",\n // \"positionSize\": \"10\",\n // \"closeOrderSize\": \"0\",\n // \"availableCloseSize\": \"10\",\n // \"entryPrice\": \"27060\",\n // \"openOrderSize\": \"0\",\n // \"isolatedMargin\": \"1.0824\",\n // \"openOrderMarginFrozen\": \"0\",\n // \"realizedProfit\": \"-0.00130138\",\n // \"autoMargin\": false,\n // \"leverage\": 25\n // }\n //\n const marketId = this.safeString (position, 'symbol');\n market = this.safeMarket (marketId, market, undefined, 'contract');\n const symbol = this.safeSymbol (marketId, market, undefined, 'contract');\n const positionType = this.safeString (position, 'positionType');\n const marginMode = (positionType === 'CROSSED') ? 'cross' : 'isolated';\n const collateral = this.safeNumber (position, 'isolatedMargin');\n return this.safePosition ({\n 'info': position,\n 'id': undefined,\n 'symbol': symbol,\n 'timestamp': undefined,\n 'datetime': undefined,\n 'hedged': undefined,\n 'side': this.safeStringLower (position, 'positionSide'),\n 'contracts': this.safeNumber (position, 'positionSize'),\n 'contractSize': market['contractSize'],\n 'entryPrice': this.safeNumber (position, 'entryPrice'),\n 'markPrice': undefined,\n 'notional': undefined,\n 'leverage': this.safeInteger (position, 'leverage'),\n 'collateral': collateral,\n 'initialMargin': collateral,\n 'maintenanceMargin': undefined,\n 'initialMarginPercentage': undefined,\n 'maintenanceMarginPercentage': undefined,\n 'unrealizedPnl': undefined,\n 'liquidationPrice': undefined,\n 'marginMode': marginMode,\n 'percentage': undefined,\n 'marginRatio': undefined,\n });\n }" }, %{ "comment" => nil, "examples" => [ "{\n \"s\": \"btc_usdt\",\n \"t\": 1678172693931,\n \"cv\": \"34.00\",\n \"cr\": \"0.0015\",\n \"o\": \"22398.05\",\n \"l\": \"22323.72\",\n \"h\": \"22600.50\",\n \"c\": \"22432.05\",\n \"q\": \"7962.256931\",\n \"v\": \"178675209.47416856\"\n }", "{\n \"t\": 1678172848572,\n \"s\": \"btc_usdt\",\n \"c\": \"22415.5\",\n \"h\": \"22590.0\",\n \"l\": \"22310.0\",\n \"a\": \"623654031\",\n \"v\": \"1399166074.31675\",\n \"o\": \"22381.5\",\n \"r\": \"0.0015\",\n \"i\": \"22424.5\",\n \"m\": \"22416.5\",\n \"bp\": \"22415\",\n \"ap\": \"22415.5\"\n }", "{\n \"s\": \"kas_usdt\",\n \"t\": 1679539891853,\n \"ap\": \"0.016298\",\n \"aq\": \"5119.09\",\n \"bp\": \"0.016290\",\n \"bq\": \"135.37\"\n }" ], "line_end" => 1910, "line_start" => 1829, "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.safeNumber (ticker, 'h')" }, %{ "comment" => nil, "key" => "low", "value" => "this.safeNumber (ticker, 'l')" }, %{ "comment" => nil, "key" => "bid", "value" => "this.safeNumber (ticker, 'bp')" }, %{ "comment" => nil, "key" => "bidVolume", "value" => "this.safeNumber (ticker, 'bq')" }, %{ "comment" => nil, "key" => "ask", "value" => "this.safeNumber (ticker, 'ap')" }, %{ "comment" => nil, "key" => "askVolume", "value" => "this.safeNumber (ticker, 'aq')" }, %{ "comment" => nil, "key" => "vwap", "value" => "undefined" }, %{ "comment" => nil, "key" => "open", "value" => "this.safeString (ticker, 'o')" }, %{ "comment" => nil, "key" => "close", "value" => "this.safeString (ticker, 'c')" }, %{ "comment" => nil, "key" => "last", "value" => "this.safeString (ticker, 'c')" }, %{ "comment" => nil, "key" => "previousClose", "value" => "undefined" }, %{ "comment" => nil, "key" => "change", "value" => "this.safeNumber (ticker, 'cv')" }, %{ "comment" => nil, "key" => "percentage", "value" => "this.parseNumber (percentage)" }, %{ "comment" => nil, "key" => "average", "value" => "undefined" }, %{ "comment" => nil, "key" => "baseVolume", "value" => "this.safeNumber (ticker, 'a')" }, %{ "comment" => nil, "key" => "quoteVolume", "value" => "this.safeNumber (ticker, 'v')" }, %{ "comment" => nil, "key" => "info", "value" => "ticker" } ], "name" => "parseTicker", "signature" => "parseTicker (ticker, market = undefined)", "source" => "parseTicker (ticker, market = undefined) {\n //\n // spot: fetchTicker, fetchTickers\n //\n // {\n // \"s\": \"btc_usdt\",\n // \"t\": 1678172693931,\n // \"cv\": \"34.00\",\n // \"cr\": \"0.0015\",\n // \"o\": \"22398.05\",\n // \"l\": \"22323.72\",\n // \"h\": \"22600.50\",\n // \"c\": \"22432.05\",\n // \"q\": \"7962.256931\",\n // \"v\": \"178675209.47416856\"\n // }\n //\n // swap and future: fetchTicker, fetchTickers\n //\n // {\n // \"t\": 1678172848572,\n // \"s\": \"btc_usdt\",\n // \"c\": \"22415.5\",\n // \"h\": \"22590.0\",\n // \"l\": \"22310.0\",\n // \"a\": \"623654031\",\n // \"v\": \"1399166074.31675\",\n // \"o\": \"22381.5\",\n // \"r\": \"0.0015\",\n // \"i\": \"22424.5\",\n // \"m\": \"22416.5\",\n // \"bp\": \"22415\",\n // \"ap\": \"22415.5\"\n // }\n //\n // fetchBidsAsks\n //\n // {\n // \"s\": \"kas_usdt\",\n // \"t\": 1679539891853,\n // \"ap\": \"0.016298\",\n // \"aq\": \"5119.09\",\n // \"bp\": \"0.016290\",\n // \"bq\": \"135.37\"\n // }\n //\n const marketId = this.safeString (ticker, 's');\n let marketType = (market !== undefined) ? market['type'] : undefined;\n const hasSpotKeys = ('cv' in ticker) || ('aq' in ticker);\n if (marketType === undefined) {\n marketType = hasSpotKeys ? 'spot' : 'contract';\n }\n market = this.safeMarket (marketId, market, '_', marketType);\n const symbol = market['symbol'];\n const timestamp = this.safeInteger (ticker, 't');\n let percentage = this.safeString2 (ticker, 'cr', 'r');\n if (percentage !== undefined) {\n percentage = Precise.stringMul (percentage, '100');\n }\n return this.safeTicker ({\n 'symbol': symbol,\n 'timestamp': timestamp,\n 'datetime': this.iso8601 (timestamp),\n 'high': this.safeNumber (ticker, 'h'),\n 'low': this.safeNumber (ticker, 'l'),\n 'bid': this.safeNumber (ticker, 'bp'),\n 'bidVolume': this.safeNumber (ticker, 'bq'),\n 'ask': this.safeNumber (ticker, 'ap'),\n 'askVolume': this.safeNumber (ticker, 'aq'),\n 'vwap': undefined,\n 'open': this.safeString (ticker, 'o'),\n 'close': this.safeString (ticker, 'c'),\n 'last': this.safeString (ticker, 'c'),\n 'previousClose': undefined,\n 'change': this.safeNumber (ticker, 'cv'),\n 'percentage': this.parseNumber (percentage),\n 'average': undefined,\n 'baseVolume': this.safeNumber (ticker, 'a'),\n 'quoteVolume': this.safeNumber (ticker, 'v'),\n 'info': ticker,\n }, market);\n }" }, %{ "comment" => nil, "examples" => [ "{\n \"i\": 203530723141917063,\n \"t\": 1678227505815,\n \"p\": \"22038.81\",\n \"q\": \"0.000978\",\n \"v\": \"21.55395618\",\n \"b\": true\n }", "{\n s: 'btc_usdt',\n i: '228825383103928709',\n t: 1684258222702,\n p: '27003.65',\n q: '0.000796',\n b: true\n }", "{\n \"s\": \"btc_usdt\", // symbol\n \"t\": 1656043204763, // time\n \"i\": \"6316559590087251233\", // tradeId\n \"oi\": \"6216559590087220004\", // orderId\n \"p\": \"30000\", // trade price\n \"q\": \"3\", // qty quantity\n \"v\": \"90000\" // volume trade amount\n }", "{\n \"t\": 1678227683897,\n \"s\": \"btc_usdt\",\n \"p\": \"22031\",\n \"a\": \"1067\",\n \"m\": \"BID\"\n }", "{\n \"symbol\": \"btc_usdt\",\n \"tradeId\": \"206906233569974658\",\n \"orderId\": \"206906233178463488\",\n \"orderSide\": \"SELL\",\n \"orderType\": \"MARKET\",\n \"bizType\": \"SPOT\",\n \"time\": 1679032290215,\n \"price\": \"25703.46\",\n \"quantity\": \"0.000099\",\n \"quoteQty\": \"2.54464254\",\n \"baseCurrency\": \"btc\",\n \"quoteCurrency\": \"usdt\",\n \"fee\": \"0.00508929\",\n \"feeCurrency\": \"usdt\",\n \"takerMaker\": \"TAKER\"\n }" ], "line_end" => 2267, "line_start" => 2096, "mappings" => [ %{ "comment" => nil, "key" => "info", "value" => "trade" }, %{ "comment" => nil, "key" => "id", "value" => "this.safeStringN (trade, [ 'i', 'tradeId', 'execId' ])" }, %{ "comment" => nil, "key" => "timestamp", "value" => "timestamp" }, %{ "comment" => nil, "key" => "datetime", "value" => "this.iso8601 (timestamp)" }, %{ "comment" => nil, "key" => "symbol", "value" => "market['symbol']" }, %{ "comment" => nil, "key" => "order", "value" => "this.safeString2 (trade, 'orderId', 'oi')" }, %{ "comment" => nil, "key" => "type", "value" => "this.safeStringLower (trade, 'orderType')" }, %{ "comment" => nil, "key" => "side", "value" => "side" }, %{ "comment" => nil, "key" => "takerOrMaker", "value" => "takerOrMaker" }, %{ "comment" => nil, "key" => "price", "value" => "this.safeString2 (trade, 'p', 'price')" }, %{ "comment" => nil, "key" => "amount", "value" => "amount" }, %{ "comment" => nil, "key" => "cost", "value" => "undefined" }, %{ "comment" => nil, "key" => "fee", "value" => "{\n 'currency': this.safeCurrencyCode (this.safeString2 (trade, 'feeCurrency', 'feeCoin')),\n 'cost': this.safeString (trade, 'fee'),\n }" }, %{ "comment" => nil, "key" => "currency", "value" => "this.safeCurrencyCode (this.safeString2 (trade, 'feeCurrency', 'feeCoin'))" }, %{ "comment" => nil, "key" => "cost", "value" => "this.safeString (trade, 'fee')" } ], "name" => "parseTrade", "signature" => "parseTrade (trade, market = undefined)", "source" => "parseTrade (trade, market = undefined) {\n //\n // spot: fetchTrades\n //\n // {\n // \"i\": 203530723141917063,\n // \"t\": 1678227505815,\n // \"p\": \"22038.81\",\n // \"q\": \"0.000978\",\n // \"v\": \"21.55395618\",\n // \"b\": true\n // }\n //\n // spot: watchTrades\n //\n // {\n // s: 'btc_usdt',\n // i: '228825383103928709',\n // t: 1684258222702,\n // p: '27003.65',\n // q: '0.000796',\n // b: true\n // }\n //\n // spot: watchMyTrades\n //\n // {\n // \"s\": \"btc_usdt\", // symbol\n // \"t\": 1656043204763, // time\n // \"i\": \"6316559590087251233\", // tradeId\n // \"oi\": \"6216559590087220004\", // orderId\n // \"p\": \"30000\", // trade price\n // \"q\": \"3\", // qty quantity\n // \"v\": \"90000\" // volume trade amount\n // }\n //\n // swap and future: fetchTrades\n //\n // {\n // \"t\": 1678227683897,\n // \"s\": \"btc_usdt\",\n // \"p\": \"22031\",\n // \"a\": \"1067\",\n // \"m\": \"BID\"\n // }\n //\n // spot: fetchMyTrades\n //\n // {\n // \"symbol\": \"btc_usdt\",\n // \"tradeId\": \"206906233569974658\",\n // \"orderId\": \"206906233178463488\",\n // \"orderSide\": \"SELL\",\n // \"orderType\": \"MARKET\",\n // \"bizType\": \"SPOT\",\n // \"time\": 1679032290215,\n // \"price\": \"25703.46\",\n // \"quantity\": \"0.000099\",\n // \"quoteQty\": \"2.54464254\",\n // \"baseCurrency\": \"btc\",\n // \"quoteCurrency\": \"usdt\",\n // \"fee\": \"0.00508929\",\n // \"feeCurrency\": \"usdt\",\n // \"takerMaker\": \"TAKER\"\n // }\n //\n // swap and future: fetchMyTrades\n //\n // {\n // \"orderId\": \"207260566170987200\",\n // \"execId\": \"207260566790603265\",\n // \"symbol\": \"btc_usdt\",\n // \"quantity\": \"13\",\n // \"price\": \"27368\",\n // \"fee\": \"0.02134704\",\n // \"feeCoin\": \"usdt\",\n // \"timestamp\": 1679116769838,\n // \"takerMaker\": \"TAKER\"\n // }\n //\n // contract watchMyTrades\n //\n // {\n // \"symbol\": 'btc_usdt',\n // \"orderSide\": 'SELL',\n // \"positionSide\": 'LONG',\n // \"orderId\": '231485367663419328',\n // \"price\": '27152.7',\n // \"quantity\": '33',\n // \"marginUnfrozen\": '2.85318000',\n // \"timestamp\": 1684892412565\n // }\n //\n // watchMyTrades (ws, swap)\n //\n // {\n // 'fee': '0.04080840',\n // 'isMaker': False,\n // 'marginUnfrozen': '0.75711984',\n // 'orderId': '376172779053188416',\n // 'orderSide': 'BUY',\n // 'positionSide': 'LONG',\n // 'price': '3400.70',\n // 'quantity': '2',\n // 'symbol': 'eth_usdt',\n // 'timestamp': 1719388579622\n // }\n //\n const marketId = this.safeString2 (trade, 's', 'symbol');\n let marketType = (market !== undefined) ? market['type'] : undefined;\n const hasSpotKeys = ('b' in trade) || ('bizType' in trade) || ('oi' in trade);\n if (marketType === undefined) {\n marketType = hasSpotKeys ? 'spot' : 'contract';\n }\n market = this.safeMarket (marketId, market, '_', marketType);\n let side = undefined;\n let takerOrMaker = undefined;\n const isBuyerMaker = this.safeBool (trade, 'b');\n if (isBuyerMaker !== undefined) {\n side = isBuyerMaker ? 'sell' : 'buy';\n takerOrMaker = 'taker'; // public trades always taker\n } else {\n const takerMaker = this.safeStringLower (trade, 'takerMaker');\n if (takerMaker !== undefined) {\n takerOrMaker = takerMaker;\n } else {\n const isMaker = this.safeBool (trade, 'isMaker');\n if (isMaker !== undefined) {\n takerOrMaker = isMaker ? 'maker' : 'taker';\n }\n }\n const orderSide = this.safeStringLower (trade, 'orderSide');\n if (orderSide !== undefined) {\n side = orderSide;\n } else {\n const bidOrAsk = this.safeString (trade, 'm');\n if (bidOrAsk !== undefined) {\n side = (bidOrAsk === 'BID') ? 'buy' : 'sell';\n }\n }\n }\n const timestamp = this.safeIntegerN (trade, [ 't', 'time', 'timestamp' ]);\n const quantity = this.safeString2 (trade, 'q', 'quantity');\n let amount = undefined;\n if (marketType === 'spot') {\n amount = quantity;\n } else {\n if (quantity === undefined) {\n amount = Precise.stringMul (this.safeString (trade, 'a'), this.numberToString (market['contractSize']));\n } else {\n amount = Precise.stringMul (quantity, this.numberToString (market['contractSize']));\n }\n }\n return this.safeTrade ({\n 'info': trade,\n 'id': this.safeStringN (trade, [ 'i', 'tradeId', 'execId' ]),\n 'timestamp': timestamp,\n 'datetime': this.iso8601 (timestamp),\n 'symbol': market['symbol'],\n 'order': this.safeString2 (trade, 'orderId', 'oi'),\n 'type': this.safeStringLower (trade, 'orderType'),\n 'side': side,\n 'takerOrMaker': takerOrMaker,\n 'price': this.safeString2 (trade, 'p', 'price'),\n 'amount': amount,\n 'cost': undefined,\n 'fee': {\n 'currency': this.safeCurrencyCode (this.safeString2 (trade, 'feeCurrency', 'feeCoin')),\n 'cost': this.safeString (trade, 'fee'),\n },\n }, market);\n }" }, %{ "comment" => nil, "examples" => [ "{\n \"id\": 170368702,\n \"currency\": \"usdt\",\n \"chain\": \"Ethereum\",\n \"memo\": \"\",\n \"status\": \"SUCCESS\",\n \"amount\": \"31.792528\",\n \"confirmations\": 12,\n \"transactionId\": \"0x90b8487c258b81b85e15e461b1839c49d4d8e6e9de4c1adb658cd47d4f5c5321\",\n \"address\": \"0x7f7172cf29d3846d30ca5a3aec1120b92dbd150b\",\n \"fromAddr\": \"0x7830c87c02e56aff27fa9ab1241711331fa86f58\",\n \"createdTime\": 1678491442000\n }", "{\n \"id\": 950898,\n \"currency\": \"usdt\",\n \"chain\": \"Tron\",\n \"address\": \"TGB2vxTjiqraVZBy7YHXF8V3CSMVhQKcaf\",\n \"memo\": \"\",\n \"status\": \"SUCCESS\",\n \"amount\": \"5\",\n \"fee\": \"2\",\n \"confirmations\": 6,\n \"transactionId\": \"c36e230b879842b1d7afd19d15ee1a866e26eaa0626e367d6f545d2932a15156\",\n \"createdTime\": 1680049062000\n }", "{\n \"id\": 950898\n }" ], "line_end" => 4060, "line_start" => 3986, "mappings" => [ %{ "comment" => nil, "key" => "info", "value" => "transaction" }, %{ "comment" => nil, "key" => "id", "value" => "this.safeString (transaction, 'id')" }, %{ "comment" => nil, "key" => "txid", "value" => "this.safeString (transaction, 'transactionId')" }, %{ "comment" => nil, "key" => "timestamp", "value" => "timestamp" }, %{ "comment" => nil, "key" => "datetime", "value" => "this.iso8601 (timestamp)" }, %{ "comment" => nil, "key" => "updated", "value" => "undefined" }, %{ "comment" => nil, "key" => "addressFrom", "value" => "this.safeString (transaction, 'fromAddr')" }, %{ "comment" => nil, "key" => "addressTo", "value" => "address" }, %{ "comment" => nil, "key" => "address", "value" => "address" }, %{ "comment" => nil, "key" => "tagFrom", "value" => "undefined" }, %{ "comment" => nil, "key" => "tagTo", "value" => "undefined" }, %{ "comment" => nil, "key" => "tag", "value" => "memo" }, %{ "comment" => nil, "key" => "type", "value" => "type" }, %{ "comment" => nil, "key" => "amount", "value" => "this.safeNumber (transaction, 'amount')" }, %{ "comment" => nil, "key" => "currency", "value" => "currencyCode" }, %{ "comment" => nil, "key" => "network", "value" => "this.networkIdToCode (networkId, currencyCode)" }, %{ "comment" => nil, "key" => "status", "value" => "this.parseTransactionStatus (this.safeString (transaction, 'status'))" }, %{ "comment" => nil, "key" => "comment", "value" => "memo" }, %{ "comment" => nil, "key" => "fee", "value" => "{\n 'currency': feeCurrency,\n 'cost': fee,\n 'rate': undefined,\n }" }, %{ "comment" => nil, "key" => "internal", "value" => "undefined" }, %{ "comment" => nil, "key" => "currency", "value" => "feeCurrency" }, %{ "comment" => nil, "key" => "cost", "value" => "fee" }, %{ "comment" => nil, "key" => "rate", "value" => "undefined" } ], "name" => "parseTransaction", "signature" => "parseTransaction (transaction: Dict, currency: Currency = undefined): Transaction", "source" => "parseTransaction (transaction: Dict, currency: Currency = undefined): Transaction {\n //\n // fetchDeposits\n //\n // {\n // \"id\": 170368702,\n // \"currency\": \"usdt\",\n // \"chain\": \"Ethereum\",\n // \"memo\": \"\",\n // \"status\": \"SUCCESS\",\n // \"amount\": \"31.792528\",\n // \"confirmations\": 12,\n // \"transactionId\": \"0x90b8487c258b81b85e15e461b1839c49d4d8e6e9de4c1adb658cd47d4f5c5321\",\n // \"address\": \"0x7f7172cf29d3846d30ca5a3aec1120b92dbd150b\",\n // \"fromAddr\": \"0x7830c87c02e56aff27fa9ab1241711331fa86f58\",\n // \"createdTime\": 1678491442000\n // }\n //\n // fetchWithdrawals\n //\n // {\n // \"id\": 950898,\n // \"currency\": \"usdt\",\n // \"chain\": \"Tron\",\n // \"address\": \"TGB2vxTjiqraVZBy7YHXF8V3CSMVhQKcaf\",\n // \"memo\": \"\",\n // \"status\": \"SUCCESS\",\n // \"amount\": \"5\",\n // \"fee\": \"2\",\n // \"confirmations\": 6,\n // \"transactionId\": \"c36e230b879842b1d7afd19d15ee1a866e26eaa0626e367d6f545d2932a15156\",\n // \"createdTime\": 1680049062000\n // }\n //\n // withdraw\n //\n // {\n // \"id\": 950898\n // }\n //\n const type = ('fromAddr' in transaction) ? 'deposit' : 'withdraw';\n const timestamp = this.safeInteger (transaction, 'createdTime');\n const address = this.safeString (transaction, 'address');\n const memo = this.safeString (transaction, 'memo');\n const currencyCode = this.safeCurrencyCode (this.safeString (transaction, 'currency'), currency);\n const fee = this.safeNumber (transaction, 'fee');\n const feeCurrency = (fee !== undefined) ? currencyCode : undefined;\n const networkId = this.safeString (transaction, 'chain');\n return {\n 'info': transaction,\n 'id': this.safeString (transaction, 'id'),\n 'txid': this.safeString (transaction, 'transactionId'),\n 'timestamp': timestamp,\n 'datetime': this.iso8601 (timestamp),\n 'updated': undefined,\n 'addressFrom': this.safeString (transaction, 'fromAddr'),\n 'addressTo': address,\n 'address': address,\n 'tagFrom': undefined,\n 'tagTo': undefined,\n 'tag': memo,\n 'type': type,\n 'amount': this.safeNumber (transaction, 'amount'),\n 'currency': currencyCode,\n 'network': this.networkIdToCode (networkId, currencyCode),\n 'status': this.parseTransactionStatus (this.safeString (transaction, 'status')),\n 'comment': memo,\n 'fee': {\n 'currency': feeCurrency,\n 'cost': fee,\n 'rate': undefined,\n },\n 'internal': undefined,\n } as Transaction;\n }" }, %{ "comment" => nil, "examples" => [], "line_end" => 4073, "line_start" => 4062, "mappings" => [ %{ "comment" => nil, "key" => "SUBMIT", "value" => "'pending'" }, %{ "comment" => nil, "key" => "REVIEW", "value" => "'pending'" }, %{ "comment" => nil, "key" => "AUDITED", "value" => "'pending'" }, %{ "comment" => nil, "key" => "PENDING", "value" => "'pending'" }, %{ "comment" => nil, "key" => "CANCEL", "value" => "'canceled'" }, %{ "comment" => nil, "key" => "FAIL", "value" => "'failed'" }, %{ "comment" => nil, "key" => "SUCCESS", "value" => "'ok'" } ], "name" => "parseTransactionStatus", "signature" => "parseTransactionStatus (status)", "source" => "parseTransactionStatus (status) {\n const statuses = {\n 'SUBMIT': 'pending',\n 'REVIEW': 'pending',\n 'AUDITED': 'pending',\n 'PENDING': 'pending',\n 'CANCEL': 'canceled',\n 'FAIL': 'failed',\n 'SUCCESS': 'ok',\n };\n return this.safeString (statuses, status, status);\n }" }, %{ "comment" => nil, "examples" => [], "line_end" => 4861, "line_start" => 4849, "mappings" => [ %{ "comment" => nil, "key" => "info", "value" => "transfer" }, %{ "comment" => nil, "key" => "id", "value" => "this.safeString (transfer, 'result')" }, %{ "comment" => nil, "key" => "timestamp", "value" => "undefined" }, %{ "comment" => nil, "key" => "datetime", "value" => "undefined" }, %{ "comment" => nil, "key" => "currency", "value" => "undefined" }, %{ "comment" => nil, "key" => "amount", "value" => "undefined" }, %{ "comment" => nil, "key" => "fromAccount", "value" => "undefined" }, %{ "comment" => nil, "key" => "toAccount", "value" => "undefined" }, %{ "comment" => nil, "key" => "status", "value" => "undefined" } ], "name" => "parseTransfer", "signature" => "parseTransfer (transfer, currency = undefined)", "source" => "parseTransfer (transfer, currency = undefined) {\n return {\n 'info': transfer,\n 'id': this.safeString (transfer, 'result'),\n 'timestamp': undefined,\n 'datetime': undefined,\n 'currency': undefined,\n 'amount': undefined,\n 'fromAccount': undefined,\n 'toAccount': undefined,\n 'status': undefined,\n };\n }" } ], path_prefix: "/v4/", pro: true, quote_json_numbers: nil, rate_limits: %{ interval_ms: 100, period: 1000, requests: 10, rolling_window_size: 60000 }, raw_endpoints: %{ private: [], public: [] }, required_credentials: %{ api_key: true, password: false, secret: true, uid: false }, requires_eddsa: false, response_error: nil, signing: %{ api_key_header: "xt-validate-appkey", confidence: :medium, pattern: :hmac_sha256_headers, recv_window: 5000, recv_window_header: "xt-validate-recvwindow", signature_header: "xt-validate-signature", timestamp_header: "xt-validate-timestamp", uses_recv_window: true }, spec_format_version: 1, status: %{ "eta" => nil, "status" => "ok", "updated" => nil, "url" => nil }, symbol_format: nil, symbol_formats: %{ future: %{ base: "BTC", base_id: "btc", case: :lower, contract: true, contract_size: 0.001, expiry: 1719561600000, expiry_datetime: "2024-06-28T08:00:00.000Z", id: "btc_usdt_240628", inverse: false, limits: %{ "amount" => %{ "min" => 1 }, "cost" => %{ "max" => 5000000, "min" => 5 }, "leverage" => %{ "min" => 1 }, "price" => %{ "max" => 1, "min" => 0 } }, linear: true, maker: 0.0004, precision: %{ "amount" => 1, "base" => 1.0e-8, "price" => 0.01, "quote" => 1.0e-8 }, quote: "USDT", quote_id: "usdt", separator: "_", settle: "USDT", settle_id: "btc", symbol: "BTC/USDT:USDT-240628", taker: 0.0006 }, precision_mode: 4, sample_limits: %{ "amount" => %{}, "cost" => %{ "min" => 1 }, "price" => %{} }, sample_precision: %{ "amount" => 0.01, "price" => 0.0001 }, spot: %{ base: "XT", base_id: "xt", case: :lower, contract: false, id: "xt_usdt", limits: %{ "amount" => %{}, "cost" => %{ "min" => 1 }, "leverage" => %{ "min" => 1 }, "price" => %{} }, precision: %{ "amount" => 0.01, "price" => 0.0001 }, quote: "USDT", quote_id: "usdt", separator: "_", symbol: "XT/USDT" }, swap: %{ base: "BTC", base_id: "btc", case: :lower, contract: true, contract_size: 0.0001, id: "btc_usdt", inverse: false, limits: %{ "amount" => %{ "min" => 1 }, "cost" => %{ "max" => 25000000, "min" => 10 }, "leverage" => %{ "min" => 1 }, "price" => %{} }, linear: true, maker: 0.0004, precision: %{ "amount" => 1, "base" => 1.0e-8, "price" => 0.1, "quote" => 1.0e-8 }, quote: "USDT", quote_id: "usdt", separator: "_", settle: "USDT", settle_id: "btc", symbol: "BTC/USDT:USDT", taker: 0.0006 } }, symbol_patterns: %{ future: %{ case: :lower, component_order: [ :base, :quote, :date ], date_format: :yymmdd, pattern: :future_yymmdd, separator: "_", suffix: nil }, spot: %{ case: :lower, component_order: nil, date_format: nil, pattern: :underscore_lower, separator: "_", suffix: nil }, swap: %{ case: :lower, component_order: nil, date_format: nil, pattern: :implicit, separator: "_", suffix: nil } }, timeframes: %{ "15m" => "15m", "1M" => "1M", "1d" => "1d", "1h" => "1h", "1m" => "1m", "1w" => "1w", "2h" => "2h", "30m" => "30m", "3d" => "3d", "4h" => "4h", "5m" => "5m", "6h" => "6h", "8h" => "8h" }, url_strategy: %{ detected_from: "sign_method", pattern: :version_slash, prefix: "/v4/" }, urls: %{ api: "https://sapi.xt.com", api_sections: %{ "inverse" => "https://dapi.xt.com", "linear" => "https://fapi.xt.com", "spot" => "https://sapi.xt.com", "user" => "https://api.xt.com" }, doc: [ "https://doc.xt.com/", "https://github.com/xtpub/api-doc" ], other: nil, sandbox: nil, www: "https://xt.com" }, version: "v4", ws: %{ channel_templates: %{ watch_balance: %{ channel_name: "balance", market_id_format: :native, params: [], pattern: :stream_based, separator: "@" }, watch_my_trades: %{ channel_name: "trade", market_id_format: :native, params: [ %{ "default" => nil, "name" => "limit" } ], pattern: :stream_based, separator: "@" }, watch_ohlcv: %{ market_id_format: :native, params: [ %{ "default" => nil, "name" => "limit" } ], pattern: :stream_based, separator: "@" }, watch_order_book: %{ market_id_format: :native, params: [ %{ "default" => nil, "name" => "levels" }, %{ "default" => nil, "name" => "limit" } ], pattern: :stream_based, separator: "@" }, watch_orders: %{ channel_name: "order", market_id_format: :native, params: [ %{ "default" => nil, "name" => "limit" } ], pattern: :stream_based, separator: "@" }, watch_positions: %{ channel_name: "position", market_id_format: :native, params: [ %{ "default" => nil, "name" => "limit" } ], pattern: :stream_based, separator: "@" }, watch_ticker: %{ market_id_format: :native, params: [], pattern: :stream_based, separator: "@" }, watch_tickers: %{ market_id_format: :native, params: [], pattern: :stream_based, separator: "@" }, watch_trades: %{ market_id_format: :native, params: [ %{ "default" => nil, "name" => "limit" } ], pattern: :stream_based, separator: "@" } }, 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: true, watch_ohlcv: true, 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: true, watch_status: nil, watch_ticker: true, watch_tickers: true, watch_trades: true, watch_trades_for_symbols: false }, message_patterns: [ %{ args_field: "params", format: :method, id_field: "id", keys: [ "id", "method", "params" ], kind_field: "method", kind_value: "subscribe", sources: [ :send, :watch ] }, %{ args_field: "params", format: :method, id_field: "id", keys: [ "id", "method", "params" ], kind_field: "method", kind_value: "unsubscribe", sources: [ :send, :watch ] }, %{ format: :string, sources: [ :ping ] } ], options: %{ "watchPositions" => %{ "awaitPositionsSnapshot" => true, "fetchPositionsSnapshot" => true, "type" => "swap" }, "watchTicker" => %{ "method" => "ticker" }, "watchTickers" => %{ "method" => "tickers" } }, streaming: %{ keep_alive: 20000 }, subscription_config: %{ args_field: "params", args_format: :string_list, market_id_format: :native, op_field: "method", separator: "@" }, subscription_pattern: :method_subscribe, urls: %{ "contract" => "wss://fstream.xt.com/ws", "spot" => "wss://stream.xt.com" }, watch_methods: [ "watchBalance", "watchMyTrades", "watchOHLCV", "watchOrderBook", "watchOrders", "watchPositions", "watchTicker", "watchTickers", "watchTrades" ] } }