UNPKG

consequunturatque

Version:

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

1,161 lines (1,137 loc) 78.5 kB
'use strict'; // --------------------------------------------------------------------------- const Exchange = require ('./base/Exchange'); const { ArgumentsRequired, AuthenticationError, ExchangeError, InsufficientFunds, OrderNotFound, PermissionDenied, BadRequest, DDoSProtection } = require ('./base/errors'); const Precise = require ('./base/Precise'); // --------------------------------------------------------------------------- module.exports = class stex extends Exchange { describe () { return this.deepExtend (super.describe (), { 'id': 'stex', 'name': 'STEX', // formerly known as stocks.exchange 'countries': [ 'EE' ], // Estonia 'rateLimit': 500, // https://help.stex.com/en/articles/2815043-api-3-rate-limits 'certified': false, // new metainfo interface 'has': { 'cancelAllOrders': true, 'cancelOrder': true, 'CORS': false, 'createDepositAddress': true, 'createMarketOrder': false, // limit orders only 'createOrder': true, 'fetchBalance': true, 'fetchCurrencies': true, 'fetchDepositAddress': true, 'fetchDeposits': true, 'fetchFundingFees': true, 'fetchMarkets': true, 'fetchMyTrades': true, 'fetchOHLCV': true, 'fetchOpenOrders': true, 'fetchOrder': true, 'fetchOrderBook': true, 'fetchOrderTrades': true, 'fetchTicker': true, 'fetchTickers': true, 'fetchTime': true, 'fetchTrades': true, 'fetchWithdrawals': true, 'withdraw': true, }, 'version': 'v3', 'urls': { 'logo': 'https://user-images.githubusercontent.com/1294454/69680782-03fd0b80-10bd-11ea-909e-7f603500e9cc.jpg', 'api': 'https://api3.stex.com', 'www': 'https://www.stex.com', 'doc': [ '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', // Available Currencies 'currencies/{currencyId}', // Get currency info 'markets', // Available markets 'pairs-groups', // Available currency pairs groups (as displayed at stex trading page) 'currency_pairs/list/{code}', // Available currency pairs 'currency_pairs/group/{currencyPairGroupId}', // Available currency pairs for a given group 'currency_pairs/{currencyPairId}', // Get currency pair information 'ticker', // Tickers list for all currency pairs 'ticker/{currencyPairId}', // Ticker for currency pair 'trades/{currencyPairId}', // Trades for given currency pair 'orderbook/{currencyPairId}', // Orderbook for given currency pair 'chart/{currencyPairId}/{candlesType}', // A list of candles for given currency pair 'deposit-statuses', // Available Deposit Statuses 'deposit-statuses/{statusId}', // Get deposit status info 'withdrawal-statuses', // Available Withdrawal Statuses 'withdrawal-statuses/{statusId}', // Get status info 'ping', // Test API is working and get server time 'mobile-versions', // Shows the official mobile applications data ], }, 'trading': { 'get': [ 'fees/{currencyPairId}', // Returns the user's fees for a given currency pair 'orders', // List your currently open orders 'orders/{currencyPairId}', // List your currently open orders for given currency pair 'order/{orderId}', // Get a single order ], 'post': [ 'orders/{currencyPairId}', // Create new order and put it to the orders processing queue ], 'delete': [ 'orders', // Delete all active orders 'orders/{currencyPairId}', // Delete active orders for given currency pair 'order/{orderId}', // Cancel order ], }, 'reports': { 'get': [ 'orders', // Get past orders 'orders/{orderId}', // Get specified order details 'trades/{currencyPairId}', // Get a list of user trades according to request parameters 'background/{listMode}', // Get reports list for category 'background/{id}', // Get some report info 'background/download/{id}', // Get file by id ], 'post': [ 'background/create', // Create new report ], 'delete': [ 'background/{id}', // Remove report by id ], }, 'profile': { 'get': [ 'info', // Account information 'wallets', // Get a list of user wallets 'wallets/{walletId}', // Single wallet information 'wallets/address/{walletId}', // Get deposit address for given wallet 'deposits', // Get a list of deposits made by user 'deposits/{id}', // Get deposit by id 'withdrawals', // Get a list of withdrawals made by user 'withdrawals/{id}', // Get withdrawal by id 'notifications', // Get notifications 'favorite/currency_pairs', // Get favorite currency pairs 'token-scopes', // Get current token scopes ], 'post': [ 'wallets/burn/{walletId}', // Burns the given wallet 'wallets/{currencyId}', // Create a wallet for given currency 'wallets/address/{walletId}', // Create new deposit address 'withdraw', // Create withdrawal request 'referral/program', // Create referral program 'referral/insert/{code}', // Insert referral code 'referral/bonus_transfer/{currencyId}', // Transfer referral bonuses balance to main balance for given currency ], 'put': [ 'profile/favorite/currency_pairs/set', // Set favorite currency pairs ], 'delete': [ 'profile/withdraw/{withdrawalId}', // Cancel unconfirmed withdrawal ], }, 'verification': { 'get': [ 'verification/countries', // Countries list, beta 'verification/stex', // Get information about your KYC, beta ], 'post': [ 'verification/stex', // Update information regarding of your KYC verification, beta ], }, 'settings': { 'get': [ 'notifications/{event}', // User event notification settings 'notifications', // User events notification settings ], 'put': [ 'notifications', // Set notification settings 'notifications/set', ], }, }, 'fees': { 'trading': { 'tierBased': false, 'percentage': true, 'taker': 0.002, 'maker': 0.002, }, }, 'commonCurrencies': { 'BC': 'Bitcoin Confidential', 'BITS': 'Bitcoinus', 'BITSW': 'BITS', 'BHD': 'Bithold', 'BTH': 'Bithereum', 'MPH': 'Chasyr Token', 'SBTC': 'SBTCT', // SiamBitcoin }, 'options': { 'parseOrderToPrecision': false, }, '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': BadRequest, 'Unauthenticated.': AuthenticationError, // {"message":"Unauthenticated."} 'Server Error': ExchangeError, // { "message": "Server Error" } 'This feature is only enabled for users verifies by Cryptonomica': PermissionDenied, // {"success":false,"message":"This feature is only enabled for users verifies by Cryptonomica"} 'Too Many Attempts.': DDoSProtection, // { "message": "Too Many Attempts." } }, 'broad': { 'Not enough': InsufficientFunds, // {"success":false,"message":"Not enough ETH"} }, }, }); } async fetchCurrencies (params = {}) { 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.safeString (currency, 'precision'); const amountLimit = this.parsePrecision (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, 'fee': fee, 'precision': parseInt (precision), 'limits': { 'amount': { 'min': this.parseNumber (amountLimit), 'max': undefined }, 'deposit': { 'min': this.safeNumber (currency, 'minimum_deposit_amount'), 'max': undefined, }, 'withdraw': { 'min': this.safeNumber (currency, 'minimum_withdrawal_amount'), 'max': undefined, }, }, }; } return result; } async fetchMarkets (params = {}) { 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 symbol = base + '/' + quote; const precision = { 'amount': this.safeInteger (market, 'currency_precision'), 'price': this.safeInteger (market, 'market_precision'), }; const active = this.safeValue (market, 'active'); const minBuyPrice = this.safeNumber (market, 'min_buy_price'); const minSellPrice = this.safeNumber (market, 'min_sell_price'); const minPrice = Math.max (minBuyPrice, minSellPrice); const buyFee = this.safeNumber (market, 'buy_fee_percent') / 100; const sellFee = this.safeNumber (market, 'sell_fee_percent') / 100; const fee = Math.max (buyFee, sellFee); result.push ({ 'id': id, 'numericId': numericId, 'symbol': symbol, 'base': base, 'quote': quote, 'baseId': baseId, 'quoteId': quoteId, 'baseNumericId': baseNumericId, 'quoteNumericId': quoteNumericId, 'info': market, 'active': active, 'maker': fee, 'taker': fee, 'precision': precision, 'limits': { 'amount': { 'min': this.safeNumber (market, 'min_order_amount'), 'max': undefined, }, 'price': { 'min': minPrice, 'max': undefined }, 'cost': { 'min': undefined, 'max': undefined, }, }, }); } return result; } async fetchTicker (symbol, params = {}) { 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 = {}) { 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 = {}) { 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.safeNumber (ticker, 'last'); const open = this.safeNumber (ticker, 'open'); let change = undefined; let percentage = undefined; if (last !== undefined) { if ((open !== undefined) && (open > 0)) { change = last - open; percentage = ((100 / open) * last) - 100; } } return { 'symbol': symbol, 'timestamp': timestamp, 'datetime': this.iso8601 (timestamp), 'high': this.safeNumber (ticker, 'high'), 'low': this.safeNumber (ticker, 'low'), 'bid': this.safeNumber (ticker, 'bid'), 'bidVolume': undefined, 'ask': this.safeNumber (ticker, 'ask'), 'askVolume': undefined, 'vwap': undefined, 'open': open, 'close': last, 'last': last, 'previousClose': undefined, // previous day close 'change': change, 'percentage': percentage, 'average': undefined, 'baseVolume': this.safeNumber (ticker, 'volumeQuote'), 'quoteVolume': this.safeNumber (ticker, 'volume'), 'info': ticker, }; } async fetchTickers (symbols = undefined, params = {}) { 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 = '1d', since = undefined, limit = undefined, params = {}) { await this.loadMarkets (); const market = this.market (symbol); const request = { 'currencyPairId': market['id'], 'candlesType': this.timeframes[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'] = parseInt (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'); const price = this.parseNumber (priceString); const amount = this.parseNumber (amountString); const cost = this.parseNumber (Precise.stringMul (priceString, amountString)); let symbol = undefined; if ((symbol === undefined) && (market !== undefined)) { symbol = market['symbol']; } const side = this.safeStringLower2 (trade, 'type', 'trade_type'); return { 'info': trade, 'timestamp': timestamp, 'datetime': this.iso8601 (timestamp), 'symbol': symbol, 'id': id, 'order': undefined, 'type': undefined, 'takerOrMaker': undefined, 'side': side, 'price': price, 'amount': amount, 'cost': cost, 'fee': undefined, }; } async fetchTrades (symbol, since = undefined, limit = undefined, params = {}) { 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'] = parseInt (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 fetchBalance (params = {}) { 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" }, // }, // ] // } // 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.parseBalance (result, false); } 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.safeNumber (order, 'price'); const amount = this.safeNumber (order, 'initial_amount'); const filled = this.safeNumber (order, 'processed_amount'); let remaining = undefined; let cost = undefined; if (filled !== undefined) { if (amount !== undefined) { remaining = amount - filled; if (this.options['parseOrderToPrecision']) { remaining = parseFloat (this.amountToPrecision (symbol, remaining)); } remaining = Math.max (remaining, 0.0); } if (price !== undefined) { if (cost === undefined) { cost = price * filled; } } } let type = this.safeString (order, 'original_type'); if ((type === 'BUY') || (type === 'SELL')) { type = undefined; } const side = this.safeStringLower (order, 'type'); const rawTrades = this.safeValue (order, 'trades'); let trades = undefined; if (rawTrades !== undefined) { trades = this.parseTrades (rawTrades, market, undefined, undefined, { 'symbol': symbol, 'order': id, }); } const stopPrice = this.safeNumber (order, 'trigger_price'); const result = { 'info': order, 'id': id, 'clientOrderId': undefined, 'timestamp': timestamp, 'datetime': this.iso8601 (timestamp), 'lastTradeTimestamp': undefined, 'symbol': symbol, 'type': type, 'timeInForce': undefined, 'postOnly': undefined, 'side': side, 'price': price, 'stopPrice': stopPrice, 'amount': amount, 'cost': cost, 'average': undefined, 'filled': filled, 'remaining': remaining, 'status': status, 'trades': trades, }; const fees = this.safeValue (order, 'fees'); if (fees === undefined) { result['fee'] = undefined; } else { const numFees = fees.length; if (numFees > 0) { result['fees'] = []; for (let i = 0; i < fees.length; i++) { const feeCost = this.safeNumber (fees[i], 'amount'); if (feeCost !== undefined) { const feeCurrencyId = this.safeString (fees[i], 'currency_id'); const feeCurrencyCode = this.safeCurrencyCode (feeCurrencyId); result['fees'].push ({ 'cost': feeCost, 'currency': feeCurrencyCode, }); } } } else { result['fee'] = undefined; } } return result; } async createOrder (symbol, type, side, amount, price = undefined, params = {}) { if (type === 'market') { throw new ExchangeError (this.id + ' createOrder allows limit orders only'); } await this.loadMarkets (); const market = this.market (symbol); if (type === 'limit') { type = side; } const request = { 'currencyPairId': market['id'], 'type': type.toUpperCase (), // 'BUY', 'SELL', 'STOP_LIMIT_BUY', 'STOP_LIMIT_SELL' 'amount': parseFloat (this.amountToPrecision (symbol, amount)), // required 'price': parseFloat (this.priceToPrecision (symbol, price)), // required // 'trigger_price': 123.45 // required for STOP_LIMIT_BUY or STOP_LIMIT_SELL }; const response = await this.tradingPostOrdersCurrencyPairId (this.extend (request, params)); // // { // "success": true, // "data": { // "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", // "type": "SELL", // "original_type": "STOP_LIMIT_SELL", // "created": "2019-01-17 10:14:48", // "timestamp": "1547720088", // "status": "PARTIAL" // } // } // const data = this.safeValue (response, 'data', {}); return this.parseOrder (data, market); } async fetchOrder (id, symbol = undefined, params = {}) { await this.loadMarkets (); const request = { 'orderId': id, }; const response = await this.tradingGetOrderOrderId (this.extend (request, params)); // // { // "success": true, // "data": { // "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", // "type": "SELL", // "original_type": "STOP_LIMIT_SELL", // "created": "2019-01-17 10:14:48", // "timestamp": "1547720088", // "status": "PARTIAL" // } // } // const data = this.safeValue (response, 'data', {}); let market = undefined; if (symbol !== undefined) { market = this.market (symbol); } return this.parseOrder (data, market); } async fetchClosedOrder (id, symbol = undefined, params = {}) { await this.loadMarkets (); const request = { 'orderId': id, }; const response = await this.reportsGetOrdersOrderId (this.extend (request, params)); // // { // "success": true, // "data": { // "id": 5478965, // "currency_pair_id": 1, // "currency_pair_name": "NXT_BTC", // "price": "0.00013800", // "initial_amount": "1.00000000", // "type": "BUY", // "created": "2019-01-22 09:27:17", // "timestamp": 1548149237, // "status": "FINISHED", // "trades": [ // { // "id": 658745, // "buy_order_id": 6587453, // "sell_order_id": 6587459, // "price": 0.012285, // "amount": 6.35, // "trade_type": "SELL", // "timestamp": "1538737692" // } // ], // "fees": [ // { // "id": 1234567, // "currency_id": 1, // "amount": 0.00025, // "timestamp": "1548149238" // } // ] // } // } // const data = this.safeValue (response, 'data', {}); let market = undefined; if (symbol !== undefined) { market = this.market (symbol); } return this.parseOrder (data, market); } async fetchOrderTrades (id, symbol = undefined, since = undefined, limit = undefined, params = {}) { const order = await this.fetchClosedOrder (id, symbol, params); return order['trades']; } async fetchOpenOrders (symbol = undefined, since = undefined, limit = undefined, params = {}) { await this.loadMarkets (); let market = undefined; let method = 'tradingGetOrders'; const request = { // 'limit': 100, // default 100 // 'offset': 100, }; if (symbol !== undefined) { method = 'tradingGetOrdersCurrencyPairId'; market = this.market (symbol); request['currencyPairId'] = market['id']; } if (limit !== undefined) { request['limit'] = limit; } const response = await this[method] (this.extend (request, params)); // // { // "success": true, // "data": [ // { // "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", // "type": "SELL", // "original_type": "STOP_LIMIT_SELL", // "created": "2019-01-17 10:14:48", // "timestamp": "1547720088", // "status": "PARTIAL" // } // ] // } // const data = this.safeValue (response, 'data', []); return this.parseOrders (data, market, since, limit); } async cancelOrder (id, symbol = undefined, params = {}) { await this.loadMarkets (); const request = { 'orderId': id, }; const response = await this.tradingDeleteOrderOrderId (this.extend (request, params)); // // { // "success": true, // "data": { // "put_into_processing_queue": [ // { // "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", // "type": "SELL", // "original_type": "STOP_LIMIT_SELL", // "created": "2019-01-17 10:14:48", // "timestamp": "1547720088", // "status": "PARTIAL" // } // ], // "not_put_into_processing_queue": [ // { // "id": 828680