diff --git a/Project.njsproj b/Project.njsproj
index f6457a78a..79f95a42d 100644
--- a/Project.njsproj
+++ b/Project.njsproj
@@ -56,10 +56,17 @@
Code
-
+
+
+
Code
+
+
+
+
+
Code
@@ -216,17 +223,20 @@
+
+
-
+
+
diff --git a/Server/Exchange/ExchangeAPI.js b/Server/Exchange/ExchangeAPI.js
new file mode 100644
index 000000000..7ee2dad62
--- /dev/null
+++ b/Server/Exchange/ExchangeAPI.js
@@ -0,0 +1,247 @@
+exports.newExchangeAPI = function newExchangeAPI(bot, logger) {
+
+ /*
+
+ This module allows trading bots to connect to the exchange and do trading operations on it. So far it can only work with Poloniex.
+
+ */
+ const _ = require('lodash');
+ const isValidOrder = require('./exchangeUtils').isValidOrder;
+
+ let MODULE_NAME = "Exchange API";
+
+ let thisObject = {
+ initialize: initialize,
+ getTicker: getTicker,
+ getOpenPositions: getOpenPositions,
+ getExecutedTrades: getExecutedTrades,
+ putPosition: putPosition,
+ movePosition: movePosition,
+ getPublicTradeHistory: getPublicTradeHistory,
+ getExchangeProperties: getExchangeProperties,
+ getMaxDecimalPositions: getMaxDecimalPositions
+ };
+
+ let apiClient;
+
+ return thisObject;
+
+ function initialize(callBackFunction) {
+ try {
+
+ if (global.LOG_CONTROL[MODULE_NAME].logInfo === true) { logger.write(MODULE_NAME, "[INFO] initialize -> Entering function."); }
+
+ let exchange = global.EXCHANGE_NAME.toLowerCase() + 'Client.js';
+ let api = require('./Wrappers/' + exchange);
+ if (!bot.instanceIndex)
+ bot.instanceIndex = 0;
+ apiClient = api.newAPIClient(global.EXCHANGE_KEYS[global.EXCHANGE_NAME][bot.instanceIndex].Key, global.EXCHANGE_KEYS[global.EXCHANGE_NAME][bot.instanceIndex].Secret, logger);
+
+ callBackFunction(global.DEFAULT_OK_RESPONSE);
+
+ } catch (err) {
+ logger.write(MODULE_NAME, "[ERROR] initialize -> err = " + err.message);
+ callBackFunction(global.DEFAULT_FAIL_RESPONSE);
+ }
+ }
+
+ /*
+ * Position Object = {
+ * id, String
+ * type, String
+ * rate, Number
+ * amountA, Number
+ * amountB, Number
+ * fee, Number
+ * datetime Date
+ * };
+ */
+ function truncDecimals(pFloatValue) {
+ let decimals = getMaxDecimalPositions();
+ return parseFloat(parseFloat(pFloatValue).toFixed(decimals));
+ }
+
+ /*
+ * Return number of decimals for the current market
+ */
+ function getMaxDecimalPositions() {
+ return getMarketConfig().maxDecimals;
+ }
+
+ /*
+ * Return number of decimals for the current market
+ */
+ function getMarketConfig() {
+ return _.find(getExchangeProperties().markets, (p) => {
+ return _.first(p.pair) === global.MARKET.assetA.toUpperCase() &&
+ _.last(p.pair) === global.MARKET.assetB.toUpperCase();
+ });
+ }
+
+ /*
+ * Return number of decimals for the current market
+ */
+ function getExchangeProperties() {
+ try {
+
+ if (global.LOG_CONTROL[MODULE_NAME].logInfo === true) { logger.write(MODULE_NAME, "[INFO] getExchangeProperties -> Entering function."); }
+
+ return apiClient.getExchangeProperties();
+
+ } catch (err) {
+ logger.write(MODULE_NAME, "[ERROR] getExchangeProperties -> err = " + err.message);
+ callBack(global.DEFAULT_FAIL_RESPONSE);
+ }
+ }
+
+ /*
+ * Returns the price for a given pair of assets.
+ * The object returned is an array of trades:
+ * ticker = {
+ * bid, Number
+ * ask, Number
+ * last Number
+ * };
+ */
+ function getTicker(pMarket, callBack) {
+ try {
+
+ if (global.LOG_CONTROL[MODULE_NAME].logInfo === true) { logger.write(MODULE_NAME, "[INFO] getTicker -> Entering function."); }
+
+ apiClient.getTicker(pMarket, callBack);
+
+ } catch (err) {
+ logger.write(MODULE_NAME, "[ERROR] getTicker -> err = " + err.message);
+ callBack(global.DEFAULT_FAIL_RESPONSE);
+ }
+ }
+
+ /*
+ * Returns the open positions ath the exchange for a given market and user account.
+ * The object returned is an array of positions
+ *
+ */
+ function getOpenPositions(pMarket, callBack) {
+ try {
+
+ if (global.LOG_CONTROL[MODULE_NAME].logInfo === true) { logger.write(MODULE_NAME, "[INFO] getOpenPositions -> Entering function."); }
+ if (global.LOG_CONTROL[MODULE_NAME].logInfo === true) { logger.write(MODULE_NAME, "[INFO] getOpenPositions -> pMarket = " + JSON.stringify(pMarket)); }
+
+ apiClient.getOpenPositions(pMarket, callBack);
+
+ } catch (err) {
+ logger.write(MODULE_NAME, "[ERROR] getOpenPositions -> Error = " + err.message);
+ callBack(global.DEFAULT_FAIL_RESPONSE);
+ }
+ }
+
+ /*
+ * Returns the trades for a given order number.
+ * The object returned is an array of positions
+ */
+ function getExecutedTrades(pPositionId, callBack) {
+ try {
+
+ if (global.LOG_CONTROL[MODULE_NAME].logInfo === true) { logger.write(MODULE_NAME, "[INFO] getExecutedTrades -> Entering function."); }
+ if (global.LOG_CONTROL[MODULE_NAME].logInfo === true) { logger.write(MODULE_NAME, "[INFO] getExecutedTrades -> pPositionId = " + pPositionId); }
+
+ apiClient.getExecutedTrades(pPositionId, callBack);
+
+ } catch (err) {
+ logger.write(MODULE_NAME, "[ERROR] getExecutedTrades -> Error = " + err.message);
+ callBack(global.DEFAULT_FAIL_RESPONSE);
+ }
+ }
+
+ /*
+ * Creates a new buy or sell order.
+ * The orderNumber is returned. String
+ */
+ function putPosition(pMarket, pType, pRate, pAmountA, pAmountB, callBack) {
+ try {
+
+ if (global.LOG_CONTROL[MODULE_NAME].logInfo === true) { logger.write(MODULE_NAME, "[INFO] putPosition -> Entering function."); }
+ if (global.LOG_CONTROL[MODULE_NAME].logInfo === true) { logger.write(MODULE_NAME, "[INFO] putPosition -> pMarket = " + JSON.stringify(pMarket)); }
+ if (global.LOG_CONTROL[MODULE_NAME].logInfo === true) { logger.write(MODULE_NAME, "[INFO] putPosition -> pType = " + pType); }
+ if (global.LOG_CONTROL[MODULE_NAME].logInfo === true) { logger.write(MODULE_NAME, "[INFO] putPosition -> pRate = " + truncDecimals(pRate)); }
+ if (global.LOG_CONTROL[MODULE_NAME].logInfo === true) { logger.write(MODULE_NAME, "[INFO] putPosition -> pAmountA = " + truncDecimals(pAmountA)); }
+ if (global.LOG_CONTROL[MODULE_NAME].logInfo === true) { logger.write(MODULE_NAME, "[INFO] putPosition -> pAmountB = " + truncDecimals(pAmountB)); }
+
+ let check = isValidOrder({
+ market: getMarketConfig(),
+ api: apiClient,
+ amount: truncDecimals(pAmountB),
+ price: truncDecimals(pRate)
+ });
+
+ if (check.valid) {
+ if (pType === "buy") {
+ apiClient.buy(pMarket.assetA, pMarket.assetB, truncDecimals(pRate), truncDecimals(pAmountB), callBack);
+ return;
+ }
+
+ if (pType === "sell") {
+ apiClient.sell(pMarket.assetA, pMarket.assetB, truncDecimals(pRate), truncDecimals(pAmountB), callBack);
+ return;
+ }
+
+ logger.write(MODULE_NAME, "[ERROR] putPosition -> pType must be either 'buy' or 'sell'.");
+ callBack(global.DEFAULT_FAIL_RESPONSE);
+
+ } else {
+ logger.write(MODULE_NAME, "[ERROR] putPosition -> The order is invalid: " + check.reason);
+ callBack(global.DEFAULT_FAIL_RESPONSE);
+ }
+
+ } catch (err) {
+ logger.write(MODULE_NAME, "[ERROR] putPosition -> err = " + err.message);
+ callBack(global.DEFAULT_FAIL_RESPONSE);
+ }
+ }
+
+ /*
+ * Move an existing position to the new rate.
+ * The new orderNumber is returned.
+ */
+ function movePosition(pPosition, pNewRate, pNewAmountB, callBack) {
+ try {
+
+ if (global.LOG_CONTROL[MODULE_NAME].logInfo === true) { logger.write(MODULE_NAME, "[INFO] movePosition -> Entering function."); }
+ if (global.LOG_CONTROL[MODULE_NAME].logInfo === true) { logger.write(MODULE_NAME, "[INFO] movePosition -> pPosition = " + JSON.stringify(pPosition)); }
+ if (global.LOG_CONTROL[MODULE_NAME].logInfo === true) { logger.write(MODULE_NAME, "[INFO] movePosition -> pNewRate = " + truncDecimals(pNewRate)); }
+
+ apiClient.movePosition(pPosition, truncDecimals(pNewRate), truncDecimals(pNewAmountB), callBack);
+
+ } catch (err) {
+ logger.write(MODULE_NAME, "[ERROR] movePosition -> err = " + err.message);
+ callBack(global.DEFAULT_FAIL_RESPONSE);
+ }
+ }
+
+ /*
+ * Returns all the trade history from the Exchange since startTime to endTime orderd by tradeId.
+ * It's possible that the exchange doesn't support this method.
+ * The object returned is an array of trades:
+ * trade = {
+ * tradeID, String
+ * globalTradeID, String
+ * type, String
+ * rate, Number
+ * amountA, Number
+ * amountB, Number
+ * date Date
+ * };
+ */
+ function getPublicTradeHistory(assetA, assetB, startTime, endTime, callBack) {
+ try {
+
+ if (global.LOG_CONTROL[MODULE_NAME].logInfo === true) { logger.write(MODULE_NAME, "[INFO] getTradeHistory -> Entering function."); }
+
+ apiClient.getPublicTradeHistory(assetA, assetB, startTime, endTime, callBack);
+
+ } catch (err) {
+ logger.write(MODULE_NAME, "[ERROR] getTradeHistory -> err = " + err.message);
+ callBack(global.DEFAULT_FAIL_RESPONSE);
+ }
+ }
+};
\ No newline at end of file
diff --git a/Server/Exchange/PoloniexAPIClient.js b/Server/Exchange/PoloniexAPIClient.js
deleted file mode 100644
index f1950f295..000000000
--- a/Server/Exchange/PoloniexAPIClient.js
+++ /dev/null
@@ -1,500 +0,0 @@
-exports.newPoloniexAPIClient = function newPoloniexAPIClient(pKey, pSecret) {
-
- /*
- /* ATENTION: This Library is used both a the cloud (AACloud) and also at the AAWeb on the server side without any modifications.
- /* There is a second version, stripped of all the inner functionality that runs at AAWeb browser side, which channels the requests to the server side one.
- */
-
- let newFunction = new API(pKey, pSecret);
-
- let thisObject = {
- API: newFunction
- };
-
- return thisObject;
-
- function API(key, secret) {
- 'use strict';
-
- // Module dependencies
- var crypto = require('crypto'),
- request = require('request'),
- nonce = require('nonce')();
-
- // Constants
- var version = '0.0.8',
- PUBLIC_API_URL = 'https://poloniex.com/public',
- PRIVATE_API_URL = 'https://poloniex.com/tradingApi',
- USER_AGENT = 'poloniex.js ' + version;
- //USER_AGENT = 'Mozilla/5.0 (Windows NT 6.3; WOW64; rv:26.0) Gecko/20100101 Firefox/26.0'
-
- // Helper methods
- function joinCurrencies(currencyA, currencyB) {
- // If only one arg, then return the first
- if (typeof currencyB !== 'string') {
- return currencyA;
- }
-
- return currencyA + '_' + currencyB;
- }
-
- // Generate headers signed by thisObject user's key and secret.
- // The secret is encapsulated and never exposed
- function _getPrivateHeaders(parameters) {
- var paramString, signature;
-
- if (!key || !secret) {
- throw 'Poloniex: Error. API key and secret required';
- }
-
- // Convert to `arg1=foo&arg2=bar`
- paramString = Object.keys(parameters).map(function (param) {
- return encodeURIComponent(param) + '=' + encodeURIComponent(parameters[param]);
- }).join('&');
-
- signature = crypto.createHmac('sha512', secret).update(paramString).digest('hex');
-
- return {
- Key: key,
- Sign: signature
- };
- };
-
- // Currently, thisObject fails with `Error: CERT_UNTRUSTED`
- // Poloniex.STRICT_SSL can be set to `false` to avoid thisObject. Use with caution.
- // Will be removed in future, once thisObject is resolved.
- const STRICT_SSL = true;
-
- // Prototype
- let thisObject = {
-
- // Make an API request
- _request: function (options, callback) {
- if (!('headers' in options)) {
- options.headers = {};
- }
-
- options.json = true;
- options.headers['User-Agent'] = USER_AGENT;
- options.strictSSL = STRICT_SSL;
-
- request(options, function (err, response, body) {
- // Empty response
- if (!err && (typeof body === 'undefined' || body === null)) {
- err = 'Empty response';
- }
-
- callback(err, body);
- });
-
- return thisObject;
- },
-
- // Make a public API request
- _public: function (command, parameters, callback) {
- var options;
-
- if (typeof parameters === 'function') {
- callback = parameters;
- parameters = {};
- }
-
- parameters || (parameters = {});
- parameters.command = command;
- options = {
- method: 'GET',
- url: PUBLIC_API_URL,
- qs: parameters
- };
-
- options.qs.command = command;
- return thisObject._request(options, callback);
- },
-
- // Make a private API request
- _private: function (command, parameters, callback) {
- var options;
-
- if (typeof parameters === 'function') {
- callback = parameters;
- parameters = {};
- }
-
- parameters || (parameters = {});
- parameters.command = command;
- parameters.nonce = nonce();
-
- options = {
- method: 'POST',
- url: PRIVATE_API_URL,
- form: parameters,
- headers: _getPrivateHeaders(parameters)
- };
-
- return thisObject._request(options, callback);
- },
-
- /////
- // PUBLIC METHODS
-
- returnTicker: function (callback) {
- return thisObject._public('returnTicker', callback);
- },
-
- return24hVolume: function (callback) {
- return thisObject._public('return24hVolume', callback);
- },
-
- returnOrderBook: function (currencyA, currencyB, depth, callback) {
- var parameters = {
- currencyPair: joinCurrencies(currencyA, currencyB),
- depth: depth
- };
-
- return thisObject._public('returnOrderBook', parameters, callback);
- },
-
- returnOrderBooks: function (depth, callback) {
- var parameters = {
- currencyPair: 'all',
- depth: depth
- };
-
- return thisObject._public('returnOrderBook', parameters, callback);
- },
-
- returnPublicTradeHistory: function (currencyA, currencyB, start, end, callback) {
- var parameters = {
- currencyPair: joinCurrencies(currencyA, currencyB),
- start: start,
- end: end
- };
-
- return thisObject._public('returnTradeHistory', parameters, callback);
- },
-
- returnChartData: function (currencyA, currencyB, period, start, end, callback) {
- var parameters = {
- currencyPair: joinCurrencies(currencyA, currencyB),
- period: period,
- start: start,
- end: end
- };
-
- return thisObject._public('returnChartData', parameters, callback);
- },
-
- returnCurrencies: function (callback) {
- return thisObject._public('returnCurrencies', callback);
- },
-
- returnLoanOrders: function (currency, callback) {
- return thisObject._public('returnLoanOrders', { currency: currency }, callback);
- },
-
- /////
- // PRIVATE METHODS
-
- returnBalances: function (callback) {
- return thisObject._private('returnBalances', {}, callback);
- },
-
- returnCompleteBalances: function (callback) {
- return thisObject._private('returnCompleteBalances', {}, callback);
- },
-
- returnDepositAddresses: function (callback) {
- return thisObject._private('returnDepositAddresses', {}, callback);
- },
-
- generateNewAddress: function (currency, callback) {
- return thisObject._private('returnDepositsWithdrawals', { currency: currency }, callback);
- },
-
- returnDepositsWithdrawals: function (start, end, callback) {
- return thisObject._private('returnDepositsWithdrawals', { start: start, end: end }, callback);
- },
-
- returnOpenOrders: function (currencyA, currencyB, callback) {
- var parameters = {
- currencyPair: joinCurrencies(currencyA, currencyB)
- };
-
- return thisObject._private('returnOpenOrders', parameters, callback);
- },
-
- returnTradeHistory: function (currencyA, currencyB, callback) {
- var parameters = {
- currencyPair: joinCurrencies(currencyA, currencyB)
- };
-
- return thisObject._private('returnTradeHistory', parameters, callback);
- },
-
- returnOrderTrades: function (orderNumber, callback) {
- var parameters = {
- orderNumber: orderNumber
- };
-
- return thisObject._private('returnOrderTrades', parameters, callback);
- },
-
- buy: function (currencyA, currencyB, rate, amount, callback) {
- var parameters = {
- currencyPair: joinCurrencies(currencyA, currencyB),
- rate: rate,
- amount: amount
- };
-
- return thisObject._private('buy', parameters, callback);
- },
-
- sell: function (currencyA, currencyB, rate, amount, callback) {
- var parameters = {
- currencyPair: joinCurrencies(currencyA, currencyB),
- rate: rate,
- amount: amount
- };
-
- return thisObject._private('sell', parameters, callback);
- },
-
- cancelOrder: function (currencyA, currencyB, orderNumber, callback) {
- var parameters = {
- currencyPair: joinCurrencies(currencyA, currencyB),
- orderNumber: orderNumber
- };
-
- return thisObject._private('cancelOrder', parameters, callback);
- },
-
- moveOrder: function (orderNumber, rate, amount, callback) {
- var parameters = {
- orderNumber: orderNumber,
- rate: rate,
- amount: amount ? amount : null
- };
-
- return thisObject._private('moveOrder', parameters, callback);
- },
-
- withdraw: function (currency, amount, address, callback) {
- var parameters = {
- currency: currency,
- amount: amount,
- address: address
- };
-
- return thisObject._private('withdraw', parameters, callback);
- },
-
- returnFeeInfo: function (callback) {
- return thisObject._private('returnFeeInfo', {}, callback);
- },
-
- returnAvailableAccountBalances: function (account, callback) {
- var options = {};
- if (account) {
- options.account = account;
- }
- return thisObject._private('returnAvailableAccountBalances', options, callback);
- },
-
- returnTradableBalances: function (callback) {
- return thisObject._private('returnTradableBalances', {}, callback);
- },
-
- transferBalance: function (currency, amount, fromAccount, toAccount, callback) {
- var parameters = {
- currency: currency,
- amount: amount,
- fromAccount: fromAccount,
- toAccount: toAccount
- };
-
- return thisObject._private('transferBalance', parameters, callback);
- },
-
- returnMarginAccountSummary: function (callback) {
- return thisObject._private('returnMarginAccountSummary', {}, callback);
- },
-
- marginBuy: function (currencyA, currencyB, rate, amount, lendingRate, callback) {
- var parameters = {
- currencyPair: joinCurrencies(currencyA, currencyB),
- rate: rate,
- amount: amount,
- lendingRate: lendingRate ? lendingRate : null
- };
-
- return thisObject._private('marginBuy', parameters, callback);
- },
-
- marginSell: function (currencyA, currencyB, rate, amount, lendingRate, callback) {
- var parameters = {
- currencyPair: joinCurrencies(currencyA, currencyB),
- rate: rate,
- amount: amount,
- lendingRate: lendingRate ? lendingRate : null
- };
-
- return thisObject._private('marginSell', parameters, callback);
- },
-
- getMarginPosition: function (currencyA, currencyB, callback) {
- var parameters = {
- currencyPair: joinCurrencies(currencyA, currencyB)
- };
-
- return thisObject._private('getMarginPosition', parameters, callback);
- },
-
- closeMarginPosition: function (currencyA, currencyB, callback) {
- var parameters = {
- currencyPair: joinCurrencies(currencyA, currencyB)
- };
-
- return thisObject._private('closeMarginPosition', parameters, callback);
- },
-
- createLoanOffer: function (currency, amount, duration, autoRenew, lendingRate, callback) {
- var parameters = {
- currency: currency,
- amount: amount,
- duration: duration,
- autoRenew: autoRenew,
- lendingRate: lendingRate
- };
-
- return thisObject._private('createLoanOffer', parameters, callback);
- },
-
- cancelLoanOffer: function (orderNumber, callback) {
- var parameters = {
- orderNumber: orderNumber
- };
-
- return thisObject._private('cancelLoanOffer', parameters, callback);
- },
-
- returnOpenLoanOffers: function (callback) {
- return thisObject._private('returnOpenLoanOffers', {}, callback);
- },
-
- returnActiveLoans: function (callback) {
- return thisObject._private('returnActiveLoans', {}, callback);
- },
-
- returnLendingHistory: function (start, end, limit, callback) {
- var parameters = {
- start: start,
- end: end,
- limit: limit
- };
-
- return thisObject._private('returnLendingHistory', parameters, callback);
- },
-
- toggleAutoRenew: function (orderNumber, callback) {
- return thisObject._private('toggleAutoRenew', { orderNumber: orderNumber }, callback);
- },
-
- analizeResponse: function (logger, exchangeErr, exchangeResponse, notOkCallBack, okCallBack) {
-
- const FULL_LOG = false;
- const LOG_FILE_CONTENT = false;
- const MODULE_NAME = "Poloniex API Client";
-
- /* This function analizes the different situations we might encounter trying to access Poloniex and returns appropiate standard errors. */
-
- try {
-
- let stringExchangeResponse = JSON.stringify(exchangeResponse);
- let stringExchangeErr = JSON.stringify(exchangeErr);
-
- if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] analizeResponse -> exchangeErr = " + stringExchangeErr); }
- if (LOG_FILE_CONTENT === true) { logger.write(MODULE_NAME, "[INFO] analizeResponse -> exchangeResponse = " + stringExchangeResponse); }
-
- if (stringExchangeResponse === undefined) {
-
- logger.write(MODULE_NAME, "[WARN] analizeResponse -> No response received from the exchange. Retrying Later.");
-
- notOkCallBack(global.DEFAULT_RETRY_RESPONSE);
- return;
- }
-
- if (stringExchangeErr.indexOf("ETIMEDOUT") > 0 ||
- stringExchangeErr.indexOf("ENOTFOUND") > 0 ||
- stringExchangeErr.indexOf("ECONNREFUSED") > 0 ||
- stringExchangeErr.indexOf("ESOCKETTIMEDOUT") > 0 ||
- stringExchangeErr.indexOf("ECONNRESET") > 0 ||
- (stringExchangeResponse !== undefined && (
- stringExchangeResponse.indexOf("Connection timed out") > 0 ||
- stringExchangeResponse.indexOf("Connection Error") > 0 ||
- stringExchangeResponse.indexOf("Bad gateway") > 0 ||
- stringExchangeResponse.indexOf("Nonce must be greater than") > 0 ||
- stringExchangeResponse.indexOf("Internal error. Please try again") > 0))) {
-
- logger.write(MODULE_NAME, "[ERROR] analizeResponse -> Somethng bad happened while trying to access the Exchange API. Requesting new execution later.");
- logger.write(MODULE_NAME, "[ERROR] analizeResponse -> stringExchangeErr = " + stringExchangeErr);
-
- notOkCallBack(global.DEFAULT_RETRY_RESPONSE);
- return;
-
- } else {
-
- if (JSON.stringify(exchangeResponse).indexOf("error") > 0) {
-
- logger.write(MODULE_NAME, "[ERROR] analizeResponse -> Unexpected response from the Exchange.");
- logger.write(MODULE_NAME, "[ERROR] analizeResponse -> JSON.stringify(exchangeErr) = " + JSON.stringify(exchangeErr));
- logger.write(MODULE_NAME, "[ERROR] analizeResponse -> exchangeErr = " + exchangeErr);
- logger.write(MODULE_NAME, "[ERROR] analizeResponse -> exchangeResponse = " + exchangeResponse);
-
- /* {"error":"Not enough USDT.","success":0}*/
-
- if (JSON.stringify(exchangeResponse).indexOf("Not enough") > 0) {
-
- let err = {
- resutl: global.CUSTOM_FAIL_RESPONSE.result,
- message: exchangeResponse.error
- };
-
- notOkCallBack(err);
-
- } else {
-
- notOkCallBack(global.DEFAULT_FAIL_RESPONSE);
-
- }
- return;
- }
-
- if (exchangeErr) {
-
- logger.write(MODULE_NAME, "[ERROR] analizeResponse -> Unexpected error trying to contact the Exchange.");
- logger.write(MODULE_NAME, "[ERROR] analizeResponse -> exchangeErr = " + exchangeErr);
-
- notOkCallBack(global.DEFAULT_FAIL_RESPONSE);
- return;
-
- } else {
-
- logger.write(MODULE_NAME, "[INFO] analizeResponse -> No problem found.");
- okCallBack();
- return;
- }
- }
-
- } catch (err) {
- logger.write(MODULE_NAME, "[ERROR] analizeResponse -> err.message = " + err.message);
- notOkCallBack(global.DEFAULT_FAIL_RESPONSE);
- return;
- }
- }
- };
-
- return thisObject;
- }
-
-
-}
diff --git a/Server/Exchange/Wrappers/beautifier.js b/Server/Exchange/Wrappers/beautifier.js
new file mode 100644
index 000000000..5e5e6a051
--- /dev/null
+++ b/Server/Exchange/Wrappers/beautifier.js
@@ -0,0 +1,183 @@
+const _ = require('underscore');
+
+class Beautifier {
+
+ constructor() {
+ this._beautifications = {
+ aggTrades: {
+ a: 'aggTradeId',
+ p: 'price',
+ q: 'quantity',
+ f: 'firstTradeId',
+ l: 'lastTradeId',
+ T: 'timestamp',
+ m: 'maker',
+ M: 'bestPriceMatch'
+ },
+ klines: {
+ 0: 'openTime',
+ 1: 'open',
+ 2: 'high',
+ 3: 'low',
+ 4: 'close',
+ 5: 'volume',
+ 6: 'closeTime',
+ 7: 'quoteAssetVolume',
+ 8: 'trades',
+ 9: 'takerBaseAssetVolume',
+ 10: 'takerQuoteAssetVolume',
+ 11: 'ignored'
+ },
+ bids: [
+ {
+ 0: 'price',
+ 1: 'quantity',
+ 2: 'ignored'
+ }
+ ],
+ asks: [
+ {
+ 0: 'price',
+ 1: 'quantity',
+ 2: 'ignored'
+ }
+ ],
+ depthUpdateEvent: {
+ e: 'eventType',
+ E: 'eventTime',
+ s: 'symbol',
+ u: 'updateId',
+ b: 'bidDepthDelta',
+ a: 'askDepthDelta'
+ },
+ bidDepthDelta: [
+ {
+ 0: 'price',
+ 1: 'quantity',
+ 2: 'ignored'
+ }
+ ],
+ askDepthDelta: [
+ {
+ 0: 'price',
+ 1: 'quantity',
+ 2: 'ignored'
+ }
+ ],
+ klineEvent: {
+ e: 'eventType',
+ E: 'eventTime',
+ s: 'symbol',
+ k: 'kline'
+ },
+ kline: {
+ t: 'startTime',
+ T: 'endTime',
+ s: 'symbol',
+ i: 'interval',
+ f: 'firstTradeId',
+ L: 'lastTradeId',
+ o: 'open',
+ c: 'close',
+ h: 'high',
+ l: 'low',
+ v: 'volume',
+ n: 'trades',
+ x: 'final',
+ q: 'quoteVolume',
+ V: 'volumeActive',
+ Q: 'quoteVolumeActive',
+ B: 'ignored'
+ },
+ aggTradeEvent: {
+ e: 'eventType',
+ E: 'eventTime',
+ s: 'symbol',
+ a: 'tradeId',
+ p: 'price',
+ q: 'quantity',
+ f: 'firstTradeId',
+ l: 'lastTradeId',
+ T: 'time',
+ m: 'maker',
+ M: 'ignored'
+ },
+ outboundAccountInfoEvent: {
+ e: 'eventType',
+ E: 'eventTime',
+ m: 'makerCommission',
+ t: 'takerCommission',
+ b: 'buyerCommission',
+ s: 'sellerCommission',
+ T: 'canTrade',
+ W: 'canWithdraw',
+ D: 'canDeposit',
+ B: 'balances'
+ },
+ balances: [
+ {
+ a: 'asset',
+ f: 'availableBalance',
+ l: 'onOrderBalance'
+ }
+ ],
+ executionReportEvent: {
+ e: 'eventType',
+ E: 'eventTime',
+ s: 'symbol',
+ c: 'newClientOrderId',
+ S: 'side',
+ o: 'orderType',
+ f: 'cancelType', // GTC 'Good till Cancel', IOC: 'Immediate or Cancel'
+ q: 'quantity',
+ p: 'price',
+ x: 'executionType',
+ X: 'orderStatus',
+ r: 'rejectReason',
+ i: 'orderId',
+ l: 'lastTradeQuantity',
+ z: 'accumulatedQuantity',
+ L: 'lastTradePrice',
+ n: 'commission',
+ N: 'commissionAsset',
+ m: 'maker',
+ T: 'tradeTime',
+ t: 'tradeId'
+ }
+ }
+ }
+
+ beautify(object, type) {
+ const beautifications = _.isObject(type) ? type : this._beautifications[type];
+ if (!beautifications) {
+ return object;
+ }
+ let newItem = {};
+ _.each(object, (value, key) => {
+ if (_.isArray(value)) {
+ const newArray = [];
+ if (_.isArray(this._beautifications[beautifications[key]])) {
+ _.each(value, arrayValue => {
+ newArray.push(this.beautify(arrayValue, this._beautifications[beautifications[key]][0]));
+ });
+ } else {
+ _.each(value, (value, key) => {
+ newItem.push(this.beautify(value, beautifications[key]))
+ });
+ }
+ const newKey = beautifications[key] || key;
+ newItem[newKey] = newArray;
+ } else if (_.isObject(value)) {
+ const newKey = beautifications[key] || key;
+ newItem[newKey] = this.beautify(value, beautifications[key]);
+ } else {
+ const newKey = beautifications[key] || key;
+ newItem[newKey] = value;
+ }
+ });
+ return newItem;
+ }
+
+}
+
+module.exports = Beautifier;
\ No newline at end of file
diff --git a/Server/Exchange/Wrappers/binance.js b/Server/Exchange/Wrappers/binance.js
new file mode 100644
index 000000000..624c0fc06
--- /dev/null
+++ b/Server/Exchange/Wrappers/binance.js
@@ -0,0 +1,368 @@
+// Source: https://github.com/zoeyg/binance/blob/master/lib/rest.js
+
+const request = require('request');
+const qs = require('querystring');
+const _ = require('underscore');
+const crypto = require('crypto');
+const Beautifier = require('./beautifier.js');
+const assert = require('assert');
+
+class BinanceRest {
+
+ constructor({
+ key,
+ secret,
+ recvWindow = false,
+ timeout = 15000,
+ disableBeautification = false,
+ handleDrift = false
+ }) {
+ this.key = key;
+ this.secret = secret;
+ this.recvWindow = recvWindow;
+ this.timeout = timeout;
+ this.disableBeautification = disableBeautification;
+ this.handleDrift = handleDrift;
+
+ this._beautifier = new Beautifier();
+ this._baseUrl = 'https://api.binance.com/';
+ this._drift = 0;
+ this._syncInterval = 0;
+ }
+
+ _makeRequest(query, callback, route, security, method, attempt = 0) {
+ assert(_.isUndefined(callback) || _.isFunction(callback), 'callback must be a function or undefined');
+ assert(_.isObject(query), 'query must be an object');
+
+ let queryString;
+ const type = _.last(route.split('/')),
+ options = {
+ url: `${this._baseUrl}${route}`,
+ timeout: this.timeout
+ };
+
+ if (security === 'SIGNED') {
+ if (this.recvWindow) {
+ query.recvWindow = this.recvWindow;
+ }
+ queryString = qs.stringify(query);
+ options.url += '?' + queryString;
+ if (options.url.substr(options.url.length - 1) !== '?') {
+ options.url += '&';
+ }
+ options.url += `signature=${this._sign(queryString)}`;
+ } else {
+ queryString = qs.stringify(query);
+ if (queryString) {
+ options.url += '?' + queryString;
+ }
+ }
+ if (security === 'API-KEY' || security === 'SIGNED') {
+ options.headers = { 'X-MBX-APIKEY': this.key };
+ }
+ if (method) {
+ options.method = method;
+ }
+
+ const action = cb => {
+ request(options, (err, response, body) => {
+ let payload;
+ try {
+ payload = JSON.parse(body);
+ } catch (e) {
+ payload = body;
+ }
+ if (err) {
+ cb(err, payload);
+ } else if (response.statusCode < 200 || response.statusCode > 299) {
+ /*
+ * If we get a response that the timestamp is ahead of the server,
+ * calculate the drift and then attempt the request again
+ */
+ if (response.statusCode === 400 && payload.code === -1021 &&
+ this.handleDrift && attempt === 0) {
+
+ this.calculateDrift()
+ .then(() => {
+ query.timestamp = this._getTime() + this._drift;
+ return this._makeRequest(query, cb, route, security, method,
+ ++attempt);
+ });
+ } else {
+ cb(new Error(`Response code ${response.statusCode}`), payload);
+ }
+ } else {
+ if (_.isArray(payload)) {
+ payload = _.map(payload, (item) => {
+ return this._doBeautifications(item, type);
+ });
+ } else {
+ payload = this._doBeautifications(payload);
+ }
+ cb(err, payload);
+ }
+ });
+ };
+ if (callback) {
+ action(callback);
+ } else {
+ return new Promise((resolve, reject) => action((err, payload) => {
+ if (err) {
+ if (payload === undefined) {
+ reject(err);
+ } else {
+ reject(payload);
+ }
+ } else {
+ resolve(payload);
+ }
+ }));
+ }
+ }
+
+ _doBeautifications(response, route) {
+ if (this.disableBeautification) {
+ return response;
+ }
+ return this._beautifier.beautify(response, route);
+ }
+
+ _sign(queryString) {
+ return crypto.createHmac('sha256', this.secret)
+ .update(queryString)
+ .digest('hex');
+ }
+
+ _setTimestamp(query) {
+ if (!query.timestamp) {
+ query.timestamp = this._getTime() + this._drift;
+ }
+ }
+
+ _getTime() {
+ return new Date().getTime();
+ }
+
+ calculateDrift() {
+ const systemTime = this._getTime();
+ return this.time()
+ .then((response) => {
+ // Calculate the approximate trip time from here to binance
+ const transitTime = parseInt((this._getTime() - systemTime) / 2);
+ this._drift = response.serverTime - (systemTime + transitTime);
+ });
+ }
+
+ startTimeSync(interval = 300000, onRecalculateDriftCb) {
+ return new Promise((resolve, reject) => {
+ // If there's already an interval running, clear it and reset values
+ if (this._syncInterval !== 0) {
+ this.endTimeSync();
+ return resolve();
+ }
+
+ // Calculate initial drift value and setup interval to periodically update it
+ this.calculateDrift()
+ .then(resolve)
+ .catch(reject);
+
+ this._syncInterval = setInterval(() => {
+ const promise = this.calculateDrift();
+
+ if (_.isFunction(onRecalculateDriftCb)) {
+ onRecalculateDriftCb(promise);
+ }
+ }, interval);
+ });
+ }
+
+ endTimeSync() {
+ clearInterval(this._syncInterval);
+ this._drift = 0;
+ this._syncInterval = 0;
+ }
+
+ // Public APIs
+ ping(callback) {
+ return this._makeRequest({}, callback, 'api/v1/ping');
+ }
+
+ time(callback) {
+ return this._makeRequest({}, callback, 'api/v1/time');
+ }
+
+ depth(query = {}, callback) {
+ if (_.isString(query)) {
+ query = { symbol: query };
+ }
+
+ return this._makeRequest(query, callback, 'api/v1/depth');
+ }
+
+ trades(query = {}, callback) {
+ if (_.isString(query)) {
+ query = { symbol: query };
+ }
+
+ return this._makeRequest(query, callback, 'api/v1/trades');
+ }
+
+ historicalTrades(query = {}, callback) {
+ if (_.isString(query)) {
+ query = { symbol: query };
+ }
+
+ return this._makeRequest(query, callback, 'api/v1/historicalTrades', 'API-KEY');
+ }
+
+ aggTrades(query = {}, callback) {
+ if (_.isString(query)) {
+ query = { symbol: query };
+ }
+
+ return this._makeRequest(query, callback, 'api/v1/aggTrades');
+ }
+
+ exchangeInfo(callback) {
+ return this._makeRequest({}, callback, 'api/v1/exchangeInfo');
+ }
+
+ klines(query = {}, callback) {
+ return this._makeRequest(query, callback, 'api/v1/klines');
+ }
+
+ ticker24hr(query = {}, callback) {
+ if (_.isString(query)) {
+ query = { symbol: query };
+ }
+
+ return this._makeRequest(query, callback, 'api/v1/ticker/24hr');
+ }
+
+ tickerPrice(query = {}, callback) {
+ if (_.isString(query)) {
+ query = { symbol: query };
+ }
+
+ return this._makeRequest(query, callback, 'api/v3/ticker/price');
+ }
+
+ bookTicker(query = {}, callback) {
+ if (_.isString(query)) {
+ query = { symbol: query };
+ }
+
+ return this._makeRequest(query, callback, 'api/v3/ticker/bookTicker');
+ }
+
+ allBookTickers(callback) {
+ return this._makeRequest({}, callback, 'api/v1/ticker/allBookTickers');
+ }
+
+ allPrices(callback) {
+ return this._makeRequest({}, callback, 'api/v1/ticker/allPrices');
+ }
+
+ // Private APIs
+ newOrder(query = {}, callback) {
+ this._setTimestamp(query);
+ return this._makeRequest(query, callback, 'api/v3/order', 'SIGNED', 'POST');
+ }
+
+ testOrder(query = {}, callback) {
+ this._setTimestamp(query);
+ return this._makeRequest(query, callback, 'api/v3/order/test', 'SIGNED', 'POST');
+ }
+
+ queryOrder(query = {}, callback) {
+ this._setTimestamp(query);
+ return this._makeRequest(query, callback, 'api/v3/order', 'SIGNED');
+ }
+
+ cancelOrder(query = {}, callback) {
+ this._setTimestamp(query);
+ return this._makeRequest(query, callback, 'api/v3/order', 'SIGNED', 'DELETE');
+ }
+
+ openOrders(query = {}, callback) {
+ if (_.isString(query)) {
+ query = { symbol: query };
+ }
+ this._setTimestamp(query);
+ return this._makeRequest(query, callback, 'api/v3/openOrders', 'SIGNED');
+ }
+
+ allOrders(query = {}, callback) {
+ if (_.isString(query)) {
+ query = { symbol: query };
+ }
+ this._setTimestamp(query);
+ return this._makeRequest(query, callback, 'api/v3/allOrders', 'SIGNED');
+ }
+
+ account(query = {}, callback) {
+ if (_.isFunction(query)) {
+ callback = query;
+ query = {};
+ }
+ this._setTimestamp(query);
+ return this._makeRequest(query, callback, 'api/v3/account', 'SIGNED');
+ }
+
+ myTrades(query = {}, callback) {
+ if (_.isString(query)) {
+ query = { symbol: query };
+ }
+ this._setTimestamp(query);
+ return this._makeRequest(query, callback, 'api/v3/myTrades', 'SIGNED');
+ }
+
+ withdraw(query = {}, callback) {
+ this._setTimestamp(query);
+ return this._makeRequest(query, callback, 'wapi/v3/withdraw.html', 'SIGNED', 'POST');
+ }
+
+ depositHistory(query = {}, callback) {
+ if (_.isString(query)) {
+ query = { asset: query };
+ }
+ this._setTimestamp(query);
+ return this._makeRequest(query, callback, 'wapi/v3/depositHistory.html', 'SIGNED');
+ }
+
+ withdrawHistory(query = {}, callback) {
+ if (_.isString(query)) {
+ query = { asset: query };
+ }
+ this._setTimestamp(query);
+ return this._makeRequest(query, callback, 'wapi/v3/withdrawHistory.html', 'SIGNED');
+ }
+
+ depositAddress(query = {}, callback) {
+ if (_.isString(query)) {
+ query = { asset: query };
+ }
+ this._setTimestamp(query);
+ return this._makeRequest(query, callback, 'wapi/v3/depositAddress.html', 'SIGNED');
+ }
+
+ accountStatus(callback) {
+ const query = {};
+ this._setTimestamp(query);
+ return this._makeRequest(query, callback, 'wapi/v3/accountStatus.html', 'SIGNED');
+ }
+
+ startUserDataStream(callback) {
+ return this._makeRequest({}, callback, 'api/v1/userDataStream', 'API-KEY', 'POST');
+ }
+
+ keepAliveUserDataStream(query = {}, callback) {
+ return this._makeRequest(query, callback, 'api/v1/userDataStream', 'API-KEY', 'PUT');
+ }
+
+ closeUserDataStream(query = {}, callback) {
+ return this._makeRequest(query, callback, 'api/v1/userDataStream', 'API-KEY', 'DELETE');
+ }
+}
+
+module.exports = BinanceRest;
\ No newline at end of file
diff --git a/Server/Exchange/Wrappers/binanceClient.js b/Server/Exchange/Wrappers/binanceClient.js
new file mode 100644
index 000000000..a46ca7d24
--- /dev/null
+++ b/Server/Exchange/Wrappers/binanceClient.js
@@ -0,0 +1,360 @@
+exports.newAPIClient = function newAPIClient(pKey, pSecret, logger) {
+
+ /*
+ /* ATENTION: This Library is used both a the cloud (AACloud) and also at the AAWeb on the server side without any modifications.
+ /* There is a second version, stripped of all the inner functionality that runs at AAWeb browser side, which channels the requests to the server side one.
+ */
+
+ const FULL_LOG = true;
+ const LOG_FILE_CONTENT = true;
+ const MODULE_NAME = "binanceClient";
+
+ const retry = require('../exchangeUtils').retry;
+ const includes = require('../exchangeUtils').includes;
+ const _ = require('lodash');
+ const Binance = require("./binance");
+ const exchangeProperties = require('./poloniexProperties.json');
+
+ const recoverableErrors = [
+ 'SOCKETTIMEDOUT',
+ 'TIMEDOUT',
+ 'CONNRESET',
+ 'CONNREFUSED',
+ 'NOTFOUND',
+ 'Error -1021',
+ 'Response code 429',
+ 'Response code 5',
+ 'ETIMEDOUT'
+ ];
+
+ let API = new Binance({
+ key: pKey,
+ secret: pSecret,
+ timeout: 15000,
+ recvWindow: 60000,
+ disableBeautification: false,
+ handleDrift: true,
+ });
+
+ let thisObject = {
+ getTicker: getTicker,
+ getOpenPositions: getOpenPositions,
+ getExecutedTrades: getExecutedTrades,
+ buy: buy,
+ sell: sell,
+ movePosition: movePosition,
+ getPublicTradeHistory: getPublicTradeHistory,
+ getExchangeProperties: getExchangeProperties,
+ isValidPrice: isValidPrice,
+ isValidLot: isValidLot
+ };
+
+ return thisObject;
+
+ function joinCurrencies(currencyA, currencyB) {
+ // If only one arg, then return the first
+ if (typeof currencyB !== 'string') {
+ return currencyA;
+ }
+
+ return currencyB + '' + currencyA;
+ }
+
+ /*
+ * Returns the properties for this exchange
+ */
+ function getExchangeProperties() {
+ return exchangeProperties;
+ }
+
+ function truncDecimals(pFloatValue) {
+
+ let decimals = 6;
+
+ return parseFloat(parseFloat(pFloatValue).toFixed(decimals));
+
+ }
+
+ /*
+ * Returns the price for a given pair of assets.
+ * The object returned is an array of trades:
+ * ticker = {
+ * bid, Number
+ * ask, Number
+ * last Number
+ * };
+ */
+ function getTicker(pMarket, callBack) {
+
+ let market = joinCurrencies(pMarket.assetA, pMarket.assetB);
+ const handle = (err, response) => {
+ let ticker;
+ if (err.result === global.DEFAULT_OK_RESPONSE.result) {
+ ticker = {
+ bid: Number(response.bidPrice),
+ ask: Number(response.askPrice),
+ last: Number(response.lastPrice)
+ };
+ }
+ callBack(err, ticker);
+ };
+
+ const fetch = next => API.ticker24hr(market, analizeResponse(next));
+
+ retry(null, fetch, handle);
+ }
+
+ /*
+ * Returns the open positions ath the exchange for a given market and user account.
+ * The object returned is an array of positions:
+ * position = {
+ * id,
+ * type,
+ * rate, Number
+ * amountA, Number
+ * amountB, Number
+ * fee, (not required) Number
+ * datetime
+ * };
+ */
+ function getOpenPositions(pMarket, callBack) {
+
+ let market = joinCurrencies(pMarket.assetA, pMarket.assetB);
+ const handle = (err, response) => {
+ let exchangePositions = [];
+ if (err.result === global.DEFAULT_OK_RESPONSE.result) {
+ for (let i = 0; i < response.length; i++) {
+ let openPosition = {
+ id: response[i].orderId,
+ type: response[i].side.toLowerCase(),
+ rate: Number(response[i].price),
+ amountA: truncDecimals(response[i].origQty * response[i].price),
+ amountB: Number(response[i].origQty),
+ date: (new Date(response[i].time)).valueOf()
+ };
+ exchangePositions.push(openPosition);
+ }
+ }
+ callBack(err, exchangePositions);
+ };
+
+ const fetch = next => API.openOrders(market, analizeResponse(next));
+
+ retry(null, fetch, handle);
+ }
+
+ /*
+ * Returns the trades for a given order number.
+ * The object returned is an array of positions:
+ * position = {
+ * id,
+ * type,
+ * rate, Number
+ * amountA, Number
+ * amountB, Number
+ * fee, Number
+ * datetime
+ * };
+ */
+ function getExecutedTrades(pPositionId, callBack) {
+
+ let market = joinCurrencies(global.MARKET.assetA, global.MARKET.assetB);
+ const handle = (err, response) => {
+ let exchangeTrades = [];
+ if (err.result === global.DEFAULT_OK_RESPONSE.result) {
+ for (let i = 0; i < response.length; i++) {
+ if (response[i].orderId === pPositionId) {
+ let type = "sell"
+ if (response[i].isBuyer === true) {
+ type = "buy";
+ }
+ let trade = {
+ id: response[i].orderId,
+ type: type,
+ rate: Number(response[i].price),
+ amountA: truncDecimals(response[i].qty * response[i].price),
+ amountB: Number(response[i].qty),
+ fee: Number(response[i].commission),
+ date: (new Date(response[i].time)).valueOf()
+ };
+ exchangeTrades.push(trade);
+ break;
+ }
+ }
+ }
+ callBack(err, exchangeTrades);
+ };
+
+ const fetch = next => API.myTrades(market, analizeResponse(next));
+
+ retry(null, fetch, handle);
+ }
+
+ /*
+ * Creates a new buy order.
+ * The orderNumber is returned.
+ */
+ function buy(pCurrencyA, pCurrencyB, pRate, pAmount, callBack) {
+
+ var parameters = {
+ symbol: joinCurrencies(pCurrencyA, pCurrencyB),
+ side: 'BUY',
+ type: 'LIMIT',
+ quantity: pAmount,
+ price: pRate,
+ timeInForce: 'GTC'
+ };
+ const handle = (err, response) => {
+ let orderNumber;
+ if (err.result === global.DEFAULT_OK_RESPONSE.result) {
+ orderNumber = response.orderId;
+ }
+ callBack(err, orderNumber);
+ };
+
+ const fetch = next => API.newOrder(parameters, analizeResponse(next));
+
+ retry(null, fetch, handle);
+
+ }
+
+ /*
+ * Creates a new sell order.
+ * The orderNumber is returned. String
+ */
+ function sell(pCurrencyA, pCurrencyB, pRate, pAmount, callBack) {
+
+ var parameters = {
+ symbol: joinCurrencies(pCurrencyA, pCurrencyB),
+ side: 'SELL',
+ type: 'LIMIT',
+ quantity: pAmount,
+ price: pRate,
+ timeInForce: 'GTC'
+ };
+ const handle = (err, response) => {
+ let orderNumber;
+ if (err.result === global.DEFAULT_OK_RESPONSE.result) {
+ orderNumber = response.orderId;
+ }
+ callBack(err, orderNumber);
+ };
+
+ const fetch = next => API.newOrder(parameters, analizeResponse(next));
+
+ retry(null, fetch, handle);
+ }
+
+ /* //TODO Complete partial orders
+ * Move an existing position to the new rate.
+ * The new orderNumber is returned. String
+ */
+ function movePosition(pPosition, pNewRate, pNewAmountB, callBack) {
+
+ var parameters = {
+ symbol: joinCurrencies(global.MARKET.assetA, global.MARKET.assetB),
+ orderId: pPosition.id
+ };
+
+ if (global.LOG_CONTROL[MODULE_NAME].logInfo === true) { logger.write(MODULE_NAME, "[INFO] moveOrder -> Step1 - Cancelling Position: " + JSON.stringify(pPosition)); }
+
+ const handle = (err, response) => {
+ if (err.result === global.DEFAULT_OK_RESPONSE.result) {
+ if (global.LOG_CONTROL[MODULE_NAME].logInfo === true) { logger.write(MODULE_NAME, "[INFO] moveOrder -> Step1 Complete - Position Cancelled. Proceeding to put the new position."); }
+
+ if (position.type === "buy")
+ thisObject.buy(global.MARKET.assetA, global.MARKET.assetB, pNewRate, pNewAmountB, callBack);
+ else
+ thisObject.sell(global.MARKET.assetA, global.MARKET.assetB, pNewRate, pNewAmountB, callBack);
+ } else {
+ callBack(err);
+ }
+ };
+
+ const fetch = next => API.cancelOrder(parameters, analizeResponse(next));
+
+ retry(null, fetch, handle);
+ }
+
+ /* //TODO Pending Review
+ * Returns all the trade history from the Exchange since startTime to endTime orderd by tradeId.
+ * It's possible that the exchange doesn't support this method.
+ * The object returned is an array of trades:
+ * trade = {
+ * tradeIdAtExchange,
+ * marketIdAtExchange,
+ * type,
+ * rate, Number
+ * amountA, Number
+ * amountB, Number
+ * datetime
+ * };
+ */
+ function getPublicTradeHistory(assetA, assetB, startTime, endTime, callBack) {
+
+ if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] getPublicTradeHistory -> Not implemented yet."); }
+ callBack(global.DEFAULT_FAIL_RESPONSE);
+ }
+
+ function isValidPrice(price) {
+ return price >= market.minimalOrder.price;
+ }
+
+ function isValidLot(price, amount) {
+ return amount * price >= market.minimalOrder.order;
+ }
+
+ function analizeResponse(callBack) {
+
+ return (exchangeErr, exchangeResponse) => {
+ let error;
+
+ /* This function analizes the different situations we might encounter trying to access Poloniex and returns appropiate standard errors. */
+
+ let stringExchangeErr = JSON.stringify(exchangeErr);
+ let stringExchangeResponse = JSON.stringify(exchangeResponse);
+
+ try {
+ if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] analizeResponse -> exchangeErr = " + stringExchangeErr); }
+ if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] analizeResponse -> exchangeResponse = " + stringExchangeResponse); }
+
+ if (exchangeErr) {
+ error = global.DEFAULT_FAIL_RESPONSE;
+ } else if (!exchangeResponse) {
+ error = {
+ result: global.DEFAULT_FAIL_RESPONSE.result,
+ message: 'Empty response'
+ };
+ } else if (includes(exchangeResponse.error, [''])) {
+ error = {
+ result: global.DEFAULT_FAIL_RESPONSE.result,
+ message: exchangeResponse
+ };
+ } else if (includes(exchangeResponse.error, ['Order does not exist.'])) {
+ error = {
+ result: global.CUSTOM_OK_RESPONSE.result,
+ message: exchangeResponse.error
+ };
+ } else if (exchangeResponse.error) {
+ error = {
+ result: global.DEFAULT_FAIL_RESPONSE.result,
+ message: exchangeResponse.error
+ };
+ }
+
+ if (error) {
+ if (includes(error.message, recoverableErrors)) {
+ error.notFatal = true;
+ }
+ }
+
+ return callBack(error, exchangeResponse);
+
+ } catch (err) {
+ logger.write(MODULE_NAME, "[ERROR] analizeResponse -> err.message = " + err.message);
+ return callBack(global.DEFAULT_FAIL_RESPONSE, exchangeResponse);
+ }
+ }
+ }
+
+}
diff --git a/Server/Exchange/Wrappers/binanceProperties.json b/Server/Exchange/Wrappers/binanceProperties.json
new file mode 100644
index 000000000..ad4438de0
--- /dev/null
+++ b/Server/Exchange/Wrappers/binanceProperties.json
@@ -0,0 +1,4594 @@
+{
+ "assets": [
+ "NULS",
+ "VEN",
+ "BNB",
+ "NEO",
+ "LINK",
+ "SALT",
+ "IOTA",
+ "ETC",
+ "AST",
+ "KNC",
+ "WTC",
+ "SNGLS",
+ "EOS",
+ "SNT",
+ "MCO",
+ "BTC",
+ "OAX",
+ "OMG",
+ "GAS",
+ "BQX",
+ "QTUM",
+ "BNT",
+ "DNT",
+ "ICN",
+ "SNM",
+ "STRAT",
+ "ZRX",
+ "FUN",
+ "LTC",
+ "ETH",
+ "XVG",
+ "BCC",
+ "ADA",
+ "ADX",
+ "AE",
+ "AGI",
+ "AION",
+ "AMB",
+ "APPC",
+ "ARK",
+ "ARN",
+ "BAT",
+ "BCD",
+ "BCN",
+ "BCPT",
+ "BLZ",
+ "BRD",
+ "BTG",
+ "BTS",
+ "CDT",
+ "CHAT",
+ "CLOAK",
+ "CMT",
+ "CND",
+ "CVC",
+ "DASH",
+ "DATA",
+ "DENT",
+ "DGD",
+ "DLT",
+ "EDO",
+ "ELF",
+ "ENG",
+ "ENJ",
+ "EVX",
+ "FUEL",
+ "GNT",
+ "GRS",
+ "GTO",
+ "GVT",
+ "GXS",
+ "HSR",
+ "ICX",
+ "INS",
+ "IOST",
+ "IOTX",
+ "KEY",
+ "KMD",
+ "LEND",
+ "LOOM",
+ "LRC",
+ "LSK",
+ "LUN",
+ "MANA",
+ "MDA",
+ "MFT",
+ "MOD",
+ "MTH",
+ "MTL",
+ "NANO",
+ "NAS",
+ "NAV",
+ "NCASH",
+ "NEBL",
+ "NPXS",
+ "NXS",
+ "ONT",
+ "OST",
+ "PIVX",
+ "POA",
+ "POE",
+ "POWR",
+ "PPT",
+ "QKC",
+ "QLC",
+ "QSP",
+ "RCN",
+ "RDN",
+ "REP",
+ "REQ",
+ "RLC",
+ "RPX",
+ "SC",
+ "SKY",
+ "STEEM",
+ "STORJ",
+ "STORM",
+ "SUB",
+ "SYS",
+ "THETA",
+ "TNB",
+ "TNT",
+ "TRIG",
+ "TRX",
+ "TUSD",
+ "VIA",
+ "VIB",
+ "VIBE",
+ "WABI",
+ "WAN",
+ "WAVES",
+ "WINGS",
+ "WPR",
+ "XEM",
+ "XLM",
+ "XMR",
+ "XRP",
+ "XZC",
+ "YOYO",
+ "ZEC",
+ "ZEN",
+ "ZIL"
+ ],
+ "currencies": [
+ "BNB",
+ "BTC",
+ "ETH",
+ "USDT"
+ ],
+ "markets": [
+ {
+ "pair": [
+ "BNB",
+ "NULS"
+ ],
+ "maxDecimals": 6,
+ "minimalOrder": {
+ "amount": 0.01,
+ "price": 0.00001,
+ "order": 1
+ }
+ },
+ {
+ "pair": [
+ "BNB",
+ "VEN"
+ ],
+ "maxDecimals": 6,
+ "minimalOrder": {
+ "amount": 0.01,
+ "price": 0.0001,
+ "order": 1
+ }
+ },
+ {
+ "pair": [
+ "BTC",
+ "BNB"
+ ],
+ "maxDecimals": 6,
+ "minimalOrder": {
+ "amount": 0.01,
+ "price": 1e-7,
+ "order": 0.001
+ }
+ },
+ {
+ "pair": [
+ "BTC",
+ "NULS"
+ ],
+ "maxDecimals": 6,
+ "minimalOrder": {
+ "amount": 1,
+ "price": 1e-8,
+ "order": 0.001
+ }
+ },
+ {
+ "pair": [
+ "BTC",
+ "NEO"
+ ],
+ "maxDecimals": 6,
+ "minimalOrder": {
+ "amount": 0.01,
+ "price": 0.000001,
+ "order": 0.001
+ }
+ },
+ {
+ "pair": [
+ "ETH",
+ "NULS"
+ ],
+ "maxDecimals": 6,
+ "minimalOrder": {
+ "amount": 1,
+ "price": 1e-8,
+ "order": 0.01
+ }
+ },
+ {
+ "pair": [
+ "BTC",
+ "LINK"
+ ],
+ "maxDecimals": 6,
+ "minimalOrder": {
+ "amount": 1,
+ "price": 1e-8,
+ "order": 0.001
+ }
+ },
+ {
+ "pair": [
+ "BTC",
+ "SALT"
+ ],
+ "maxDecimals": 6,
+ "minimalOrder": {
+ "amount": 0.01,
+ "price": 1e-7,
+ "order": 0.001
+ }
+ },
+ {
+ "pair": [
+ "BTC",
+ "IOTA"
+ ],
+ "maxDecimals": 6,
+ "minimalOrder": {
+ "amount": 1,
+ "price": 1e-8,
+ "order": 0.001
+ }
+ },
+ {
+ "pair": [
+ "BTC",
+ "ETC"
+ ],
+ "maxDecimals": 6,
+ "minimalOrder": {
+ "amount": 0.01,
+ "price": 0.000001,
+ "order": 0.001
+ }
+ },
+ {
+ "pair": [
+ "ETH",
+ "AST"
+ ],
+ "maxDecimals": 6,
+ "minimalOrder": {
+ "amount": 1,
+ "price": 1e-7,
+ "order": 0.01
+ }
+ },
+ {
+ "pair": [
+ "BTC",
+ "KNC"
+ ],
+ "maxDecimals": 6,
+ "minimalOrder": {
+ "amount": 1,
+ "price": 1e-8,
+ "order": 0.001
+ }
+ },
+ {
+ "pair": [
+ "BTC",
+ "WTC"
+ ],
+ "maxDecimals": 6,
+ "minimalOrder": {
+ "amount": 0.01,
+ "price": 1e-7,
+ "order": 0.001
+ }
+ },
+ {
+ "pair": [
+ "BTC",
+ "SNGLS"
+ ],
+ "maxDecimals": 6,
+ "minimalOrder": {
+ "amount": 1,
+ "price": 1e-8,
+ "order": 0.001
+ }
+ },
+ {
+ "pair": [
+ "ETH",
+ "EOS"
+ ],
+ "maxDecimals": 6,
+ "minimalOrder": {
+ "amount": 0.01,
+ "price": 0.000001,
+ "order": 0.01
+ }
+ },
+ {
+ "pair": [
+ "ETH",
+ "SNT"
+ ],
+ "maxDecimals": 6,
+ "minimalOrder": {
+ "amount": 1,
+ "price": 1e-8,
+ "order": 0.01
+ }
+ },
+ {
+ "pair": [
+ "ETH",
+ "MCO"
+ ],
+ "maxDecimals": 6,
+ "minimalOrder": {
+ "amount": 0.01,
+ "price": 0.000001,
+ "order": 0.01
+ }
+ },
+ {
+ "pair": [
+ "USDT",
+ "BTC"
+ ],
+ "maxDecimals": 6,
+ "minimalOrder": {
+ "amount": 0.000001,
+ "price": 0.01,
+ "order": 10
+ }
+ },
+ {
+ "pair": [
+ "ETH",
+ "OAX"
+ ],
+ "maxDecimals": 6,
+ "minimalOrder": {
+ "amount": 1,
+ "price": 1e-7,
+ "order": 0.01
+ }
+ },
+ {
+ "pair": [
+ "ETH",
+ "OMG"
+ ],
+ "maxDecimals": 6,
+ "minimalOrder": {
+ "amount": 0.01,
+ "price": 0.000001,
+ "order": 0.01
+ }
+ },
+ {
+ "pair": [
+ "BTC",
+ "GAS"
+ ],
+ "maxDecimals": 6,
+ "minimalOrder": {
+ "amount": 0.01,
+ "price": 0.000001,
+ "order": 0.001
+ }
+ },
+ {
+ "pair": [
+ "ETH",
+ "BQX"
+ ],
+ "maxDecimals": 6,
+ "minimalOrder": {
+ "amount": 1,
+ "price": 1e-7,
+ "order": 0.01
+ }
+ },
+ {
+ "pair": [
+ "ETH",
+ "WTC"
+ ],
+ "maxDecimals": 6,
+ "minimalOrder": {
+ "amount": 0.01,
+ "price": 0.000001,
+ "order": 0.01
+ }
+ },
+ {
+ "pair": [
+ "ETH",
+ "QTUM"
+ ],
+ "maxDecimals": 6,
+ "minimalOrder": {
+ "amount": 0.01,
+ "price": 0.000001,
+ "order": 0.01
+ }
+ },
+ {
+ "pair": [
+ "ETH",
+ "BNT"
+ ],
+ "maxDecimals": 6,
+ "minimalOrder": {
+ "amount": 0.01,
+ "price": 0.000001,
+ "order": 0.01
+ }
+ },
+ {
+ "pair": [
+ "ETH",
+ "DNT"
+ ],
+ "maxDecimals": 6,
+ "minimalOrder": {
+ "amount": 1,
+ "price": 1e-8,
+ "order": 0.01
+ }
+ },
+ {
+ "pair": [
+ "ETH",
+ "ICN"
+ ],
+ "maxDecimals": 6,
+ "minimalOrder": {
+ "amount": 1,
+ "price": 1e-7,
+ "order": 0.01
+ }
+ },
+ {
+ "pair": [
+ "BTC",
+ "SNM"
+ ],
+ "maxDecimals": 6,
+ "minimalOrder": {
+ "amount": 1,
+ "price": 1e-8,
+ "order": 0.001
+ }
+ },
+ {
+ "pair": [
+ "ETH",
+ "SNM"
+ ],
+ "maxDecimals": 6,
+ "minimalOrder": {
+ "amount": 1,
+ "price": 1e-8,
+ "order": 0.01
+ }
+ },
+ {
+ "pair": [
+ "ETH",
+ "SNGLS"
+ ],
+ "maxDecimals": 6,
+ "minimalOrder": {
+ "amount": 1,
+ "price": 1e-8,
+ "order": 0.01
+ }
+ },
+ {
+ "pair": [
+ "BTC",
+ "BQX"
+ ],
+ "maxDecimals": 6,
+ "minimalOrder": {
+ "amount": 1,
+ "price": 1e-8,
+ "order": 0.001
+ }
+ },
+ {
+ "pair": [
+ "ETH",
+ "NEO"
+ ],
+ "maxDecimals": 6,
+ "minimalOrder": {
+ "amount": 0.01,
+ "price": 0.000001,
+ "order": 0.01
+ }
+ },
+ {
+ "pair": [
+ "ETH",
+ "KNC"
+ ],
+ "maxDecimals": 6,
+ "minimalOrder": {
+ "amount": 1,
+ "price": 1e-7,
+ "order": 0.01
+ }
+ },
+ {
+ "pair": [
+ "ETH",
+ "STRAT"
+ ],
+ "maxDecimals": 6,
+ "minimalOrder": {
+ "amount": 0.01,
+ "price": 0.000001,
+ "order": 0.01
+ }
+ },
+ {
+ "pair": [
+ "ETH",
+ "ZRX"
+ ],
+ "maxDecimals": 6,
+ "minimalOrder": {
+ "amount": 1,
+ "price": 1e-8,
+ "order": 0.01
+ }
+ },
+ {
+ "pair": [
+ "BTC",
+ "QTUM"
+ ],
+ "maxDecimals": 6,
+ "minimalOrder": {
+ "amount": 0.01,
+ "price": 0.000001,
+ "order": 0.001
+ }
+ },
+ {
+ "pair": [
+ "ETH",
+ "FUN"
+ ],
+ "maxDecimals": 6,
+ "minimalOrder": {
+ "amount": 1,
+ "price": 1e-8,
+ "order": 0.01
+ }
+ },
+ {
+ "pair": [
+ "BTC",
+ "LTC"
+ ],
+ "maxDecimals": 6,
+ "minimalOrder": {
+ "amount": 0.01,
+ "price": 0.000001,
+ "order": 0.001
+ }
+ },
+ {
+ "pair": [
+ "ETH",
+ "LINK"
+ ],
+ "maxDecimals": 6,
+ "minimalOrder": {
+ "amount": 1,
+ "price": 1e-8,
+ "order": 0.01
+ }
+ },
+ {
+ "pair": [
+ "BTC",
+ "ETH"
+ ],
+ "maxDecimals": 6,
+ "minimalOrder": {
+ "amount": 0.001,
+ "price": 0.000001,
+ "order": 0.001
+ }
+ },
+ {
+ "pair": [
+ "ETH",
+ "XVG"
+ ],
+ "maxDecimals": 6,
+ "minimalOrder": {
+ "amount": 1,
+ "price": 1e-8,
+ "order": 0.01
+ }
+ },
+ {
+ "pair": [
+ "BTC",
+ "STRAT"
+ ],
+ "maxDecimals": 6,
+ "minimalOrder": {
+ "amount": 0.01,
+ "price": 1e-7,
+ "order": 0.001
+ }
+ },
+ {
+ "pair": [
+ "BTC",
+ "ZRX"
+ ],
+ "maxDecimals": 6,
+ "minimalOrder": {
+ "amount": 1,
+ "price": 1e-8,
+ "order": 0.001
+ }
+ },
+ {
+ "pair": [
+ "ETH",
+ "IOTA"
+ ],
+ "maxDecimals": 6,
+ "minimalOrder": {
+ "amount": 1,
+ "price": 1e-8,
+ "order": 0.01
+ }
+ },
+ {
+ "pair": [
+ "BTC",
+ "BCC"
+ ],
+ "maxDecimals": 6,
+ "minimalOrder": {
+ "amount": 0.001,
+ "price": 0.000001,
+ "order": 0.001
+ }
+ },
+ {
+ "pair": [
+ "BTC",
+ "OMG"
+ ],
+ "maxDecimals": 6,
+ "minimalOrder": {
+ "amount": 0.01,
+ "price": 0.000001,
+ "order": 0.001
+ }
+ },
+ {
+ "pair": [
+ "BTC",
+ "MCO"
+ ],
+ "maxDecimals": 6,
+ "minimalOrder": {
+ "amount": 0.01,
+ "price": 0.000001,
+ "order": 0.001
+ }
+ },
+ {
+ "pair": [
+ "ETH",
+ "SALT"
+ ],
+ "maxDecimals": 6,
+ "minimalOrder": {
+ "amount": 0.01,
+ "price": 0.000001,
+ "order": 0.01
+ }
+ },
+ {
+ "pair": [
+ "BNB",
+ "ADA"
+ ],
+ "maxDecimals": 6,
+ "minimalOrder": {
+ "amount": 0.01,
+ "price": 0.00001,
+ "order": 1
+ }
+ },
+ {
+ "pair": [
+ "BTC",
+ "ADA"
+ ],
+ "maxDecimals": 6,
+ "minimalOrder": {
+ "amount": 1,
+ "price": 1e-8,
+ "order": 0.001
+ }
+ },
+ {
+ "pair": [
+ "ETH",
+ "ADA"
+ ],
+ "maxDecimals": 6,
+ "minimalOrder": {
+ "amount": 1,
+ "price": 1e-8,
+ "order": 0.01
+ }
+ },
+ {
+ "pair": [
+ "USDT",
+ "ADA"
+ ],
+ "maxDecimals": 6,
+ "minimalOrder": {
+ "amount": 0.1,
+ "price": 0.00001,
+ "order": 10
+ }
+ },
+ {
+ "pair": [
+ "BNB",
+ "ADX"
+ ],
+ "maxDecimals": 6,
+ "minimalOrder": {
+ "amount": 0.01,
+ "price": 0.00001,
+ "order": 1
+ }
+ },
+ {
+ "pair": [
+ "BTC",
+ "ADX"
+ ],
+ "maxDecimals": 6,
+ "minimalOrder": {
+ "amount": 1,
+ "price": 1e-8,
+ "order": 0.001
+ }
+ },
+ {
+ "pair": [
+ "ETH",
+ "ADX"
+ ],
+ "maxDecimals": 6,
+ "minimalOrder": {
+ "amount": 1,
+ "price": 1e-7,
+ "order": 0.01
+ }
+ },
+ {
+ "pair": [
+ "BNB",
+ "AE"
+ ],
+ "maxDecimals": 6,
+ "minimalOrder": {
+ "amount": 0.01,
+ "price": 0.00001,
+ "order": 1
+ }
+ },
+ {
+ "pair": [
+ "BTC",
+ "AE"
+ ],
+ "maxDecimals": 6,
+ "minimalOrder": {
+ "amount": 0.01,
+ "price": 1e-7,
+ "order": 0.001
+ }
+ },
+ {
+ "pair": [
+ "ETH",
+ "AE"
+ ],
+ "maxDecimals": 6,
+ "minimalOrder": {
+ "amount": 0.01,
+ "price": 0.000001,
+ "order": 0.01
+ }
+ },
+ {
+ "pair": [
+ "BNB",
+ "AGI"
+ ],
+ "maxDecimals": 6,
+ "minimalOrder": {
+ "amount": 0.01,
+ "price": 0.00001,
+ "order": 1
+ }
+ },
+ {
+ "pair": [
+ "BTC",
+ "AGI"
+ ],
+ "maxDecimals": 6,
+ "minimalOrder": {
+ "amount": 1,
+ "price": 1e-8,
+ "order": 0.001
+ }
+ },
+ {
+ "pair": [
+ "ETH",
+ "AGI"
+ ],
+ "maxDecimals": 6,
+ "minimalOrder": {
+ "amount": 1,
+ "price": 1e-8,
+ "order": 0.01
+ }
+ },
+ {
+ "pair": [
+ "BNB",
+ "AION"
+ ],
+ "maxDecimals": 6,
+ "minimalOrder": {
+ "amount": 0.01,
+ "price": 0.00001,
+ "order": 1
+ }
+ },
+ {
+ "pair": [
+ "BTC",
+ "AION"
+ ],
+ "maxDecimals": 6,
+ "minimalOrder": {
+ "amount": 0.01,
+ "price": 1e-7,
+ "order": 0.001
+ }
+ },
+ {
+ "pair": [
+ "ETH",
+ "AION"
+ ],
+ "maxDecimals": 6,
+ "minimalOrder": {
+ "amount": 0.01,
+ "price": 0.000001,
+ "order": 0.01
+ }
+ },
+ {
+ "pair": [
+ "BNB",
+ "AMB"
+ ],
+ "maxDecimals": 6,
+ "minimalOrder": {
+ "amount": 0.01,
+ "price": 0.00001,
+ "order": 1
+ }
+ },
+ {
+ "pair": [
+ "BTC",
+ "AMB"
+ ],
+ "maxDecimals": 6,
+ "minimalOrder": {
+ "amount": 1,
+ "price": 1e-8,
+ "order": 0.001
+ }
+ },
+ {
+ "pair": [
+ "ETH",
+ "AMB"
+ ],
+ "maxDecimals": 6,
+ "minimalOrder": {
+ "amount": 1,
+ "price": 1e-8,
+ "order": 0.01
+ }
+ },
+ {
+ "pair": [
+ "BNB",
+ "APPC"
+ ],
+ "maxDecimals": 6,
+ "minimalOrder": {
+ "amount": 0.01,
+ "price": 0.00001,
+ "order": 1
+ }
+ },
+ {
+ "pair": [
+ "BTC",
+ "APPC"
+ ],
+ "maxDecimals": 6,
+ "minimalOrder": {
+ "amount": 1,
+ "price": 1e-8,
+ "order": 0.001
+ }
+ },
+ {
+ "pair": [
+ "ETH",
+ "APPC"
+ ],
+ "maxDecimals": 6,
+ "minimalOrder": {
+ "amount": 1,
+ "price": 1e-7,
+ "order": 0.01
+ }
+ },
+ {
+ "pair": [
+ "BTC",
+ "ARK"
+ ],
+ "maxDecimals": 6,
+ "minimalOrder": {
+ "amount": 0.01,
+ "price": 1e-7,
+ "order": 0.001
+ }
+ },
+ {
+ "pair": [
+ "ETH",
+ "ARK"
+ ],
+ "maxDecimals": 6,
+ "minimalOrder": {
+ "amount": 0.01,
+ "price": 0.000001,
+ "order": 0.01
+ }
+ },
+ {
+ "pair": [
+ "BTC",
+ "ARN"
+ ],
+ "maxDecimals": 6,
+ "minimalOrder": {
+ "amount": 1,
+ "price": 1e-8,
+ "order": 0.001
+ }
+ },
+ {
+ "pair": [
+ "ETH",
+ "ARN"
+ ],
+ "maxDecimals": 6,
+ "minimalOrder": {
+ "amount": 1,
+ "price": 1e-8,
+ "order": 0.01
+ }
+ },
+ {
+ "pair": [
+ "BTC",
+ "AST"
+ ],
+ "maxDecimals": 6,
+ "minimalOrder": {
+ "amount": 1,
+ "price": 1e-8,
+ "order": 0.001
+ }
+ },
+ {
+ "pair": [
+ "BNB",
+ "BAT"
+ ],
+ "maxDecimals": 6,
+ "minimalOrder": {
+ "amount": 0.01,
+ "price": 0.00001,
+ "order": 1
+ }
+ },
+ {
+ "pair": [
+ "BTC",
+ "BAT"
+ ],
+ "maxDecimals": 6,
+ "minimalOrder": {
+ "amount": 1,
+ "price": 1e-8,
+ "order": 0.001
+ }
+ },
+ {
+ "pair": [
+ "ETH",
+ "BAT"
+ ],
+ "maxDecimals": 6,
+ "minimalOrder": {
+ "amount": 1,
+ "price": 1e-8,
+ "order": 0.01
+ }
+ },
+ {
+ "pair": [
+ "BNB",
+ "BCC"
+ ],
+ "maxDecimals": 6,
+ "minimalOrder": {
+ "amount": 0.00001,
+ "price": 0.01,
+ "order": 1
+ }
+ },
+ {
+ "pair": [
+ "ETH",
+ "BCC"
+ ],
+ "maxDecimals": 6,
+ "minimalOrder": {
+ "amount": 0.001,
+ "price": 0.00001,
+ "order": 0.01
+ }
+ },
+ {
+ "pair": [
+ "USDT",
+ "BCC"
+ ],
+ "maxDecimals": 6,
+ "minimalOrder": {
+ "amount": 0.00001,
+ "price": 0.01,
+ "order": 10
+ }
+ },
+ {
+ "pair": [
+ "BTC",
+ "BCD"
+ ],
+ "maxDecimals": 6,
+ "minimalOrder": {
+ "amount": 0.001,
+ "price": 0.000001,
+ "order": 0.001
+ }
+ },
+ {
+ "pair": [
+ "ETH",
+ "BCD"
+ ],
+ "maxDecimals": 6,
+ "minimalOrder": {
+ "amount": 0.001,
+ "price": 0.00001,
+ "order": 0.01
+ }
+ },
+ {
+ "pair": [
+ "BNB",
+ "BCN"
+ ],
+ "maxDecimals": 6,
+ "minimalOrder": {
+ "amount": 1,
+ "price": 0.000001,
+ "order": 1
+ }
+ },
+ {
+ "pair": [
+ "BTC",
+ "BCN"
+ ],
+ "maxDecimals": 6,
+ "minimalOrder": {
+ "amount": 1,
+ "price": 1e-8,
+ "order": 0.001
+ }
+ },
+ {
+ "pair": [
+ "ETH",
+ "BCN"
+ ],
+ "maxDecimals": 6,
+ "minimalOrder": {
+ "amount": 1,
+ "price": 1e-8,
+ "order": 0.01
+ }
+ },
+ {
+ "pair": [
+ "BNB",
+ "BCPT"
+ ],
+ "maxDecimals": 6,
+ "minimalOrder": {
+ "amount": 0.01,
+ "price": 0.00001,
+ "order": 1
+ }
+ },
+ {
+ "pair": [
+ "BTC",
+ "BCPT"
+ ],
+ "maxDecimals": 6,
+ "minimalOrder": {
+ "amount": 1,
+ "price": 1e-8,
+ "order": 0.001
+ }
+ },
+ {
+ "pair": [
+ "ETH",
+ "BCPT"
+ ],
+ "maxDecimals": 6,
+ "minimalOrder": {
+ "amount": 1,
+ "price": 1e-8,
+ "order": 0.01
+ }
+ },
+ {
+ "pair": [
+ "BNB",
+ "BLZ"
+ ],
+ "maxDecimals": 6,
+ "minimalOrder": {
+ "amount": 0.01,
+ "price": 0.00001,
+ "order": 1
+ }
+ },
+ {
+ "pair": [
+ "BTC",
+ "BLZ"
+ ],
+ "maxDecimals": 6,
+ "minimalOrder": {
+ "amount": 1,
+ "price": 1e-8,
+ "order": 0.001
+ }
+ },
+ {
+ "pair": [
+ "ETH",
+ "BLZ"
+ ],
+ "maxDecimals": 6,
+ "minimalOrder": {
+ "amount": 1,
+ "price": 1e-8,
+ "order": 0.01
+ }
+ },
+ {
+ "pair": [
+ "ETH",
+ "BNB"
+ ],
+ "maxDecimals": 6,
+ "minimalOrder": {
+ "amount": 0.01,
+ "price": 0.000001,
+ "order": 0.01
+ }
+ },
+ {
+ "pair": [
+ "BTC",
+ "BNT"
+ ],
+ "maxDecimals": 6,
+ "minimalOrder": {
+ "amount": 1,
+ "price": 1e-8,
+ "order": 0.001
+ }
+ },
+ {
+ "pair": [
+ "BNB",
+ "BRD"
+ ],
+ "maxDecimals": 6,
+ "minimalOrder": {
+ "amount": 0.01,
+ "price": 0.00001,
+ "order": 1
+ }
+ },
+ {
+ "pair": [
+ "BTC",
+ "BRD"
+ ],
+ "maxDecimals": 6,
+ "minimalOrder": {
+ "amount": 1,
+ "price": 1e-8,
+ "order": 0.001
+ }
+ },
+ {
+ "pair": [
+ "ETH",
+ "BRD"
+ ],
+ "maxDecimals": 6,
+ "minimalOrder": {
+ "amount": 1,
+ "price": 1e-7,
+ "order": 0.01
+ }
+ },
+ {
+ "pair": [
+ "BTC",
+ "BTG"
+ ],
+ "maxDecimals": 6,
+ "minimalOrder": {
+ "amount": 0.01,
+ "price": 0.000001,
+ "order": 0.001
+ }
+ },
+ {
+ "pair": [
+ "ETH",
+ "BTG"
+ ],
+ "maxDecimals": 6,
+ "minimalOrder": {
+ "amount": 0.01,
+ "price": 0.000001,
+ "order": 0.01
+ }
+ },
+ {
+ "pair": [
+ "BNB",
+ "BTS"
+ ],
+ "maxDecimals": 6,
+ "minimalOrder": {
+ "amount": 0.01,
+ "price": 0.00001,
+ "order": 1
+ }
+ },
+ {
+ "pair": [
+ "BTC",
+ "BTS"
+ ],
+ "maxDecimals": 6,
+ "minimalOrder": {
+ "amount": 1,
+ "price": 1e-8,
+ "order": 0.001
+ }
+ },
+ {
+ "pair": [
+ "ETH",
+ "BTS"
+ ],
+ "maxDecimals": 6,
+ "minimalOrder": {
+ "amount": 1,
+ "price": 1e-8,
+ "order": 0.01
+ }
+ },
+ {
+ "pair": [
+ "BTC",
+ "CDT"
+ ],
+ "maxDecimals": 6,
+ "minimalOrder": {
+ "amount": 1,
+ "price": 1e-8,
+ "order": 0.001
+ }
+ },
+ {
+ "pair": [
+ "ETH",
+ "CDT"
+ ],
+ "maxDecimals": 6,
+ "minimalOrder": {
+ "amount": 1,
+ "price": 1e-8,
+ "order": 0.01
+ }
+ },
+ {
+ "pair": [
+ "BTC",
+ "CHAT"
+ ],
+ "maxDecimals": 6,
+ "minimalOrder": {
+ "amount": 1,
+ "price": 1e-8,
+ "order": 0.001
+ }
+ },
+ {
+ "pair": [
+ "ETH",
+ "CHAT"
+ ],
+ "maxDecimals": 6,
+ "minimalOrder": {
+ "amount": 1,
+ "price": 1e-8,
+ "order": 0.01
+ }
+ },
+ {
+ "pair": [
+ "BTC",
+ "CLOAK"
+ ],
+ "maxDecimals": 6,
+ "minimalOrder": {
+ "amount": 0.01,
+ "price": 1e-7,
+ "order": 0.001
+ }
+ },
+ {
+ "pair": [
+ "ETH",
+ "CLOAK"
+ ],
+ "maxDecimals": 6,
+ "minimalOrder": {
+ "amount": 0.01,
+ "price": 0.000001,
+ "order": 0.01
+ }
+ },
+ {
+ "pair": [
+ "BNB",
+ "CMT"
+ ],
+ "maxDecimals": 6,
+ "minimalOrder": {
+ "amount": 0.01,
+ "price": 0.00001,
+ "order": 1
+ }
+ },
+ {
+ "pair": [
+ "BTC",
+ "CMT"
+ ],
+ "maxDecimals": 6,
+ "minimalOrder": {
+ "amount": 1,
+ "price": 1e-8,
+ "order": 0.001
+ }
+ },
+ {
+ "pair": [
+ "ETH",
+ "CMT"
+ ],
+ "maxDecimals": 6,
+ "minimalOrder": {
+ "amount": 1,
+ "price": 1e-8,
+ "order": 0.01
+ }
+ },
+ {
+ "pair": [
+ "BNB",
+ "CND"
+ ],
+ "maxDecimals": 6,
+ "minimalOrder": {
+ "amount": 1,
+ "price": 0.000001,
+ "order": 1
+ }
+ },
+ {
+ "pair": [
+ "BTC",
+ "CND"
+ ],
+ "maxDecimals": 6,
+ "minimalOrder": {
+ "amount": 1,
+ "price": 1e-8,
+ "order": 0.001
+ }
+ },
+ {
+ "pair": [
+ "ETH",
+ "CND"
+ ],
+ "maxDecimals": 6,
+ "minimalOrder": {
+ "amount": 1,
+ "price": 1e-8,
+ "order": 0.01
+ }
+ },
+ {
+ "pair": [
+ "BNB",
+ "CVC"
+ ],
+ "maxDecimals": 6,
+ "minimalOrder": {
+ "amount": 0.01,
+ "price": 0.00001,
+ "order": 1
+ }
+ },
+ {
+ "pair": [
+ "BTC",
+ "CVC"
+ ],
+ "maxDecimals": 6,
+ "minimalOrder": {
+ "amount": 1,
+ "price": 1e-8,
+ "order": 0.001
+ }
+ },
+ {
+ "pair": [
+ "ETH",
+ "CVC"
+ ],
+ "maxDecimals": 6,
+ "minimalOrder": {
+ "amount": 1,
+ "price": 1e-8,
+ "order": 0.01
+ }
+ },
+ {
+ "pair": [
+ "BTC",
+ "DASH"
+ ],
+ "maxDecimals": 6,
+ "minimalOrder": {
+ "amount": 0.001,
+ "price": 0.000001,
+ "order": 0.001
+ }
+ },
+ {
+ "pair": [
+ "ETH",
+ "DASH"
+ ],
+ "maxDecimals": 6,
+ "minimalOrder": {
+ "amount": 0.001,
+ "price": 0.00001,
+ "order": 0.01
+ }
+ },
+ {
+ "pair": [
+ "BTC",
+ "DATA"
+ ],
+ "maxDecimals": 6,
+ "minimalOrder": {
+ "amount": 1,
+ "price": 1e-8,
+ "order": 0.001
+ }
+ },
+ {
+ "pair": [
+ "ETH",
+ "DATA"
+ ],
+ "maxDecimals": 6,
+ "minimalOrder": {
+ "amount": 1,
+ "price": 1e-8,
+ "order": 0.01
+ }
+ },
+ {
+ "pair": [
+ "BTC",
+ "DENT"
+ ],
+ "maxDecimals": 6,
+ "minimalOrder": {
+ "amount": 1,
+ "price": 1e-8,
+ "order": 0.001
+ }
+ },
+ {
+ "pair": [
+ "ETH",
+ "DENT"
+ ],
+ "maxDecimals": 6,
+ "minimalOrder": {
+ "amount": 1,
+ "price": 1e-8,
+ "order": 0.01
+ }
+ },
+ {
+ "pair": [
+ "BTC",
+ "DGD"
+ ],
+ "maxDecimals": 6,
+ "minimalOrder": {
+ "amount": 0.001,
+ "price": 0.000001,
+ "order": 0.001
+ }
+ },
+ {
+ "pair": [
+ "ETH",
+ "DGD"
+ ],
+ "maxDecimals": 6,
+ "minimalOrder": {
+ "amount": 0.001,
+ "price": 0.00001,
+ "order": 0.01
+ }
+ },
+ {
+ "pair": [
+ "BNB",
+ "DLT"
+ ],
+ "maxDecimals": 6,
+ "minimalOrder": {
+ "amount": 0.01,
+ "price": 0.00001,
+ "order": 1
+ }
+ },
+ {
+ "pair": [
+ "BTC",
+ "DLT"
+ ],
+ "maxDecimals": 6,
+ "minimalOrder": {
+ "amount": 1,
+ "price": 1e-8,
+ "order": 0.001
+ }
+ },
+ {
+ "pair": [
+ "ETH",
+ "DLT"
+ ],
+ "maxDecimals": 6,
+ "minimalOrder": {
+ "amount": 1,
+ "price": 1e-8,
+ "order": 0.01
+ }
+ },
+ {
+ "pair": [
+ "BTC",
+ "DNT"
+ ],
+ "maxDecimals": 6,
+ "minimalOrder": {
+ "amount": 1,
+ "price": 1e-8,
+ "order": 0.001
+ }
+ },
+ {
+ "pair": [
+ "BTC",
+ "EDO"
+ ],
+ "maxDecimals": 6,
+ "minimalOrder": {
+ "amount": 0.01,
+ "price": 1e-7,
+ "order": 0.001
+ }
+ },
+ {
+ "pair": [
+ "ETH",
+ "EDO"
+ ],
+ "maxDecimals": 6,
+ "minimalOrder": {
+ "amount": 0.01,
+ "price": 0.000001,
+ "order": 0.01
+ }
+ },
+ {
+ "pair": [
+ "BTC",
+ "ELF"
+ ],
+ "maxDecimals": 6,
+ "minimalOrder": {
+ "amount": 1,
+ "price": 1e-8,
+ "order": 0.001
+ }
+ },
+ {
+ "pair": [
+ "ETH",
+ "ELF"
+ ],
+ "maxDecimals": 6,
+ "minimalOrder": {
+ "amount": 1,
+ "price": 1e-8,
+ "order": 0.01
+ }
+ },
+ {
+ "pair": [
+ "BTC",
+ "ENG"
+ ],
+ "maxDecimals": 6,
+ "minimalOrder": {
+ "amount": 1,
+ "price": 1e-8,
+ "order": 0.001
+ }
+ },
+ {
+ "pair": [
+ "ETH",
+ "ENG"
+ ],
+ "maxDecimals": 6,
+ "minimalOrder": {
+ "amount": 1,
+ "price": 1e-7,
+ "order": 0.01
+ }
+ },
+ {
+ "pair": [
+ "BNB",
+ "ENJ"
+ ],
+ "maxDecimals": 6,
+ "minimalOrder": {
+ "amount": 1,
+ "price": 0.000001,
+ "order": 1
+ }
+ },
+ {
+ "pair": [
+ "BTC",
+ "ENJ"
+ ],
+ "maxDecimals": 6,
+ "minimalOrder": {
+ "amount": 1,
+ "price": 1e-8,
+ "order": 0.001
+ }
+ },
+ {
+ "pair": [
+ "ETH",
+ "ENJ"
+ ],
+ "maxDecimals": 6,
+ "minimalOrder": {
+ "amount": 1,
+ "price": 1e-8,
+ "order": 0.01
+ }
+ },
+ {
+ "pair": [
+ "BNB",
+ "EOS"
+ ],
+ "maxDecimals": 6,
+ "minimalOrder": {
+ "amount": 0.01,
+ "price": 0.0001,
+ "order": 1
+ }
+ },
+ {
+ "pair": [
+ "BTC",
+ "EOS"
+ ],
+ "maxDecimals": 6,
+ "minimalOrder": {
+ "amount": 0.01,
+ "price": 1e-7,
+ "order": 0.001
+ }
+ },
+ {
+ "pair": [
+ "USDT",
+ "EOS"
+ ],
+ "maxDecimals": 6,
+ "minimalOrder": {
+ "amount": 0.01,
+ "price": 0.0001,
+ "order": 10
+ }
+ },
+ {
+ "pair": [
+ "BNB",
+ "ETC"
+ ],
+ "maxDecimals": 6,
+ "minimalOrder": {
+ "amount": 0.01,
+ "price": 0.0001,
+ "order": 1
+ }
+ },
+ {
+ "pair": [
+ "ETH",
+ "ETC"
+ ],
+ "maxDecimals": 6,
+ "minimalOrder": {
+ "amount": 0.01,
+ "price": 0.000001,
+ "order": 0.01
+ }
+ },
+ {
+ "pair": [
+ "USDT",
+ "ETC"
+ ],
+ "maxDecimals": 6,
+ "minimalOrder": {
+ "amount": 0.01,
+ "price": 0.0001,
+ "order": 10
+ }
+ },
+ {
+ "pair": [
+ "BTC",
+ "EVX"
+ ],
+ "maxDecimals": 6,
+ "minimalOrder": {
+ "amount": 1,
+ "price": 1e-8,
+ "order": 0.001
+ }
+ },
+ {
+ "pair": [
+ "ETH",
+ "EVX"
+ ],
+ "maxDecimals": 6,
+ "minimalOrder": {
+ "amount": 1,
+ "price": 1e-7,
+ "order": 0.01
+ }
+ },
+ {
+ "pair": [
+ "BTC",
+ "FUEL"
+ ],
+ "maxDecimals": 6,
+ "minimalOrder": {
+ "amount": 1,
+ "price": 1e-8,
+ "order": 0.001
+ }
+ },
+ {
+ "pair": [
+ "ETH",
+ "FUEL"
+ ],
+ "maxDecimals": 6,
+ "minimalOrder": {
+ "amount": 1,
+ "price": 1e-8,
+ "order": 0.01
+ }
+ },
+ {
+ "pair": [
+ "BTC",
+ "FUN"
+ ],
+ "maxDecimals": 6,
+ "minimalOrder": {
+ "amount": 1,
+ "price": 1e-8,
+ "order": 0.001
+ }
+ },
+ {
+ "pair": [
+ "BNB",
+ "GNT"
+ ],
+ "maxDecimals": 6,
+ "minimalOrder": {
+ "amount": 0.01,
+ "price": 0.00001,
+ "order": 1
+ }
+ },
+ {
+ "pair": [
+ "BTC",
+ "GNT"
+ ],
+ "maxDecimals": 6,
+ "minimalOrder": {
+ "amount": 1,
+ "price": 1e-8,
+ "order": 0.001
+ }
+ },
+ {
+ "pair": [
+ "ETH",
+ "GNT"
+ ],
+ "maxDecimals": 6,
+ "minimalOrder": {
+ "amount": 1,
+ "price": 1e-8,
+ "order": 0.01
+ }
+ },
+ {
+ "pair": [
+ "BTC",
+ "GRS"
+ ],
+ "maxDecimals": 6,
+ "minimalOrder": {
+ "amount": 1,
+ "price": 1e-8,
+ "order": 0.001
+ }
+ },
+ {
+ "pair": [
+ "ETH",
+ "GRS"
+ ],
+ "maxDecimals": 6,
+ "minimalOrder": {
+ "amount": 1,
+ "price": 1e-8,
+ "order": 0.01
+ }
+ },
+ {
+ "pair": [
+ "BNB",
+ "GTO"
+ ],
+ "maxDecimals": 6,
+ "minimalOrder": {
+ "amount": 0.01,
+ "price": 0.00001,
+ "order": 1
+ }
+ },
+ {
+ "pair": [
+ "BTC",
+ "GTO"
+ ],
+ "maxDecimals": 6,
+ "minimalOrder": {
+ "amount": 1,
+ "price": 1e-8,
+ "order": 0.001
+ }
+ },
+ {
+ "pair": [
+ "ETH",
+ "GTO"
+ ],
+ "maxDecimals": 6,
+ "minimalOrder": {
+ "amount": 1,
+ "price": 1e-8,
+ "order": 0.01
+ }
+ },
+ {
+ "pair": [
+ "BTC",
+ "GVT"
+ ],
+ "maxDecimals": 6,
+ "minimalOrder": {
+ "amount": 0.01,
+ "price": 1e-7,
+ "order": 0.001
+ }
+ },
+ {
+ "pair": [
+ "ETH",
+ "GVT"
+ ],
+ "maxDecimals": 6,
+ "minimalOrder": {
+ "amount": 0.01,
+ "price": 0.000001,
+ "order": 0.01
+ }
+ },
+ {
+ "pair": [
+ "BTC",
+ "GXS"
+ ],
+ "maxDecimals": 6,
+ "minimalOrder": {
+ "amount": 0.01,
+ "price": 1e-7,
+ "order": 0.001
+ }
+ },
+ {
+ "pair": [
+ "ETH",
+ "GXS"
+ ],
+ "maxDecimals": 6,
+ "minimalOrder": {
+ "amount": 0.01,
+ "price": 0.000001,
+ "order": 0.01
+ }
+ },
+ {
+ "pair": [
+ "BTC",
+ "HSR"
+ ],
+ "maxDecimals": 6,
+ "minimalOrder": {
+ "amount": 0.01,
+ "price": 0.000001,
+ "order": 0.001
+ }
+ },
+ {
+ "pair": [
+ "ETH",
+ "HSR"
+ ],
+ "maxDecimals": 6,
+ "minimalOrder": {
+ "amount": 0.01,
+ "price": 0.000001,
+ "order": 0.01
+ }
+ },
+ {
+ "pair": [
+ "BTC",
+ "ICN"
+ ],
+ "maxDecimals": 6,
+ "minimalOrder": {
+ "amount": 1,
+ "price": 1e-8,
+ "order": 0.001
+ }
+ },
+ {
+ "pair": [
+ "BNB",
+ "ICX"
+ ],
+ "maxDecimals": 6,
+ "minimalOrder": {
+ "amount": 0.01,
+ "price": 0.00001,
+ "order": 1
+ }
+ },
+ {
+ "pair": [
+ "BTC",
+ "ICX"
+ ],
+ "maxDecimals": 6,
+ "minimalOrder": {
+ "amount": 0.01,
+ "price": 1e-7,
+ "order": 0.001
+ }
+ },
+ {
+ "pair": [
+ "ETH",
+ "ICX"
+ ],
+ "maxDecimals": 6,
+ "minimalOrder": {
+ "amount": 0.01,
+ "price": 0.000001,
+ "order": 0.01
+ }
+ },
+ {
+ "pair": [
+ "USDT",
+ "ICX"
+ ],
+ "maxDecimals": 6,
+ "minimalOrder": {
+ "amount": 0.01,
+ "price": 0.0001,
+ "order": 10
+ }
+ },
+ {
+ "pair": [
+ "BTC",
+ "INS"
+ ],
+ "maxDecimals": 6,
+ "minimalOrder": {
+ "amount": 0.01,
+ "price": 1e-7,
+ "order": 0.001
+ }
+ },
+ {
+ "pair": [
+ "ETH",
+ "INS"
+ ],
+ "maxDecimals": 6,
+ "minimalOrder": {
+ "amount": 0.01,
+ "price": 0.000001,
+ "order": 0.01
+ }
+ },
+ {
+ "pair": [
+ "BTC",
+ "IOST"
+ ],
+ "maxDecimals": 6,
+ "minimalOrder": {
+ "amount": 1,
+ "price": 1e-8,
+ "order": 0.001
+ }
+ },
+ {
+ "pair": [
+ "ETH",
+ "IOST"
+ ],
+ "maxDecimals": 6,
+ "minimalOrder": {
+ "amount": 1,
+ "price": 1e-8,
+ "order": 0.01
+ }
+ },
+ {
+ "pair": [
+ "BNB",
+ "IOTA"
+ ],
+ "maxDecimals": 6,
+ "minimalOrder": {
+ "amount": 0.01,
+ "price": 0.00001,
+ "order": 1
+ }
+ },
+ {
+ "pair": [
+ "USDT",
+ "IOTA"
+ ],
+ "maxDecimals": 6,
+ "minimalOrder": {
+ "amount": 0.01,
+ "price": 0.0001,
+ "order": 10
+ }
+ },
+ {
+ "pair": [
+ "BTC",
+ "IOTX"
+ ],
+ "maxDecimals": 6,
+ "minimalOrder": {
+ "amount": 1,
+ "price": 1e-8,
+ "order": 0.001
+ }
+ },
+ {
+ "pair": [
+ "ETH",
+ "IOTX"
+ ],
+ "maxDecimals": 6,
+ "minimalOrder": {
+ "amount": 1,
+ "price": 1e-8,
+ "order": 0.01
+ }
+ },
+ {
+ "pair": [
+ "BTC",
+ "KEY"
+ ],
+ "maxDecimals": 6,
+ "minimalOrder": {
+ "amount": 1,
+ "price": 1e-8,
+ "order": 0.001
+ }
+ },
+ {
+ "pair": [
+ "ETH",
+ "KEY"
+ ],
+ "maxDecimals": 6,
+ "minimalOrder": {
+ "amount": 1,
+ "price": 1e-8,
+ "order": 0.01
+ }
+ },
+ {
+ "pair": [
+ "BTC",
+ "KMD"
+ ],
+ "maxDecimals": 6,
+ "minimalOrder": {
+ "amount": 0.01,
+ "price": 1e-7,
+ "order": 0.001
+ }
+ },
+ {
+ "pair": [
+ "ETH",
+ "KMD"
+ ],
+ "maxDecimals": 6,
+ "minimalOrder": {
+ "amount": 0.01,
+ "price": 0.000001,
+ "order": 0.01
+ }
+ },
+ {
+ "pair": [
+ "BTC",
+ "LEND"
+ ],
+ "maxDecimals": 6,
+ "minimalOrder": {
+ "amount": 1,
+ "price": 1e-8,
+ "order": 0.001
+ }
+ },
+ {
+ "pair": [
+ "ETH",
+ "LEND"
+ ],
+ "maxDecimals": 6,
+ "minimalOrder": {
+ "amount": 1,
+ "price": 1e-8,
+ "order": 0.01
+ }
+ },
+ {
+ "pair": [
+ "BNB",
+ "LOOM"
+ ],
+ "maxDecimals": 6,
+ "minimalOrder": {
+ "amount": 0.01,
+ "price": 0.00001,
+ "order": 1
+ }
+ },
+ {
+ "pair": [
+ "BTC",
+ "LOOM"
+ ],
+ "maxDecimals": 6,
+ "minimalOrder": {
+ "amount": 1,
+ "price": 1e-8,
+ "order": 0.001
+ }
+ },
+ {
+ "pair": [
+ "ETH",
+ "LOOM"
+ ],
+ "maxDecimals": 6,
+ "minimalOrder": {
+ "amount": 1,
+ "price": 1e-8,
+ "order": 0.01
+ }
+ },
+ {
+ "pair": [
+ "BTC",
+ "LRC"
+ ],
+ "maxDecimals": 6,
+ "minimalOrder": {
+ "amount": 1,
+ "price": 1e-8,
+ "order": 0.001
+ }
+ },
+ {
+ "pair": [
+ "ETH",
+ "LRC"
+ ],
+ "maxDecimals": 6,
+ "minimalOrder": {
+ "amount": 1,
+ "price": 1e-8,
+ "order": 0.01
+ }
+ },
+ {
+ "pair": [
+ "BNB",
+ "LSK"
+ ],
+ "maxDecimals": 6,
+ "minimalOrder": {
+ "amount": 0.01,
+ "price": 0.0001,
+ "order": 1
+ }
+ },
+ {
+ "pair": [
+ "BTC",
+ "LSK"
+ ],
+ "maxDecimals": 6,
+ "minimalOrder": {
+ "amount": 0.01,
+ "price": 1e-7,
+ "order": 0.001
+ }
+ },
+ {
+ "pair": [
+ "ETH",
+ "LSK"
+ ],
+ "maxDecimals": 6,
+ "minimalOrder": {
+ "amount": 0.01,
+ "price": 0.000001,
+ "order": 0.01
+ }
+ },
+ {
+ "pair": [
+ "BNB",
+ "LTC"
+ ],
+ "maxDecimals": 6,
+ "minimalOrder": {
+ "amount": 0.00001,
+ "price": 0.01,
+ "order": 1
+ }
+ },
+ {
+ "pair": [
+ "ETH",
+ "LTC"
+ ],
+ "maxDecimals": 6,
+ "minimalOrder": {
+ "amount": 0.001,
+ "price": 0.00001,
+ "order": 0.01
+ }
+ },
+ {
+ "pair": [
+ "USDT",
+ "LTC"
+ ],
+ "maxDecimals": 6,
+ "minimalOrder": {
+ "amount": 0.00001,
+ "price": 0.01,
+ "order": 10
+ }
+ },
+ {
+ "pair": [
+ "BTC",
+ "LUN"
+ ],
+ "maxDecimals": 6,
+ "minimalOrder": {
+ "amount": 0.01,
+ "price": 1e-7,
+ "order": 0.001
+ }
+ },
+ {
+ "pair": [
+ "ETH",
+ "LUN"
+ ],
+ "maxDecimals": 6,
+ "minimalOrder": {
+ "amount": 0.01,
+ "price": 0.000001,
+ "order": 0.01
+ }
+ },
+ {
+ "pair": [
+ "BTC",
+ "MANA"
+ ],
+ "maxDecimals": 6,
+ "minimalOrder": {
+ "amount": 1,
+ "price": 1e-8,
+ "order": 0.001
+ }
+ },
+ {
+ "pair": [
+ "ETH",
+ "MANA"
+ ],
+ "maxDecimals": 6,
+ "minimalOrder": {
+ "amount": 1,
+ "price": 1e-8,
+ "order": 0.01
+ }
+ },
+ {
+ "pair": [
+ "BNB",
+ "MCO"
+ ],
+ "maxDecimals": 6,
+ "minimalOrder": {
+ "amount": 0.01,
+ "price": 0.00001,
+ "order": 1
+ }
+ },
+ {
+ "pair": [
+ "BTC",
+ "MDA"
+ ],
+ "maxDecimals": 6,
+ "minimalOrder": {
+ "amount": 1,
+ "price": 1e-8,
+ "order": 0.001
+ }
+ },
+ {
+ "pair": [
+ "ETH",
+ "MDA"
+ ],
+ "maxDecimals": 6,
+ "minimalOrder": {
+ "amount": 1,
+ "price": 1e-7,
+ "order": 0.01
+ }
+ },
+ {
+ "pair": [
+ "BNB",
+ "MFT"
+ ],
+ "maxDecimals": 6,
+ "minimalOrder": {
+ "amount": 1,
+ "price": 0.000001,
+ "order": 1
+ }
+ },
+ {
+ "pair": [
+ "BTC",
+ "MFT"
+ ],
+ "maxDecimals": 6,
+ "minimalOrder": {
+ "amount": 1,
+ "price": 1e-8,
+ "order": 0.001
+ }
+ },
+ {
+ "pair": [
+ "ETH",
+ "MFT"
+ ],
+ "maxDecimals": 6,
+ "minimalOrder": {
+ "amount": 1,
+ "price": 1e-8,
+ "order": 0.01
+ }
+ },
+ {
+ "pair": [
+ "BTC",
+ "MOD"
+ ],
+ "maxDecimals": 6,
+ "minimalOrder": {
+ "amount": 0.01,
+ "price": 1e-7,
+ "order": 0.001
+ }
+ },
+ {
+ "pair": [
+ "ETH",
+ "MOD"
+ ],
+ "maxDecimals": 6,
+ "minimalOrder": {
+ "amount": 0.01,
+ "price": 0.000001,
+ "order": 0.01
+ }
+ },
+ {
+ "pair": [
+ "BTC",
+ "MTH"
+ ],
+ "maxDecimals": 6,
+ "minimalOrder": {
+ "amount": 1,
+ "price": 1e-8,
+ "order": 0.001
+ }
+ },
+ {
+ "pair": [
+ "ETH",
+ "MTH"
+ ],
+ "maxDecimals": 6,
+ "minimalOrder": {
+ "amount": 1,
+ "price": 1e-8,
+ "order": 0.01
+ }
+ },
+ {
+ "pair": [
+ "BTC",
+ "MTL"
+ ],
+ "maxDecimals": 6,
+ "minimalOrder": {
+ "amount": 0.01,
+ "price": 1e-7,
+ "order": 0.001
+ }
+ },
+ {
+ "pair": [
+ "ETH",
+ "MTL"
+ ],
+ "maxDecimals": 6,
+ "minimalOrder": {
+ "amount": 0.01,
+ "price": 0.000001,
+ "order": 0.01
+ }
+ },
+ {
+ "pair": [
+ "BNB",
+ "NANO"
+ ],
+ "maxDecimals": 6,
+ "minimalOrder": {
+ "amount": 0.01,
+ "price": 0.0001,
+ "order": 1
+ }
+ },
+ {
+ "pair": [
+ "BTC",
+ "NANO"
+ ],
+ "maxDecimals": 6,
+ "minimalOrder": {
+ "amount": 0.01,
+ "price": 1e-7,
+ "order": 0.001
+ }
+ },
+ {
+ "pair": [
+ "ETH",
+ "NANO"
+ ],
+ "maxDecimals": 6,
+ "minimalOrder": {
+ "amount": 0.01,
+ "price": 0.000001,
+ "order": 0.01
+ }
+ },
+ {
+ "pair": [
+ "BNB",
+ "NAS"
+ ],
+ "maxDecimals": 6,
+ "minimalOrder": {
+ "amount": 0.01,
+ "price": 0.00001,
+ "order": 1
+ }
+ },
+ {
+ "pair": [
+ "BTC",
+ "NAS"
+ ],
+ "maxDecimals": 6,
+ "minimalOrder": {
+ "amount": 0.01,
+ "price": 1e-7,
+ "order": 0.001
+ }
+ },
+ {
+ "pair": [
+ "ETH",
+ "NAS"
+ ],
+ "maxDecimals": 6,
+ "minimalOrder": {
+ "amount": 0.01,
+ "price": 0.000001,
+ "order": 0.01
+ }
+ },
+ {
+ "pair": [
+ "BNB",
+ "NAV"
+ ],
+ "maxDecimals": 6,
+ "minimalOrder": {
+ "amount": 0.01,
+ "price": 0.00001,
+ "order": 1
+ }
+ },
+ {
+ "pair": [
+ "BTC",
+ "NAV"
+ ],
+ "maxDecimals": 6,
+ "minimalOrder": {
+ "amount": 0.01,
+ "price": 1e-7,
+ "order": 0.001
+ }
+ },
+ {
+ "pair": [
+ "ETH",
+ "NAV"
+ ],
+ "maxDecimals": 6,
+ "minimalOrder": {
+ "amount": 0.01,
+ "price": 0.000001,
+ "order": 0.01
+ }
+ },
+ {
+ "pair": [
+ "BNB",
+ "NCASH"
+ ],
+ "maxDecimals": 6,
+ "minimalOrder": {
+ "amount": 1,
+ "price": 0.000001,
+ "order": 1
+ }
+ },
+ {
+ "pair": [
+ "BTC",
+ "NCASH"
+ ],
+ "maxDecimals": 6,
+ "minimalOrder": {
+ "amount": 1,
+ "price": 1e-8,
+ "order": 0.001
+ }
+ },
+ {
+ "pair": [
+ "ETH",
+ "NCASH"
+ ],
+ "maxDecimals": 6,
+ "minimalOrder": {
+ "amount": 1,
+ "price": 1e-8,
+ "order": 0.01
+ }
+ },
+ {
+ "pair": [
+ "BNB",
+ "NEBL"
+ ],
+ "maxDecimals": 6,
+ "minimalOrder": {
+ "amount": 0.01,
+ "price": 0.00001,
+ "order": 1
+ }
+ },
+ {
+ "pair": [
+ "BTC",
+ "NEBL"
+ ],
+ "maxDecimals": 6,
+ "minimalOrder": {
+ "amount": 0.01,
+ "price": 1e-7,
+ "order": 0.001
+ }
+ },
+ {
+ "pair": [
+ "ETH",
+ "NEBL"
+ ],
+ "maxDecimals": 6,
+ "minimalOrder": {
+ "amount": 0.01,
+ "price": 0.000001,
+ "order": 0.01
+ }
+ },
+ {
+ "pair": [
+ "BNB",
+ "NEO"
+ ],
+ "maxDecimals": 6,
+ "minimalOrder": {
+ "amount": 0.001,
+ "price": 0.001,
+ "order": 1
+ }
+ },
+ {
+ "pair": [
+ "USDT",
+ "NEO"
+ ],
+ "maxDecimals": 6,
+ "minimalOrder": {
+ "amount": 0.001,
+ "price": 0.001,
+ "order": 10
+ }
+ },
+ {
+ "pair": [
+ "BTC",
+ "NPXS"
+ ],
+ "maxDecimals": 6,
+ "minimalOrder": {
+ "amount": 1,
+ "price": 1e-8,
+ "order": 0.001
+ }
+ },
+ {
+ "pair": [
+ "ETH",
+ "NPXS"
+ ],
+ "maxDecimals": 6,
+ "minimalOrder": {
+ "amount": 1,
+ "price": 1e-8,
+ "order": 0.01
+ }
+ },
+ {
+ "pair": [
+ "BNB",
+ "NXS"
+ ],
+ "maxDecimals": 6,
+ "minimalOrder": {
+ "amount": 0.01,
+ "price": 0.0001,
+ "order": 1
+ }
+ },
+ {
+ "pair": [
+ "BTC",
+ "NXS"
+ ],
+ "maxDecimals": 6,
+ "minimalOrder": {
+ "amount": 0.01,
+ "price": 1e-7,
+ "order": 0.001
+ }
+ },
+ {
+ "pair": [
+ "ETH",
+ "NXS"
+ ],
+ "maxDecimals": 6,
+ "minimalOrder": {
+ "amount": 0.01,
+ "price": 0.000001,
+ "order": 0.01
+ }
+ },
+ {
+ "pair": [
+ "BTC",
+ "OAX"
+ ],
+ "maxDecimals": 6,
+ "minimalOrder": {
+ "amount": 1,
+ "price": 1e-8,
+ "order": 0.001
+ }
+ },
+ {
+ "pair": [
+ "BNB",
+ "ONT"
+ ],
+ "maxDecimals": 6,
+ "minimalOrder": {
+ "amount": 0.01,
+ "price": 0.00001,
+ "order": 1
+ }
+ },
+ {
+ "pair": [
+ "BTC",
+ "ONT"
+ ],
+ "maxDecimals": 6,
+ "minimalOrder": {
+ "amount": 0.01,
+ "price": 1e-7,
+ "order": 0.001
+ }
+ },
+ {
+ "pair": [
+ "ETH",
+ "ONT"
+ ],
+ "maxDecimals": 6,
+ "minimalOrder": {
+ "amount": 0.01,
+ "price": 0.000001,
+ "order": 0.01
+ }
+ },
+ {
+ "pair": [
+ "USDT",
+ "ONT"
+ ],
+ "maxDecimals": 6,
+ "minimalOrder": {
+ "amount": 0.001,
+ "price": 0.001,
+ "order": 10
+ }
+ },
+ {
+ "pair": [
+ "BNB",
+ "OST"
+ ],
+ "maxDecimals": 6,
+ "minimalOrder": {
+ "amount": 1,
+ "price": 0.000001,
+ "order": 1
+ }
+ },
+ {
+ "pair": [
+ "BTC",
+ "OST"
+ ],
+ "maxDecimals": 6,
+ "minimalOrder": {
+ "amount": 1,
+ "price": 1e-8,
+ "order": 0.001
+ }
+ },
+ {
+ "pair": [
+ "ETH",
+ "OST"
+ ],
+ "maxDecimals": 6,
+ "minimalOrder": {
+ "amount": 1,
+ "price": 1e-8,
+ "order": 0.01
+ }
+ },
+ {
+ "pair": [
+ "BNB",
+ "PIVX"
+ ],
+ "maxDecimals": 6,
+ "minimalOrder": {
+ "amount": 0.01,
+ "price": 0.00001,
+ "order": 1
+ }
+ },
+ {
+ "pair": [
+ "BTC",
+ "PIVX"
+ ],
+ "maxDecimals": 6,
+ "minimalOrder": {
+ "amount": 0.01,
+ "price": 1e-7,
+ "order": 0.001
+ }
+ },
+ {
+ "pair": [
+ "ETH",
+ "PIVX"
+ ],
+ "maxDecimals": 6,
+ "minimalOrder": {
+ "amount": 0.01,
+ "price": 0.000001,
+ "order": 0.01
+ }
+ },
+ {
+ "pair": [
+ "BNB",
+ "POA"
+ ],
+ "maxDecimals": 6,
+ "minimalOrder": {
+ "amount": 0.01,
+ "price": 0.00001,
+ "order": 1
+ }
+ },
+ {
+ "pair": [
+ "BTC",
+ "POA"
+ ],
+ "maxDecimals": 6,
+ "minimalOrder": {
+ "amount": 1,
+ "price": 1e-8,
+ "order": 0.001
+ }
+ },
+ {
+ "pair": [
+ "ETH",
+ "POA"
+ ],
+ "maxDecimals": 6,
+ "minimalOrder": {
+ "amount": 1,
+ "price": 1e-8,
+ "order": 0.01
+ }
+ },
+ {
+ "pair": [
+ "BTC",
+ "POE"
+ ],
+ "maxDecimals": 6,
+ "minimalOrder": {
+ "amount": 1,
+ "price": 1e-8,
+ "order": 0.001
+ }
+ },
+ {
+ "pair": [
+ "ETH",
+ "POE"
+ ],
+ "maxDecimals": 6,
+ "minimalOrder": {
+ "amount": 1,
+ "price": 1e-8,
+ "order": 0.01
+ }
+ },
+ {
+ "pair": [
+ "BNB",
+ "POWR"
+ ],
+ "maxDecimals": 6,
+ "minimalOrder": {
+ "amount": 0.01,
+ "price": 0.00001,
+ "order": 1
+ }
+ },
+ {
+ "pair": [
+ "BTC",
+ "POWR"
+ ],
+ "maxDecimals": 6,
+ "minimalOrder": {
+ "amount": 1,
+ "price": 1e-8,
+ "order": 0.001
+ }
+ },
+ {
+ "pair": [
+ "ETH",
+ "POWR"
+ ],
+ "maxDecimals": 6,
+ "minimalOrder": {
+ "amount": 1,
+ "price": 1e-8,
+ "order": 0.01
+ }
+ },
+ {
+ "pair": [
+ "BTC",
+ "PPT"
+ ],
+ "maxDecimals": 6,
+ "minimalOrder": {
+ "amount": 0.01,
+ "price": 1e-7,
+ "order": 0.001
+ }
+ },
+ {
+ "pair": [
+ "ETH",
+ "PPT"
+ ],
+ "maxDecimals": 6,
+ "minimalOrder": {
+ "amount": 0.01,
+ "price": 0.000001,
+ "order": 0.01
+ }
+ },
+ {
+ "pair": [
+ "BTC",
+ "QKC"
+ ],
+ "maxDecimals": 6,
+ "minimalOrder": {
+ "amount": 1,
+ "price": 1e-8,
+ "order": 0.001
+ }
+ },
+ {
+ "pair": [
+ "ETH",
+ "QKC"
+ ],
+ "maxDecimals": 6,
+ "minimalOrder": {
+ "amount": 1,
+ "price": 1e-8,
+ "order": 0.01
+ }
+ },
+ {
+ "pair": [
+ "BNB",
+ "QLC"
+ ],
+ "maxDecimals": 6,
+ "minimalOrder": {
+ "amount": 1,
+ "price": 0.000001,
+ "order": 1
+ }
+ },
+ {
+ "pair": [
+ "BTC",
+ "QLC"
+ ],
+ "maxDecimals": 6,
+ "minimalOrder": {
+ "amount": 1,
+ "price": 1e-8,
+ "order": 0.001
+ }
+ },
+ {
+ "pair": [
+ "ETH",
+ "QLC"
+ ],
+ "maxDecimals": 6,
+ "minimalOrder": {
+ "amount": 1,
+ "price": 1e-8,
+ "order": 0.01
+ }
+ },
+ {
+ "pair": [
+ "BNB",
+ "QSP"
+ ],
+ "maxDecimals": 6,
+ "minimalOrder": {
+ "amount": 1,
+ "price": 0.000001,
+ "order": 1
+ }
+ },
+ {
+ "pair": [
+ "BTC",
+ "QSP"
+ ],
+ "maxDecimals": 6,
+ "minimalOrder": {
+ "amount": 1,
+ "price": 1e-8,
+ "order": 0.001
+ }
+ },
+ {
+ "pair": [
+ "ETH",
+ "QSP"
+ ],
+ "maxDecimals": 6,
+ "minimalOrder": {
+ "amount": 1,
+ "price": 1e-8,
+ "order": 0.01
+ }
+ },
+ {
+ "pair": [
+ "BNB",
+ "QTUM"
+ ],
+ "maxDecimals": 6,
+ "minimalOrder": {
+ "amount": 0.01,
+ "price": 0.00001,
+ "order": 1
+ }
+ },
+ {
+ "pair": [
+ "USDT",
+ "QTUM"
+ ],
+ "maxDecimals": 6,
+ "minimalOrder": {
+ "amount": 0.001,
+ "price": 0.001,
+ "order": 10
+ }
+ },
+ {
+ "pair": [
+ "BNB",
+ "RCN"
+ ],
+ "maxDecimals": 6,
+ "minimalOrder": {
+ "amount": 1,
+ "price": 0.000001,
+ "order": 1
+ }
+ },
+ {
+ "pair": [
+ "BTC",
+ "RCN"
+ ],
+ "maxDecimals": 6,
+ "minimalOrder": {
+ "amount": 1,
+ "price": 1e-8,
+ "order": 0.001
+ }
+ },
+ {
+ "pair": [
+ "ETH",
+ "RCN"
+ ],
+ "maxDecimals": 6,
+ "minimalOrder": {
+ "amount": 1,
+ "price": 1e-8,
+ "order": 0.01
+ }
+ },
+ {
+ "pair": [
+ "BNB",
+ "RDN"
+ ],
+ "maxDecimals": 6,
+ "minimalOrder": {
+ "amount": 0.01,
+ "price": 0.00001,
+ "order": 1
+ }
+ },
+ {
+ "pair": [
+ "BTC",
+ "RDN"
+ ],
+ "maxDecimals": 6,
+ "minimalOrder": {
+ "amount": 1,
+ "price": 1e-8,
+ "order": 0.001
+ }
+ },
+ {
+ "pair": [
+ "ETH",
+ "RDN"
+ ],
+ "maxDecimals": 6,
+ "minimalOrder": {
+ "amount": 1,
+ "price": 1e-7,
+ "order": 0.01
+ }
+ },
+ {
+ "pair": [
+ "BNB",
+ "REP"
+ ],
+ "maxDecimals": 6,
+ "minimalOrder": {
+ "amount": 0.001,
+ "price": 0.001,
+ "order": 1
+ }
+ },
+ {
+ "pair": [
+ "BTC",
+ "REP"
+ ],
+ "maxDecimals": 6,
+ "minimalOrder": {
+ "amount": 0.001,
+ "price": 0.000001,
+ "order": 0.001
+ }
+ },
+ {
+ "pair": [
+ "ETH",
+ "REP"
+ ],
+ "maxDecimals": 6,
+ "minimalOrder": {
+ "amount": 0.001,
+ "price": 0.00001,
+ "order": 0.01
+ }
+ },
+ {
+ "pair": [
+ "BTC",
+ "REQ"
+ ],
+ "maxDecimals": 6,
+ "minimalOrder": {
+ "amount": 1,
+ "price": 1e-8,
+ "order": 0.001
+ }
+ },
+ {
+ "pair": [
+ "ETH",
+ "REQ"
+ ],
+ "maxDecimals": 6,
+ "minimalOrder": {
+ "amount": 1,
+ "price": 1e-8,
+ "order": 0.01
+ }
+ },
+ {
+ "pair": [
+ "BNB",
+ "RLC"
+ ],
+ "maxDecimals": 6,
+ "minimalOrder": {
+ "amount": 0.01,
+ "price": 0.00001,
+ "order": 1
+ }
+ },
+ {
+ "pair": [
+ "BTC",
+ "RLC"
+ ],
+ "maxDecimals": 6,
+ "minimalOrder": {
+ "amount": 0.01,
+ "price": 1e-7,
+ "order": 0.001
+ }
+ },
+ {
+ "pair": [
+ "ETH",
+ "RLC"
+ ],
+ "maxDecimals": 6,
+ "minimalOrder": {
+ "amount": 0.01,
+ "price": 0.000001,
+ "order": 0.01
+ }
+ },
+ {
+ "pair": [
+ "BNB",
+ "RPX"
+ ],
+ "maxDecimals": 6,
+ "minimalOrder": {
+ "amount": 1,
+ "price": 0.000001,
+ "order": 1
+ }
+ },
+ {
+ "pair": [
+ "BTC",
+ "RPX"
+ ],
+ "maxDecimals": 6,
+ "minimalOrder": {
+ "amount": 1,
+ "price": 1e-8,
+ "order": 0.001
+ }
+ },
+ {
+ "pair": [
+ "ETH",
+ "RPX"
+ ],
+ "maxDecimals": 6,
+ "minimalOrder": {
+ "amount": 1,
+ "price": 1e-8,
+ "order": 0.01
+ }
+ },
+ {
+ "pair": [
+ "BNB",
+ "SC"
+ ],
+ "maxDecimals": 6,
+ "minimalOrder": {
+ "amount": 1,
+ "price": 0.000001,
+ "order": 1
+ }
+ },
+ {
+ "pair": [
+ "BTC",
+ "SC"
+ ],
+ "maxDecimals": 6,
+ "minimalOrder": {
+ "amount": 1,
+ "price": 1e-8,
+ "order": 0.001
+ }
+ },
+ {
+ "pair": [
+ "ETH",
+ "SC"
+ ],
+ "maxDecimals": 6,
+ "minimalOrder": {
+ "amount": 1,
+ "price": 1e-8,
+ "order": 0.01
+ }
+ },
+ {
+ "pair": [
+ "BNB",
+ "SKY"
+ ],
+ "maxDecimals": 6,
+ "minimalOrder": {
+ "amount": 0.001,
+ "price": 0.001,
+ "order": 1
+ }
+ },
+ {
+ "pair": [
+ "BTC",
+ "SKY"
+ ],
+ "maxDecimals": 6,
+ "minimalOrder": {
+ "amount": 0.001,
+ "price": 0.000001,
+ "order": 0.001
+ }
+ },
+ {
+ "pair": [
+ "ETH",
+ "SKY"
+ ],
+ "maxDecimals": 6,
+ "minimalOrder": {
+ "amount": 0.001,
+ "price": 0.00001,
+ "order": 0.01
+ }
+ },
+ {
+ "pair": [
+ "BTC",
+ "SNT"
+ ],
+ "maxDecimals": 6,
+ "minimalOrder": {
+ "amount": 1,
+ "price": 1e-8,
+ "order": 0.001
+ }
+ },
+ {
+ "pair": [
+ "BNB",
+ "STEEM"
+ ],
+ "maxDecimals": 6,
+ "minimalOrder": {
+ "amount": 0.01,
+ "price": 0.00001,
+ "order": 1
+ }
+ },
+ {
+ "pair": [
+ "BTC",
+ "STEEM"
+ ],
+ "maxDecimals": 6,
+ "minimalOrder": {
+ "amount": 0.01,
+ "price": 1e-7,
+ "order": 0.001
+ }
+ },
+ {
+ "pair": [
+ "ETH",
+ "STEEM"
+ ],
+ "maxDecimals": 6,
+ "minimalOrder": {
+ "amount": 0.01,
+ "price": 0.000001,
+ "order": 0.01
+ }
+ },
+ {
+ "pair": [
+ "BTC",
+ "STORJ"
+ ],
+ "maxDecimals": 6,
+ "minimalOrder": {
+ "amount": 1,
+ "price": 1e-8,
+ "order": 0.001
+ }
+ },
+ {
+ "pair": [
+ "ETH",
+ "STORJ"
+ ],
+ "maxDecimals": 6,
+ "minimalOrder": {
+ "amount": 1,
+ "price": 1e-7,
+ "order": 0.01
+ }
+ },
+ {
+ "pair": [
+ "BNB",
+ "STORM"
+ ],
+ "maxDecimals": 6,
+ "minimalOrder": {
+ "amount": 1,
+ "price": 0.000001,
+ "order": 1
+ }
+ },
+ {
+ "pair": [
+ "BTC",
+ "STORM"
+ ],
+ "maxDecimals": 6,
+ "minimalOrder": {
+ "amount": 1,
+ "price": 1e-8,
+ "order": 0.001
+ }
+ },
+ {
+ "pair": [
+ "ETH",
+ "STORM"
+ ],
+ "maxDecimals": 6,
+ "minimalOrder": {
+ "amount": 1,
+ "price": 1e-8,
+ "order": 0.01
+ }
+ },
+ {
+ "pair": [
+ "BTC",
+ "SUB"
+ ],
+ "maxDecimals": 6,
+ "minimalOrder": {
+ "amount": 1,
+ "price": 1e-8,
+ "order": 0.001
+ }
+ },
+ {
+ "pair": [
+ "ETH",
+ "SUB"
+ ],
+ "maxDecimals": 6,
+ "minimalOrder": {
+ "amount": 1,
+ "price": 1e-8,
+ "order": 0.01
+ }
+ },
+ {
+ "pair": [
+ "BNB",
+ "SYS"
+ ],
+ "maxDecimals": 6,
+ "minimalOrder": {
+ "amount": 0.01,
+ "price": 0.00001,
+ "order": 1
+ }
+ },
+ {
+ "pair": [
+ "BTC",
+ "SYS"
+ ],
+ "maxDecimals": 6,
+ "minimalOrder": {
+ "amount": 1,
+ "price": 1e-8,
+ "order": 0.001
+ }
+ },
+ {
+ "pair": [
+ "ETH",
+ "SYS"
+ ],
+ "maxDecimals": 6,
+ "minimalOrder": {
+ "amount": 1,
+ "price": 1e-8,
+ "order": 0.01
+ }
+ },
+ {
+ "pair": [
+ "BNB",
+ "THETA"
+ ],
+ "maxDecimals": 6,
+ "minimalOrder": {
+ "amount": 0.01,
+ "price": 0.00001,
+ "order": 1
+ }
+ },
+ {
+ "pair": [
+ "BTC",
+ "THETA"
+ ],
+ "maxDecimals": 6,
+ "minimalOrder": {
+ "amount": 1,
+ "price": 1e-8,
+ "order": 0.001
+ }
+ },
+ {
+ "pair": [
+ "ETH",
+ "THETA"
+ ],
+ "maxDecimals": 6,
+ "minimalOrder": {
+ "amount": 1,
+ "price": 1e-8,
+ "order": 0.01
+ }
+ },
+ {
+ "pair": [
+ "BTC",
+ "TNB"
+ ],
+ "maxDecimals": 6,
+ "minimalOrder": {
+ "amount": 1,
+ "price": 1e-8,
+ "order": 0.001
+ }
+ },
+ {
+ "pair": [
+ "ETH",
+ "TNB"
+ ],
+ "maxDecimals": 6,
+ "minimalOrder": {
+ "amount": 1,
+ "price": 1e-8,
+ "order": 0.01
+ }
+ },
+ {
+ "pair": [
+ "BTC",
+ "TNT"
+ ],
+ "maxDecimals": 6,
+ "minimalOrder": {
+ "amount": 1,
+ "price": 1e-8,
+ "order": 0.001
+ }
+ },
+ {
+ "pair": [
+ "ETH",
+ "TNT"
+ ],
+ "maxDecimals": 6,
+ "minimalOrder": {
+ "amount": 1,
+ "price": 1e-8,
+ "order": 0.01
+ }
+ },
+ {
+ "pair": [
+ "BNB",
+ "TRIG"
+ ],
+ "maxDecimals": 6,
+ "minimalOrder": {
+ "amount": 0.01,
+ "price": 0.00001,
+ "order": 1
+ }
+ },
+ {
+ "pair": [
+ "BTC",
+ "TRIG"
+ ],
+ "maxDecimals": 6,
+ "minimalOrder": {
+ "amount": 0.01,
+ "price": 1e-7,
+ "order": 0.001
+ }
+ },
+ {
+ "pair": [
+ "ETH",
+ "TRIG"
+ ],
+ "maxDecimals": 6,
+ "minimalOrder": {
+ "amount": 0.01,
+ "price": 0.000001,
+ "order": 0.01
+ }
+ },
+ {
+ "pair": [
+ "BTC",
+ "TRX"
+ ],
+ "maxDecimals": 6,
+ "minimalOrder": {
+ "amount": 1,
+ "price": 1e-8,
+ "order": 0.001
+ }
+ },
+ {
+ "pair": [
+ "ETH",
+ "TRX"
+ ],
+ "maxDecimals": 6,
+ "minimalOrder": {
+ "amount": 1,
+ "price": 1e-8,
+ "order": 0.01
+ }
+ },
+ {
+ "pair": [
+ "USDT",
+ "TRX"
+ ],
+ "maxDecimals": 6,
+ "minimalOrder": {
+ "amount": 0.1,
+ "price": 0.00001,
+ "order": 10
+ }
+ },
+ {
+ "pair": [
+ "BNB",
+ "TUSD"
+ ],
+ "maxDecimals": 6,
+ "minimalOrder": {
+ "amount": 0.01,
+ "price": 0.00001,
+ "order": 1
+ }
+ },
+ {
+ "pair": [
+ "BTC",
+ "TUSD"
+ ],
+ "maxDecimals": 6,
+ "minimalOrder": {
+ "amount": 1,
+ "price": 1e-8,
+ "order": 0.001
+ }
+ },
+ {
+ "pair": [
+ "ETH",
+ "TUSD"
+ ],
+ "maxDecimals": 6,
+ "minimalOrder": {
+ "amount": 1,
+ "price": 1e-8,
+ "order": 0.01
+ }
+ },
+ {
+ "pair": [
+ "USDT",
+ "TUSD"
+ ],
+ "maxDecimals": 6,
+ "minimalOrder": {
+ "amount": 0.01,
+ "price": 0.0001,
+ "order": 10
+ }
+ },
+ {
+ "pair": [
+ "BTC",
+ "VEN"
+ ],
+ "maxDecimals": 6,
+ "minimalOrder": {
+ "amount": 1,
+ "price": 1e-8,
+ "order": 0.001
+ }
+ },
+ {
+ "pair": [
+ "ETH",
+ "VEN"
+ ],
+ "maxDecimals": 6,
+ "minimalOrder": {
+ "amount": 1,
+ "price": 1e-8,
+ "order": 0.01
+ }
+ },
+ {
+ "pair": [
+ "USDT",
+ "VEN"
+ ],
+ "maxDecimals": 6,
+ "minimalOrder": {
+ "amount": 0.01,
+ "price": 0.0001,
+ "order": 10
+ }
+ },
+ {
+ "pair": [
+ "BNB",
+ "VIA"
+ ],
+ "maxDecimals": 6,
+ "minimalOrder": {
+ "amount": 0.01,
+ "price": 0.00001,
+ "order": 1
+ }
+ },
+ {
+ "pair": [
+ "BTC",
+ "VIA"
+ ],
+ "maxDecimals": 6,
+ "minimalOrder": {
+ "amount": 0.01,
+ "price": 1e-7,
+ "order": 0.001
+ }
+ },
+ {
+ "pair": [
+ "ETH",
+ "VIA"
+ ],
+ "maxDecimals": 6,
+ "minimalOrder": {
+ "amount": 0.01,
+ "price": 0.000001,
+ "order": 0.01
+ }
+ },
+ {
+ "pair": [
+ "BTC",
+ "VIB"
+ ],
+ "maxDecimals": 6,
+ "minimalOrder": {
+ "amount": 1,
+ "price": 1e-8,
+ "order": 0.001
+ }
+ },
+ {
+ "pair": [
+ "BTC",
+ "VIBE"
+ ],
+ "maxDecimals": 6,
+ "minimalOrder": {
+ "amount": 1,
+ "price": 1e-8,
+ "order": 0.001
+ }
+ },
+ {
+ "pair": [
+ "ETH",
+ "VIBE"
+ ],
+ "maxDecimals": 6,
+ "minimalOrder": {
+ "amount": 1,
+ "price": 1e-7,
+ "order": 0.01
+ }
+ },
+ {
+ "pair": [
+ "ETH",
+ "VIB"
+ ],
+ "maxDecimals": 6,
+ "minimalOrder": {
+ "amount": 1,
+ "price": 1e-8,
+ "order": 0.01
+ }
+ },
+ {
+ "pair": [
+ "BNB",
+ "WABI"
+ ],
+ "maxDecimals": 6,
+ "minimalOrder": {
+ "amount": 0.01,
+ "price": 0.00001,
+ "order": 1
+ }
+ },
+ {
+ "pair": [
+ "BTC",
+ "WABI"
+ ],
+ "maxDecimals": 6,
+ "minimalOrder": {
+ "amount": 1,
+ "price": 1e-8,
+ "order": 0.001
+ }
+ },
+ {
+ "pair": [
+ "ETH",
+ "WABI"
+ ],
+ "maxDecimals": 6,
+ "minimalOrder": {
+ "amount": 1,
+ "price": 1e-8,
+ "order": 0.01
+ }
+ },
+ {
+ "pair": [
+ "BNB",
+ "WAN"
+ ],
+ "maxDecimals": 6,
+ "minimalOrder": {
+ "amount": 0.01,
+ "price": 0.00001,
+ "order": 1
+ }
+ },
+ {
+ "pair": [
+ "BTC",
+ "WAN"
+ ],
+ "maxDecimals": 6,
+ "minimalOrder": {
+ "amount": 0.01,
+ "price": 1e-7,
+ "order": 0.001
+ }
+ },
+ {
+ "pair": [
+ "ETH",
+ "WAN"
+ ],
+ "maxDecimals": 6,
+ "minimalOrder": {
+ "amount": 0.01,
+ "price": 0.000001,
+ "order": 0.01
+ }
+ },
+ {
+ "pair": [
+ "BNB",
+ "WAVES"
+ ],
+ "maxDecimals": 6,
+ "minimalOrder": {
+ "amount": 0.01,
+ "price": 0.0001,
+ "order": 1
+ }
+ },
+ {
+ "pair": [
+ "BTC",
+ "WAVES"
+ ],
+ "maxDecimals": 6,
+ "minimalOrder": {
+ "amount": 0.01,
+ "price": 1e-7,
+ "order": 0.001
+ }
+ },
+ {
+ "pair": [
+ "ETH",
+ "WAVES"
+ ],
+ "maxDecimals": 6,
+ "minimalOrder": {
+ "amount": 0.01,
+ "price": 0.000001,
+ "order": 0.01
+ }
+ },
+ {
+ "pair": [
+ "BTC",
+ "WINGS"
+ ],
+ "maxDecimals": 6,
+ "minimalOrder": {
+ "amount": 1,
+ "price": 1e-8,
+ "order": 0.001
+ }
+ },
+ {
+ "pair": [
+ "ETH",
+ "WINGS"
+ ],
+ "maxDecimals": 6,
+ "minimalOrder": {
+ "amount": 1,
+ "price": 1e-7,
+ "order": 0.01
+ }
+ },
+ {
+ "pair": [
+ "BTC",
+ "WPR"
+ ],
+ "maxDecimals": 6,
+ "minimalOrder": {
+ "amount": 1,
+ "price": 1e-8,
+ "order": 0.001
+ }
+ },
+ {
+ "pair": [
+ "ETH",
+ "WPR"
+ ],
+ "maxDecimals": 6,
+ "minimalOrder": {
+ "amount": 1,
+ "price": 1e-8,
+ "order": 0.01
+ }
+ },
+ {
+ "pair": [
+ "BNB",
+ "WTC"
+ ],
+ "maxDecimals": 6,
+ "minimalOrder": {
+ "amount": 0.01,
+ "price": 0.0001,
+ "order": 1
+ }
+ },
+ {
+ "pair": [
+ "BNB",
+ "XEM"
+ ],
+ "maxDecimals": 6,
+ "minimalOrder": {
+ "amount": 0.01,
+ "price": 0.00001,
+ "order": 1
+ }
+ },
+ {
+ "pair": [
+ "BTC",
+ "XEM"
+ ],
+ "maxDecimals": 6,
+ "minimalOrder": {
+ "amount": 1,
+ "price": 1e-8,
+ "order": 0.001
+ }
+ },
+ {
+ "pair": [
+ "ETH",
+ "XEM"
+ ],
+ "maxDecimals": 6,
+ "minimalOrder": {
+ "amount": 1,
+ "price": 1e-8,
+ "order": 0.01
+ }
+ },
+ {
+ "pair": [
+ "BNB",
+ "XLM"
+ ],
+ "maxDecimals": 6,
+ "minimalOrder": {
+ "amount": 0.01,
+ "price": 0.00001,
+ "order": 1
+ }
+ },
+ {
+ "pair": [
+ "BTC",
+ "XLM"
+ ],
+ "maxDecimals": 6,
+ "minimalOrder": {
+ "amount": 1,
+ "price": 1e-8,
+ "order": 0.001
+ }
+ },
+ {
+ "pair": [
+ "ETH",
+ "XLM"
+ ],
+ "maxDecimals": 6,
+ "minimalOrder": {
+ "amount": 1,
+ "price": 1e-8,
+ "order": 0.01
+ }
+ },
+ {
+ "pair": [
+ "USDT",
+ "XLM"
+ ],
+ "maxDecimals": 6,
+ "minimalOrder": {
+ "amount": 0.01,
+ "price": 0.00001,
+ "order": 10
+ }
+ },
+ {
+ "pair": [
+ "BTC",
+ "XMR"
+ ],
+ "maxDecimals": 6,
+ "minimalOrder": {
+ "amount": 0.001,
+ "price": 0.000001,
+ "order": 0.001
+ }
+ },
+ {
+ "pair": [
+ "ETH",
+ "XMR"
+ ],
+ "maxDecimals": 6,
+ "minimalOrder": {
+ "amount": 0.001,
+ "price": 0.00001,
+ "order": 0.01
+ }
+ },
+ {
+ "pair": [
+ "BNB",
+ "XRP"
+ ],
+ "maxDecimals": 6,
+ "minimalOrder": {
+ "amount": 0.01,
+ "price": 0.00001,
+ "order": 1
+ }
+ },
+ {
+ "pair": [
+ "BTC",
+ "XRP"
+ ],
+ "maxDecimals": 6,
+ "minimalOrder": {
+ "amount": 1,
+ "price": 1e-8,
+ "order": 0.001
+ }
+ },
+ {
+ "pair": [
+ "ETH",
+ "XRP"
+ ],
+ "maxDecimals": 6,
+ "minimalOrder": {
+ "amount": 1,
+ "price": 1e-8,
+ "order": 0.01
+ }
+ },
+ {
+ "pair": [
+ "USDT",
+ "XRP"
+ ],
+ "maxDecimals": 6,
+ "minimalOrder": {
+ "amount": 0.1,
+ "price": 0.00001,
+ "order": 10
+ }
+ },
+ {
+ "pair": [
+ "BTC",
+ "XVG"
+ ],
+ "maxDecimals": 6,
+ "minimalOrder": {
+ "amount": 1,
+ "price": 1e-8,
+ "order": 0.001
+ }
+ },
+ {
+ "pair": [
+ "BNB",
+ "XZC"
+ ],
+ "maxDecimals": 6,
+ "minimalOrder": {
+ "amount": 0.001,
+ "price": 0.001,
+ "order": 1
+ }
+ },
+ {
+ "pair": [
+ "BTC",
+ "XZC"
+ ],
+ "maxDecimals": 6,
+ "minimalOrder": {
+ "amount": 0.01,
+ "price": 0.000001,
+ "order": 0.001
+ }
+ },
+ {
+ "pair": [
+ "ETH",
+ "XZC"
+ ],
+ "maxDecimals": 6,
+ "minimalOrder": {
+ "amount": 0.01,
+ "price": 0.000001,
+ "order": 0.01
+ }
+ },
+ {
+ "pair": [
+ "BNB",
+ "YOYO"
+ ],
+ "maxDecimals": 6,
+ "minimalOrder": {
+ "amount": 1,
+ "price": 0.000001,
+ "order": 1
+ }
+ },
+ {
+ "pair": [
+ "BTC",
+ "YOYO"
+ ],
+ "maxDecimals": 6,
+ "minimalOrder": {
+ "amount": 1,
+ "price": 1e-8,
+ "order": 0.001
+ }
+ },
+ {
+ "pair": [
+ "ETH",
+ "YOYO"
+ ],
+ "maxDecimals": 6,
+ "minimalOrder": {
+ "amount": 1,
+ "price": 1e-8,
+ "order": 0.01
+ }
+ },
+ {
+ "pair": [
+ "BTC",
+ "ZEC"
+ ],
+ "maxDecimals": 6,
+ "minimalOrder": {
+ "amount": 0.001,
+ "price": 0.000001,
+ "order": 0.001
+ }
+ },
+ {
+ "pair": [
+ "ETH",
+ "ZEC"
+ ],
+ "maxDecimals": 6,
+ "minimalOrder": {
+ "amount": 0.001,
+ "price": 0.00001,
+ "order": 0.01
+ }
+ },
+ {
+ "pair": [
+ "BNB",
+ "ZEN"
+ ],
+ "maxDecimals": 6,
+ "minimalOrder": {
+ "amount": 0.001,
+ "price": 0.001,
+ "order": 1
+ }
+ },
+ {
+ "pair": [
+ "BTC",
+ "ZEN"
+ ],
+ "maxDecimals": 6,
+ "minimalOrder": {
+ "amount": 0.001,
+ "price": 0.000001,
+ "order": 0.001
+ }
+ },
+ {
+ "pair": [
+ "ETH",
+ "ZEN"
+ ],
+ "maxDecimals": 6,
+ "minimalOrder": {
+ "amount": 0.001,
+ "price": 0.00001,
+ "order": 0.01
+ }
+ },
+ {
+ "pair": [
+ "BNB",
+ "ZIL"
+ ],
+ "maxDecimals": 6,
+ "minimalOrder": {
+ "amount": 1,
+ "price": 0.000001,
+ "order": 1
+ }
+ },
+ {
+ "pair": [
+ "BTC",
+ "ZIL"
+ ],
+ "maxDecimals": 6,
+ "minimalOrder": {
+ "amount": 1,
+ "price": 1e-8,
+ "order": 0.001
+ }
+ },
+ {
+ "pair": [
+ "ETH",
+ "ZIL"
+ ],
+ "maxDecimals": 6,
+ "minimalOrder": {
+ "amount": 1,
+ "price": 1e-8,
+ "order": 0.01
+ }
+ },
+ {
+ "pair": [
+ "USDT",
+ "BNB"
+ ],
+ "maxDecimals": 6,
+ "minimalOrder": {
+ "amount": 0.01,
+ "price": 0.0001,
+ "order": 10
+ }
+ },
+ {
+ "pair": [
+ "USDT",
+ "ETH"
+ ],
+ "maxDecimals": 6,
+ "minimalOrder": {
+ "amount": 0.00001,
+ "price": 0.01,
+ "order": 10
+ }
+ }
+ ]
+}
\ No newline at end of file
diff --git a/Server/Exchange/Wrappers/poloniex.js b/Server/Exchange/Wrappers/poloniex.js
new file mode 100644
index 000000000..b486342b3
--- /dev/null
+++ b/Server/Exchange/Wrappers/poloniex.js
@@ -0,0 +1,439 @@
+// Source: https://github.com/premasagar/poloniex.js
+// Documentation: https://poloniex.com/support/api/
+
+module.exports = (function () {
+ 'use strict';
+
+ // Module dependencies
+ var crypto = require('crypto'),
+ request = require('request'),
+ nonce = require('nonce')();
+
+ // Constants
+ var version = '0.0.9',
+ PUBLIC_API_URL = 'https://poloniex.com/public',
+ PRIVATE_API_URL = 'https://poloniex.com/tradingApi',
+ USER_AGENT = 'poloniex.js ' + version;
+ //USER_AGENT = 'Mozilla/5.0 (Windows NT 6.3; WOW64; rv:26.0) Gecko/20100101 Firefox/26.0'
+
+ // Helper methods
+ function joinCurrencies(currencyA, currencyB) {
+ // If only one arg, then return the first
+ if (typeof currencyB !== 'string') {
+ return currencyA;
+ }
+
+ return currencyA + '_' + currencyB;
+ }
+
+ // Constructor
+ function Poloniex(key, secret) {
+ // Generate headers signed by this user's key and secret.
+ // The secret is encapsulated and never exposed
+ this._getPrivateHeaders = function (parameters) {
+ var paramString, signature;
+
+ if (!key || !secret) {
+ throw 'Poloniex: Error. API key and secret required';
+ }
+
+ // Convert to `arg1=foo&arg2=bar`
+ paramString = Object.keys(parameters).map(function (param) {
+ return encodeURIComponent(param) + '=' + encodeURIComponent(parameters[param]);
+ }).join('&');
+
+ signature = crypto.createHmac('sha512', secret).update(paramString).digest('hex');
+
+ return {
+ Key: key,
+ Sign: signature
+ };
+ };
+ }
+
+ // Currently, this fails with `Error: CERT_UNTRUSTED`
+ // Poloniex.STRICT_SSL can be set to `false` to avoid this. Use with caution.
+ // Will be removed in future, once this is resolved.
+ Poloniex.STRICT_SSL = true;
+
+ // Customisable user agent string
+ Poloniex.USER_AGENT = USER_AGENT;
+
+ // Prototype
+ Poloniex.prototype = {
+ constructor: Poloniex,
+
+ // Make an API request
+ _request: function (options, callback) {
+ if (!('headers' in options)) {
+ options.headers = {};
+ }
+
+ options.json = true;
+ options.headers['User-Agent'] = Poloniex.USER_AGENT;
+ options.strictSSL = Poloniex.STRICT_SSL;
+ options.timeout = 60 * 1000;
+
+ request(options, function (err, response, body) {
+ // Empty response
+ if (!err && (typeof body === 'undefined' || body === null)) {
+ err = 'Empty response';
+ }
+
+ callback(err, body);
+ });
+
+ return this;
+ },
+
+ // Make a public API request
+ _public: function (command, parameters, callback) {
+ var options;
+
+ if (typeof parameters === 'function') {
+ callback = parameters;
+ parameters = {};
+ }
+
+ parameters || (parameters = {});
+ parameters.command = command;
+ options = {
+ method: 'GET',
+ url: PUBLIC_API_URL,
+ qs: parameters
+ };
+
+ options.qs.command = command;
+ return this._request(options, callback);
+ },
+
+ // Make a private API request
+ _private: function (command, parameters, callback) {
+ var options;
+
+ if (typeof parameters === 'function') {
+ callback = parameters;
+ parameters = {};
+ }
+
+ parameters || (parameters = {});
+ parameters.command = command;
+ parameters.nonce = nonce();
+
+ options = {
+ method: 'POST',
+ url: PRIVATE_API_URL,
+ form: parameters,
+ headers: this._getPrivateHeaders(parameters)
+ };
+
+ return this._request(options, callback);
+ },
+
+ /////
+ // PUBLIC METHODS
+
+ returnTicker: function (callback) {
+ return this._public('returnTicker', callback);
+ },
+
+ return24hVolume: function (callback) {
+ return this._public('return24hVolume', callback);
+ },
+
+ returnOrderBook: function (currencyA, currencyB, callback) {
+ var currencyPair;
+
+ if (typeof currencyB === 'function') {
+ currencyPair = currencyA;
+ callback = currencyB;
+ currencyB = null;
+ }
+
+ else {
+ currencyPair = joinCurrencies(currencyA, currencyB);
+ }
+
+ var parameters = {
+ currencyPair: currencyPair
+ };
+
+ return this._public('returnOrderBook', parameters, callback);
+ },
+
+ returnChartData: function (currencyA, currencyB, period, start, end, callback) {
+ var parameters = {
+ currencyPair: joinCurrencies(currencyA, currencyB),
+ period: period,
+ start: start,
+ end: end
+ };
+
+ return this._public('returnChartData', parameters, callback);
+ },
+
+ returnCurrencies: function (callback) {
+ return this._public('returnCurrencies', callback);
+ },
+
+ returnLoanOrders: function (currency, callback) {
+ return this._public('returnLoanOrders', { currency: currency }, callback);
+ },
+
+ returnTradeHistory: function (currencyA, currencyB, start, end, callback) {
+ if (arguments.length < 5) {
+ callback = start;
+ start = Date.now() / 1000 - 60 * 60;
+ end = Date.now() / 1000 + 60 * 60; // Some buffer in case of client/server time out of sync.
+ }
+
+ var parameters = {
+ currencyPair: joinCurrencies(currencyA, currencyB),
+ start: start,
+ end: end
+ };
+
+ return this._public('returnTradeHistory', parameters, callback);
+ },
+
+ /////
+ // PRIVATE METHODS
+
+ returnBalances: function (callback) {
+ return this._private('returnBalances', {}, callback);
+ },
+
+ returnCompleteBalances: function (account, callback) {
+ var parameters = {};
+
+ if (typeof account === 'function') {
+ callback = account;
+ }
+
+ else if (typeof account === 'string' && !!account) {
+ parameters.account = account;
+ }
+
+ return this._private('returnCompleteBalances', parameters, callback);
+ },
+
+ returnDepositAddresses: function (callback) {
+ return this._private('returnDepositAddresses', {}, callback);
+ },
+
+ generateNewAddress: function (currency, callback) {
+ return this._private('generateNewAddress', { currency: currency }, callback);
+ },
+
+ returnDepositsWithdrawals: function (start, end, callback) {
+ return this._private('returnDepositsWithdrawals', { start: start, end: end }, callback);
+ },
+
+ // can be called with `returnOpenOrders('all', callback)`
+ returnOpenOrders: function (currencyA, currencyB, callback) {
+ var currencyPair;
+
+ if (typeof currencyB === 'function') {
+ currencyPair = currencyA;
+ callback = currencyB;
+ currencyB = null;
+ }
+
+ else {
+ currencyPair = joinCurrencies(currencyA, currencyB);
+ }
+
+ var parameters = {
+ currencyPair: currencyPair
+ };
+
+ return this._private('returnOpenOrders', parameters, callback);
+ },
+
+ returnOrderTrades: function (orderNumber, callback) {
+ var parameters = {
+ orderNumber: orderNumber
+ };
+
+ return this._private('returnOrderTrades', parameters, callback);
+ },
+
+ buy: function (currencyA, currencyB, rate, amount, callback) {
+ var parameters = {
+ currencyPair: joinCurrencies(currencyA, currencyB),
+ rate: rate,
+ amount: amount
+ };
+
+ return this._private('buy', parameters, callback);
+ },
+
+ sell: function (currencyA, currencyB, rate, amount, callback) {
+ var parameters = {
+ currencyPair: joinCurrencies(currencyA, currencyB),
+ rate: rate,
+ amount: amount
+ };
+
+ return this._private('sell', parameters, callback);
+ },
+
+ cancelOrder: function (currencyA, currencyB, orderNumber, callback) {
+ var parameters = {
+ currencyPair: joinCurrencies(currencyA, currencyB),
+ orderNumber: orderNumber
+ };
+
+ return this._private('cancelOrder', parameters, callback);
+ },
+
+ moveOrder: function (orderNumber, rate, amount, callback) {
+ var parameters = {
+ orderNumber: orderNumber,
+ rate: rate,
+ amount: amount ? amount : null
+ };
+
+ return this._private('moveOrder', parameters, callback);
+ },
+
+ withdraw: function (currency, amount, address, callback) {
+ var parameters = {
+ currency: currency,
+ amount: amount,
+ address: address
+ };
+
+ return this._private('withdraw', parameters, callback);
+ },
+
+ returnFeeInfo: function (callback) {
+ return this._private('returnFeeInfo', {}, callback);
+ },
+
+ returnAvailableAccountBalances: function (account, callback) {
+ var parameters = {};
+
+ if (typeof account === 'function') {
+ callback = account;
+ }
+
+ else if (typeof account === 'string' && !!account) {
+ parameters.account = account;
+ }
+
+ return this._private('returnAvailableAccountBalances', parameters, callback);
+ },
+
+ returnTradableBalances: function (callback) {
+ return this._private('returnTradableBalances', {}, callback);
+ },
+
+ transferBalance: function (currency, amount, fromAccount, toAccount, callback) {
+ var parameters = {
+ currency: currency,
+ amount: amount,
+ fromAccount: fromAccount,
+ toAccount: toAccount
+ };
+
+ return this._private('transferBalance', parameters, callback);
+ },
+
+ returnMarginAccountSummary: function (callback) {
+ return this._private('returnMarginAccountSummary', {}, callback);
+ },
+
+ marginBuy: function (currencyA, currencyB, rate, amount, lendingRate, callback) {
+ var parameters = {
+ currencyPair: joinCurrencies(currencyA, currencyB),
+ rate: rate,
+ amount: amount,
+ lendingRate: lendingRate ? lendingRate : null
+ };
+
+ return this._private('marginBuy', parameters, callback);
+ },
+
+ marginSell: function (currencyA, currencyB, rate, amount, lendingRate, callback) {
+ var parameters = {
+ currencyPair: joinCurrencies(currencyA, currencyB),
+ rate: rate,
+ amount: amount,
+ lendingRate: lendingRate ? lendingRate : null
+ };
+
+ return this._private('marginSell', parameters, callback);
+ },
+
+ getMarginPosition: function (currencyA, currencyB, callback) {
+ var parameters = {
+ currencyPair: joinCurrencies(currencyA, currencyB)
+ };
+
+ return this._private('getMarginPosition', parameters, callback);
+ },
+
+ closeMarginPosition: function (currencyA, currencyB, callback) {
+ var parameters = {
+ currencyPair: joinCurrencies(currencyA, currencyB)
+ };
+
+ return this._private('closeMarginPosition', parameters, callback);
+ },
+
+ createLoanOffer: function (currency, amount, duration, autoRenew, lendingRate, callback) {
+ var parameters = {
+ currency: currency,
+ amount: amount,
+ duration: duration,
+ autoRenew: autoRenew,
+ lendingRate: lendingRate
+ };
+
+ return this._private('createLoanOffer', parameters, callback);
+ },
+
+ cancelLoanOffer: function (orderNumber, callback) {
+ var parameters = {
+ orderNumber: orderNumber
+ };
+
+ return this._private('cancelLoanOffer', parameters, callback);
+ },
+
+ returnOpenLoanOffers: function (callback) {
+ return this._private('returnOpenLoanOffers', {}, callback);
+ },
+
+ returnActiveLoans: function (callback) {
+ return this._private('returnActiveLoans', {}, callback);
+ },
+
+ returnLendingHistory: function (start, end, limit, callback) {
+ var parameters = {
+ start: start,
+ end: end,
+ limit: limit
+ };
+
+ return this._private('returnLendingHistory', parameters, callback);
+ },
+
+ toggleAutoRenew: function (orderNumber, callback) {
+ return this._private('toggleAutoRenew', { orderNumber: orderNumber }, callback);
+ }
+
+ };
+
+ // Backwards Compatibility
+ Poloniex.prototype.getTicker = Poloniex.prototype.returnTicker;
+ Poloniex.prototype.get24hVolume = Poloniex.prototype.return24hVolume;
+ Poloniex.prototype.getOrderBook = Poloniex.prototype.returnOrderBook;
+ Poloniex.prototype.getTradeHistory = Poloniex.prototype.returnChartData;
+ Poloniex.prototype.myBalances = Poloniex.prototype.returnBalances;
+ Poloniex.prototype.myOpenOrders = Poloniex.prototype.returnOpenOrders;
+ Poloniex.prototype.myTradeHistory = Poloniex.prototype.returnTradeHistory;
+
+ return Poloniex;
+})();
\ No newline at end of file
diff --git a/Server/Exchange/Wrappers/poloniexClient.js b/Server/Exchange/Wrappers/poloniexClient.js
new file mode 100644
index 000000000..ad2d14378
--- /dev/null
+++ b/Server/Exchange/Wrappers/poloniexClient.js
@@ -0,0 +1,353 @@
+exports.newAPIClient = function newAPIClient(pKey, pSecret, logger) {
+
+ /*
+ /* ATENTION: This Library is used both a the cloud (AACloud) and also at the AAWeb on the server side without any modifications.
+ /* There is a second version, stripped of all the inner functionality that runs at AAWeb browser side, which channels the requests to the server side one.
+ */
+
+ const FULL_LOG = true;
+ const LOG_FILE_CONTENT = true;
+ const MODULE_NAME = "poloniexClient";
+
+ const retry = require('../exchangeUtils').retry;
+ const includes = require('../exchangeUtils').includes;
+ const _ = require('lodash');
+ const Poloniex = require("./poloniex");
+ const exchangeProperties = require('./poloniexProperties.json');
+
+ const recoverableErrors = [
+ 'SOCKETTIMEDOUT',
+ 'TIMEDOUT',
+ 'CONNRESET',
+ 'CONNREFUSED',
+ 'NOTFOUND',
+ '429',
+ '522',
+ '504',
+ '503',
+ '500',
+ '502',
+ 'Empty response',
+ 'Please try again in a few minutes.',
+ 'Nonce must be greater than',
+ 'Internal error. Please try again.',
+ 'Connection timed out. Please try again.',
+ 'ENOTFOUND',
+ 'ECONNREFUSED',
+ 'CONNREFUSED',
+ 'NOTFOUND',
+ 'ESOCKETTIMEDOUT',
+ 'ECONNRESET',
+ 'Connection timed out',
+ 'Connection Error',
+ 'Order not found, or you are not the person who placed it.',
+ 'ETIMEDOUT'
+ ];
+
+ let API = new Poloniex(pKey, pSecret);
+
+ let thisObject = {
+ getTicker: getTicker,
+ getOpenPositions: getOpenPositions,
+ getExecutedTrades: getExecutedTrades,
+ buy: buy,
+ sell: sell,
+ movePosition: movePosition,
+ getPublicTradeHistory: getPublicTradeHistory,
+ getExchangeProperties: getExchangeProperties,
+ isValidLot: isValidLot
+ };
+
+ return thisObject;
+
+ function joinCurrencies(currencyA, currencyB) {
+ // If only one arg, then return the first
+ if (typeof currencyB !== 'string') {
+ return currencyA;
+ }
+
+ return currencyA + '_' + currencyB;
+ }
+
+
+ /*
+ * Returns the properties for this exchange
+ */
+ function getExchangeProperties() {
+ return exchangeProperties;
+ }
+
+ /*
+ * Returns the price for a given pair of assets.
+ * The object returned is an array of trades:
+ * ticker = {
+ * bid, Number
+ * ask, Number
+ * last Number
+ * };
+ */
+ function getTicker(pMarket, callBack) {
+
+ const handle = (err, response) => {
+ let ticker;
+ let market = joinCurrencies(pMarket.assetA, pMarket.assetB);
+ if (err.result === global.DEFAULT_OK_RESPONSE.result) {
+ ticker = {
+ bid: Number(response[market].highestBid),
+ ask: Number(response[market].lowestAsk),
+ last: Number(response[market].last)
+ };
+ }
+ callBack(err, ticker);
+ };
+
+ const fetch = next => API.getTicker(analizeResponse(next));
+
+ retry(null, fetch, handle);
+ }
+
+ /*
+ * Returns the open positions ath the exchange for a given market and user account.
+ * The object returned is an array of positions:
+ * position = {
+ * id,
+ * type,
+ * rate, Number
+ * amountA, Number
+ * amountB, Number
+ * fee, (not required) Number
+ * datetime
+ * };
+ */
+ function getOpenPositions(pMarket, callBack) {
+
+ const handle = (err, response) => {
+ let exchangePositions = [];
+ if (err.result === global.DEFAULT_OK_RESPONSE.result) {
+ for (let i = 0; i < response.length; i++) {
+ let openPosition = {
+ id: response[i].orderNumber,
+ type: response[i].type,
+ rate: Number(response[i].rate),
+ amountA: Number(response[i].total),
+ amountB: Number(response[i].amount),
+ date: (new Date(response[i].time)).valueOf()
+ };
+ exchangePositions.push(openPosition);
+ }
+ }
+ callBack(err, exchangePositions);
+ };
+
+ const fetch = next => API.returnOpenOrders(pMarket.assetA, pMarket.assetB, analizeResponse(next));
+
+ retry(null, fetch, handle);
+ }
+
+ /*
+ * Returns the trades for a given order number.
+ * The object returned is an array of positions:
+ * position = {
+ * id,
+ * type,
+ * rate, Number
+ * amountA, Number
+ * amountB, Number
+ * fee, Number
+ * datetime
+ * };
+ */
+ function getExecutedTrades(pPositionId, callBack) {
+
+ const handle = (err, response) => {
+ let trades = [];
+ if (err.result === global.DEFAULT_OK_RESPONSE.result) {
+ for (let i = 0; i < response.length; i++) {
+ let trade = {
+ id: response[i].tradeID,
+ type: response[i].type,
+ rate: Number(response[i].rate),
+ amountA: Number(response[i].total),
+ amountB: Number(response[i].amount),
+ fee: Number(response[i].fee),
+ date: (new Date(response[i].date)).valueOf()
+ }
+ trades.push(trade);
+ }
+ } else if (err.result === global.CUSTOM_OK_RESPONSE.result) {
+ // No trades found at the exchange for the position, but returning empy trades object.
+ err = global.DEFAULT_OK_RESPONSE;
+ }
+ callBack(err, trades);
+ };
+
+ const fetch = next => API.returnOrderTrades(pPositionId, analizeResponse(next));
+
+ retry(null, fetch, handle);
+ }
+
+ /*
+ * Creates a new buy order.
+ * The orderNumber is returned. String
+ */
+ function buy(pCurrencyA, pCurrencyB, pRate, pAmount, callBack) {
+
+ const handle = (err, response) => {
+ let orderNumber;
+ if (err.result === global.DEFAULT_OK_RESPONSE.result) {
+ orderNumber = response.orderNumber;
+ }
+ callBack(err, orderNumber);
+ };
+
+ const fetch = next => API.buy(pCurrencyA, pCurrencyB, pRate, pAmount, analizeResponse(next));
+
+ retry(null, fetch, handle);
+
+ }
+
+ /*
+ * Creates a new sell order.
+ * The orderNumber is returned. String
+ */
+ function sell(pCurrencyA, pCurrencyB, pRate, pAmount, callBack) {
+
+ const handle = (err, response) => {
+ let orderNumber;
+ if (err.result === global.DEFAULT_OK_RESPONSE.result) {
+ orderNumber = response.orderNumber;
+ }
+ callBack(err, orderNumber);
+ };
+
+ const fetch = next => API.sell(pCurrencyA, pCurrencyB, pRate, pAmount, analizeResponse(next));
+
+ retry(null, fetch, handle);
+ }
+
+ /*
+ * Move an existing position to the new rate.
+ * The orderNumber is returned. String
+ */
+ function movePosition(pPosition, pNewRate, pNewAmountB, callBack) {
+
+ const handle = (err, response) => {
+ let orderNumber;
+ if (err.result === global.DEFAULT_OK_RESPONSE.result) {
+ orderNumber = response.orderNumber;
+ }
+ callBack(err, orderNumber);
+ };
+
+ const fetch = next => API.moveOrder(pPosition.id, pNewRate, pNewAmountB, analizeResponse(next));
+
+ retry(null, fetch, handle);
+ }
+
+ /*
+ * Returns all the trade history from the Exchange since startTime to endTime orderd by tradeId.
+ * It's possible that the exchange doesn't support this method.
+ * The object returned is an array of trades:
+ * trade = {
+ * tradeID, String
+ * globalTradeID, String
+ * type, String
+ * rate, Number
+ * amountA, Number
+ * amountB, Number
+ * date Date
+ * };
+ */
+ function getPublicTradeHistory(assetA, assetB, startTime, endTime, callBack) {
+
+ const handle = (err, response) => {
+ let trades = [];
+ if (err.result === global.DEFAULT_OK_RESPONSE.result) {
+ for (let i = 0; i < response.length; i++) {
+ let trade = {
+ tradeID: response[i].tradeID,
+ globalTradeID: response[i].globalTradeID,
+ type: response[i].type,
+ rate: Number(response[i].rate),
+ total: Number(response[i].total),
+ amount: Number(response[i].amount),
+ date: new Date(response[i].date)
+ }
+ trades.push(trade);
+ }
+ }
+ callBack(err, trades);
+ };
+
+ const fetch = next => API.returnTradeHistory(assetA, assetB, startTime, endTime, analizeResponse(next));
+
+ retry(null, fetch, handle);
+ }
+
+ function isValidLot(price, amount) {
+ return amount * price >= 0.0001;
+ }
+
+ function analizeResponse(callBack) {
+
+ return (exchangeErr, exchangeResponse) => {
+ let error;
+
+ /* This function analizes the different situations we might encounter trying to access Poloniex and returns appropiate standard errors. */
+
+ let stringExchangeErr = JSON.stringify(exchangeErr);
+ let stringExchangeResponse = JSON.stringify(exchangeResponse);
+
+ try {
+ if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] analizeResponse -> exchangeErr = " + stringExchangeErr); }
+ if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] analizeResponse -> exchangeResponse = " + stringExchangeResponse); }
+
+ if (exchangeErr) {
+ error = global.DEFAULT_FAIL_RESPONSE;
+
+ if (includes(exchangeErr.code, recoverableErrors)) {
+ error.notFatal = true;
+ }
+ } else if (!exchangeResponse || exchangeResponse === undefined) {
+ error = {
+ result: global.DEFAULT_FAIL_RESPONSE.result,
+ message: 'Empty response',
+ notFatal: true
+ };
+ } else if (includes(exchangeResponse.error, ['Please complete the security check to proceed.'])) {
+ error = {
+ result: global.DEFAULT_FAIL_RESPONSE.result,
+ message: 'The IP has been flagged by CloudFlare.'
+ };
+ } else if (includes(exchangeResponse.error, [''])) {
+ error = {
+ result: global.DEFAULT_FAIL_RESPONSE.result,
+ message: exchangeResponse
+ };
+ } else if (includes(exchangeResponse.error, ['Not enough'])) {
+ error = {
+ result: global.DEFAULT_RETRY_RESPONSE.result,
+ message: exchangeResponse.error
+ };
+ } else if (includes(exchangeResponse.error, ['Order not found, or you are not the person who placed it.'])) {
+ error = {
+ result: global.CUSTOM_OK_RESPONSE.result,
+ message: exchangeResponse.error
+ };
+ } else if (exchangeResponse.error) {
+ error = {
+ result: global.DEFAULT_FAIL_RESPONSE.result,
+ message: exchangeResponse.error
+ };
+ }
+
+ return callBack(error, exchangeResponse);
+
+ } catch (err) {
+ logger.write(MODULE_NAME, "[ERROR] analizeResponse -> err.message = " + err.message);
+ return callBack(global.DEFAULT_FAIL_RESPONSE, exchangeResponse);
+ }
+ }
+ }
+
+}
diff --git a/Server/Exchange/Wrappers/poloniexProperties.json b/Server/Exchange/Wrappers/poloniexProperties.json
new file mode 100644
index 000000000..a5716ba3b
--- /dev/null
+++ b/Server/Exchange/Wrappers/poloniexProperties.json
@@ -0,0 +1,3513 @@
+{
+ "currencies": ["BTC", "ETH", "XMR", "USDT"],
+ "assets": [
+ "1CR", "ABY", "AC", "ACH", "ADN", "AEON", "AERO", "AIR", "AMP", "APH",
+ "ARCH", "AUR", "AXIS", "BALLS", "BANK", "BBL", "BBR", "BCC", "BCH", "BCN",
+ "BCY", "BDC", "BDG", "BELA", "BITCNY", "BITS", "BITUSD", "BLK", "BLOCK",
+ "BLU", "BNS", "BONES", "BOST", "BTC", "BTCD", "BTCS", "BTM", "BTS",
+ "BURN", "BURST", "C2", "CACH", "CAI", "CC", "CCN", "CGA", "CHA", "CINNI",
+ "CLAM", "CNL", "CNMT", "CNOTE", "COMM", "CON", "CORG", "CRYPT", "CURE",
+ "CVC", "CYC", "DAO", "DASH", "DCR", "DGB", "DICE", "DIEM", "DIME", "DIS", "DNS",
+ "DOGE", "DRKC", "DRM", "DSH", "DVK", "EAC", "EBT", "ECC", "EFL", "EMC2",
+ "EMO", "ENC", "ETC", "ETH", "eTOK", "EXE", "EXP", "FAC", "FCN", "FCT",
+ "FIBRE", "FLAP", "FLDC", "FLO", "FLT", "FOX", "FRAC", "FRK", "FRQ", "GNO",
+ "FVZ", "FZ", "FZN", "GAME", "GAP", "GAS", "GDN", "GEMZ", "GEO", "GIAR", "GLB",
+ "GML", "GNS", "GNT", "GOLD", "GPC", "GPUC", "GRC", "GRCX", "GRS", "GUE", "H2O",
+ "HIRO", "HOT", "HUC", "HUGE", "HVC", "HYP", "HZ", "IFC", "INDEX", "IOC",
+ "ITC", "IXC", "JLH", "JPC", "JUG", "KDC", "KEY", "LBC", "LC", "LCL",
+ "LEAF", "LGC", "LOL", "LOVE", "LQD", "LSK", "LTBC", "LTC", "LTCX",
+ "MAID", "MAST", "MAX", "MCN", "MEC", "METH", "MIL", "MIN", "MINT", "MMC",
+ "MMNXT", "MMXIV", "MNTA", "MON", "MRC", "MRS", "MTS", "MUN", "MYR",
+ "MZC", "N5X", "NAS", "NAUT", "NAV", "NBT", "NEOS", "NL", "NMC", "NOBL",
+ "NOTE", "NOXT", "NRS", "NSR", "NTX", "NXT", "NXTI", "OMG", "OMNI", "OPAL",
+ "PAND", "PASC", "PAWN", "PIGGY", "PINK", "PLX", "PMC", "POT", "PPC", "PRC",
+ "PRT", "PTS", "Q2C", "QBK", "QCN", "QORA", "QTL", "RADS", "RBY", "RDD", "REP",
+ "RIC", "RZR", "SBD", "SC", "SDC", "SHIBE", "SHOPX", "SILK", "SJCX",
+ "SLR", "SMC", "SOC", "SPA", "SQL", "SRCC", "SRG", "SSD", "STEEM", "STR",
+ "SUM", "SUN", "SWARM", "SXC", "SYNC", "SYS", "TAC", "TOR", "TRUST",
+ "TWE", "UIS", "ULTC", "UNITY", "URO", "USDE", "USDT", "UTC", "UTIL",
+ "UVC", "VIA", "VOOT", "VOX", "VRC", "VTC", "WC", "WDC", "WIKI", "WOLF",
+ "X13", "XAI", "XAP", "XBC", "XC", "XCH", "XCN", "XCP", "XCR", "XDN",
+ "XDP", "XEM", "XHC", "XLB", "XMG", "XMR", "XPB", "XPM", "XRP", "XSI",
+ "XST", "XSV", "XUSD", "XVC", "XXC", "BCH", "YACC", "YANG", "YC", "YIN", "ZEC",
+ "ZRX"
+ ],
+ "markets": [
+ {
+ "pair": [
+ "BTC",
+ "1CR"
+ ],
+ "maxDecimals": 8,
+ "minimalOrder": {
+ "amount": 0.0001,
+ "unit": "asset"
+ }
+ },
+ {
+ "pair": [
+ "BTC",
+ "ABY"
+ ],
+ "maxDecimals": 8,
+ "minimalOrder": {
+ "amount": 0.0001,
+ "unit": "asset"
+ }
+ },
+ {
+ "pair": [
+ "BTC",
+ "AC"
+ ],
+ "maxDecimals": 8,
+ "minimalOrder": {
+ "amount": 0.0001,
+ "unit": "asset"
+ }
+ },
+ {
+ "pair": [
+ "BTC",
+ "ACH"
+ ],
+ "maxDecimals": 8,
+ "minimalOrder": {
+ "amount": 0.0001,
+ "unit": "asset"
+ }
+ },
+ {
+ "pair": [
+ "BTC",
+ "ADN"
+ ],
+ "maxDecimals": 8,
+ "minimalOrder": {
+ "amount": 0.0001,
+ "unit": "asset"
+ }
+ },
+ {
+ "pair": [
+ "BTC",
+ "AEON"
+ ],
+ "maxDecimals": 8,
+ "minimalOrder": {
+ "amount": 0.0001,
+ "unit": "asset"
+ }
+ },
+ {
+ "pair": [
+ "BTC",
+ "AERO"
+ ],
+ "maxDecimals": 8,
+ "minimalOrder": {
+ "amount": 0.0001,
+ "unit": "asset"
+ }
+ },
+ {
+ "pair": [
+ "BTC",
+ "AIR"
+ ],
+ "maxDecimals": 8,
+ "minimalOrder": {
+ "amount": 0.0001,
+ "unit": "asset"
+ }
+ },
+ {
+ "pair": [
+ "BTC",
+ "AMP"
+ ],
+ "maxDecimals": 8,
+ "minimalOrder": {
+ "amount": 0.0001,
+ "unit": "asset"
+ }
+ },
+ {
+ "pair": [
+ "BTC",
+ "APH"
+ ],
+ "maxDecimals": 8,
+ "minimalOrder": {
+ "amount": 0.0001,
+ "unit": "asset"
+ }
+ },
+ {
+ "pair": [
+ "BTC",
+ "ARCH"
+ ],
+ "maxDecimals": 8,
+ "minimalOrder": {
+ "amount": 0.0001,
+ "unit": "asset"
+ }
+ },
+ {
+ "pair": [
+ "BTC",
+ "AUR"
+ ],
+ "maxDecimals": 8,
+ "minimalOrder": {
+ "amount": 0.0001,
+ "unit": "asset"
+ }
+ },
+ {
+ "pair": [
+ "BTC",
+ "AXIS"
+ ],
+ "maxDecimals": 8,
+ "minimalOrder": {
+ "amount": 0.0001,
+ "unit": "asset"
+ }
+ },
+ {
+ "pair": [
+ "BTC",
+ "BALLS"
+ ],
+ "maxDecimals": 8,
+ "minimalOrder": {
+ "amount": 0.0001,
+ "unit": "asset"
+ }
+ },
+ {
+ "pair": [
+ "BTC",
+ "BANK"
+ ],
+ "maxDecimals": 8,
+ "minimalOrder": {
+ "amount": 0.0001,
+ "unit": "asset"
+ }
+ },
+ {
+ "pair": [
+ "BTC",
+ "BBL"
+ ],
+ "maxDecimals": 8,
+ "minimalOrder": {
+ "amount": 0.0001,
+ "unit": "asset"
+ }
+ },
+ {
+ "pair": [
+ "BTC",
+ "BBR"
+ ],
+ "maxDecimals": 8,
+ "minimalOrder": {
+ "amount": 0.0001,
+ "unit": "asset"
+ }
+ },
+ {
+ "pair": [
+ "BTC",
+ "BCC"
+ ],
+ "maxDecimals": 8,
+ "minimalOrder": {
+ "amount": 0.0001,
+ "unit": "asset"
+ }
+ },
+ {
+ "pair": [
+ "BTC",
+ "BCN"
+ ],
+ "maxDecimals": 8,
+ "minimalOrder": {
+ "amount": 0.0001,
+ "unit": "asset"
+ }
+ },
+ {
+ "pair": [
+ "BTC",
+ "BCH"
+ ],
+ "maxDecimals": 8,
+ "minimalOrder": {
+ "amount": 0.0001,
+ "unit": "asset"
+ }
+ },
+ {
+ "pair": [
+ "BTC",
+ "BCY"
+ ],
+ "maxDecimals": 8,
+ "minimalOrder": {
+ "amount": 0.0001,
+ "unit": "asset"
+ }
+ },
+ {
+ "pair": [
+ "BTC",
+ "BDC"
+ ],
+ "maxDecimals": 8,
+ "minimalOrder": {
+ "amount": 0.0001,
+ "unit": "asset"
+ }
+ },
+ {
+ "pair": [
+ "BTC",
+ "BDG"
+ ],
+ "maxDecimals": 8,
+ "minimalOrder": {
+ "amount": 0.0001,
+ "unit": "asset"
+ }
+ },
+ {
+ "pair": [
+ "BTC",
+ "BELA"
+ ],
+ "maxDecimals": 8,
+ "minimalOrder": {
+ "amount": 0.0001,
+ "unit": "asset"
+ }
+ },
+ {
+ "pair": [
+ "BTC",
+ "BITCNY"
+ ],
+ "maxDecimals": 8,
+ "minimalOrder": {
+ "amount": 0.0001,
+ "unit": "asset"
+ }
+ },
+ {
+ "pair": [
+ "BTC",
+ "BITS"
+ ],
+ "maxDecimals": 8,
+ "minimalOrder": {
+ "amount": 0.0001,
+ "unit": "asset"
+ }
+ },
+ {
+ "pair": [
+ "BTC",
+ "BITUSD"
+ ],
+ "maxDecimals": 8,
+ "minimalOrder": {
+ "amount": 0.0001,
+ "unit": "asset"
+ }
+ },
+ {
+ "pair": [
+ "BTC",
+ "BLK"
+ ],
+ "maxDecimals": 8,
+ "minimalOrder": {
+ "amount": 0.0001,
+ "unit": "asset"
+ }
+ },
+ {
+ "pair": [
+ "BTC",
+ "BLOCK"
+ ],
+ "maxDecimals": 8,
+ "minimalOrder": {
+ "amount": 0.0001,
+ "unit": "asset"
+ }
+ },
+ {
+ "pair": [
+ "BTC",
+ "BLU"
+ ],
+ "maxDecimals": 8,
+ "minimalOrder": {
+ "amount": 0.0001,
+ "unit": "asset"
+ }
+ },
+ {
+ "pair": [
+ "BTC",
+ "BNS"
+ ],
+ "maxDecimals": 8,
+ "minimalOrder": {
+ "amount": 0.0001,
+ "unit": "asset"
+ }
+ },
+ {
+ "pair": [
+ "BTC",
+ "BONES"
+ ],
+ "maxDecimals": 8,
+ "minimalOrder": {
+ "amount": 0.0001,
+ "unit": "asset"
+ }
+ },
+ {
+ "pair": [
+ "BTC",
+ "BOST"
+ ],
+ "maxDecimals": 8,
+ "minimalOrder": {
+ "amount": 0.0001,
+ "unit": "asset"
+ }
+ },
+ {
+ "pair": [
+ "BTC",
+ "BTCD"
+ ],
+ "maxDecimals": 8,
+ "minimalOrder": {
+ "amount": 0.0001,
+ "unit": "asset"
+ }
+ },
+ {
+ "pair": [
+ "BTC",
+ "BTCS"
+ ],
+ "maxDecimals": 8,
+ "minimalOrder": {
+ "amount": 0.0001,
+ "unit": "asset"
+ }
+ },
+ {
+ "pair": [
+ "BTC",
+ "BTM"
+ ],
+ "maxDecimals": 8,
+ "minimalOrder": {
+ "amount": 0.0001,
+ "unit": "asset"
+ }
+ },
+ {
+ "pair": [
+ "BTC",
+ "BTS"
+ ],
+ "maxDecimals": 8,
+ "minimalOrder": {
+ "amount": 0.0001,
+ "unit": "asset"
+ }
+ },
+ {
+ "pair": [
+ "BTC",
+ "BURN"
+ ],
+ "maxDecimals": 8,
+ "minimalOrder": {
+ "amount": 0.0001,
+ "unit": "asset"
+ }
+ },
+ {
+ "pair": [
+ "BTC",
+ "BURST"
+ ],
+ "maxDecimals": 8,
+ "minimalOrder": {
+ "amount": 0.0001,
+ "unit": "asset"
+ }
+ },
+ {
+ "pair": [
+ "BTC",
+ "C2"
+ ],
+ "maxDecimals": 8,
+ "minimalOrder": {
+ "amount": 0.0001,
+ "unit": "asset"
+ }
+ },
+ {
+ "pair": [
+ "BTC",
+ "CACH"
+ ],
+ "maxDecimals": 8,
+ "minimalOrder": {
+ "amount": 0.0001,
+ "unit": "asset"
+ }
+ },
+ {
+ "pair": [
+ "BTC",
+ "CAI"
+ ],
+ "maxDecimals": 8,
+ "minimalOrder": {
+ "amount": 0.0001,
+ "unit": "asset"
+ }
+ },
+ {
+ "pair": [
+ "BTC",
+ "CC"
+ ],
+ "maxDecimals": 8,
+ "minimalOrder": {
+ "amount": 0.0001,
+ "unit": "asset"
+ }
+ },
+ {
+ "pair": [
+ "BTC",
+ "CCN"
+ ],
+ "maxDecimals": 8,
+ "minimalOrder": {
+ "amount": 0.0001,
+ "unit": "asset"
+ }
+ },
+ {
+ "pair": [
+ "BTC",
+ "CGA"
+ ],
+ "maxDecimals": 8,
+ "minimalOrder": {
+ "amount": 0.0001,
+ "unit": "asset"
+ }
+ },
+ {
+ "pair": [
+ "BTC",
+ "CHA"
+ ],
+ "maxDecimals": 8,
+ "minimalOrder": {
+ "amount": 0.0001,
+ "unit": "asset"
+ }
+ },
+ {
+ "pair": [
+ "BTC",
+ "CINNI"
+ ],
+ "maxDecimals": 8,
+ "minimalOrder": {
+ "amount": 0.0001,
+ "unit": "asset"
+ }
+ },
+ {
+ "pair": [
+ "BTC",
+ "CLAM"
+ ],
+ "maxDecimals": 8,
+ "minimalOrder": {
+ "amount": 0.0001,
+ "unit": "asset"
+ }
+ },
+ {
+ "pair": [
+ "BTC",
+ "CNL"
+ ],
+ "maxDecimals": 8,
+ "minimalOrder": {
+ "amount": 0.0001,
+ "unit": "asset"
+ }
+ },
+ {
+ "pair": [
+ "BTC",
+ "CNMT"
+ ],
+ "maxDecimals": 8,
+ "minimalOrder": {
+ "amount": 0.0001,
+ "unit": "asset"
+ }
+ },
+ {
+ "pair": [
+ "BTC",
+ "CNOTE"
+ ],
+ "maxDecimals": 8,
+ "minimalOrder": {
+ "amount": 0.0001,
+ "unit": "asset"
+ }
+ },
+ {
+ "pair": [
+ "BTC",
+ "COMM"
+ ],
+ "maxDecimals": 8,
+ "minimalOrder": {
+ "amount": 0.0001,
+ "unit": "asset"
+ }
+ },
+ {
+ "pair": [
+ "BTC",
+ "CON"
+ ],
+ "maxDecimals": 8,
+ "minimalOrder": {
+ "amount": 0.0001,
+ "unit": "asset"
+ }
+ },
+ {
+ "pair": [
+ "BTC",
+ "CORG"
+ ],
+ "maxDecimals": 8,
+ "minimalOrder": {
+ "amount": 0.0001,
+ "unit": "asset"
+ }
+ },
+ {
+ "pair": [
+ "BTC",
+ "CRYPT"
+ ],
+ "maxDecimals": 8,
+ "minimalOrder": {
+ "amount": 0.0001,
+ "unit": "asset"
+ }
+ },
+ {
+ "pair": [
+ "BTC",
+ "CURE"
+ ],
+ "maxDecimals": 8,
+ "minimalOrder": {
+ "amount": 0.0001,
+ "unit": "asset"
+ }
+ },
+ {
+ "pair": [
+ "BTC",
+ "CVC"
+ ],
+ "maxDecimals": 8,
+ "minimalOrder": {
+ "amount": 0.0001,
+ "unit": "asset"
+ }
+ },
+ {
+ "pair": [
+ "BTC",
+ "CYC"
+ ],
+ "maxDecimals": 8,
+ "minimalOrder": {
+ "amount": 0.0001,
+ "unit": "asset"
+ }
+ },
+ {
+ "pair": [
+ "BTC",
+ "DAO"
+ ],
+ "maxDecimals": 8,
+ "minimalOrder": {
+ "amount": 0.0001,
+ "unit": "asset"
+ }
+ },
+ {
+ "pair": [
+ "BTC",
+ "DASH"
+ ],
+ "maxDecimals": 8,
+ "minimalOrder": {
+ "amount": 0.0001,
+ "unit": "asset"
+ }
+ },
+ {
+ "pair": [
+ "BTC",
+ "DCR"
+ ],
+ "maxDecimals": 8,
+ "minimalOrder": {
+ "amount": 0.0001,
+ "unit": "asset"
+ }
+ },
+ {
+ "pair": [
+ "BTC",
+ "DGB"
+ ],
+ "maxDecimals": 8,
+ "minimalOrder": {
+ "amount": 0.0001,
+ "unit": "asset"
+ }
+ },
+ {
+ "pair": [
+ "BTC",
+ "DICE"
+ ],
+ "maxDecimals": 8,
+ "minimalOrder": {
+ "amount": 0.0001,
+ "unit": "asset"
+ }
+ },
+ {
+ "pair": [
+ "BTC",
+ "DIEM"
+ ],
+ "maxDecimals": 8,
+ "minimalOrder": {
+ "amount": 0.0001,
+ "unit": "asset"
+ }
+ },
+ {
+ "pair": [
+ "BTC",
+ "DIME"
+ ],
+ "maxDecimals": 8,
+ "minimalOrder": {
+ "amount": 0.0001,
+ "unit": "asset"
+ }
+ },
+ {
+ "pair": [
+ "BTC",
+ "DIS"
+ ],
+ "maxDecimals": 8,
+ "minimalOrder": {
+ "amount": 0.0001,
+ "unit": "asset"
+ }
+ },
+ {
+ "pair": [
+ "BTC",
+ "DNS"
+ ],
+ "maxDecimals": 8,
+ "minimalOrder": {
+ "amount": 0.0001,
+ "unit": "asset"
+ }
+ },
+ {
+ "pair": [
+ "BTC",
+ "DOGE"
+ ],
+ "maxDecimals": 8,
+ "minimalOrder": {
+ "amount": 0.0001,
+ "unit": "asset"
+ }
+ },
+ {
+ "pair": [
+ "BTC",
+ "DRKC"
+ ],
+ "maxDecimals": 8,
+ "minimalOrder": {
+ "amount": 0.0001,
+ "unit": "asset"
+ }
+ },
+ {
+ "pair": [
+ "BTC",
+ "DRM"
+ ],
+ "maxDecimals": 8,
+ "minimalOrder": {
+ "amount": 0.0001,
+ "unit": "asset"
+ }
+ },
+ {
+ "pair": [
+ "BTC",
+ "DSH"
+ ],
+ "maxDecimals": 8,
+ "minimalOrder": {
+ "amount": 0.0001,
+ "unit": "asset"
+ }
+ },
+ {
+ "pair": [
+ "BTC",
+ "DVK"
+ ],
+ "maxDecimals": 8,
+ "minimalOrder": {
+ "amount": 0.0001,
+ "unit": "asset"
+ }
+ },
+ {
+ "pair": [
+ "BTC",
+ "EAC"
+ ],
+ "maxDecimals": 8,
+ "minimalOrder": {
+ "amount": 0.0001,
+ "unit": "asset"
+ }
+ },
+ {
+ "pair": [
+ "BTC",
+ "EBT"
+ ],
+ "maxDecimals": 8,
+ "minimalOrder": {
+ "amount": 0.0001,
+ "unit": "asset"
+ }
+ },
+ {
+ "pair": [
+ "BTC",
+ "ECC"
+ ],
+ "maxDecimals": 8,
+ "minimalOrder": {
+ "amount": 0.0001,
+ "unit": "asset"
+ }
+ },
+ {
+ "pair": [
+ "BTC",
+ "EFL"
+ ],
+ "maxDecimals": 8,
+ "minimalOrder": {
+ "amount": 0.0001,
+ "unit": "asset"
+ }
+ },
+ {
+ "pair": [
+ "BTC",
+ "EMC2"
+ ],
+ "maxDecimals": 8,
+ "minimalOrder": {
+ "amount": 0.0001,
+ "unit": "asset"
+ }
+ },
+ {
+ "pair": [
+ "BTC",
+ "EMO"
+ ],
+ "maxDecimals": 8,
+ "minimalOrder": {
+ "amount": 0.0001,
+ "unit": "asset"
+ }
+ },
+ {
+ "pair": [
+ "BTC",
+ "ENC"
+ ],
+ "maxDecimals": 8,
+ "minimalOrder": {
+ "amount": 0.0001,
+ "unit": "asset"
+ }
+ },
+ {
+ "pair": [
+ "BTC",
+ "ETC"
+ ],
+ "maxDecimals": 8,
+ "minimalOrder": {
+ "amount": 0.0001,
+ "unit": "asset"
+ }
+ },
+ {
+ "pair": [
+ "BTC",
+ "ETH"
+ ],
+ "maxDecimals": 8,
+ "minimalOrder": {
+ "amount": 0.0001,
+ "unit": "asset"
+ }
+ },
+ {
+ "pair": [
+ "BTC",
+ "eTOK"
+ ],
+ "maxDecimals": 8,
+ "minimalOrder": {
+ "amount": 0.0001,
+ "unit": "asset"
+ }
+ },
+ {
+ "pair": [
+ "BTC",
+ "EXE"
+ ],
+ "maxDecimals": 8,
+ "minimalOrder": {
+ "amount": 0.0001,
+ "unit": "asset"
+ }
+ },
+ {
+ "pair": [
+ "BTC",
+ "EXP"
+ ],
+ "maxDecimals": 8,
+ "minimalOrder": {
+ "amount": 0.0001,
+ "unit": "asset"
+ }
+ },
+ {
+ "pair": [
+ "BTC",
+ "FAC"
+ ],
+ "maxDecimals": 8,
+ "minimalOrder": {
+ "amount": 0.0001,
+ "unit": "asset"
+ }
+ },
+ {
+ "pair": [
+ "BTC",
+ "FCN"
+ ],
+ "maxDecimals": 8,
+ "minimalOrder": {
+ "amount": 0.0001,
+ "unit": "asset"
+ }
+ },
+ {
+ "pair": [
+ "BTC",
+ "FCT"
+ ],
+ "maxDecimals": 8,
+ "minimalOrder": {
+ "amount": 0.0001,
+ "unit": "asset"
+ }
+ },
+ {
+ "pair": [
+ "BTC",
+ "FIBRE"
+ ],
+ "maxDecimals": 8,
+ "minimalOrder": {
+ "amount": 0.0001,
+ "unit": "asset"
+ }
+ },
+ {
+ "pair": [
+ "BTC",
+ "FLAP"
+ ],
+ "maxDecimals": 8,
+ "minimalOrder": {
+ "amount": 0.0001,
+ "unit": "asset"
+ }
+ },
+ {
+ "pair": [
+ "BTC",
+ "FLDC"
+ ],
+ "maxDecimals": 8,
+ "minimalOrder": {
+ "amount": 0.0001,
+ "unit": "asset"
+ }
+ },
+ {
+ "pair": [
+ "BTC",
+ "FLO"
+ ],
+ "maxDecimals": 8,
+ "minimalOrder": {
+ "amount": 0.0001,
+ "unit": "asset"
+ }
+ },
+ {
+ "pair": [
+ "BTC",
+ "FLT"
+ ],
+ "maxDecimals": 8,
+ "minimalOrder": {
+ "amount": 0.0001,
+ "unit": "asset"
+ }
+ },
+ {
+ "pair": [
+ "BTC",
+ "FOX"
+ ],
+ "maxDecimals": 8,
+ "minimalOrder": {
+ "amount": 0.0001,
+ "unit": "asset"
+ }
+ },
+ {
+ "pair": [
+ "BTC",
+ "FRAC"
+ ],
+ "maxDecimals": 8,
+ "minimalOrder": {
+ "amount": 0.0001,
+ "unit": "asset"
+ }
+ },
+ {
+ "pair": [
+ "BTC",
+ "FRK"
+ ],
+ "maxDecimals": 8,
+ "minimalOrder": {
+ "amount": 0.0001,
+ "unit": "asset"
+ }
+ },
+ {
+ "pair": [
+ "BTC",
+ "FRQ"
+ ],
+ "maxDecimals": 8,
+ "minimalOrder": {
+ "amount": 0.0001,
+ "unit": "asset"
+ }
+ },
+ {
+ "pair": [
+ "BTC",
+ "FVZ"
+ ],
+ "maxDecimals": 8,
+ "minimalOrder": {
+ "amount": 0.0001,
+ "unit": "asset"
+ }
+ },
+ {
+ "pair": [
+ "BTC",
+ "FZ"
+ ],
+ "maxDecimals": 8,
+ "minimalOrder": {
+ "amount": 0.0001,
+ "unit": "asset"
+ }
+ },
+ {
+ "pair": [
+ "BTC",
+ "FZN"
+ ],
+ "maxDecimals": 8,
+ "minimalOrder": {
+ "amount": 0.0001,
+ "unit": "asset"
+ }
+ },
+ {
+ "pair": [
+ "BTC",
+ "GAME"
+ ],
+ "maxDecimals": 8,
+ "minimalOrder": {
+ "amount": 0.0001,
+ "unit": "asset"
+ }
+ },
+ {
+ "pair": [
+ "BTC",
+ "GAP"
+ ],
+ "maxDecimals": 8,
+ "minimalOrder": {
+ "amount": 0.0001,
+ "unit": "asset"
+ }
+ },
+ {
+ "pair": [
+ "BTC",
+ "GAS"
+ ],
+ "maxDecimals": 8,
+ "minimalOrder": {
+ "amount": 0.0001,
+ "unit": "asset"
+ }
+ },
+ {
+ "pair": [
+ "BTC",
+ "GDN"
+ ],
+ "maxDecimals": 8,
+ "minimalOrder": {
+ "amount": 0.0001,
+ "unit": "asset"
+ }
+ },
+ {
+ "pair": [
+ "BTC",
+ "GEMZ"
+ ],
+ "maxDecimals": 8,
+ "minimalOrder": {
+ "amount": 0.0001,
+ "unit": "asset"
+ }
+ },
+ {
+ "pair": [
+ "BTC",
+ "GEO"
+ ],
+ "maxDecimals": 8,
+ "minimalOrder": {
+ "amount": 0.0001,
+ "unit": "asset"
+ }
+ },
+ {
+ "pair": [
+ "BTC",
+ "GIAR"
+ ],
+ "maxDecimals": 8,
+ "minimalOrder": {
+ "amount": 0.0001,
+ "unit": "asset"
+ }
+ },
+ {
+ "pair": [
+ "BTC",
+ "GLB"
+ ],
+ "maxDecimals": 8,
+ "minimalOrder": {
+ "amount": 0.0001,
+ "unit": "asset"
+ }
+ },
+ {
+ "pair": [
+ "BTC",
+ "GML"
+ ],
+ "maxDecimals": 8,
+ "minimalOrder": {
+ "amount": 0.0001,
+ "unit": "asset"
+ }
+ },
+ {
+ "pair": [
+ "BTC",
+ "GNS"
+ ],
+ "maxDecimals": 8,
+ "minimalOrder": {
+ "amount": 0.0001,
+ "unit": "asset"
+ }
+ },
+ {
+ "pair": [
+ "BTC",
+ "GOLD"
+ ],
+ "maxDecimals": 8,
+ "minimalOrder": {
+ "amount": 0.0001,
+ "unit": "asset"
+ }
+ },
+ {
+ "pair": [
+ "BTC",
+ "GPC"
+ ],
+ "maxDecimals": 8,
+ "minimalOrder": {
+ "amount": 0.0001,
+ "unit": "asset"
+ }
+ },
+ {
+ "pair": [
+ "BTC",
+ "GPUC"
+ ],
+ "maxDecimals": 8,
+ "minimalOrder": {
+ "amount": 0.0001,
+ "unit": "asset"
+ }
+ },
+ {
+ "pair": [
+ "BTC",
+ "GRC"
+ ],
+ "maxDecimals": 8,
+ "minimalOrder": {
+ "amount": 0.0001,
+ "unit": "asset"
+ }
+ },
+ {
+ "pair": [
+ "BTC",
+ "GRCX"
+ ],
+ "maxDecimals": 8,
+ "minimalOrder": {
+ "amount": 0.0001,
+ "unit": "asset"
+ }
+ },
+ {
+ "pair": [
+ "BTC",
+ "GRS"
+ ],
+ "maxDecimals": 8,
+ "minimalOrder": {
+ "amount": 0.0001,
+ "unit": "asset"
+ }
+ },
+ {
+ "pair": [
+ "BTC",
+ "GUE"
+ ],
+ "maxDecimals": 8,
+ "minimalOrder": {
+ "amount": 0.0001,
+ "unit": "asset"
+ }
+ },
+ {
+ "pair": [
+ "BTC",
+ "H2O"
+ ],
+ "maxDecimals": 8,
+ "minimalOrder": {
+ "amount": 0.0001,
+ "unit": "asset"
+ }
+ },
+ {
+ "pair": [
+ "BTC",
+ "HIRO"
+ ],
+ "maxDecimals": 8,
+ "minimalOrder": {
+ "amount": 0.0001,
+ "unit": "asset"
+ }
+ },
+ {
+ "pair": [
+ "BTC",
+ "HOT"
+ ],
+ "maxDecimals": 8,
+ "minimalOrder": {
+ "amount": 0.0001,
+ "unit": "asset"
+ }
+ },
+ {
+ "pair": [
+ "BTC",
+ "HUC"
+ ],
+ "maxDecimals": 8,
+ "minimalOrder": {
+ "amount": 0.0001,
+ "unit": "asset"
+ }
+ },
+ {
+ "pair": [
+ "BTC",
+ "HUGE"
+ ],
+ "maxDecimals": 8,
+ "minimalOrder": {
+ "amount": 0.0001,
+ "unit": "asset"
+ }
+ },
+ {
+ "pair": [
+ "BTC",
+ "HVC"
+ ],
+ "maxDecimals": 8,
+ "minimalOrder": {
+ "amount": 0.0001,
+ "unit": "asset"
+ }
+ },
+ {
+ "pair": [
+ "BTC",
+ "HYP"
+ ],
+ "maxDecimals": 8,
+ "minimalOrder": {
+ "amount": 0.0001,
+ "unit": "asset"
+ }
+ },
+ {
+ "pair": [
+ "BTC",
+ "HZ"
+ ],
+ "maxDecimals": 8,
+ "minimalOrder": {
+ "amount": 0.0001,
+ "unit": "asset"
+ }
+ },
+ {
+ "pair": [
+ "BTC",
+ "IFC"
+ ],
+ "maxDecimals": 8,
+ "minimalOrder": {
+ "amount": 0.0001,
+ "unit": "asset"
+ }
+ },
+ {
+ "pair": [
+ "BTC",
+ "INDEX"
+ ],
+ "maxDecimals": 8,
+ "minimalOrder": {
+ "amount": 0.0001,
+ "unit": "asset"
+ }
+ },
+ {
+ "pair": [
+ "BTC",
+ "IOC"
+ ],
+ "maxDecimals": 8,
+ "minimalOrder": {
+ "amount": 0.0001,
+ "unit": "asset"
+ }
+ },
+ {
+ "pair": [
+ "BTC",
+ "ITC"
+ ],
+ "maxDecimals": 8,
+ "minimalOrder": {
+ "amount": 0.0001,
+ "unit": "asset"
+ }
+ },
+ {
+ "pair": [
+ "BTC",
+ "IXC"
+ ],
+ "maxDecimals": 8,
+ "minimalOrder": {
+ "amount": 0.0001,
+ "unit": "asset"
+ }
+ },
+ {
+ "pair": [
+ "BTC",
+ "JLH"
+ ],
+ "maxDecimals": 8,
+ "minimalOrder": {
+ "amount": 0.0001,
+ "unit": "asset"
+ }
+ },
+ {
+ "pair": [
+ "BTC",
+ "JPC"
+ ],
+ "maxDecimals": 8,
+ "minimalOrder": {
+ "amount": 0.0001,
+ "unit": "asset"
+ }
+ },
+ {
+ "pair": [
+ "BTC",
+ "JUG"
+ ],
+ "maxDecimals": 8,
+ "minimalOrder": {
+ "amount": 0.0001,
+ "unit": "asset"
+ }
+ },
+ {
+ "pair": [
+ "BTC",
+ "KDC"
+ ],
+ "maxDecimals": 8,
+ "minimalOrder": {
+ "amount": 0.0001,
+ "unit": "asset"
+ }
+ },
+ {
+ "pair": [
+ "BTC",
+ "KEY"
+ ],
+ "maxDecimals": 8,
+ "minimalOrder": {
+ "amount": 0.0001,
+ "unit": "asset"
+ }
+ },
+ {
+ "pair": [
+ "BTC",
+ "LBC"
+ ],
+ "maxDecimals": 8,
+ "minimalOrder": {
+ "amount": 0.0001,
+ "unit": "asset"
+ }
+ },
+ {
+ "pair": [
+ "BTC",
+ "LC"
+ ],
+ "maxDecimals": 8,
+ "minimalOrder": {
+ "amount": 0.0001,
+ "unit": "asset"
+ }
+ },
+ {
+ "pair": [
+ "BTC",
+ "LCL"
+ ],
+ "maxDecimals": 8,
+ "minimalOrder": {
+ "amount": 0.0001,
+ "unit": "asset"
+ }
+ },
+ {
+ "pair": [
+ "BTC",
+ "LEAF"
+ ],
+ "maxDecimals": 8,
+ "minimalOrder": {
+ "amount": 0.0001,
+ "unit": "asset"
+ }
+ },
+ {
+ "pair": [
+ "BTC",
+ "LGC"
+ ],
+ "maxDecimals": 8,
+ "minimalOrder": {
+ "amount": 0.0001,
+ "unit": "asset"
+ }
+ },
+ {
+ "pair": [
+ "BTC",
+ "LOL"
+ ],
+ "maxDecimals": 8,
+ "minimalOrder": {
+ "amount": 0.0001,
+ "unit": "asset"
+ }
+ },
+ {
+ "pair": [
+ "BTC",
+ "LOVE"
+ ],
+ "maxDecimals": 8,
+ "minimalOrder": {
+ "amount": 0.0001,
+ "unit": "asset"
+ }
+ },
+ {
+ "pair": [
+ "BTC",
+ "LQD"
+ ],
+ "maxDecimals": 8,
+ "minimalOrder": {
+ "amount": 0.0001,
+ "unit": "asset"
+ }
+ },
+ {
+ "pair": [
+ "BTC",
+ "LSK"
+ ],
+ "maxDecimals": 8,
+ "minimalOrder": {
+ "amount": 0.0001,
+ "unit": "asset"
+ }
+ },
+ {
+ "pair": [
+ "BTC",
+ "LTBC"
+ ],
+ "maxDecimals": 8,
+ "minimalOrder": {
+ "amount": 0.0001,
+ "unit": "asset"
+ }
+ },
+ {
+ "pair": [
+ "BTC",
+ "LTC"
+ ],
+ "maxDecimals": 8,
+ "minimalOrder": {
+ "amount": 0.0001,
+ "unit": "asset"
+ }
+ },
+ {
+ "pair": [
+ "BTC",
+ "LTCX"
+ ],
+ "maxDecimals": 8,
+ "minimalOrder": {
+ "amount": 0.0001,
+ "unit": "asset"
+ }
+ },
+ {
+ "pair": [
+ "BTC",
+ "MAID"
+ ],
+ "maxDecimals": 8,
+ "minimalOrder": {
+ "amount": 0.0001,
+ "unit": "asset"
+ }
+ },
+ {
+ "pair": [
+ "BTC",
+ "MAST"
+ ],
+ "maxDecimals": 8,
+ "minimalOrder": {
+ "amount": 0.0001,
+ "unit": "asset"
+ }
+ },
+ {
+ "pair": [
+ "BTC",
+ "MAX"
+ ],
+ "maxDecimals": 8,
+ "minimalOrder": {
+ "amount": 0.0001,
+ "unit": "asset"
+ }
+ },
+ {
+ "pair": [
+ "BTC",
+ "MCN"
+ ],
+ "maxDecimals": 8,
+ "minimalOrder": {
+ "amount": 0.0001,
+ "unit": "asset"
+ }
+ },
+ {
+ "pair": [
+ "BTC",
+ "MEC"
+ ],
+ "maxDecimals": 8,
+ "minimalOrder": {
+ "amount": 0.0001,
+ "unit": "asset"
+ }
+ },
+ {
+ "pair": [
+ "BTC",
+ "METH"
+ ],
+ "maxDecimals": 8,
+ "minimalOrder": {
+ "amount": 0.0001,
+ "unit": "asset"
+ }
+ },
+ {
+ "pair": [
+ "BTC",
+ "MIL"
+ ],
+ "maxDecimals": 8,
+ "minimalOrder": {
+ "amount": 0.0001,
+ "unit": "asset"
+ }
+ },
+ {
+ "pair": [
+ "BTC",
+ "MIN"
+ ],
+ "maxDecimals": 8,
+ "minimalOrder": {
+ "amount": 0.0001,
+ "unit": "asset"
+ }
+ },
+ {
+ "pair": [
+ "BTC",
+ "MINT"
+ ],
+ "maxDecimals": 8,
+ "minimalOrder": {
+ "amount": 0.0001,
+ "unit": "asset"
+ }
+ },
+ {
+ "pair": [
+ "BTC",
+ "MMC"
+ ],
+ "maxDecimals": 8,
+ "minimalOrder": {
+ "amount": 0.0001,
+ "unit": "asset"
+ }
+ },
+ {
+ "pair": [
+ "BTC",
+ "MMNXT"
+ ],
+ "maxDecimals": 8,
+ "minimalOrder": {
+ "amount": 0.0001,
+ "unit": "asset"
+ }
+ },
+ {
+ "pair": [
+ "BTC",
+ "MMXIV"
+ ],
+ "maxDecimals": 8,
+ "minimalOrder": {
+ "amount": 0.0001,
+ "unit": "asset"
+ }
+ },
+ {
+ "pair": [
+ "BTC",
+ "MNTA"
+ ],
+ "maxDecimals": 8,
+ "minimalOrder": {
+ "amount": 0.0001,
+ "unit": "asset"
+ }
+ },
+ {
+ "pair": [
+ "BTC",
+ "MON"
+ ],
+ "maxDecimals": 8,
+ "minimalOrder": {
+ "amount": 0.0001,
+ "unit": "asset"
+ }
+ },
+ {
+ "pair": [
+ "BTC",
+ "MRC"
+ ],
+ "maxDecimals": 8,
+ "minimalOrder": {
+ "amount": 0.0001,
+ "unit": "asset"
+ }
+ },
+ {
+ "pair": [
+ "BTC",
+ "MRS"
+ ],
+ "maxDecimals": 8,
+ "minimalOrder": {
+ "amount": 0.0001,
+ "unit": "asset"
+ }
+ },
+ {
+ "pair": [
+ "BTC",
+ "MTS"
+ ],
+ "maxDecimals": 8,
+ "minimalOrder": {
+ "amount": 0.0001,
+ "unit": "asset"
+ }
+ },
+ {
+ "pair": [
+ "BTC",
+ "MUN"
+ ],
+ "maxDecimals": 8,
+ "minimalOrder": {
+ "amount": 0.0001,
+ "unit": "asset"
+ }
+ },
+ {
+ "pair": [
+ "BTC",
+ "MYR"
+ ],
+ "maxDecimals": 8,
+ "minimalOrder": {
+ "amount": 0.0001,
+ "unit": "asset"
+ }
+ },
+ {
+ "pair": [
+ "BTC",
+ "MZC"
+ ],
+ "maxDecimals": 8,
+ "minimalOrder": {
+ "amount": 0.0001,
+ "unit": "asset"
+ }
+ },
+ {
+ "pair": [
+ "BTC",
+ "N5X"
+ ],
+ "maxDecimals": 8,
+ "minimalOrder": {
+ "amount": 0.0001,
+ "unit": "asset"
+ }
+ },
+ {
+ "pair": [
+ "BTC",
+ "NAS"
+ ],
+ "maxDecimals": 8,
+ "minimalOrder": {
+ "amount": 0.0001,
+ "unit": "asset"
+ }
+ },
+ {
+ "pair": [
+ "BTC",
+ "NAUT"
+ ],
+ "maxDecimals": 8,
+ "minimalOrder": {
+ "amount": 0.0001,
+ "unit": "asset"
+ }
+ },
+ {
+ "pair": [
+ "BTC",
+ "NAV"
+ ],
+ "maxDecimals": 8,
+ "minimalOrder": {
+ "amount": 0.0001,
+ "unit": "asset"
+ }
+ },
+ {
+ "pair": [
+ "BTC",
+ "NBT"
+ ],
+ "maxDecimals": 8,
+ "minimalOrder": {
+ "amount": 0.0001,
+ "unit": "asset"
+ }
+ },
+ {
+ "pair": [
+ "BTC",
+ "NEOS"
+ ],
+ "maxDecimals": 8,
+ "minimalOrder": {
+ "amount": 0.0001,
+ "unit": "asset"
+ }
+ },
+ {
+ "pair": [
+ "BTC",
+ "NL"
+ ],
+ "maxDecimals": 8,
+ "minimalOrder": {
+ "amount": 0.0001,
+ "unit": "asset"
+ }
+ },
+ {
+ "pair": [
+ "BTC",
+ "NMC"
+ ],
+ "maxDecimals": 8,
+ "minimalOrder": {
+ "amount": 0.0001,
+ "unit": "asset"
+ }
+ },
+ {
+ "pair": [
+ "BTC",
+ "NOBL"
+ ],
+ "maxDecimals": 8,
+ "minimalOrder": {
+ "amount": 0.0001,
+ "unit": "asset"
+ }
+ },
+ {
+ "pair": [
+ "BTC",
+ "NOTE"
+ ],
+ "maxDecimals": 8,
+ "minimalOrder": {
+ "amount": 0.0001,
+ "unit": "asset"
+ }
+ },
+ {
+ "pair": [
+ "BTC",
+ "NOXT"
+ ],
+ "maxDecimals": 8,
+ "minimalOrder": {
+ "amount": 0.0001,
+ "unit": "asset"
+ }
+ },
+ {
+ "pair": [
+ "BTC",
+ "NRS"
+ ],
+ "maxDecimals": 8,
+ "minimalOrder": {
+ "amount": 0.0001,
+ "unit": "asset"
+ }
+ },
+ {
+ "pair": [
+ "BTC",
+ "NSR"
+ ],
+ "maxDecimals": 8,
+ "minimalOrder": {
+ "amount": 0.0001,
+ "unit": "asset"
+ }
+ },
+ {
+ "pair": [
+ "BTC",
+ "NTX"
+ ],
+ "maxDecimals": 8,
+ "minimalOrder": {
+ "amount": 0.0001,
+ "unit": "asset"
+ }
+ },
+ {
+ "pair": [
+ "BTC",
+ "NXT"
+ ],
+ "maxDecimals": 8,
+ "minimalOrder": {
+ "amount": 0.0001,
+ "unit": "asset"
+ }
+ },
+ {
+ "pair": [
+ "BTC",
+ "NXTI"
+ ],
+ "maxDecimals": 8,
+ "minimalOrder": {
+ "amount": 0.0001,
+ "unit": "asset"
+ }
+ },
+ {
+ "pair": [
+ "BTC",
+ "OMG"
+ ],
+ "maxDecimals": 8,
+ "minimalOrder": {
+ "amount": 0.0001,
+ "unit": "asset"
+ }
+ },
+ {
+ "pair": [
+ "BTC",
+ "OMNI"
+ ],
+ "maxDecimals": 8,
+ "minimalOrder": {
+ "amount": 0.0001,
+ "unit": "asset"
+ }
+ },
+ {
+ "pair": [
+ "BTC",
+ "OPAL"
+ ],
+ "maxDecimals": 8,
+ "minimalOrder": {
+ "amount": 0.0001,
+ "unit": "asset"
+ }
+ },
+ {
+ "pair": [
+ "BTC",
+ "PAND"
+ ],
+ "maxDecimals": 8,
+ "minimalOrder": {
+ "amount": 0.0001,
+ "unit": "asset"
+ }
+ },
+ {
+ "pair": [
+ "BTC",
+ "PASC"
+ ],
+ "maxDecimals": 8,
+ "minimalOrder": {
+ "amount": 0.0001,
+ "unit": "asset"
+ }
+ },
+ {
+ "pair": [
+ "BTC",
+ "PAWN"
+ ],
+ "maxDecimals": 8,
+ "minimalOrder": {
+ "amount": 0.0001,
+ "unit": "asset"
+ }
+ },
+ {
+ "pair": [
+ "BTC",
+ "PIGGY"
+ ],
+ "maxDecimals": 8,
+ "minimalOrder": {
+ "amount": 0.0001,
+ "unit": "asset"
+ }
+ },
+ {
+ "pair": [
+ "BTC",
+ "PINK"
+ ],
+ "maxDecimals": 8,
+ "minimalOrder": {
+ "amount": 0.0001,
+ "unit": "asset"
+ }
+ },
+ {
+ "pair": [
+ "BTC",
+ "PLX"
+ ],
+ "maxDecimals": 8,
+ "minimalOrder": {
+ "amount": 0.0001,
+ "unit": "asset"
+ }
+ },
+ {
+ "pair": [
+ "BTC",
+ "PMC"
+ ],
+ "maxDecimals": 8,
+ "minimalOrder": {
+ "amount": 0.0001,
+ "unit": "asset"
+ }
+ },
+ {
+ "pair": [
+ "BTC",
+ "POT"
+ ],
+ "maxDecimals": 8,
+ "minimalOrder": {
+ "amount": 0.0001,
+ "unit": "asset"
+ }
+ },
+ {
+ "pair": [
+ "BTC",
+ "PPC"
+ ],
+ "maxDecimals": 8,
+ "minimalOrder": {
+ "amount": 0.0001,
+ "unit": "asset"
+ }
+ },
+ {
+ "pair": [
+ "BTC",
+ "PRC"
+ ],
+ "maxDecimals": 8,
+ "minimalOrder": {
+ "amount": 0.0001,
+ "unit": "asset"
+ }
+ },
+ {
+ "pair": [
+ "BTC",
+ "PRT"
+ ],
+ "maxDecimals": 8,
+ "minimalOrder": {
+ "amount": 0.0001,
+ "unit": "asset"
+ }
+ },
+ {
+ "pair": [
+ "BTC",
+ "PTS"
+ ],
+ "maxDecimals": 8,
+ "minimalOrder": {
+ "amount": 0.0001,
+ "unit": "asset"
+ }
+ },
+ {
+ "pair": [
+ "BTC",
+ "Q2C"
+ ],
+ "maxDecimals": 8,
+ "minimalOrder": {
+ "amount": 0.0001,
+ "unit": "asset"
+ }
+ },
+ {
+ "pair": [
+ "BTC",
+ "QBK"
+ ],
+ "maxDecimals": 8,
+ "minimalOrder": {
+ "amount": 0.0001,
+ "unit": "asset"
+ }
+ },
+ {
+ "pair": [
+ "BTC",
+ "QCN"
+ ],
+ "maxDecimals": 8,
+ "minimalOrder": {
+ "amount": 0.0001,
+ "unit": "asset"
+ }
+ },
+ {
+ "pair": [
+ "BTC",
+ "QORA"
+ ],
+ "maxDecimals": 8,
+ "minimalOrder": {
+ "amount": 0.0001,
+ "unit": "asset"
+ }
+ },
+ {
+ "pair": [
+ "BTC",
+ "QTL"
+ ],
+ "maxDecimals": 8,
+ "minimalOrder": {
+ "amount": 0.0001,
+ "unit": "asset"
+ }
+ },
+ {
+ "pair": [
+ "BTC",
+ "RADS"
+ ],
+ "maxDecimals": 8,
+ "minimalOrder": {
+ "amount": 0.0001,
+ "unit": "asset"
+ }
+ },
+ {
+ "pair": [
+ "BTC",
+ "RBY"
+ ],
+ "maxDecimals": 8,
+ "minimalOrder": {
+ "amount": 0.0001,
+ "unit": "asset"
+ }
+ },
+ {
+ "pair": [
+ "BTC",
+ "RDD"
+ ],
+ "maxDecimals": 8,
+ "minimalOrder": {
+ "amount": 0.0001,
+ "unit": "asset"
+ }
+ },
+ {
+ "pair": [
+ "BTC",
+ "REP"
+ ],
+ "maxDecimals": 8,
+ "minimalOrder": {
+ "amount": 0.0001,
+ "unit": "asset"
+ }
+ },
+ {
+ "pair": [
+ "BTC",
+ "RIC"
+ ],
+ "maxDecimals": 8,
+ "minimalOrder": {
+ "amount": 0.0001,
+ "unit": "asset"
+ }
+ },
+ {
+ "pair": [
+ "BTC",
+ "RZR"
+ ],
+ "maxDecimals": 8,
+ "minimalOrder": {
+ "amount": 0.0001,
+ "unit": "asset"
+ }
+ },
+ {
+ "pair": [
+ "BTC",
+ "SBD"
+ ],
+ "maxDecimals": 8,
+ "minimalOrder": {
+ "amount": 0.0001,
+ "unit": "asset"
+ }
+ },
+ {
+ "pair": [
+ "BTC",
+ "SC"
+ ],
+ "maxDecimals": 8,
+ "minimalOrder": {
+ "amount": 0.0001,
+ "unit": "asset"
+ }
+ },
+ {
+ "pair": [
+ "BTC",
+ "SDC"
+ ],
+ "maxDecimals": 8,
+ "minimalOrder": {
+ "amount": 0.0001,
+ "unit": "asset"
+ }
+ },
+ {
+ "pair": [
+ "BTC",
+ "SHIBE"
+ ],
+ "maxDecimals": 8,
+ "minimalOrder": {
+ "amount": 0.0001,
+ "unit": "asset"
+ }
+ },
+ {
+ "pair": [
+ "BTC",
+ "SHOPX"
+ ],
+ "maxDecimals": 8,
+ "minimalOrder": {
+ "amount": 0.0001,
+ "unit": "asset"
+ }
+ },
+ {
+ "pair": [
+ "BTC",
+ "SILK"
+ ],
+ "maxDecimals": 8,
+ "minimalOrder": {
+ "amount": 0.0001,
+ "unit": "asset"
+ }
+ },
+ {
+ "pair": [
+ "BTC",
+ "SJCX"
+ ],
+ "maxDecimals": 8,
+ "minimalOrder": {
+ "amount": 0.0001,
+ "unit": "asset"
+ }
+ },
+ {
+ "pair": [
+ "BTC",
+ "SLR"
+ ],
+ "maxDecimals": 8,
+ "minimalOrder": {
+ "amount": 0.0001,
+ "unit": "asset"
+ }
+ },
+ {
+ "pair": [
+ "BTC",
+ "SMC"
+ ],
+ "maxDecimals": 8,
+ "minimalOrder": {
+ "amount": 0.0001,
+ "unit": "asset"
+ }
+ },
+ {
+ "pair": [
+ "BTC",
+ "SOC"
+ ],
+ "maxDecimals": 8,
+ "minimalOrder": {
+ "amount": 0.0001,
+ "unit": "asset"
+ }
+ },
+ {
+ "pair": [
+ "BTC",
+ "SPA"
+ ],
+ "maxDecimals": 8,
+ "minimalOrder": {
+ "amount": 0.0001,
+ "unit": "asset"
+ }
+ },
+ {
+ "pair": [
+ "BTC",
+ "SQL"
+ ],
+ "maxDecimals": 8,
+ "minimalOrder": {
+ "amount": 0.0001,
+ "unit": "asset"
+ }
+ },
+ {
+ "pair": [
+ "BTC",
+ "SRCC"
+ ],
+ "maxDecimals": 8,
+ "minimalOrder": {
+ "amount": 0.0001,
+ "unit": "asset"
+ }
+ },
+ {
+ "pair": [
+ "BTC",
+ "SRG"
+ ],
+ "maxDecimals": 8,
+ "minimalOrder": {
+ "amount": 0.0001,
+ "unit": "asset"
+ }
+ },
+ {
+ "pair": [
+ "BTC",
+ "SSD"
+ ],
+ "maxDecimals": 8,
+ "minimalOrder": {
+ "amount": 0.0001,
+ "unit": "asset"
+ }
+ },
+ {
+ "pair": [
+ "BTC",
+ "STEEM"
+ ],
+ "maxDecimals": 8,
+ "minimalOrder": {
+ "amount": 0.0001,
+ "unit": "asset"
+ }
+ },
+ {
+ "pair": [
+ "BTC",
+ "STR"
+ ],
+ "maxDecimals": 8,
+ "minimalOrder": {
+ "amount": 0.0001,
+ "unit": "asset"
+ }
+ },
+ {
+ "pair": [
+ "BTC",
+ "SUM"
+ ],
+ "maxDecimals": 8,
+ "minimalOrder": {
+ "amount": 0.0001,
+ "unit": "asset"
+ }
+ },
+ {
+ "pair": [
+ "BTC",
+ "SUN"
+ ],
+ "maxDecimals": 8,
+ "minimalOrder": {
+ "amount": 0.0001,
+ "unit": "asset"
+ }
+ },
+ {
+ "pair": [
+ "BTC",
+ "SWARM"
+ ],
+ "maxDecimals": 8,
+ "minimalOrder": {
+ "amount": 0.0001,
+ "unit": "asset"
+ }
+ },
+ {
+ "pair": [
+ "BTC",
+ "SXC"
+ ],
+ "maxDecimals": 8,
+ "minimalOrder": {
+ "amount": 0.0001,
+ "unit": "asset"
+ }
+ },
+ {
+ "pair": [
+ "BTC",
+ "SYNC"
+ ],
+ "maxDecimals": 8,
+ "minimalOrder": {
+ "amount": 0.0001,
+ "unit": "asset"
+ }
+ },
+ {
+ "pair": [
+ "BTC",
+ "SYS"
+ ],
+ "maxDecimals": 8,
+ "minimalOrder": {
+ "amount": 0.0001,
+ "unit": "asset"
+ }
+ },
+ {
+ "pair": [
+ "BTC",
+ "TAC"
+ ],
+ "maxDecimals": 8,
+ "minimalOrder": {
+ "amount": 0.0001,
+ "unit": "asset"
+ }
+ },
+ {
+ "pair": [
+ "BTC",
+ "TOR"
+ ],
+ "maxDecimals": 8,
+ "minimalOrder": {
+ "amount": 0.0001,
+ "unit": "asset"
+ }
+ },
+ {
+ "pair": [
+ "BTC",
+ "TRUST"
+ ],
+ "maxDecimals": 8,
+ "minimalOrder": {
+ "amount": 0.0001,
+ "unit": "asset"
+ }
+ },
+ {
+ "pair": [
+ "BTC",
+ "TWE"
+ ],
+ "maxDecimals": 8,
+ "minimalOrder": {
+ "amount": 0.0001,
+ "unit": "asset"
+ }
+ },
+ {
+ "pair": [
+ "BTC",
+ "UIS"
+ ],
+ "maxDecimals": 8,
+ "minimalOrder": {
+ "amount": 0.0001,
+ "unit": "asset"
+ }
+ },
+ {
+ "pair": [
+ "BTC",
+ "ULTC"
+ ],
+ "maxDecimals": 8,
+ "minimalOrder": {
+ "amount": 0.0001,
+ "unit": "asset"
+ }
+ },
+ {
+ "pair": [
+ "BTC",
+ "UNITY"
+ ],
+ "maxDecimals": 8,
+ "minimalOrder": {
+ "amount": 0.0001,
+ "unit": "asset"
+ }
+ },
+ {
+ "pair": [
+ "BTC",
+ "URO"
+ ],
+ "maxDecimals": 8,
+ "minimalOrder": {
+ "amount": 0.0001,
+ "unit": "asset"
+ }
+ },
+ {
+ "pair": [
+ "BTC",
+ "USDE"
+ ],
+ "maxDecimals": 8,
+ "minimalOrder": {
+ "amount": 0.0001,
+ "unit": "asset"
+ }
+ },
+ {
+ "pair": [
+ "BTC",
+ "USDT"
+ ],
+ "maxDecimals": 8,
+ "minimalOrder": {
+ "amount": 0.0001,
+ "unit": "asset"
+ }
+ },
+ {
+ "pair": [
+ "BTC",
+ "UTC"
+ ],
+ "maxDecimals": 8,
+ "minimalOrder": {
+ "amount": 0.0001,
+ "unit": "asset"
+ }
+ },
+ {
+ "pair": [
+ "BTC",
+ "UTIL"
+ ],
+ "maxDecimals": 8,
+ "minimalOrder": {
+ "amount": 0.0001,
+ "unit": "asset"
+ }
+ },
+ {
+ "pair": [
+ "BTC",
+ "UVC"
+ ],
+ "maxDecimals": 8,
+ "minimalOrder": {
+ "amount": 0.0001,
+ "unit": "asset"
+ }
+ },
+ {
+ "pair": [
+ "BTC",
+ "VIA"
+ ],
+ "maxDecimals": 8,
+ "minimalOrder": {
+ "amount": 0.0001,
+ "unit": "asset"
+ }
+ },
+ {
+ "pair": [
+ "BTC",
+ "VOOT"
+ ],
+ "maxDecimals": 8,
+ "minimalOrder": {
+ "amount": 0.0001,
+ "unit": "asset"
+ }
+ },
+ {
+ "pair": [
+ "BTC",
+ "VOX"
+ ],
+ "maxDecimals": 8,
+ "minimalOrder": {
+ "amount": 0.0001,
+ "unit": "asset"
+ }
+ },
+ {
+ "pair": [
+ "BTC",
+ "VRC"
+ ],
+ "maxDecimals": 8,
+ "minimalOrder": {
+ "amount": 0.0001,
+ "unit": "asset"
+ }
+ },
+ {
+ "pair": [
+ "BTC",
+ "VTC"
+ ],
+ "maxDecimals": 8,
+ "minimalOrder": {
+ "amount": 0.0001,
+ "unit": "asset"
+ }
+ },
+ {
+ "pair": [
+ "BTC",
+ "WC"
+ ],
+ "maxDecimals": 8,
+ "minimalOrder": {
+ "amount": 0.0001,
+ "unit": "asset"
+ }
+ },
+ {
+ "pair": [
+ "BTC",
+ "WDC"
+ ],
+ "maxDecimals": 8,
+ "minimalOrder": {
+ "amount": 0.0001,
+ "unit": "asset"
+ }
+ },
+ {
+ "pair": [
+ "BTC",
+ "WIKI"
+ ],
+ "maxDecimals": 8,
+ "minimalOrder": {
+ "amount": 0.0001,
+ "unit": "asset"
+ }
+ },
+ {
+ "pair": [
+ "BTC",
+ "WOLF"
+ ],
+ "maxDecimals": 8,
+ "minimalOrder": {
+ "amount": 0.0001,
+ "unit": "asset"
+ }
+ },
+ {
+ "pair": [
+ "BTC",
+ "X13"
+ ],
+ "maxDecimals": 8,
+ "minimalOrder": {
+ "amount": 0.0001,
+ "unit": "asset"
+ }
+ },
+ {
+ "pair": [
+ "BTC",
+ "XAI"
+ ],
+ "maxDecimals": 8,
+ "minimalOrder": {
+ "amount": 0.0001,
+ "unit": "asset"
+ }
+ },
+ {
+ "pair": [
+ "BTC",
+ "XAP"
+ ],
+ "maxDecimals": 8,
+ "minimalOrder": {
+ "amount": 0.0001,
+ "unit": "asset"
+ }
+ },
+ {
+ "pair": [
+ "BTC",
+ "XBC"
+ ],
+ "maxDecimals": 8,
+ "minimalOrder": {
+ "amount": 0.0001,
+ "unit": "asset"
+ }
+ },
+ {
+ "pair": [
+ "BTC",
+ "XC"
+ ],
+ "maxDecimals": 8,
+ "minimalOrder": {
+ "amount": 0.0001,
+ "unit": "asset"
+ }
+ },
+ {
+ "pair": [
+ "BTC",
+ "XCH"
+ ],
+ "maxDecimals": 8,
+ "minimalOrder": {
+ "amount": 0.0001,
+ "unit": "asset"
+ }
+ },
+ {
+ "pair": [
+ "BTC",
+ "XCN"
+ ],
+ "maxDecimals": 8,
+ "minimalOrder": {
+ "amount": 0.0001,
+ "unit": "asset"
+ }
+ },
+ {
+ "pair": [
+ "BTC",
+ "XCP"
+ ],
+ "maxDecimals": 8,
+ "minimalOrder": {
+ "amount": 0.0001,
+ "unit": "asset"
+ }
+ },
+ {
+ "pair": [
+ "BTC",
+ "XCR"
+ ],
+ "maxDecimals": 8,
+ "minimalOrder": {
+ "amount": 0.0001,
+ "unit": "asset"
+ }
+ },
+ {
+ "pair": [
+ "BTC",
+ "XDN"
+ ],
+ "maxDecimals": 8,
+ "minimalOrder": {
+ "amount": 0.0001,
+ "unit": "asset"
+ }
+ },
+ {
+ "pair": [
+ "BTC",
+ "XDP"
+ ],
+ "maxDecimals": 8,
+ "minimalOrder": {
+ "amount": 0.0001,
+ "unit": "asset"
+ }
+ },
+ {
+ "pair": [
+ "BTC",
+ "XEM"
+ ],
+ "maxDecimals": 8,
+ "minimalOrder": {
+ "amount": 0.0001,
+ "unit": "asset"
+ }
+ },
+ {
+ "pair": [
+ "BTC",
+ "XHC"
+ ],
+ "maxDecimals": 8,
+ "minimalOrder": {
+ "amount": 0.0001,
+ "unit": "asset"
+ }
+ },
+ {
+ "pair": [
+ "BTC",
+ "XLB"
+ ],
+ "maxDecimals": 8,
+ "minimalOrder": {
+ "amount": 0.0001,
+ "unit": "asset"
+ }
+ },
+ {
+ "pair": [
+ "BTC",
+ "XMG"
+ ],
+ "maxDecimals": 8,
+ "minimalOrder": {
+ "amount": 0.0001,
+ "unit": "asset"
+ }
+ },
+ {
+ "pair": [
+ "BTC",
+ "XMR"
+ ],
+ "maxDecimals": 8,
+ "minimalOrder": {
+ "amount": 0.0001,
+ "unit": "asset"
+ }
+ },
+ {
+ "pair": [
+ "BTC",
+ "XPB"
+ ],
+ "maxDecimals": 8,
+ "minimalOrder": {
+ "amount": 0.0001,
+ "unit": "asset"
+ }
+ },
+ {
+ "pair": [
+ "BTC",
+ "XPM"
+ ],
+ "maxDecimals": 8,
+ "minimalOrder": {
+ "amount": 0.0001,
+ "unit": "asset"
+ }
+ },
+ {
+ "pair": [
+ "BTC",
+ "XRP"
+ ],
+ "maxDecimals": 8,
+ "minimalOrder": {
+ "amount": 0.0001,
+ "unit": "asset"
+ }
+ },
+ {
+ "pair": [
+ "BTC",
+ "XSI"
+ ],
+ "maxDecimals": 8,
+ "minimalOrder": {
+ "amount": 0.0001,
+ "unit": "asset"
+ }
+ },
+ {
+ "pair": [
+ "BTC",
+ "XST"
+ ],
+ "maxDecimals": 8,
+ "minimalOrder": {
+ "amount": 0.0001,
+ "unit": "asset"
+ }
+ },
+ {
+ "pair": [
+ "BTC",
+ "XSV"
+ ],
+ "maxDecimals": 8,
+ "minimalOrder": {
+ "amount": 0.0001,
+ "unit": "asset"
+ }
+ },
+ {
+ "pair": [
+ "BTC",
+ "XUSD"
+ ],
+ "maxDecimals": 8,
+ "minimalOrder": {
+ "amount": 0.0001,
+ "unit": "asset"
+ }
+ },
+ {
+ "pair": [
+ "BTC",
+ "XVC"
+ ],
+ "maxDecimals": 8,
+ "minimalOrder": {
+ "amount": 0.0001,
+ "unit": "asset"
+ }
+ },
+ {
+ "pair": [
+ "BTC",
+ "XXC"
+ ],
+ "maxDecimals": 8,
+ "minimalOrder": {
+ "amount": 0.0001,
+ "unit": "asset"
+ }
+ },
+ {
+ "pair": [
+ "BTC",
+ "YACC"
+ ],
+ "maxDecimals": 8,
+ "minimalOrder": {
+ "amount": 0.0001,
+ "unit": "asset"
+ }
+ },
+ {
+ "pair": [
+ "BTC",
+ "YANG"
+ ],
+ "maxDecimals": 8,
+ "minimalOrder": {
+ "amount": 0.0001,
+ "unit": "asset"
+ }
+ },
+ {
+ "pair": [
+ "BTC",
+ "YC"
+ ],
+ "maxDecimals": 8,
+ "minimalOrder": {
+ "amount": 0.0001,
+ "unit": "asset"
+ }
+ },
+ {
+ "pair": [
+ "BTC",
+ "YIN"
+ ],
+ "maxDecimals": 8,
+ "minimalOrder": {
+ "amount": 0.0001,
+ "unit": "asset"
+ }
+ },
+ {
+ "pair": [
+ "BTC",
+ "ZEC"
+ ],
+ "maxDecimals": 8,
+ "minimalOrder": {
+ "amount": 0.0001,
+ "unit": "asset"
+ }
+ },
+ {
+ "pair": [
+ "BTC",
+ "ZRX"
+ ],
+ "maxDecimals": 8,
+ "minimalOrder": {
+ "amount": 0.0001,
+ "unit": "asset"
+ }
+ },
+ {
+ "pair": [
+ "USDT",
+ "BTC"
+ ],
+ "maxDecimals": 8,
+ "minimalOrder": {
+ "amount": 0.0001,
+ "unit": "asset"
+ }
+ },
+ {
+ "pair": [
+ "USDT",
+ "BCH"
+ ],
+ "maxDecimals": 8,
+ "minimalOrder": {
+ "amount": 0.0001,
+ "unit": "asset"
+ }
+ },
+ {
+ "pair": [
+ "USDT",
+ "DASH"
+ ],
+ "maxDecimals": 8,
+ "minimalOrder": {
+ "amount": 0.0001,
+ "unit": "asset"
+ }
+ },
+ {
+ "pair": [
+ "USDT",
+ "ETC"
+ ],
+ "maxDecimals": 8,
+ "minimalOrder": {
+ "amount": 0.0001,
+ "unit": "asset"
+ }
+ },
+ {
+ "pair": [
+ "USDT",
+ "ETH"
+ ],
+ "maxDecimals": 8,
+ "minimalOrder": {
+ "amount": 0.0001,
+ "unit": "asset"
+ }
+ },
+ {
+ "pair": [
+ "USDT",
+ "LTC"
+ ],
+ "maxDecimals": 8,
+ "minimalOrder": {
+ "amount": 0.0001,
+ "unit": "asset"
+ }
+ },
+ {
+ "pair": [
+ "USDT",
+ "NXT"
+ ],
+ "maxDecimals": 8,
+ "minimalOrder": {
+ "amount": 0.0001,
+ "unit": "asset"
+ }
+ },
+ {
+ "pair": [
+ "USDT",
+ "REP"
+ ],
+ "maxDecimals": 8,
+ "minimalOrder": {
+ "amount": 0.0001,
+ "unit": "asset"
+ }
+ },
+ {
+ "pair": [
+ "USDT",
+ "STR"
+ ],
+ "maxDecimals": 8,
+ "minimalOrder": {
+ "amount": 0.0001,
+ "unit": "asset"
+ }
+ },
+ {
+ "pair": [
+ "USDT",
+ "XMR"
+ ],
+ "maxDecimals": 8,
+ "minimalOrder": {
+ "amount": 0.0001,
+ "unit": "asset"
+ }
+ },
+ {
+ "pair": [
+ "USDT",
+ "XRP"
+ ],
+ "maxDecimals": 8,
+ "minimalOrder": {
+ "amount": 0.0001,
+ "unit": "asset"
+ }
+ },
+ {
+ "pair": [
+ "USDT",
+ "ZEC"
+ ],
+ "maxDecimals": 8,
+ "minimalOrder": {
+ "amount": 0.0001,
+ "unit": "asset"
+ }
+ },
+ {
+ "pair": [
+ "ETH",
+ "CVC"
+ ],
+ "maxDecimals": 8,
+ "minimalOrder": {
+ "amount": 0.0001,
+ "unit": "asset"
+ }
+ },
+ {
+ "pair": [
+ "ETH",
+ "ETC"
+ ],
+ "maxDecimals": 8,
+ "minimalOrder": {
+ "amount": 0.0001,
+ "unit": "asset"
+ }
+ },
+ {
+ "pair": [
+ "ETH",
+ "BCH"
+ ],
+ "maxDecimals": 8,
+ "minimalOrder": {
+ "amount": 0.0001,
+ "unit": "asset"
+ }
+ },
+ {
+ "pair": [
+ "ETH",
+ "GAS"
+ ],
+ "maxDecimals": 8,
+ "minimalOrder": {
+ "amount": 0.0001,
+ "unit": "asset"
+ }
+ },
+ {
+ "pair": [
+ "ETH",
+ "GNO"
+ ],
+ "maxDecimals": 8,
+ "minimalOrder": {
+ "amount": 0.0001,
+ "unit": "asset"
+ }
+ },
+ {
+ "pair": [
+ "ETH",
+ "GNT"
+ ],
+ "maxDecimals": 8,
+ "minimalOrder": {
+ "amount": 0.0001,
+ "unit": "asset"
+ }
+ },
+ {
+ "pair": [
+ "ETH",
+ "LSK"
+ ],
+ "maxDecimals": 8,
+ "minimalOrder": {
+ "amount": 0.0001,
+ "unit": "asset"
+ }
+ },
+ {
+ "pair": [
+ "ETH",
+ "OMG"
+ ],
+ "maxDecimals": 8,
+ "minimalOrder": {
+ "amount": 0.0001,
+ "unit": "asset"
+ }
+ },
+ {
+ "pair": [
+ "ETH",
+ "REP"
+ ],
+ "maxDecimals": 8,
+ "minimalOrder": {
+ "amount": 0.0001,
+ "unit": "asset"
+ }
+ },
+ {
+ "pair": [
+ "ETH",
+ "STEEM"
+ ],
+ "maxDecimals": 8,
+ "minimalOrder": {
+ "amount": 0.0001,
+ "unit": "asset"
+ }
+ },
+ {
+ "pair": [
+ "ETH",
+ "ZEC"
+ ],
+ "maxDecimals": 8,
+ "minimalOrder": {
+ "amount": 0.0001,
+ "unit": "asset"
+ }
+ },
+ {
+ "pair": [
+ "ETH",
+ "ZRX"
+ ],
+ "maxDecimals": 8,
+ "minimalOrder": {
+ "amount": 0.0001,
+ "unit": "asset"
+ }
+ },
+ {
+ "pair": [
+ "XMR",
+ "BCN"
+ ],
+ "maxDecimals": 8,
+ "minimalOrder": {
+ "amount": 0.0001,
+ "unit": "asset"
+ }
+ },
+ {
+ "pair": [
+ "XMR",
+ "BLK"
+ ],
+ "maxDecimals": 8,
+ "minimalOrder": {
+ "amount": 0.0001,
+ "unit": "asset"
+ }
+ },
+ {
+ "pair": [
+ "XMR",
+ "BTCD"
+ ],
+ "maxDecimals": 8,
+ "minimalOrder": {
+ "amount": 0.0001,
+ "unit": "asset"
+ }
+ },
+ {
+ "pair": [
+ "XMR",
+ "DASH"
+ ],
+ "maxDecimals": 8,
+ "minimalOrder": {
+ "amount": 0.0001,
+ "unit": "asset"
+ }
+ },
+ {
+ "pair": [
+ "XMR",
+ "LTC"
+ ],
+ "maxDecimals": 8,
+ "minimalOrder": {
+ "amount": 0.0001,
+ "unit": "asset"
+ }
+ },
+ {
+ "pair": [
+ "XMR",
+ "MAID"
+ ],
+ "maxDecimals": 8,
+ "minimalOrder": {
+ "amount": 0.0001,
+ "unit": "asset"
+ }
+ },
+ {
+ "pair": [
+ "XMR",
+ "NXT"
+ ],
+ "maxDecimals": 8,
+ "minimalOrder": {
+ "amount": 0.0001,
+ "unit": "asset"
+ }
+ },
+ {
+ "pair": [
+ "XMR",
+ "ZEC"
+ ],
+ "maxDecimals": 8,
+ "minimalOrder": {
+ "amount": 0.0001,
+ "unit": "asset"
+ }
+ }
+ ]
+}
\ No newline at end of file
diff --git a/Server/Exchange/exchangeUtils.js b/Server/Exchange/exchangeUtils.js
new file mode 100644
index 000000000..853d6d825
--- /dev/null
+++ b/Server/Exchange/exchangeUtils.js
@@ -0,0 +1,100 @@
+// generic low level reusuable utils for interacting with exchanges.
+
+const retry = require('retry');
+const _ = require('lodash');
+
+const retryInstance = (options, checkFn, callback) => {
+ if(!options) {
+ options = {
+ retries: 100,
+ factor: 1.2,
+ minTimeout: 1 * 1000,
+ maxTimeout: 4 * 1000
+ };
+ }
+
+ let attempt = 0;
+
+ const operation = retry.operation(options);
+ operation.attempt(function(currentAttempt) {
+ checkFn((err, result) => {
+ if (!err) {
+ return callback(global.DEFAULT_OK_RESPONSE, result);
+ } else {
+ if (err.result === global.CUSTOM_OK_RESPONSE.result) {
+ return callback(err, result);
+ }
+ }
+
+ let maxAttempts = err.retry;
+ if(maxAttempts === true)
+ maxAttempts = 10;
+
+ if(err.retry && attempt++ < maxAttempts) {
+ return operation.retry(err);
+ }
+
+ if(err.notFatal) {
+ if(err.backoffDelay) {
+ return setTimeout(() => operation.retry(err), err.backoffDelay);
+ }
+
+ return operation.retry(err);
+ }
+
+ callback(err, result);
+ });
+ });
+}
+
+const isValidOrder = ({api, market, amount, price}) => {
+ let reason = false;
+
+ // Check amount
+ if(amount < market.minimalOrder.amount) {
+ reason = 'Amount is too small';
+ }
+
+ // Some exchanges have restrictions on prices
+ if(
+ _.isFunction(api.isValidPrice) &&
+ !api.isValidPrice(price)
+ ) {
+ reason = 'Price is not valid';
+ }
+
+ if(
+ _.isFunction(api.isValidLot) &&
+ !api.isValidLot(price, amount)
+ ) {
+ reason = 'Lot size is too small';
+ }
+
+ return {
+ reason,
+ valid: !reason
+ }
+}
+
+const includes = function(str, list) {
+ if (!_.isString(str))
+ return false;
+
+ return _.some(list, item => str.includes(item));
+}
+
+
+const getMarketConfig = function(exchangeProperties) {
+ return _.find(exchangeProperties.markets, (p) => {
+ return _.first(p.pair) === global.MARKET.assetA.toUpperCase() &&
+ _.last(p.pair) === global.MARKET.assetB.toUpperCase();
+ });
+}
+
+module.exports = {
+ retry: retryInstance,
+ includes: includes,
+ isValidOrder,
+ getMarketConfig
+
+}
\ No newline at end of file
diff --git a/server.js b/server.js
index 5a1b710cc..1020377e9 100644
--- a/server.js
+++ b/server.js
@@ -711,7 +711,7 @@ function onBrowserRequest(request, response) {
let exchangeKey = session.exchangeKeys[0].key; // 0 because we only deal with one exchange for now.
let exchangeSecret = session.exchangeKeys[0].secret;
- const POLONIEX_CLIENT_MODULE = require('./Server/Exchange/' + 'PoloniexAPIClient');
+ const POLONIEX_CLIENT_MODULE = require('./Server/Exchange/' + 'ExchangeAPI');
let poloniexApiClient = POLONIEX_CLIENT_MODULE.newPoloniexAPIClient(exchangeKey, exchangeSecret);
switch (requestParameters[2]) {