UNPKG

@proton/ccxt

Version:

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

1,099 lines (1,097 loc) 177 kB
// ---------------------------------------------------------------------------- // PLEASE DO NOT EDIT THIS FILE, IT IS GENERATED AND WILL BE OVERWRITTEN: // https://github.com/ccxt/ccxt/blob/master/CONTRIBUTING.md#how-to-contribute-code // EDIT THE CORRESPONDENT .ts FILE INSTEAD // --------------------------------------------------------------------------- import Exchange from './abstract/kucoin.js'; import { ExchangeError, ExchangeNotAvailable, InsufficientFunds, OrderNotFound, InvalidOrder, AccountSuspended, InvalidNonce, NotSupported, BadRequest, AuthenticationError, BadSymbol, RateLimitExceeded, PermissionDenied, InvalidAddress, ArgumentsRequired } from './base/errors.js'; import { Precise } from './base/Precise.js'; import { TICK_SIZE } from './base/functions/number.js'; import { sha256 } from './static_dependencies/noble-hashes/sha256.js'; // --------------------------------------------------------------------------- export default class kucoin extends Exchange { describe() { return this.deepExtend(super.describe(), { 'id': 'kucoin', 'name': 'KuCoin', 'countries': ['SC'], // note "only some endpoints are rate-limited" // so I set the 'ratelimit' on those which supposedly 'arent ratelimited' // to the limit of the cheapest endpoint // 60 requests in 3 seconds = 20 requests per second => ( 1000ms / 20 ) = 50 ms between requests on average 'rateLimit': 50, 'version': 'v2', 'certified': true, 'pro': true, 'comment': 'Platform 2.0', 'quoteJsonNumbers': false, 'has': { 'CORS': undefined, 'spot': true, 'margin': true, 'swap': false, 'future': false, 'option': undefined, 'borrowMargin': true, 'cancelAllOrders': true, 'cancelOrder': true, 'createDepositAddress': true, 'createOrder': true, 'createStopLimitOrder': true, 'createStopMarketOrder': true, 'createStopOrder': true, 'editOrder': true, 'fetchAccounts': true, 'fetchBalance': true, 'fetchBorrowInterest': true, 'fetchBorrowRate': false, 'fetchBorrowRateHistories': false, 'fetchBorrowRateHistory': true, 'fetchBorrowRates': false, 'fetchClosedOrders': true, 'fetchCurrencies': true, 'fetchDepositAddress': true, 'fetchDepositAddressesByNetwork': true, 'fetchDeposits': true, 'fetchDepositWithdrawFee': true, 'fetchDepositWithdrawFees': true, 'fetchFundingHistory': false, 'fetchFundingRate': false, 'fetchFundingRateHistory': false, 'fetchFundingRates': false, 'fetchIndexOHLCV': false, 'fetchL3OrderBook': true, 'fetchLedger': true, 'fetchMarginMode': false, 'fetchMarkets': true, 'fetchMarkOHLCV': false, 'fetchMyTrades': true, 'fetchOHLCV': true, 'fetchOpenInterestHistory': false, 'fetchOpenOrders': true, 'fetchOrder': true, 'fetchOrderBook': true, 'fetchOrdersByStatus': true, 'fetchOrderTrades': true, 'fetchPositionMode': false, 'fetchPremiumIndexOHLCV': false, 'fetchStatus': true, 'fetchTicker': true, 'fetchTickers': true, 'fetchTime': true, 'fetchTrades': true, 'fetchTradingFee': true, 'fetchTradingFees': false, 'fetchTransactionFee': true, 'fetchWithdrawals': true, 'repayMargin': true, 'setMarginMode': false, 'transfer': true, 'withdraw': true, }, 'urls': { 'logo': 'https://user-images.githubusercontent.com/51840849/87295558-132aaf80-c50e-11ea-9801-a2fb0c57c799.jpg', 'referral': 'https://www.kucoin.com/ucenter/signup?rcode=E5wkqe', 'api': { 'public': 'https://api.kucoin.com', 'private': 'https://api.kucoin.com', 'futuresPrivate': 'https://api-futures.kucoin.com', 'futuresPublic': 'https://api-futures.kucoin.com', }, 'test': { 'public': 'https://openapi-sandbox.kucoin.com', 'private': 'https://openapi-sandbox.kucoin.com', 'futuresPrivate': 'https://api-sandbox-futures.kucoin.com', 'futuresPublic': 'https://api-sandbox-futures.kucoin.com', }, 'www': 'https://www.kucoin.com', 'doc': [ 'https://docs.kucoin.com', ], }, 'requiredCredentials': { 'apiKey': true, 'secret': true, 'password': true, }, 'api': { 'public': { 'get': { 'timestamp': 1, 'status': 1, 'symbols': 1, 'markets': 1, 'market/allTickers': 1, 'market/orderbook/level{level}_{limit}': 1, 'market/orderbook/level2_20': 1, 'market/orderbook/level2_100': 1, 'market/histories': 1, 'market/candles': 1, 'market/stats': 1, 'currencies': 1, 'currencies/{currency}': 1, 'prices': 1, 'mark-price/{symbol}/current': 1, 'margin/config': 1, 'margin/trade/last': 1, }, 'post': { 'bullet-public': 1, }, }, 'private': { 'get': { 'market/orderbook/level{level}': 1, 'market/orderbook/level2': { 'v3': 2 }, 'market/orderbook/level3': 1, 'accounts': 1, 'accounts/{accountId}': 1, // 'accounts/{accountId}/ledgers': 1, Deprecated endpoint 'accounts/ledgers': 3.333, 'accounts/{accountId}/holds': 1, 'accounts/transferable': 1, 'base-fee': 1, 'sub/user': 1, 'user-info': 1, 'sub/api-key': 1, 'sub-accounts': 1, 'sub-accounts/{subUserId}': 1, 'deposit-addresses': 1, 'deposits': 10, 'hist-deposits': 10, // 'hist-orders': 1, Deprecated endpoint 'hist-withdrawals': 10, 'withdrawals': 10, 'withdrawals/quotas': 1, 'orders': 2, 'order/client-order/{clientOid}': 1, 'orders/{orderId}': 1, 'limit/orders': 1, 'fills': 6.66667, 'limit/fills': 1, 'isolated/accounts': 2, 'isolated/account/{symbol}': 2, 'isolated/borrow/outstanding': 2, 'isolated/borrow/repaid': 2, 'isolated/symbols': 2, 'margin/account': 1, 'margin/borrow': 1, 'margin/borrow/outstanding': 1, 'margin/borrow/repaid': 1, 'margin/lend/active': 1, 'margin/lend/done': 1, 'margin/lend/trade/unsettled': 1, 'margin/lend/trade/settled': 1, 'margin/lend/assets': 1, 'margin/market': 1, 'stop-order/{orderId}': 1, 'stop-order': 1, 'stop-order/queryOrderByClientOid': 1, 'trade-fees': 1.3333, 'hf/accounts/ledgers': 3.33, 'hf/orders/active': 2, 'hf/orders/active/symbols': 20, 'hf/orders/done': 2, 'hf/orders/{orderId}': 1, 'hf/orders/client-order/{clientOid}': 2, 'hf/fills': 6.67, // 9 times/3s = 3/s => cost = 20 / 3 = 6.67 }, 'post': { 'accounts': 1, 'accounts/inner-transfer': { 'v2': 1 }, 'accounts/sub-transfer': { 'v2': 25 }, 'deposit-addresses': 1, 'withdrawals': 1, 'orders': 4, 'orders/multi': 20, 'isolated/borrow': 2, 'isolated/repay/all': 2, 'isolated/repay/single': 2, 'margin/borrow': 1, 'margin/order': 1, 'margin/repay/all': 1, 'margin/repay/single': 1, 'margin/lend': 1, 'margin/toggle-auto-lend': 1, 'bullet-private': 1, 'stop-order': 1, 'sub/user': 1, 'sub/api-key': 1, 'sub/api-key/update': 1, 'hf/orders': 0.4, 'hf/orders/sync': 1.33, 'hf/orders/multi': 20, 'hf/orders/multi/sync': 20, 'hf/orders/alter': 1, // 60 times/3s = 20/s => cost = 20/20 = 1 }, 'delete': { 'withdrawals/{withdrawalId}': 1, 'orders': 20, 'order/client-order/{clientOid}': 1, 'orders/{orderId}': 1, 'margin/lend/{orderId}': 1, 'stop-order/cancelOrderByClientOid': 1, 'stop-order/{orderId}': 1, 'stop-order/cancel': 1, 'sub/api-key': 1, 'hf/orders/{orderId}': 0.4, 'hf/orders/sync/{orderId}': 0.4, 'hf/orders/client-order/{clientOid}': 0.4, 'hf/orders/sync/client-order/{clientOid}': 0.4, 'hf/orders/cancel/{orderId}': 1, 'hf/orders': 20, // 3 times/3s = 1/s => cost = 20 / 1 = 20 }, }, 'futuresPublic': { // cheapest futures 'limited' endpoint is 40 requests per 3 seconds = 14.333 per second => cost = 20/14.333 = 1.3953 'get': { 'contracts/active': 1.3953, 'contracts/{symbol}': 1.3953, 'ticker': 1.3953, 'level2/snapshot': 2, 'level2/depth20': 1.3953, 'level2/depth100': 1.3953, 'level2/message/query': 1.3953, 'level3/message/query': 1.3953, 'level3/snapshot': 1.3953, 'trade/history': 1.3953, 'interest/query': 1.3953, 'index/query': 1.3953, 'mark-price/{symbol}/current': 1.3953, 'premium/query': 1.3953, 'funding-rate/{symbol}/current': 1.3953, 'timestamp': 1.3953, 'status': 1.3953, 'kline/query': 1.3953, }, 'post': { 'bullet-public': 1.3953, }, }, 'futuresPrivate': { 'get': { 'account-overview': 2, 'transaction-history': 6.666, 'deposit-address': 1.3953, 'deposit-list': 1.3953, 'withdrawals/quotas': 1.3953, 'withdrawal-list': 1.3953, 'transfer-list': 1.3953, 'orders': 1.3953, 'stopOrders': 1.3953, 'recentDoneOrders': 1.3953, 'orders/{orderId}': 1.3953, 'orders/byClientOid': 1.3953, 'fills': 6.666, 'recentFills': 6.666, 'openOrderStatistics': 1.3953, 'position': 1.3953, 'positions': 6.666, 'funding-history': 6.666, // 9 requests per 3 seconds = 3 per second => cost = 20/3 = 6.666 }, 'post': { 'withdrawals': 1.3953, 'transfer-out': 1.3953, 'orders': 1.3953, 'position/margin/auto-deposit-status': 1.3953, 'position/margin/deposit-margin': 1.3953, 'bullet-private': 1.3953, }, 'delete': { 'withdrawals/{withdrawalId}': 1.3953, 'cancel/transfer-out': 1.3953, 'orders/{orderId}': 1.3953, 'orders': 6.666, 'stopOrders': 1.3953, }, }, }, 'timeframes': { '1m': '1min', '3m': '3min', '5m': '5min', '15m': '15min', '30m': '30min', '1h': '1hour', '2h': '2hour', '4h': '4hour', '6h': '6hour', '8h': '8hour', '12h': '12hour', '1d': '1day', '1w': '1week', }, 'precisionMode': TICK_SIZE, 'exceptions': { 'exact': { 'order not exist': OrderNotFound, 'order not exist.': OrderNotFound, 'order_not_exist': OrderNotFound, 'order_not_exist_or_not_allow_to_cancel': InvalidOrder, 'Order size below the minimum requirement.': InvalidOrder, 'The withdrawal amount is below the minimum requirement.': ExchangeError, 'Unsuccessful! Exceeded the max. funds out-transfer limit': InsufficientFunds, '400': BadRequest, '401': AuthenticationError, '403': NotSupported, '404': NotSupported, '405': NotSupported, '429': RateLimitExceeded, '500': ExchangeNotAvailable, '503': ExchangeNotAvailable, '101030': PermissionDenied, '103000': InvalidOrder, '200004': InsufficientFunds, '210014': InvalidOrder, '210021': InsufficientFunds, '230003': InsufficientFunds, '260000': InvalidAddress, '260100': InsufficientFunds, '300000': InvalidOrder, '400000': BadSymbol, '400001': AuthenticationError, '400002': InvalidNonce, '400003': AuthenticationError, '400004': AuthenticationError, '400005': AuthenticationError, '400006': AuthenticationError, '400007': AuthenticationError, '400008': NotSupported, '400100': BadRequest, '400200': InvalidOrder, '400350': InvalidOrder, '400370': InvalidOrder, '400500': InvalidOrder, '400600': BadSymbol, '400760': InvalidOrder, '401000': BadRequest, '411100': AccountSuspended, '415000': BadRequest, '500000': ExchangeNotAvailable, '260220': InvalidAddress, '900014': BadRequest, // {"code":"900014","msg":"Invalid chainId"} }, 'broad': { 'Exceeded the access frequency': RateLimitExceeded, 'require more permission': PermissionDenied, }, }, 'fees': { 'trading': { 'tierBased': true, 'percentage': true, 'taker': this.parseNumber('0.001'), 'maker': this.parseNumber('0.001'), 'tiers': { 'taker': [ [this.parseNumber('0'), this.parseNumber('0.001')], [this.parseNumber('50'), this.parseNumber('0.001')], [this.parseNumber('200'), this.parseNumber('0.0009')], [this.parseNumber('500'), this.parseNumber('0.0008')], [this.parseNumber('1000'), this.parseNumber('0.0007')], [this.parseNumber('2000'), this.parseNumber('0.0007')], [this.parseNumber('4000'), this.parseNumber('0.0006')], [this.parseNumber('8000'), this.parseNumber('0.0005')], [this.parseNumber('15000'), this.parseNumber('0.00045')], [this.parseNumber('25000'), this.parseNumber('0.0004')], [this.parseNumber('40000'), this.parseNumber('0.00035')], [this.parseNumber('60000'), this.parseNumber('0.0003')], [this.parseNumber('80000'), this.parseNumber('0.00025')], ], 'maker': [ [this.parseNumber('0'), this.parseNumber('0.001')], [this.parseNumber('50'), this.parseNumber('0.0009')], [this.parseNumber('200'), this.parseNumber('0.0007')], [this.parseNumber('500'), this.parseNumber('0.0005')], [this.parseNumber('1000'), this.parseNumber('0.0003')], [this.parseNumber('2000'), this.parseNumber('0')], [this.parseNumber('4000'), this.parseNumber('0')], [this.parseNumber('8000'), this.parseNumber('0')], [this.parseNumber('15000'), this.parseNumber('-0.00005')], [this.parseNumber('25000'), this.parseNumber('-0.00005')], [this.parseNumber('40000'), this.parseNumber('-0.00005')], [this.parseNumber('60000'), this.parseNumber('-0.00005')], [this.parseNumber('80000'), this.parseNumber('-0.00005')], ], }, }, 'funding': { 'tierBased': false, 'percentage': false, 'withdraw': {}, 'deposit': {}, }, }, 'commonCurrencies': { 'BIFI': 'BIFIF', 'EDGE': 'DADI', 'HOT': 'HOTNOW', 'TRY': 'Trias', 'VAI': 'VAIOT', 'WAX': 'WAXP', }, 'options': { 'version': 'v1', 'symbolSeparator': '-', 'fetchMyTradesMethod': 'private_get_fills', 'fetchMarkets': { 'fetchTickersFees': true, }, 'withdraw': { 'includeFee': false, }, // endpoint versions 'versions': { 'public': { 'GET': { 'currencies/{currency}': 'v2', 'status': 'v1', 'market/orderbook/level2_20': 'v1', 'market/orderbook/level2_100': 'v1', 'market/orderbook/level{level}_{limit}': 'v1', }, }, 'private': { 'GET': { 'market/orderbook/level2': 'v3', 'market/orderbook/level3': 'v3', 'market/orderbook/level{level}': 'v3', 'deposit-addresses': 'v1', 'hf/accounts/ledgers': 'v1', 'hf/orders/active': 'v1', 'hf/orders/active/symbols': 'v1', 'hf/orders/done': 'v1', 'hf/orders/{orderId}': 'v1', 'hf/orders/client-order/{clientOid}': 'v1', 'hf/fills': 'v1', }, 'POST': { 'accounts/inner-transfer': 'v2', 'accounts/sub-transfer': 'v2', 'accounts': 'v1', 'hf/orders': 'v1', 'hf/orders/sync': 'v1', 'hf/orders/multi': 'v1', 'hf/orders/multi/sync': 'v1', 'hf/orders/alter': 'v1', }, 'DELETE': { 'hf/orders/{orderId}': 'v1', 'hf/orders/sync/{orderId}': 'v1', 'hf/orders/client-order/{clientOid}': 'v1', 'hf/orders/sync/client-order/{clientOid}': 'v1', 'hf/orders/cancel/{orderId}': 'v1', 'hf/orders': 'v1', }, }, 'futuresPrivate': { 'GET': { 'account-overview': 'v1', 'positions': 'v1', }, 'POST': { 'transfer-out': 'v2', }, }, 'futuresPublic': { 'GET': { 'level3/snapshot': 'v2', }, }, }, 'partner': { // the support for spot and future exchanges as separate settings 'spot': { 'id': 'ccxt', 'key': '9e58cc35-5b5e-4133-92ec-166e3f077cb8', }, 'future': { 'id': 'ccxtfutures', 'key': '1b327198-f30c-4f14-a0ac-918871282f15', }, // exchange-wide settings are also supported // 'id': 'ccxt' // 'key': '9e58cc35-5b5e-4133-92ec-166e3f077cb8', }, 'accountsByType': { 'spot': 'trade', 'margin': 'margin', 'cross': 'margin', 'isolated': 'isolated', 'main': 'main', 'funding': 'main', 'future': 'contract', 'swap': 'contract', 'mining': 'pool', 'hf': 'trade_hf', }, 'networks': { 'Native': 'bech32', 'BTC-Segwit': 'btc', 'ERC20': 'eth', 'BEP20': 'bsc', 'TRC20': 'trx', 'TERRA': 'luna', 'BNB': 'bsc', 'HRC20': 'heco', 'HT': 'heco', }, 'networksById': { 'BEP20': 'BSC', }, 'marginModes': { 'cross': 'MARGIN_TRADE', 'isolated': 'MARGIN_ISOLATED_TRADE', 'spot': 'TRADE', }, }, }); } nonce() { return this.milliseconds(); } async fetchTime(params = {}) { /** * @method * @name kucoin#fetchTime * @description fetches the current integer timestamp in milliseconds from the exchange server * @param {object} params extra parameters specific to the kucoin api endpoint * @returns {int} the current integer timestamp in milliseconds from the exchange server */ const response = await this.publicGetTimestamp(params); // // { // "code":"200000", // "msg":"success", // "data":1546837113087 // } // return this.safeInteger(response, 'data'); } async fetchStatus(params = {}) { /** * @method * @name kucoin#fetchStatus * @description the latest known information on the availability of the exchange API * @param {object} params extra parameters specific to the kucoin api endpoint * @returns {object} a [status structure]{@link https://docs.ccxt.com/#/?id=exchange-status-structure} */ const response = await this.publicGetStatus(params); // // { // "code":"200000", // "data":{ // "status":"open", //open, close, cancelonly // "msg":"upgrade match engine" //remark for operation // } // } // const data = this.safeValue(response, 'data', {}); const status = this.safeString(data, 'status'); return { 'status': (status === 'open') ? 'ok' : 'maintenance', 'updated': undefined, 'eta': undefined, 'url': undefined, 'info': response, }; } async fetchMarkets(params = {}) { /** * @method * @name kucoin#fetchMarkets * @description retrieves data on all markets for kucoin * @param {object} params extra parameters specific to the exchange api endpoint * @returns {[object]} an array of objects representing market data */ const response = await this.publicGetSymbols(params); // // { // "code": "200000", // "data": [ // { // "symbol": "XLM-USDT", // "name": "XLM-USDT", // "baseCurrency": "XLM", // "quoteCurrency": "USDT", // "feeCurrency": "USDT", // "market": "USDS", // "baseMinSize": "0.1", // "quoteMinSize": "0.01", // "baseMaxSize": "10000000000", // "quoteMaxSize": "99999999", // "baseIncrement": "0.0001", // "quoteIncrement": "0.000001", // "priceIncrement": "0.000001", // "priceLimitRate": "0.1", // "isMarginEnabled": true, // "enableTrading": true // }, // ] // } // const data = this.safeValue(response, 'data'); const options = this.safeValue(this.options, 'fetchMarkets', {}); const fetchTickersFees = this.safeValue(options, 'fetchTickersFees', true); let tickersResponse = {}; if (fetchTickersFees) { tickersResponse = await this.publicGetMarketAllTickers(params); } // // { // "code": "200000", // "data": { // "time":1602832092060, // "ticker":[ // { // "symbol": "BTC-USDT", // symbol // "symbolName":"BTC-USDT", // Name of trading pairs, it would change after renaming // "buy": "11328.9", // bestAsk // "sell": "11329", // bestBid // "changeRate": "-0.0055", // 24h change rate // "changePrice": "-63.6", // 24h change price // "high": "11610", // 24h highest price // "low": "11200", // 24h lowest price // "vol": "2282.70993217", // 24h volume,the aggregated trading volume in BTC // "volValue": "25984946.157790431", // 24h total, the trading volume in quote currency of last 24 hours // "last": "11328.9", // last price // "averagePrice": "11360.66065903", // 24h average transaction price yesterday // "takerFeeRate": "0.001", // Basic Taker Fee // "makerFeeRate": "0.001", // Basic Maker Fee // "takerCoefficient": "1", // Taker Fee Coefficient // "makerCoefficient": "1" // Maker Fee Coefficient // } // ] // } // } // const tickersData = this.safeValue(tickersResponse, 'data', {}); const tickers = this.safeValue(tickersData, 'ticker', []); const tickersByMarketId = this.indexBy(tickers, 'symbol'); const result = []; for (let i = 0; i < data.length; i++) { const market = data[i]; const id = this.safeString(market, 'symbol'); const [baseId, quoteId] = id.split('-'); const base = this.safeCurrencyCode(baseId); const quote = this.safeCurrencyCode(quoteId); // const quoteIncrement = this.safeNumber (market, 'quoteIncrement'); const ticker = this.safeValue(tickersByMarketId, id, {}); const makerFeeRate = this.safeString(ticker, 'makerFeeRate'); const takerFeeRate = this.safeString(ticker, 'takerFeeRate'); const makerCoefficient = this.safeString(ticker, 'makerCoefficient'); const takerCoefficient = this.safeString(ticker, 'takerCoefficient'); result.push({ 'id': id, 'symbol': base + '/' + quote, 'base': base, 'quote': quote, 'settle': undefined, 'baseId': baseId, 'quoteId': quoteId, 'settleId': undefined, 'type': 'spot', 'spot': true, 'margin': this.safeValue(market, 'isMarginEnabled'), 'swap': false, 'future': false, 'option': false, 'active': this.safeValue(market, 'enableTrading'), 'contract': false, 'linear': undefined, 'inverse': undefined, 'taker': this.parseNumber(Precise.stringMul(takerFeeRate, takerCoefficient)), 'maker': this.parseNumber(Precise.stringMul(makerFeeRate, makerCoefficient)), 'contractSize': undefined, 'expiry': undefined, 'expiryDatetime': undefined, 'strike': undefined, 'optionType': undefined, 'precision': { 'amount': this.safeNumber(market, 'baseIncrement'), 'price': this.safeNumber(market, 'priceIncrement'), }, 'limits': { 'leverage': { 'min': undefined, 'max': undefined, }, 'amount': { 'min': this.safeNumber(market, 'baseMinSize'), 'max': this.safeNumber(market, 'baseMaxSize'), }, 'price': { 'min': undefined, 'max': undefined, }, 'cost': { 'min': this.safeNumber(market, 'quoteMinSize'), 'max': this.safeNumber(market, 'quoteMaxSize'), }, }, 'info': market, }); } return result; } async fetchCurrencies(params = {}) { /** * @method * @name kucoin#fetchCurrencies * @description fetches all available currencies on an exchange * @see https://docs.kucoin.com/#get-currencies * @param {object} params extra parameters specific to the kucoin api endpoint * @returns {object} an associative dictionary of currencies */ const response = await this.publicGetCurrencies(params); // // { // "currency": "OMG", // "name": "OMG", // "fullName": "OmiseGO", // "precision": 8, // "confirms": 12, // "withdrawalMinSize": "4", // "withdrawalMinFee": "1.25", // "isWithdrawEnabled": false, // "isDepositEnabled": false, // "isMarginEnabled": false, // "isDebitEnabled": false // } // const data = this.safeValue(response, 'data', []); const result = {}; for (let i = 0; i < data.length; i++) { const entry = data[i]; const id = this.safeString(entry, 'currency'); const name = this.safeString(entry, 'fullName'); const code = this.safeCurrencyCode(id); const isWithdrawEnabled = this.safeValue(entry, 'isWithdrawEnabled', false); const isDepositEnabled = this.safeValue(entry, 'isDepositEnabled', false); const fee = this.safeNumber(entry, 'withdrawalMinFee'); const active = (isWithdrawEnabled && isDepositEnabled); result[code] = { 'id': id, 'name': name, 'code': code, 'precision': this.parseNumber(this.parsePrecision(this.safeString(entry, 'precision'))), 'info': entry, 'active': active, 'deposit': isDepositEnabled, 'withdraw': isWithdrawEnabled, 'fee': fee, 'limits': this.limits, 'networks': {}, }; } return result; } async fetchAccounts(params = {}) { /** * @method * @name kucoin#fetchAccounts * @description fetch all the accounts associated with a profile * @param {object} params extra parameters specific to the kucoin api endpoint * @returns {object} a dictionary of [account structures]{@link https://docs.ccxt.com/#/?id=account-structure} indexed by the account type */ const response = await this.privateGetAccounts(params); // // { // code: "200000", // data: [ // { // balance: "0.00009788", // available: "0.00009788", // holds: "0", // currency: "BTC", // id: "5c6a4fd399a1d81c4f9cc4d0", // type: "trade" // }, // { // balance: "0.00000001", // available: "0.00000001", // holds: "0", // currency: "ETH", // id: "5c6a49ec99a1d819392e8e9f", // type: "trade" // } // ] // } // const data = this.safeValue(response, 'data', []); const result = []; for (let i = 0; i < data.length; i++) { const account = data[i]; const accountId = this.safeString(account, 'id'); const currencyId = this.safeString(account, 'currency'); const code = this.safeCurrencyCode(currencyId); const type = this.safeString(account, 'type'); // main or trade result.push({ 'id': accountId, 'type': type, 'currency': code, 'info': account, }); } return result; } async fetchTransactionFee(code, params = {}) { /** * @method * @name kucoin#fetchTransactionFee * @description *DEPRECATED* please use fetchDepositWithdrawFee instead * @see https://docs.kucoin.com/#get-withdrawal-quotas * @param {string} code unified currency code * @param {object} params extra parameters specific to the kucoin api endpoint * @returns {object} a [fee structure]{@link https://docs.ccxt.com/#/?id=fee-structure} */ await this.loadMarkets(); const currency = this.currency(code); const request = { 'currency': currency['id'], }; const networks = this.safeValue(this.options, 'networks', {}); let network = this.safeStringUpper2(params, 'network', 'chain'); network = this.safeStringLower(networks, network, network); if (network !== undefined) { network = network.toLowerCase(); request['chain'] = network.toLowerCase(); params = this.omit(params, ['network', 'chain']); } const response = await this.privateGetWithdrawalsQuotas(this.extend(request, params)); const data = response['data']; const withdrawFees = {}; withdrawFees[code] = this.safeNumber(data, 'withdrawMinFee'); return { 'info': response, 'withdraw': withdrawFees, 'deposit': {}, }; } async fetchDepositWithdrawFee(code, params = {}) { /** * @method * @name kucoin#fetchDepositWithdrawFee * @description fetch the fee for deposits and withdrawals * @see https://docs.kucoin.com/#get-withdrawal-quotas * @param {string} code unified currency code * @param {object} params extra parameters specific to the kucoin api endpoint * @param {string|undefined} params.network The chain of currency. This only apply for multi-chain currency, and there is no need for single chain currency; you can query the chain through the response of the GET /api/v2/currencies/{currency} interface * @returns {object} a [fee structure]{@link https://docs.ccxt.com/#/?id=fee-structure} */ await this.loadMarkets(); const currency = this.currency(code); const request = { 'currency': currency['id'], }; const networkCode = this.safeStringUpper(params, 'network'); const network = this.networkCodeToId(networkCode, code); if (network !== undefined) { request['chain'] = network.toLowerCase(); params = this.omit(params, ['network']); } const response = await this.privateGetWithdrawalsQuotas(this.extend(request, params)); // // { // "code": "200000", // "data": { // "currency": "USDT", // "limitBTCAmount": "1.00000000", // "usedBTCAmount": "0.00000000", // "remainAmount": "16548.072149", // "availableAmount": "0", // "withdrawMinFee": "25", // "innerWithdrawMinFee": "0", // "withdrawMinSize": "50", // "isWithdrawEnabled": true, // "precision": 6, // "chain": "ERC20" // } // } // const data = this.safeValue(response, 'data'); return this.parseDepositWithdrawFee(data, currency); } parseDepositWithdrawFee(fee, currency = undefined) { // // { // "currency": "USDT", // "limitBTCAmount": "1.00000000", // "usedBTCAmount": "0.00000000", // "remainAmount": "16548.072149", // "availableAmount": "0", // "withdrawMinFee": "25", // "innerWithdrawMinFee": "0", // "withdrawMinSize": "50", // "isWithdrawEnabled": true, // "precision": 6, // "chain": "ERC20" // } // const result = { 'info': fee, 'withdraw': { 'fee': undefined, 'percentage': undefined, }, 'deposit': { 'fee': undefined, 'percentage': undefined, }, 'networks': {}, }; const isWithdrawEnabled = this.safeValue(fee, 'isWithdrawEnabled'); if (isWithdrawEnabled) { result['withdraw']['fee'] = this.safeNumber(fee, 'withdrawalMinFee'); result['withdraw']['percentage'] = false; const networkId = this.safeString(fee, 'chain'); if (networkId) { const networkCode = this.networkIdToCode(networkId, this.safeString(currency, 'code')); result['networks'][networkCode] = { 'withdraw': result['withdraw'], 'deposit': { 'fee': undefined, 'percentage': undefined, }, }; } } return result; } isFuturesMethod(methodName, params) { // // Helper // @methodName (string): The name of the method // @params (dict): The parameters passed into {methodName} // @return: true if the method used is meant for futures trading, false otherwise // const defaultType = this.safeString2(this.options, methodName, 'defaultType', 'trade'); const requestedType = this.safeString(params, 'type', defaultType); const accountsByType = this.safeValue(this.options, 'accountsByType'); const type = this.safeString(accountsByType, requestedType); if (type === undefined) { const keys = Object.keys(accountsByType); throw new ExchangeError(this.id + ' isFuturesMethod() type must be one of ' + keys.join(', ')); } params = this.omit(params, 'type'); return (type === 'contract') || (type === 'future') || (type === 'futures'); // * (type === 'futures') deprecated, use (type === 'future') } parseTicker(ticker, market = undefined) { // // { // "symbol": "BTC-USDT", // symbol // "symbolName":"BTC-USDT", // Name of trading pairs, it would change after renaming // "buy": "11328.9", // bestAsk // "sell": "11329", // bestBid // "changeRate": "-0.0055", // 24h change rate // "changePrice": "-63.6", // 24h change price // "high": "11610", // 24h highest price // "low": "11200", // 24h lowest price // "vol": "2282.70993217", // 24h volume,the aggregated trading volume in BTC // "volValue": "25984946.157790431", // 24h total, the trading volume in quote currency of last 24 hours // "last": "11328.9", // last price // "averagePrice": "11360.66065903", // 24h average transaction price yesterday // "takerFeeRate": "0.001", // Basic Taker Fee // "makerFeeRate": "0.001", // Basic Maker Fee // "takerCoefficient": "1", // Taker Fee Coefficient // "makerCoefficient": "1" // Maker Fee Coefficient // } // // { // "trading": true, // "symbol": "KCS-BTC", // "buy": 0.00011, // "sell": 0.00012, // "sort": 100, // "volValue": 3.13851792584, //total // "baseCurrency": "KCS", // "market": "BTC", // "quoteCurrency": "BTC", // "symbolCode": "KCS-BTC", // "datetime": 1548388122031, // "high": 0.00013, // "vol": 27514.34842, // "low": 0.0001, // "changePrice": -1.0e-5, // "changeRate": -0.0769, // "lastTradedPrice": 0.00012, // "board": 0, // "mark": 0 // } // // market/ticker ws subscription // // { // bestAsk: '62258.9', // bestAskSize: '0.38579986', // bestBid: '62258.8', // bestBidSize: '0.0078381', // price: '62260.7', // sequence: '1621383297064', // size: '0.00002841', // time: 1634641777363 // } // let percentage = this.safeString(ticker, 'changeRate'); if (percentage !== undefined) { percentage = Precise.stringMul(percentage, '100'); } let last = this.safeString2(ticker, 'last', 'lastTradedPrice'); last = this.safeString(ticker, 'price', last); const marketId = this.safeString(ticker, 'symbol'); market = this.safeMarket(marketId, market, '-'); const symbol = market['symbol']; const baseVolume = this.safeString(ticker, 'vol'); const quoteVolume = this.safeString(ticker, 'volValue'); const timestamp = this.safeInteger2(ticker, 'time', 'datetime'); return this.safeTicker({ 'symbol': symbol, 'timestamp': timestamp, 'datetime': this.iso8601(timestamp), 'high': this.safeString(ticker, 'high'), 'low': this.safeString(ticker, 'low'), 'bid': this.safeString2(ticker, 'buy', 'bestBid'), 'bidVolume': this.safeString(ticker, 'bestBidSize'), 'ask': this.safeString2(ticker, 'sell', 'bestAsk'), 'askVolume': this.safeString(ticker, 'bestAskSize'), 'vwap': undefined, 'open': this.safeString(ticker, 'open'), 'close': last, 'last': last, 'previousClose': undefined, 'change': this.safeString(ticker, 'changePrice'), 'percentage': percentage, 'average': this.safeString(ticker, 'averagePrice'), 'baseVolume': baseVolume, 'quoteVolume': quoteVolume, 'info': ticker, }, market); } async fetchTickers(symbols = undefined, params = {}) { /** * @method * @name kucoin#fetchTickers * @description fetches price tickers for multiple markets, statistical calculations with the information calculated over the past 24 hours each market * @param {[string]|undefined} symbols unified symbols of the markets to fetch the ticker for, all market tickers are returned if not assigned * @param {object} params extra parameters specific to the kucoin api endpoint * @returns {object} a dictionary of [ticker structures]{@link https://docs.ccxt.com/#/?id=ticker-structure} */ await this.loadMarkets(); symbols = this.marketSymbols(symbols); const response = await this.publicGetMarketAllTickers(params); // // { // "code": "200000", // "data": { // "time":1602832092060, // "ticker":[ // { // "symbol": "BTC-USDT", // symbol // "symbolName":"BTC-USDT", // Name of trading pairs, it would change after renaming // "buy": "11328.9", // bestAsk // "sell": "11329", // bestBid // "changeRate": "-0.0055", // 24h change rate // "changePrice": "-63.6", // 24h change price // "high": "11610", // 24h highest price // "low": "11200", // 24h lowest price // "vol": "2282.70993217", // 24h