From 1dc1e8b676dc1c9a9995bb7db62757aa3befbc25 Mon Sep 17 00:00:00 2001 From: Luis Fernando Molina Date: Thu, 6 Feb 2020 16:06:22 +0100 Subject: [PATCH] get ticker working with ccxt --- Assistant.js | 94 ------------------------------------ ExchangeAPI.js | 50 +++++++++++++++++-- TradingBotProcessMainLoop.js | 4 +- 3 files changed, 47 insertions(+), 101 deletions(-) diff --git a/Assistant.js b/Assistant.js index f7661e768..b7cc33f6b 100644 --- a/Assistant.js +++ b/Assistant.js @@ -63,7 +63,6 @@ } case 'Backtest': { - // getMarketRateFromIndicator(); NOTE: This path is disabled since for now we do not allow ticker in simulation. Also it allow us to ship a dataset without bruce validateExchangeSyncronicity(); break; } @@ -119,99 +118,6 @@ } } - function getMarketRateFromIndicator() { - - try { - - if (global.LOG_CONTROL[MODULE_NAME].logInfo === true) { logger.write(MODULE_NAME, "[INFO] initialize -> getMarketRateFromIndicator -> Entering function."); } - - /* Procedure to get the current market rate. */ - - let key = - bot.marketRateProvider.dataMine + "-" + - bot.marketRateProvider.bot + "-" + - bot.marketRateProvider.product + "-" + - bot.marketRateProvider.dataSet + "-" + - bot.marketRateProvider.dataSetVersion; - - if (global.LOG_CONTROL[MODULE_NAME].logInfo === true) { logger.write(MODULE_NAME, "[INFO] initialize -> getMarketRateFromIndicator -> key = " + key); } - - let dataSet = thisObject.dataDependencies.dataSets.get(key); - - let dateForPath = bot.processDatetime.getUTCFullYear() + '/' + utilities.pad(bot.processDatetime.getUTCMonth() + 1, 2) + '/' + utilities.pad(bot.processDatetime.getUTCDate(), 2); - let fileName = '' + bot.market.baseAsset + '_' + bot.market.quotedAsset + '.json'; - let filePath = bot.marketRateProvider.product + "/" + bot.marketRateProvider.dataSet + "/" + dateForPath; - - dataSet.getTextFile(filePath, fileName, onFileReceived); - - function onFileReceived(err, text) { - - if (global.LOG_CONTROL[MODULE_NAME].logInfo === true) { logger.write(MODULE_NAME, "[INFO] initialize -> getMarketRateFromIndicator -> onFileReceived -> Entering function."); } - if (global.LOG_CONTROL[MODULE_NAME].logContent === true) { logger.write(MODULE_NAME, "[INFO] initialize -> getMarketRateFromIndicator -> onFileReceived -> text = " + text); } - - let candleArray; - - if (err.result === global.CUSTOM_FAIL_RESPONSE.result || err.code === "The specified key does not exist." || err.message === "File does not exist.") { // Just past midnight, this file will not exist for a couple of minutes. - - logger.write(MODULE_NAME, "[WARN] initialize -> getMarketRateFromIndicator -> onFileReceived -> err = " + JSON.stringify(err)); - logger.write(MODULE_NAME, "[WARN] initialize -> getMarketRateFromIndicator -> This could happen when there are still holes on trades and the process needs to catch up. "); - callBackFunction(global.DEFAULT_FAIL_RESPONSE); - return; - - } - - if (err.result === global.DEFAULT_OK_RESPONSE.result) { - try { - candleArray = JSON.parse(text); - - /* We need to find the candle at which the process is currently running. */ - - for (let i = 0; i < candleArray.length; i++) { - - let candle = { - open: candleArray[i][2], - close: candleArray[i][3], - min: candleArray[i][0], - max: candleArray[i][1], - begin: candleArray[i][4], - end: candleArray[i][5] - }; - - // TODO condition added for when there is no market rate available. - if ((bot.processDatetime.valueOf() >= candle.begin && bot.processDatetime.valueOf() < candle.end) - || (i + 1) === candleArray.length) { - - marketRate = (candle.open + candle.close) / 2; - marketRate = thisObject.truncDecimals(marketRate); - context.newHistoryRecord.marketRate = marketRate; - - ticker = { - bid: marketRate, - ask: marketRate, - last: marketRate - }; - - validateExchangeSyncronicity(); - return; - } - } - } catch (err) { - logger.write(MODULE_NAME, "[ERROR] initialize -> getMarketRateFromIndicator -> onFileReceived -> err = " + JSON.stringify(err)); - logger.write(MODULE_NAME, "[ERROR] initialize -> getMarketRateFromIndicator -> onFileReceived -> Asuming this is a temporary situation. Requesting a Retry."); - callBackFunction(global.DEFAULT_RETRY_RESPONSE); - } - } else { - logger.write(MODULE_NAME, "[ERROR] initialize -> getMarketRateFromIndicator -> onFileReceived -> err = " + JSON.stringify(err)); - callBackFunction(err); - } - } - - } catch (err) { - logger.write(MODULE_NAME, "[ERROR] initialize -> getMarketRateFromIndicator -> err = " + err.stack); - callBackFunction(global.DEFAULT_FAIL_RESPONSE); - } - } - function validateExchangeSyncronicity() { try { diff --git a/ExchangeAPI.js b/ExchangeAPI.js index 23996337c..50adc5b49 100644 --- a/ExchangeAPI.js +++ b/ExchangeAPI.js @@ -1,8 +1,9 @@ -exports.newExchangeAPI = function newExchangeAPI(logger, exchangeName) { +exports.newExchangeAPI = function newExchangeAPI(logger, BOT) { let MODULE_NAME = "Exchange API"; let LOG_INFO = true; let apiClient; + let bot = BOT let thisObject = { initialize: initialize, @@ -14,11 +15,41 @@ getMaxDecimalPositions: getMaxDecimalPositions }; + let exchangeId + let options = {} + let exchange + const symbol = bot.market.baseAsset + '/' + bot.market.quotedAsset + const ccxt = require('ccxt') + return thisObject; function initialize(callBackFunction) { + try { + exchangeId = bot.exchange.toLowerCase() - callBackFunction(global.DEFAULT_OK_RESPONSE); + let key = process.env.KEY + let secret = process.env.SECRET + + if (key === "undefined") { key = undefined } + if (secret === "undefined") { secret = undefined } + + const exchangeClass = ccxt[exchangeId] + const exchangeConstructorParams = { + 'apiKey': key, + 'secret': secret, + 'timeout': 30000, + 'enableRateLimit': true, + verbose: false, + options: options + } + + exchange = new exchangeClass(exchangeConstructorParams) + + callBackFunction(global.DEFAULT_OK_RESPONSE) + } catch (err) { + logError("initialize -> err = " + err.message); + callBackFunction(global.DEFAULT_FAIL_RESPONSE); + } } function getMaxDecimalPositions() { @@ -34,13 +65,22 @@ * last Number * }; */ - function getTicker(pMarket, callBack) { + async function getTicker(pMarket, callBackFunction) { try { logInfo("getTicker -> Entering function."); - apiClient.getTicker(pMarket, callBack); + let ticker + + if (exchange.has['fetchTicker']) { + ticker = await (exchange.fetchTicker(symbol)) + callBackFunction(global.DEFAULT_OK_RESPONSE, ticker) + } else { + logError("getTicker -> Exchange does not support fetchTicker command."); + callBackFunction(global.DEFAULT_FAIL_RESPONSE); + } + } catch (err) { logError("getTicker -> err = " + err.message); - callBack(global.DEFAULT_FAIL_RESPONSE); + callBackFunction(global.DEFAULT_FAIL_RESPONSE); } } diff --git a/TradingBotProcessMainLoop.js b/TradingBotProcessMainLoop.js index ca5bda4aa..0aac6246a 100644 --- a/TradingBotProcessMainLoop.js +++ b/TradingBotProcessMainLoop.js @@ -145,7 +145,7 @@ /* We define here all the modules that the rest of the infraestructure, including the bots themselves can consume. */ const UTILITIES = require(ROOT_DIR + 'CloudUtilities'); - const EXCHANGE_API = require('ExchangeAPI'); + const EXCHANGE_API = require(ROOT_DIR + 'ExchangeAPI'); const CONTEXT = require(ROOT_DIR + 'Context'); const ASSISTANT = require(ROOT_DIR + 'Assistant'); const STATUS_REPORT = require(ROOT_DIR + 'StatusReport'); @@ -581,7 +581,7 @@ if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] run -> loop -> initializeExchangeAPI -> Entering function."); } - exchangeAPI = EXCHANGE_API.newExchangeAPI(logger, bot.exchange); + exchangeAPI = EXCHANGE_API.newExchangeAPI(logger, bot); exchangeAPI.initialize(onInizialized);