UNPKG

@proton/ccxt

Version:

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

1,181 lines (1,179 loc) 208 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/coinex.js'; import { ExchangeError, ArgumentsRequired, BadSymbol, InsufficientFunds, OrderNotFound, InvalidOrder, AuthenticationError, PermissionDenied, ExchangeNotAvailable, RequestTimeout, BadRequest, RateLimitExceeded, NotSupported } 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'; import { md5 } from './static_dependencies/noble-hashes/md5.js'; // --------------------------------------------------------------------------- export default class coinex extends Exchange { describe() { return this.deepExtend(super.describe(), { 'id': 'coinex', 'name': 'CoinEx', 'version': 'v1', 'countries': ['CN'], // IP ratelimit is 400 requests per second // rateLimit = 1000ms / 400 = 2.5 // 200 per 2 seconds => 100 per second => weight = 4 // 120 per 2 seconds => 60 per second => weight = 6.667 // 80 per 2 seconds => 40 per second => weight = 10 // 60 per 2 seconds => 30 per second => weight = 13.334 // 40 per 2 seconds => 20 per second => weight = 20 // 20 per 2 seconds => 10 per second => weight = 40 'rateLimit': 2.5, 'pro': true, 'has': { 'CORS': undefined, 'spot': true, 'margin': true, 'swap': true, 'future': false, 'option': false, 'addMargin': true, 'borrowMargin': true, 'cancelAllOrders': true, 'cancelOrder': true, 'createDepositAddress': true, 'createOrder': true, 'createReduceOnlyOrder': true, 'editOrder': true, 'fetchBalance': true, 'fetchBorrowInterest': true, 'fetchBorrowRate': true, 'fetchBorrowRateHistories': false, 'fetchBorrowRateHistory': false, 'fetchBorrowRates': true, 'fetchClosedOrders': true, 'fetchCurrencies': true, 'fetchDepositAddress': true, 'fetchDepositAddressByNetwork': false, 'fetchDepositAddresses': false, 'fetchDeposits': true, 'fetchDepositWithdrawFees': true, 'fetchDepsoitWithdrawFee': 'emulated', 'fetchFundingHistory': true, 'fetchFundingRate': true, 'fetchFundingRateHistory': true, 'fetchFundingRates': true, 'fetchIndexOHLCV': false, 'fetchLeverage': false, 'fetchLeverageTiers': true, 'fetchMarketLeverageTiers': 'emulated', '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, 'fetchTime': true, 'fetchTrades': true, 'fetchTradingFee': true, 'fetchTradingFees': true, 'fetchTransfer': false, 'fetchTransfers': true, 'fetchWithdrawal': false, 'fetchWithdrawals': true, 'reduceMargin': true, 'repayMargin': 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': 40, 'account/investment/balance': 40, 'account/balance/history': 40, 'account/market/fee': 40, 'balance/coin/deposit': 40, 'balance/coin/withdraw': 40, 'balance/info': 40, 'balance/deposit/address/{coin_type}': 40, 'contract/transfer/history': 40, 'credit/info': 40, 'credit/balance': 40, 'investment/transfer/history': 40, 'margin/account': 1, 'margin/config': 1, 'margin/loan/history': 40, 'margin/transfer/history': 40, 'order/deals': 40, 'order/finished': 40, 'order/pending': 8, 'order/status': 8, 'order/status/batch': 8, 'order/user/deals': 40, 'order/stop/finished': 40, 'order/stop/pending': 8, 'order/user/trade/fee': 1, 'order/market/trade/info': 1, 'sub_account/balance': 1, 'sub_account/transfer/history': 40, 'sub_account/auth/api': 40, 'sub_account/auth/api/{user_auth_id}': 40, }, 'post': { 'balance/coin/withdraw': 40, 'contract/balance/transfer': 40, 'margin/flat': 40, 'margin/loan': 40, 'margin/transfer': 40, 'order/limit/batch': 40, 'order/ioc': 13.334, 'order/limit': 13.334, 'order/market': 13.334, 'order/modify': 13.334, 'order/stop/limit': 13.334, 'order/stop/market': 13.334, 'order/stop/modify': 13.334, 'sub_account/transfer': 40, 'sub_account/register': 1, 'sub_account/unfrozen': 40, 'sub_account/frozen': 40, 'sub_account/auth/api': 40, }, 'put': { 'balance/deposit/address/{coin_type}': 40, 'sub_account/auth/api/{user_auth_id}': 40, 'v1/account/settings': 40, }, 'delete': { 'balance/coin/withdraw': 40, 'order/pending/batch': 40, 'order/pending': 13.334, 'order/stop/pending': 40, 'order/stop/pending/{id}': 13.334, 'sub_account/auth/api/{user_auth_id}': 40, }, }, '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': 40, 'order/pending': 8, 'order/finished': 40, 'order/stop_finished': 40, 'order/stop_pending': 8, 'order/status': 8, 'order/stop_status': 8, 'position/pending': 40, 'position/funding': 40, }, 'post': { 'market/adjust_leverage': 1, 'market/position_expect': 1, 'order/put_limit': 20, 'order/put_market': 20, 'order/put_stop_limit': 20, 'order/put_stop_market': 20, 'order/modify': 20, 'order/modify_stop': 20, 'order/cancel': 20, 'order/cancel_all': 40, 'order/cancel_batch': 40, 'order/cancel_stop': 20, 'order/cancel_stop_all': 40, 'order/close_limit': 20, 'order/close_market': 20, 'position/adjust_margin': 20, 'position/stop_loss': 20, 'position/take_profit': 20, 'position/market_close': 20, }, }, }, '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, }, }, 'options': { 'createMarketBuyOrderRequiresPrice': true, 'defaultType': 'spot', 'defaultSubType': 'linear', 'fetchDepositAddress': { 'fillResponseFromRequest': true, }, 'accountsById': { 'spot': '0', }, }, 'commonCurrencies': { 'ACM': 'Actinium', }, 'precisionMode': TICK_SIZE, }); } async fetchCurrencies(params = {}) { const response = await this.publicGetCommonAssetConfig(params); // { // code: 0, // data: { // "USDT-ERC20": { // "asset": "USDT", // "chain": "ERC20", // "withdrawal_precision": 6, // "can_deposit": true, // "can_withdraw": true, // "deposit_least_amount": "4.9", // "withdraw_least_amount": "4.9", // "withdraw_tx_fee": "4.9", // "explorer_asset_url": "https://etherscan.io/token/0xdac17f958d2ee523a2206206994597c13d831ec7" // }, // ... // }, // message: 'Success', // } // const data = this.safeValue(response, 'data', []); const coins = Object.keys(data); const result = {}; for (let i = 0; i < coins.length; i++) { const coin = coins[i]; const currency = data[coin]; const currencyId = this.safeString(currency, 'asset'); const networkId = this.safeString(currency, 'chain'); const code = this.safeCurrencyCode(currencyId); const precisionString = this.parsePrecision(this.safeString(currency, 'withdrawal_precision')); const precision = this.parseNumber(precisionString); const canDeposit = this.safeValue(currency, 'can_deposit'); const canWithdraw = this.safeValue(currency, 'can_withdraw'); const feeString = this.safeString(currency, 'withdraw_tx_fee'); const fee = this.parseNumber(feeString); const minNetworkDepositString = this.safeString(currency, 'deposit_least_amount'); const minNetworkDeposit = this.parseNumber(minNetworkDepositString); const minNetworkWithdrawString = this.safeString(currency, 'withdraw_least_amount'); const minNetworkWithdraw = this.parseNumber(minNetworkWithdrawString); if (this.safeValue(result, code) === undefined) { result[code] = { 'id': currencyId, 'numericId': undefined, 'code': code, 'info': undefined, 'name': undefined, 'active': canDeposit && canWithdraw, 'deposit': canDeposit, 'withdraw': canWithdraw, 'fee': fee, 'precision': precision, 'limits': { 'amount': { 'min': undefined, 'max': undefined, }, 'deposit': { 'min': minNetworkDeposit, 'max': undefined, }, 'withdraw': { 'min': minNetworkWithdraw, 'max': undefined, }, }, }; } let minFeeString = this.safeString(result[code], 'fee'); if (feeString !== undefined) { minFeeString = (minFeeString === undefined) ? feeString : Precise.stringMin(feeString, minFeeString); } let depositAvailable = this.safeValue(result[code], 'deposit'); depositAvailable = (canDeposit) ? canDeposit : depositAvailable; let withdrawAvailable = this.safeValue(result[code], 'withdraw'); withdrawAvailable = (canWithdraw) ? canWithdraw : withdrawAvailable; let minDepositString = this.safeString(result[code]['limits']['deposit'], 'min'); if (minNetworkDepositString !== undefined) { minDepositString = (minDepositString === undefined) ? minNetworkDepositString : Precise.stringMin(minNetworkDepositString, minDepositString); } let minWithdrawString = this.safeString(result[code]['limits']['withdraw'], 'min'); if (minNetworkWithdrawString !== undefined) { minWithdrawString = (minWithdrawString === undefined) ? minNetworkWithdrawString : Precise.stringMin(minNetworkWithdrawString, minWithdrawString); } let minPrecisionString = this.safeString(result[code], 'precision'); if (precisionString !== undefined) { minPrecisionString = (minPrecisionString === undefined) ? precisionString : Precise.stringMin(precisionString, minPrecisionString); } const networks = this.safeValue(result[code], 'networks', {}); const network = { 'info': currency, 'id': networkId, 'network': networkId, 'name': undefined, 'limits': { 'amount': { 'min': undefined, 'max': undefined, }, 'deposit': { 'min': this.safeNumber(currency, 'deposit_least_amount'), 'max': undefined, }, 'withdraw': { 'min': this.safeNumber(currency, 'withdraw_least_amount'), 'max': undefined, }, }, 'active': canDeposit && canWithdraw, 'deposit': canDeposit, 'withdraw': canWithdraw, 'fee': fee, 'precision': precision, }; networks[networkId] = network; result[code]['networks'] = networks; result[code]['active'] = depositAvailable && withdrawAvailable; result[code]['deposit'] = depositAvailable; result[code]['withdraw'] = withdrawAvailable; const info = this.safeValue(result[code], 'info', []); info.push(currency); result[code]['info'] = info; result[code]['fee'] = this.parseNumber(minFeeString); result[code]['precision'] = this.parseNumber(minPrecisionString); result[code]['limits']['deposit']['min'] = this.parseNumber(minDepositString); result[code]['limits']['withdraw']['min'] = this.parseNumber(minWithdrawString); } return result; } async fetchMarkets(params = {}) { /** * @method * @name coinex#fetchMarkets * @description retrieves data on all markets for coinex * @param {object} params extra parameters specific to the exchange api endpoint * @returns {[object]} an array of objects representing market data */ let promises = [ this.fetchSpotMarkets(params), this.fetchContractMarkets(params), ]; promises = await Promise.all(promises); const spotMarkets = promises[0]; const swapMarkets = promises[1]; return this.arrayConcat(spotMarkets, swapMarkets); } 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.parseNumber(this.parsePrecision(this.safeString(market, 'trading_decimal'))), 'price': this.parseNumber(this.parsePrecision(this.safeString(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); const inverse = (subType === 2); 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; const leveragesLength = leverages.length; 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.safeValue(entry, 'available'), 'contract': true, 'linear': linear, 'inverse': inverse, 'taker': fees['trading']['taker'], 'maker': fees['trading']['maker'], 'contractSize': this.safeNumber(entry, 'multiplier'), 'expiry': undefined, 'expiryDatetime': undefined, 'strike': undefined, 'optionType': undefined, 'precision': { 'amount': this.parseNumber(this.parsePrecision(this.safeString(entry, 'amount_prec'))), 'price': this.parseNumber(this.parsePrecision(this.safeString(entry, 'money_prec'))), }, 'limits': { 'leverage': { 'min': this.safeNumber(leverages, 0), 'max': this.safeNumber(leverages, leveragesLength - 1), }, 'amount': { 'min': this.safeNumber(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); } async fetchTicker(symbol, params = {}) { /** * @method * @name coinex#fetchTicker * @description fetches a price ticker, a statistical calculation with the information calculated over the past 24 hours for a specific market * @param {string} symbol unified symbol of the market to fetch the ticker for * @param {object} params extra parameters specific to the coinex api endpoint * @returns {object} a [ticker structure]{@link https://docs.ccxt.com/#/?id=ticker-structure} */ 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 = {}) { /** * @method * @name coinex#fetchTickers * @description fetches price tickers for multiple markets, statistical calculations with the information calculated over the past 24 hours each market * @see https://viabtc.github.io/coinex_api_en_doc/spot/#docsspot001_market008_all_market_ticker * @see https://viabtc.github.io/coinex_api_en_doc/futures/#docsfutures001_http009_market_ticker_all * @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 coinex api endpoint * @returns {object} a dictionary of [ticker structures]{@link https://docs.ccxt.com/#/?id=ticker-structure} */ await this.loadMarkets(); symbols = this.marketSymbols(symbols); let market = undefined; if (symbols !== undefined) { const symbol = this.safeValue(symbols, 0); market = this.market(symbol); } const [marketType, query] = this.handleMarketTypeAndParams('fetchTickers', market, 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 marketInner = this.safeMarket(marketId, undefined, undefined, marketType); const symbol = marketInner['symbol']; const ticker = this.parseTicker({ 'date': timestamp, 'ticker': tickers[marketId], }, marketInner); ticker['symbol'] = symbol; result[symbol] = ticker; } return this.filterByArray(result, 'symbol', symbols); } async fetchTime(params = {}) { /** * @method * @name coinex#fetchTime * @description fetches the current integer timestamp in milliseconds from the exchange server * @param {object} params extra parameters specific to the coinex api endpoint * @returns {int} the current integer timestamp in milliseconds from the exchange server */ const response = await this.perpetualPublicGetTime(params); // // { // code: '0', // data: '1653261274414', // message: 'OK' // } // return this.safeNumber(response, 'data'); } async fetchOrderBook(symbol, limit = 20, params = {}) { /** * @method * @name coinex#fetchOrderBook * @description fetches information on open orders with bid (buy) and ask (sell) prices, volumes and other data * @param {string} symbol unified symbol of the market to fetch the order book for * @param {int|undefined} limit the maximum amount of order book entries to return * @param {object} params extra parameters specific to the coinex api endpoint * @returns {object} A dictionary of [order book structures]{@link https://docs.ccxt.com/#/?id=order-book-structure} indexed by market symbols */ 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', '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 and Margin 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 defaultType = this.safeString(this.options, 'defaultType'); market = this.safeMarket(marketId, market, undefined, defaultType); const symbol = this.safeSymbol(marketId, market, undefined, defaultType); 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 = {}) { /** * @method * @name coinex#fetchTrades * @description get the list of most recent trades for a particular symbol * @param {string} symbol unified symbol of the market to fetch trades for * @param {int|undefined} since timestamp in ms of the earliest trade to fetch * @param {int|undefined} limit the maximum amount of trades to fetch * @param {object} params extra parameters specific to the coinex api endpoint * @returns {[object]} a list of [trade structures]{@link https://docs.ccxt.com/en/latest/manual.html?#public-trades} */ 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 = {}) { /** * @method * @name coinex#fetchTradingFee * @description fetch the trading fees for a market * @param {string} symbol unified market symbol * @param {object} params extra parameters specific to the coinex api endpoint * @returns {object} a [fee structure]{@link https://docs.ccxt.com/#/?id=fee-structure} */ 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, market); } async fetchTradingFees(params = {}) { /** * @method * @name coinex#fetchTradingFees * @description fetch the trading fees for multiple markets * @param {object} params extra parameters specific to the coinex api endpoint * @returns {object} a dictionary of [fee structures]{@link https://docs.ccxt.com/#/?id=fee-structure} indexed by market symbols */ 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_d