UNPKG

ccxt-look

Version:

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

1,269 lines (1,245 loc) 141 kB
'use strict'; // --------------------------------------------------------------------------- const Exchange = require ('./base/Exchange'); const { ExchangeError, ArgumentsRequired, BadRequest, BadSymbol, InsufficientFunds, OrderNotFound, InvalidOrder, AuthenticationError, PermissionDenied, ExchangeNotAvailable, RequestTimeout } = require ('./base/errors'); const Precise = require ('./base/Precise'); // --------------------------------------------------------------------------- module.exports = class coinex extends Exchange { describe () { return this.deepExtend (super.describe (), { 'id': 'coinex', 'name': 'CoinEx', 'version': 'v1', 'countries': [ 'CN' ], 'rateLimit': 50, // Normal limit frequency is single IP:200 times / 10 seconds 'has': { 'CORS': undefined, 'spot': true, 'margin': undefined, // has but unimplemented 'swap': true, 'future': false, 'option': false, 'addMargin': true, 'cancelAllOrders': true, 'cancelOrder': true, 'createOrder': true, 'createReduceOnlyOrder': true, 'fetchBalance': true, 'fetchClosedOrders': true, 'fetchDeposits': true, 'fetchFundingHistory': true, 'fetchFundingRate': true, 'fetchFundingRateHistory': true, 'fetchFundingRates': false, 'fetchIndexOHLCV': false, 'fetchLeverage': undefined, 'fetchLeverageTiers': undefined, 'fetchMarketLeverageTiers': undefined, 'fetchMarkets': true, 'fetchMarkOHLCV': false, 'fetchMyTrades': true, 'fetchOHLCV': true, 'fetchOpenOrders': true, 'fetchOrder': true, 'fetchOrderBook': true, 'fetchPosition': true, 'fetchPositions': true, 'fetchPositionsRisk': false, 'fetchPremiumIndexOHLCV': false, 'fetchTicker': true, 'fetchTickers': true, 'fetchTrades': true, 'fetchTradingFee': true, 'fetchTradingFees': true, 'fetchTransfers': true, 'fetchWithdrawals': true, 'reduceMargin': true, 'setLeverage': true, 'setMarginMode': true, 'setPositionMode': false, 'transfer': true, 'withdraw': true, }, 'timeframes': { '1m': '1min', '3m': '3min', '5m': '5min', '15m': '15min', '30m': '30min', '1h': '1hour', '2h': '2hour', '4h': '4hour', '6h': '6hour', '12h': '12hour', '1d': '1day', '3d': '3day', '1w': '1week', }, 'urls': { 'logo': 'https://user-images.githubusercontent.com/51840849/87182089-1e05fa00-c2ec-11ea-8da9-cc73b45abbbc.jpg', 'api': { 'public': 'https://api.coinex.com', 'private': 'https://api.coinex.com', 'perpetualPublic': 'https://api.coinex.com/perpetual', 'perpetualPrivate': 'https://api.coinex.com/perpetual', }, 'www': 'https://www.coinex.com', 'doc': 'https://github.com/coinexcom/coinex_exchange_api/wiki', 'fees': 'https://www.coinex.com/fees', 'referral': 'https://www.coinex.com/register?refer_code=yw5fz', }, 'api': { 'public': { 'get': { 'amm/market': 1, 'common/currency/rate': 1, 'common/asset/config': 1, 'common/maintain/info': 1, 'common/temp-maintain/info': 1, 'margin/market': 1, 'market/info': 1, 'market/list': 1, 'market/ticker': 1, 'market/ticker/all': 1, 'market/depth': 1, 'market/deals': 1, 'market/kline': 1, 'market/detail': 1, }, }, 'private': { 'get': { 'account/amm/balance': 1, 'account/investment/balance': 1, 'account/balance/history': 1, 'account/market/fee': 1, 'balance/coin/deposit': 1, 'balance/coin/withdraw': 1, 'balance/info': 1, 'balance/deposit/address/{coin_type}': 1, 'contract/transfer/history': 1, 'credit/info': 1, 'credit/balance': 1, 'investment/transfer/history': 1, 'margin/account': 1, 'margin/config': 1, 'margin/loan/history': 1, 'margin/transfer/history': 1, 'order': 1, 'order/deals': 1, 'order/finished': 1, 'order/pending': 1, 'order/status': 1, 'order/status/batch': 1, 'order/user/deals': 1, 'order/stop/finished': 1, 'order/stop/pending': 1, 'order/user/trade/fee': 1, 'order/market/trade/info': 1, 'sub_account/balance': 1, 'sub_account/transfer/history': 1, 'sub_account/auth/api/{user_auth_id}': 1, }, 'post': { 'balance/coin/withdraw': 1, 'contract/balance/transfer': 1, 'margin/flat': 1, 'margin/loan': 1, 'margin/transfer': 1, 'order/limit/batch': 1, 'order/ioc': 1, 'order/limit': 1, 'order/market': 1, 'order/stop/limit': 1, 'order/stop/market': 1, 'sub_account/transfer': 1, 'sub_account/register': 1, 'sub_account/unfrozen': 1, 'sub_account/frozen': 1, 'sub_account/auth/api': 1, }, 'put': { 'balance/deposit/address/{coin_type}': 1, 'sub_account/auth/api/{user_auth_id}': 1, 'v1/account/settings': 1, }, 'delete': { 'balance/coin/withdraw': 1, 'order/pending/batch': 1, 'order/pending': 1, 'order/stop/pending': 1, 'order/stop/pending/{id}': 1, 'sub_account/auth/api/{user_auth_id}': 1, }, }, 'perpetualPublic': { 'get': { 'ping': 1, 'time': 1, 'market/list': 1, 'market/limit_config': 1, 'market/ticker': 1, 'market/ticker/all': 1, 'market/depth': 1, 'market/deals': 1, 'market/funding_history': 1, 'market/user_deals': 1, 'market/kline': 1, }, }, 'perpetualPrivate': { 'get': { 'asset/query': 1, 'order/pending': 1, 'order/finished': 1, 'order/stop_pending': 1, 'order/status': 1, 'order/stop_status': 1, 'position/pending': 1, 'position/funding': 1, }, 'post': { 'market/adjust_leverage': 1, 'market/position_expect': 1, 'order/put_limit': 1, 'order/put_market': 1, 'order/put_stop_limit': 1, 'order/put_stop_market': 1, 'order/cancel': 1, 'order/cancel_all': 1, 'order/cancel_stop': 1, 'order/cancel_stop_all': 1, 'order/close_limit': 1, 'order/close_market': 1, 'position/adjust_margin': 1, }, }, }, 'fees': { 'trading': { 'maker': 0.001, 'taker': 0.001, }, 'funding': { 'withdraw': { 'BCH': 0.0, 'BTC': 0.001, 'LTC': 0.001, 'ETH': 0.001, 'ZEC': 0.0001, 'DASH': 0.0001, }, }, }, 'limits': { 'amount': { 'min': 0.001, 'max': undefined, }, }, 'precision': { 'amount': 8, 'price': 8, }, 'options': { 'createMarketBuyOrderRequiresPrice': true, 'defaultType': 'spot', // spot, swap, margin 'defaultSubType': 'linear', // linear, inverse 'defaultMarginType': 'isolated', // isolated, cross }, 'commonCurrencies': { 'ACM': 'Actinium', }, }); } async fetchMarkets (params = {}) { let result = []; const [ type, query ] = this.handleMarketTypeAndParams ('fetchMarkets', undefined, params); if (type === 'spot' || type === 'margin') { result = await this.fetchSpotMarkets (query); } else if (type === 'swap') { result = await this.fetchContractMarkets (query); } else { throw new ExchangeError (this.id + " does not support the '" + type + "' market type, set exchange.options['defaultType'] to 'spot', 'margin' or 'swap'"); } return result; } async fetchSpotMarkets (params) { const response = await this.publicGetMarketInfo (params); // // { // "code": 0, // "data": { // "WAVESBTC": { // "name": "WAVESBTC", // "min_amount": "1", // "maker_fee_rate": "0.001", // "taker_fee_rate": "0.001", // "pricing_name": "BTC", // "pricing_decimal": 8, // "trading_name": "WAVES", // "trading_decimal": 8 // } // } // } // const markets = this.safeValue (response, 'data', {}); const result = []; const keys = Object.keys (markets); for (let i = 0; i < keys.length; i++) { const key = keys[i]; const market = markets[key]; const id = this.safeString (market, 'name'); const tradingName = this.safeString (market, 'trading_name'); const baseId = tradingName; const quoteId = this.safeString (market, 'pricing_name'); const base = this.safeCurrencyCode (baseId); const quote = this.safeCurrencyCode (quoteId); let symbol = base + '/' + quote; if (tradingName === id) { symbol = id; } result.push ({ 'id': id, 'symbol': symbol, 'base': base, 'quote': quote, 'settle': undefined, 'baseId': baseId, 'quoteId': quoteId, 'settleId': undefined, 'type': 'spot', 'spot': true, 'margin': undefined, 'swap': false, 'future': false, 'option': false, 'active': undefined, 'contract': false, 'linear': undefined, 'inverse': undefined, 'taker': this.safeNumber (market, 'taker_fee_rate'), 'maker': this.safeNumber (market, 'maker_fee_rate'), 'contractSize': undefined, 'expiry': undefined, 'expiryDatetime': undefined, 'strike': undefined, 'optionType': undefined, 'precision': { 'amount': this.safeInteger (market, 'trading_decimal'), 'price': this.safeInteger (market, 'pricing_decimal'), }, 'limits': { 'leverage': { 'min': undefined, 'max': undefined, }, 'amount': { 'min': this.safeNumber (market, 'min_amount'), 'max': undefined, }, 'price': { 'min': undefined, 'max': undefined, }, 'cost': { 'min': undefined, 'max': undefined, }, }, 'info': market, }); } return result; } async fetchContractMarkets (params) { const response = await this.perpetualPublicGetMarketList (params); // // { // "code": 0, // "data": [ // { // "name": "BTCUSD", // "type": 2, // 1: USDT-M Contracts, 2: Coin-M Contracts // "leverages": ["3", "5", "8", "10", "15", "20", "30", "50", "100"], // "stock": "BTC", // "money": "USD", // "fee_prec": 5, // "stock_prec": 8, // "money_prec": 1, // "amount_prec": 0, // "amount_min": "10", // "multiplier": "1", // "tick_size": "0.1", // Min. Price Increment // "available": true // }, // ], // "message": "OK" // } // const markets = this.safeValue (response, 'data', []); const result = []; for (let i = 0; i < markets.length; i++) { const entry = markets[i]; const fees = this.fees; const leverages = this.safeValue (entry, 'leverages', []); const subType = this.safeInteger (entry, 'type'); const linear = (subType === 1) ? true : false; const inverse = (subType === 2) ? true : false; const id = this.safeString (entry, 'name'); const baseId = this.safeString (entry, 'stock'); const quoteId = this.safeString (entry, 'money'); const base = this.safeCurrencyCode (baseId); const quote = this.safeCurrencyCode (quoteId); const settleId = (subType === 1) ? 'USDT' : baseId; const settle = this.safeCurrencyCode (settleId); const symbol = base + '/' + quote + ':' + settle; result.push ({ 'id': id, 'symbol': symbol, 'base': base, 'quote': quote, 'settle': settle, 'baseId': baseId, 'quoteId': quoteId, 'settleId': settleId, 'type': 'swap', 'spot': false, 'margin': false, 'swap': true, 'future': false, 'option': false, 'active': this.safeString (entry, 'available'), 'contract': true, 'linear': linear, 'inverse': inverse, 'taker': fees['trading']['taker'], 'maker': fees['trading']['maker'], 'contractSize': undefined, 'expiry': undefined, 'expiryDatetime': undefined, 'strike': undefined, 'optionType': undefined, 'precision': { 'amount': this.safeInteger (entry, 'stock_prec'), 'price': this.safeInteger (entry, 'money_prec'), }, 'limits': { 'leverage': { 'min': this.safeString (leverages, 0), 'max': this.safeString (leverages, leverages.length - 1), }, 'amount': { 'min': this.safeString (entry, 'amount_min'), 'max': undefined, }, 'price': { 'min': undefined, 'max': undefined, }, 'cost': { 'min': undefined, 'max': undefined, }, }, 'info': entry, }); } return result; } parseTicker (ticker, market = undefined) { // // Spot fetchTicker, fetchTickers // // { // "vol": "293.19415130", // "low": "38200.00", // "open": "39514.99", // "high": "39530.00", // "last": "38649.57", // "buy": "38640.20", // "buy_amount": "0.22800000", // "sell": "38640.21", // "sell_amount": "0.02828439" // } // // Swap fetchTicker, fetchTickers // // { // "vol": "7714.2175", // "low": "38200.00", // "open": "39569.23", // "high": "39569.23", // "last": "38681.37", // "buy": "38681.36", // "period": 86400, // "funding_time": 462, // "position_amount": "296.7552", // "funding_rate_last": "0.00009395", // "funding_rate_next": "0.00000649", // "funding_rate_predict": "-0.00007176", // "insurance": "16464465.09431942163278132918", // "sign_price": "38681.93", // "index_price": "38681.69500000", // "sell_total": "16.6039", // "buy_total": "19.8481", // "buy_amount": "4.6315", // "sell": "38681.37", // "sell_amount": "11.4044" // } // const timestamp = this.safeInteger (ticker, 'date'); const symbol = this.safeSymbol (undefined, market); ticker = this.safeValue (ticker, 'ticker', {}); const last = this.safeString (ticker, 'last'); return this.safeTicker ({ 'symbol': symbol, 'timestamp': timestamp, 'datetime': this.iso8601 (timestamp), 'high': this.safeString (ticker, 'high'), 'low': this.safeString (ticker, 'low'), 'bid': this.safeString (ticker, 'buy'), 'bidVolume': undefined, 'ask': this.safeString (ticker, 'sell'), 'askVolume': undefined, 'vwap': undefined, 'open': this.safeString (ticker, 'open'), 'close': last, 'last': last, 'previousClose': undefined, 'change': undefined, 'percentage': undefined, 'average': undefined, 'baseVolume': this.safeString2 (ticker, 'vol', 'volume'), 'quoteVolume': undefined, 'info': ticker, }, market, false); } async fetchTicker (symbol, params = {}) { await this.loadMarkets (); const market = this.market (symbol); const request = { 'market': market['id'], }; const method = market['swap'] ? 'perpetualPublicGetMarketTicker' : 'publicGetMarketTicker'; const response = await this[method] (this.extend (request, params)); // // Spot // // { // "code": 0, // "data": { // "date": 1651306913414, // "ticker": { // "vol": "293.19415130", // "low": "38200.00", // "open": "39514.99", // "high": "39530.00", // "last": "38649.57", // "buy": "38640.20", // "buy_amount": "0.22800000", // "sell": "38640.21", // "sell_amount": "0.02828439" // } // }, // "message": "OK" // } // // Swap // // { // "code": 0, // "data": { // "date": 1651306641500, // "ticker": { // "vol": "7714.2175", // "low": "38200.00", // "open": "39569.23", // "high": "39569.23", // "last": "38681.37", // "buy": "38681.36", // "period": 86400, // "funding_time": 462, // "position_amount": "296.7552", // "funding_rate_last": "0.00009395", // "funding_rate_next": "0.00000649", // "funding_rate_predict": "-0.00007176", // "insurance": "16464465.09431942163278132918", // "sign_price": "38681.93", // "index_price": "38681.69500000", // "sell_total": "16.6039", // "buy_total": "19.8481", // "buy_amount": "4.6315", // "sell": "38681.37", // "sell_amount": "11.4044" // } // }, // "message": "OK" // } // return this.parseTicker (response['data'], market); } async fetchTickers (symbols = undefined, params = {}) { await this.loadMarkets (); const [ marketType, query ] = this.handleMarketTypeAndParams ('fetchTickers', undefined, params); const method = (marketType === 'swap') ? 'perpetualPublicGetMarketTickerAll' : 'publicGetMarketTickerAll'; const response = await this[method] (query); // // Spot // // { // "code": 0, // "data": { // "date": 1651519857284, // "ticker": { // "PSPUSDT": { // "vol": "127131.55227034", // "low": "0.0669", // "open": "0.0688", // "high": "0.0747", // "last": "0.0685", // "buy": "0.0676", // "buy_amount": "702.70117866", // "sell": "0.0690", // "sell_amount": "686.76861562" // }, // } // }, // "message": "Ok" // } // // Swap // // { // "code": 0, // "data": { // "date": 1651520268644, // "ticker": { // "KAVAUSDT": { // "vol": "834924", // "low": "3.9418", // "open": "4.1834", // "high": "4.4328", // "last": "4.0516", // "buy": "4.0443", // "period": 86400, // "funding_time": 262, // "position_amount": "16111", // "funding_rate_last": "-0.00069514", // "funding_rate_next": "-0.00061009", // "funding_rate_predict": "-0.00055812", // "insurance": "16532425.53026084124483989548", // "sign_price": "4.0516", // "index_price": "4.0530", // "sell_total": "59446", // "buy_total": "62423", // "buy_amount": "959", // "sell": "4.0466", // "sell_amount": "141" // }, // } // }, // "message": "Ok" // } // const data = this.safeValue (response, 'data'); const timestamp = this.safeInteger (data, 'date'); const tickers = this.safeValue (data, 'ticker'); const marketIds = Object.keys (tickers); const result = {}; for (let i = 0; i < marketIds.length; i++) { const marketId = marketIds[i]; const market = this.safeMarket (marketId); const symbol = market['symbol']; const ticker = this.parseTicker ({ 'date': timestamp, 'ticker': tickers[marketId], }, market); ticker['symbol'] = symbol; result[symbol] = ticker; } return this.filterByArray (result, 'symbol', symbols); } async fetchOrderBook (symbol, limit = 20, params = {}) { if (symbol === undefined) { throw new ArgumentsRequired (this.id + ' fetchOrderBook() requires a symbol argument'); } await this.loadMarkets (); const market = this.market (symbol); if (limit === undefined) { limit = 20; // default } const request = { 'market': this.marketId (symbol), 'merge': '0.0000000001', 'limit': limit.toString (), }; const method = market['swap'] ? 'perpetualPublicGetMarketDepth' : 'publicGetMarketDepth'; const response = await this[method] (this.extend (request, params)); // // Spot // // { // "code": 0, // "data": { // "asks": [ // ["41056.33", "0.31727613"], // ["41056.34", "1.05657294"], // ["41056.35", "0.02346648"] // ], // "bids": [ // ["41050.61", "0.40618608"], // ["41046.98", "0.13800000"], // ["41046.56", "0.22579234"] // ], // "last": "41050.61", // "time": 1650573220346 // }, // "message": "OK" // } // // Swap // // { // "code": 0, // "data": { // "asks": [ // ["40620.90", "0.0384"], // ["40625.50", "0.0219"], // ["40625.90", "0.3506"] // ], // "bids": [ // ["40620.89", "19.6861"], // ["40620.80", "0.0012"], // ["40619.87", "0.0365"] // ], // "last": "40620.89", // "time": 1650587672406, // "sign_price": "40619.32", // "index_price": "40609.93" // }, // "message": "OK" // } // const result = this.safeValue (response, 'data', {}); const timestamp = this.safeInteger (result, 'time'); return this.parseOrderBook (result, symbol, timestamp); } parseTrade (trade, market = undefined) { // // Spot and Swap fetchTrades (public) // // { // "id": 2611511379, // "type": "buy", // "price": "192.63", // "amount": "0.02266931", // "date": 1638990110, // "date_ms": 1638990110518 // }, // // Spot fetchMyTrades (private) // // { // "id": 2611520950, // "order_id": 63286573298, // "account_id": 0, // "create_time": 1638990636, // "type": "sell", // "role": "taker", // "price": "192.29", // "amount": "0.098", // "fee": "0.03768884", // "fee_asset": "USDT", // "market": "AAVEUSDT", // "deal_money": "18.84442" // } // // Swap fetchMyTrades (private) // // { // "amount": "0.0012", // "deal_fee": "0.0237528", // "deal_insurance": "0", // "deal_margin": "15.8352", // "deal_order_id": 17797031903, // "deal_profit": "0", // "deal_stock": "47.5056", // "deal_type": 1, // "deal_user_id": 2969195, // "fee_asset": "", // "fee_discount": "0", // "fee_price": "0", // "fee_rate": "0.0005", // "fee_real_rate": "0.0005", // "id": 379044296, // "leverage": "3", // "margin_amount": "15.8352", // "market": "BTCUSDT", // "open_price": "39588", // "order_id": 17797092987, // "position_amount": "0.0012", // "position_id": 62052321, // "position_type": 1, // "price": "39588", // "role": 2, // "side": 2, // "time": 1650675936.016103, // "user_id": 3620173 // } // let timestamp = this.safeTimestamp2 (trade, 'create_time', 'time'); if (timestamp === undefined) { timestamp = this.safeInteger (trade, 'date_ms'); } const tradeId = this.safeString (trade, 'id'); const orderId = this.safeString (trade, 'order_id'); const priceString = this.safeString (trade, 'price'); const amountString = this.safeString (trade, 'amount'); const marketId = this.safeString (trade, 'market'); const symbol = this.safeSymbol (marketId, market); const costString = this.safeString (trade, 'deal_money'); let fee = undefined; const feeCostString = this.safeString2 (trade, 'fee', 'deal_fee'); if (feeCostString !== undefined) { const feeCurrencyId = this.safeString (trade, 'fee_asset'); const feeCurrencyCode = this.safeCurrencyCode (feeCurrencyId); fee = { 'cost': feeCostString, 'currency': feeCurrencyCode, }; } let takerOrMaker = this.safeString (trade, 'role'); if (takerOrMaker === '1') { takerOrMaker = 'maker'; } else if (takerOrMaker === '2') { takerOrMaker = 'taker'; } let side = undefined; if (market['type'] === 'swap') { side = this.safeInteger (trade, 'side'); if (side === 1) { side = 'sell'; } else if (side === 2) { side = 'buy'; } if (side === undefined) { side = this.safeString (trade, 'type'); } } else { side = this.safeString (trade, 'type'); } return this.safeTrade ({ 'info': trade, 'timestamp': timestamp, 'datetime': this.iso8601 (timestamp), 'symbol': symbol, 'id': tradeId, 'order': orderId, 'type': undefined, 'side': side, 'takerOrMaker': takerOrMaker, 'price': priceString, 'amount': amountString, 'cost': costString, 'fee': fee, }, market); } async fetchTrades (symbol, since = undefined, limit = undefined, params = {}) { await this.loadMarkets (); const market = this.market (symbol); const request = { 'market': market['id'], // 'last_id': 0, }; if (limit !== undefined) { request['limit'] = limit; } const method = market['swap'] ? 'perpetualPublicGetMarketDeals' : 'publicGetMarketDeals'; const response = await this[method] (this.extend (request, params)); // // Spot and Swap // // { // "code": 0, // "data": [ // { // "id": 2611511379, // "type": "buy", // "price": "192.63", // "amount": "0.02266931", // "date": 1638990110, // "date_ms": 1638990110518 // }, // ], // "message": "OK" // } // return this.parseTrades (response['data'], market, since, limit); } async fetchTradingFee (symbol, params = {}) { await this.loadMarkets (); const market = this.market (symbol); const request = { 'market': market['id'], }; const response = await this.publicGetMarketDetail (this.extend (request, params)); // // { // "code": 0, // "data": { // "name": "BTCUSDC", // "min_amount": "0.0005", // "maker_fee_rate": "0.002", // "taker_fee_rate": "0.002", // "pricing_name": "USDC", // "pricing_decimal": 2, // "trading_name": "BTC", // "trading_decimal": 8 // }, // "message": "OK" // } // const data = this.safeValue (response, 'data', {}); return this.parseTradingFee (data); } async fetchTradingFees (params = {}) { await this.loadMarkets (); const response = await this.publicGetMarketInfo (params); // // { // "code": 0, // "data": { // "WAVESBTC": { // "name": "WAVESBTC", // "min_amount": "1", // "maker_fee_rate": "0.001", // "taker_fee_rate": "0.001", // "pricing_name": "BTC", // "pricing_decimal": 8, // "trading_name": "WAVES", // "trading_decimal": 8 // } // ... // } // } // const data = this.safeValue (response, 'data', {}); const result = {}; for (let i = 0; i < this.symbols.length; i++) { const symbol = this.symbols[i]; const market = this.market (symbol); const fee = this.safeValue (data, market['id'], {}); result[symbol] = this.parseTradingFee (fee, market); } return result; } parseTradingFee (fee, market = undefined) { const marketId = this.safeValue (fee, 'name'); const symbol = this.safeSymbol (marketId, market); return { 'info': fee, 'symbol': symbol, 'maker': this.safeNumber (fee, 'maker_fee_rate'), 'taker': this.safeNumber (fee, 'taker_fee_rate'), 'percentage': true, 'tierBased': true, }; } parseOHLCV (ohlcv, market = undefined) { // // [ // 1591484400, // "0.02505349", // "0.02506988", // "0.02507000", // "0.02505304", // "343.19716223", // "8.6021323866383196", // "ETHBTC" // ] // return [ this.safeTimestamp (ohlcv, 0), this.safeNumber (ohlcv, 1), this.safeNumber (ohlcv, 3), this.safeNumber (ohlcv, 4), this.safeNumber (ohlcv, 2), this.safeNumber (ohlcv, 5), ]; } async fetchOHLCV (symbol, timeframe = '5m', since = undefined, limit = undefined, params = {}) { await this.loadMarkets (); const market = this.market (symbol); const request = { 'market': market['id'], 'type': this.timeframes[timeframe], }; if (limit !== undefined) { request['limit'] = limit; } const method = market['swap'] ? 'perpetualPublicGetMarketKline' : 'publicGetMarketKline'; const response = await this[method] (this.extend (request, params)); // // Spot // // { // "code": 0, // "data": [ // [1591484400, "0.02505349", "0.02506988", "0.02507000", "0.02505304", "343.19716223", "8.6021323866383196", "ETHBTC"], // [1591484700, "0.02506990", "0.02508109", "0.02508109", "0.02506979", "91.59841581", "2.2972047780447000", "ETHBTC"], // [1591485000, "0.02508106", "0.02507996", "0.02508106", "0.02507500", "65.15307697", "1.6340597822306000", "ETHBTC"], // ], // "message": "OK" // } // // Swap // // { // "code": 0, // "data": [ // [1650569400, "41524.64", "41489.31", "41564.61", "41480.58", "29.7060", "1233907.099562"], // [1650569700, "41489.31", "41438.29", "41489.31", "41391.87", "42.4115", "1756154.189061"], // [1650570000, "41438.29", "41482.21", "41485.05", "41427.31", "22.2892", "924000.317861"] // ], // "message": "OK" // } // const data = this.safeValue (response, 'data', []); return this.parseOHLCVs (data, market, timeframe, since, limit); } async fetchMarginBalance (params = {}) { await this.loadMarkets (); const symbol = this.safeString (params, 'symbol'); let marketId = this.safeString (params, 'market'); let market = undefined; if (symbol !== undefined) { market = this.market (symbol); marketId = market['id']; } else if (marketId === undefined) { throw new ArgumentsRequired (this.id + ' fetchMarginBalance() fetching a margin account requires a market parameter or a symbol parameter'); } params = this.omit (params, [ 'symbol', 'market' ]); const request = { 'market': marketId, }; const response = await this.privateGetMarginAccount (this.extend (request, params)); // // { // "code": 0, // "data": { // "account_id": 126, // "leverage": 3, // "market_type": "AAVEUSDT", // "sell_asset_type": "AAVE", // "buy_asset_type": "USDT", // "balance": { // "sell_type": "0.3", // borrowed // "buy_type": "30" // }, // "frozen": { // "sell_type": "0", // "buy_type": "0" // }, // "loan": { // "sell_type": "0.3", // loan // "buy_type": "0" // }, // "interest": { // "sell_type": "0.0000125", // "buy_type": "0" // }, // "can_transfer": { // "sell_type": "0.02500646", // "buy_type": "4.28635738" // }, // "warn_rate": "", // "liquidation_price": "" // }, // "message": "Success" // } // const result = { 'info': response }; const data = this.safeValue (response, 'data', {}); const free = this.safeValue (data, 'can_transfer', {}); const total = this.safeValue (data, 'balance', {}); // const sellAccount = this.account (); const sellCurrencyId = this.safeString (data, 'sell_asset_type'); const sellCurrencyCode = this.safeCurrencyCode (sellCurrencyId); sellAccount['free'] = this.safeString (free, 'sell_type'); sellAccount['total'] = this.safeString (total, 'sell_type'); result[sellCurrencyCode] = sellAccount; // const buyAccount = this.account (); const buyCurrencyId = this.safeString (data, 'buy_asset_type'); const buyCurrencyCode = this.safeCurrencyCode (buyCurrencyId); buyAccount['free'] = this.safeString (free, 'buy_type'); buyAccount['total'] = this.safeString (total, 'buy_type'); result[buyCurrencyCode] = buyAccount; // return this.safeBalance (result); } async fetchSpotBalance (params = {}) { await this.loadMarkets (); const response = await this.privateGetBalanceInfo (params); // // { // "code": 0, // "data": { // "BCH": { # BCH account // "available": "13.60109", # Available BCH // "frozen": "0.00000" # Frozen BCH // }, // "BTC": { # BTC account // "available": "32590.16", # Available BTC // "frozen": "7000.00" # Frozen BTC // }, // "ETH": { # ETH account // "available": "5.06000", # Available ETH // "frozen": "0.00000" # Frozen ETH // } // }, // "message": "Ok" // } // const result = { 'info': response }; const balances = this.safeValue (response, 'data', {}); const currencyIds = Object.keys (balances); for (let i = 0; i < currencyIds.length; i++) { const currencyId = currencyIds[i]; const code = this.safeCurrencyCode (currencyId); const balance = this.safeValue (balances, currencyId, {}); const account = this.account (); account['free'] = this.safeString (balance, 'available'); account['used'] = this.safeString (balance, 'frozen'); result[code] = account; } return this.safeBalance (result); } async fetchSwapBalance (params = {}) { await this.loadMarkets (); const response = await this.perpetualPrivateGetAssetQuery (params); // // { // "code": 0, // "data": { // "USDT": { // "available": "37.24817690383456000000", // "balance_total": "37.24817690383456000000", // "frozen": "0.00000000000000000000", // "margin": "0.00000000000000000000", // "profit_unreal": "0.00000000000000000000", // "transfer": "37.24817690383456000000" // } // }, // "message": "OK" // } // const result = { 'info': response }; const balances = this.safeValue (response, 'data', {}); const currencyIds = Object.keys (balances); for (let i = 0; i < currencyIds.length; i++) { const currencyId = currencyIds[i]; const code = this.safeCurrencyCode (currencyId); const balance = this.safeValue (balances, currencyId, {}); const account = this.account (); account['free'] = this.safeString (balance, 'available'); account['used'] = this.safeString (balance, 'frozen'); account['total'] = this.safeString (balance, 'balance_total'); result[code] = account; } return this.safeBalance (result); } async fetchBalance (params = {}) { const accountType = this.safeString (params, 'type', 'main'); params = this.omit (params, 'type'); if (accountType === 'margin') { return await this.fetchMarginBalance (params); } else if (accountType === 'swap') { return await this.fetchSwapBalance (params); } else { return await this.fetchSpotBalance (params); } } parseOrderStatus (status) { const statuses = { 'not_deal': 'open', 'part_deal': 'open', 'done': 'closed', 'cancel': 'canceled', }; return this.safeString (statuses, status, status); } parseOrder (order, market = undefined) { // // fetchOrder // // { // "amount": "0.1", // "asset_fee": "0.22736197736197736197", // "avg_price": "196.85000000000000000000", // "create_time": 1537270135, // "deal_amount": "0.1", // "deal_fee": "0", // "deal_money": "19.685", // "fee_asset": "CET", // "fee_discount": "0.5", // "id": 1788259447, // "left": "0", // "maker_fee_rate": "0", // "market": "ETHUSDT", // "order_type": "limit", // "price": "170.00000000", // "status": "done", // "taker_fee_rate": "0.0005", // "type": "sell", // } // // Spot createOrder, cancelOrder, fetchOrder // // { // "amount":"1.5", // "asset_fee":"0", // "avg_price":"0.14208538", // "client_id":"", // "create_time":1650993819, // "deal_amount":"10.55703267", // "deal_fee":"0.0029999999971787292", // "deal_money":"1.4999999985893646", // "fee_asset":null, // "fee_discount":"1", // "finished_time":null, // "id":74556296907, // "left":"0.0000000014106354", // "maker_fee_rate":"0", // "market":"DOGEUSDT", // "money_fee":"0.0029999999971787292", // "order_type":"market", // "price":"0", // "status":"done", // "stock_fee":"0", // "taker_fee_rate":"0.002", // "type":"buy" // } // // Swap createOrder, cancelOrder, fetchOrder // // { // "amount": "0.0005", // "client_id": "", // "create_time": 1651004578.618224, // "deal_asset_fee": "0.00000000000000000000", // "deal_fee": "0.00000000000000000000", // "deal_profit": "0.00000000000000000000", // "deal_stock": "0.00000000000000000000", // "effect_type": 1, // "fee_asset": "", // "fee_discount": "0.00000000000000000000", // "last_deal_amount": "0.00000000000000000000", // "last_deal_id": 0, // "last_deal_price": "0.00000000000000000000", // "last_deal_role": 0, // "last_deal_time": 0, // "last_deal_type": 0, // "left": "0.0