UNPKG

ccxt

Version:

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

1,110 lines (1,108 loc) • 110 kB
'use strict'; var coinlist$1 = require('./abstract/coinlist.js'); var errors = require('./base/errors.js'); var number = require('./base/functions/number.js'); var Precise = require('./base/Precise.js'); var sha256 = require('./static_dependencies/noble-hashes/sha256.js'); // ---------------------------------------------------------------------------- /** * @class coinlist * @augments Exchange */ class coinlist extends coinlist$1 { describe() { return this.deepExtend(super.describe(), { 'id': 'coinlist', 'name': 'Coinlist', 'countries': ['US'], 'version': 'v1', 'rateLimit': 300, 'certified': false, 'pro': false, 'has': { 'CORS': undefined, 'spot': true, 'margin': false, 'swap': false, 'future': false, 'option': false, 'addMargin': false, 'cancelAllOrders': true, 'cancelOrder': true, 'cancelOrders': true, 'closeAllPositions': false, 'closePosition': false, 'createDepositAddress': false, 'createOrder': true, 'createPostOnlyOrder': true, 'createReduceOnlyOrder': false, 'createStopLimitOrder': true, 'createStopMarketOrder': true, 'createStopOrder': true, 'deposit': false, 'editOrder': true, 'fetchAccounts': true, 'fetchBalance': true, 'fetchBidsAsks': false, 'fetchBorrowInterest': false, 'fetchBorrowRateHistories': false, 'fetchBorrowRateHistory': false, 'fetchCanceledOrders': true, 'fetchClosedOrder': false, 'fetchClosedOrders': true, 'fetchCrossBorrowRate': false, 'fetchCrossBorrowRates': false, 'fetchCurrencies': true, 'fetchDeposit': false, 'fetchDepositAddress': false, 'fetchDepositAddresses': false, 'fetchDepositAddressesByNetwork': false, 'fetchDeposits': false, 'fetchDepositsWithdrawals': true, 'fetchDepositWithdrawFee': false, 'fetchDepositWithdrawFees': false, 'fetchFundingHistory': false, 'fetchFundingRate': false, 'fetchFundingRateHistory': false, 'fetchFundingRates': false, 'fetchIndexOHLCV': false, 'fetchIsolatedBorrowRate': false, 'fetchIsolatedBorrowRates': false, 'fetchL3OrderBook': false, 'fetchLedger': true, 'fetchLeverage': false, 'fetchLeverageTiers': false, 'fetchMarketLeverageTiers': false, 'fetchMarkets': true, 'fetchMarkOHLCV': false, 'fetchMyTrades': true, 'fetchOHLCV': true, 'fetchOpenInterestHistory': false, 'fetchOpenOrder': false, 'fetchOpenOrders': true, 'fetchOrder': true, 'fetchOrderBook': true, 'fetchOrderBooks': false, 'fetchOrders': true, 'fetchOrderTrades': true, 'fetchPosition': false, 'fetchPositionHistory': false, 'fetchPositionMode': false, 'fetchPositions': false, 'fetchPositionsForSymbol': false, 'fetchPositionsHistory': false, 'fetchPositionsRisk': false, 'fetchPremiumIndexOHLCV': false, 'fetchStatus': false, 'fetchTicker': true, 'fetchTickers': true, 'fetchTime': true, 'fetchTrades': true, 'fetchTradingFee': false, 'fetchTradingFees': true, 'fetchTradingLimits': false, 'fetchTransactionFee': false, 'fetchTransactionFees': false, 'fetchTransactions': true, 'fetchTransfers': true, 'fetchWithdrawal': false, 'fetchWithdrawals': false, 'fetchWithdrawalWhitelist': false, 'reduceMargin': false, 'repayCrossMargin': false, 'repayIsolatedMargin': false, 'setLeverage': false, 'setMargin': false, 'setMarginMode': false, 'setPositionMode': false, 'signIn': false, 'transfer': true, 'withdraw': true, 'ws': false, }, 'timeframes': { '1m': '1m', '5m': '5m', '30m': '30m', }, 'urls': { 'logo': 'https://github-production-user-asset-6210df.s3.amazonaws.com/1294454/281108917-eff2ae1d-ce8a-4b2a-950d-8678b12da965.jpg', 'api': { 'public': 'https://trade-api.coinlist.co', 'private': 'https://trade-api.coinlist.co', }, 'www': 'https://coinlist.co', 'doc': [ 'https://trade-docs.coinlist.co', ], 'fees': 'https://coinlist.co/fees', }, 'api': { 'public': { 'get': { 'v1/symbols': 1, 'v1/symbols/summary': 1, 'v1/symbols/{symbol}': 1, 'v1/symbols/{symbol}/summary': 1, 'v1/symbols/{symbol}/book': 1, 'v1/symbols/{symbol}/quote': 1, 'v1/symbols/{symbol}/candles': 1, 'v1/symbols/{symbol}/auctions': 1, 'v1/symbols/{symbol}/auctions/{auction_code}': 1, 'v1/time': 1, 'v1/assets': 1, 'v1/leaderboard': 1, 'v1/affiliate/{competition_code}': 1, 'v1/competition/{competition_id}': 1, }, }, 'private': { 'get': { 'v1/fees': 1, 'v1/accounts': 1, 'v1/accounts/{trader_id}': 1, 'v1/accounts/{trader_id}/alias': 1, 'v1/accounts/{trader_id}/ledger': 1, 'v1/accounts/{trader_id}/wallets': 1, 'v1/accounts/{trader_id}/wallet-ledger': 1, 'v1/accounts/{trader_id}/ledger-summary': 1, 'v1/keys': 1, 'v1/fills': 1, 'v1/orders': 1, 'v1/orders/{order_id}': 1, 'v1/reports': 1, 'v1/balances': 1, 'v1/transfers': 1, 'v1/user': 1, 'v1/credits': 1, 'v1/positions': 1, 'v1/accounts/{trader_id}/competitions': 1, }, 'post': { 'v1/keys': 1, 'v1/orders': 1, 'v1/orders/cancel-all-after': 1, 'v1/reports': 1, 'v1/transfers/to-wallet': 1, 'v1/transfers/from-wallet': 1, 'v1/transfers/internal-transfer': 1, 'v1/transfers/withdrawal-request': 1, 'v1/orders/bulk': 1, 'v1/accounts/{trader_id}/competitions': 1, 'v1/accounts/{trader_id}/create-competition': 1, }, 'patch': { 'v1/orders/{order_id}': 1, 'v1/orders/bulk': 1, // not unified }, 'delete': { 'v1/keys/{key}': 1, 'v1/orders': 1, 'v1/orders/{order_id}': 1, 'v1/orders/bulk': 1, }, }, }, 'features': { 'default': { 'sandbox': false, 'createOrder': { 'marginMode': false, 'triggerPrice': true, 'triggerPriceType': { 'last': true, 'mark': true, 'index': true, }, 'triggerDirection': false, 'stopLossPrice': false, 'takeProfitPrice': false, 'attachedStopLossTakeProfit': undefined, 'timeInForce': { 'IOC': false, 'FOK': false, 'PO': true, 'GTD': false, }, 'hedged': false, 'trailing': true, 'leverage': false, 'marketBuyByCost': false, 'marketBuyRequiresPrice': false, 'selfTradePrevention': true, 'iceberg': false, }, 'createOrders': undefined, 'fetchMyTrades': { 'marginMode': false, 'limit': 500, 'daysBack': 100000, 'untilDays': 100000, 'symbolRequired': false, }, 'fetchOrder': { 'marginMode': false, 'trigger': false, 'trailing': false, 'symbolRequired': false, }, 'fetchOpenOrders': { 'marginMode': false, 'limit': 500, 'trigger': false, 'trailing': false, 'symbolRequired': false, }, 'fetchOrders': { 'marginMode': false, 'limit': 500, 'daysBack': 100000, 'untilDays': 100000, 'trigger': false, 'trailing': false, 'symbolRequired': false, }, 'fetchClosedOrders': { 'marginMode': false, 'limit': 500, 'daysBack': 100000, 'daysBackCanceled': undefined, 'untilDays': 100000, 'trigger': false, 'trailing': false, 'symbolRequired': false, }, 'fetchOHLCV': { 'limit': 300, }, }, 'swap': { 'linear': undefined, 'inverse': undefined, }, 'future': { 'linear': undefined, 'inverse': undefined, }, }, 'fees': { 'trading': { 'feeSide': 'get', 'tierBased': true, 'percentage': true, 'taker': this.parseNumber('0.0045'), 'maker': this.parseNumber('0.0025'), 'tiers': { 'taker': [ [this.parseNumber('0'), this.parseNumber('0.0045')], [this.parseNumber('20000'), this.parseNumber('0.003')], [this.parseNumber('50000'), this.parseNumber('0.0025')], [this.parseNumber('100000'), this.parseNumber('0.002')], [this.parseNumber('500000'), this.parseNumber('0.0018')], [this.parseNumber('750000'), this.parseNumber('0.0018')], [this.parseNumber('1000000'), this.parseNumber('0.0016')], [this.parseNumber('2500000'), this.parseNumber('0.0013')], [this.parseNumber('5000000'), this.parseNumber('0.0012')], [this.parseNumber('10000000'), this.parseNumber('0.001')], [this.parseNumber('50000000'), this.parseNumber('0.0005')], [this.parseNumber('100000000'), this.parseNumber('0.0005')], ], 'maker': [ [this.parseNumber('0'), this.parseNumber('0.0025')], [this.parseNumber('20000'), this.parseNumber('0.0025')], [this.parseNumber('50000'), this.parseNumber('0.0025')], [this.parseNumber('100000'), this.parseNumber('0.002')], [this.parseNumber('500000'), this.parseNumber('0.0015')], [this.parseNumber('750000'), this.parseNumber('0.0012')], [this.parseNumber('1000000'), this.parseNumber('0.001')], [this.parseNumber('2500000'), this.parseNumber('0.0008')], [this.parseNumber('5000000'), this.parseNumber('0.0007')], [this.parseNumber('10000000'), this.parseNumber('0.0006')], [this.parseNumber('50000000'), this.parseNumber('0.0000')], [this.parseNumber('100000000'), this.parseNumber('0.00')], ], }, }, }, 'precisionMode': number.TICK_SIZE, // exchange-specific options 'options': { 'accountsByType': { 'CoinList Pro': 'trading', 'CoinList Pro trading account': 'trading', 'Pro': 'trading', 'pro': 'trading', 'trade': 'trading', 'trading': 'trading', 'CoinList': 'funding', 'CoinList wallet': 'funding', 'Wallet': 'funding', 'wallet': 'funding', 'fund': 'funding', 'funding': 'funding', }, }, 'exceptions': { // https://trade-docs.coinlist.co/?javascript--nodejs#message-codes 'exact': { 'AUTH_SIG_INVALID': errors.AuthenticationError, 'DENIED_MAINTENANCE': errors.OnMaintenance, 'ORDER_REJECT_BAD_STATUS': errors.InvalidOrder, 'ORDER_REJECT_INVALID_POST_ONLY': errors.InvalidOrder, 'ORDER_REJECT_INVALID_CLOSE_ONLY': errors.InvalidOrder, 'ORDER_REJECT_POST_ONLY_REQUIRED': errors.InvalidOrder, 'ORDER_REJECT_FROZEN_ORDER': errors.InvalidOrder, 'ORDER_REJECT_LIMIT_PRICE_PROTECTION_VIOLATION': errors.InvalidOrder, 'ORDER_REJECT_CLOSED': errors.NotSupported, 'ORDER_REJECT_MAX_ORDERS': errors.BadRequest, 'ORDER_REJECT_NOT_FOUND': errors.OrderNotFound, 'ORDER_REJECT_PARSE_ERROR': errors.BadRequest, 'ORDER_REJECT_PRICE_INVALID': errors.InvalidOrder, 'ORDER_REJECT_QUANTITY_ZERO': errors.InvalidOrder, 'ORDER_REJECT_TOKEN_LIMIT': errors.InsufficientFunds, 'ORDER_REJECT_TOKEN_LIMIT_OTHER': errors.InvalidOrder, 'ORDER_REJECT_SELF_TRADE': errors.InvalidOrder, 'ORDER_VALIDATE_BAD_SIZE_ALIGNMENT': errors.InvalidOrder, 'ORDER_VALIDATE_BAD_TICK_ALIGNMENT': errors.InvalidOrder, 'ORDER_VALIDATE_SYMBOL_NOT_FOUND': errors.BadSymbol, 'TRANSFERS_WITHDRAWAL_REQUEST_TOO_LARGE': errors.InsufficientFunds, 'WITHDRAWAL_REQUEST_NOT_ALLOWED': errors.PermissionDenied, // {"message":"Withdrawal from CoinList not allowed for trader.","message_code":"WITHDRAWAL_REQUEST_NOT_ALLOWED","message_details":{"asset":"USDT","amount":"5","trader_id":"9c6f737e-a829-4843-87b1-b1ce86f2853b","destination_address":"0x9050dfA063D1bE7cA711c750b18D51fDD13e90Ee"}} }, 'broad': { 'A destinationAddress is required for non-USD withdrawals': errors.InvalidAddress, 'fails to match the JsonSchema date-time format pattern': errors.BadRequest, 'is required': errors.ArgumentsRequired, 'must be a string': errors.BadRequest, 'must be a valid GUID': errors.BadRequest, 'must be greater than or equal to': errors.BadRequest, 'must be less than or equal to': errors.BadRequest, 'must be one of': errors.BadRequest, 'Symbol not found': errors.BadSymbol, // {"message":"Symbol not found: {symbol}"} }, }, }); } calculateRateLimiterCost(api, method, path, params, config = {}) { if (Array.isArray(params)) { const length = params.length; return Math.ceil(length / 2); } return 1; } /** * @method * @name coinlist#fetchTime * @description fetches the current integer timestamp in milliseconds from the exchange server * @see https://trade-docs.coinlist.co/?javascript--nodejs#get-system-time * @param {object} [params] extra parameters specific to the exchange API endpoint * @returns {int} the current integer timestamp in milliseconds from the exchange server */ async fetchTime(params = {}) { const response = await this.publicGetV1Time(params); // // { // "epoch": 1698087996.039, // "iso": "2023-10-23T19:06:36.039Z" // } // const string = this.safeString(response, 'iso'); return this.parse8601(string); } /** * @method * @name coinlist#fetchCurrencies * @description fetches all available currencies on an exchange * @see https://trade-docs.coinlist.co/?javascript--nodejs#list-supported-assets * @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.publicGetV1Assets(params); // // { // "assets": [ // { // "asset": "AAVE", // "index_code": ".AAVEUSD", // "decimal_places": 18, // "min_withdrawal": "1.0000", // "is_transferable": true, // "is_visible": true // }, // { // "asset": "ALGO", // "index_code": ".ALGOUSD", // "decimal_places": 6, // "min_withdrawal": "1.0000", // "is_transferable": true, // "is_visible": true // } // ] // } // const currencies = this.safeValue(response, 'assets', []); const result = {}; for (let i = 0; i < currencies.length; i++) { const currency = currencies[i]; const id = this.safeString(currency, 'asset'); const code = this.safeCurrencyCode(id); const isTransferable = this.safeBool(currency, 'is_transferable', false); const withdrawEnabled = isTransferable; const depositEnabled = isTransferable; const active = isTransferable; const decimalPlaces = this.safeString(currency, 'decimal_places'); const precision = this.parseNumber(this.parsePrecision(decimalPlaces)); const minWithdrawal = this.safeString(currency, 'min_withdrawal'); result[code] = { 'id': id, 'code': code, 'name': code, 'info': currency, 'active': active, 'deposit': depositEnabled, 'withdraw': withdrawEnabled, 'fee': undefined, 'precision': precision, 'limits': { 'amount': { 'min': undefined, 'max': undefined }, 'withdraw': { 'min': minWithdrawal, 'max': undefined }, }, 'networks': {}, }; } return result; } /** * @method * @name coinlist#fetchMarkets * @description retrieves data on all markets for coinlist * @see https://trade-docs.coinlist.co/?javascript--nodejs#list-symbols * @param {object} [params] extra parameters specific to the exchange API endpoint * @returns {object[]} an array of objects representing market data */ async fetchMarkets(params = {}) { const response = await this.publicGetV1Symbols(params); // // { // "symbols": [ // { // "symbol": "CQT-USDT", // "base_currency": "CQT", // "is_trader_geofenced": false, // "list_time": "2021-06-15T00:00:00.000Z", // "type": "spot", // "series_code": "CQT-USDT-SPOT", // "long_name": "Covalent", // "asset_class": "CRYPTO", // "minimum_price_increment": "0.0001", // "minimum_size_increment": "0.0001", // "quote_currency": "USDT", // "index_code": null, // "price_band_threshold_market": "0.05", // "price_band_threshold_limit": "0.25", // "last_price": "0.12160000", // "fair_price": "0.12300000", // "index_price": null // }, // ] // } // const markets = this.safeValue(response, 'symbols', []); return this.parseMarkets(markets); } parseMarket(market) { const id = this.safeString(market, 'symbol'); const baseId = this.safeString(market, 'base_currency'); const quoteId = this.safeString(market, 'quote_currency'); const base = this.safeCurrencyCode(baseId); const quote = this.safeCurrencyCode(quoteId); const amountPrecision = this.safeString(market, 'minimum_size_increment'); const pricePrecision = this.safeString(market, 'minimum_price_increment'); const created = this.safeString(market, 'list_time'); return { 'id': id, 'symbol': base + '/' + quote, 'base': base, 'quote': quote, 'settle': undefined, 'baseId': baseId, 'quoteId': quoteId, 'settleId': undefined, 'type': 'spot', 'spot': true, 'margin': false, 'swap': false, 'future': false, 'option': false, 'active': true, 'contract': false, 'linear': undefined, 'inverse': undefined, 'contractSize': undefined, 'expiry': undefined, 'expiryDatetime': undefined, 'strike': undefined, 'optionType': undefined, 'precision': { 'amount': this.parseNumber(amountPrecision), 'price': this.parseNumber(pricePrecision), }, 'limits': { 'leverage': { 'min': undefined, 'max': undefined, }, 'amount': { 'min': undefined, 'max': undefined, }, 'price': { 'min': undefined, 'max': undefined, }, 'cost': { 'min': undefined, 'max': undefined, }, }, 'created': this.parse8601(created), 'info': market, }; } /** * @method * @name coinlist#fetchTickers * @description fetches price tickers for multiple markets, statistical information calculated over the past 24 hours for each market * @see https://trade-docs.coinlist.co/?javascript--nodejs#get-symbol-summaries * @param {string[]} [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 exchange API endpoint * @returns {object} a dictionary of [ticker structures]{@link https://docs.ccxt.com/#/?id=ticker-structure} */ async fetchTickers(symbols = undefined, params = {}) { await this.loadMarkets(); const request = {}; const tickers = await this.publicGetV1SymbolsSummary(this.extend(request, params)); // // { // "MATIC-USD": { // "type":"spot", // "last_price":"0.60990000", // "lowest_ask":"0.61190000", // "highest_bid":"0.60790000", // "last_trade": { // "price":"0.60000000", // "volume":"2.0000", // "imbalance":"198.0000", // "logicalTime":"2023-10-22T23:02:25.000Z", // "auctionCode":"MATIC-USD-2023-10-22T23:02:25.000Z" // }, // "volume_base_24h":"34.0555", // "volume_quote_24h":"19.9282", // "price_change_percent_24h":"7.50925436", // "highest_price_24h":"0.68560000", // "lowest_price_24h":"0.55500000" // }, // } // return this.parseTickers(tickers, symbols, params); } /** * @method * @name coinlist#fetchTicker * @description fetches a price ticker, a statistical calculation with the information calculated over the past 24 hours for a specific market * @see https://trade-docs.coinlist.co/?javascript--nodejs#get-market-summary * @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 = { 'symbol': market['id'], }; const ticker = await this.publicGetV1SymbolsSymbolSummary(this.extend(request, params)); // // { // "type":"spot", // "last_price":"31125.00000000", // "lowest_ask":"31349.99000000", // "highest_bid":"30900.00000000", // "last_trade": { // "price":"31000.00000000", // "volume":"0.0003", // "imbalance":"0.0000", // "logicalTime":"2023-10-23T16:57:15.000Z", // "auctionCode":"BTC-USDT-2023-10-23T16:57:15.000Z" // }, // "volume_base_24h":"0.3752", // "volume_quote_24h":"11382.7181", // "price_change_percent_24h":"3.66264694", // "highest_price_24h":"31225.12000000", // "lowest_price_24h":"29792.81000000" // } // return this.parseTicker(ticker, market); } parseTicker(ticker, market = undefined) { // // { // "type":"spot", // "last_price":"0.60990000", // "lowest_ask":"0.61190000", // "highest_bid":"0.60790000", // "last_trade": { // "price":"0.60000000", // "volume":"2.0000", // "imbalance":"198.0000", // "logicalTime":"2023-10-22T23:02:25.000Z", // "auctionCode":"MATIC-USD-2023-10-22T23:02:25.000Z" // }, // "volume_base_24h":"34.0555", // "volume_quote_24h":"19.9282", // "price_change_percent_24h":"7.50925436", // "highest_price_24h":"0.68560000", // "lowest_price_24h":"0.55500000" // } // const lastTrade = this.safeValue(ticker, 'last_trade', {}); const timestamp = this.parse8601(this.safeString(lastTrade, 'logicalTime')); const bid = this.safeString(ticker, 'highest_bid'); const ask = this.safeString(ticker, 'lowest_ask'); const baseVolume = this.safeString(ticker, 'volume_base_24h'); const quoteVolume = this.safeString(ticker, 'volume_quote_24h'); const high = this.safeString(ticker, 'highest_price_24h'); const low = this.safeString(ticker, 'lowest_price_24h'); const close = this.safeString(ticker, 'last_price'); const changePcnt = this.safeString(ticker, 'price_change_percent_24h'); return this.safeTicker({ 'symbol': market['symbol'], 'timestamp': timestamp, 'datetime': this.iso8601(timestamp), 'open': undefined, 'high': high, 'low': low, 'close': close, 'bid': bid, 'bidVolume': undefined, 'ask': ask, 'askVolume': undefined, 'vwap': undefined, 'previousClose': undefined, 'change': undefined, 'percentage': changePcnt, 'average': undefined, 'baseVolume': baseVolume, 'quoteVolume': quoteVolume, 'info': ticker, }, market); } /** * @method * @name coinlist#fetchOrderBook * @description fetches information on open orders with bid (buy) and ask (sell) prices, volumes and other data * @see https://trade-docs.coinlist.co/?javascript--nodejs#get-order-book-level-2 * @param {string} symbol unified symbol of the market to fetch the order book for * @param {int} [limit] the maximum amount of order book entries to return (default 100, max 200) * @param {object} [params] extra parameters specific to the exchange API endpoint * @returns {object} A dictionary of [order book structures]{@link https://docs.ccxt.com/#/?id=order-book-structure} indexed by market symbols */ async fetchOrderBook(symbol, limit = undefined, params = {}) { await this.loadMarkets(); const market = this.market(symbol); const request = { 'symbol': market['id'], }; const response = await this.publicGetV1SymbolsSymbolBook(this.extend(request, params)); // // { // "bids": [ // [ "30900.00000000", "0.0001" ], // [ "30664.21000000", "0.0172" ], // [ "30664.20000000", "0.0906" ], // ], // "asks": [ // [ "31349.99000000", "0.0003" ], // [ "31350.00000000", "0.0023" ], // [ "31359.33000000", "0.0583" ], // ], // "after_auction_code": "BTC-USDT-2023-10-23T18:40:51.000Z", // "call_time": "2023-10-23T18:40:51.068Z", // "logical_time": "2023-10-23T18:40:51.000Z" // } // const logical_time = this.parse8601(this.safeString(response, 'logical_time')); const orderbook = this.parseOrderBook(response, symbol, logical_time); orderbook['nonce'] = undefined; return orderbook; } /** * @method * @name coinlist#fetchOHLCV * @description fetches historical candlestick data containing the open, high, low, and close price, and the volume of a market * @see https://trade-docs.coinlist.co/?javascript--nodejs#get-candles * @param {string} symbol unified symbol of the market to fetch OHLCV data for * @param {string} timeframe the length of time each candle represents * @param {int} [since] timestamp in ms of the earliest candle to fetch * @param {int} [limit] the maximum amount of candles to fetch * @param {object} [params] extra parameters specific to the exchange API endpoint * @param {int} [params.until] the latest time in ms to fetch entries for * @returns {int[][]} A list of candles ordered as timestamp, open, high, low, close, volume */ async fetchOHLCV(symbol, timeframe = '1m', since = undefined, limit = undefined, params = {}) { await this.loadMarkets(); const market = this.market(symbol); const granularity = this.safeString(this.timeframes, timeframe); const request = { 'symbol': market['id'], 'granularity': granularity, }; if (since !== undefined) { request['start_time'] = this.iso8601(since); if (limit !== undefined) { const duration = this.parseTimeframe(timeframe) * 1000; request['end_time'] = this.iso8601(this.sum(since, duration * (limit))); } else { request['end_time'] = this.iso8601(this.milliseconds()); } } const until = this.safeInteger(params, 'until'); if (until !== undefined) { params = this.omit(params, ['until']); request['end_time'] = this.iso8601(until); } const response = await this.publicGetV1SymbolsSymbolCandles(this.extend(request, params)); // // { // "candles": [ // [ // "2023-10-17T15:00:00.000Z", // "28522.96000000", // "28522.96000000", // "28522.96000000", // "28522.96000000", // "0.1881", // null // ], // [ // "2023-10-17T15:30:00.000Z", // "28582.64000000", // "28582.64000000", // "28582.64000000", // "28582.64000000", // "0.0050", // null // ] // ] // } // const candles = this.safeList(response, 'candles', []); return this.parseOHLCVs(candles, market, timeframe, since, limit); } parseOHLCV(ohlcv, market = undefined) { // // [ // "2023-10-17T15:30:00.000Z", // "28582.64000000", // "28582.64000000", // "28582.64000000", // "28582.64000000", // "0.0050", // null // ] // return [ this.parse8601(this.safeString(ohlcv, 0)), this.safeNumber(ohlcv, 1), this.safeNumber(ohlcv, 2), this.safeNumber(ohlcv, 3), this.safeNumber(ohlcv, 4), this.safeNumber(ohlcv, 5), ]; } /** * @method * @name coinlist#fetchTrades * @description get the list of most recent trades for a particular symbol * @see https://trade-docs.coinlist.co/?javascript--nodejs#list-auctions * @param {string} symbol unified symbol of the market to fetch trades for * @param {int} [since] timestamp in ms of the earliest trade to fetch * @param {int} [limit] the maximum amount of trades to fetch (default 200, max 500) * @param {object} [params] extra parameters specific to the exchange API endpoint * @param {int} [params.until] the latest time in ms to fetch entries for * @returns {Trade[]} a list of [trade structures]{@link https://docs.ccxt.com/#/?id=public-trades} */ async fetchTrades(symbol, since = undefined, limit = undefined, params = {}) { await this.loadMarkets(); const market = this.market(symbol); const request = { 'symbol': market['id'], }; if (since !== undefined) { request['start_time'] = this.iso8601(since); } if (limit !== undefined) { request['count'] = Math.min(limit, 500); } const until = this.safeInteger(params, 'until'); if (until !== undefined) { params = this.omit(params, ['until']); request['end_time'] = this.iso8601(until); } const response = await this.publicGetV1SymbolsSymbolAuctions(this.extend(request, params)); // // { // "auctions": [ // { // "symbol":"BTC-USDT", // "auction_code":"BTC-USDT-2023-10-01T08:05:56.000Z", // "price":"27241.53000000", // "volume":"0.0052", // "imbalance":"-1.0983", // "logical_time":"2023-10-01T08:05:56.000Z", // "call_time":"2023-10-01T08:05:56.068Z" // }, // { // "symbol":"BTC-USDT", // "auction_code":"BTC-USDT-2023-10-01T08:09:09.000Z", // "price":"27236.83000000", // "volume":"0.0283", // "imbalance":"-1.0754", // "logical_time":"2023-10-01T08:09:09.000Z", // "call_time":"2023-10-01T08:09:09.078Z" // } // ] // } // const auctions = this.safeList(response, 'auctions', []); return this.parseTrades(auctions, market, since, limit); } parseTrade(trade, market = undefined) { // // fetchTrades // { // "symbol": "BTC-USDT", // "auction_code": "BTC-USDT-2023-10-01T08:05:56.000Z", // "price": "27241.53000000", // "volume": "0.0052", // "imbalance": "-1.0983", // "logical_time": "2023-10-01T08:05:56.000Z", // "call_time": "2023-10-01T08:05:56.068Z" // } // // fetchMyTrades // { // "symbol": "ETH-USDT", // "auction_code": "ETH-USDT-2023-10-20T13:22:14.000Z", // "order_id": "83ed365f-497d-433b-96c1-9d08c1a12842", // "quantity": "0.0008", // "price": "1615.24000000", // "fee": "0.005815", // "fee_type": "taker", // "fee_currency": "USDT", // "logical_time": "2023-10-20T13:22:14.000Z" // } // const marketId = this.safeString(trade, 'symbol'); market = this.safeMarket(marketId, market); const symbol = market['symbol']; const id = this.safeString(trade, 'auction_code'); const timestamp = this.parse8601(this.safeString(trade, 'logical_time')); const priceString = this.safeString(trade, 'price'); let amountString = this.safeString2(trade, 'volume', 'quantity'); const order = this.safeString(trade, 'order_id'); let fee = undefined; let side = undefined; const feeCost = this.safeString(trade, 'fee'); if (feeCost !== undefined) { // only in fetchMyTrades const amountIsNegative = Precise["default"].stringLt(amountString, '0'); if (amountIsNegative) { side = 'sell'; amountString = Precise["default"].stringNeg(amountString); } else { side = 'buy'; } fee = { 'cost': feeCost, 'currency': this.safeString(trade, 'fee_currency'), }; } else { const imbalance = this.safeString(trade, 'imbalance'); if (Precise["default"].stringLt(imbalance, '0')) { side = 'buy'; } else { side = 'sell'; } } const takerOrMaker = this.safeString(trade, 'fee_type'); return this.safeTrade({ 'id': id, 'order': order, 'timestamp': timestamp, 'datetime': this.iso8601(timestamp), 'symbol': symbol, 'type': undefined, 'side': side, 'takerOrMaker': takerOrMaker, 'price': priceString, 'amount': amountString, 'cost': undefined, 'fee': fee, 'info': trade, }, market); } /** * @method * @name coinlist#fetchTradingFees * @description fetch the trading fees for multiple markets * @see https://trade-docs.coinlist.co/?javascript--nodejs#list-fees * @param {object} [params] extra parameters specific to the exchange API endpoint * @returns {object} a dictionary of [fee structures]{@link https://docs.ccxt.com/#/?id=fee-structure} indexed by market symbols */ async fetchTradingFees(params = {}) { await this.loadMarkets(); const response = await this.privateGetV1Fees(params); // // { // fees_by_symbols: { // 'BTC-USD,BTC-USDT,ETH-USD,ETH-USDT,ETH-BTC,AAVE-USD,AAVE-USDT,ALGO-USD,ALGO-USDT,AVAX-USD,AVAX-USDT,BICO-USD,BICO-USDT,BLD-USD,BLD-USDT,BTRST-USDT,BZZ-USDT,CELO-USD,CELO-BTC,CFG-USD,CFG-USDT,CLV-USDT,COMP-USD,COMP-USDT,CYBER-USDT,CQT-USDT,CSPR-USD,CSPR-USDT,CUSD-USD,CUSD-USDC,DOGE-USD,DOGE-USDT,DOT-USD,DOT-USDT,EFI-USDT,FIL-USD,FIL-USDT,FLOW-USD,FLOW-USDT,GAL-USD,GAL-USDT,GODS-USDT,GOG-USDT,HMT-USD,HMT-USDT,ICP-USD,ICP-USDT,IMX-USD,IMX-USDT,LINK-USD,LINK-USDT,MATIC-USD,MATIC-USDT,MINA-USD,MINA-USDT,MKR-USD,MKR-USDT,NEON-USDT,NYM-USD,NYM-USDT,OCEAN-USD,OXT-USD,ROSE-USD,ROSE-USDT,SKL-USD,SKL-USDT,SOL-USD,SOL-USDT,STX-USDT,SUI-USDT,T-USDT,UNI-USD,UNI-USDT,USDT-USD,VEGA-USDT,WAXL-USD,WAXL-USDT,WBTC-BTC,WCFG-USD,WCFG-USDT,XTZ-USD': { // base: { // fees: { maker: '0', taker: '0.0045', liquidation: '0' }, // floors: { maker: null, taker: null } // }, // volume_tier_1: { // fees: { maker: '0', taker: '0.003', liquidation: '0' }, // floors: { maker: null, taker: null } // }, // volume_tier_2: { // fees: { maker: '0', taker: '0.0025', liquidation: '0' }, // floors: { maker: null, taker: null } // }, // volume_tier_3: { // fees: { maker: '0', taker: '0.002', liquidation: '0' }, // floors: { maker: null, taker: null } // }, // volume_tier_4: { // fees: { maker: '0', taker: '0.0018', liquidation: '0' }, // floors: { maker: null, taker: null } // }, // volume_tier_5: { // fees: { maker: '0', taker: '0.0018', liquidation: '0' }, // floors: { maker: null, taker: null } // }, // volume_tier_6: { // fees: { maker: '0', taker: '0.0016', liquidation: '0' }, // floors: { maker: null, taker: null } // }, // volume_tier_7: { // fees: { maker: '0', taker: '0.0013', liquidation: '0' }, // floors: { maker: null, taker: null } // }, // volume_tier_8: { // fees: { maker: '0', taker: '0.0012', liquidation: '0' }, // floors: { maker: null, taker: null } // }, // volume_tier_9: { // fees: { maker: '0', taker: '0.001', liquidation: '0' }, // floors: { maker: null, taker: null } // } // volume_tier_10: { // fees: { maker: '0', taker: '0.0005', liquidation: '0' }, // floors: { maker: null, taker: null } // }, // volume_tier_11: { // fees: { maker: '0', taker: '0.0005', liquidation: '0' }, // floors: { maker: null, taker: null } // }, // } // } // } // const fees = this.safeValue(response, 'fees_by_symbols', {}); const result = {}; const groupsOfSymbols = Object.keys(fees); for (let i = 0; i < groupsOfSymbols.length; i++) { const group = groupsOfSymbols[i]; const feeTiers = this.safeValue(fees, group, {}); const tiers = this.parseFeeTiers(feeTiers); const firstTier = this.safeValue(feeTiers, 'base', {}); const firstTierFees = this.safeValue(firstTier, 'fees', {}); const ids = group.split(','); for (let j = 0; j < ids.length; j++) { const id = ids[j]; const market = this.safeMarket(id); const symbol = market['symbol']; const info = {}; info[group] = feeTiers; result[symbol] = { 'info': info, 'symbol': symbol, 'maker': this.safeNumber(firstTierFees, 'maker'), 'taker': this.safeNumber(firstTierFees, 'taker'), 'percentage': true, 'tierBased': true, 'tiers': tiers, }; } } return result; } parseFeeTiers(feeTiers, market = undefined) { // // base: { // fees: { maker: '0', taker: '0.0045', liquidation: '0' }, // floors: { maker: null, taker: null } // }, // volume_tier_1: { // fees: { maker: '0', taker: '0.003', liquidation: '0' }, // floors: { maker: null, taker: null } // }, // volume_tier_2: { // fees: { maker: '0', taker: '0.0025', liquidation: '0' }, // floors: { maker: null, taker: null } // }, // volume_tier_3: { // fees: { maker: '0', taker: '0.002', liquidation: '0' }, // floors: { maker: null, taker: null } // }, // volume_tier_4: { // fees: { maker: '0', taker: '0.0018', liquidation: '0' }, // floors: { maker: null, taker: null } // }, // volume_tier_5: { // fees: { maker: '0', taker: '0.0018', liquidation: '0' }, // floors: { maker: null, taker: null } // }, // volume_tier_6: { // fees: { maker: '0', taker: '0.0016', liquidation: '0' }, // floors: { maker: null, taker: null } // }, // volume_tier_7: { // fees: { maker: '0', taker: '0.0013', liquidation: '0' }, // floors: { maker: null, taker: null } // }, // volume_tier_8: { // fees: { maker: '0', taker: '0.0012', liquidation: '0' }, // floors: { maker: null, taker: null } // }, // volume_tier_9: { // fees: { maker: '0', taker: '0.001', liquidation: '0' }, // floors: { maker: null, taker: null } // } // volume_tier_10: { // fees: { maker: '0', taker: '0.0005', liquidation: '0' }, // floors: { maker: null, taker: null } // }, // volume_tier_11: { // fees: { maker: '0', taker: '0.0005', liquidation: '0' }, // floors: { maker: null, taker: null } // }, // let takerFees = []; let makerFees = []; const keys = Object.