ccxt
Version:
1,110 lines (1,108 loc) • 110 kB
JavaScript
'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.