consequunturatque
Version:
A JavaScript / Python / PHP cryptocurrency trading library with support for 130+ exchanges
999 lines (963 loc) • 6.3 MB
JavaScript
(function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({1:[function(require,module,exports){
/* A entry point for the browser bundle version. This gets compiled by:
browserify --debug ./ccxt.browser.js > ./dist/ccxt.browser.js
*/
window.ccxt = require ('./ccxt')
},{"./ccxt":2}],2:[function(require,module,exports){
"use strict";
/*
MIT License
Copyright (c) 2017 Igor Kroitor
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/
//-----------------------------------------------------------------------------
const Exchange = require ('./js/base/Exchange')
, functions = require ('./js/base/functions')
, errors = require ('./js/base/errors')
//-----------------------------------------------------------------------------
// this is updated by vss.js when building
const version = '1.49.12'
Exchange.ccxtVersion = version
//-----------------------------------------------------------------------------
const exchanges = {
'aax': require ('./js/aax.js'),
'aofex': require ('./js/aofex.js'),
'ascendex': require ('./js/ascendex.js'),
'bequant': require ('./js/bequant.js'),
'bibox': require ('./js/bibox.js'),
'bigone': require ('./js/bigone.js'),
'binance': require ('./js/binance.js'),
'binanceus': require ('./js/binanceus.js'),
'bit2c': require ('./js/bit2c.js'),
'bitbank': require ('./js/bitbank.js'),
'bitbay': require ('./js/bitbay.js'),
'bitcoincom': require ('./js/bitcoincom.js'),
'bitfinex': require ('./js/bitfinex.js'),
'bitfinex2': require ('./js/bitfinex2.js'),
'bitflyer': require ('./js/bitflyer.js'),
'bitforex': require ('./js/bitforex.js'),
'bitget': require ('./js/bitget.js'),
'bithumb': require ('./js/bithumb.js'),
'bitkk': require ('./js/bitkk.js'),
'bitmart': require ('./js/bitmart.js'),
'bitmex': require ('./js/bitmex.js'),
'bitpanda': require ('./js/bitpanda.js'),
'bitso': require ('./js/bitso.js'),
'bitstamp': require ('./js/bitstamp.js'),
'bitstamp1': require ('./js/bitstamp1.js'),
'bittrex': require ('./js/bittrex.js'),
'bitvavo': require ('./js/bitvavo.js'),
'bitz': require ('./js/bitz.js'),
'bl3p': require ('./js/bl3p.js'),
'braziliex': require ('./js/braziliex.js'),
'btcalpha': require ('./js/btcalpha.js'),
'btcbox': require ('./js/btcbox.js'),
'btcmarkets': require ('./js/btcmarkets.js'),
'btctradeua': require ('./js/btctradeua.js'),
'btcturk': require ('./js/btcturk.js'),
'buda': require ('./js/buda.js'),
'bw': require ('./js/bw.js'),
'bybit': require ('./js/bybit.js'),
'bytetrade': require ('./js/bytetrade.js'),
'cdax': require ('./js/cdax.js'),
'cex': require ('./js/cex.js'),
'coinbase': require ('./js/coinbase.js'),
'coinbaseprime': require ('./js/coinbaseprime.js'),
'coinbasepro': require ('./js/coinbasepro.js'),
'coincheck': require ('./js/coincheck.js'),
'coinegg': require ('./js/coinegg.js'),
'coinex': require ('./js/coinex.js'),
'coinfalcon': require ('./js/coinfalcon.js'),
'coinfloor': require ('./js/coinfloor.js'),
'coingi': require ('./js/coingi.js'),
'coinmarketcap': require ('./js/coinmarketcap.js'),
'coinmate': require ('./js/coinmate.js'),
'coinone': require ('./js/coinone.js'),
'coinspot': require ('./js/coinspot.js'),
'crex24': require ('./js/crex24.js'),
'currencycom': require ('./js/currencycom.js'),
'delta': require ('./js/delta.js'),
'deribit': require ('./js/deribit.js'),
'digifinex': require ('./js/digifinex.js'),
'equos': require ('./js/equos.js'),
'eterbase': require ('./js/eterbase.js'),
'exmo': require ('./js/exmo.js'),
'exx': require ('./js/exx.js'),
'fcoin': require ('./js/fcoin.js'),
'fcoinjp': require ('./js/fcoinjp.js'),
'flowbtc': require ('./js/flowbtc.js'),
'foxbit': require ('./js/foxbit.js'),
'ftx': require ('./js/ftx.js'),
'gateio': require ('./js/gateio.js'),
'gemini': require ('./js/gemini.js'),
'gopax': require ('./js/gopax.js'),
'hbtc': require ('./js/hbtc.js'),
'hitbtc': require ('./js/hitbtc.js'),
'hollaex': require ('./js/hollaex.js'),
'huobijp': require ('./js/huobijp.js'),
'huobipro': require ('./js/huobipro.js'),
'idex': require ('./js/idex.js'),
'independentreserve': require ('./js/independentreserve.js'),
'indodax': require ('./js/indodax.js'),
'itbit': require ('./js/itbit.js'),
'kraken': require ('./js/kraken.js'),
'kucoin': require ('./js/kucoin.js'),
'kuna': require ('./js/kuna.js'),
'lakebtc': require ('./js/lakebtc.js'),
'latoken': require ('./js/latoken.js'),
'lbank': require ('./js/lbank.js'),
'liquid': require ('./js/liquid.js'),
'luno': require ('./js/luno.js'),
'lykke': require ('./js/lykke.js'),
'mercado': require ('./js/mercado.js'),
'mixcoins': require ('./js/mixcoins.js'),
'ndax': require ('./js/ndax.js'),
'novadax': require ('./js/novadax.js'),
'oceanex': require ('./js/oceanex.js'),
'okcoin': require ('./js/okcoin.js'),
'okex': require ('./js/okex.js'),
'paymium': require ('./js/paymium.js'),
'phemex': require ('./js/phemex.js'),
'poloniex': require ('./js/poloniex.js'),
'probit': require ('./js/probit.js'),
'qtrade': require ('./js/qtrade.js'),
'rightbtc': require ('./js/rightbtc.js'),
'ripio': require ('./js/ripio.js'),
'southxchange': require ('./js/southxchange.js'),
'stex': require ('./js/stex.js'),
'surbitcoin': require ('./js/surbitcoin.js'),
'therock': require ('./js/therock.js'),
'tidebit': require ('./js/tidebit.js'),
'tidex': require ('./js/tidex.js'),
'timex': require ('./js/timex.js'),
'upbit': require ('./js/upbit.js'),
'vbtc': require ('./js/vbtc.js'),
'vcc': require ('./js/vcc.js'),
'wavesexchange': require ('./js/wavesexchange.js'),
'whitebit': require ('./js/whitebit.js'),
'xbtce': require ('./js/xbtce.js'),
'xena': require ('./js/xena.js'),
'yobit': require ('./js/yobit.js'),
'zaif': require ('./js/zaif.js'),
'zb': require ('./js/zb.js'),
}
//-----------------------------------------------------------------------------
module.exports = Object.assign ({ version, Exchange, 'exchanges': Object.keys (exchanges) }, exchanges, functions, errors)
//-----------------------------------------------------------------------------
},{"./js/aax.js":3,"./js/aofex.js":4,"./js/ascendex.js":5,"./js/base/Exchange":6,"./js/base/errors":9,"./js/base/functions":10,"./js/bequant.js":21,"./js/bibox.js":22,"./js/bigone.js":23,"./js/binance.js":24,"./js/binanceus.js":25,"./js/bit2c.js":26,"./js/bitbank.js":27,"./js/bitbay.js":28,"./js/bitcoincom.js":29,"./js/bitfinex.js":30,"./js/bitfinex2.js":31,"./js/bitflyer.js":32,"./js/bitforex.js":33,"./js/bitget.js":34,"./js/bithumb.js":35,"./js/bitkk.js":36,"./js/bitmart.js":37,"./js/bitmex.js":38,"./js/bitpanda.js":39,"./js/bitso.js":40,"./js/bitstamp.js":41,"./js/bitstamp1.js":42,"./js/bittrex.js":43,"./js/bitvavo.js":44,"./js/bitz.js":45,"./js/bl3p.js":46,"./js/braziliex.js":47,"./js/btcalpha.js":48,"./js/btcbox.js":49,"./js/btcmarkets.js":50,"./js/btctradeua.js":51,"./js/btcturk.js":52,"./js/buda.js":53,"./js/bw.js":54,"./js/bybit.js":55,"./js/bytetrade.js":56,"./js/cdax.js":57,"./js/cex.js":58,"./js/coinbase.js":59,"./js/coinbaseprime.js":60,"./js/coinbasepro.js":61,"./js/coincheck.js":62,"./js/coinegg.js":63,"./js/coinex.js":64,"./js/coinfalcon.js":65,"./js/coinfloor.js":66,"./js/coingi.js":67,"./js/coinmarketcap.js":68,"./js/coinmate.js":69,"./js/coinone.js":70,"./js/coinspot.js":71,"./js/crex24.js":72,"./js/currencycom.js":73,"./js/delta.js":74,"./js/deribit.js":75,"./js/digifinex.js":76,"./js/equos.js":77,"./js/eterbase.js":78,"./js/exmo.js":79,"./js/exx.js":80,"./js/fcoin.js":81,"./js/fcoinjp.js":82,"./js/flowbtc.js":83,"./js/foxbit.js":84,"./js/ftx.js":85,"./js/gateio.js":86,"./js/gemini.js":87,"./js/gopax.js":88,"./js/hbtc.js":89,"./js/hitbtc.js":90,"./js/hollaex.js":91,"./js/huobijp.js":92,"./js/huobipro.js":93,"./js/idex.js":94,"./js/independentreserve.js":95,"./js/indodax.js":96,"./js/itbit.js":97,"./js/kraken.js":98,"./js/kucoin.js":99,"./js/kuna.js":100,"./js/lakebtc.js":101,"./js/latoken.js":102,"./js/lbank.js":103,"./js/liquid.js":104,"./js/luno.js":105,"./js/lykke.js":106,"./js/mercado.js":107,"./js/mixcoins.js":108,"./js/ndax.js":109,"./js/novadax.js":110,"./js/oceanex.js":111,"./js/okcoin.js":112,"./js/okex.js":113,"./js/paymium.js":114,"./js/phemex.js":115,"./js/poloniex.js":116,"./js/probit.js":117,"./js/qtrade.js":118,"./js/rightbtc.js":119,"./js/ripio.js":120,"./js/southxchange.js":121,"./js/stex.js":162,"./js/surbitcoin.js":163,"./js/therock.js":164,"./js/tidebit.js":165,"./js/tidex.js":166,"./js/timex.js":167,"./js/upbit.js":168,"./js/vbtc.js":169,"./js/vcc.js":170,"./js/wavesexchange.js":171,"./js/whitebit.js":172,"./js/xbtce.js":173,"./js/xena.js":174,"./js/yobit.js":175,"./js/zaif.js":176,"./js/zb.js":177}],3:[function(require,module,exports){
'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 Argume