UNPKG

consequunturatque

Version:

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

1,147 lines (1,128 loc) 77.2 kB
'use strict'; // ---------------------------------------------------------------------------- const Exchange = require ('./base/Exchange'); const { ArgumentsRequired, AuthenticationError, ExchangeError, ExchangeNotAvailable, OrderNotFound, InvalidOrder, CancelPending, RateLimitExceeded, InsufficientFunds, BadRequest, BadSymbol, PermissionDenied } = require ('./base/errors'); const { TICK_SIZE } = require ('./base/functions/number'); const Precise = require ('./base/Precise'); // ---------------------------------------------------------------------------- module.exports = class aax extends Exchange { describe () { return this.deepExtend (super.describe (), { 'id': 'aax', 'name': 'AAX', 'countries': [ 'MT' ], // Malta 'enableRateLimit': true, 'rateLimit': 500, 'version': 'v2', 'hostname': 'aaxpro.com', // aax.com 'certified': true, 'has': { 'cancelAllOrders': true, 'cancelOrder': true, 'createOrder': true, 'editOrder': true, 'fetchBalance': true, 'fetchCanceledOrders': true, 'fetchClosedOrders': true, 'fetchDepositAddress': true, 'fetchMarkets': true, 'fetchMyTrades': true, 'fetchOHLCV': true, 'fetchOpenOrders': true, 'fetchOrder': true, 'fetchOrderBook': true, 'fetchOrders': true, 'fetchStatus': true, 'fetchTicker': 'emulated', 'fetchTickers': true, 'fetchTrades': true, }, 'timeframes': { '1m': '1m', '5m': '5m', '15m': '15m', '30m': '30m', '1h': '1h', '2h': '2h', '4h': '4h', '12h': '12h', '1d': '1d', '3d': '3d', '1w': '1w', }, 'urls': { 'logo': 'https://user-images.githubusercontent.com/1294454/104140087-a27f2580-53c0-11eb-87c1-5d9e81208fe9.jpg', 'test': { 'v1': 'https://api.testnet.{hostname}/marketdata/v1', 'public': 'https://api.testnet.{hostname}', 'private': 'https://api.testnet.{hostname}', }, 'api': { 'v1': 'https://api.{hostname}/marketdata/v1', 'public': 'https://api.{hostname}', 'private': 'https://api.{hostname}', }, 'www': 'https://www.aaxpro.com', // string website URL 'doc': 'https://www.aaxpro.com/apidoc/index.html', 'fees': 'https://www.aaxpro.com/en-US/fees/', 'referral': 'https://www.aaxpro.com/invite/sign-up?inviteCode=JXGm5Fy7R2MB', }, 'api': { 'v1': { 'get': [ 'getHistMarketData', // Get OHLC k line of specific market ], }, 'public': { // these endpoints are not documented // 'get': [ // 'order_book', // Get the order book of specified market // 'order_book/{market}', // 'trades', // Get recent trades on market, each trade is included only once Trades are sorted in reverse creation order. // 'trades/{market}', // 'tickers', // Get ticker of all markets // 'tickers/{market}', // Get ticker of specific market // ], 'get': [ 'announcement/maintenance', // System Maintenance Notice 'instruments', // Retrieve all trading pairs information 'market/orderbook', // Order Book 'futures/position/openInterest', // Open Interest 'market/tickers', // Get the Last 24h Market Summary 'market/candles', // Get Current Candlestick 'market/history/candles', // Get Current Candlestick 'market/trades', // Get the Most Recent Trades 'market/markPrice', // Get Current Mark Price 'futures/funding/predictedFunding/{symbol}', // Get Predicted Funding Rate 'futures/funding/prevFundingRate/{symbol}', // Get Last Funding Rate 'market/candles/index', // Get Current Index Candlestick ], }, 'private': { 'get': [ 'user/info', // Retrieve user information 'account/balances', // Get Account Balances 'account/deposit/address', // undocumented 'spot/trades', // Retrieve trades details for a spot order 'spot/openOrders', // Retrieve spot open orders 'spot/orders', // Retrieve historical spot orders 'futures/position', // Get positions for all contracts 'futures/position/closed', // Get closed positions 'futures/trades', // Retrieve trade details for a futures order 'futures/openOrders', // Retrieve futures open orders 'futures/orders', // Retrieve historical futures orders 'futures/funding/predictedFundingFee/{symbol}', // Get predicted funding fee ], 'post': [ 'account/transfer', // Asset Transfer 'spot/orders', // Create a new spot order 'spot/orders/cancelAllOnTimeout', // Automatically cancel all your spot orders after a specified timeout. 'futures/orders', // Create a new futures order 'futures/orders/cancelAllOnTimeout', // Automatically cancel all your futures orders after a specified timeout. 'futures/position/sltp', // Set take profit and stop loss orders for an opening position 'futures/position/close', // Close position 'futures/position/leverage', // Update leverage for position 'futures/position/margin', // Modify Isolated Position Margin ], 'put': [ 'spot/orders', // Amend spot order 'futures/orders', // Amend the quantity of an open futures order ], 'delete': [ 'spot/orders/cancel/{orderID}', // Cancel a spot order 'spot/orders/cancel/all', // Batch cancel spot orders 'futures/orders/cancel/{orderID}', // Cancel a futures order 'futures/orders/cancel/all', // Batch cancel futures orders ], }, }, 'fees': { 'trading': { 'tierBased': false, 'percentage': true, 'maker': 0.06 / 100, 'taker': 0.10 / 100, }, 'funding': { 'tierBased': false, 'percentage': true, 'withdraw': {}, // There is only 1% fee on withdrawals to your bank account. }, }, 'commonCurrencies': { 'XBT': 'XBT', }, 'exceptions': { 'exact': { '2002': InsufficientFunds, '2003': OrderNotFound, '10003': BadRequest, // Parameter validation error '10006': AuthenticationError, // Session expired, please relogin '10007': AuthenticationError, // Invalid authentication key or token '11007': AuthenticationError, // Invalid key format '20001': InsufficientFunds, // Insufficient balance. Please deposit to trade. '20009': InvalidOrder, // Order amount must be positive '30000': OrderNotFound, // {"code":30000,"data":null,"message":"The order does not exist","ts":1610259732263} '30001': InvalidOrder, // The order is being submitted, please try again later '30004': InvalidOrder, // Minimum quantity is {0} '30005': InvalidOrder, // Quantity maximum precision is {0} decimal places '30006': InvalidOrder, // Price maximum precision is {0} decimal places '30007': InvalidOrder, // Minimum price is {0} '30008': InvalidOrder, // Stop price maximum precision is {0} decimal places '30009': InvalidOrder, // Stop Price cannot be less than {0} '30010': InvalidOrder, // Market price cannot be empty '30011': CancelPending, // The order is being cancelled, please wait. '30012': BadRequest, // Unknown currency '30013': BadSymbol, // Unknown symbol '30014': OrderNotFound, // Futures order cannot be found '30015': InvalidOrder, // This is not an open order and cannot modified '30016': ExchangeError, // No position found '30017': InvalidOrder, // The current close position is 0. It is recommended that you cancel the current order closing order. '30018': InvalidOrder, // Order price cannot be greater than {0} '30019': InvalidOrder, // Order quantity cannot be greater than {0} '30020': InvalidOrder, // Order price must be a multiple of {0} '30021': InvalidOrder, // Margin adjustement must be greater than 0 '30022': InvalidOrder, // New quantity must be greater than filled quantity '30023': InvalidOrder, // Order failed, please try again '30024': InvalidOrder, // TimeInForce error, only GTC or IOC are allowed '30025': InvalidOrder, // TimeInForce error, only GTC is allowed '30026': InvalidOrder, // Quantity is not a multiple of {0} '30027': InvalidOrder, // Close position failed, it is recommended that you cancel the current order and then close the position. '30028': BadSymbol, // Symbol cannot be traded at this time '30029': InvalidOrder, // Modified quantity or price cannot be empty '30030': InvalidOrder, // Price cannot be specified for market orders '30031': InvalidOrder, // Liquidation orders cannot be modified '30032': InvalidOrder, // Leverage cannot be greater than {0} '30033': InvalidOrder, // Leverage cannot be smaller than {0} '30034': RateLimitExceeded, // The max number of open orders is {0}. To place a new order, please cancel a previous one '30035': RateLimitExceeded, // The max number of {0} open orders is {1}. To place a new order, please cancel a previous one '30036': ExchangeNotAvailable, // Liquidation is in progress, please try again later '30037': InvalidOrder, // Once stop limit order triggered, stop price cannot be amended '30038': ExchangeError, // The total value of your orders has exceeded the current risk limit. Please adjust the risk limit '30039': InsufficientFunds, // Your risk limit has now been changed to {0}, your maximum leverage less than 1, please readjust accordingly '30040': InvalidOrder, // Order status has changed, please try again later '30041': InvalidOrder, // Liquidation orders cannot be cancelled '30042': InvalidOrder, // Order cannot be placed as you will be breaching you max limit value of {1} BTC for {0} '30043': InvalidOrder, // The risk limit cannot be less than 0 '30044': BadRequest, // Timeout cannot be greater than 60 minutes '30045': InvalidOrder, // Side is not valid, it should be BUY or SELL '30046': InvalidOrder, // Order type is not valid, it should be MARKET or LIMIT or STOP-LIMIT or STOP '30047': InvalidOrder, // The order is closed. Can't cancel '30048': InvalidOrder, // Market orders cannot be modified '30049': InvalidOrder, // The order is being modified, please wait '30050': InvalidOrder, // Maximum 10 orders '40004': BadRequest, // Requested resource doesn't exist '40009': RateLimitExceeded, // Too many requests '40102': AuthenticationError, // {"code":40102,"message":"Unauthorized(invalid key)"} '40103': AuthenticationError, // {"code":40103,"message":"Unauthorized(invalid sign)"} '40303': PermissionDenied, // {"code":40303,"message":"Forbidden(invalid scopes)"} '41001': BadRequest, // Incorrect HTTP request '41002': BadRequest, // Unsupported HTTP request method '42001': ExchangeNotAvailable, // Duplicated data entry, please check and try again '50001': ExchangeError, // Server side exception, please try again later '50002': ExchangeError, // Server is busy, please try again later }, 'broad': {}, }, 'precisionMode': TICK_SIZE, 'options': { 'defaultType': 'spot', // 'spot', 'future' }, }); } async fetchStatus (params = {}) { const response = await this.publicGetAnnouncementMaintenance (params); // // { // "code": 1, // "data": { // "startTime":"2020-06-25T02:15:00.000Z", // "endTime":"2020-06-25T02:45:00.000Z", // "description":"Spot Trading :UTC Jun 25, 2020 02:15 to 02:45 (HKT Jun 25 10:15 to 10:45),Futures Trading: UTC Jun 25, 2020 02:15 to 02:45 (HKT Jun 25 10:15 to 10:45).We apologize for any inconvenience caused. Thank you for your patience and understanding.Should you have any enquiries, please do not hesitate our live chat support or via email at cs@aax.com." // }, // "message":"success", // "ts":1593043237000 // } // const data = this.safeValue (response, 'data', {}); const timestamp = this.milliseconds (); const startTime = this.parse8601 (this.safeString (data, 'startTime')); const endTime = this.parse8601 (this.safeString (data, 'endTime')); const update = { 'updated': this.safeInteger (response, 'ts', timestamp), }; if (endTime !== undefined) { const startTimeIsOk = (startTime === undefined) ? true : (timestamp < startTime); const isOk = (timestamp > endTime) || startTimeIsOk; update['eta'] = endTime; update['status'] = isOk ? 'ok' : 'maintenance'; } this.status = this.extend (this.status, update); return this.status; } async fetchMarkets (params = {}) { const response = await this.publicGetInstruments (params); // // { // "code":1, // "message":"success", // "ts":1610159448962, // "data":[ // { // "tickSize":"0.01", // "lotSize":"1", // "base":"BTC", // "quote":"USDT", // "minQuantity":"1.0000000000", // "maxQuantity":"30000", // "minPrice":"0.0100000000", // "maxPrice":"999999.0000000000", // "status":"readOnly", // "symbol":"BTCUSDTFP", // "code":"FP", // "takerFee":"0.00040", // "makerFee":"0.00020", // "multiplier":"0.001000000000", // "mmRate":"0.00500", // "imRate":"0.01000", // "type":"futures", // "settleType":"Vanilla", // "settleCurrency":"USDT" // }, // { // "tickSize":"0.5", // "lotSize":"10", // "base":"BTC", // "quote":"USD", // "minQuantity":"10.0000000000", // "maxQuantity":"300000", // "minPrice":"0.5000000000", // "maxPrice":"999999.0000000000", // "status":"readOnly", // "symbol":"BTCUSDFP", // "code":"FP", // "takerFee":"0.00040", // "makerFee":"0.00020", // "multiplier":"1.000000000000", // "mmRate":"0.00500", // "imRate":"0.01000", // "type":"futures", // "settleType":"Inverse", // "settleCurrency":"BTC" // }, // { // "tickSize":"0.0001", // "lotSize":"0.01", // "base":"AAB", // "quote":"USDT", // "minQuantity":"5.0000000000", // "maxQuantity":"50000.0000000000", // "minPrice":"0.0001000000", // "maxPrice":"999999.0000000000", // "status":"readOnly", // "symbol":"AABUSDT", // "code":null, // "takerFee":"0.00100", // "makerFee":"0.00100", // "multiplier":"1.000000000000", // "mmRate":"0.02500", // "imRate":"0.05000", // "type":"spot", // "settleType":null, // "settleCurrency":null // }, // ] // } // const data = this.safeValue (response, 'data'); const result = []; for (let i = 0; i < data.length; i++) { const market = data[i]; const id = this.safeString (market, 'symbol'); const baseId = this.safeString (market, 'base'); const quoteId = this.safeString (market, 'quote'); const base = this.safeCurrencyCode (baseId); const quote = this.safeCurrencyCode (quoteId); const status = this.safeString (market, 'status'); const active = (status === 'enable'); const taker = this.safeNumber (market, 'takerFee'); const maker = this.safeNumber (market, 'makerFee'); const type = this.safeString (market, 'type'); let inverse = undefined; let linear = undefined; let quanto = undefined; const spot = (type === 'spot'); const futures = (type === 'futures'); const settleType = this.safeStringLower (market, 'settleType'); if (settleType !== undefined) { inverse = (settleType === 'inverse'); linear = (settleType === 'vanilla'); quanto = (settleType === 'quanto'); } let symbol = id; if (type === 'spot') { symbol = base + '/' + quote; } const precision = { 'amount': this.safeNumber (market, 'lotSize'), 'price': this.safeNumber (market, 'tickSize'), }; result.push ({ 'id': id, 'symbol': symbol, 'base': base, 'quote': quote, 'baseId': baseId, 'quoteId': quoteId, 'type': type, 'spot': spot, 'futures': futures, 'inverse': inverse, 'linear': linear, 'quanto': quanto, 'precision': precision, 'info': market, 'active': active, 'taker': taker, 'maker': maker, 'percentage': false, 'tierBased': true, 'limits': { 'amount': { 'min': this.safeString (market, 'minQuantity'), 'max': this.safeString (market, 'maxQuantity'), }, 'price': { 'min': this.safeString (market, 'minPrice'), 'max': this.safeString (market, 'maxPrice'), }, 'cost': { 'min': undefined, 'max': undefined, }, }, }); } return result; } parseTicker (ticker, market = undefined) { // // { // "t":1610162685342, // timestamp // "a":"0.00000000", // trading volume in USD in the last 24 hours, futures only // "c":"435.20000000", // close // "d":"4.22953489", // change // "h":"455.04000000", // high // "l":"412.78000000", // low // "o":"417.54000000", // open // "s":"BCHUSDTFP", // market id // "v":"2031068.00000000", // trading volume in quote currency of last 24 hours // } // const timestamp = this.safeInteger (ticker, 't'); const marketId = this.safeString (ticker, 's'); const symbol = this.safeSymbol (marketId, market); const last = this.safeNumber (ticker, 'c'); const open = this.safeNumber (ticker, 'o'); let change = undefined; let percentage = undefined; let average = undefined; if (last !== undefined && open !== undefined) { change = last - open; if (open > 0) { percentage = change / open * 100; } average = this.sum (last, open) / 2; } const quoteVolume = this.safeNumber (ticker, 'v'); return { 'symbol': symbol, 'timestamp': timestamp, 'datetime': this.iso8601 (timestamp), 'high': this.safeNumber (ticker, 'h'), 'low': this.safeNumber (ticker, 'l'), 'bid': undefined, 'bidVolume': undefined, 'ask': undefined, 'askVolume': undefined, 'vwap': undefined, 'open': open, 'close': last, 'last': last, 'previousClose': undefined, 'change': change, 'percentage': percentage, 'average': average, 'baseVolume': undefined, 'quoteVolume': quoteVolume, 'info': ticker, }; } async fetchTicker (symbol, params = {}) { const tickers = await this.fetchTickers (undefined, params); if (symbol in tickers) { return tickers[symbol]; } throw new BadSymbol (this.id + ' fetchTicker() symbol ' + symbol + ' ticker not found'); } async fetchTickers (symbols = undefined, params = {}) { await this.loadMarkets (); const response = await this.publicGetMarketTickers (params); // // { // "e":"tickers", // "t":1610162685342, // "tickers":[ // { // "a":"0.00000000", // "c":"435.20000000", // "d":"4.22953489", // "h":"455.04000000", // "l":"412.78000000", // "o":"417.54000000", // "s":"BCHUSDTFP", // "v":"2031068.00000000", // }, // ], // } // const tickers = this.safeValue (response, 'tickers', []); const result = []; const timestamp = this.safeInteger (response, 't'); for (let i = 0; i < tickers.length; i++) { const ticker = this.parseTicker (this.extend (tickers[i], { 't': timestamp })); result.push (ticker); } return this.filterByArray (result, 'symbol', symbols); } async fetchOrderBook (symbol, limit = undefined, params = {}) { await this.loadMarkets (); const market = this.market (symbol); if (limit === undefined) { limit = 20; } else { if ((limit !== 20) && (limit !== 50)) { throw new BadRequest (this.id + ' fetchOrderBook() limit argument must be undefined, 20 or 50'); } } const request = { 'symbol': market['id'], 'level': limit, // required }; // const response = await this.publicGetMarketOrderbook (this.extend (request, params)); // // { // "asks":[ // ["10823.00000000","0.004000"], // ["10823.10000000","0.100000"], // ["10823.20000000","0.010000"] // ], // "bids":[ // ["10821.20000000","0.002000"], // ["10821.10000000","0.005000"], // ["10820.40000000","0.013000"] // ], // "e":"BTCUSDT@book_50", // "t":1561543614756 // } // const timestamp = this.safeInteger (response, 't'); // need unix type return this.parseOrderBook (response, symbol, timestamp); } parseTrade (trade, market = undefined) { // // public fetchTrades // // { // "p":"9395.50000000", // "q":"50.000000", // "t":1592563996718 // } // // private fetchMyTrades // // { // "avgPrice":"1199.8", // "base":"ETH", // "clOrdID":null, // "commission":"0.00002", // "createTime":"2021-01-11T02:47:51.512Z", // "cumQty":"0.02", // "filledOrderID":"1eUD4F5rwK", // "filledPrice":"1199.8", // "filledQty":"0.02", // "leavesQty":"0", // "oCreateTime":"2021-01-11T02:47:51.377Z", // "orderID":"1eUD4EHfdU", // "orderQty":"0.02", // "orderStatus":3, // "orderType":1, // "price":"1198.25", // "quote":"USDT", // "rejectCode":null, // "rejectReason":null, // "side":1, // "stopPrice":"0", // "symbol":"ETHUSDT", // "taker":true, // "tradeID":"E04WTIgfmULU", // "transactTime":"2021-01-11T02:47:51.389Z", // "updateTime":null, // "userID":"1362494" // } // let timestamp = this.safeInteger (trade, 't'); if (timestamp === undefined) { timestamp = this.parse8601 (this.safeString (trade, 'createTime')); } const id = this.safeString2 (trade, 'tid', 'tradeID'); let symbol = undefined; const marketId = this.safeString (trade, 'symbol'); market = this.safeMarket (marketId, market); if (market !== undefined) { symbol = market['symbol']; } let priceString = this.safeString2 (trade, 'p', 'filledPrice'); const amountString = this.safeString2 (trade, 'q', 'filledQty'); const orderId = this.safeString (trade, 'orderID'); const isTaker = this.safeValue (trade, 'taker'); let takerOrMaker = undefined; if (isTaker !== undefined) { takerOrMaker = isTaker ? 'taker' : 'maker'; } let side = this.safeString (trade, 'side'); if (side === '1') { side = 'buy'; } else if (side === '2') { side = 'sell'; } if (side === undefined) { side = (priceString[0] === '-') ? 'sell' : 'buy'; } priceString = Precise.stringAbs (priceString); const price = this.parseNumber (priceString); const amount = this.parseNumber (amountString); const cost = this.parseNumber (Precise.stringMul (priceString, amountString)); const orderType = this.parseOrderType (this.safeString (trade, 'orderType')); let fee = undefined; const feeCost = this.safeNumber (trade, 'commission'); if (feeCost !== undefined) { let feeCurrency = undefined; if (market !== undefined) { if (side === 'buy') { feeCurrency = market['base']; } else if (side === 'sell') { feeCurrency = market['quote']; } } fee = { 'currency': feeCurrency, 'cost': feeCost, }; } return { 'info': trade, 'id': id, 'timestamp': timestamp, 'datetime': this.iso8601 (timestamp), 'symbol': symbol, 'type': orderType, 'side': side, 'order': orderId, 'takerOrMaker': takerOrMaker, 'price': price, 'amount': amount, 'cost': cost, 'fee': fee, }; } async fetchTrades (symbol, since = undefined, limit = undefined, params = {}) { await this.loadMarkets (); const market = this.market (symbol); limit = (limit === undefined) ? 2000 : limit; limit = Math.min (limit, 2000); const request = { 'symbol': market['id'], 'limit': limit, }; const response = await this.publicGetMarketTrades (request); // // { // "e":"BTCUSDFP@trades", // "trades": [ // {"p":"9395.50000000","q":"50.000000","t":1592563996718}, // {"p":"9395.50000000","q":"50.000000","t":1592563993577}, // ], // } // const trades = this.safeValue (response, 'trades', []); return this.parseTrades (trades, market, since, limit); } parseOHLCV (ohlcv, market = undefined) { // // [ // 0.042398, // 0 open // 0.042684, // 1 high // 0.042366, // 2 low // 0.042386, // 3 close // 0.93734243, // 4 volume // 1611514800, // 5 timestamp // ] // return [ this.safeTimestamp (ohlcv, 5), this.safeNumber (ohlcv, 0), this.safeNumber (ohlcv, 1), this.safeNumber (ohlcv, 2), this.safeNumber (ohlcv, 3), this.safeNumber (ohlcv, 4), ]; } async fetchOHLCV (symbol, timeframe = '1h', since = undefined, limit = undefined, params = {}) { await this.loadMarkets (); const market = this.market (symbol); const request = { // 'limit': limit, // if set counts from now into the past 'symbol': market['id'], 'timeFrame': this.timeframes[timeframe], }; limit = (limit === undefined) ? 500 : limit; const duration = this.parseTimeframe (timeframe); if (since === undefined) { const end = this.seconds (); request['start'] = end - duration * limit; request['end'] = end; } else { const start = parseInt (since / 1000); request['start'] = start; request['end'] = this.sum (start, duration * limit); } const response = await this.publicGetMarketHistoryCandles (this.extend (request, params)); // // { // "data":[ // [0.042398,0.042684,0.042366,0.042386,0.93734243,1611514800], // [0.042386,0.042602,0.042234,0.042373,1.01925239,1611518400], // [0.042373,0.042558,0.042362,0.042389,0.93801705,1611522000], // ], // "success":true, // "t":1611875157 // } // const data = this.safeValue (response, 'data', []); return this.parseOHLCVs (data, market, timeframe, since, limit); } async fetchBalance (params = {}) { await this.loadMarkets (); const defaultType = this.safeString2 (this.options, 'fetchBalance', 'defaultType', 'spot'); const type = this.safeString (params, 'type', defaultType); const types = { 'spot': 'SPTP', 'future': 'FUTP', 'otc': 'F2CP', 'saving': 'VLTP', }; const purseType = this.safeString (types, type, type); const request = { 'purseType': purseType, }; params = this.omit (params, 'type'); const response = await this.privateGetAccountBalances (this.extend (request, params)); // // { // "code":1, // "data":[ // { // "purseType":"FUTP", // "currency":"BTC", // "available":"0.41000000", // "unavailable":"0.00000000" // }, // { // "purseType":"FUTP", // "currency":"USDT", // "available":"0.21000000", // "unvaliable":"0.00000000" // } // ] // "message":"success", // "ts":1573530401020 // } // const data = this.safeValue (response, 'data'); const timestamp = this.safeInteger (response, 'ts'); const result = { 'info': response, 'timestamp': timestamp, 'datetime': this.iso8601 (timestamp), }; for (let i = 0; i < data.length; i++) { const balance = data[i]; const balanceType = this.safeString (balance, 'purseType'); if (balanceType === purseType) { const currencyId = this.safeString (balance, 'currency'); const code = this.safeCurrencyCode (currencyId); const account = this.account (); account['free'] = this.safeString (balance, 'available'); account['used'] = this.safeString (balance, 'unavailable'); result[code] = account; } } return this.parseBalance (result, false); } async createOrder (symbol, type, side, amount, price = undefined, params = {}) { let orderType = type.toUpperCase (); const orderSide = side.toUpperCase (); await this.loadMarkets (); const market = this.market (symbol); const request = { // 'orderType': orderType, // MARKET, LIMIT, STOP, STOP-LIMIT 'symbol': market['id'], 'orderQty': this.amountToPrecision (symbol, amount), 'side': orderSide, // 'stopPrice': this.priceToPrecision (symbol, stopPrice), // 'clOrdID': clientOrderId, // up to 20 chars, lowercase and uppercase letters only // 'timeInForce': 'GTC', // GTC, IOC, FOK, default is GTC // 'execInst': 'Post-Only', // the only value supported by the exchange, futures-only }; const timeInForce = this.safeString (params, 'timeInForce'); if (timeInForce !== undefined) { request['timeInForce'] = timeInForce; params = this.omit (params, 'timeInForce'); } const clientOrderId = this.safeString2 (params, 'clOrdID', 'clientOrderId'); if (clientOrderId !== undefined) { request['clOrdID'] = clientOrderId; params = this.omit (params, [ 'clOrdID', 'clientOrderId' ]); } const stopPrice = this.safeNumber (params, 'stopPrice'); if (stopPrice === undefined) { if ((orderType === 'STOP-LIMIT') || (orderType === 'STOP')) { throw new ArgumentsRequired (this.id + ' createOrder() requires a stopPrice parameter for ' + orderType + ' orders'); } } else { if (orderType === 'LIMIT') { orderType = 'STOP-LIMIT'; } else if (orderType === 'MARKET') { orderType = 'STOP'; } request['stopPrice'] = this.priceToPrecision (symbol, stopPrice); params = this.omit (params, 'stopPrice'); } if (orderType === 'LIMIT' || orderType === 'STOP-LIMIT') { request['price'] = this.priceToPrecision (symbol, price); } request['orderType'] = orderType; let method = undefined; if (market['spot']) { method = 'privatePostSpotOrders'; } else if (market['futures']) { method = 'privatePostFuturesOrders'; } const response = await this[method] (this.extend (request, params)); // // spot // // { // "code":1, // "data":{ // "symbol":"ETHUSDT", // "orderType":2, // "avgPrice":"0", // "execInst":null, // "orderStatus":0, // "userID":"1362494", // "quote":"USDT", // "rejectReason":null, // "rejectCode":null, // "price":"1500", // "orderQty":"1", // "commission":"0", // "id":"268323430253735936", // "timeInForce":1, // "isTriggered":false, // "side":2, // "orderID":"1eO51MDSpQ", // "leavesQty":"0", // "cumQty":"0", // "updateTime":null, // "lastQty":"0", // "clOrdID":null, // "stopPrice":null, // "createTime":null, // "transactTime":null, // "base":"ETH", // "lastPrice":"0" // }, // "message":"success", // "ts":1610245290980 // } // // futures // // { // "code":1, // "data":{ // "liqType":0, // "symbol":"ETHUSDTFP", // "orderType":2, // "leverage":"1", // "marketPrice":"1318.3150000000", // "code":"FP", // "avgPrice":"0", // "execInst":null, // "orderStatus":0, // "userID":"1362494", // "quote":"USDT", // "rejectReason":null, // "rejectCode":null, // "price":"500", // "orderQty":"1", // "commission":"0", // "id":"268346885133053953", // "timeInForce":1, // "isTriggered":false, // "side":1, // "orderID":"1eOuPUAAkq", // "leavesQty":"1", // "cumQty":"0", // "updateTime":null, // "lastQty":null, // "clOrdID":null, // "stopPrice":null, // "createTime":null, // "transactTime":null, // "settleType":"VANILLA", // "base":"ETH", // "lastPrice":"0" // }, // "message":"success", // "ts":1610250883059 // } // const data = this.safeValue (response, 'data', {}); return this.parseOrder (data, market); } async editOrder (id, symbol, type, side, amount, price = undefined, params = {}) { await this.loadMarkets (); const market = this.market (symbol); const request = { 'orderID': id, // 'orderQty': this.amountToPrecision (symbol, amount), // 'price': this.priceToPrecision (symbol, price), // 'stopPrice': this.priceToPrecision (symbol, stopPrice), }; const stopPrice = this.safeNumber (params, 'stopPrice'); if (stopPrice !== undefined) { request['stopPrice'] = this.priceToPrecision (symbol, stopPrice); params = this.omit (params, 'stopPrice'); } if (price !== undefined) { request['price'] = this.priceToPrecision (symbol, price); } if (amount !== undefined) { request['orderQty'] = this.amountToPrecision (symbol, amount); } let method = undefined; if (market['spot']) { method = 'privatePutSpotOrders'; } else if (market['futures']) { method = 'privatePutFuturesOrders'; } const response = await this[method] (this.extend (request, params)); // // spot // // { // "code":1, // "data":{ // "symbol":"ETHUSDT", // "orderType":2, // "avgPrice":"0", // "execInst":null, // "orderStatus":0, // "userID":"1362494", // "quote":"USDT", // "rejectReason":null, // "rejectCode":null, // "price":"1500", // "orderQty":"1", // "commission":"0", // "id":"268323430253735936", // "timeInForce":1, // "isTriggered":false, // "side":2, // "orderID":"1eO51MDSpQ", // "leavesQty":"0", // "cumQty":"0", // "updateTime":null, // "lastQty":"0", // "clOrdID":null, // "stopPrice":null, // "createTime":null, // "transactTime":null, // "base":"ETH", // "lastPrice":"0" // }, // "message":"success", // "ts":1610245290980 // } // // futures // // { // "code":1, // "data":{ // "liqType":0, // "symbol":"ETHUSDTFP", // "orderType":2, // "leverage":"1", // "marketPrice":"1318.3150000000", // "code":"FP", // "avgPrice":"0", // "execInst":null, // "orderStatus":0, // "userID":"1362494", // "quote":"USDT", // "rejectReason":null, // "rejectCode":null, // "price":"500", // "orderQty":"1", // "commission":"0", // "id":"268346885133053953", // "timeInForce":1, // "isTriggered":false, // "side":1, // "orderID":"1eOuPUAAkq", // "leavesQty":"1", // "cumQty":"0", // "updateTime":null, // "lastQty":null, // "clOrdID":null, // "stopPrice":null, // "createTime":null, // "transactTime":null, // "settleType":"VANILLA", // "base":"ETH", // "lastPrice":"0" // }, // "message":"success", // "ts":1610250883059 // } // const data = this.safeValue (response, 'data', {}); return this.parseOrder (data, market); } async cancelOrder (id, symbol = undefined, params = {}) { await this.loadMarkets (); const request = { 'orderID': id, }; let method = undefined; const defaultType = this.safeString2 (this.options, 'cancelOrder', 'defaultType', 'spot'); let type = this.safeString (params, 'type', defaultType); params = this.omit (params, 'type'); let market = undefined; if (symbol !== undefined) { market = this.market (symbol); type = market['type']; } if (type === 'spot') { method = 'privateDeleteSpotOrdersCancelOrderID'; } else if (type === 'futures') { method = 'privateDeleteFuturesOrdersCancelOrderID'; } const response = await this[method] (this.extend (request, params)); // // spot // // { // "code":1, // "data":{ // "avgPrice":"0", // "base":"BTC", // "clOrdID":"aax", // "commission":"0", // "createTime":"2019-11-12T03:46:41Z", // "cumQty":"0", // "id":"114330021504606208", // "isTriggered":false, // "lastPrice":"0", // "lastQty":"0", // "leavesQty":"0", // "orderID":"wJ4L366KB", // "orderQty":"0.05", // "orderStatus":1, // "orderType":2, // "price":"8000", // "quote":"USDT", // "rejectCode":0, // "rejectReason":null, // "side":1, // "stopPrice":"0", // "symbol":"BTCUSDT", // "transactTime":null, // "updateTime":"2019-11-12T03:46:41Z", // "timeInForce":1, // "userID":"216214" // }, // "message":"success", // "ts":1573530402029 // } // // futures // // { // "code":1, // "data":{ // "avgPrice":"0", // "base":"BTC", // "clOrdID":"aax_futures", // "code":"FP", // "commission":"0", // "createTime":"2019-11-12T06:48:58Z", // "cumQty":"0", // "id":"114375893764395008", // "isTriggered":false, // "lastPrice":"0", // "lastQty":null, // "leavesQty":"300", // "leverage":"1", // "liqType":0, // "marketPrice":"8760.75", // "orderID":"wJTewQc81", // "orderQty":"300", // "orderStatus":1, // "orderType":2, // "price":"8000", // "quote":"USD", // "rejectCode":0, // "rejectReason":null, // "settleType":"INVERSE", // "side":1, // "stopPrice":"0", // "symbol":"BTCUSDFP", // "transactTime":"2019-11-12T06:48:58Z", // "updateTime":"2019-11-12T06:48:58Z", // "timeInForce":1, // "execInst": "", // "userID":"216214" // }, // "message":"success", // "ts":1573541642970 // } // const data = this.safeValue (response, 'data', {}); return this.parseOrder (data, market); } async cancelAllOrders (symbol = undefined, params = {}) { if (symbol === undefined) { throw new ArgumentsRequired (this.id + ' cancelAllOrders() requires a symbol argument'); } await this.loadMarkets (); const market = this.market (symbol); const request = { 'symbol': market['id'], }; let method