UNPKG

ccxt

Version:

A JavaScript / TypeScript / Python / C# / PHP cryptocurrency trading library with support for 100+ exchanges

1,085 lines (1,083 loc) • 196 kB
'use strict'; var hashkey$1 = require('./abstract/hashkey.js'); var errors = require('./base/errors.js'); var Precise = require('./base/Precise.js'); var number = require('./base/functions/number.js'); var sha256 = require('./static_dependencies/noble-hashes/sha256.js'); // ---------------------------------------------------------------------------- // --------------------------------------------------------------------------- /** * @class hashkey * @augments Exchange */ class hashkey extends hashkey$1 { describe() { return this.deepExtend(super.describe(), { 'id': 'hashkey', 'name': 'HashKey Global', 'countries': ['BM'], 'rateLimit': 100, 'version': 'v1', 'certified': true, 'pro': true, 'has': { 'CORS': undefined, 'spot': true, 'margin': false, 'swap': false, 'future': false, 'option': false, 'addMargin': false, 'cancelAllOrders': true, 'cancelAllOrdersAfter': false, 'cancelOrder': true, 'cancelOrders': true, 'cancelWithdraw': false, 'closePosition': false, 'createConvertTrade': false, 'createDepositAddress': false, 'createMarketBuyOrderWithCost': true, 'createMarketOrder': true, 'createMarketOrderWithCost': false, 'createMarketSellOrderWithCost': false, 'createOrder': true, 'createOrderWithTakeProfitAndStopLoss': false, 'createReduceOnlyOrder': true, 'createStopLimitOrder': true, 'createStopLossOrder': false, 'createStopMarketOrder': true, 'createStopOrder': true, 'createTakeProfitOrder': false, 'createTrailingAmountOrder': false, 'createTrailingPercentOrder': false, 'createTriggerOrder': true, 'fetchAccounts': true, 'fetchBalance': true, 'fetchCanceledAndClosedOrders': true, 'fetchCanceledOrders': true, 'fetchClosedOrder': true, 'fetchClosedOrders': false, 'fetchConvertCurrencies': false, 'fetchConvertQuote': false, 'fetchConvertTrade': false, 'fetchConvertTradeHistory': false, 'fetchCurrencies': true, 'fetchDepositAddress': true, 'fetchDepositAddresses': false, 'fetchDepositAddressesByNetwork': false, 'fetchDeposits': true, 'fetchDepositsWithdrawals': false, 'fetchFundingHistory': false, 'fetchFundingRate': true, 'fetchFundingRateHistory': true, 'fetchFundingRates': true, 'fetchIndexOHLCV': false, 'fetchLedger': true, 'fetchLeverage': true, 'fetchLeverageTiers': true, 'fetchMarginAdjustmentHistory': false, 'fetchMarginMode': false, 'fetchMarketLeverageTiers': 'emulated', 'fetchMarkets': true, 'fetchMarkOHLCV': false, 'fetchMyTrades': true, 'fetchOHLCV': true, 'fetchOpenInterestHistory': false, 'fetchOpenOrder': false, 'fetchOpenOrders': true, 'fetchOrder': true, 'fetchOrderBook': true, 'fetchOrders': false, 'fetchOrderTrades': false, 'fetchPosition': false, 'fetchPositionHistory': false, 'fetchPositionMode': false, 'fetchPositions': true, 'fetchPositionsForSymbol': true, 'fetchPositionsHistory': false, 'fetchPremiumIndexOHLCV': false, 'fetchStatus': true, 'fetchTicker': true, 'fetchTickers': true, 'fetchTime': true, 'fetchTrades': true, 'fetchTradingFee': true, 'fetchTradingFees': true, 'fetchTransactions': false, 'fetchTransfers': false, 'fetchWithdrawals': true, 'reduceMargin': false, 'sandbox': false, 'setLeverage': true, 'setMargin': false, 'setPositionMode': false, 'transfer': true, 'withdraw': true, }, 'timeframes': { '1m': '1m', '3m': '3m', '5m': '5m', '15m': '15m', '30m': '30m', '1h': '1h', '2h': '2h', '4h': '4h', '6h': '6h', '8h': '8h', '12h': '12h', '1d': '1d', '1w': '1w', '1M': '1M', }, 'urls': { 'logo': 'https://github.com/user-attachments/assets/6dd6127b-cc19-4a13-9b29-a98d81f80e98', 'api': { 'public': 'https://api-glb.hashkey.com', 'private': 'https://api-glb.hashkey.com', }, 'test': { 'public': 'https://api-glb.sim.hashkeydev.com', 'private': 'https://api-glb.sim.hashkeydev.com', }, 'www': 'https://global.hashkey.com/', 'doc': 'https://hashkeyglobal-apidoc.readme.io/', 'fees': 'https://support.global.hashkey.com/hc/en-us/articles/13199900083612-HashKey-Global-Fee-Structure', 'referral': 'https://global.hashkey.com/en-US/register/invite?invite_code=82FQUN', }, 'api': { 'public': { 'get': { 'api/v1/exchangeInfo': 5, 'quote/v1/depth': 1, 'quote/v1/trades': 1, 'quote/v1/klines': 1, 'quote/v1/ticker/24hr': 1, 'quote/v1/ticker/price': 1, 'quote/v1/ticker/bookTicker': 1, 'quote/v1/depth/merged': 1, 'quote/v1/markPrice': 1, 'quote/v1/index': 1, 'api/v1/futures/fundingRate': 1, 'api/v1/futures/historyFundingRate': 1, 'api/v1/ping': 1, 'api/v1/time': 1, }, }, 'private': { 'get': { 'api/v1/spot/order': 1, 'api/v1/spot/openOrders': 1, 'api/v1/spot/tradeOrders': 5, 'api/v1/futures/leverage': 1, 'api/v1/futures/order': 1, 'api/v1/futures/openOrders': 1, 'api/v1/futures/userTrades': 1, 'api/v1/futures/positions': 1, 'api/v1/futures/historyOrders': 1, 'api/v1/futures/balance': 1, 'api/v1/futures/liquidationAssignStatus': 1, 'api/v1/futures/riskLimit': 1, 'api/v1/futures/commissionRate': 1, 'api/v1/futures/getBestOrder': 1, 'api/v1/account/vipInfo': 1, 'api/v1/account': 1, 'api/v1/account/trades': 5, 'api/v1/account/type': 5, 'api/v1/account/checkApiKey': 1, 'api/v1/account/balanceFlow': 5, 'api/v1/spot/subAccount/openOrders': 1, 'api/v1/spot/subAccount/tradeOrders': 1, 'api/v1/subAccount/trades': 1, 'api/v1/futures/subAccount/openOrders': 1, 'api/v1/futures/subAccount/historyOrders': 1, 'api/v1/futures/subAccount/userTrades': 1, 'api/v1/account/deposit/address': 1, 'api/v1/account/depositOrders': 1, 'api/v1/account/withdrawOrders': 1, }, 'post': { 'api/v1/userDataStream': 1, 'api/v1/spot/orderTest': 1, 'api/v1/spot/order': 1, 'api/v1.1/spot/order': 1, 'api/v1/spot/batchOrders': 5, 'api/v1/futures/leverage': 1, 'api/v1/futures/order': 1, 'api/v1/futures/position/trading-stop': 3, 'api/v1/futures/batchOrders': 5, 'api/v1/account/assetTransfer': 1, 'api/v1/account/authAddress': 1, 'api/v1/account/withdraw': 1, }, 'put': { 'api/v1/userDataStream': 1, }, 'delete': { 'api/v1/spot/order': 1, 'api/v1/spot/openOrders': 5, 'api/v1/spot/cancelOrderByIds': 5, 'api/v1/futures/order': 1, 'api/v1/futures/batchOrders': 1, 'api/v1/futures/cancelOrderByIds': 1, 'api/v1/userDataStream': 1, }, }, }, 'fees': { 'trading': { 'spot': { 'tierBased': true, 'percentage': true, 'feeSide': 'get', 'maker': this.parseNumber('0.0012'), 'taker': this.parseNumber('0.0012'), 'tiers': { 'maker': [ [this.parseNumber('0'), this.parseNumber('0.0012')], [this.parseNumber('1000000'), this.parseNumber('0.00080')], [this.parseNumber('5000000'), this.parseNumber('0.00070')], [this.parseNumber('10000000'), this.parseNumber('0.00060')], [this.parseNumber('50000000'), this.parseNumber('0.00040')], [this.parseNumber('200000000'), this.parseNumber('0.00030')], [this.parseNumber('400000000'), this.parseNumber('0.00010')], [this.parseNumber('800000000'), this.parseNumber('0.00')], ], 'taker': [ [this.parseNumber('0'), this.parseNumber('0.0012')], [this.parseNumber('1000000'), this.parseNumber('0.00090')], [this.parseNumber('5000000'), this.parseNumber('0.00085')], [this.parseNumber('10000000'), this.parseNumber('0.00075')], [this.parseNumber('50000000'), this.parseNumber('0.00065')], [this.parseNumber('200000000'), this.parseNumber('0.00045')], [this.parseNumber('400000000'), this.parseNumber('0.00040')], [this.parseNumber('800000000'), this.parseNumber('0.00035')], ], }, }, 'swap': { 'tierBased': true, 'percentage': true, 'feeSide': 'get', 'maker': this.parseNumber('0.00025'), 'taker': this.parseNumber('0.00060'), 'tiers': { 'maker': [ [this.parseNumber('0'), this.parseNumber('0.00025')], [this.parseNumber('1000000'), this.parseNumber('0.00016')], [this.parseNumber('5000000'), this.parseNumber('0.00014')], [this.parseNumber('10000000'), this.parseNumber('0.00012')], [this.parseNumber('50000000'), this.parseNumber('0.000080')], [this.parseNumber('200000000'), this.parseNumber('0.000060')], [this.parseNumber('400000000'), this.parseNumber('0.000020')], [this.parseNumber('800000000'), this.parseNumber('0.00')], ], 'taker': [ [this.parseNumber('0'), this.parseNumber('0.00060')], [this.parseNumber('1000000'), this.parseNumber('0.00050')], [this.parseNumber('5000000'), this.parseNumber('0.00045')], [this.parseNumber('10000000'), this.parseNumber('0.00040')], [this.parseNumber('50000000'), this.parseNumber('0.00035')], [this.parseNumber('200000000'), this.parseNumber('0.00030')], [this.parseNumber('400000000'), this.parseNumber('0.00025')], [this.parseNumber('800000000'), this.parseNumber('0.00020')], ], }, }, }, }, 'options': { 'broker': '10000700011', 'recvWindow': undefined, 'sandboxMode': false, 'networks': { 'BTC': 'BTC', 'ERC20': 'ETH', 'AVAX': 'AvalancheC', 'SOL': 'Solana', 'MATIC': 'Polygon', 'ATOM': 'Cosmos', 'DOT': 'Polkadot', 'LTC': 'LTC', 'OPTIMISM': 'Optimism', 'ARB': 'Arbitrum', 'DOGE': 'Dogecoin', 'TRC20': 'Tron', 'ZKSYNC': 'zkSync', 'TON': 'TON', 'KLAYTN': 'Klaytn', 'MERLINCHAIN': 'Merlin Chain', }, 'networksById': { 'BTC': 'BTC', 'Bitcoin': 'BTC', 'ETH': 'ERC20', 'ERC20': 'ERC20', 'AvalancheC': 'AVAX', 'AVAX C-Chain': 'AVAX', 'Solana': 'SOL', 'Cosmos': 'ATOM', 'Arbitrum': 'ARB', 'Polygon': 'MATIC', 'Optimism': 'OPTIMISM', 'Polkadot': 'DOT', 'LTC': 'LTC', 'Litecoin': 'LTC', 'Dogecoin': 'DOGE', 'Merlin Chain': 'MERLINCHAIN', 'zkSync': 'ZKSYNC', 'TRC20': 'TRC20', 'Tron': 'TRC20', 'TON': 'TON', 'BSC(BEP20)': 'BSC', 'Klaytn': 'KLAYTN', }, 'defaultNetwork': 'ERC20', }, 'features': { 'default': { 'sandbox': true, 'createOrder': { 'marginMode': false, 'triggerPrice': false, 'triggerPriceType': undefined, 'triggerDirection': false, 'stopLossPrice': false, 'takeProfitPrice': false, 'attachedStopLossTakeProfit': undefined, 'timeInForce': { 'IOC': true, 'FOK': true, 'PO': true, 'GTD': false, }, 'hedged': false, 'trailing': false, 'leverage': false, 'marketBuyByCost': true, 'marketBuyRequiresPrice': true, 'selfTradePrevention': true, 'iceberg': false, }, 'createOrders': { 'max': 20, }, 'fetchMyTrades': { 'marginMode': false, 'limit': 1000, 'daysBack': 30, 'untilDays': 30, 'symbolRequired': false, }, 'fetchOrder': { 'marginMode': false, 'trigger': false, 'trailing': false, 'symbolRequired': false, }, 'fetchOpenOrders': { 'marginMode': false, 'limit': 1000, 'trigger': false, 'trailing': false, 'symbolRequired': false, }, 'fetchOrders': undefined, 'fetchClosedOrders': undefined, 'fetchOHLCV': { 'limit': 1000, }, }, 'spot': { 'extends': 'default', }, 'forDerivatives': { 'extends': 'default', 'createOrder': { 'triggerPrice': true, 'selfTradePrevention': true, }, 'fetchOpenOrders': { 'trigger': true, 'limit': 500, }, }, 'swap': { 'linear': { 'extends': 'forDerivatives', }, 'inverse': undefined, }, 'future': { 'linear': undefined, 'inverse': undefined, }, }, 'commonCurrencies': {}, 'exceptions': { 'exact': { '0001': errors.BadRequest, '0002': errors.AuthenticationError, '0003': errors.RateLimitExceeded, '0102': errors.AuthenticationError, '0103': errors.AuthenticationError, '0104': errors.PermissionDenied, '0201': errors.ExchangeError, '0202': errors.PermissionDenied, '0206': errors.BadRequest, '0207': errors.BadRequest, '0209': errors.BadRequest, '0210': errors.BadRequest, '0211': errors.OrderNotFound, '0401': errors.InsufficientFunds, '0402': errors.BadRequest, '-1000': errors.ExchangeError, '-1001': errors.ExchangeError, '-100010': errors.BadSymbol, '-100012': errors.BadSymbol, '-1002': errors.AuthenticationError, '-1004': errors.BadRequest, '-1005': errors.PermissionDenied, '-1006': errors.ExchangeError, '-1007': errors.RequestTimeout, '-1014': errors.InvalidOrder, '-1015': errors.InvalidOrder, '-1020': errors.OperationRejected, '-1021': errors.InvalidNonce, '-1024': errors.BadRequest, '-1101': errors.ExchangeNotAvailable, '-1115': errors.InvalidOrder, '-1117': errors.InvalidOrder, '-1123': errors.InvalidOrder, '-1124': errors.InvalidOrder, '-1126': errors.InvalidOrder, '-1129': errors.BadRequest, '-1130': errors.BadRequest, '-1132': errors.BadRequest, '-1133': errors.BadRequest, '-1135': errors.BadRequest, '-1136': errors.BadRequest, '-1138': errors.InvalidOrder, '-1137': errors.InvalidOrder, '-1139': errors.OrderImmediatelyFillable, '-1140': errors.InvalidOrder, '-1141': errors.DuplicateOrderId, '-1142': errors.OrderNotFillable, '-1143': errors.OrderNotFound, '-1144': errors.OperationRejected, '-1145': errors.NotSupported, '-1146': errors.RequestTimeout, '-1147': errors.RequestTimeout, '-1148': errors.InvalidOrder, '-1149': errors.OperationRejected, '-1150': errors.OperationFailed, '-1151': errors.OperationRejected, '-1152': errors.AccountNotEnabled, '-1153': errors.InvalidOrder, '-1154': errors.InvalidOrder, '-1155': errors.OperationRejected, '-1156': errors.OperationFailed, '-1157': errors.OperationFailed, '-1158': errors.OperationFailed, '-1159': errors.AccountNotEnabled, '-1160': errors.AccountNotEnabled, '-1161': errors.OperationFailed, '-1162': errors.ContractUnavailable, '-1163': errors.InvalidAddress, '-1164': errors.OperationFailed, '-1165': errors.ArgumentsRequired, '-1166': errors.OperationRejected, '-1167': errors.BadRequest, '-1168': errors.BadRequest, '-1169': errors.PermissionDenied, '-1170': errors.PermissionDenied, '-1171': errors.PermissionDenied, '-1172': errors.BadRequest, '-1173': errors.BadRequest, '-1174': errors.PermissionDenied, '-1175': errors.BadRequest, '-1176': errors.BadRequest, '-1177': errors.InvalidOrder, '-1178': errors.AccountNotEnabled, '-1179': errors.AccountSuspended, '-1181': errors.ExchangeError, '-1193': errors.OperationRejected, '-1194': errors.OperationRejected, '-1195': errors.BadRequest, '-1196': errors.BadRequest, '-1200': errors.BadRequest, '-1201': errors.BadRequest, '-1202': errors.BadRequest, '-1203': errors.BadRequest, '-1204': errors.BadRequest, '-1205': errors.AccountNotEnabled, '-1206': errors.BadRequest, '-1207': errors.BadRequest, '-1208': errors.BadRequest, '-1209': errors.BadRequest, '-2001': errors.ExchangeNotAvailable, '-2002': errors.OperationFailed, '-2003': errors.OperationFailed, '-2004': errors.OperationFailed, '-2005': errors.RequestTimeout, '-2010': errors.OperationRejected, '-2011': errors.OperationRejected, '-2016': errors.OperationRejected, '-2017': errors.OperationRejected, '-2018': errors.OperationRejected, '-2019': errors.PermissionDenied, '-2020': errors.PermissionDenied, '-2021': errors.PermissionDenied, '-2022': errors.OperationRejected, '-2023': errors.AuthenticationError, '-2024': errors.AccountNotEnabled, '-2025': errors.AccountNotEnabled, '-2026': errors.BadRequest, '-2027': errors.OperationRejected, '-2028': errors.OperationRejected, '-2029': errors.OperationRejected, '-2030': errors.InsufficientFunds, '-2031': errors.NotSupported, '-2032': errors.OperationRejected, '-2033': errors.OperationFailed, '-2034': errors.InsufficientFunds, '-2035': errors.OperationRejected, '-2036': errors.NotSupported, '-2037': errors.ExchangeError, '-2038': errors.InsufficientFunds, '-2039': errors.NotSupported, '-2040': errors.ExchangeNotAvailable, '-2041': errors.BadRequest, '-2042': errors.OperationRejected, '-2043': errors.OperationRejected, '-2044': errors.BadRequest, '-2045': errors.BadRequest, '-2046': errors.BadRequest, '-2048': errors.BadRequest, '-2049': errors.BadRequest, '-2050': errors.BadRequest, '-2051': errors.OperationRejected, '-2052': errors.OperationRejected, '-2053': errors.OperationRejected, '-2054': errors.BadRequest, '-2055': errors.BadRequest, '-2056': errors.BadRequest, '-2057': errors.BadRequest, '-3117': errors.PermissionDenied, '-3143': errors.PermissionDenied, '-3144': errors.PermissionDenied, '-3145': errors.DDoSProtection, '-4001': errors.BadRequest, '-4002': errors.BadRequest, '-4003': errors.InsufficientFunds, '-4004': errors.BadRequest, '-4005': errors.BadRequest, '-4006': errors.AccountNotEnabled, '-4007': errors.NotSupported, '-4008': errors.AccountNotEnabled, '-4009': errors.PermissionDenied, '-4010': errors.PermissionDenied, '-4011': errors.ExchangeError, '-4012': errors.ExchangeError, '-4013': errors.OperationFailed, // Withdraw repeatly }, 'broad': {}, }, 'precisionMode': number.TICK_SIZE, }); } /** * @method * @name hashkey#fetchTime * @description fetches the current integer timestamp in milliseconds from the exchange server * @see https://hashkeyglobal-apidoc.readme.io/reference/check-server-time * @param {object} [params] extra parameters specific to the exchange API endpoint * @returns {int} the current integer timestamp in milliseconds from the exchange server */ async fetchTime(params = {}) { const response = await this.publicGetApiV1Time(params); // // { // "serverTime": 1721661553214 // } // return this.safeInteger(response, 'serverTime'); } /** * @method * @name hashkey#fetchStatus * @description the latest known information on the availability of the exchange API * @see https://hashkeyglobal-apidoc.readme.io/reference/test-connectivity * @param {object} [params] extra parameters specific to the exchange API endpoint * @returns {object} a [status structure]{@link https://docs.ccxt.com/#/?id=exchange-status-structure} */ async fetchStatus(params = {}) { const response = await this.publicGetApiV1Ping(params); // // {} // return { 'status': 'ok', 'updated': undefined, 'eta': undefined, 'url': undefined, 'info': response, }; } /** * @method * @name hashkey#fetchMarkets * @description retrieves data on all markets for the exchange * @see https://hashkeyglobal-apidoc.readme.io/reference/exchangeinfo * @param {object} [params] extra parameters specific to the exchange API endpoint * @param {string} [params.symbol] the id of the market to fetch * @returns {object[]} an array of objects representing market data */ async fetchMarkets(params = {}) { const request = {}; const response = await this.publicGetApiV1ExchangeInfo(this.extend(request, params)); // // { // "timezone": "UTC", // "serverTime": "1721661653952", // "brokerFilters": [], // "symbols": [ // { // "symbol": "BTCUSDT", // "symbolName": "BTCUSDT", // "status": "TRADING", // "baseAsset": "BTC", // "baseAssetName": "BTC", // "baseAssetPrecision": "0.00001", // "quoteAsset": "USDT", // "quoteAssetName": "USDT", // "quotePrecision": "0.0000001", // "retailAllowed": true, // "piAllowed": true, // "corporateAllowed": true, // "omnibusAllowed": true, // "icebergAllowed": false, // "isAggregate": false, // "allowMargin": false, // "filters": [ // { // "minPrice": "0.01", // "maxPrice": "100000.00000000", // "tickSize": "0.01", // "filterType": "PRICE_FILTER" // }, // { // "minQty": "0.00001", // "maxQty": "8", // "stepSize": "0.00001", // "marketOrderMinQty": "0.00001", // "marketOrderMaxQty": "4", // "filterType": "LOT_SIZE" // }, // { // "minNotional": "1", // "filterType": "MIN_NOTIONAL" // }, // { // "minAmount": "1", // "maxAmount": "400000", // "minBuyPrice": "0", // "marketOrderMinAmount": "1", // "marketOrderMaxAmount": "200000", // "filterType": "TRADE_AMOUNT" // }, // { // "maxSellPrice": "0", // "buyPriceUpRate": "0.1", // "sellPriceDownRate": "0.1", // "filterType": "LIMIT_TRADING" // }, // { // "buyPriceUpRate": "0.1", // "sellPriceDownRate": "0.1", // "filterType": "MARKET_TRADING" // }, // { // "noAllowMarketStartTime": "1710485700000", // "noAllowMarketEndTime": "1710486000000", // "limitOrderStartTime": "0", // "limitOrderEndTime": "0", // "limitMinPrice": "0", // "limitMaxPrice": "0", // "filterType": "OPEN_QUOTE" // } // ] // } // ], // "options": [ ], // "contracts": [ // { // "filters": [ // { // "minPrice": "0.1", // "maxPrice": "100000.00000000", // "tickSize": "0.1", // "filterType": "PRICE_FILTER" // }, // { // "minQty": "0.001", // "maxQty": "10", // "stepSize": "0.001", // "marketOrderMinQty": "0", // "marketOrderMaxQty": "0", // "filterType": "LOT_SIZE" // }, // { // "minNotional": "0", // "filterType": "MIN_NOTIONAL" // }, // { // "maxSellPrice": "999999", // "buyPriceUpRate": "0.05", // "sellPriceDownRate": "0.05", // "maxEntrustNum": 200, // "maxConditionNum": 200, // "filterType": "LIMIT_TRADING" // }, // { // "buyPriceUpRate": "0.05", // "sellPriceDownRate": "0.05", // "filterType": "MARKET_TRADING" // }, // { // "noAllowMarketStartTime": "0", // "noAllowMarketEndTime": "0", // "limitOrderStartTime": "0", // "limitOrderEndTime": "0", // "limitMinPrice": "0", // "limitMaxPrice": "0", // "filterType": "OPEN_QUOTE" // } // ], // "exchangeId": "301", // "symbol": "BTCUSDT-PERPETUAL", // "symbolName": "BTCUSDT-PERPETUAL", // "status": "TRADING", // "baseAsset": "BTCUSDT-PERPETUAL", // "baseAssetPrecision": "0.001", // "quoteAsset": "USDT", // "quoteAssetPrecision": "0.1", // "icebergAllowed": false, // "inverse": false, // "index": "USDT", // "marginToken": "USDT", // "marginPrecision": "0.0001", // "contractMultiplier": "0.001", // "underlying": "BTC", // "riskLimits": [ // { // "riskLimitId": "200000722", // "quantity": "1000.00", // "initialMargin": "0.10", // "maintMargin": "0.005", // "isWhite": false // }, // { // "riskLimitId": "200000723", // "quantity": "2000.00", // "initialMargin": "0.10", // "maintMargin": "0.01", // "isWhite": false // } // ] // } // ], // "coins": [ // { // "orgId": "9001", // "coinId": "BTC", // "coinName": "BTC", // "coinFullName": "Bitcoin", // "allowWithdraw": true, // "allowDeposit": true, // "tokenType": "CHAIN_TOKEN", // "chainTypes": [ // { // "chainType": "Bitcoin", // "withdrawFee": "0", // "minWithdrawQuantity": "0.002", // "maxWithdrawQuantity": "0", // "minDepositQuantity": "0.0005", // "allowDeposit": true, // "allowWithdraw": true // } // ] // } // ] // } // const spotMarkets = this.safeList(response, 'symbols', []); const swapMarkets = this.safeList(response, 'contracts', []); let markets = this.arrayConcat(spotMarkets, swapMarkets); if (this.isEmpty(markets)) { markets = [response]; // if user provides params.symbol the exchange returns a single object insted of list of objects } return this.parseMarkets(markets); } parseMarket(market) { // spot // { // "symbol": "BTCUSDT", // "symbolName": "BTCUSDT", // "status": "TRADING", // "baseAsset": "BTC", // "baseAssetName": "BTC", // "baseAssetPrecision": "0.00001", // "quoteAsset": "USDT", // "quoteAssetName": "USDT", // "quotePrecision": "0.0000001", // "retailAllowed": true, // "piAllowed": true, // "corporateAllowed": true, // "omnibusAllowed": true, // "icebergAllowed": false, // "isAggregate": false, // "allowMargin": false, // "filters": [ // { // "minPrice": "0.01", // "maxPrice": "100000.00000000", // "tickSize": "0.01", // "filterType": "PRICE_FILTER" // }, // { // "minQty": "0.00001", // "maxQty": "8", // "stepSize": "0.00001", // "marketOrderMinQty": "0.00001", // "marketOrderMaxQty": "4", // "filterType": "LOT_SIZE" // }, // { // "minNotional": "1", // "filterType": "MIN_NOTIONAL" // }, // { // "minAmount": "1", // "maxAmount": "400000", // "minBuyPrice": "0", // "marketOrderMinAmount": "1", // "marketOrderMaxAmount": "200000", // "filterType": "TRADE_AMOUNT" // }, // { // "maxSellPrice": "0", // "buyPriceUpRate": "0.1", // "sellPriceDownRate": "0.1", // "filterType": "LIMIT_TRADING" // }, // { // "buyPriceUpRate": "0.1", // "sellPriceDownRate": "0.1", // "filterType": "MARKET_TRADING" // }, // { // "noAllowMarketStartTime": "1710485700000", // "noAllowMarketEndTime": "1710486000000", // "limitOrderStartTime": "0", // "limitOrderEndTime": "0", // "limitMinPrice": "0", // "limitMaxPrice": "0", // "filterType": "OPEN_QUOTE" // } // ] // } // // swap // { // "filters": [ // { // "minPrice": "0.1", // "maxPrice": "100000.00000000", // "tickSize": "0.1", // "filterType": "PRICE_FILTER" // }, // { // "minQty": "0.001", // "maxQty": "10", // "stepSize": "0.001", // "marketOrderMinQty": "0", // "marketOrderMaxQty": "0", // "filterType": "LOT_SIZE" // }, // { // "minNotional": "0", // "filterType": "MIN_NOTIONAL" // }, // { // "maxSellPrice": "999999", // "buyPriceUpRate": "0.05", // "sellPriceDownRate": "0.05", // "maxEntrustNum": 200, // "maxConditionNum": 200, // "filterType": "LIMIT_TRADING" // }, // { // "buyPriceUpRate": "0.05", // "sellPriceDownRate": "0.05", // "filterType": "MARKET_TRADING" // }, // { // "noAllowMarketStartTime": "0", // "noAllowMarketEndTime": "0", // "limitOrderStartTime": "0", // "limitOrderEndTime": "0", // "limitMinPrice": "0", // "limitMaxPrice": "0", // "filterType": "OPEN_QUOTE" // } // ], // "exchangeId": "301", // "symbol": "BTCUSDT-PERPETUAL", // "symbolName": "BTCUSDT-PERPETUAL", // "status": "TRADING", // "baseAsset": "BTCUSDT-PERPETUAL", // "baseAssetPrecision": "0.001", // "quoteAsset": "USDT", // "quoteAssetPrecision": "0.1", // "icebergAllowed": false, // "inverse": false, // "index": "USDT", // "marginToken": "USDT", // "marginPrecision": "0.0001", // "contractMultiplier": "0.001", // "underlying": "BTC", // "riskLimits": [ // { // "riskLimitId": "200000722", // "quantity": "1000.00", // "initialMargin": "0.10", // "maintMargin": "0.005", // "isWhite": false // }, // { // "riskLimitId": "200000723", // "quantity": "2000.00", // "initialMargin": "0.10", // "maintMargin": "0.01", // "isWhite": false // } // ] // } // const marketId = this.safeString(market, 'symbol'); const quoteId = this.safeString(market, 'quoteAsset'); const quote = this.safeCurrencyCode(quoteId); const settleId = this.safeString(market, 'marginToken'); const settle = this.safeCurrencyCode(settleId); let baseId = this.safeString(market, 'baseAsset'); let marketType = 'spot'; let isSpot = true; let isSwap = false; let suffix = ''; const parts = marketId.split('-'); const secondPart = this.safeString(parts, 1); if (secondPart === 'PERPETUAL') { marketType = 'swap'; isSpot = false; isSwap = true; baseId = this.safeString(market, 'underlying'); suffix += ':' + settleId; } const base = this.safeCurrencyCode(baseId); const symbol = base + '/' + quote + suffix; const status = this.safeString(market, 'status'); const active = status === 'TRADING'; let isLinear = undefined; let subType = undefined; const isInverse = this.safeBool(market, 'inverse'); if (isInverse !== undefined) { if (isInverse) { isLinear = false; subType = 'inverse'; } else { isLinear = true; subType = 'linear'; } } const filtersList = this.safeList(market, 'filters', []); const filters = this.indexBy(filtersList, 'filterType'); const priceFilter = this.safeDict(filters, 'PRICE_FILTER', {}); const amountFilter = this.safeDict(filters, 'LOT_SIZE', {}); const costFilter = this.safeDict(filters, 'MIN_NOTIONAL', {}); const minCostString = this.omitZero(this.safeString(costFilter, 'min_notional')); const contractSizeString = this.safeString(market, 'contractMultiplier'); let amountPrecisionString = this.safeString(amountFilter, 'stepSize'); let amountMinLimitString = this.safeString(amountFilter, 'minQty'); let amountMaxLimitString = this.safeString(amountFilter, 'maxQty'); let minLeverage = undefined; let maxLeverage = undefined; if (isSwap) { amountPrecisionString = Precise["default"].stringDiv(amountPrecisionString, contractSizeString); amountMinLimitString = Precise["default"].stringDiv(amountMinLimitString, contractSizeString); amountMaxLimitString = Precise["default"].stringDiv(amountMaxLimitString, contractSizeString); const riskLimits = this.safeList(market, 'riskLimits'); if (riskLimits !== undefined) { const first = this.safeDict(riskLimits, 0); const arrayLength = riskLimits.length; const last = this.safeDict(riskLimits, arrayLength - 1); let minInitialMargin = this.safeString(first, 'initialMargin'); let maxInitialMargin = this.safeString(last, 'initialMargin'); if (Precise["default"].stringGt(minInitialMargin, maxInitialMargin)) { [minInitialMargin, maxInitialMargin] = [maxInitialMargin, minInitialMargin]; } minLeverage = this.parseToInt(Precise["default"].stringDiv('1', maxInitialMargin)); maxLeverage = this.parseToInt(Precise["default"].stringDiv('1', minInitialMargin)); } } const tradingFees = this.safeDict(this.fees, 'trading'); const fees = isSpot ? this.safeDict(tradingFees, 'spot') : this.safeDict(tradingFees, 'swap'); return this.safeMarketStructure({ 'id': marketId, 'symbol': symbol, 'base': base, 'quote': quote, 'baseId': baseId, 'quoteId': quoteId, 'active': active, 'type': marketType, 'subType': subType, 'spot': isSpot, 'margin': this.safeBool(market, 'allowMargin'), 'swap': isSwap, 'future': false, 'option': false, 'contract': isSwap, 'settle': settle, 'settleId': settleId, 'contractSize': this.parseNumber(contractSizeString), 'linear': isLinear, 'inverse': isInverse, 'taker': this.safeNumber(fees, 'taker'), 'maker': this.safeNumber(fees, 'maker'), 'percentage': this.safeBool(fees, 'percentage'), 'tierBased': this.safeBool(fees, 'tierBased'), 'feeSide': this.safeString(fees, 'feeSide'), 'expiry': undefined, 'expiryDatetime': undefined, 'strike': undefined, 'optionType': undefined, 'precision': { 'amount': this.parseNumber(amountPrecisionString), 'price': this.safeNumber(priceFilter, 'tickSize'), }, 'limits': { 'amount': { 'min': this.parseNumber(amountMinLimitString), 'max': this.parseNumber(amountMaxLimitString), }, 'price': { 'min': this.safeNumber(priceFilter, 'minPrice'), 'max': this.safeNumber(priceFilter, 'maxPrice'), }, 'leverage': { 'min': minLeverage, 'max': maxLeverage, }, 'cost':