UNPKG

@proton/ccxt

Version:

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

1,090 lines (1,087 loc) 68.6 kB
// ---------------------------------------------------------------------------- // PLEASE DO NOT EDIT THIS FILE, IT IS GENERATED AND WILL BE OVERWRITTEN: // https://github.com/ccxt/ccxt/blob/master/CONTRIBUTING.md#how-to-contribute-code // EDIT THE CORRESPONDENT .ts FILE INSTEAD import Exchange from './abstract/timex.js'; import { ExchangeError, PermissionDenied, ExchangeNotAvailable, InsufficientFunds, OrderNotFound, InvalidOrder, RateLimitExceeded, NotSupported, BadRequest, AuthenticationError, ArgumentsRequired } from './base/errors.js'; import { Precise } from './base/Precise.js'; import { TICK_SIZE } from './base/functions/number.js'; export default class timex extends Exchange { describe() { return this.deepExtend(super.describe(), { 'id': 'timex', 'name': 'TimeX', 'countries': ['AU'], 'version': 'v1', 'rateLimit': 1500, 'has': { 'CORS': undefined, 'spot': true, 'margin': false, 'swap': false, 'future': false, 'option': false, 'addMargin': false, 'cancelOrder': true, 'cancelOrders': true, 'createOrder': true, 'createReduceOnlyOrder': false, 'createStopLimitOrder': false, 'createStopMarketOrder': false, 'createStopOrder': false, 'editOrder': true, 'fetchBalance': true, 'fetchBorrowRate': false, 'fetchBorrowRateHistories': false, 'fetchBorrowRateHistory': false, 'fetchBorrowRates': false, 'fetchBorrowRatesPerSymbol': false, 'fetchClosedOrders': true, 'fetchCurrencies': true, 'fetchDeposit': false, 'fetchDeposits': true, 'fetchFundingHistory': false, 'fetchFundingRate': false, 'fetchFundingRateHistory': false, 'fetchFundingRates': false, 'fetchIndexOHLCV': false, 'fetchLeverage': false, 'fetchLeverageTiers': false, 'fetchMarginMode': false, 'fetchMarkets': true, 'fetchMarkOHLCV': false, 'fetchMyTrades': true, 'fetchOHLCV': true, 'fetchOpenInterestHistory': false, 'fetchOpenOrders': true, 'fetchOrder': true, 'fetchOrderBook': true, 'fetchPosition': false, 'fetchPositionMode': false, 'fetchPositions': false, 'fetchPositionsRisk': false, 'fetchPremiumIndexOHLCV': false, 'fetchTicker': true, 'fetchTickers': true, 'fetchTrades': true, 'fetchTradingFee': true, 'fetchWithdrawal': false, 'fetchWithdrawals': true, 'reduceMargin': false, 'setLeverage': false, 'setMarginMode': false, 'setPositionMode': false, }, 'timeframes': { '1m': 'I1', '5m': 'I5', '15m': 'I15', '30m': 'I30', '1h': 'H1', '2h': 'H2', '4h': 'H4', '6h': 'H6', '12h': 'H12', '1d': 'D1', '1w': 'W1', }, 'urls': { 'logo': 'https://user-images.githubusercontent.com/1294454/70423869-6839ab00-1a7f-11ea-8f94-13ae72c31115.jpg', 'api': { 'rest': 'https://plasma-relay-backend.timex.io', }, 'www': 'https://timex.io', 'doc': 'https://docs.timex.io', 'referral': 'https://timex.io/?refcode=1x27vNkTbP1uwkCck', }, 'api': { 'addressbook': { 'get': [ 'me', ], 'post': [ '', 'id/{id}', 'id/{id}/remove', ], }, 'custody': { 'get': [ 'credentials', 'credentials/h/{hash}', 'credentials/k/{key}', 'credentials/me', 'credentials/me/address', 'deposit-addresses', 'deposit-addresses/h/{hash}', // Get deposit address by hash ], }, 'history': { 'get': [ 'orders', 'orders/details', 'orders/export/csv', 'trades', 'trades/export/csv', // Export trades to csv ], }, 'currencies': { 'get': [ 'a/{address}', 'i/{id}', 's/{symbol}', // Gets currency by symbol ], 'post': [ 'perform', 'prepare', 'remove/perform', 's/{symbol}/remove/prepare', 's/{symbol}/update/perform', 's/{symbol}/update/prepare', // Prepare update currency by symbol ], }, 'manager': { 'get': [ 'deposits', 'transfers', 'withdrawals', ], }, 'markets': { 'get': [ 'i/{id}', 's/{symbol}', // Gets market by symbol ], 'post': [ 'perform', 'prepare', 'remove/perform', 's/{symbol}/remove/prepare', 's/{symbol}/update/perform', 's/{symbol}/update/prepare', // Prepare update market by symbol ], }, 'public': { 'get': [ 'candles', 'currencies', 'markets', 'orderbook', 'orderbook/raw', 'orderbook/v2', 'tickers', 'trades', // Gets trades ], }, 'statistics': { 'get': [ 'address', // calculateAddressStatistics ], }, 'trading': { 'get': [ 'balances', 'fees', 'orders', // Gets open orders ], 'post': [ 'orders', 'orders/json', // Create orders ], 'put': [ 'orders', 'orders/json', // Update orders ], 'delete': [ 'orders', 'orders/json', // Delete orders ], }, 'tradingview': { 'get': [ 'config', 'history', 'symbol_info', 'time', // Gets time ], }, }, 'precisionMode': TICK_SIZE, 'exceptions': { 'exact': { '0': ExchangeError, '1': NotSupported, '4000': BadRequest, '4001': BadRequest, '4002': InsufficientFunds, '4003': AuthenticationError, '4004': AuthenticationError, '4005': BadRequest, '4006': BadRequest, '4007': BadRequest, '4300': PermissionDenied, '4100': AuthenticationError, '4400': OrderNotFound, '5001': InvalidOrder, '5002': ExchangeError, '400': BadRequest, '401': AuthenticationError, '403': PermissionDenied, '404': OrderNotFound, '429': RateLimitExceeded, '500': ExchangeError, '503': ExchangeNotAvailable, }, 'broad': { 'Insufficient': InsufficientFunds, }, }, 'options': { 'expireIn': 31536000, 'fetchTickers': { 'period': '1d', }, 'fetchTrades': { 'sort': 'timestamp,asc', }, 'fetchMyTrades': { 'sort': 'timestamp,asc', }, 'fetchOpenOrders': { 'sort': 'createdAt,asc', }, 'fetchClosedOrders': { 'sort': 'createdAt,asc', }, 'defaultSort': 'timestamp,asc', 'defaultSortOrders': 'createdAt,asc', }, }); } async fetchMarkets(params = {}) { /** * @method * @name timex#fetchMarkets * @description retrieves data on all markets for timex * @param {object} params extra parameters specific to the exchange api endpoint * @returns {[object]} an array of objects representing market data */ const response = await this.publicGetMarkets(params); // // [ // { // "symbol": "ETHBTC", // "name": "ETH/BTC", // "baseCurrency": "ETH", // "baseTokenAddress": "0x45932db54b38af1f5a57136302eeba66a5975c15", // "quoteCurrency": "BTC", // "quoteTokenAddress": "0x8370fbc6ddec1e18b4e41e72ed943e238458487c", // "feeCurrency": "BTC", // "feeTokenAddress": "0x8370fbc6ddec1e18b4e41e72ed943e238458487c", // "quantityIncrement": "0.0000001", // "takerFee": "0.005", // "makerFee": "0.0025", // "tickSize": "0.00000001", // "baseMinSize": "0.0001", // "quoteMinSize": "0.00001", // "locked": false // } // ] // const result = []; for (let i = 0; i < response.length; i++) { result.push(this.parseMarket(response[i])); } return result; } async fetchCurrencies(params = {}) { /** * @method * @name timex#fetchCurrencies * @description fetches all available currencies on an exchange * @param {object} params extra parameters specific to the timex api endpoint * @returns {object} an associative dictionary of currencies */ const response = await this.publicGetCurrencies(params); // // [ // { // "symbol": "BTC", // "name": "Bitcoin", // "address": "0x8370fbc6ddec1e18b4e41e72ed943e238458487c", // "icon": "data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iNjAiIGhlaWdodD0iNjAiIHZpZXdCb3g9IjAgMCA2MCA2MCIgZmlsbD0ibm9uZSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj4KPHBhdGggb3BhY2l0eT0iMC41IiBmaWxsLXJ1bGU9ImV2ZW5vZGQiIGNsaXAtcnVsZT0iZXZlbm9kZCIgZD0iTTMwIDUzQzQyLjcwMjUgNTMgNTMgNDIuNzAyNSA1MyAzMEM1MyAxNy4yOTc1IDQyLjcwMjUgNyAzMCA3QzE3LjI5NzUgNyA3IDE3LjI5NzUgNyAzMEM3IDQyLjcwMjUgMTcuMjk3NSA1MyAzMCA1M1pNMzAgNTVDNDMuODA3MSA1NSA1NSA0My44MDcxIDU1IDMwQzU1IDE2LjE5MjkgNDMuODA3MSA1IDMwIDVDMTYuMTkyOSA1IDUgMTYuMTkyOSA1IDMwQzUgNDMuODA3MSAxNi4xOTI5IDU1IDMwIDU1WiIvPgo8cGF0aCBkPSJNNDAuOTQyNSAyNi42NTg1QzQxLjQwMDMgMjMuNjExMyAzOS4wNzA1IDIxLjk3MzIgMzUuODg0OCAyMC44ODA0TDM2LjkxODIgMTYuNzUyNkwzNC4zOTUxIDE2LjEyNjRMMzMuMzg5IDIwLjE0NTVDMzIuNzI1OCAxOS45ODA5IDMyLjA0NDUgMTkuODI1NiAzMS4zNjc1IDE5LjY3MTdMMzIuMzgwOCAxNS42MjYyTDI5Ljg1OTEgMTVMMjguODI1IDE5LjEyNjRDMjguMjc2IDE5LjAwMTkgMjcuNzM3IDE4Ljg3ODggMjcuMjEzOSAxOC43NDkzTDI3LjIxNjggMTguNzM2NEwyMy43MzcyIDE3Ljg3MTJMMjMuMDY2IDIwLjU1NDhDMjMuMDY2IDIwLjU1NDggMjQuOTM4IDIwLjk4MjEgMjQuODk4NSAyMS4wMDg1QzI1LjkyMDQgMjEuMjYyNiAyNi4xMDUgMjEuOTM2IDI2LjA3NDEgMjIuNDY5OUwyNC44OTcgMjcuMTcyNEMyNC45Njc1IDI3LjE5MDMgMjUuMDU4NyAyNy4yMTYgMjUuMTU5MyAyNy4yNTYxQzI1LjA3NTMgMjcuMjM1NCAyNC45ODU0IDI3LjIxMjQgMjQuODkyNyAyNy4xOTAzTDIzLjI0MjggMzMuNzc3OEMyMy4xMTc3IDM0LjA4NjkgMjIuODAwOCAzNC41NTA2IDIyLjA4NjUgMzQuMzc0NkMyMi4xMTE3IDM0LjQxMTEgMjAuMjUyNiAzMy45MTg3IDIwLjI1MjYgMzMuOTE4N0wxOSAzNi43OTQ5TDIyLjI4MzQgMzcuNjFDMjIuODk0MiAzNy43NjI0IDIzLjQ5MjggMzcuOTIyIDI0LjA4MjEgMzguMDcyM0wyMy4wMzggNDIuMjQ3NEwyNS41NTgyIDQyLjg3MzZMMjYuNTkyMyAzOC43NDI5QzI3LjI4MDcgMzguOTI5IDI3Ljk0OSAzOS4xMDA3IDI4LjYwMyAzOS4yNjI0TDI3LjU3MjUgNDMuMzczOEwzMC4wOTU2IDQ0TDMxLjEzOTcgMzkuODMyOEMzNS40NDIyIDQwLjY0MzYgMzguNjc3NCA0MC4zMTY2IDQwLjAzOTIgMzYuNDQxNEM0MS4xMzY1IDMzLjMyMTIgMzkuOTg0NiAzMS41MjEzIDM3LjcyMDkgMzAuMzQ3N0MzOS4zNjk0IDI5Ljk2OTEgNDAuNjExMiAyOC44ODkyIDQwLjk0MjUgMjYuNjU4NVYyNi42NTg1Wk0zNS4xNzc3IDM0LjcwODhDMzQuMzk4IDM3LjgyOSAyOS4xMjI2IDM2LjE0MjIgMjcuNDEyMiAzNS43MTkzTDI4Ljc5NzcgMzAuMTg4MUMzMC41MDgxIDMwLjYxMzIgMzUuOTkyNiAzMS40NTQ4IDM1LjE3NzcgMzQuNzA4OFpNMzUuOTU4MSAyNi42MTM0QzM1LjI0NjcgMjkuNDUxNyAzMC44NTU5IDI4LjAwOTcgMjkuNDMxNiAyNy42NTYxTDMwLjY4NzcgMjIuNjM5NUMzMi4xMTIgMjIuOTkzIDM2LjY5OSAyMy42NTI4IDM1Ljk1ODEgMjYuNjEzNFoiLz4KPC9zdmc+Cg==", // "background": "transparent", // "fiatSymbol": "BTC", // "decimals": 8, // "tradeDecimals": 20, // "displayDecimals": 4, // "crypto": true, // "depositEnabled": true, // "withdrawalEnabled": true, // "transferEnabled": true, // "buyEnabled": false, // "purchaseEnabled": false, // "redeemEnabled": false, // "active": true, // "withdrawalFee": "50000000000000000", // "purchaseCommissions": [] // }, // ] // const result = []; for (let i = 0; i < response.length; i++) { const currency = response[i]; result.push(this.parseCurrency(currency)); } return this.indexBy(result, 'code'); } async fetchDeposits(code = undefined, since = undefined, limit = undefined, params = {}) { /** * @method * @name timex#fetchDeposits * @description fetch all deposits made to an account * @param {string|undefined} code unified currency code * @param {int|undefined} since the earliest time in ms to fetch deposits for * @param {int|undefined} limit the maximum number of deposits structures to retrieve * @param {object} params extra parameters specific to the timex api endpoint * @returns {[object]} a list of [transaction structures]{@link https://docs.ccxt.com/#/?id=transaction-structure} */ const address = this.safeString(params, 'address'); params = this.omit(params, 'address'); if (address === undefined) { throw new ArgumentsRequired(this.id + ' fetchDeposits() requires an address parameter'); } const request = { 'address': address, }; const response = await this.managerGetDeposits(this.extend(request, params)); // // [ // { // "from": "0x1134cc86b45039cc211c6d1d2e4b3c77f60207ed", // "timestamp": "2022-01-01T00:00:00Z", // "to": "0x1134cc86b45039cc211c6d1d2e4b3c77f60207ed", // "token": "0x6baad3fe5d0fd4be604420e728adbd68d67e119e", // "transferHash": "0x5464cdff35448314e178b8677ea41e670ea0f2533f4e52bfbd4e4a6cfcdef4c2", // "value": "100" // } // ] // const currency = this.safeCurrency(code); return this.parseTransactions(response, currency, since, limit); } async fetchWithdrawals(code = undefined, since = undefined, limit = undefined, params = {}) { /** * @method * @name timex#fetchWithdrawals * @description fetch all withdrawals made to an account * @param {string|undefined} code unified currency code * @param {int|undefined} since the earliest time in ms to fetch withdrawals for * @param {int|undefined} limit the maximum number of transaction structures to retrieve * @param {object} params extra parameters specific to the timex api endpoint * @returns {[object]} a list of [transaction structures]{@link https://docs.ccxt.com/#/?id=transaction-structure} */ const address = this.safeString(params, 'address'); params = this.omit(params, 'address'); if (address === undefined) { throw new ArgumentsRequired(this.id + ' fetchDeposits() requires an address parameter'); } const request = { 'address': address, }; const response = await this.managerGetWithdrawals(this.extend(request, params)); // // [ // { // "from": "0x1134cc86b45039cc211c6d1d2e4b3c77f60207ed", // "timestamp": "2022-01-01T00:00:00Z", // "to": "0x1134cc86b45039cc211c6d1d2e4b3c77f60207ed", // "token": "0x6baad3fe5d0fd4be604420e728adbd68d67e119e", // "transferHash": "0x5464cdff35448314e178b8677ea41e670ea0f2533f4e52bfbd4e4a6cfcdef4c2", // "value": "100" // } // ] // const currency = this.safeCurrency(code); return this.parseTransactions(response, currency, since, limit); } getCurrencyByAddress(address) { const currencies = this.currencies; for (let i = 0; i < currencies.length; i++) { const currency = currencies[i]; const info = this.safeValue(currency, 'info', {}); const a = this.safeString(info, 'address'); if (a === address) { return currency; } } return undefined; } parseTransaction(transaction, currency = undefined) { // // { // "from": "0x1134cc86b45039cc211c6d1d2e4b3c77f60207ed", // "timestamp": "2022-01-01T00:00:00Z", // "to": "0x1134cc86b45039cc211c6d1d2e4b3c77f60207ed", // "token": "0x6baad3fe5d0fd4be604420e728adbd68d67e119e", // "transferHash": "0x5464cdff35448314e178b8677ea41e670ea0f2533f4e52bfbd4e4a6cfcdef4c2", // "value": "100" // } // const datetime = this.safeString(transaction, 'timestamp'); const currencyAddresss = this.safeString(transaction, 'token', ''); currency = this.getCurrencyByAddress(currencyAddresss); return { 'info': transaction, 'id': this.safeString(transaction, 'transferHash'), 'txid': this.safeString(transaction, 'txid'), 'timestamp': this.parse8601(datetime), 'datetime': datetime, 'network': undefined, 'address': undefined, 'addressTo': this.safeString(transaction, 'to'), 'addressFrom': this.safeString(transaction, 'from'), 'tag': undefined, 'tagTo': undefined, 'tagFrom': undefined, 'type': undefined, 'amount': this.safeNumber(transaction, 'value'), 'currency': this.safeCurrencyCode(undefined, currency), 'status': 'ok', 'updated': undefined, 'fee': undefined, }; } async fetchTickers(symbols = undefined, params = {}) { /** * @method * @name timex#fetchTickers * @description fetches price tickers for multiple markets, statistical calculations with the information calculated over the past 24 hours each market * @param {[string]|undefined} symbols unified symbols of the markets to fetch the ticker for, all market tickers are returned if not assigned * @param {object} params extra parameters specific to the timex api endpoint * @returns {object} a dictionary of [ticker structures]{@link https://docs.ccxt.com/#/?id=ticker-structure} */ await this.loadMarkets(); const period = this.safeString(this.options['fetchTickers'], 'period', '1d'); const request = { 'period': this.timeframes[period], // I1, I5, I15, I30, H1, H2, H4, H6, H12, D1, W1 }; const response = await this.publicGetTickers(this.extend(request, params)); // // [ // { // "ask": 0.017, // "bid": 0.016, // "high": 0.019, // "last": 0.017, // "low": 0.015, // "market": "TIME/ETH", // "open": 0.016, // "period": "H1", // "timestamp": "2018-12-14T20:50:36.134Z", // "volume": 4.57, // "volumeQuote": 0.07312 // } // ] // return this.parseTickers(response, symbols); } async fetchTicker(symbol, params = {}) { /** * @method * @name timex#fetchTicker * @description fetches a price ticker, a statistical calculation with the information calculated over the past 24 hours for a specific market * @param {string} symbol unified symbol of the market to fetch the ticker for * @param {object} params extra parameters specific to the timex api endpoint * @returns {object} a [ticker structure]{@link https://docs.ccxt.com/#/?id=ticker-structure} */ await this.loadMarkets(); const market = this.market(symbol); const period = this.safeString(this.options['fetchTickers'], 'period', '1d'); const request = { 'market': market['id'], 'period': this.timeframes[period], // I1, I5, I15, I30, H1, H2, H4, H6, H12, D1, W1 }; const response = await this.publicGetTickers(this.extend(request, params)); // // [ // { // "ask": 0.017, // "bid": 0.016, // "high": 0.019, // "last": 0.017, // "low": 0.015, // "market": "TIME/ETH", // "open": 0.016, // "period": "H1", // "timestamp": "2018-12-14T20:50:36.134Z", // "volume": 4.57, // "volumeQuote": 0.07312 // } // ] // const ticker = this.safeValue(response, 0); return this.parseTicker(ticker, market); } async fetchOrderBook(symbol, limit = undefined, params = {}) { /** * @method * @name timex#fetchOrderBook * @description fetches information on open orders with bid (buy) and ask (sell) prices, volumes and other data * @param {string} symbol unified symbol of the market to fetch the order book for * @param {int|undefined} limit the maximum amount of order book entries to return * @param {object} params extra parameters specific to the timex api endpoint * @returns {object} A dictionary of [order book structures]{@link https://docs.ccxt.com/#/?id=order-book-structure} indexed by market symbols */ await this.loadMarkets(); const market = this.market(symbol); const request = { 'market': market['id'], }; if (limit !== undefined) { request['limit'] = limit; } const response = await this.publicGetOrderbookV2(this.extend(request, params)); // // { // "timestamp":"2019-12-05T00:21:09.538", // "bid":[ // { // "index":"2", // "price":"0.02024007", // "baseTokenAmount":"0.0096894", // "baseTokenCumulativeAmount":"0.0096894", // "quoteTokenAmount":"0.000196114134258", // "quoteTokenCumulativeAmount":"0.000196114134258" // }, // "ask":[ // { // "index":"-3", // "price":"0.02024012", // "baseTokenAmount":"0.005", // "baseTokenCumulativeAmount":"0.005", // "quoteTokenAmount":"0.0001012006", // "quoteTokenCumulativeAmount":"0.0001012006" // }, // ] // } // const timestamp = this.parse8601(this.safeString(response, 'timestamp')); return this.parseOrderBook(response, symbol, timestamp, 'bid', 'ask', 'price', 'baseTokenAmount'); } async fetchTrades(symbol, since = undefined, limit = undefined, params = {}) { /** * @method * @name timex#fetchTrades * @description get the list of most recent trades for a particular symbol * @param {string} symbol unified symbol of the market to fetch trades for * @param {int|undefined} since timestamp in ms of the earliest trade to fetch * @param {int|undefined} limit the maximum amount of trades to fetch * @param {object} params extra parameters specific to the timex api endpoint * @returns {[object]} a list of [trade structures]{@link https://docs.ccxt.com/en/latest/manual.html?#public-trades} */ await this.loadMarkets(); const market = this.market(symbol); const options = this.safeValue(this.options, 'fetchTrades', {}); const defaultSort = this.safeValue(options, 'sort', 'timestamp,asc'); const sort = this.safeString(params, 'sort', defaultSort); const query = this.omit(params, 'sort'); const request = { // 'address': 'string', // trade’s member account (?) // 'cursor': 1234, // int64 (?) // 'from': this.iso8601 (since), 'market': market['id'], // 'page': 0, // results page you want to retrieve 0 .. N // 'size': limit, // number of records per page, 100 by default 'sort': sort, // array[string], sorting criteria in the format "property,asc" or "property,desc", default is ascending // 'till': this.iso8601 (this.milliseconds ()), }; if (since !== undefined) { request['from'] = this.iso8601(since); } if (limit !== undefined) { request['size'] = limit; // default is 100 } const response = await this.publicGetTrades(this.extend(request, query)); // // [ // { // "id":1, // "timestamp":"2019-06-25T17:01:50.309", // "direction":"BUY", // "price":"0.027", // "quantity":"0.001" // } // ] // return this.parseTrades(response, market, since, limit); } async fetchOHLCV(symbol, timeframe = '1m', since = undefined, limit = undefined, params = {}) { /** * @method * @name timex#fetchOHLCV * @description fetches historical candlestick data containing the open, high, low, and close price, and the volume of a market * @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|undefined} since timestamp in ms of the earliest candle to fetch * @param {int|undefined} limit the maximum amount of candles to fetch * @param {object} params extra parameters specific to the timex api endpoint * @returns {[[int]]} A list of candles ordered as timestamp, open, high, low, close, volume */ await this.loadMarkets(); const market = this.market(symbol); const request = { 'market': market['id'], 'period': this.safeString(this.timeframes, timeframe, timeframe), }; // if since and limit are not specified const duration = this.parseTimeframe(timeframe); if (limit === undefined) { limit = 1000; // exchange provides tens of thousands of data, but we set generous default value } if (since !== undefined) { request['from'] = this.iso8601(since); request['till'] = this.iso8601(this.sum(since, this.sum(limit, 1) * duration * 1000)); } else { const now = this.milliseconds(); request['till'] = this.iso8601(now); request['from'] = this.iso8601(now - limit * duration * 1000 - 1); } const response = await this.publicGetCandles(this.extend(request, params)); // // [ // { // "timestamp":"2019-12-04T23:00:00", // "open":"0.02024009", // "high":"0.02024009", // "low":"0.02024009", // "close":"0.02024009", // "volume":"0.00008096036", // "volumeQuote":"0.004", // }, // ] // return this.parseOHLCVs(response, market, timeframe, since, limit); } parseBalance(response) { const result = { 'info': response, 'timestamp': undefined, 'datetime': undefined, }; for (let i = 0; i < response.length; i++) { const balance = response[i]; const currencyId = this.safeString(balance, 'currency'); const code = this.safeCurrencyCode(currencyId); const account = this.account(); account['total'] = this.safeString(balance, 'totalBalance'); account['used'] = this.safeString(balance, 'lockedBalance'); result[code] = account; } return this.safeBalance(result); } async fetchBalance(params = {}) { /** * @method * @name timex#fetchBalance * @description query for balance and get the amount of funds available for trading or funds locked in orders * @param {object} params extra parameters specific to the timex api endpoint * @returns {object} a [balance structure]{@link https://docs.ccxt.com/en/latest/manual.html?#balance-structure} */ await this.loadMarkets(); const response = await this.tradingGetBalances(params); // // [ // {"currency":"BTC","totalBalance":"0","lockedBalance":"0"}, // {"currency":"AUDT","totalBalance":"0","lockedBalance":"0"}, // {"currency":"ETH","totalBalance":"0","lockedBalance":"0"}, // {"currency":"TIME","totalBalance":"0","lockedBalance":"0"}, // {"currency":"USDT","totalBalance":"0","lockedBalance":"0"} // ] // return this.parseBalance(response); } async createOrder(symbol, type, side, amount, price = undefined, params = {}) { /** * @method * @name timex#createOrder * @description create a trade order * @param {string} symbol unified symbol of the market to create an order in * @param {string} type 'market' or 'limit' * @param {string} side 'buy' or 'sell' * @param {float} amount how much of currency you want to trade in units of base currency * @param {float|undefined} price the price at which the order is to be fullfilled, in units of the quote currency, ignored in market orders * @param {object} params extra parameters specific to the timex api endpoint * @returns {object} an [order structure]{@link https://docs.ccxt.com/#/?id=order-structure} */ await this.loadMarkets(); const market = this.market(symbol); const uppercaseSide = side.toUpperCase(); let uppercaseType = type.toUpperCase(); const postOnly = this.safeValue(params, 'postOnly', false); if (postOnly) { uppercaseType = 'POST_ONLY'; params = this.omit(params, ['postOnly']); } const request = { 'symbol': market['id'], 'quantity': this.amountToPrecision(symbol, amount), 'side': uppercaseSide, 'orderTypes': uppercaseType, // 'clientOrderId': '123', // 'expireIn': 1575523308, // in seconds // 'expireTime': 1575523308, // unix timestamp }; let query = params; if ((uppercaseType === 'LIMIT') || (uppercaseType === 'POST_ONLY')) { request['price'] = this.priceToPrecision(symbol, price); const defaultExpireIn = this.safeInteger(this.options, 'expireIn'); const expireTime = this.safeValue(params, 'expireTime'); const expireIn = this.safeValue(params, 'expireIn', defaultExpireIn); if (expireTime !== undefined) { request['expireTime'] = expireTime; } else if (expireIn !== undefined) { request['expireIn'] = expireIn; } else { throw new InvalidOrder(this.id + ' createOrder() method requires a expireTime or expireIn param for a ' + type + ' order, you can also set the expireIn exchange-wide option'); } query = this.omit(params, ['expireTime', 'expireIn']); } else { request['price'] = 0; } const response = await this.tradingPostOrders(this.extend(request, query)); // // { // "orders": [ // { // "cancelledQuantity": "0.3", // "clientOrderId": "my-order-1", // "createdAt": "1970-01-01T00:00:00", // "cursorId": 50, // "expireTime": "1970-01-01T00:00:00", // "filledQuantity": "0.3", // "id": "string", // "price": "0.017", // "quantity": "0.3", // "side": "BUY", // "symbol": "TIMEETH", // "type": "LIMIT", // "updatedAt": "1970-01-01T00:00:00" // } // ] // } // const orders = this.safeValue(response, 'orders', []); const order = this.safeValue(orders, 0, {}); return this.parseOrder(order, market); } async editOrder(id, symbol, type, side, amount = undefined, price = undefined, params = {}) { await this.loadMarkets(); const market = this.market(symbol); const request = { 'id': id, }; if (amount !== undefined) { request['quantity'] = this.amountToPrecision(symbol, amount); } if (price !== undefined) { request['price'] = this.priceToPrecision(symbol, price); } const response = await this.tradingPutOrders(this.extend(request, params)); // // { // "changedOrders": [ // { // "newOrder": { // "cancelledQuantity": "0.3", // "clientOrderId": "my-order-1", // "createdAt": "1970-01-01T00:00:00", // "cursorId": 50, // "expireTime": "1970-01-01T00:00:00", // "filledQuantity": "0.3", // "id": "string", // "price": "0.017", // "quantity": "0.3", // "side": "BUY", // "symbol": "TIMEETH", // "type": "LIMIT", // "updatedAt": "1970-01-01T00:00:00" // }, // "oldId": "string", // }, // ], // "unchangedOrders": [ "string" ], // } // if ('unchangedOrders' in response) { const orderIds = this.safeValue(response, 'unchangedOrders', []); const orderId = this.safeString(orderIds, 0); return this.safeOrder({ 'id': orderId, 'info': response, }); } const orders = this.safeValue(response, 'changedOrders', []); const firstOrder = this.safeValue(orders, 0, {}); const order = this.safeValue(firstOrder, 'newOrder', {}); return this.parseOrder(order, market); } async cancelOrder(id, symbol = undefined, params = {}) { /** * @method * @name timex#cancelOrder * @description cancels an open order * @param {string} id order id * @param {string|undefined} symbol not used by timex cancelOrder () * @param {object} params extra parameters specific to the timex api endpoint * @returns {object} An [order structure]{@link https://docs.ccxt.com/#/?id=order-structure} */ await this.loadMarkets(); return await this.cancelOrders([id], symbol, params); } async cancelOrders(ids, symbol = undefined, params = {}) { /** * @method * @name timex#cancelOrders * @description cancel multiple orders * @param {[string]} ids order ids * @param {string|undefined} symbol unified market symbol, default is undefined * @param {object} params extra parameters specific to the timex api endpoint * @returns {object} an list of [order structures]{@link https://docs.ccxt.com/#/?id=order-structure} */ await this.loadMarkets(); const request = { 'id': ids, }; const response = await this.tradingDeleteOrders(this.extend(request, params)); // // { // "changedOrders": [ // { // "newOrder": { // "cancelledQuantity": "0.3", // "clientOrderId": "my-order-1", // "createdAt": "1970-01-01T00:00:00", // "cursorId": 50, // "expireTime": "1970-01-01T00:00:00", // "filledQuantity": "0.3", // "id": "string", // "price": "0.017", // "quantity": "0.3", // "side": "BUY", // "symbol": "TIMEETH", // "type": "LIMIT", // "updatedAt": "1970-01-01T00:00:00" // }, // "oldId": "string", // }, // ], // "unchangedOrders": [ "string" ], // } return response; } async fetchOrder(id, symbol = undefined, params = {}) { /** * @method * @name timex#fetchOrder * @description fetches information on an order made by the user * @param {string|undefined} symbol not used by timex fetchOrder * @param {object} params extra parameters specific to the timex api endpoint * @returns {object} An [order structure]{@link https://docs.ccxt.com/#/?id=order-structure} */ await this.loadMarkets(); const request = { 'orderHash': id, }; const response = await this.historyGetOrdersDetails(request); // // { // "order": { // "cancelledQuantity": "0.3", // "clientOrderId": "my-order-1", // "createdAt": "1970-01-01T00:00:00", // "cursorId": 50, // "expireTime": "1970-01-01T00:00:00", // "filledQuantity": "0.3", // "id": "string", // "price": "0.017", // "quantity": "0.3", // "side": "BUY", // "symbol": "TIMEETH", // "type": "LIMIT", // "updatedAt": "1970-01-01T00:00:00" // }, // "trades": [ // { // "fee": "0.3", // "id": 100, // "makerOrTaker": "MAKER", // "makerOrderId": "string", // "price": "0.017", // "quantity": "0.3", // "side": "BUY", // "symbol": "TIMEETH", // "takerOrderId": "string", // "timestamp": "2019-12-05T07:48:26.310Z" // } // ] // } // const order = this.safeValue(response, 'order', {}); const trades = this.safeValue(response, 'trades', []); return this.parseOrder(this.extend(order, { 'trades': trades })); } async fetchOpenOrders(symbol = undefined, since = undefined, limit = undefined, params = {}) { /** * @method * @name timex#fetchOpenOrders * @description fetch all unfilled currently open orders * @param {string|undefined} symbol unified market symbol * @param {int|undefined} since the earliest time in ms to fetch open orders for * @param {int|undefined} limit the maximum number of open orders structures to retrieve * @param {object} params extra parameters specific to the timex api endpoint * @returns {[object]} a list of [order structures]{@link https://docs.ccxt.com/#/?id=order-structure} */ await this.loadMarkets(); const options = this.safeValue(this.options, 'fetchOpenOrders', {}); const defaultSort = this.safeValue(options, 'sort', 'createdAt,asc'); const sort = this.safeString(params, 'sort', defaultSort); const query = this.omit(params, 'sort'); const request = { // 'clientOrderId': '123', // order’s client id list for filter // page: 0, // results page you want to retrieve (0 .. N) 'sort': sort, // sorting criteria in the format "property,asc" or "property,desc", default order is ascending, multiple sort criteria are supported }; let market = undefined; if (symbol !== undefined) { market = this.market(symbol); request['symbol'] = market['id']; } if (limit !== undefined) { request['size'] = limit; } const response = await this.tradingGetOrders(this.extend(request, query)); // // { // "orders": [ // { // "cancelledQuantity": "0.3", // "clientOrderId": "my-order-1", // "createdAt": "1970-01-01T00:00:00", // "cursorId": 50, // "expireTime": "1970-01-01T00:00:00", // "filledQuantity": "0.3", // "id": "string", // "price": "0.017", // "quantity": "0.3", // "side": "BUY", // "symbol": "TIMEETH", // "type": "LIMIT", // "updatedAt": "1970-01-01T00:00:00" // } // ] // } // const orders = this.safeValue(response, 'orders', []); return this.parseOrders(orders, market, since, limit); } async fetchClosedOrders(symbol = undefined, since = undefined, limit = undefined, params = {}) { /** * @method * @name timex#fetchClosedOrders * @description fetches information on multiple closed orders made by the user * @param {string|undefined} symbol unified market symbol of the market orders were made in * @param {int|undefined} since the earliest time in ms to fetch orders for * @param {int|undefined} limit the maximum number of orde structures to retrieve * @param {object} params extra parameters specific to the timex api endpoint * @returns {[object]} a list of [order structures]{@link https://docs.ccxt.com/#/?id=order-structure} */ await this.loadMarkets(); const options = this.safeValue(this.options, 'fetchClosedOrders', {}); const defaultSort = this.safeValue(options, 'sort', 'createdAt,asc'); const sort = this.safeString(params, 'sort', defaultSort); const query = this.omit(params, 'sort'); const request = { // 'clientOrderId': '123', // order’s client id list for filter // page: 0, // results page you want to retrieve (0 .. N) 'sort': sort, 'side': 'BUY', // or 'SELL' // 'till': this.iso8601 (this.milliseconds ()), }; let market = undefined; if (symbol !== undefined) { market = this.market(symbol); request['symbol'] = market['id']; } if (since !== undefined) { request['from'] = this.iso8601(since); } if (limit !== undefined) { request['size'] = limit; } const response = await this.historyGetOrders(this.extend(request, query)); // // { // "orders": [ // { // "cancelledQuantity": "0.3", // "clientOrderId": "my-order-1", // "createdAt": "1970-01-01T00:00:00", // "cursorId": 50, // "expireTime": "1970-01-01T00:00:00", // "filledQuantity": "0.3", // "id": "string", // "price": "0.017", // "quantity": "0.3", // "side": "BUY", // "symbol": "TIMEETH", // "type": "LIMIT", // "updatedAt": "1970-01-01T00:00:00" // } // ] // } // const orders = this.safeValue(response, 'orders', []); return this.parseOrders(orders, market, since, limit); } async fetchMyTrades(symbol = undefined, since = undefined, limit = undefined, params = {}) { /** * @method * @name timex#fetchMyTrades * @description fetch all trades made by the user * @param {string|undefined} symbol unified market symbol * @param {int|undefined} since the earliest time in ms to fetch trades for * @param {int|undefined} limit the maximum number of trades structures to retrieve * @param {object} params extra parameters specific to the timex api endpoint * @returns {[object]} a list of [trade structures]{@link https://docs.ccxt.com/#/?id=trade-structure} */ await this.loadMarkets(); const options = this.safeValue(this.options, 'fetchMyTrades', {}); const defaultSort = this.safeValue(options, 'sort', 'timestamp,asc'); const sort = this.safeString(params, 'sort', defaultSort); const query = this.omit(params, 'sort'); const request = { // 'cursorId': 123, // int64 (?) // 'from': this.iso8601 (since), // 'makerOrderId': '1234', // maker order hash // 'owner': '...', // owner address (?) // 'page': 0, // results page you want to retrieve (0 .. N) // 'side': 'BUY', // or 'SELL' // 'size': limit, 'sort': sort, // sorting criteria in the format "property,asc" or "property,desc", default order is ascending, multiple sort criteria are supported // 'symbol': market['id'], // 'takerOrderId': '1234', // 'till': this.iso8601 (this.milliseconds ()), }; let market = undefined; if (symbol !== undefined) { market = this.market(symbol); request['symbol'] = market['id']; } if (since !== undefined) { request['from'] = this.iso8601(since); }