UNPKG

@proton/ccxt

Version:

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

1,125 lines (1,122 loc) 122 kB
'use strict'; var stex$1 = require('./abstract/stex.js'); var errors = require('./base/errors.js'); var Precise = require('./base/Precise.js'); var number = require('./base/functions/number.js'); // --------------------------------------------------------------------------- // --------------------------------------------------------------------------- class stex extends stex$1 { describe() { return this.deepExtend(super.describe(), { 'id': 'stex', 'name': 'STEX', 'countries': ['EE'], 'rateLimit': 1000 / 3, 'certified': false, // new metainfo interface 'has': { 'CORS': undefined, 'spot': true, 'margin': false, 'swap': false, 'future': false, 'option': false, 'addMargin': false, 'cancelAllOrders': true, 'cancelOrder': true, 'createDepositAddress': true, 'createMarketOrder': false, 'createOrder': true, 'createReduceOnlyOrder': false, 'fetchBalance': true, 'fetchBorrowRate': false, 'fetchBorrowRateHistories': false, 'fetchBorrowRateHistory': false, 'fetchBorrowRates': false, 'fetchBorrowRatesPerSymbol': false, 'fetchClosedOrder': true, 'fetchCurrencies': true, 'fetchDeposit': true, 'fetchDepositAddress': true, 'fetchDeposits': true, 'fetchDepositWithdrawFee': 'emulated', 'fetchDepositWithdrawFees': 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, 'fetchOrderTrades': true, 'fetchPosition': false, 'fetchPositionMode': false, 'fetchPositions': false, 'fetchPositionsRisk': false, 'fetchPremiumIndexOHLCV': false, 'fetchTicker': true, 'fetchTickers': true, 'fetchTime': true, 'fetchTrades': true, 'fetchTradingFee': true, 'fetchTradingFees': false, 'fetchTransactionFees': true, 'fetchWithdrawal': true, 'fetchWithdrawals': true, 'reduceMargin': false, 'setLeverage': false, 'setMarginMode': false, 'setPositionMode': false, 'transfer': true, 'withdraw': true, }, 'version': 'v3', 'urls': { 'logo': 'https://user-images.githubusercontent.com/1294454/69680782-03fd0b80-10bd-11ea-909e-7f603500e9cc.jpg', 'api': { 'rest': 'https://api3.stex.com', }, 'www': 'https://www.stex.com', 'doc': [ 'https://apidocs.stex.com/', 'https://help.stex.com/en/collections/1593608-api-v3-documentation', ], 'fees': 'https://app.stex.com/en/pairs-specification', 'referral': 'https://app.stex.com?ref=36416021', }, 'requiredCredentials': { 'apiKey': false, 'secret': false, 'token': true, }, 'timeframes': { '1m': '1', '5m': '5', '30m': '30', '1h': '60', '4h': '240', '12h': '720', '1d': '1D', // default }, 'api': { 'public': { 'get': { 'currencies': 1, 'currencies/{currencyId}': 1, 'markets': 1, 'pairs-groups': 1, 'currency_pairs/list/{code}': 1, 'currency_pairs/group/{currencyPairGroupId}': 1, 'currency_pairs/{currencyPairId}': 1, 'ticker': 1, 'ticker/{currencyPairId}': 1, 'trades/{currencyPairId}': 1, 'orderbook/{currencyPairId}': 1, 'chart/{currencyPairId}/{candlesType}': 1, 'deposit-statuses': 1, 'deposit-statuses/{statusId}': 1, 'withdrawal-statuses': 1, 'withdrawal-statuses/{statusId}': 1, 'ping': 1, 'mobile-versions': 1, 'twitter': 1, // Get the last 20 posts (stex.com) on Twitter }, }, 'trading': { 'get': { 'fees/{currencyPairId}': 1, 'orders': 12, 'orders/{currencyPairId}': 6, 'order/{orderId}': 12, // Get a single order }, 'post': { 'orders/{currencyPairId}': 1.5, 'orders/bulk/{currencyPairId}': 12, // Create new orders in a bulk and put it to the orders processing queue }, 'delete': { 'orders': 30, 'orders/{currencyPairId}': 12, 'order/{orderId}': 1.5, // Cancel order }, }, 'reports': { 'get': { 'currencies': 12, 'currency_pairs': 12, 'orders': 12, 'orders/{orderId}': 12, 'trades/{currencyPairId}': 12, 'background/{listMode}': 12, 'background/{id}': 12, 'background/download/{id}': 12, // Get file by id }, 'post': { 'background/create': 12, // Create new report }, 'delete': { 'background/{id}': 12, // Remove report by id }, }, 'profile': { 'get': { 'info': 3, 'wallets': 3, 'wallets/{walletId}': 3, 'wallets/address/{walletId}': 3, 'deposits': 3, 'deposits/{id}': 3, 'rewards': 3, 'rewards/{id}': 3, 'addressbook': 3, 'addressbook/{itemId}': 3, 'withdrawals': 3, 'withdrawals/{id}': 3, 'notifications': 3, 'notifications/price': 3, 'favorite/currency_pairs': 3, 'token-scopes': 3, // Get current token scopes }, 'post': { 'wallets/burn/{walletId}': 3, 'wallets/{walletId}/hold_amount': 3, 'wallets/{currencyId}': 3, 'wallets/address/{walletId}': 3, 'addressbook/disable_item/{itemId}': 3, 'addressbook/enable_item/{itemId}': 3, 'addressbook/enable_strict_wd': 3, 'addressbook/disable_strict_wd': 3, 'withdraw': 30, 'notifications/price': 3, 'referral/program': 3, 'referral/insert/{code}': 3, 'referral/bonus_transfer/{currencyId}': 3, // Transfer referral bonuses balance to main balance for given currency }, 'put': { 'favorite/currency_pairs/set': 3, // Set favorite currency pairs }, 'delete': { 'addressbook/{itemId}': 3, 'withdraw/{withdrawalId}': 30, 'notifications/price/{priceAlertId}': 3, // Delete the price alert by ID }, }, 'verification': { 'get': { 'countries': 1, 'status': 1, 'fractal/url': 1, 'smart-id': 1, 'stex': 1, 'cryptonomica/code': 1, // Get Discount code for Cryptonomica }, 'post': { 'smart-id': 1, 'stex': 1, 'cryptonomica': 1, // Add verification from Cryptonomica }, }, 'settings': { 'get': { 'notifications/{event}': 1, 'notifications': 1, // User events notification settings }, 'put': { 'notifications': 1, 'notifications/set': 1, }, }, }, 'fees': { 'trading': { 'tierBased': false, 'percentage': true, 'taker': this.parseNumber('0.002'), 'maker': this.parseNumber('0.002'), }, }, 'commonCurrencies': { 'BC': 'Bitcoin Confidential', 'BITS': 'Bitcoinus', 'BITSW': 'BITS', 'BHD': 'Bithold', 'BTH': 'Bithereum', 'MPH': 'Chasyr Token', 'SBTC': 'SBTCT', // SiamBitcoin }, 'options': { 'parseOrderToPrecision': false, 'networks': { 'ERC20': 5, 'ETH': 5, 'OMNI': 10, 'XLM': 20, 'BEP2': 22, 'TRC20': 24, 'TRX': 24, 'SOL': 25, 'BEP20': 501, }, 'accountsByType': { 'spot': 'spot', 'hold': 'hold', 'funding': 'funding', 'referal': 'referal', }, 'transfer': { 'fillResponseFromRequest': true, }, }, 'precisionMode': number.TICK_SIZE, 'exceptions': { 'exact': { // {"success":false,"message":"Wrong parameters","errors":{"candleType":["Invalid Candle Type!"]}} // {"success":false,"message":"Wrong parameters","errors":{"time":["timeStart or timeEnd is less then 1"]}} 'Wrong parameters': errors.BadRequest, 'Unauthenticated.': errors.AuthenticationError, 'Server Error': errors.ExchangeError, 'This feature is only enabled for users verifies by Cryptonomica': errors.PermissionDenied, 'Too Many Attempts.': errors.DDoSProtection, 'Selected Pair is disabled': errors.BadSymbol, 'Invalid scope(s) provided.': errors.PermissionDenied, 'The maximum amount of open orders with the same price cannot exceed 10': errors.InvalidOrder, 'Your account not verified!': errors.AccountSuspended, // {"success":false,"message":"Your account not verified!","unified_message":{"message_id":"verification_required_to_continue","substitutions":null},"notice":"Please be informed that parameter `message` is deprecated and will be removed. Use unified_message instead."} }, 'broad': { 'Not enough': errors.InsufficientFunds, // {"success":false,"message":"Not enough ETH"} }, }, }); } async fetchCurrencies(params = {}) { /** * @method * @name stex#fetchCurrencies * @see https://apidocs.stex.com/#tag/Public/paths/~1public~1currencies/get * @description fetches all available currencies on an exchange * @param {object} params extra parameters specific to the stex api endpoint * @returns {object} an associative dictionary of currencies */ const response = await this.publicGetCurrencies(params); // // { // "success":true, // "data":[ // { // "id":1, // "code":"BTC", // "name":"Bitcoin", // "active":true, // "delisted":false, // "precision":8, // "minimum_tx_confirmations":1, // "minimum_withdrawal_amount":"0.00200000", // "minimum_deposit_amount":"0.00000000", // "deposit_fee_currency_id":1, // "deposit_fee_currency_code":"BTC", // "deposit_fee_const":"0.00000000", // "deposit_fee_percent":"0.00000000", // "withdrawal_fee_currency_id":1, // "withdrawal_fee_currency_code":"BTC", // "withdrawal_fee_const":"0.00100000", // "withdrawal_fee_percent":"0.00000000", // "block_explorer_url":"https:\/\/blockchain.info\/tx\/", // "protocol_specific_settings":null // }, // ] // } // const result = {}; const currencies = this.safeValue(response, 'data', []); for (let i = 0; i < currencies.length; i++) { const currency = currencies[i]; const id = this.safeString(currency, 'id'); const numericId = this.safeInteger(currency, 'id'); // todo: will need to rethink the fees // to add support for multiple withdrawal/deposit methods and // differentiated fees for each particular method const code = this.safeCurrencyCode(this.safeString(currency, 'code')); const precision = this.parseNumber(this.parsePrecision(this.safeString(currency, 'precision'))); const fee = this.safeNumber(currency, 'withdrawal_fee_const'); // todo: redesign const active = this.safeValue(currency, 'active', true); result[code] = { 'id': id, 'numericId': numericId, 'code': code, 'info': currency, 'type': undefined, 'name': this.safeString(currency, 'name'), 'active': active, 'deposit': undefined, 'withdraw': undefined, 'fee': fee, 'precision': precision, 'limits': { 'amount': { 'min': precision, 'max': undefined, }, 'deposit': { 'min': this.safeNumber(currency, 'minimum_deposit_amount'), 'max': undefined, }, 'withdraw': { 'min': this.safeNumber(currency, 'minimum_withdrawal_amount'), 'max': undefined, }, }, 'networks': {}, }; } return result; } async fetchMarkets(params = {}) { /** * @method * @name stex#fetchMarkets * @see https://apidocs.stex.com/#tag/Public/paths/~1public~1currency_pairs~1list~1{code}/get * @description retrieves data on all markets for stex * @param {object} params extra parameters specific to the exchange api endpoint * @returns {[object]} an array of objects representing market data */ const request = { 'code': 'ALL', }; const response = await this.publicGetCurrencyPairsListCode(this.extend(request, params)); // // { // "success":true, // "data":[ // { // "id":935, // "currency_id":662, // "currency_code":"ABET", // "currency_name":"Altbet", // "market_currency_id":1, // "market_code":"BTC", // "market_name":"Bitcoin", // "min_order_amount":"0.00000010", // "min_buy_price":"0.00000001", // "min_sell_price":"0.00000001", // "buy_fee_percent":"0.20000000", // "sell_fee_percent":"0.20000000", // "active":true, // "delisted":false, // "pair_message":"", // "currency_precision":8, // "market_precision":8, // "symbol":"ABET_BTC", // "group_name":"BTC", // "group_id":1 // } // ] // } // const result = []; const markets = this.safeValue(response, 'data', []); for (let i = 0; i < markets.length; i++) { const market = markets[i]; const id = this.safeString(market, 'id'); const numericId = this.safeInteger(market, 'id'); const baseId = this.safeString(market, 'currency_id'); const quoteId = this.safeString(market, 'market_currency_id'); const baseNumericId = this.safeInteger(market, 'currency_id'); const quoteNumericId = this.safeInteger(market, 'market_currency_id'); const base = this.safeCurrencyCode(this.safeString(market, 'currency_code')); const quote = this.safeCurrencyCode(this.safeString(market, 'market_code')); const minBuyPrice = this.safeString(market, 'min_buy_price'); const minSellPrice = this.safeString(market, 'min_sell_price'); const minPrice = Precise["default"].stringMax(minBuyPrice, minSellPrice); const buyFee = Precise["default"].stringDiv(this.safeString(market, 'buy_fee_percent'), '100'); const sellFee = Precise["default"].stringDiv(this.safeString(market, 'sell_fee_percent'), '100'); const fee = this.parseNumber(Precise["default"].stringMax(buyFee, sellFee)); result.push({ 'id': id, 'numericId': numericId, 'symbol': base + '/' + quote, 'base': base, 'quote': quote, 'settle': undefined, 'baseId': baseId, 'quoteId': quoteId, 'settleId': undefined, 'baseNumericId': baseNumericId, 'quoteNumericId': quoteNumericId, 'type': 'spot', 'spot': true, 'margin': false, 'swap': false, 'future': false, 'option': false, 'active': this.safeValue(market, 'active'), 'contract': false, 'linear': undefined, 'inverse': undefined, 'taker': fee, 'maker': fee, 'contractSize': undefined, 'expiry': undefined, 'expiryDatetime': undefined, 'strike': undefined, 'optionType': undefined, 'precision': { 'amount': this.parseNumber(this.parsePrecision(this.safeString(market, 'currency_precision'))), 'price': this.parseNumber(this.parsePrecision(this.safeString(market, 'market_precision'))), }, 'limits': { 'leverage': { 'min': undefined, 'max': undefined, }, 'amount': { 'min': this.safeNumber(market, 'min_order_amount'), 'max': undefined, }, 'price': { 'min': minPrice, 'max': undefined, }, 'cost': { 'min': undefined, 'max': undefined, }, }, 'info': market, }); } return result; } async fetchTicker(symbol, params = {}) { /** * @method * @name stex#fetchTicker * @see https://apidocs.stex.com/#tag/Public/paths/~1public~1ticker~1{currencyPairId}/get * @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 stex api endpoint * @returns {object} a [ticker structure]{@link https://docs.ccxt.com/#/?id=ticker-structure} */ await this.loadMarkets(); const market = this.market(symbol); const request = { 'currencyPairId': market['id'], }; const response = await this.publicGetTickerCurrencyPairId(this.extend(request, params)); // // { // "success": true, // "data": { // "id": 2, // "amount_multiplier": 1, // "currency_code": "ETH", // "market_code": "BTC", // "currency_name": "Ethereum", // "market_name": "Bitcoin", // "symbol": "ETH_BTC", // "group_name": "BTC", // "group_id": 1, // "ask": "0.02069998", // "bid": "0.02028622", // "last": "0.02049224", // "open": "0.02059605", // "low": "0.01977744", // "high": "0.02097005", // "volume": "480.43248971", // "volumeQuote": "23491.29826130", // "count": "7384", // "fiatsRate": { // "USD": 7230.86, // "EUR": 6590.79, // "UAH": 173402, // "AUD": 10595.51, // "IDR": 101568085, // "CNY": 50752, // "KRW": 8452295, // "JPY": 784607, // "VND": 167315119, // "INR": 517596, // "GBP": 5607.25, // "CAD": 9602.63, // "BRL": 30472, // "RUB": 460718 // }, // "timestamp": 1574698235601 // } // } // const ticker = this.safeValue(response, 'data', {}); return this.parseTicker(ticker, market); } async fetchTime(params = {}) { /** * @method * @name stex#fetchTime * @see https://apidocs.stex.com/#tag/Public/paths/~1public~1ping/get * @description fetches the current integer timestamp in milliseconds from the exchange server * @param {object} params extra parameters specific to the stex api endpoint * @returns {int} the current integer timestamp in milliseconds from the exchange server */ const response = await this.publicGetPing(params); // // { // "success": true, // "data": { // "server_datetime": { // "date": "2019-01-22 15:13:34.233796", // "timezone_type": 3, // "timezone": "UTC" // }, // "server_timestamp": 1548170014 // } // } // const data = this.safeValue(response, 'data', {}); const serverDatetime = this.safeValue(data, 'server_datetime', {}); return this.parse8601(this.safeString(serverDatetime, 'date')); } async fetchOrderBook(symbol, limit = undefined, params = {}) { /** * @method * @name stex#fetchOrderBook * @see https://apidocs.stex.com/#tag/Public/paths/~1public~1orderbook~1{currencyPairId}/get * @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 stex 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 = { 'currencyPairId': market['id'], }; if (limit !== undefined) { request['limit_bids'] = limit; // returns all if set to 0, default 100 request['limit_asks'] = limit; // returns all if set to 0, default 100 } const response = await this.publicGetOrderbookCurrencyPairId(this.extend(request, params)); // // { // "success": true, // "data": { // "ask": [ // { "currency_pair_id": 2, "amount": "2.17865373", "price": "0.02062917", "amount2": "0.04494382", "count": 1, "cumulative_amount": 2.17865373 }, // { "currency_pair_id": 2, "amount": "2.27521743", "price": "0.02062918", "amount2": "0.04693587", "count": 1, "cumulative_amount": 4.45387116 }, // { "currency_pair_id": 2, "amount": "1.26980049", "price": "0.02063170", "amount2": "0.02619814", "count": 1, "cumulative_amount": 5.72367165 }, // ], // "bid": [ // { "currency_pair_id": 2, "amount": "0.00978005", "price": "0.02057000", "amount2": "0.00020118", "count": 1, "cumulative_amount": 0.00978005 }, // { "currency_pair_id": 2, "amount": "0.00500000", "price": "0.02056000", "amount2": "0.00010280", "count": 1, "cumulative_amount": 0.01478005 }, // { "currency_pair_id": 2, "amount": "0.77679882", "price": "0.02054001", "amount2": "0.01595546", "count": 1, "cumulative_amount": 0.79157887 }, // ], // "ask_total_amount": 2555.749174609999, // "bid_total_amount": 29.180037330000005 // } // } // const orderbook = this.safeValue(response, 'data', {}); return this.parseOrderBook(orderbook, symbol, undefined, 'bid', 'ask', 'price', 'amount'); } parseTicker(ticker, market = undefined) { // // { // "id": 2, // "amount_multiplier": 1, // "currency_code": "ETH", // "market_code": "BTC", // "currency_name": "Ethereum", // "market_name": "Bitcoin", // "symbol": "ETH_BTC", // "group_name": "BTC", // "group_id": 1, // "ask": "0.02069998", // "bid": "0.02028622", // "last": "0.02049224", // "open": "0.02059605", // "low": "0.01977744", // "high": "0.02097005", // "volume": "480.43248971", // "volumeQuote": "23491.29826130", // "count": "7384", // "fiatsRate": { // "USD": 7230.86, // "EUR": 6590.79, // "UAH": 173402, // "AUD": 10595.51, // "IDR": 101568085, // "CNY": 50752, // "KRW": 8452295, // "JPY": 784607, // "VND": 167315119, // "INR": 517596, // "GBP": 5607.25, // "CAD": 9602.63, // "BRL": 30472, // "RUB": 460718 // }, // "timestamp": 1574698235601 // } // const timestamp = this.safeInteger(ticker, 'timestamp'); const marketId = this.safeString2(ticker, 'id', 'symbol'); const symbol = this.safeSymbol(marketId, market, '_'); const last = this.safeString(ticker, 'last'); const open = this.safeString(ticker, 'open'); return this.safeTicker({ 'symbol': symbol, 'timestamp': timestamp, 'datetime': this.iso8601(timestamp), 'high': this.safeString(ticker, 'high'), 'low': this.safeString(ticker, 'low'), 'bid': this.safeString(ticker, 'bid'), 'bidVolume': undefined, 'ask': this.safeString(ticker, 'ask'), 'askVolume': undefined, 'vwap': undefined, 'open': open, 'close': last, 'last': last, 'previousClose': undefined, 'change': undefined, 'percentage': undefined, 'average': undefined, 'baseVolume': this.safeString(ticker, 'volumeQuote'), 'quoteVolume': this.safeString(ticker, 'volume'), 'info': ticker, }, market); } async fetchTickers(symbols = undefined, params = {}) { /** * @method * @name stex#fetchTickers * @see https://apidocs.stex.com/#tag/Public/paths/~1public~1ticker/get * @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 stex api endpoint * @returns {object} a dictionary of [ticker structures]{@link https://docs.ccxt.com/#/?id=ticker-structure} */ await this.loadMarkets(); const response = await this.publicGetTicker(params); // // { // "success":true, // "data":[ // { // "id":262, // "amount_multiplier":1, // "currency_code":"ARDR", // "market_code":"BTC", // "currency_name":"ARDOR", // "market_name":"Bitcoin", // "symbol":"ARDR_BTC", // "group_name":"BTC", // "group_id":1, // "ask":"0.00000630", // "bid":"0.00000613", // "last":"0.00000617", // "open":"0.00000620", // "low":"0.00000614", // "high":"0.00000630", // "volume":"30.37795305", // "volumeQuote":"4911487.01996544", // "count":"710", // "fiatsRate":{ // "USD":7230.86, // "EUR":6590.79, // "UAH":173402, // "AUD":10744.52, // "IDR":101568085, // "CNY":50752, // "KRW":8452295, // "JPY":784607, // "VND":167315119, // "INR":517596, // "GBP":5607.25, // "CAD":9602.63, // "BRL":30472, // "RUB":467358 // }, // "timestamp":1574698617304, // "group_position":1 // }, // ] // } // const tickers = this.safeValue(response, 'data', []); return this.parseTickers(tickers, symbols); } parseOHLCV(ohlcv, market = undefined) { // // { // "time": 1566086400000, // "close": 0.01895, // "open": 0.01812427, // "high": 0.0191588, // "low": 0.01807001, // "volume": 2588.597813750006 // } // return [ this.safeInteger(ohlcv, 'time'), this.safeNumber(ohlcv, 'open'), this.safeNumber(ohlcv, 'high'), this.safeNumber(ohlcv, 'low'), this.safeNumber(ohlcv, 'close'), this.safeNumber(ohlcv, 'volume'), ]; } async fetchOHLCV(symbol, timeframe = '1m', since = undefined, limit = undefined, params = {}) { /** * @method * @name stex#fetchOHLCV * @see https://apidocs.stex.com/#tag/Public/paths/~1public~1chart~1{currencyPairId}~1{candlesType}/get * @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 stex 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 = { 'currencyPairId': market['id'], 'candlesType': this.safeString(this.timeframes, timeframe, timeframe), // default 1d // 'timeStart': 1574709092, // unix timestamp in seconds, required // 'timeEnd': 1574709092, // unix timestamp in seconds, required // 'limit': 100, // default 100, optional // 'offset' 100, // optional, pagination within timerange }; if (limit === undefined) { limit = 100; } else { request['limit'] = limit; } const duration = this.parseTimeframe(timeframe); const timerange = limit * duration; if (since === undefined) { request['timeEnd'] = this.seconds(); request['timeStart'] = request['timeEnd'] - timerange; } else { request['timeStart'] = this.parseToInt(since / 1000); request['timeEnd'] = this.sum(request['timeStart'], timerange); } const response = await this.publicGetChartCurrencyPairIdCandlesType(this.extend(request, params)); // // { // "success": true, // "data": [ // { // "time": 1566086400000, // "close": 0.01895, // "open": 0.01812427, // "high": 0.0191588, // "low": 0.01807001, // "volume": 2588.597813750006 // }, // ] // } // const data = this.safeValue(response, 'data', []); return this.parseOHLCVs(data, market, timeframe, since, limit); } parseTrade(trade, market = undefined) { // // public fetchTrades // // { // "id": 35989317, // "price": "0.02033813", // "amount": "3.60000000", // "type": "BUY", // "timestamp": "1574713503" // } // // private fetchMyTrades, fetchClosedOrder, fetchOrderTrades // // { // "id": 658745, // "buy_order_id": 6587453, // "sell_order_id": 6587459, // "price": 0.012285, // "amount": 6.35, // "trade_type": "SELL", // "timestamp": "1538737692" // } // const id = this.safeString(trade, 'id'); const timestamp = this.safeTimestamp(trade, 'timestamp'); const priceString = this.safeString(trade, 'price'); const amountString = this.safeString(trade, 'amount'); let symbol = undefined; if ((symbol === undefined) && (market !== undefined)) { symbol = market['symbol']; } const side = this.safeStringLower2(trade, 'type', 'trade_type'); return this.safeTrade({ 'info': trade, 'timestamp': timestamp, 'datetime': this.iso8601(timestamp), 'symbol': symbol, 'id': id, 'order': undefined, 'type': undefined, 'takerOrMaker': undefined, 'side': side, 'price': priceString, 'amount': amountString, 'cost': undefined, 'fee': undefined, }, market); } async fetchTrades(symbol, since = undefined, limit = undefined, params = {}) { /** * @method * @name stex#fetchTrades * @see https://apidocs.stex.com/#tag/Public/paths/~1public~1trades~1{currencyPairId}/get * @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 stex api endpoint * @returns {[object]} a list of [trade structures]{@link https://docs.ccxt.com/en/latest/manual.html?#public-trades} */ await this.loadMarkets(); const market = this.market(symbol); const request = { 'currencyPairId': market['id'], // 'sort': 'ASC', // ASC or DESC, default DESC // 'from': 1574709092, // unix timestamp, optional // 'till': 1574709092, // unix timestamp, optional // 'limit': 100, // default 100, optional // 'offset': 100, // optional }; if (limit !== undefined) { request['limit'] = limit; // currently limited to 100 or fewer } if (since !== undefined) { request['sort'] = 'ASC'; // needed to make the from param work request['from'] = this.parseToInt(since / 1000); } const response = await this.publicGetTradesCurrencyPairId(this.extend(request, params)); // // { // "success": true, // "data": [ // { // "id": 35989317, // "price": "0.02033813", // "amount": "3.60000000", // "type": "BUY", // "timestamp": "1574713503" // }, // ] // } // const trades = this.safeValue(response, 'data', []); return this.parseTrades(trades, market, since, limit); } async fetchTradingFee(symbol, params = {}) { /** * @method * @name stex#fetchTradingFee * @see https://apidocs.stex.com/#tag/Trading/paths/~1trading~1fees~1{currencyPairId}/get * @description fetch the trading fees for a market * @param {string} symbol unified market symbol * @param {object} params extra parameters specific to the stex api endpoint * @returns {object} a [fee structure]{@link https://docs.ccxt.com/#/?id=fee-structure} */ await this.loadMarkets(); const market = this.market(symbol); const request = { 'currencyPairId': market['id'], }; const response = await this.tradingGetFeesCurrencyPairId(this.extend(request, params)); // // { // success: true, // data: { buy_fee: '0.00200000', sell_fee: '0.00200000' }, // unified_message: { message_id: 'operation_successful', substitutions: [] } // } // const data = this.safeValue(response, 'data'); return { 'info': response, 'symbol': market['symbol'], 'maker': this.safeNumber(data, 'sell_fee'), 'taker': this.safeNumber(data, 'buy_fee'), 'percentage': true, 'tierBased': true, }; } parseBalance(response) { const result = { 'info': response, 'timestamp': undefined, 'datetime': undefined, }; const balances = this.safeValue(response, 'data', []); for (let i = 0; i < balances.length; i++) { const balance = balances[i]; const code = this.safeCurrencyCode(this.safeString(balance, 'currency_id')); const account = this.account(); account['free'] = this.safeString(balance, 'balance'); account['used'] = this.safeString(balance, 'frozen_balance'); result[code] = account; } return this.safeBalance(result); } async fetchBalance(params = {}) { /** * @method * @name stex#fetchBalance * @see https://apidocs.stex.com/#tag/Profile/paths/~1profile~1wallets/get * @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 stex api endpoint * @returns {object} a [balance structure]{@link https://docs.ccxt.com/en/latest/manual.html?#balance-structure} */ await this.loadMarkets(); // await this.loadAccounts (); const response = await this.profileGetWallets(params); // // { // "success": true, // "data": [ // { // "id": null, // "currency_id": 665, // "delisted": false, // "disabled": false, // "disable_deposits": false, // "currency_code": "ORM", // "currency_name": "Orium", // "currency_type_id": 5, // "balance": "0", // "frozen_balance": "0", // "bonus_balance": "0", // "total_balance": "0", // "protocol_specific_settings": null, // "rates": { "BTC": "0.00000000020", "USD": "0.00000147" }, // }, // { // "id": null, // "currency_id": 272, // "delisted": false, // "disabled": false, // "disable_deposits": false, // "currency_code": "USDT", // "currency_name": "TetherUSD", // "currency_type_id": 23, // "balance": "0", // "frozen_balance": "0", // "bonus_balance": "0", // "total_balance": "0", // "protocol_specific_settings": [ // { "protocol_name": "OMNI", "protocol_id": 10, "active": true, "withdrawal_fee_currency_id": 272, "withdrawal_fee_const": 10, "withdrawal_fee_percent": 0, "block_explorer_url": "https://omniexplorer.info/search/" }, // { "protocol_name": "ERC20", "protocol_id": 5, "active": true, "withdrawal_fee_const": 1.2, "withdrawal_fee_percent": 0, "block_explorer_url": "https://etherscan.io/tx/" }, // { "protocol_name": "TRON", "protocol_id": 24, "active": true, "withdrawal_fee_currency_id": 272, "withdrawal_fee_const": 0.2, "withdrawal_fee_percent": 0, "block_explorer_url": "https://tronscan.org/#/transaction/" } // ], // "rates": { "BTC": "0.00013893", "USD": "1" }, // }, // ] // } // return this.parseBalance(response); } parseOrderStatus(status) { const statuses = { 'PROCESSING': 'open', 'PENDING': 'open', 'PARTIAL': 'open', 'FINISHED': 'closed', 'CANCELLED': 'canceled', }; return this.safeString(statuses, status, status); } parseOrder(order, market = undefined) { // // createOrder, fetchOpenOrders, fetchClosedOrders, cancelOrder, fetchOrder, fetchClosedOrder // // { // "id": 828680665, // "currency_pair_id": 1, // "currency_pair_name": "NXT_BTC", // "price": "0.011384", // "trigger_price": 0.011385, // "initial_amount": "13.942", // "processed_amount": "3.724", // missing in fetchClosedOrder // "type": "SELL", // "original_type": "STOP_LIMIT_SELL", // "created": "2019-01-17 10:14:48", // "timestamp": "1547720088", // "status": "PARTIAL" // // fetchClosedOrder only // "trades": [ // { // "id": 658745, // "buy_order_id": 658745, // "sell_order_id": 828680665, // "price": 0.012285, // "amount": 6.35, // "trade_type": "SELL", // "timestamp": "1538737692" // } // ], // // fetchClosedOrder only // "fees": [ // { // "id": 1234567, // "currency_id": 1, // "amount": 0.00025, // "timestamp": "1548149238" // } // ] // } // const id = this.safeString(order, 'id'); const status = this.parseOrderStatus(this.safeString(order, 'status')); const marketId = this.safeString2(order, 'currency_pair_id', 'currency_pair_name'); const symbol = this.safeSymbol(marketId, market, '_'); const timestamp = this.safeTimestamp(order, 'timestamp'); const price = this.safeString(order, 'price'); const amount = this.safeString(order, 'initial_amount'); const filled = this.safeString(order, 'processed_amount'); let remaining = undefined; let cost = undefined; if (filled !== undefined) { if (amount !== undefined) { remaining = Precise["default"].stringSub(amount, filled); if (this.options['parseOrderToPrecision']) { remaining = this.amountToPrecision(symbol, remaining); } remaining = Precise["default"].stringMax(remaining, '0.0'); } if (price !== undefined) { if (cost === undefined) { cost = Precise["default"].stringMul(price, filled); } } } let type = this.safeString(order, 'original_type'); if ((type === 'BUY') || (type === 'SELL')) { type = undefined; } const side = this.safeStringLower(order, 'type'); const trades = this.safeValue(order, 'trades'); const stopPrice = this.safeNumber(order, 'trigger_price'); const result = { 'info': order, 'id': id, 'clientOrderId': undefined, 'timestamp': timestamp,