# BloFin Exchange Specification # # Auto-generated by: mix ccxt.extract blofin # 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: [ "US" ], currencies: %{}, currency_aliases: %{ "BCHSV" => "BSV", "XBT" => "BTC" }, dex: false, enable_rate_limit: true, endpoint_extraction_stats: %{ "capturedMethods" => 36, "coveragePercent" => 100, "enabledMethods" => 39, "excluded" => [ %{ "method" => "fetchFundingHistory", "reason" => "blofin fetchFundingHistory() is not supported yet" }, %{ "method" => "fetchOrderTrades", "reason" => "blofin fetchOrderTrades() is not supported yet" }, %{ "method" => "fetchDepositWithdrawFee", "reason" => "emulated (returns cached data, no HTTP call)" } ], "excludedMethods" => 3, "extractableMethods" => 36, "failures" => [] }, endpoints: [ %{ api_section: "private", auth: true, cost: 1, market_type: :swap, method: :post, name: :cancel_order, param_mappings: %{ "id" => "orderId", "symbol" => "instId" }, params: [ :id, :symbol ], path: "/trade/cancel-order", response_transformer: {:extract_path, ["data"]}, source: :intercepted }, %{ api_section: "private", auth: true, cost: 1, market_type: :swap, method: :post, name: :cancel_orders, param_mappings: %{}, params: [ :ids, :symbol ], path: "/trade/cancel-batch-orders", response_transformer: {:extract_path, ["data"]}, source: :intercepted }, %{ api_section: "private", auth: true, cost: 1, default_params: %{ "brokerId" => "ec6dd3a7dd982d0b", "marginMode" => "cross", "orderType" => "limit" }, market_type: :swap, method: :post, name: :create_limit_order, param_mappings: %{ "amount" => "size", "symbol" => "instId" }, params: [ :symbol, :side, :amount, :price ], path: "/trade/order", response_transformer: {:extract_path, ["data"]}, source: :intercepted }, %{ api_section: "private", auth: true, cost: 1, default_params: %{ "brokerId" => "ec6dd3a7dd982d0b", "marginMode" => "cross", "orderType" => "market" }, market_type: :swap, method: :post, name: :create_market_order, param_mappings: %{ "amount" => "size", "symbol" => "instId" }, params: [ :symbol, :side, :amount, :price ], path: "/trade/order", response_transformer: {:extract_path, ["data"]}, source: :intercepted }, %{ api_section: "private", auth: true, cost: 1, default_params: %{ "brokerId" => "ec6dd3a7dd982d0b", "marginMode" => "cross" }, market_type: :swap, method: :post, name: :create_order, param_mappings: %{ "amount" => "size", "symbol" => "instId", "type" => "orderType" }, params: [ :symbol, :type, :side, :amount, :price ], path: "/trade/order", response_transformer: {:extract_path, ["data"]}, source: :intercepted }, %{ api_section: "private", auth: true, cost: 1, default_params: %{ "brokerId" => "ec6dd3a7dd982d0b", "marginMode" => "cross", "slOrderPrice" => "-1", "tpOrderPrice" => "-1" }, market_type: :swap, method: :post, name: :create_order_with_take_profit_and_stop_loss, param_mappings: %{ "amount" => "size", "stopLoss" => "slTriggerPrice", "symbol" => "instId", "takeProfit" => "tpTriggerPrice", "type" => "orderType" }, params: [ :symbol, :type, :side, :amount, :price, :takeProfit, :stopLoss ], path: "/trade/order", response_transformer: {:extract_path, ["data"]}, source: :intercepted }, %{ api_section: "private", auth: true, cost: 1, market_type: :swap, method: :post, name: :create_orders, param_mappings: %{}, params: [ :orders ], path: "/trade/batch-orders", response_transformer: {:extract_path, ["data"]}, source: :intercepted }, %{ api_section: "private", auth: true, cost: 1, default_params: %{ "brokerId" => "ec6dd3a7dd982d0b", "marginMode" => "cross", "positionSide" => "net", "triggerDirection" => "below" }, market_type: :swap, method: :post, name: :create_stop_loss_order, param_mappings: %{ "amount" => "size", "price" => "slOrderPrice", "stopLossPrice" => "slTriggerPrice", "symbol" => "instId" }, params: [ :symbol, :type, :side, :amount, :price, :stopLossPrice ], path: "/trade/order-tpsl", response_transformer: {:extract_path, ["data"]}, source: :intercepted }, %{ api_section: "private", auth: true, cost: 1, default_params: %{ "brokerId" => "ec6dd3a7dd982d0b", "marginMode" => "cross", "positionSide" => "net", "triggerDirection" => "above" }, market_type: :swap, method: :post, name: :create_take_profit_order, param_mappings: %{ "amount" => "size", "price" => "tpOrderPrice", "symbol" => "instId", "takeProfitPrice" => "tpTriggerPrice" }, params: [ :symbol, :type, :side, :amount, :price, :takeProfitPrice ], path: "/trade/order-tpsl", response_transformer: {:extract_path, ["data"]}, source: :intercepted }, %{ api_section: "private", auth: true, cost: 1, default_params: %{ "brokerId" => "ec6dd3a7dd982d0b", "marginMode" => "cross", "orderType" => "trigger", "triggerDirection" => "below" }, market_type: :swap, method: :post, name: :create_trigger_order, param_mappings: %{ "amount" => "size", "price" => "orderPrice", "symbol" => "instId" }, params: [ :symbol, :type, :side, :amount, :price, :triggerPrice ], path: "/trade/order-algo", response_transformer: {:extract_path, ["data"]}, source: :intercepted }, %{ api_section: "private", auth: true, cost: 1, market_type: :swap, method: :get, name: :fetch_balance, param_mappings: %{}, params: [], path: "/account/balance", response_transformer: {:extract_path, ["data"]}, source: :intercepted }, %{ api_section: "private", auth: true, cost: 1, market_type: :swap, method: :get, name: :fetch_closed_orders, param_mappings: %{ "symbol" => "instId" }, params: [ :symbol, :since, :limit ], path: "/trade/orders-history", response_transformer: {:extract_path, ["data"]}, source: :intercepted }, %{ api_section: "private", auth: true, cost: 1, market_type: :swap, method: :get, name: :fetch_deposits, param_mappings: %{ "code" => "currency" }, params: [ :code, :since, :limit ], path: "/asset/deposit-history", response_transformer: {:extract_path, ["data"]}, source: :intercepted }, %{ api_section: "public", auth: false, cost: 1, market_type: :swap, method: :get, name: :fetch_funding_rate, param_mappings: %{ "symbol" => "instId" }, params: [ :symbol ], path: "/market/funding-rate", response_transformer: {:extract_path_unwrap, ["data"]}, source: :intercepted }, %{ api_section: "public", auth: false, cost: 1, market_type: :swap, method: :get, name: :fetch_funding_rate_history, param_mappings: %{ "symbol" => "instId" }, params: [ :symbol, :since, :limit ], path: "/market/funding-rate-history", response_transformer: {:extract_path, ["data"]}, source: :intercepted }, %{ api_section: "public", auth: false, cost: 1, default_params: %{ "size" => 50 }, market_type: :swap, method: :get, name: :fetch_l2_order_book, param_mappings: %{ "symbol" => "instId" }, params: [ :symbol, :limit ], path: "/market/books", response_transformer: {:extract_path, ["data"]}, source: :intercepted }, %{ api_section: "private", auth: true, cost: 1, market_type: :swap, method: :get, name: :fetch_ledger, param_mappings: %{ "code" => "currency" }, params: [ :code, :since, :limit ], path: "/asset/bills", response_transformer: {:extract_path, ["data"]}, source: :intercepted }, %{ api_section: "private", auth: true, cost: 1, default_params: %{ "marginMode" => "cross" }, market_type: :swap, method: :get, name: :fetch_leverage, param_mappings: %{ "symbol" => "instId" }, params: [ :symbol ], path: "/account/leverage-info", response_transformer: {:extract_path_unwrap, ["data"]}, source: :intercepted }, %{ api_section: "private", auth: true, cost: 1, default_params: %{ "instId" => "BTCUSDT", "marginMode" => "cross" }, market_type: :swap, method: :get, name: :fetch_leverages, param_mappings: %{}, params: [ :symbols ], path: "/account/batch-leverage-info", response_transformer: {:extract_path, ["data"]}, source: :intercepted }, %{ api_section: "private", auth: true, cost: 1, market_type: :swap, method: :get, name: :fetch_margin_mode, param_mappings: %{}, params: [ :symbol ], path: "/account/margin-mode", response_transformer: {:extract_path_unwrap, ["data"]}, source: :intercepted }, %{ api_section: "public", auth: false, cost: 1, market_type: :swap, method: :get, name: :fetch_markets, param_mappings: %{}, params: [], path: "/market/instruments", response_transformer: {:extract_path, ["data"]}, source: :intercepted }, %{ api_section: "private", auth: true, cost: 1, market_type: :swap, method: :get, name: :fetch_my_trades, param_mappings: %{ "symbol" => "instId" }, params: [ :symbol, :since, :limit ], path: "/trade/fills-history", response_transformer: {:extract_path, ["data"]}, source: :intercepted }, %{ api_section: "public", auth: false, cost: 1, market_type: :swap, method: :get, name: :fetch_ohlcv, param_mappings: %{ "symbol" => "instId", "timeframe" => "bar" }, params: [ :symbol, :timeframe, :since, :limit ], path: "/market/candles", response_transformer: {:extract_path, ["data"]}, source: :intercepted }, %{ api_section: "private", auth: true, cost: 1, market_type: :swap, method: :get, name: :fetch_open_orders, param_mappings: %{ "symbol" => "instId" }, params: [ :symbol, :since, :limit ], path: "/trade/orders-pending", response_transformer: {:extract_path, ["data"]}, source: :intercepted }, %{ api_section: "public", auth: false, cost: 1, market_type: :swap, method: :get, name: :fetch_order_book, param_mappings: %{ "limit" => "size", "symbol" => "instId" }, params: [ :symbol, :limit ], path: "/market/books", response_transformer: {:extract_path_unwrap, ["data"]}, source: :intercepted }, %{ api_section: "private", auth: true, cost: 1, market_type: :swap, method: :get, name: :fetch_position, param_mappings: %{ "symbol" => "instId" }, params: [ :symbol ], path: "/account/positions", response_transformer: {:extract_path_unwrap, ["data"]}, source: :intercepted }, %{ api_section: "private", auth: true, cost: 1, market_type: :swap, method: :get, name: :fetch_position_mode, param_mappings: %{}, params: [ :symbol ], path: "/account/position-mode", response_transformer: {:extract_path, ["data", "positionMode"]}, source: :intercepted }, %{ api_section: "private", auth: true, cost: 1, market_type: :swap, method: :get, name: :fetch_positions, param_mappings: %{}, params: [ :symbols ], path: "/account/positions", response_transformer: {:extract_path, ["data"]}, source: :intercepted }, %{ api_section: "public", auth: false, cost: 1, market_type: :swap, method: :get, name: :fetch_ticker, param_mappings: %{ "symbol" => "instId" }, params: [ :symbol ], path: "/market/tickers", response_transformer: {:extract_path_unwrap, ["data"]}, source: :intercepted }, %{ api_section: "public", auth: false, cost: 1, market_type: :swap, method: :get, name: :fetch_tickers, param_mappings: %{}, params: [ :symbols ], path: "/market/tickers", response_transformer: {:extract_path, ["data"]}, source: :intercepted }, %{ api_section: "public", auth: false, cost: 1, market_type: :swap, method: :get, name: :fetch_trades, param_mappings: %{ "symbol" => "instId" }, params: [ :symbol, :since, :limit ], path: "/market/trades", response_transformer: {:extract_path, ["data"]}, source: :intercepted }, %{ api_section: "private", auth: true, cost: 1, market_type: :swap, method: :get, name: :fetch_withdrawals, param_mappings: %{ "code" => "currency" }, params: [ :code, :since, :limit ], path: "/asset/withdrawal-history", response_transformer: {:extract_path, ["data"]}, source: :intercepted }, %{ api_section: "private", auth: true, cost: 1, default_params: %{ "marginMode" => "cross" }, market_type: :swap, method: :post, name: :set_leverage, param_mappings: %{ "symbol" => "instId" }, params: [ :leverage, :symbol ], path: "/account/set-leverage", response_transformer: {:extract_path, ["data"]}, source: :intercepted }, %{ api_section: "private", auth: true, cost: 1, market_type: :swap, method: :post, name: :set_margin_mode, param_mappings: %{}, params: [ :marginMode, :symbol ], path: "/account/set-margin-mode", response_transformer: {:extract_path, ["data"]}, source: :intercepted }, %{ api_section: "private", auth: true, cost: 1, default_params: %{ "positionMode" => "long_short_mode" }, market_type: :swap, method: :post, name: :set_position_mode, param_mappings: %{}, params: [ :hedged, :symbol ], path: "/account/set-position-mode", response_transformer: {:extract_path, ["data"]}, source: :intercepted }, %{ api_section: "private", auth: true, cost: 1, default_params: %{ "toAccount" => "futures" }, market_type: :swap, method: :post, name: :transfer, param_mappings: %{ "code" => "currency" }, params: [ :code, :amount, :fromAccount, :toAccount ], path: "/asset/transfer", response_transformer: {:extract_path, ["data"]}, source: :intercepted } ], error_code_details: %{ 102002 => %{ description: "Duplicate customized order ID", type: :invalid_order }, 102005 => %{ description: "Position had been closed", type: :invalid_order }, 102014 => %{ description: "Limit order exceeds maximum order size limit", type: :invalid_order }, 102015 => %{ description: "Market order exceeds maximum order size limit", type: :invalid_order }, 102022 => %{ description: "Failed to place order. You don’t have any positions of this contract. Turn off Reduce-only to continue.", type: :invalid_order }, 102037 => %{ description: "TP trigger price should be higher than the latest trading price", type: :invalid_order }, 102038 => %{ description: "SL trigger price should be lower than the latest trading price", type: :invalid_order }, 102039 => %{ description: "TP trigger price should be lower than the latest trading price", type: :invalid_order }, 102040 => %{ description: "SL trigger price should be higher than the latest trading price", type: :invalid_order }, 102047 => %{ description: "Stop loss trigger price should be higher than the order price", type: :invalid_order }, 102048 => %{ description: "stop loss trigger price must be higher than the best bid price", type: :invalid_order }, 102049 => %{ description: "Take profit trigger price should be lower than the order price", type: :invalid_order }, 102050 => %{ description: "stop loss trigger price must be lower than the best ask price", type: :invalid_order }, 102051 => %{ description: "stop loss trigger price should be lower than the order price", type: :invalid_order }, 102052 => %{ description: "take profit trigger price should be higher than the order price", type: :invalid_order }, 102053 => %{ description: "take profit trigger price should be lower than the best bid price", type: :invalid_order }, 102054 => %{ description: "take profit trigger price should be higher than the best ask price", type: :invalid_order }, 102055 => %{ description: "stop loss trigger price should be lower than the best ask price", type: :invalid_order }, 102064 => %{ description: "Buy price is not within the price limit (Minimum: 310.40; Maximum:1,629.40)", type: :invalid_parameters }, 102065 => %{ description: "Sell price is not within the price limit", type: :invalid_parameters }, 102068 => %{ description: "Cancel failed as the order has been filled, triggered, canceled or does not exist", type: :invalid_parameters }, 103013 => %{ description: "Internal error; unable to process your request. Please try again.", type: :exchange_error }, 150003 => %{ description: "clientId already exist", type: :invalid_order }, 150004 => %{ description: "Insufficient balance. please adjust the amount and try again", type: :invalid_order }, 152001 => %{ description: "Parameter {} cannot be empty", type: :invalid_parameters }, 152002 => %{ description: "Parameter {} error", type: :invalid_parameters }, 152003 => %{ description: "Either parameter {} or {} is required", type: :invalid_parameters }, 152004 => %{ description: "JSON syntax error", type: :invalid_parameters }, 152005 => %{ description: "Parameter error: wrong or empty", type: :invalid_parameters }, 152006 => %{ description: "Batch orders can be placed for up to 20 at once", type: :invalid_order }, 152007 => %{ description: "Batch orders can only be placed with the same instId and marginMode", type: :invalid_order }, 152008 => %{ description: "Only the same field is allowed for bulk cancellation of orders, orderId is preferred", type: :invalid_order }, 152009 => %{ description: "{} must be a combination of numbers, letters, or underscores, and the maximum length of characters is 32", type: :invalid_order }, 400 => %{ description: "Body can not be empty", type: :invalid_parameters }, 401 => %{ description: "Invalid signature", type: :invalid_credentials }, 404 => %{ description: "not found", type: :invalid_parameters }, 405 => %{ description: "Method Not Allowed", type: :invalid_parameters }, 406 => %{ description: "Not Acceptable", type: :invalid_parameters }, 429 => %{ description: "Too Many Requests", type: :rate_limited }, 500 => %{ description: "Internal Server Error", type: :exchange_error }, 542 => %{ description: "Exceeded the maximum order size limit", type: :invalid_order }, "Internal Server Error" => %{ description: "Internal Server Error", type: :network_error }, "Order failed. Insufficient USDT margin in account" => %{ description: "Insufficient USDT margin in account", type: :insufficient_balance }, "server error" => %{ description: "server error 1236805249", type: :network_error } }, error_codes: %{ 102002 => :invalid_order, 102005 => :invalid_order, 102014 => :invalid_order, 102015 => :invalid_order, 102022 => :invalid_order, 102037 => :invalid_order, 102038 => :invalid_order, 102039 => :invalid_order, 102040 => :invalid_order, 102047 => :invalid_order, 102048 => :invalid_order, 102049 => :invalid_order, 102050 => :invalid_order, 102051 => :invalid_order, 102052 => :invalid_order, 102053 => :invalid_order, 102054 => :invalid_order, 102055 => :invalid_order, 102064 => :invalid_parameters, 102065 => :invalid_parameters, 102068 => :invalid_parameters, 103013 => :exchange_error, 150003 => :invalid_order, 150004 => :invalid_order, 152001 => :invalid_parameters, 152002 => :invalid_parameters, 152003 => :invalid_parameters, 152004 => :invalid_parameters, 152005 => :invalid_parameters, 152006 => :invalid_order, 152007 => :invalid_order, 152008 => :invalid_order, 152009 => :invalid_order, 400 => :invalid_parameters, 401 => :invalid_credentials, 404 => :invalid_parameters, 405 => :invalid_parameters, 406 => :invalid_parameters, 429 => :rate_limited, 500 => :exchange_error, 542 => :invalid_order, "Internal Server Error" => :network_error, "Order failed. Insufficient USDT margin in account" => :insufficient_balance, "server error" => :network_error }, exceptions: %{ broad: %{ "Internal Server Error" => :exchange_not_available, "server error" => :exchange_not_available }, exact: %{ "102002" => :invalid_order, "102005" => :invalid_order, "102014" => :invalid_order, "102015" => :invalid_order, "102022" => :invalid_order, "102037" => :invalid_order, "102038" => :invalid_order, "102039" => :invalid_order, "102040" => :invalid_order, "102047" => :invalid_order, "102048" => :invalid_order, "102049" => :invalid_order, "102050" => :invalid_order, "102051" => :invalid_order, "102052" => :invalid_order, "102053" => :invalid_order, "102054" => :invalid_order, "102055" => :invalid_order, "102064" => :bad_request, "102065" => :bad_request, "102068" => :bad_request, "103013" => :exchange_error, "150003" => :invalid_order, "150004" => :invalid_order, "152001" => :bad_request, "152002" => :bad_request, "152003" => :bad_request, "152004" => :bad_request, "152005" => :bad_request, "152006" => :invalid_order, "152007" => :invalid_order, "152008" => :invalid_order, "152009" => :invalid_order, "400" => :bad_request, "401" => :authentication_error, "404" => :bad_request, "405" => :bad_request, "406" => :bad_request, "429" => :rate_limit_exceeded, "500" => :exchange_error, "542" => :invalid_order, "Order failed. Insufficient USDT margin in account" => :insufficient_funds } }, exchange_options: %{ "accountsById" => %{ "copy_trading" => "copy_trading", "earn" => "earn", "funding" => "funding", "futures" => "swap", "spot" => "spot" }, "accountsByType" => %{ "copy_trading" => "copy_trading", "earn" => "earn", "funding" => "funding", "future" => "futures", "spot" => "spot", "swap" => "futures" }, "brokerId" => "ec6dd3a7dd982d0b", "cancelOrders" => %{ "method" => "privatePostTradeCancelBatchOrders" }, "createMarketBuyOrderRequiresPrice" => false, "createOrder" => "privatePostTradeOrder", "defaultNetwork" => "ERC20", "defaultNetworkCodeReplacements" => %{ "BRC20" => %{ "BRC20" => "BTC" }, "CRO" => %{ "CRC20" => "CRONOS" }, "ETH" => %{ "ERC20" => "ETH" }, "TRX" => %{ "TRC20" => "TRX" } }, "defaultNetworks" => %{ "BTC" => "BTC", "ETH" => "ERC20", "USDT" => "TRC20" }, "defaultType" => "swap", "exchangeType" => %{ "SPOT" => "SPOT", "SWAP" => "SWAP", "spot" => "SPOT", "swap" => "SWAP" }, "fetchCanceledOrders" => %{ "method" => "privateGetTradeOrdersHistory" }, "fetchClosedOrders" => %{ "method" => "privateGetTradeOrdersHistory" }, "fetchLedger" => %{ "method" => "privateGetAssetBills" }, "fetchMarkets" => [ "swap" ], "fetchOHLCV" => %{ "timezone" => "UTC" }, "fetchOpenInterestHistory" => %{ "timeframes" => %{ "1D" => "1D", "1H" => "1H", "1d" => "1D", "1h" => "1H", "5M" => "5m", "5m" => "5m", "8H" => "8H", "8h" => "8H" } }, "fetchOpenOrders" => %{ "method" => "privateGetTradeOrdersPending" }, "fetchPositions" => %{ "method" => "privateGetAccountPositions" }, "networks" => %{ "BEP20" => "BSC", "BTC" => "Bitcoin", "ERC20" => "ERC20", "TRC20" => "TRC20" }, "networksById" => %{ "BSC" => "BEP20", "Bitcoin" => "BTC", "ERC20" => "ERC20", "TRC20" => "TRC20" }, "withdraw" => %{} }, extended_metadata: %{ limits: %{ "amount" => %{}, "cost" => %{}, "leverage" => %{}, "price" => %{} }, logo_url: "https://github.com/user-attachments/assets/518cdf80-f05d-4821-a3e3-d48ceb41d73b", referral_discount: 0.05, referral_url: "https://blofin.com/register?referral_code=f79EsS" }, extracted_metadata: %{ ccxt_version: "4.5.34" }, features: %{ default: %{ create_order: %{ iceberg: false, leverage: false, market_buy_by_cost: false, market_buy_requires_price: false, self_trade_prevention: false, time_in_force: %{ fok: true, gtd: false, ioc: true, po: true }, trailing: false }, create_orders: %{ max: 10 }, fetch_closed_orders: %{ days_back: 100000, days_back_canceled: 1, limit: 1000, margin_mode: false, symbol_required: false, trailing: false, trigger: true, until_days: 100000 }, fetch_my_trades: %{ days_back: 100000, limit: 100, margin_mode: false, symbol_required: false, until_days: 100000 }, fetch_ohlcv: %{ limit: 1440 }, fetch_open_orders: %{ limit: 100, margin_mode: false, symbol_required: false, trailing: false, trigger: true }, sandbox: false }, for_derivatives: %{ create_order: %{ attached_stop_loss_take_profit: %{ price: true }, hedged: true, margin_mode: true, stop_loss_price: true, take_profit_price: true, trigger_direction: false, trigger_price: false }, extends: "default" }, future: %{}, spot: %{ create_order: %{ hedged: false, margin_mode: false, stop_loss_price: false, take_profit_price: false, trigger_direction: false, trigger_price: false }, extends: "default" }, swap: %{ linear: %{ extends: "forDerivatives" } } }, fees: %{ swap: %{ maker: 0.0002, taker: 0.0006 } }, handle_content_type_application_zip: nil, handle_errors_source: "handleErrors(httpCode, reason, url, method, headers, body, response, requestHeaders, requestBody) {\n if (response === undefined) {\n return undefined; // fallback to default error handler\n }\n //\n // {\"code\":\"152002\",\"msg\":\"Parameter bar error.\"}\n //\n const code = this.safeString(response, 'code');\n const message = this.safeString(response, 'msg');\n const feedback = this.id + ' ' + body;\n if (code !== undefined && code !== '0') {\n this.throwExactlyMatchedException(this.exceptions['exact'], message, feedback);\n this.throwExactlyMatchedException(this.exceptions['exact'], code, feedback);\n this.throwBroadlyMatchedException(this.exceptions['broad'], message, feedback);\n throw new errors.ExchangeError(feedback); // unknown message\n }\n //\n // {\n // orderId: null,\n // clientOrderId: '',\n // msg: 'Order failed. Insufficient USDT margin in account',\n // code: '103003'\n // }\n //\n const data = this.safeList(response, 'data');\n const first = this.safeDict(data, 0);\n const insideMsg = this.safeString(first, 'msg');\n const insideCode = this.safeString(first, 'code');\n if (insideCode !== undefined && insideCode !== '0') {\n this.throwExactlyMatchedException(this.exceptions['exact'], insideCode, feedback);\n this.throwExactlyMatchedException(this.exceptions['exact'], insideMsg, feedback);\n this.throwBroadlyMatchedException(this.exceptions['broad'], insideMsg, feedback);\n }\n return undefined;\n }", has: %{ add_margin: false, borrow_cross_margin: false, borrow_isolated_margin: false, borrow_margin: false, c_o_r_s: false, cancel_all_orders: false, 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: true, 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: false, 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: true, create_order_with_take_profit_and_stop_loss_ws: false, create_order_ws: false, create_orders: true, create_post_only_order: false, create_post_only_order_ws: false, create_reduce_only_order: false, create_reduce_only_order_ws: false, create_stop_limit_order: false, create_stop_limit_order_ws: false, create_stop_loss_order: true, 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: true, 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: true, create_trigger_order_ws: false, deposit: false, edit_order: false, edit_order_with_client_order_id: false, edit_order_ws: false, edit_orders: false, fetch_accounts: false, fetch_balance: true, fetch_balance_ws: false, fetch_bids_asks: false, fetch_borrow_interest: false, fetch_borrow_rate: false, fetch_borrow_rate_histories: false, fetch_borrow_rate_history: false, fetch_borrow_rates: false, fetch_borrow_rates_per_symbol: false, fetch_canceled_and_closed_orders: false, fetch_canceled_orders: false, fetch_closed_order: false, fetch_closed_orders: true, fetch_closed_orders_ws: false, fetch_convert_currencies: false, fetch_convert_quote: false, fetch_convert_trade: false, fetch_convert_trade_history: false, fetch_cross_borrow_rate: false, fetch_cross_borrow_rates: false, fetch_currencies: false, fetch_currencies_ws: true, fetch_deposit: false, fetch_deposit_address: false, fetch_deposit_addresses: false, fetch_deposit_addresses_by_network: false, fetch_deposit_withdraw_fee: true, fetch_deposit_withdraw_fees: false, fetch_deposits: true, fetch_deposits_withdrawals: false, fetch_deposits_ws: false, fetch_funding_history: true, fetch_funding_interval: false, 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: true, fetch_leverage_tiers: false, fetch_leverages: true, fetch_liquidations: false, fetch_long_short_ratio: false, fetch_long_short_ratio_history: false, fetch_margin_adjustment_history: false, fetch_margin_mode: true, fetch_margin_modes: false, fetch_mark_ohlcv: false, fetch_mark_prices: false, fetch_market_leverage_tiers: false, fetch_markets: true, fetch_markets_ws: false, fetch_my_liquidations: false, fetch_my_settlement_history: false, fetch_my_trades: true, fetch_my_trades_ws: false, fetch_ohlcv: true, fetch_ohlcv_ws: false, fetch_open_interest: false, fetch_open_interest_history: false, fetch_open_interests: false, fetch_open_order: false, fetch_open_orders: true, fetch_open_orders_ws: false, fetch_option: false, fetch_option_chain: false, fetch_order: false, fetch_order_book: true, fetch_order_book_ws: false, fetch_order_books: false, fetch_order_trades: true, fetch_order_with_client_order_id: false, fetch_order_ws: false, fetch_orders: false, fetch_orders_by_status: false, fetch_orders_ws: false, fetch_position: true, fetch_position_history: false, fetch_position_mode: true, 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: false, 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: false, margin: false, option: false, private_api: true, public_api: true, reduce_margin: false, repay_cross_margin: false, repay_isolated_margin: false, sandbox: false, set_leverage: true, set_margin: false, set_margin_mode: true, set_position_mode: true, sign_in: false, spot: false, 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: false, watch_bids_asks: true, watch_liquidations: false, watch_liquidations_for_symbols: false, watch_my_liquidations: false, watch_my_liquidations_for_symbols: false, watch_my_trades: false, watch_ohlcv: true, watch_ohlcv_for_symbols: true, watch_order_book: true, watch_order_book_for_symbols: true, watch_orders: true, watch_orders_for_symbols: true, watch_position: false, watch_positions: true, watch_status: false, watch_ticker: true, watch_tickers: true, watch_trades: true, watch_trades_for_symbols: true, withdraw: false, ws: false }, http_config: nil, id: "blofin", markets: nil, name: "BloFin", ohlcv_timestamp_resolution: :unknown, options: %{ accounts_by_id: %{ "copy_trading" => "copy_trading", "earn" => "earn", "funding" => "funding", "futures" => "swap", "spot" => "spot" }, accounts_by_type: %{ "copy_trading" => "copy_trading", "earn" => "earn", "funding" => "funding", "future" => "futures", "spot" => "spot", "swap" => "futures" }, broker_id: "ec6dd3a7dd982d0b", cancel_orders: %{ "method" => "privatePostTradeCancelBatchOrders" }, create_market_buy_order_requires_price: false, create_order: "privatePostTradeOrder", default_account_type: "swap", default_network: "ERC20", default_networks: %{ "BTC" => "BTC", "ETH" => "ERC20", "USDT" => "TRC20" }, default_type: "swap", exchange_type: %{ "SPOT" => "SPOT", "SWAP" => "SWAP", "spot" => "SPOT", "swap" => "SWAP" }, fetch_canceled_orders: %{ "method" => "privateGetTradeOrdersHistory" }, fetch_closed_orders: %{ "method" => "privateGetTradeOrdersHistory" }, fetch_ledger: %{ "method" => "privateGetAssetBills" }, fetch_markets: [ "swap" ], fetch_o_h_l_c_v: %{ "timezone" => "UTC" }, fetch_open_interest_history: %{ "timeframes" => %{ "1D" => "1D", "1H" => "1H", "1d" => "1D", "1h" => "1H", "5M" => "5m", "5m" => "5m", "8H" => "8H", "8h" => "8H" } }, fetch_open_orders: %{ "method" => "privateGetTradeOrdersPending" }, fetch_positions: %{ "method" => "privateGetAccountPositions" }, networks: %{ "BEP20" => "BSC", "BTC" => "Bitcoin", "ERC20" => "ERC20", "TRC20" => "TRC20" }, withdraw: %{} }, order_mappings: %{ side_format: :lowercase, side_key: "side", type_format: :lowercase, type_key: "orderType" }, param_mappings: %{ "amount" => "size", "code" => "currency", "id" => "orderId", "limit" => "size", "price" => "orderPrice", "stopLoss" => "slTriggerPrice", "stopLossPrice" => "slTriggerPrice", "symbol" => "instId", "takeProfit" => "tpTriggerPrice", "takeProfitPrice" => "tpTriggerPrice", "timeframe" => "bar", "type" => "orderType" }, parse_methods: [ %{ "comment" => nil, "examples" => [ "{\n \"positionId\": \"756786\",\n \"instId\": \"BTC-USDT\",\n \"instType\": \"SWAP\",\n \"marginMode\": \"cross\",\n \"positionSide\": \"net\",\n \"adl\": \"1\",\n \"positions\": \"0.1\",\n \"availablePositions\": \"0.1\",\n \"averagePrice\": \"88564.9\",\n \"markPrice\": \"88546.3696492756\",\n \"marginRatio\": \"822.305183525552961566\",\n \"liquidationPrice\": \"\",\n \"unrealizedPnl\": \"-0.00185303507244\",\n \"unrealizedPnlRatio\": \"-0.000627687178252332\",\n \"initialMargin\": \"2.951545654975853333\",\n \"maintenanceMargin\": \"0.02656391089478268\",\n \"createTime\": \"1767169876207\",\n \"updateTime\": \"1767169876207\",\n \"leverage\": \"3\"\n }" ], "line_end" => 2620, "line_start" => 2583, "mappings" => [ %{ "comment" => nil, "key" => "info", "value" => "info" }, %{ "comment" => nil, "key" => "symbol", "value" => "this.safeSymbol (marketId, market, undefined, 'contract')" }, %{ "comment" => nil, "key" => "rank", "value" => "this.safeInteger (info, 'adl')" }, %{ "comment" => nil, "key" => "rating", "value" => "undefined" }, %{ "comment" => nil, "key" => "percentage", "value" => "undefined" }, %{ "comment" => nil, "key" => "timestamp", "value" => "timestamp" }, %{ "comment" => nil, "key" => "datetime", "value" => "this.iso8601 (timestamp)" } ], "name" => "parseADLRank", "signature" => "parseADLRank (info: Dict, market: Market = undefined): ADL", "source" => "parseADLRank (info: Dict, market: Market = undefined): ADL {\n //\n // fetchPositionsADLRank\n //\n // {\n // \"positionId\": \"756786\",\n // \"instId\": \"BTC-USDT\",\n // \"instType\": \"SWAP\",\n // \"marginMode\": \"cross\",\n // \"positionSide\": \"net\",\n // \"adl\": \"1\",\n // \"positions\": \"0.1\",\n // \"availablePositions\": \"0.1\",\n // \"averagePrice\": \"88564.9\",\n // \"markPrice\": \"88546.3696492756\",\n // \"marginRatio\": \"822.305183525552961566\",\n // \"liquidationPrice\": \"\",\n // \"unrealizedPnl\": \"-0.00185303507244\",\n // \"unrealizedPnlRatio\": \"-0.000627687178252332\",\n // \"initialMargin\": \"2.951545654975853333\",\n // \"maintenanceMargin\": \"0.02656391089478268\",\n // \"createTime\": \"1767169876207\",\n // \"updateTime\": \"1767169876207\",\n // \"leverage\": \"3\"\n // }\n //\n const marketId = this.safeString (info, 'instId');\n const timestamp = this.safeIntegerOmitZero (info, 'createTime');\n return {\n 'info': info,\n 'symbol': this.safeSymbol (marketId, market, undefined, 'contract'),\n 'rank': this.safeInteger (info, 'adl'),\n 'rating': undefined,\n 'percentage': undefined,\n 'timestamp': timestamp,\n 'datetime': this.iso8601 (timestamp),\n } as ADL;\n }" }, %{ "comment" => nil, "examples" => [ "{\n \"code\": \"0\",\n \"msg\": \"success\",\n \"data\": {\n \"ts\": \"1697021343571\",\n \"totalEquity\": \"10011254.077985990315787910\",\n \"isolatedEquity\": \"861.763132108800000000\",\n \"details\": [\n {\n \"currency\": \"USDT\",\n \"equity\": \"10014042.988958415234430699548\",\n \"balance\": \"10013119.885958415234430699\",\n \"ts\": \"1697021343571\",\n \"isolatedEquity\": \"862.003200000000000000048\",\n \"available\": \"9996399.4708691159703362725\",\n \"availableEquity\": \"9996399.4708691159703362725\",\n \"frozen\": \"15805.149672632597427761\",\n \"orderFrozen\": \"14920.994472632597427761\",\n \"equityUsd\": \"10011254.077985990315787910\",\n \"isolatedUnrealizedPnl\": \"-22.151999999999999999952\",\n \"bonus\": \"0\" // present only in REST\n \"unrealizedPnl\": \"0\" // present only in WS\n }\n ]\n }\n }" ], "line_end" => 1103, "line_start" => 1048, "mappings" => [], "name" => "parseBalance", "signature" => "parseBalance (response)", "source" => "parseBalance (response) {\n //\n // \"data\" similar for REST & WS\n //\n // {\n // \"code\": \"0\",\n // \"msg\": \"success\",\n // \"data\": {\n // \"ts\": \"1697021343571\",\n // \"totalEquity\": \"10011254.077985990315787910\",\n // \"isolatedEquity\": \"861.763132108800000000\",\n // \"details\": [\n // {\n // \"currency\": \"USDT\",\n // \"equity\": \"10014042.988958415234430699548\",\n // \"balance\": \"10013119.885958415234430699\",\n // \"ts\": \"1697021343571\",\n // \"isolatedEquity\": \"862.003200000000000000048\",\n // \"available\": \"9996399.4708691159703362725\",\n // \"availableEquity\": \"9996399.4708691159703362725\",\n // \"frozen\": \"15805.149672632597427761\",\n // \"orderFrozen\": \"14920.994472632597427761\",\n // \"equityUsd\": \"10011254.077985990315787910\",\n // \"isolatedUnrealizedPnl\": \"-22.151999999999999999952\",\n // \"bonus\": \"0\" // present only in REST\n // \"unrealizedPnl\": \"0\" // present only in WS\n // }\n // ]\n // }\n // }\n //\n const result: Dict = { 'info': response };\n const data = this.safeDict (response, 'data', {});\n const timestamp = this.safeInteger (data, 'ts');\n const details = this.safeList (data, 'details', []);\n for (let i = 0; i < details.length; i++) {\n const balance = details[i];\n const currencyId = this.safeString (balance, 'currency');\n const code = this.safeCurrencyCode (currencyId);\n const account = this.account ();\n // it may be incorrect to use total, free and used for swap accounts\n const eq = this.safeString (balance, 'equity');\n const availEq = this.safeString (balance, 'available');\n if ((eq === undefined) || (availEq === undefined)) {\n account['free'] = this.safeString (balance, 'availableEquity');\n account['used'] = this.safeString (balance, 'frozen');\n } else {\n account['total'] = eq;\n account['free'] = availEq;\n }\n result[code] = account;\n }\n result['timestamp'] = timestamp;\n result['datetime'] = this.iso8601 (timestamp);\n return this.safeBalance (result);\n }" }, %{ "comment" => nil, "examples" => [], "line_end" => 1046, "line_start" => 1039, "mappings" => [], "name" => "parseBalanceByType", "signature" => "parseBalanceByType (response)", "source" => "parseBalanceByType (response) {\n const data = this.safeList (response, 'data');\n if ((data !== undefined) && Array.isArray (data)) {\n return this.parseFundingBalance (response);\n } else {\n return this.parseBalance (response);\n }\n }" }, %{ "comment" => nil, "examples" => [ "{\n \"code\": \"0\",\n \"msg\": \"success\",\n \"data\": [\n {\n \"currency\": \"USDT\",\n \"balance\": \"10012514.919418081548717298\",\n \"available\": \"9872132.414278782284622898\",\n \"frozen\": \"138556.471805965930761067\",\n \"bonus\": \"0\"\n }\n ]\n }" ], "line_end" => 1135, "line_start" => 1105, "mappings" => [], "name" => "parseFundingBalance", "signature" => "parseFundingBalance (response)", "source" => "parseFundingBalance (response) {\n //\n // {\n // \"code\": \"0\",\n // \"msg\": \"success\",\n // \"data\": [\n // {\n // \"currency\": \"USDT\",\n // \"balance\": \"10012514.919418081548717298\",\n // \"available\": \"9872132.414278782284622898\",\n // \"frozen\": \"138556.471805965930761067\",\n // \"bonus\": \"0\"\n // }\n // ]\n // }\n //\n const result: Dict = { 'info': response };\n const data = this.safeList (response, 'data', []);\n for (let i = 0; i < data.length; i++) {\n const balance = data[i];\n const currencyId = this.safeString (balance, 'currency');\n const code = this.safeCurrencyCode (currencyId);\n const account = this.account ();\n // it may be incorrect to use total, free and used for swap accounts\n account['total'] = this.safeString (balance, 'balance');\n account['free'] = this.safeString (balance, 'available');\n account['used'] = this.safeString (balance, 'frozen');\n result[code] = account;\n }\n return this.safeBalance (result);\n }" }, %{ "comment" => nil, "examples" => [ "{\n \"fundingRate\": \"0.00027815\",\n \"fundingTime\": \"1634256000000\",\n \"instId\": \"BTC-USD-SWAP\",\n }" ], "line_end" => 1000, "line_start" => 968, "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" => "this.parseNumber ('0')" }, %{ "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" => "fundingTime" }, %{ "comment" => nil, "key" => "fundingDatetime", "value" => "this.iso8601 (fundingTime)" }, %{ "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" => "undefined" } ], "name" => "parseFundingRate", "signature" => "parseFundingRate (contract, market: Market = undefined): FundingRate", "source" => "parseFundingRate (contract, market: Market = undefined): FundingRate {\n //\n // {\n // \"fundingRate\": \"0.00027815\",\n // \"fundingTime\": \"1634256000000\",\n // \"instId\": \"BTC-USD-SWAP\",\n // }\n //\n const marketId = this.safeString (contract, 'instId');\n const symbol = this.safeSymbol (marketId, market);\n const fundingTime = this.safeInteger (contract, 'fundingTime');\n // > The current interest is 0.\n return {\n 'info': contract,\n 'symbol': symbol,\n 'markPrice': undefined,\n 'indexPrice': undefined,\n 'interestRate': this.parseNumber ('0'),\n 'estimatedSettlePrice': undefined,\n 'timestamp': undefined,\n 'datetime': undefined,\n 'fundingRate': this.safeNumber (contract, 'fundingRate'),\n 'fundingTimestamp': fundingTime,\n 'fundingDatetime': this.iso8601 (fundingTime),\n 'nextFundingRate': undefined,\n 'nextFundingTimestamp': undefined,\n 'nextFundingDatetime': undefined,\n 'previousFundingRate': undefined,\n 'previousFundingTimestamp': undefined,\n 'previousFundingDatetime': undefined,\n 'interval': undefined,\n } as FundingRate;\n }" }, %{ "comment" => nil, "examples" => [ "@param {string[]|string} ids order ids", "@returns {string[]} list of order ids" ], "line_end" => 1914, "line_start" => 1901, "mappings" => [], "name" => "parseIds", "signature" => "parseIds (ids)", "source" => "parseIds (ids) {\n /**\n * @ignore\n * @method\n * @name blofin#parseIds\n * @param {string[]|string} ids order ids\n * @returns {string[]} list of order ids\n */\n if (typeof ids === 'string') {\n return ids.split (',');\n } else {\n return ids;\n }\n }" }, %{ "comment" => nil, "examples" => [], "line_end" => 1899, "line_start" => 1877, "mappings" => [ %{ "comment" => nil, "key" => "info", "value" => "item" }, %{ "comment" => nil, "key" => "id", "value" => "this.safeString (item, 'transferId')" }, %{ "comment" => nil, "key" => "direction", "value" => "undefined" }, %{ "comment" => nil, "key" => "account", "value" => "undefined" }, %{ "comment" => nil, "key" => "referenceId", "value" => "this.safeString (item, 'clientId')" }, %{ "comment" => nil, "key" => "referenceAccount", "value" => "undefined" }, %{ "comment" => nil, "key" => "type", "value" => "this.parseLedgerEntryType (this.safeString (item, 'type'))" }, %{ "comment" => nil, "key" => "currency", "value" => "code" }, %{ "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" => "undefined" }, %{ "comment" => nil, "key" => "status", "value" => "'ok'" }, %{ "comment" => nil, "key" => "fee", "value" => "undefined" } ], "name" => "parseLedgerEntry", "signature" => "parseLedgerEntry (item: Dict, currency: Currency = undefined): LedgerEntry", "source" => "parseLedgerEntry (item: Dict, currency: Currency = undefined): LedgerEntry {\n const currencyId = this.safeString (item, 'currency');\n const code = this.safeCurrencyCode (currencyId, currency);\n currency = this.safeCurrency (currencyId, currency);\n const timestamp = this.safeInteger (item, 'ts');\n return this.safeLedgerEntry ({\n 'info': item,\n 'id': this.safeString (item, 'transferId'),\n 'direction': undefined,\n 'account': undefined,\n 'referenceId': this.safeString (item, 'clientId'),\n 'referenceAccount': undefined,\n 'type': this.parseLedgerEntryType (this.safeString (item, 'type')),\n 'currency': code,\n 'amount': this.safeNumber (item, 'amount'),\n 'timestamp': timestamp,\n 'datetime': this.iso8601 (timestamp),\n 'before': undefined,\n 'after': undefined,\n 'status': 'ok',\n 'fee': undefined,\n }, currency) as LedgerEntry;\n }" }, %{ "comment" => nil, "examples" => [], "line_end" => 1875, "line_start" => 1860, "mappings" => [], "name" => "parseLedgerEntryType", "signature" => "parseLedgerEntryType (type)", "source" => "parseLedgerEntryType (type) {\n const types: Dict = {\n '1': 'transfer', // transfer\n '2': 'trade', // trade\n '3': 'trade', // delivery\n '4': 'rebate', // auto token conversion\n '5': 'trade', // liquidation\n '6': 'transfer', // margin transfer\n '7': 'trade', // interest deduction\n '8': 'fee', // funding rate\n '9': 'trade', // adl\n '10': 'trade', // clawback\n '11': 'trade', // system token conversion\n };\n return this.safeString (types, type, type);\n }" }, %{ "comment" => nil, "examples" => [], "line_end" => 2294, "line_start" => 2284, "mappings" => [ %{ "comment" => nil, "key" => "info", "value" => "leverage" }, %{ "comment" => nil, "key" => "symbol", "value" => "this.safeSymbol (marketId, market)" }, %{ "comment" => nil, "key" => "marginMode", "value" => "this.safeStringLower (leverage, 'marginMode')" }, %{ "comment" => nil, "key" => "longLeverage", "value" => "leverageValue" }, %{ "comment" => nil, "key" => "shortLeverage", "value" => "leverageValue" } ], "name" => "parseLeverage", "signature" => "parseLeverage (leverage: Dict, market: Market = undefined): Leverage", "source" => "parseLeverage (leverage: Dict, market: Market = undefined): Leverage {\n const marketId = this.safeString (leverage, 'instId');\n const leverageValue = this.safeInteger (leverage, 'leverage');\n return {\n 'info': leverage,\n 'symbol': this.safeSymbol (marketId, market),\n 'marginMode': this.safeStringLower (leverage, 'marginMode'),\n 'longLeverage': leverageValue,\n 'shortLeverage': leverageValue,\n } as Leverage;\n }" }, %{ "comment" => nil, "examples" => [], "line_end" => 2447, "line_start" => 2441, "mappings" => [ %{ "comment" => nil, "key" => "info", "value" => "marginMode" }, %{ "comment" => nil, "key" => "symbol", "value" => "this.safeString (market, 'symbol')" }, %{ "comment" => nil, "key" => "marginMode", "value" => "this.safeString (marginMode, 'marginMode')" } ], "name" => "parseMarginMode", "signature" => "parseMarginMode (marginMode: Dict, market: Market = undefined): MarginMode", "source" => "parseMarginMode (marginMode: Dict, market: Market = undefined): MarginMode {\n return {\n 'info': marginMode,\n 'symbol': this.safeString (market, 'symbol'),\n 'marginMode': this.safeString (marginMode, 'marginMode'),\n } as MarginMode;\n }" }, %{ "comment" => nil, "examples" => [], "line_end" => 582, "line_start" => 503, "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" => "baseId", "value" => "baseId" }, %{ "comment" => nil, "key" => "quoteId", "value" => "quoteId" }, %{ "comment" => nil, "key" => "settle", "value" => "settle" }, %{ "comment" => nil, "key" => "settleId", "value" => "settleId" }, %{ "comment" => nil, "key" => "type", "value" => "type" }, %{ "comment" => nil, "key" => "spot", "value" => "spot" }, %{ "comment" => nil, "key" => "option", "value" => "option" }, %{ "comment" => nil, "key" => "margin", "value" => "spot && (Precise.stringGt (maxLeverage, '1'))" }, %{ "comment" => nil, "key" => "swap", "value" => "swap" }, %{ "comment" => nil, "key" => "future", "value" => "future" }, %{ "comment" => nil, "key" => "active", "value" => "isActive" }, %{ "comment" => nil, "key" => "taker", "value" => "taker" }, %{ "comment" => nil, "key" => "maker", "value" => "maker" }, %{ "comment" => nil, "key" => "contract", "value" => "contract" }, %{ "comment" => nil, "key" => "linear", "value" => "contract ? (quoteId === settleId) : undefined" }, %{ "comment" => nil, "key" => "inverse", "value" => "contract ? (baseId === settleId) : undefined" }, %{ "comment" => nil, "key" => "contractSize", "value" => "contract ? this.safeNumber (market, 'contractValue') : undefined" }, %{ "comment" => nil, "key" => "expiry", "value" => "expiry" }, %{ "comment" => nil, "key" => "expiryDatetime", "value" => "expiry" }, %{ "comment" => nil, "key" => "strike", "value" => "strikePrice" }, %{ "comment" => nil, "key" => "optionType", "value" => "optionType" }, %{ "comment" => nil, "key" => "created", "value" => "this.safeInteger (market, 'listTime')" }, %{ "comment" => nil, "key" => "precision", "value" => "{\n 'amount': this.safeNumber (market, 'lotSize'),\n 'price': this.parseNumber (tickSize),\n }" }, %{ "comment" => nil, "key" => "limits", "value" => "{\n 'leverage': {\n 'min': this.parseNumber ('1'),\n 'max': this.parseNumber (maxLeverage),\n },\n 'amount': {\n 'min': this.safeNumber (market, 'minSize'),\n 'max': undefined,\n },\n 'price': {\n 'min': undefined,\n 'max': undefined,\n },\n 'cost': {\n 'min': undefined,\n 'max': undefined,\n },\n }" }, %{ "comment" => nil, "key" => "info", "value" => "market" }, %{ "comment" => nil, "key" => "amount", "value" => "this.safeNumber (market, 'lotSize')" }, %{ "comment" => nil, "key" => "price", "value" => "this.parseNumber (tickSize)" }, %{ "comment" => nil, "key" => "leverage", "value" => "{\n 'min': this.parseNumber ('1'),\n 'max': this.parseNumber (maxLeverage),\n }" }, %{ "comment" => nil, "key" => "amount", "value" => "{\n 'min': this.safeNumber (market, 'minSize'),\n 'max': undefined,\n }" }, %{ "comment" => nil, "key" => "price", "value" => "{\n 'min': undefined,\n 'max': undefined,\n }" }, %{ "comment" => nil, "key" => "cost", "value" => "{\n 'min': undefined,\n 'max': undefined,\n }" }, %{ "comment" => nil, "key" => "min", "value" => "undefined" }, %{ "comment" => nil, "key" => "max", "value" => "undefined" } ], "name" => "parseMarket", "signature" => "parseMarket (market: Dict): Market", "source" => "parseMarket (market: Dict): Market {\n const id = this.safeString (market, 'instId');\n const type = this.safeStringLower (market, 'instType');\n const spot = (type === 'spot');\n const future = (type === 'future');\n const swap = (type === 'swap');\n const option = (type === 'option');\n const contract = swap || future;\n const baseId = this.safeString (market, 'baseCurrency');\n const quoteId = this.safeString (market, 'quoteCurrency');\n const settleId = this.safeString (market, 'quoteCurrency');\n const settle = this.safeCurrencyCode (settleId);\n const base = this.safeCurrencyCode (baseId);\n const quote = this.safeCurrencyCode (quoteId);\n let symbol = base + '/' + quote;\n if (swap) {\n symbol = symbol + ':' + settle;\n }\n const expiry = undefined;\n const strikePrice = undefined;\n const optionType = undefined;\n const tickSize = this.safeString (market, 'tickSize');\n const fees = this.safeDict2 (this.fees, type, 'trading', {});\n const taker = this.safeNumber (fees, 'taker');\n const maker = this.safeNumber (fees, 'maker');\n let maxLeverage = this.safeString (market, 'maxLeverage', '100');\n maxLeverage = Precise.stringMax (maxLeverage, '1');\n const isActive = (this.safeString (market, 'state') === 'live');\n return this.safeMarketStructure ({\n 'id': id,\n 'symbol': symbol,\n 'base': base,\n 'quote': quote,\n 'baseId': baseId,\n 'quoteId': quoteId,\n 'settle': settle,\n 'settleId': settleId,\n 'type': type,\n 'spot': spot,\n 'option': option,\n 'margin': spot && (Precise.stringGt (maxLeverage, '1')),\n 'swap': swap,\n 'future': future,\n 'active': isActive,\n 'taker': taker,\n 'maker': maker,\n 'contract': contract,\n 'linear': contract ? (quoteId === settleId) : undefined,\n 'inverse': contract ? (baseId === settleId) : undefined,\n 'contractSize': contract ? this.safeNumber (market, 'contractValue') : undefined,\n 'expiry': expiry,\n 'expiryDatetime': expiry,\n 'strike': strikePrice,\n 'optionType': optionType,\n 'created': this.safeInteger (market, 'listTime'),\n 'precision': {\n 'amount': this.safeNumber (market, 'lotSize'),\n 'price': this.parseNumber (tickSize),\n },\n 'limits': {\n 'leverage': {\n 'min': this.parseNumber ('1'),\n 'max': this.parseNumber (maxLeverage),\n },\n 'amount': {\n 'min': this.safeNumber (market, 'minSize'),\n 'max': undefined,\n },\n 'price': {\n 'min': undefined,\n 'max': undefined,\n },\n 'cost': {\n 'min': undefined,\n 'max': undefined,\n },\n },\n 'info': market,\n });\n }" }, %{ "comment" => nil, "examples" => [ "[\n \"1678928760000\", // timestamp\n \"24341.4\", // open\n \"24344\", // high\n \"24313.2\", // low\n \"24323\", // close\n \"628\", // contract volume\n \"2.5819\", // base volume\n \"62800\", // quote volume\n \"0\" // candlestick state\n ]" ], "line_end" => 869, "line_start" => 847, "mappings" => [], "name" => "parseOHLCV", "signature" => "parseOHLCV (ohlcv, market: Market = undefined): OHLCV", "source" => "parseOHLCV (ohlcv, market: Market = undefined): OHLCV {\n //\n // [\n // \"1678928760000\", // timestamp\n // \"24341.4\", // open\n // \"24344\", // high\n // \"24313.2\", // low\n // \"24323\", // close\n // \"628\", // contract volume\n // \"2.5819\", // base volume\n // \"62800\", // quote volume\n // \"0\" // candlestick state\n // ]\n //\n return [\n this.safeInteger (ohlcv, 0),\n this.safeNumber (ohlcv, 1),\n this.safeNumber (ohlcv, 2),\n this.safeNumber (ohlcv, 3),\n this.safeNumber (ohlcv, 4),\n this.safeNumber (ohlcv, 6),\n ];\n }" }, %{ "comment" => nil, "examples" => [ "{\n \"orderId\": \"2075628533\",\n \"clientOrderId\": \"\",\n \"instId\": \"LTC-USDT\",\n \"marginMode\": \"cross\",\n \"positionSide\": \"net\",\n \"side\": \"buy\",\n \"orderType\": \"market\",\n \"price\": \"0.000000000000000000\",\n \"size\": \"1.000000000000000000\",\n \"reduceOnly\": \"true\",\n \"leverage\": \"3\",\n \"state\": \"filled\",\n \"filledSize\": \"1.000000000000000000\",\n \"pnl\": \"-0.050000000000000000\",\n \"averagePrice\": \"68.110000000000000000\",\n \"fee\": \"0.040866000000000000\",\n \"createTime\": \"1706891359010\",\n \"updateTime\": \"1706891359098\",\n \"orderCategory\": \"normal\",\n \"tpTriggerPrice\": null,\n \"tpOrderPrice\": null,\n \"slTriggerPrice\": null,\n \"slOrderPrice\": null,\n \"cancelSource\": \"not_canceled\",\n \"cancelSourceReason\": null,\n \"brokerId\": \"ec6dd3a7dd982d0b\"\n \"filled_amount\": \"1.000000000000000000\", // filledAmount in \"ws\" watchOrders\n \"cancelSource\": \"\", // only in WS\n \"instType\": \"SWAP\", // only in WS\n }" ], "line_end" => 1372, "line_start" => 1250, "mappings" => [ %{ "comment" => nil, "key" => "info", "value" => "order" }, %{ "comment" => nil, "key" => "id", "value" => "id" }, %{ "comment" => nil, "key" => "clientOrderId", "value" => "clientOrderId" }, %{ "comment" => nil, "key" => "timestamp", "value" => "timestamp" }, %{ "comment" => nil, "key" => "datetime", "value" => "this.iso8601 (timestamp)" }, %{ "comment" => nil, "key" => "lastTradeTimestamp", "value" => "lastTradeTimestamp" }, %{ "comment" => nil, "key" => "lastUpdateTimestamp", "value" => "lastUpdateTimestamp" }, %{ "comment" => nil, "key" => "symbol", "value" => "symbol" }, %{ "comment" => nil, "key" => "type", "value" => "type" }, %{ "comment" => nil, "key" => "timeInForce", "value" => "timeInForce" }, %{ "comment" => nil, "key" => "postOnly", "value" => "postOnly" }, %{ "comment" => nil, "key" => "side", "value" => "side" }, %{ "comment" => nil, "key" => "price", "value" => "price" }, %{ "comment" => nil, "key" => "stopLossTriggerPrice", "value" => "stopLossTriggerPrice" }, %{ "comment" => nil, "key" => "takeProfitTriggerPrice", "value" => "takeProfitTriggerPrice" }, %{ "comment" => nil, "key" => "stopLossPrice", "value" => "stopLossPrice" }, %{ "comment" => nil, "key" => "takeProfitPrice", "value" => "takeProfitPrice" }, %{ "comment" => nil, "key" => "average", "value" => "average" }, %{ "comment" => nil, "key" => "cost", "value" => "cost" }, %{ "comment" => nil, "key" => "amount", "value" => "amount" }, %{ "comment" => nil, "key" => "filled", "value" => "filled" }, %{ "comment" => nil, "key" => "remaining", "value" => "undefined" }, %{ "comment" => nil, "key" => "status", "value" => "status" }, %{ "comment" => nil, "key" => "fee", "value" => "fee" }, %{ "comment" => nil, "key" => "trades", "value" => "undefined" }, %{ "comment" => nil, "key" => "reduceOnly", "value" => "reduceOnly" }, %{ "comment" => nil, "key" => "cost", "value" => "this.parseNumber (feeCostSigned)" }, %{ "comment" => nil, "key" => "currency", "value" => "feeCurrencyCode" } ], "name" => "parseOrder", "signature" => "parseOrder (order: Dict, market: Market = undefined): Order", "source" => "parseOrder (order: Dict, market: Market = undefined): Order {\n //\n // response similar for REST & WS\n //\n // {\n // \"orderId\": \"2075628533\",\n // \"clientOrderId\": \"\",\n // \"instId\": \"LTC-USDT\",\n // \"marginMode\": \"cross\",\n // \"positionSide\": \"net\",\n // \"side\": \"buy\",\n // \"orderType\": \"market\",\n // \"price\": \"0.000000000000000000\",\n // \"size\": \"1.000000000000000000\",\n // \"reduceOnly\": \"true\",\n // \"leverage\": \"3\",\n // \"state\": \"filled\",\n // \"filledSize\": \"1.000000000000000000\",\n // \"pnl\": \"-0.050000000000000000\",\n // \"averagePrice\": \"68.110000000000000000\",\n // \"fee\": \"0.040866000000000000\",\n // \"createTime\": \"1706891359010\",\n // \"updateTime\": \"1706891359098\",\n // \"orderCategory\": \"normal\",\n // \"tpTriggerPrice\": null,\n // \"tpOrderPrice\": null,\n // \"slTriggerPrice\": null,\n // \"slOrderPrice\": null,\n // \"cancelSource\": \"not_canceled\",\n // \"cancelSourceReason\": null,\n // \"brokerId\": \"ec6dd3a7dd982d0b\"\n // \"filled_amount\": \"1.000000000000000000\", // filledAmount in \"ws\" watchOrders\n // \"cancelSource\": \"\", // only in WS\n // \"instType\": \"SWAP\", // only in WS\n // }\n //\n const id = this.safeStringN (order, [ 'tpslId', 'orderId', 'algoId' ]);\n const timestamp = this.safeInteger (order, 'createTime');\n const lastUpdateTimestamp = this.safeInteger (order, 'updateTime');\n const lastTradeTimestamp = this.safeInteger (order, 'fillTime');\n const side = this.safeString (order, 'side');\n let type = this.safeString (order, 'orderType');\n let postOnly = undefined;\n let timeInForce = undefined;\n if (type === 'post_only') {\n postOnly = true;\n type = 'limit';\n } else if (type === 'fok') {\n timeInForce = 'FOK';\n type = 'limit';\n } else if (type === 'ioc') {\n timeInForce = 'IOC';\n type = 'limit';\n } else if (type === 'conditional') {\n type = 'trigger';\n }\n const marketId = this.safeString (order, 'instId');\n market = this.safeMarket (marketId, market);\n const symbol = this.safeSymbol (marketId, market, '-');\n const filled = this.safeString (order, 'filledSize');\n const price = this.safeStringN (order, [ 'px', 'price', 'orderPrice' ]);\n const average = this.safeString (order, 'averagePrice');\n const status = this.parseOrderStatus (this.safeString (order, 'state'));\n const feeCostString = this.safeString (order, 'fee');\n const amount = this.safeString (order, 'size');\n const leverage = this.safeString (order, 'leverage', '1');\n const contractSize = this.safeString (market, 'contractSize');\n const baseAmount = Precise.stringMul (contractSize, filled);\n let cost: Str = undefined;\n if (average !== undefined) {\n cost = Precise.stringMul (average, baseAmount);\n cost = Precise.stringDiv (cost, leverage);\n }\n // spot market buy: \"sz\" can refer either to base currency units or to quote currency units\n let fee = undefined;\n if (feeCostString !== undefined) {\n const feeCostSigned = Precise.stringAbs (feeCostString);\n const feeCurrencyId = this.safeString (order, 'feeCcy', 'USDT');\n const feeCurrencyCode = this.safeCurrencyCode (feeCurrencyId);\n fee = {\n 'cost': this.parseNumber (feeCostSigned),\n 'currency': feeCurrencyCode,\n };\n }\n let clientOrderId = this.safeString (order, 'clientOrderId');\n if ((clientOrderId !== undefined) && (clientOrderId.length < 1)) {\n clientOrderId = undefined; // fix empty clientOrderId string\n }\n const stopLossTriggerPrice = this.safeNumber (order, 'slTriggerPrice');\n const stopLossPrice = this.safeNumber (order, 'slOrderPrice');\n const takeProfitTriggerPrice = this.safeNumber (order, 'tpTriggerPrice');\n const takeProfitPrice = this.safeNumber (order, 'tpOrderPrice');\n const reduceOnlyRaw = this.safeString (order, 'reduceOnly');\n const reduceOnly = (reduceOnlyRaw === 'true');\n return this.safeOrder ({\n 'info': order,\n 'id': id,\n 'clientOrderId': clientOrderId,\n 'timestamp': timestamp,\n 'datetime': this.iso8601 (timestamp),\n 'lastTradeTimestamp': lastTradeTimestamp,\n 'lastUpdateTimestamp': lastUpdateTimestamp,\n 'symbol': symbol,\n 'type': type,\n 'timeInForce': timeInForce,\n 'postOnly': postOnly,\n 'side': side,\n 'price': price,\n 'stopLossTriggerPrice': stopLossTriggerPrice,\n 'takeProfitTriggerPrice': takeProfitTriggerPrice,\n 'stopLossPrice': stopLossPrice,\n 'takeProfitPrice': takeProfitPrice,\n 'average': average,\n 'cost': cost,\n 'amount': amount,\n 'filled': filled,\n 'remaining': undefined,\n 'status': status,\n 'fee': fee,\n 'trades': undefined,\n 'reduceOnly': reduceOnly,\n }, market);\n }" }, %{ "comment" => nil, "examples" => [], "line_end" => 1248, "line_start" => 1238, "mappings" => [], "name" => "parseOrderStatus", "signature" => "parseOrderStatus (status: Str)", "source" => "parseOrderStatus (status: Str) {\n const statuses: Dict = {\n 'canceled': 'canceled',\n 'order_failed': 'canceled',\n 'live': 'open',\n 'partially_filled': 'open',\n 'filled': 'closed',\n 'effective': 'closed',\n };\n return this.safeString (statuses, status, status);\n }" }, %{ "comment" => nil, "examples" => [ "{\n instType: 'SWAP',\n instId: 'LTC-USDT',\n marginMode: 'cross',\n positionId: '644159',\n positionSide: 'net',\n positions: '1',\n availablePositions: '1',\n averagePrice: '68.16',\n unrealizedPnl: '0.80631223',\n unrealizedPnlRatio: '0.03548909463028169',\n leverage: '3',\n liquidationPrice: '10.116655172370356435',\n markPrice: '68.96',\n initialMargin: '22.988770743333333333',\n margin: '', // this field might not exist in rest response\n marginRatio: '152.523509620342499273',\n maintenanceMargin: '0.34483156115',\n adl: '4',\n createTime: '1707235776528',\n updateTime: '1707235776528'\n }" ], "line_end" => 2185, "line_start" => 2073, "mappings" => [ %{ "comment" => nil, "key" => "info", "value" => "position" }, %{ "comment" => nil, "key" => "id", "value" => "undefined" }, %{ "comment" => nil, "key" => "symbol", "value" => "symbol" }, %{ "comment" => nil, "key" => "notional", "value" => "notional" }, %{ "comment" => nil, "key" => "marginMode", "value" => "marginMode" }, %{ "comment" => nil, "key" => "liquidationPrice", "value" => "liquidationPrice" }, %{ "comment" => nil, "key" => "entryPrice", "value" => "this.parseNumber (entryPriceString)" }, %{ "comment" => nil, "key" => "unrealizedPnl", "value" => "this.parseNumber (unrealizedPnlString)" }, %{ "comment" => nil, "key" => "percentage", "value" => "percentage" }, %{ "comment" => nil, "key" => "contracts", "value" => "contracts" }, %{ "comment" => nil, "key" => "contractSize", "value" => "contractSize" }, %{ "comment" => nil, "key" => "markPrice", "value" => "this.parseNumber (markPriceString)" }, %{ "comment" => nil, "key" => "lastPrice", "value" => "undefined" }, %{ "comment" => nil, "key" => "side", "value" => "side" }, %{ "comment" => nil, "key" => "hedged", "value" => "hedged" }, %{ "comment" => nil, "key" => "timestamp", "value" => "timestamp" }, %{ "comment" => nil, "key" => "datetime", "value" => "this.iso8601 (timestamp)" }, %{ "comment" => nil, "key" => "lastUpdateTimestamp", "value" => "undefined" }, %{ "comment" => nil, "key" => "maintenanceMargin", "value" => "maintenanceMargin" }, %{ "comment" => nil, "key" => "maintenanceMarginPercentage", "value" => "maintenanceMarginPercentage" }, %{ "comment" => nil, "key" => "collateral", "value" => "this.parseNumber (collateralString)" }, %{ "comment" => nil, "key" => "initialMargin", "value" => "this.parseNumber (initialMarginString)" }, %{ "comment" => nil, "key" => "initialMarginPercentage", "value" => "this.parseNumber (initialMarginPercentage)" }, %{ "comment" => nil, "key" => "leverage", "value" => "this.parseNumber (leverageString)" }, %{ "comment" => nil, "key" => "marginRatio", "value" => "marginRatio" }, %{ "comment" => nil, "key" => "stopLossPrice", "value" => "undefined" }, %{ "comment" => nil, "key" => "takeProfitPrice", "value" => "undefined" } ], "name" => "parsePosition", "signature" => "parsePosition (position: Dict, market: Market = undefined)", "source" => "parsePosition (position: Dict, market: Market = undefined) {\n //\n // response similar for REST & WS\n //\n // {\n // instType: 'SWAP',\n // instId: 'LTC-USDT',\n // marginMode: 'cross',\n // positionId: '644159',\n // positionSide: 'net',\n // positions: '1',\n // availablePositions: '1',\n // averagePrice: '68.16',\n // unrealizedPnl: '0.80631223',\n // unrealizedPnlRatio: '0.03548909463028169',\n // leverage: '3',\n // liquidationPrice: '10.116655172370356435',\n // markPrice: '68.96',\n // initialMargin: '22.988770743333333333',\n // margin: '', // this field might not exist in rest response\n // marginRatio: '152.523509620342499273',\n // maintenanceMargin: '0.34483156115',\n // adl: '4',\n // createTime: '1707235776528',\n // updateTime: '1707235776528'\n // }\n //\n const marketId = this.safeString (position, 'instId');\n market = this.safeMarket (marketId, market);\n const symbol = market['symbol'];\n const pos = this.safeString (position, 'positions');\n const contractsAbs = Precise.stringAbs (pos);\n let side = this.safeString (position, 'positionSide');\n const hedged = side !== 'net';\n const contracts = this.parseNumber (contractsAbs);\n if (pos !== undefined) {\n if (side === 'net') {\n if (Precise.stringGt (pos, '0')) {\n side = 'long';\n } else if (Precise.stringLt (pos, '0')) {\n side = 'short';\n } else {\n side = undefined;\n }\n }\n }\n const contractSize = this.safeNumber (market, 'contractSize');\n const contractSizeString = this.numberToString (contractSize);\n const markPriceString = this.safeString (position, 'markPrice');\n let notionalString = this.safeString (position, 'notionalUsd');\n if (market['inverse']) {\n notionalString = Precise.stringDiv (Precise.stringMul (contractsAbs, contractSizeString), markPriceString);\n }\n const notional = this.parseNumber (notionalString);\n const marginMode = this.safeString (position, 'marginMode');\n let initialMarginString = undefined;\n const entryPriceString = this.safeString (position, 'averagePrice');\n const unrealizedPnlString = this.safeString (position, 'unrealizedPnl');\n const leverageString = this.safeString (position, 'leverage');\n let initialMarginPercentage = undefined;\n let collateralString = undefined;\n if (marginMode === 'cross') {\n initialMarginString = this.safeString (position, 'initialMargin');\n collateralString = Precise.stringAdd (initialMarginString, unrealizedPnlString);\n } else if (marginMode === 'isolated') {\n initialMarginPercentage = Precise.stringDiv ('1', leverageString);\n collateralString = this.safeString (position, 'margin');\n }\n const maintenanceMarginString = this.safeString (position, 'maintenanceMargin');\n const maintenanceMargin = this.parseNumber (maintenanceMarginString);\n const maintenanceMarginPercentageString = Precise.stringDiv (maintenanceMarginString, notionalString);\n if (initialMarginPercentage === undefined) {\n initialMarginPercentage = this.parseNumber (Precise.stringDiv (initialMarginString, notionalString, 4));\n } else if (initialMarginString === undefined) {\n initialMarginString = Precise.stringMul (initialMarginPercentage, notionalString);\n }\n const rounder = '0.00005'; // round to closest 0.01%\n const maintenanceMarginPercentage = this.parseNumber (Precise.stringDiv (Precise.stringAdd (maintenanceMarginPercentageString, rounder), '1', 4));\n const liquidationPrice = this.safeNumber (position, 'liquidationPrice');\n const percentageString = this.safeString (position, 'unrealizedPnlRatio');\n const percentage = this.parseNumber (Precise.stringMul (percentageString, '100'));\n const timestamp = this.safeInteger (position, 'updateTime');\n const marginRatio = this.parseNumber (Precise.stringDiv (maintenanceMarginString, collateralString, 4));\n return this.safePosition ({\n 'info': position,\n 'id': undefined,\n 'symbol': symbol,\n 'notional': notional,\n 'marginMode': marginMode,\n 'liquidationPrice': liquidationPrice,\n 'entryPrice': this.parseNumber (entryPriceString),\n 'unrealizedPnl': this.parseNumber (unrealizedPnlString),\n 'percentage': percentage,\n 'contracts': contracts,\n 'contractSize': contractSize,\n 'markPrice': this.parseNumber (markPriceString),\n 'lastPrice': undefined,\n 'side': side,\n 'hedged': hedged,\n 'timestamp': timestamp,\n 'datetime': this.iso8601 (timestamp),\n 'lastUpdateTimestamp': undefined,\n 'maintenanceMargin': maintenanceMargin,\n 'maintenanceMarginPercentage': maintenanceMarginPercentage,\n 'collateral': this.parseNumber (collateralString),\n 'initialMargin': this.parseNumber (initialMarginString),\n 'initialMarginPercentage': this.parseNumber (initialMarginPercentage),\n 'leverage': this.parseNumber (leverageString),\n 'marginRatio': marginRatio,\n 'stopLossPrice': undefined,\n 'takeProfitPrice': undefined,\n });\n }" }, %{ "comment" => nil, "examples" => [ "{\n instId: \"ADA-USDT\",\n ts: \"1707736811486\",\n last: \"0.5315\",\n lastSize: \"4\",\n askPrice: \"0.5318\",\n askSize: \"248\",\n bidPrice: \"0.5315\",\n bidSize: \"63\",\n open24h: \"0.5555\",\n high24h: \"0.5563\",\n low24h: \"0.5315\",\n volCurrency24h: \"198560100\",\n vol24h: \"1985601\",\n }" ], "line_end" => 687, "line_start" => 632, "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" => "high" }, %{ "comment" => nil, "key" => "low", "value" => "low" }, %{ "comment" => nil, "key" => "bid", "value" => "this.safeString (ticker, 'bidPrice')" }, %{ "comment" => nil, "key" => "bidVolume", "value" => "this.safeString (ticker, 'bidSize')" }, %{ "comment" => nil, "key" => "ask", "value" => "this.safeString (ticker, 'askPrice')" }, %{ "comment" => nil, "key" => "askVolume", "value" => "this.safeString (ticker, 'askSize')" }, %{ "comment" => nil, "key" => "vwap", "value" => "undefined" }, %{ "comment" => nil, "key" => "open", "value" => "open" }, %{ "comment" => nil, "key" => "close", "value" => "last" }, %{ "comment" => nil, "key" => "last", "value" => "last" }, %{ "comment" => nil, "key" => "previousClose", "value" => "undefined" }, %{ "comment" => nil, "key" => "change", "value" => "undefined" }, %{ "comment" => nil, "key" => "percentage", "value" => "undefined" }, %{ "comment" => nil, "key" => "average", "value" => "undefined" }, %{ "comment" => nil, "key" => "baseVolume", "value" => "baseVolume" }, %{ "comment" => nil, "key" => "quoteVolume", "value" => "quoteVolume" }, %{ "comment" => nil, "key" => "indexPrice", "value" => "this.safeString (ticker, 'indexPrice')" }, %{ "comment" => nil, "key" => "markPrice", "value" => "this.safeString (ticker, 'markPrice')" }, %{ "comment" => nil, "key" => "info", "value" => "ticker" } ], "name" => "parseTicker", "signature" => "parseTicker (ticker: Dict, market: Market = undefined): Ticker", "source" => "parseTicker (ticker: Dict, market: Market = undefined): Ticker {\n //\n // response similar for REST & WS\n //\n // {\n // instId: \"ADA-USDT\",\n // ts: \"1707736811486\",\n // last: \"0.5315\",\n // lastSize: \"4\",\n // askPrice: \"0.5318\",\n // askSize: \"248\",\n // bidPrice: \"0.5315\",\n // bidSize: \"63\",\n // open24h: \"0.5555\",\n // high24h: \"0.5563\",\n // low24h: \"0.5315\",\n // volCurrency24h: \"198560100\",\n // vol24h: \"1985601\",\n // }\n //\n const timestamp = this.safeInteger (ticker, 'ts');\n const marketId = this.safeString (ticker, 'instId');\n market = this.safeMarket (marketId, market, '-');\n const symbol = market['symbol'];\n const last = this.safeString (ticker, 'last');\n const open = this.safeString (ticker, 'open24h');\n const spot = this.safeBool (market, 'spot', false);\n const quoteVolume = spot ? this.safeString (ticker, 'volCurrency24h') : undefined;\n const baseVolume = this.safeString (ticker, 'vol24h');\n const high = this.safeString (ticker, 'high24h');\n const low = this.safeString (ticker, 'low24h');\n return this.safeTicker ({\n 'symbol': symbol,\n 'timestamp': timestamp,\n 'datetime': this.iso8601 (timestamp),\n 'high': high,\n 'low': low,\n 'bid': this.safeString (ticker, 'bidPrice'),\n 'bidVolume': this.safeString (ticker, 'bidSize'),\n 'ask': this.safeString (ticker, 'askPrice'),\n 'askVolume': this.safeString (ticker, 'askSize'),\n 'vwap': undefined,\n 'open': open,\n 'close': last,\n 'last': last,\n 'previousClose': undefined,\n 'change': undefined,\n 'percentage': undefined,\n 'average': undefined,\n 'baseVolume': baseVolume,\n 'quoteVolume': quoteVolume,\n 'indexPrice': this.safeString (ticker, 'indexPrice'),\n 'markPrice': this.safeString (ticker, 'markPrice'),\n 'info': ticker,\n }, market);\n }" }, %{ "comment" => nil, "examples" => [ "{\n \"tradeId\": \"3263934920\",\n \"instId\": \"LTC-USDT\",\n \"price\": \"67.87\",\n \"size\": \"1\",\n \"side\": \"buy\",\n \"ts\": \"1707232020854\"\n }", "{\n \"instId\": \"LTC-USDT\",\n \"tradeId\": \"1440847\",\n \"orderId\": \"2075705202\",\n \"fillPrice\": \"67.850000000000000000\",\n \"fillSize\": \"1.000000000000000000\",\n \"fillPnl\": \"0.000000000000000000\",\n \"side\": \"buy\",\n \"positionSide\": \"net\",\n \"fee\": \"0.040710000000000000\",\n \"ts\": \"1707224678878\",\n \"brokerId\": \"\"\n }" ], "line_end" => 809, "line_start" => 749, "mappings" => [ %{ "comment" => nil, "key" => "info", "value" => "trade" }, %{ "comment" => nil, "key" => "timestamp", "value" => "timestamp" }, %{ "comment" => nil, "key" => "datetime", "value" => "this.iso8601 (timestamp)" }, %{ "comment" => nil, "key" => "symbol", "value" => "symbol" }, %{ "comment" => nil, "key" => "id", "value" => "id" }, %{ "comment" => nil, "key" => "order", "value" => "orderId" }, %{ "comment" => nil, "key" => "type", "value" => "undefined" }, %{ "comment" => nil, "key" => "takerOrMaker", "value" => "undefined" }, %{ "comment" => nil, "key" => "side", "value" => "side" }, %{ "comment" => nil, "key" => "price", "value" => "price" }, %{ "comment" => nil, "key" => "amount", "value" => "amount" }, %{ "comment" => nil, "key" => "cost", "value" => "undefined" }, %{ "comment" => nil, "key" => "fee", "value" => "fee" } ], "name" => "parseTrade", "signature" => "parseTrade (trade: Dict, market: Market = undefined): Trade", "source" => "parseTrade (trade: Dict, market: Market = undefined): Trade {\n //\n // fetch trades (response similar for REST & WS)\n //\n // {\n // \"tradeId\": \"3263934920\",\n // \"instId\": \"LTC-USDT\",\n // \"price\": \"67.87\",\n // \"size\": \"1\",\n // \"side\": \"buy\",\n // \"ts\": \"1707232020854\"\n // }\n //\n // my trades\n // {\n // \"instId\": \"LTC-USDT\",\n // \"tradeId\": \"1440847\",\n // \"orderId\": \"2075705202\",\n // \"fillPrice\": \"67.850000000000000000\",\n // \"fillSize\": \"1.000000000000000000\",\n // \"fillPnl\": \"0.000000000000000000\",\n // \"side\": \"buy\",\n // \"positionSide\": \"net\",\n // \"fee\": \"0.040710000000000000\",\n // \"ts\": \"1707224678878\",\n // \"brokerId\": \"\"\n // }\n //\n const id = this.safeString (trade, 'tradeId');\n const marketId = this.safeString (trade, 'instId');\n market = this.safeMarket (marketId, market, '-');\n const symbol = market['symbol'];\n const timestamp = this.safeInteger (trade, 'ts');\n const price = this.safeString2 (trade, 'price', 'fillPrice');\n const amount = this.safeString2 (trade, 'size', 'fillSize');\n const side = this.safeString (trade, 'side');\n const orderId = this.safeString (trade, 'orderId');\n const feeCost = this.safeString (trade, 'fee');\n let fee = undefined;\n if (feeCost !== undefined) {\n fee = {\n 'cost': feeCost,\n 'currency': market['settle'],\n };\n }\n return this.safeTrade ({\n 'info': trade,\n 'timestamp': timestamp,\n 'datetime': this.iso8601 (timestamp),\n 'symbol': symbol,\n 'id': id,\n 'order': orderId,\n 'type': undefined,\n 'takerOrMaker': undefined,\n 'side': side,\n 'price': price,\n 'amount': amount,\n 'cost': undefined,\n 'fee': fee,\n }, market);\n }" }, %{ "comment" => nil, "examples" => [], "line_end" => 1147, "line_start" => 1137, "mappings" => [ %{ "comment" => nil, "key" => "info", "value" => "fee" }, %{ "comment" => nil, "key" => "symbol", "value" => "this.safeSymbol (undefined, market)" }, %{ "comment" => nil, "key" => "taker", "value" => "this.parseNumber (Precise.stringNeg (this.safeString2 (fee, 'taker', 'takerU')))" }, %{ "comment" => nil, "key" => "percentage", "value" => "undefined" }, %{ "comment" => nil, "key" => "tierBased", "value" => "undefined" } ], "name" => "parseTradingFee", "signature" => "parseTradingFee (fee: Dict, market: Market = undefined): TradingFeeInterface", "source" => "parseTradingFee (fee: Dict, market: Market = undefined): TradingFeeInterface {\n return {\n 'info': fee,\n 'symbol': this.safeSymbol (undefined, market),\n // blofin returns the fees as negative values opposed to other exchanges, so the sign needs to be flipped\n 'maker': this.parseNumber (Precise.stringNeg (this.safeString2 (fee, 'maker', 'makerU'))),\n 'taker': this.parseNumber (Precise.stringNeg (this.safeString2 (fee, 'taker', 'takerU'))),\n 'percentage': undefined,\n 'tierBased': undefined,\n };\n }" }, %{ "comment" => nil, "examples" => [ "{\n \"currency\": \"USDT\",\n \"chain\": \"TRC20\",\n \"address\": \"TGfJLtnsh3B9EqekFEBZ1nR14QanBUf5Bi\",\n \"txId\": \"892f4e0c32268b29b2e541ef30d32a30bbf10f902adcc4b1428319ed7c3758fd\",\n \"type\": \"0\",\n \"amount\": \"86.975843\",\n \"state\": \"1\",\n \"ts\": \"1703163304153\",\n \"tag\": null,\n \"confirm\": \"16\",\n \"depositId\": \"36c8e2a7ea184a219de72215a696acaf\"\n }", "{\n \"currency\": \"USDT\",\n \"chain\": \"TRC20\",\n \"address\": \"TYgB3sVXHPEDQUu288EG1uMFh9Pk2swLgW\",\n \"txId\": \"1fd5ac52df414d7ea66194cadd9a5b4d2422c2b9720037f66d98207f9858fd96\",\n \"type\": \"0\",\n \"amount\": \"9\",\n \"fee\": \"1\",\n \"feeCurrency\": \"USDT\",\n \"state\": \"3\",\n \"clientId\": null,\n \"ts\": \"1707217439351\",\n \"tag\": null,\n \"memo\": null,\n \"withdrawId\": \"e0768698cfdf4aee8e54654c3775914b\"\n }" ], "line_end" => 1848, "line_start" => 1764, "mappings" => [ %{ "comment" => nil, "key" => "info", "value" => "transaction" }, %{ "comment" => nil, "key" => "id", "value" => "id" }, %{ "comment" => nil, "key" => "currency", "value" => "code" }, %{ "comment" => nil, "key" => "amount", "value" => "amount" }, %{ "comment" => nil, "key" => "network", "value" => "undefined" }, %{ "comment" => nil, "key" => "addressFrom", "value" => "undefined" }, %{ "comment" => nil, "key" => "addressTo", "value" => "addressTo" }, %{ "comment" => nil, "key" => "address", "value" => "address" }, %{ "comment" => nil, "key" => "tagFrom", "value" => "undefined" }, %{ "comment" => nil, "key" => "tagTo", "value" => "tagTo" }, %{ "comment" => nil, "key" => "tag", "value" => "tagTo" }, %{ "comment" => nil, "key" => "status", "value" => "status" }, %{ "comment" => nil, "key" => "type", "value" => "type" }, %{ "comment" => nil, "key" => "updated", "value" => "undefined" }, %{ "comment" => nil, "key" => "txid", "value" => "txid" }, %{ "comment" => nil, "key" => "timestamp", "value" => "timestamp" }, %{ "comment" => nil, "key" => "datetime", "value" => "this.iso8601 (timestamp)" }, %{ "comment" => nil, "key" => "internal", "value" => "undefined" }, %{ "comment" => nil, "key" => "comment", "value" => "undefined" }, %{ "comment" => nil, "key" => "fee", "value" => "{\n 'currency': feeCode,\n 'cost': feeCost,\n }" } ], "name" => "parseTransaction", "signature" => "parseTransaction (transaction: Dict, currency: Currency = undefined): Transaction", "source" => "parseTransaction (transaction: Dict, currency: Currency = undefined): Transaction {\n //\n //\n // fetchDeposits\n //\n // {\n // \"currency\": \"USDT\",\n // \"chain\": \"TRC20\",\n // \"address\": \"TGfJLtnsh3B9EqekFEBZ1nR14QanBUf5Bi\",\n // \"txId\": \"892f4e0c32268b29b2e541ef30d32a30bbf10f902adcc4b1428319ed7c3758fd\",\n // \"type\": \"0\",\n // \"amount\": \"86.975843\",\n // \"state\": \"1\",\n // \"ts\": \"1703163304153\",\n // \"tag\": null,\n // \"confirm\": \"16\",\n // \"depositId\": \"36c8e2a7ea184a219de72215a696acaf\"\n // }\n // fetchWithdrawals\n // {\n // \"currency\": \"USDT\",\n // \"chain\": \"TRC20\",\n // \"address\": \"TYgB3sVXHPEDQUu288EG1uMFh9Pk2swLgW\",\n // \"txId\": \"1fd5ac52df414d7ea66194cadd9a5b4d2422c2b9720037f66d98207f9858fd96\",\n // \"type\": \"0\",\n // \"amount\": \"9\",\n // \"fee\": \"1\",\n // \"feeCurrency\": \"USDT\",\n // \"state\": \"3\",\n // \"clientId\": null,\n // \"ts\": \"1707217439351\",\n // \"tag\": null,\n // \"memo\": null,\n // \"withdrawId\": \"e0768698cfdf4aee8e54654c3775914b\"\n // }\n //\n let type = undefined;\n let id = undefined;\n const withdrawalId = this.safeString (transaction, 'withdrawId');\n const depositId = this.safeString (transaction, 'depositId');\n const addressTo = this.safeString (transaction, 'address');\n const address = addressTo;\n const tagTo = this.safeString (transaction, 'tag');\n if (withdrawalId !== undefined) {\n type = 'withdrawal';\n id = withdrawalId;\n } else {\n id = depositId;\n type = 'deposit';\n }\n const currencyId = this.safeString (transaction, 'currency');\n const code = this.safeCurrencyCode (currencyId);\n const amount = this.safeNumber (transaction, 'amount');\n const status = this.parseTransactionStatus (this.safeString (transaction, 'state'));\n const txid = this.safeString (transaction, 'txId');\n const timestamp = this.safeInteger (transaction, 'ts');\n const feeCurrencyId = this.safeString (transaction, 'feeCurrency');\n const feeCode = this.safeCurrencyCode (feeCurrencyId);\n const feeCost = this.safeNumber (transaction, 'fee');\n return {\n 'info': transaction,\n 'id': id,\n 'currency': code,\n 'amount': amount,\n 'network': undefined,\n 'addressFrom': undefined,\n 'addressTo': addressTo,\n 'address': address,\n 'tagFrom': undefined,\n 'tagTo': tagTo,\n 'tag': tagTo,\n 'status': status,\n 'type': type,\n 'updated': undefined,\n 'txid': txid,\n 'timestamp': timestamp,\n 'datetime': this.iso8601 (timestamp),\n 'internal': undefined,\n 'comment': undefined,\n 'fee': {\n 'currency': feeCode,\n 'cost': feeCost,\n },\n };\n }" }, %{ "comment" => nil, "examples" => [], "line_end" => 1858, "line_start" => 1850, "mappings" => [], "name" => "parseTransactionStatus", "signature" => "parseTransactionStatus (status: Str)", "source" => "parseTransactionStatus (status: Str) {\n const statuses: Dict = {\n '0': 'pending',\n '1': 'ok',\n '2': 'failed',\n '3': 'pending',\n };\n return this.safeString (statuses, status, status);\n }" }, %{ "comment" => nil, "examples" => [], "line_end" => 2027, "line_start" => 2014, "mappings" => [ %{ "comment" => nil, "key" => "info", "value" => "transfer" }, %{ "comment" => nil, "key" => "id", "value" => "id" }, %{ "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: Dict, currency: Currency = undefined): TransferEntry", "source" => "parseTransfer (transfer: Dict, currency: Currency = undefined): TransferEntry {\n const id = this.safeString (transfer, 'transferId');\n return {\n 'info': transfer,\n 'id': id,\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: "/api/v1/", pro: true, quote_json_numbers: nil, rate_limits: %{ interval_ms: 100, period: 1000, requests: 10, rolling_window_size: 60000 }, raw_endpoints: %{ private: [ %{ auth: false, cost: 1, method: :get, path: "/account/balance" }, %{ auth: false, cost: 1, method: :get, path: "/account/batch-leverage-info" }, %{ auth: false, cost: 1, method: :get, path: "/account/leverage-info" }, %{ auth: false, cost: 1, method: :get, path: "/account/margin-mode" }, %{ auth: false, cost: 1, method: :get, path: "/account/position-mode" }, %{ auth: false, cost: 1, method: :get, path: "/account/positions" }, %{ auth: false, cost: 1, method: :get, path: "/affiliate/basic" }, %{ auth: false, cost: 1, method: :get, path: "/asset/balances" }, %{ auth: false, cost: 1, method: :get, path: "/asset/bills" }, %{ auth: false, cost: 1, method: :get, path: "/asset/deposit-history" }, %{ auth: false, cost: 1, method: :get, path: "/asset/withdrawal-history" }, %{ auth: false, cost: 1, method: :get, path: "/copytrading/account/balance" }, %{ auth: false, cost: 1, method: :get, path: "/copytrading/account/leverage-info" }, %{ auth: false, cost: 1, method: :get, path: "/copytrading/account/position-mode" }, %{ auth: false, cost: 1, method: :get, path: "/copytrading/account/positions-by-contract" }, %{ auth: false, cost: 1, method: :get, path: "/copytrading/account/positions-by-order" }, %{ auth: false, cost: 1, method: :get, path: "/copytrading/account/positions-details-by-order" }, %{ auth: false, cost: 1, method: :get, path: "/copytrading/instruments" }, %{ auth: false, cost: 1, method: :get, path: "/copytrading/trade/orders-history" }, %{ auth: false, cost: 1, method: :get, path: "/copytrading/trade/orders-pending" }, %{ auth: false, cost: 1, method: :get, path: "/copytrading/trade/pending-tpsl-by-contract" }, %{ auth: false, cost: 1, method: :get, path: "/copytrading/trade/pending-tpsl-by-order" }, %{ auth: false, cost: 1, method: :get, path: "/copytrading/trade/position-history-by-order" }, %{ auth: false, cost: 1, method: :get, path: "/trade/fills-history" }, %{ auth: false, cost: 1, method: :get, path: "/trade/order/price-range" }, %{ auth: false, cost: 1, method: :get, path: "/trade/orders-algo-history" }, %{ auth: false, cost: 1, method: :get, path: "/trade/orders-algo-pending" }, %{ auth: false, cost: 1, method: :get, path: "/trade/orders-history" }, %{ auth: false, cost: 1, method: :get, path: "/trade/orders-pending" }, %{ auth: false, cost: 1, method: :get, path: "/trade/orders-tpsl-history" }, %{ auth: false, cost: 1, method: :get, path: "/trade/orders-tpsl-pending" }, %{ auth: false, cost: 1, method: :get, path: "/user/query-apikey" }, %{ auth: false, cost: 1, method: :post, path: "/account/set-leverage" }, %{ auth: false, cost: 1, method: :post, path: "/account/set-margin-mode" }, %{ auth: false, cost: 1, method: :post, path: "/account/set-position-mode" }, %{ auth: false, cost: 1, method: :post, path: "/asset/transfer" }, %{ auth: false, cost: 1, method: :post, path: "/copytrading/account/set-leverage" }, %{ auth: false, cost: 1, method: :post, path: "/copytrading/account/set-position-mode" }, %{ auth: false, cost: 1, method: :post, path: "/copytrading/trade/cancel-order" }, %{ auth: false, cost: 1, method: :post, path: "/copytrading/trade/cancel-tpsl-by-contract" }, %{ auth: false, cost: 1, method: :post, path: "/copytrading/trade/cancel-tpsl-by-order" }, %{ auth: false, cost: 1, method: :post, path: "/copytrading/trade/close-position-by-contract" }, %{ auth: false, cost: 1, method: :post, path: "/copytrading/trade/close-position-by-order" }, %{ auth: false, cost: 1, method: :post, path: "/copytrading/trade/place-order" }, %{ auth: false, cost: 1, method: :post, path: "/copytrading/trade/place-tpsl-by-contract" }, %{ auth: false, cost: 1, method: :post, path: "/copytrading/trade/place-tpsl-by-order" }, %{ auth: false, cost: 1, method: :post, path: "/trade/batch-orders" }, %{ auth: false, cost: 1, method: :post, path: "/trade/cancel-algo" }, %{ auth: false, cost: 1, method: :post, path: "/trade/cancel-batch-orders" }, %{ auth: false, cost: 1, method: :post, path: "/trade/cancel-order" }, %{ auth: false, cost: 1, method: :post, path: "/trade/cancel-tpsl" }, %{ auth: false, cost: 1, method: :post, path: "/trade/close-position" }, %{ auth: false, cost: 1, method: :post, path: "/trade/order" }, %{ auth: false, cost: 1, method: :post, path: "/trade/order-algo" }, %{ auth: false, cost: 1, method: :post, path: "/trade/order-tpsl" } ], public: [ %{ auth: false, cost: 1, method: :get, path: "/market/books" }, %{ auth: false, cost: 1, method: :get, path: "/market/candles" }, %{ auth: false, cost: 1, method: :get, path: "/market/funding-rate" }, %{ auth: false, cost: 1, method: :get, path: "/market/funding-rate-history" }, %{ auth: false, cost: 1, method: :get, path: "/market/instruments" }, %{ auth: false, cost: 1, method: :get, path: "/market/mark-price" }, %{ auth: false, cost: 1, method: :get, path: "/market/tickers" }, %{ auth: false, cost: 1, method: :get, path: "/market/trades" } ] }, required_credentials: %{ api_key: true, password: true, secret: true, uid: false }, requires_eddsa: false, response_error: %{ code_field: "code", field: "code", message_field: "msg", success_values: [ "0" ], type: :success_code }, signing: %{ api_key_header: "ACCESS-KEY", confidence: :high, has_passphrase: true, passphrase_header: "ACCESS-PASSPHRASE", pattern: :hmac_sha256_passphrase_signed, signature_header: "ACCESS-SIGN", timestamp_header: "ACCESS-TIMESTAMP" }, spec_format_version: 1, status: %{ "eta" => nil, "status" => "ok", "updated" => nil, "url" => nil }, symbol_format: nil, symbol_formats: %{ precision_mode: 4, sample_limits: %{ "amount" => %{ "min" => 1 }, "cost" => %{}, "price" => %{} }, sample_precision: %{ "amount" => 1, "price" => 0.1 }, swap: %{ base: "BTC", base_id: "BTC", case: :upper, contract: true, contract_size: 0.0001, id: "BTC-USDC", inverse: false, limits: %{ "amount" => %{ "min" => 1 }, "cost" => %{}, "leverage" => %{ "max" => 125, "min" => 1 }, "price" => %{} }, linear: true, maker: 0.0002, precision: %{ "amount" => 1, "price" => 0.1 }, quote: "USDC", quote_id: "USDC", separator: "-", settle: "USDC", settle_id: "USDC", symbol: "BTC/USDC:USDC", taker: 0.0006 } }, symbol_patterns: %{ swap: %{ case: :upper, component_order: nil, date_format: nil, pattern: :implicit, separator: "-", suffix: nil } }, timeframes: %{ "12h" => "12H", "15m" => "15m", "1M" => "1M", "1d" => "1D", "1h" => "1H", "1m" => "1m", "1w" => "1W", "2h" => "2H", "30m" => "30m", "3d" => "3D", "3m" => "3m", "4h" => "4H", "5m" => "5m", "6h" => "6H", "8h" => "8H" }, url_strategy: %{ detected_from: "sign_method", pattern: :api_version_slash, prefix: "/api/v1/" }, urls: %{ api: "https://openapi.blofin.com", api_sections: %{ "rest" => "https://openapi.blofin.com" }, doc: "https://blofin.com/docs", other: nil, sandbox: %{ "rest" => "https://demo-trading-openapi.blofin.com" }, www: "https://www.blofin.com" }, version: "v1", ws: %{ auth: %{ algorithm: :sha256, encoding: :base64, market_specific: false, message_format: :op_args, op_field: "op", op_value: "login", pattern: :generic_hmac, payload_format: "custom", requires_passphrase: true, timestamp_unit: :milliseconds }, channel_templates: %{ watch_balance: %{ auth_required: true, market_id_format: :native, params: [], pattern: :topic_based, separator: "." }, watch_bids_asks: %{ channel_name: "tickers", market_id_format: :native, params: [], pattern: :topic_based, separator: "." }, watch_funding_rate: %{ market_id_format: :native, params: [], pattern: :topic_based, separator: "." }, watch_ohlcv: %{ channel_name: "candle", market_id_format: :native, params: [ %{ "default" => nil, "name" => "limit" } ], pattern: :topic_based, separator: "." }, watch_ohlcv_for_symbols: %{ channel_name: "candle", market_id_format: :native, params: [ %{ "default" => nil, "name" => "limit" } ], pattern: :topic_based, separator: "." }, watch_order_book: %{ market_id_format: :native, params: [ %{ "default" => nil, "name" => "limit" } ], pattern: :topic_based, separator: "." }, watch_order_book_for_symbols: %{ market_id_format: :native, params: [ %{ "default" => nil, "name" => "limit" } ], pattern: :topic_based, separator: "." }, watch_orders: %{ auth_required: true, market_id_format: :native, params: [ %{ "default" => nil, "name" => "limit" } ], pattern: :topic_based, separator: "." }, watch_orders_for_symbols: %{ auth_required: true, market_id_format: :native, params: [ %{ "default" => nil, "name" => "limit" } ], pattern: :topic_based, separator: "." }, watch_positions: %{ auth_required: true, channel_name: "positions", market_id_format: :native, params: [ %{ "default" => nil, "name" => "limit" } ], pattern: :topic_based, separator: "." }, watch_ticker: %{ channel_name: "tickers", market_id_format: :native, params: [], pattern: :topic_based, separator: "." }, watch_tickers: %{ channel_name: "tickers", market_id_format: :native, params: [], pattern: :topic_based, separator: "." }, watch_trades: %{ channel_name: "trades", market_id_format: :native, params: [ %{ "default" => nil, "name" => "limit" } ], pattern: :topic_based, separator: "." }, watch_trades_for_symbols: %{ channel_name: "trades", market_id_format: :native, params: [ %{ "default" => nil, "name" => "limit" } ], pattern: :topic_based, separator: "." } }, has: %{ watch_balance: nil, watch_bids_asks: true, watch_liquidations: nil, watch_liquidations_for_symbols: nil, watch_my_liquidations: nil, watch_my_liquidations_for_symbols: nil, watch_my_trades: nil, watch_ohlcv: true, watch_ohlcv_for_symbols: true, watch_order_book: true, watch_order_book_for_symbols: true, watch_orders: true, watch_orders_for_symbols: true, watch_position: nil, watch_positions: true, watch_status: nil, watch_ticker: true, watch_tickers: true, watch_trades: true, watch_trades_for_symbols: true }, hostname: "www.blofin.com", message_patterns: [ %{ args_field: "args", format: :op, keys: [ "args", "op" ], kind_field: "op", kind_value: "login", sources: [ :send, :watch ] }, %{ args_field: "args", format: :op, keys: [ "args", "op" ], kind_field: "op", kind_value: "subscribe", sources: [ :send, :watch_multiple ] }, %{ format: :string, sources: [ :ping ] } ], options: %{ "watchOrderBook" => %{ "channel" => "books" }, "watchOrderBookForSymbols" => %{ "channel" => "books" } }, streaming: %{ keep_alive: 25000 }, subscription_config: %{ args_field: "args", args_format: :string_list, market_id_format: :native, op_field: "op", separator: "." }, subscription_pattern: :op_subscribe, test_urls: %{ "swap" => %{ "private" => "wss://demo-trading-openapi.blofin.com/ws/private", "public" => "wss://demo-trading-openapi.blofin.com/ws/public" } }, urls: %{ "swap" => %{ "private" => "wss://openapi.blofin.com/ws/private", "public" => "wss://openapi.blofin.com/ws/public" } }, watch_methods: [ "watchBalance", "watchBidsAsks", "watchFundingRate", "watchOHLCV", "watchOHLCVForSymbols", "watchOrderBook", "watchOrderBookForSymbols", "watchOrders", "watchOrdersForSymbols", "watchPositions", "watchTicker", "watchTickers", "watchTrades", "watchTradesForSymbols" ] } }