ccxt
Version:
1,104 lines (1,102 loc) • 278 kB
JavaScript
// ----------------------------------------------------------------------------
// 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, AccountSuspended, OperationFailed } 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';
// ---------------------------------------------------------------------------
/**
* @class coinex
* @augments Exchange
*/
export default class coinex extends Exchange {
describe() {
return this.deepExtend(super.describe(), {
'id': 'coinex',
'name': 'CoinEx',
'version': 'v2',
'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
// v1 is per 2 seconds and v2 is per 1 second
'rateLimit': 2.5,
'pro': true,
'certified': true,
'has': {
'CORS': undefined,
'spot': true,
'margin': true,
'swap': true,
'future': false,
'option': false,
'addMargin': true,
'borrowCrossMargin': false,
'borrowIsolatedMargin': true,
'cancelAllOrders': true,
'cancelOrder': true,
'cancelOrders': true,
'closeAllPositions': false,
'closePosition': true,
'createDepositAddress': true,
'createMarketBuyOrderWithCost': true,
'createMarketOrderWithCost': false,
'createMarketSellOrderWithCost': false,
'createOrder': true,
'createOrders': true,
'createReduceOnlyOrder': true,
'createStopLossOrder': true,
'createStopOrder': true,
'createTakeProfitOrder': true,
'createTriggerOrder': true,
'editOrder': true,
'fetchBalance': true,
'fetchBorrowInterest': true,
'fetchBorrowRateHistories': false,
'fetchBorrowRateHistory': false,
'fetchClosedOrders': true,
'fetchCrossBorrowRate': false,
'fetchCrossBorrowRates': false,
'fetchCurrencies': true,
'fetchDepositAddress': true,
'fetchDepositAddresses': false,
'fetchDepositAddressesByNetwork': false,
'fetchDeposits': true,
'fetchDepositWithdrawFee': true,
'fetchDepositWithdrawFees': false,
'fetchFundingHistory': true,
'fetchFundingInterval': true,
'fetchFundingIntervals': false,
'fetchFundingRate': true,
'fetchFundingRateHistory': true,
'fetchFundingRates': true,
'fetchIndexOHLCV': false,
'fetchIsolatedBorrowRate': true,
'fetchIsolatedBorrowRates': false,
'fetchLeverage': true,
'fetchLeverages': false,
'fetchLeverageTiers': true,
'fetchMarginAdjustmentHistory': true,
'fetchMarketLeverageTiers': 'emulated',
'fetchMarkets': true,
'fetchMarkOHLCV': false,
'fetchMyTrades': true,
'fetchOHLCV': true,
'fetchOpenOrders': true,
'fetchOrder': true,
'fetchOrderBook': true,
'fetchPosition': true,
'fetchPositionHistory': true,
'fetchPositions': true,
'fetchPositionsHistory': false,
'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,
'repayCrossMargin': false,
'repayIsolatedMargin': 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://docs.coinex.com/api/v2',
'fees': 'https://www.coinex.com/fees',
'referral': 'https://www.coinex.com/register?refer_code=yw5fz',
},
'api': {
'v1': {
'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/unfrozen': 40,
'sub_account/frozen': 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,
'order/pending/by_client_id': 40,
'order/stop/pending/by_client_id': 40,
'sub_account/auth/api/{user_auth_id}': 40,
'sub_account/authorize/{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/kline': 1,
},
},
'perpetualPrivate': {
'get': {
'market/user_deals': 1,
'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/finished': 40,
'position/pending': 40,
'position/funding': 40,
'position/adl_history': 40,
'market/preference': 40,
'position/margin_history': 40,
'position/settle_history': 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,
'order/cancel/by_client_id': 20,
'order/cancel_stop/by_client_id': 20,
'market/preference': 20,
},
},
},
'v2': {
'public': {
'get': {
'maintain/info': 1,
'ping': 1,
'time': 1,
'spot/market': 1,
'spot/ticker': 1,
'spot/depth': 1,
'spot/deals': 1,
'spot/kline': 1,
'spot/index': 1,
'futures/market': 1,
'futures/ticker': 1,
'futures/depth': 1,
'futures/deals': 1,
'futures/kline': 1,
'futures/index': 1,
'futures/funding-rate': 1,
'futures/funding-rate-history': 1,
'futures/position-level': 1,
'futures/liquidation-history': 1,
'futures/basis-history': 1,
'assets/deposit-withdraw-config': 1,
'assets/all-deposit-withdraw-config': 1,
},
},
'private': {
'get': {
'account/subs': 1,
'account/subs/api-detail': 40,
'account/subs/info': 1,
'account/subs/api': 40,
'account/subs/transfer-history': 40,
'account/subs/spot-balance': 1,
'account/trade-fee-rate': 40,
'assets/spot/balance': 40,
'assets/futures/balance': 40,
'assets/margin/balance': 1,
'assets/financial/balance': 40,
'assets/amm/liquidity': 40,
'assets/credit/info': 40,
'assets/margin/borrow-history': 40,
'assets/margin/interest-limit': 1,
'assets/deposit-address': 40,
'assets/deposit-history': 40,
'assets/withdraw': 40,
'assets/transfer-history': 40,
'spot/order-status': 8,
'spot/batch-order-status': 8,
'spot/pending-order': 8,
'spot/finished-order': 40,
'spot/pending-stop-order': 8,
'spot/finished-stop-order': 40,
'spot/user-deals': 40,
'spot/order-deals': 40,
'futures/order-status': 8,
'futures/batch-order-status': 1,
'futures/pending-order': 8,
'futures/finished-order': 40,
'futures/pending-stop-order': 8,
'futures/finished-stop-order': 40,
'futures/user-deals': 1,
'futures/order-deals': 1,
'futures/pending-position': 40,
'futures/finished-position': 1,
'futures/position-margin-history': 1,
'futures/position-funding-history': 40,
'futures/position-adl-history': 1,
'futures/position-settle-history': 1,
},
'post': {
'account/subs': 40,
'account/subs/frozen': 40,
'account/subs/unfrozen': 40,
'account/subs/api': 40,
'account/subs/edit-api': 40,
'account/subs/delete-api': 40,
'account/subs/transfer': 40,
'account/settings': 40,
'assets/margin/borrow': 40,
'assets/margin/repay': 40,
'assets/renewal-deposit-address': 40,
'assets/withdraw': 40,
'assets/cancel-withdraw': 40,
'assets/transfer': 40,
'assets/amm/add-liquidity': 1,
'assets/amm/remove-liquidity': 1,
'spot/order': 13.334,
'spot/stop-order': 13.334,
'spot/batch-order': 40,
'spot/batch-stop-order': 1,
'spot/modify-order': 13.334,
'spot/modify-stop-order': 13.334,
'spot/cancel-all-order': 1,
'spot/cancel-order': 6.667,
'spot/cancel-stop-order': 6.667,
'spot/cancel-batch-order': 10,
'spot/cancel-batch-stop-order': 10,
'spot/cancel-order-by-client-id': 1,
'spot/cancel-stop-order-by-client-id': 1,
'futures/order': 20,
'futures/stop-order': 20,
'futures/batch-order': 1,
'futures/batch-stop-order': 1,
'futures/modify-order': 20,
'futures/modify-stop-order': 20,
'futures/cancel-all-order': 1,
'futures/cancel-order': 10,
'futures/cancel-stop-order': 10,
'futures/cancel-batch-order': 20,
'futures/cancel-batch-stop-order': 20,
'futures/cancel-order-by-client-id': 1,
'futures/cancel-stop-order-by-client-id': 1,
'futures/close-position': 20,
'futures/adjust-position-margin': 20,
'futures/adjust-position-leverage': 20,
'futures/set-position-stop-loss': 20,
'futures/set-position-take-profit': 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': {
'brokerId': 'x-167673045',
'createMarketBuyOrderRequiresPrice': true,
'defaultType': 'spot',
'defaultSubType': 'linear',
'fetchDepositAddress': {
'fillResponseFromRequest': true,
},
'accountsByType': {
'spot': 'SPOT',
'margin': 'MARGIN',
'swap': 'FUTURES',
},
'accountsById': {
'SPOT': 'spot',
'MARGIN': 'margin',
'FUTURES': 'swap',
},
'networks': {
'BTC': 'BTC',
'BEP20': 'BSC',
'TRC20': 'TRC20',
'ERC20': 'ERC20',
'BRC20': 'BRC20',
'SOL': 'SOL',
'TON': 'TON',
'BSV': 'BSV',
'AVAXC': 'AVA_C',
'AVAXX': 'AVA',
'SUI': 'SUI',
'ACA': 'ACA',
'CHZ': 'CHILIZ',
'ADA': 'ADA',
'ARB': 'ARBITRUM',
'ARBNOVA': 'ARBITRUM_NOVA',
'OP': 'OPTIMISM',
'APT': 'APTOS',
'ATOM': 'ATOM',
'FTM': 'FTM',
'BCH': 'BCH',
'ASTR': 'ASTR',
'LTC': 'LTC',
'MATIC': 'MATIC',
'CRONOS': 'CRONOS',
'DASH': 'DASH',
'DOT': 'DOT',
'ETC': 'ETC',
'ETHW': 'ETHPOW',
'FIL': 'FIL',
'ZIL': 'ZIL',
'DOGE': 'DOGE',
'TIA': 'CELESTIA',
'SEI': 'SEI',
'XRP': 'XRP',
'XMR': 'XMR',
// CSC, AE, BASE, AIPG, AKASH, POLKADOTASSETHUB ?, ALEO, STX, ALGO, ALPH, BLAST, AR, ARCH, ARDR, ARK, ARRR, MANTA, NTRN, LUNA, AURORA, AVAIL, ASC20, AVA, AYA, AZERO, BAN, BAND, BB, RUNES, BEAM, BELLSCOIN, BITCI, NEAR, AGORIC, BLOCX, BNC, BOBA, BRISE, KRC20, CANTO, CAPS, CCD, CELO, CFX, CHI, CKB, CLORE, CLV, CORE, CSPR, CTXC, DAG, DCR, DERO, DESO, DEFI, DGB, DNX, DOCK, DOGECHAIN, DYDX, DYMENSION, EGLD, ELA, ELF, ENJIN, EOSIO, ERG, ETN_SC, EVMOS, EWC, SGB, FACT, FB, FET, FIO, FIRO, NEO3, FLOW, FLARE, FLUX, LINEA, FREN, FSN, FB_BRC20, GLMR, GRIN, GRS, HACASH, HBAR, HERB, HIVE, MAPO, HMND, HNS, ZKSYNC, HTR, HUAHUA, MERLIN, ICP, ICX, INJ, IOST, IOTA, IOTX, IRIS, IRON, ONE, JOYSTREAM, KAI, KAR, KAS, KAVA, KCN, KDA, KLAY, KLY, KMD, KSM, KUB, KUJIRA, LAT, LBC, LUNC, LUKSO, MARS, METIS, MINA, MANTLE, MOB, MODE, MONA, MOVR, MTL, NEOX, NEXA, NIBI, NIMIQ, NMC, ONOMY, NRG, WAVES, NULS, OAS, OCTA, OLT, ONT, OORT, ORAI, OSMO, P3D, COMPOSABLE, PIVX, RON, POKT, POLYMESH, PRE_MARKET, PYI, QKC, QTUM, QUBIC, RSK, ROSE, ROUTE, RTM, THORCHAIN, RVN, RADIANT, SAGA, SALVIUM, SATOX, SC, SCP, _NULL, SCRT, SDN, RGBPP, SELF, SMH, SPACE, STARGAZE, STC, STEEM, STRATISEVM, STRD, STARKNET, SXP, SYS, TAIKO, TAO, TARA, TENET, THETA, TT, VENOM, VECHAIN, TOMO, VITE, VLX, VSYS, VTC, WAN, WAXP, WEMIX, XCH, XDC, XEC, XELIS, NEM, XHV, XLM, XNA, NANO, XPLA, XPR, XPRT, XRD, XTZ, XVG, XYM, ZANO, ZEC, ZEN, ZEPH, ZETA
},
},
'features': {
'spot': {
'sandbox': false,
'createOrder': {
'marginMode': true,
'triggerPrice': true,
'triggerPriceType': undefined,
'triggerDirection': false,
'stopLossPrice': false,
'takeProfitPrice': false,
'attachedStopLossTakeProfit': undefined,
'timeInForce': {
'IOC': true,
'FOK': true,
'PO': true,
'GTD': false,
},
'hedged': false,
'trailing': false,
'leverage': false,
'marketBuyByCost': true,
'marketBuyRequiresPrice': true,
'selfTradePrevention': true,
'iceberg': true, // todo implement
},
'createOrders': {
'max': 5,
},
'fetchMyTrades': {
'marginMode': true,
'limit': 1000,
'daysBack': undefined,
'untilDays': 100000,
'symbolRequired': true,
},
'fetchOrder': {
'marginMode': false,
'trigger': false,
'trailing': false,
'symbolRequired': true,
},
'fetchOpenOrders': {
'marginMode': true,
'limit': 1000,
'trigger': true,
'trailing': false,
'symbolRequired': false,
},
'fetchOrders': undefined,
'fetchClosedOrders': {
'marginMode': true,
'limit': 1000,
'daysBack': undefined,
'daysBackCanceled': undefined,
'untilDays': undefined,
'trigger': true,
'trailing': false,
'symbolRequired': false,
},
'fetchOHLCV': {
'limit': 1000,
},
},
'forDerivatives': {
'extends': 'spot',
'createOrder': {
'marginMode': true,
'stopLossPrice': true,
'takeProfitPrice': true,
},
'fetchOpenOrders': {
'marginMode': false,
},
'fetchClosedOrders': {
'marginMode': false,
},
},
'swap': {
'linear': {
'extends': 'forDerivatives',
},
'inverse': {
'extends': 'forDerivatives',
},
},
'future': {
'linear': undefined,
'inverse': undefined,
},
},
'commonCurrencies': {
'ACM': 'Actinium',
},
'precisionMode': TICK_SIZE,
'exceptions': {
'exact': {
// https://github.com/coinexcom/coinex_exchange_api/wiki/013error_code
'23': PermissionDenied,
'24': AuthenticationError,
'25': AuthenticationError,
'34': AuthenticationError,
'35': ExchangeNotAvailable,
'36': RequestTimeout,
'213': RateLimitExceeded,
'107': InsufficientFunds,
'158': PermissionDenied,
'600': OrderNotFound,
'601': InvalidOrder,
'602': InvalidOrder,
'606': InvalidOrder,
'3008': RequestTimeout,
'3109': InsufficientFunds,
'3127': InvalidOrder,
'3600': OrderNotFound,
'3606': InvalidOrder,
'3610': ExchangeError,
'3612': InvalidOrder,
'3613': InvalidOrder,
'3614': InvalidOrder,
'3615': InvalidOrder,
'3616': InvalidOrder,
'3617': InvalidOrder,
'3618': InvalidOrder,
'3619': InvalidOrder,
'3620': InvalidOrder,
'3621': InvalidOrder,
'3622': InvalidOrder,
'3627': InvalidOrder,
'3628': InvalidOrder,
'3629': InvalidOrder,
'3632': InvalidOrder,
'3633': InvalidOrder,
'3634': InvalidOrder,
'3635': InvalidOrder,
'4001': ExchangeNotAvailable,
'4002': RequestTimeout,
'4003': ExchangeError,
'4004': BadRequest,
'4005': AuthenticationError,
'4006': AuthenticationError,
'4007': PermissionDenied,
'4008': AuthenticationError,
'4009': ExchangeError,
'4010': ExchangeError,
'4011': PermissionDenied,
'4017': ExchangeError,
'4115': AccountSuspended,
'4117': BadSymbol,
'4123': RateLimitExceeded,
'4130': ExchangeError,
'4158': ExchangeError,
'4213': RateLimitExceeded,
'4512': PermissionDenied, // Insufficient sub-account permissions, please check.
},
'broad': {
'ip not allow visit': PermissionDenied,
'service too busy': ExchangeNotAvailable,
'Service is not available during funding fee settlement': OperationFailed,
},
},
});
}
/**
* @method
* @name coinex#fetchCurrencies
* @description fetches all available currencies on an exchange
* @see https://docs.coinex.com/api/v2/assets/deposit-withdrawal/http/list-all-deposit-withdrawal-config
* @param {object} [params] extra parameters specific to the exchange API endpoint
* @returns {object} an associative dictionary of currencies
*/
async fetchCurrencies(params = {}) {
const response = await this.v2PublicGetAssetsAllDepositWithdrawConfig(params);
//
// {
// "code": 0,
// "data": [
// {
// "asset": {
// "ccy": "CET",
// "deposit_enabled": true,
// "withdraw_enabled": true,
// "inter_transfer_enabled": true,
// "is_st": false
// },
// "chains": [
// {
// "chain": "CSC",
// "min_deposit_amount": "0.8",
// "min_withdraw_amount": "8",
// "deposit_enabled": true,
// "withdraw_enabled": true,
// "deposit_delay_minutes": 0,
// "safe_confirmations": 10,
// "irreversible_confirmations": 20,
// "deflation_rate": "0",
// "withdrawal_fee": "0.026",
// "withdrawal_precision": 8,
// "memo": "",
// "is_memo_required_for_deposit": false,
// "explorer_asset_url": ""
// },
// ]
// }
// ],
// "message": "OK"
// }
//
const data = this.safeList(response, 'data', []);
const result = {};
for (let i = 0; i < data.length; i++) {
const coin = data[i];
const asset = this.safeDict(coin, 'asset', {});
const chains = this.safeList(coin, 'chains', []);
const currencyId = this.safeString(asset, 'ccy');
if (currencyId === undefined) {
continue; // coinex returns empty structures for some reason
}
const code = this.safeCurrencyCode(currencyId);
const canDeposit = this.safeBool(asset, 'deposit_enabled');
const canWithdraw = this.safeBool(asset, 'withdraw_enabled');
const firstChain = this.safeDict(chains, 0, {});
const firstPrecisionString = this.parsePrecision(this.safeString(firstChain, 'withdrawal_precision'));
const networks = {};
for (let j = 0; j < chains.length; j++) {
const chain = chains[j];
const networkId = this.safeString(chain, 'chain');
if (networkId === undefined) {
continue;
}
const precisionString = this.parsePrecision(this.safeString(chain, 'withdrawal_precision'));
const feeString = this.safeString(chain, 'withdrawal_fee');
const minNetworkDepositString = this.safeString(chain, 'min_deposit_amount');
const minNetworkWithdrawString = this.safeString(chain, 'min_withdraw_amount');
const canDepositChain = this.safeBool(chain, 'deposit_enabled');
const canWithdrawChain = this.safeBool(chain, 'withdraw_enabled');
const network = {
'id': networkId,
'network': networkId,
'name': undefined,
'active': canDepositChain && canWithdrawChain,
'deposit': canDepositChain,
'withdraw': canWithdrawChain,
'fee': this.parseNumber(feeString),
'precision': this.parseNumber(precisionString),
'limits': {
'amount': {
'min': undefined,
'max': undefined,
},
'deposit': {
'min': this.parseNumber(minNetworkDepositString),
'max': undefined,
},
'withdraw': {
'min': this.parseNumber(minNetworkWithdrawString),
'max': undefined,
},
},
'info': chain,
};
networks[networkId] = network;
}
result[code] = this.safeCurrencyStructure({
'id': currencyId,
'code': code,
'name': undefined,
'active': canDeposit && canWithdraw,
'deposit': canDeposit,
'withdraw': canWithdraw,
'fee': undefined,
'precision': this.parseNumber(firstPrecisionString),
'limits': {
'amount': {
'min': undefined,
'max': undefined,
},
'deposit': {
'min': undefined,
'max': undefined,
},
'withdraw': {
'min': undefined,
'max': undefined,
},
},
'networks': networks,
'type': 'crypto',
'info': coin,
});
}
return result;
}
/**
* @method
* @name coinex#fetchMarkets
* @description retrieves data on all markets for coinex
* @see https://docs.coinex.com/api/v2/spot/market/http/list-market
* @see https://docs.coinex.com/api/v2/futures/market/http/list-market
* @param {object} [params] extra parameters specific to the exchange API endpoint
* @returns {object[]} an array of objects representing market data
*/
async fetchMarkets(params = {}) {
const promisesUnresolved = [
this.fetchSpotMarkets(params),
this.fetchContractMarkets(params),
];
const promises = await Promise.all(promisesUnresolved);
const spotMarkets = promises[0];
const swapMarkets = promises[1];
return this.arrayConcat(spotMarkets, swapMarkets);
}
async fetchSpotMarkets(params) {
const response = await this.v2PublicGetSpotMarket(params);
//
// {
// "code": 0,
// "data": [
// {
// "market": "BTCUSDT",
// "taker_fee_rate": "0.002",
// "maker_fee_rate": "0.002",
// "min_amount": "0.0005",
// "base_ccy": "BTC",
// "quote_ccy": "USDT",
// "base_ccy_precision": 8,
// "quote_ccy_precision": 2,
// "is_amm_available": true,
// "is_margin_available": true,
// "is_pre_trading_available": true,
// "is_api_trading_available": true
// }
// ],
// "message": "OK"
// }
//
const markets = this.safeList(response, 'data', []);
const result = [];
for (let i = 0; i < markets.length; i++) {
const market = markets[i];
const id = this.safeString(market, 'market');
const baseId = this.safeString(market, 'base_ccy');
const quoteId = this.safeString(market, 'quote_ccy');
const base = this.safeCurrencyCode(baseId);
const quote = this.safeCurrencyCode(quoteId);
const symbol = base + '/' + quote;
result.push({
'id': id,
'symbol': symbol,
'base': base,
'quote': quote,
'settle': undefined,
'baseId': baseId,
'quoteId': quoteId,
'settleId': undefined,
'type': 'spot',
'spot': true,
'margin': this.safeBool(market, 'is_margin_available'),
'swap': false,
'future': false,
'option': false,
'active': this.safeBool(market, 'is_api_trading_available'),
'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, 'base_ccy_precision'))),
'price': this.parseNumber(this.parsePrecision(this.safeString(market, 'quote_ccy_precision'))),
},
'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,
},
},
'created': undefined,
'info': market,
});
}
return result;
}
async fetchContractMarkets(params) {
const response = await this.v2PublicGetFuturesMarket(params);
//
// {
// "code": 0,
// "data": [
// {
// "base_ccy": "BTC",
// "base_ccy_precision": 8,
// "contract_type": "inverse",
// "leverage": ["1","2","3","5","8","10","15","20","30","50","100"],
// "maker_fee_rate": "0",
// "market": "BTCUSD",
// "min_amount": "10",
// "open_interest_volume": "2566879",
// "quote_ccy": "USD",
// "quote_ccy_precision": 2,
// "taker_fee_rate": "0"
// },
// ],
// "message": "OK"
// }
//
const markets = this.safeList(response, 'data', []);
const result = [];
for (let i = 0; i < markets.length; i++) {
const entry = markets[i];
const fees = this.fees;
const leverages = this.safeList(entry, 'leverage', []);
const subType = this.safeString(entry, 'contract_type');
const linear = (subType === 'linear');
const inverse = (subType === 'inverse');
const id = this.safeString(entry, 'market');
const baseId = this.safeString(entry, 'base_ccy');
const quoteId = this.safeString(entry, 'quote_ccy');
const base = this.safeCurrencyCode(baseId);
const quote = this.safeCurrencyCode(quoteId);
const settleId = (subType === 'linear') ? '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': undefined,
'contract': true,
'linear': linear,
'inverse': inverse,
'taker': fees['trading']['taker'],
'maker': fees['trading']['maker'],
'contractSize': this.parseNumber('1'),
'expiry': undefined,
'expiryDatetime': undefined,
'strike': undefined,
'optionType': undefined,
'precision': {
'amount': this.parseNumber(this.parsePrecision(this.safeString(entry, 'base_ccy_precision'))),
'price': this.parseNumber(this.parsePrecision(this.safeString(entry, 'quote_ccy_precision'))),
},
'limits': {
'leverage': {
'min': this.safeNumber(leverages, 0),
'max': this.safeNumber(leverages, leveragesLength - 1),
},
'amount': {
'min': this.safeNumber(entry, 'min_amount'),
'max': undefined,
},
'price': {
'min': undefined,
'max': undefined,
},
'cost': {
'min': undefined,
'max': undefined,
},
},
'created': undefined,
'info': entry,
});
}
return result;
}
parseTicker(ticker, market = undefined) {
//
// Spot fetchTicker, fetchTickers
//
// {
// "close": "62393.47",
// "high": "64106.41",
// "last": "62393.47",
// "low": "59650.01",
// "market": "BTCUSDT",
// "open": "61616.15",
// "period": 86400,
// "value": "28711273.4065667262",
// "volume": "461.76557205",
// "volume_buy": "11.41506354",
// "volume_sell": "7.3240169"
// }
//
// Swap fetchTicker, fetchTickers
//
// {
// "close": "62480.08",
// "high": "64100",
// "index_price": "62443.05",
// "last": "62480.08",
// "low": "59600",
// "mark_price": "62443.05",
// "market": "BTCUSDT",
// "open": "61679.98",
// "period": 86400,
// "value": "180226025.69791713065326633165",
// "volume": "2900.2218",
// "volume_buy": "7.3847",
// "volume_sell": "6.1249"
// }
//
const marketType = ('mark_price' in ticker) ? 'swap' : 'spot';
const marketId = this.safeString(ticker, 'market');
const symbol = this.safeSymbol(marketId, market, undefined, marketType);
return this.safeTicker({
'symbol': symbol,
'timestamp': undefined,
'datetime': undefined,
'high': this.safeString(ticker, 'high'),
'low': this.safeString(ticker, 'low'),
'bid': undefined,
'bidVolume': this.safeString(ticker, 'volume_buy'),
'ask': undefined,
'askVolume': this.safeString(ticker, 'volume_sell'),
'vwap': undefined,
'open': this.safeString(ticker, 'open'),
'close': this.safeString(ticker, 'close'),
'last': this.safeString(ticker, 'last'),
'previousClose': undefined,
'change': undefined,
'percentage': undefined,
'average': undefined,
'baseVolume': this.safeString(ticker, 'volume'),
'quoteVolume': undefined,
'markPrice': this.safeString(ticker, 'mark_price'),
'indexPrice': this.safeString(ticker, 'index_price'),
'info': ticker,
}, market);
}
/**
* @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
* @see https://docs.coinex.com/api/v2/spot/market/http/list-market-ticker
* @see https://docs.coinex.com/api/v2/futures/market/http/list-market-ticker
* @param {string} symbol unified symbol of the market to fetch the ticker for
* @param {object} [params] extra parameters specific to the exchange API endpoint
* @returns {object} a [ticker structure]{@link https://docs.ccxt.com/#/?id=ticker-structure}
*/
async fetchTicker(symbol, params = {}) {
await this.loadMarkets();
const market = this.market(symbol);
const request = {
'market': market['id'],
};
let response = undefined;
if (market['swap']) {
response = await this.v2PublicGetFuturesTicker(this.extend(request, params));
}
else {
response = await this.v2PublicGetSpotTicker(this.extend(request, params));
}
//
// Spot
//
// {
// "code": 0,
// "data": [
// {
// "close": "62393.47",
// "high": "64106.41",
// "last": "62393.47",
// "low": "59650.01",
// "market": "BTCUSDT",
// "open": "61616.15",
// "period": 86400,
// "value": "28711273.4065667262",
// "volume": "461.76557205",
// "volume_buy": "11.41506354",
//