From cf33836157ebad92fa5d18ac9e9934d06b8c2fe2 Mon Sep 17 00:00:00 2001 From: Luis Fernando Molina Date: Wed, 16 May 2018 20:55:48 +0200 Subject: [PATCH] marketRate and ticker from the exchange without delays --- Assistant.js | 190 +++++++---------------------------------------- Blob Storage.js | 8 +- ExchangeAPI.js | 65 +++++++++++++++- this.config.json | 19 +---- 4 files changed, 98 insertions(+), 184 deletions(-) diff --git a/Assistant.js b/Assistant.js index a69982466..d41630c92 100644 --- a/Assistant.js +++ b/Assistant.js @@ -22,6 +22,7 @@ getInvestment: getInvestment, getProfits: getProfits, getMarketRate: getMarketRate, + getTicker: getTicker, sendMessage: sendMessage }; @@ -40,6 +41,7 @@ let exchangeAPI; let marketRate; + let ticker; return thisObject; @@ -63,180 +65,36 @@ if (FULL_LOG === true) { logger.write("[INFO] initialize -> getMarketRate -> Entering function."); } - /* Procedure to get the current market rate. */ + exchangeAPI.getTicker(global.MARKET.assetA + '_' + global.MARKET.assetB, onTicker); - let key = - global.PLATFORM_CONFIG.marketRateProvider.devTeam + "-" + - global.PLATFORM_CONFIG.marketRateProvider.bot + "-" + - global.PLATFORM_CONFIG.marketRateProvider.product + "-" + - global.PLATFORM_CONFIG.marketRateProvider.dataSet + "-" + - global.PLATFORM_CONFIG.marketRateProvider.dataSetVersion; + return; - if (FULL_LOG === true) { logger.write("[INFO] initialize -> getMarketRate -> key = " + key); } + function onTicker(err, pTicker) { - let dataSet = thisObject.dataDependencies.dataSets.get(key); + try { - let dateForPath = bot.processDatetime.getUTCFullYear() + '/' + utilities.pad(bot.processDatetime.getUTCMonth() + 1, 2) + '/' + utilities.pad(bot.processDatetime.getUTCDate(), 2); - let fileName = '' + global.MARKET.assetA + '_' + global.MARKET.assetB + '.json'; - let filePath = global.PLATFORM_CONFIG.marketRateProvider.product + "/" + global.PLATFORM_CONFIG.marketRateProvider.dataSet + "/" + dateForPath; + if (FULL_LOG === true) { logger.write("[INFO] initialize -> getMarketRate -> onTicker -> Entering function."); } - dataSet.getTextFile(filePath, fileName, onFileReceived, true); + if (err.result !== global.DEFAULT_OK_RESPONSE.result) { - function onFileReceived(err, text) { + if (FULL_LOG === true) { logger.write("[INFO] initialize -> getMarketRate -> onTicker -> We could not get the Market Price now."); } - if (FULL_LOG === true) { logger.write("[INFO] initialize -> getMarketRate -> onFileReceived -> Entering function."); } - if (LOG_FILE_CONTENT === true) { logger.write("[INFO] initialize -> getMarketRate -> onFileReceived -> text = " + text); } - - let candleArray; - - if (err.result === global.CUSTOM_FAIL_RESPONSE.result) { // Just past midnight, this file will not exist for a couple of minutes. - if (err.message === "File does not exist.") { - callBackFunction(global.DEFAULT_RETRY_RESPONSE); + callBackFunction(err); return; } + + ticker = pTicker; + marketRate = pTicker.last; + + context.newHistoryRecord.marketRate = marketRate; + + validateExchangeSyncronicity(); + + } catch (err) { + logger.write("[ERROR] initialize -> getMarketRate -> onTicker -> err = " + err.message); + callBackFunction(global.DEFAULT_FAIL_RESPONSE); } - - if (err.result === global.DEFAULT_OK_RESPONSE.result) { - try { - candleArray = JSON.parse(text); - - switch (bot.runMode) { - - case "Live": { - - logger.write("[INFO] initialize -> getMarketRate -> onFileReceived -> Live Mode detected."); - - let lastCandleRecord = candleArray[candleArray.length - 1]; // The last candle contains at its close value the market rate. - - let candle = { - open: lastCandleRecord[2], - close: lastCandleRecord[3], - min: lastCandleRecord[0], - max: lastCandleRecord[1], - begin: lastCandleRecord[4], - end: lastCandleRecord[5] - }; - - marketRate = candle.close; - marketRate = Number(marketRate.toFixed(8)); - context.newHistoryRecord.marketRate = marketRate; - - /* - Now we verify that this candle is not too old. Lets say no more than 10 minutes old. This could happen if the datasets for - any reason stops being updated. - */ - - let delay = (bot.processDatetime.valueOf() - candle.begin) / 1000 / 60; - - logger.write("[INFO] initialize -> getMarketRate -> onFileReceived -> Market Rate " + delay + " minutes old."); - - if (delay > 30) { - - logger.write("[ERROR] initialize -> getMarketRate -> onFileReceived -> Market Rate more than 10 minutes old. Retrying later."); - - callBackFunction(global.DEFAULT_RETRY_RESPONSE); - return; - } - - validateExchangeSyncronicity(); - return; - } - - case "Backtest": { - - logger.write("[INFO] initialize -> getMarketRate -> onFileReceived -> Backtest Mode detected."); - - /* 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] - }; - - if (bot.processDatetime.valueOf() >= candle.begin && bot.processDatetime.valueOf() < candle.end) { - - marketRate = (candle.open + candle.close) / 2; - marketRate = Number(marketRate.toFixed(8)); - context.newHistoryRecord.marketRate = marketRate; - - /* The Backtest Mode simulates that every trade posted is executed. - In order to do this, we will take all open orders from the context and create a trades array similar to the one returned by the Exchange. */ - - validateExchangeSyncronicity(); - return; - } - } - - logger.write("[ERROR] initialize -> getMarketRate -> onFileReceived -> No candle found for the current Process Datetime."); - logger.write("[ERROR] initialize -> getMarketRate -> onFileReceived -> bot.processDatetime = " + bot.processDatetime); - callBackFunction(global.DEFAULT_FAIL_RESPONSE); - return; - } - - case "Competition": { - - logger.write("[INFO] initialize -> getMarketRate -> onFileReceived -> Competition Mode detected."); - - let lastCandleRecord = candleArray[candleArray.length - 1]; // The last candle contains at its close value the market rate. - - let candle = { - open: lastCandleRecord[2], - close: lastCandleRecord[3], - min: lastCandleRecord[0], - max: lastCandleRecord[1], - begin: lastCandleRecord[4], - end: lastCandleRecord[5] - }; - - marketRate = candle.close; - marketRate = Number(marketRate.toFixed(8)); - context.newHistoryRecord.marketRate = marketRate; - - /* - Now we verify that this candle is not too old. Lets say no more than 10 minutes old. This could happen if the datasets for - any reason stops being updated. - */ - - let delay = (bot.processDatetime.valueOf() - candle.begin) / 1000 / 60; - - logger.write("[INFO] initialize -> getMarketRate -> onFileReceived -> Market Rate " + delay + " minutes old."); - - if (delay > 30) { - - logger.write("[ERROR] initialize -> getMarketRate -> onFileReceived -> Market Rate more than 10 minutes old. Retrying later."); - - callBackFunction(global.DEFAULT_RETRY_RESPONSE); - return; - } - - validateExchangeSyncronicity(); - return; - } - - default: { - logger.write("[ERROR] initialize -> getMarketRate -> onFileReceived -> Unexpected bot.runMode."); - logger.write("[ERROR] initialize -> getMarketRate -> onFileReceived -> bot.runMode = " + bot.runMode); - callBackFunction(global.DEFAULT_FAIL_RESPONSE); - return; - } - } - - } catch (err) { - logger.write("[ERROR] initialize -> getMarketRate -> onFileReceived -> err = " + err.message); - logger.write("[ERROR] initialize -> getMarketRate -> onFileReceived -> Asuming this is a temporary situation. Requesting a Retry."); - callBackFunction(global.DEFAULT_RETRY_RESPONSE); - } - } else { - logger.write("[ERROR] initialize -> getMarketRate -> onFileReceived -> err = " + err.message); - callBackFunction(err); - } - } + } } catch (err) { logger.write("[ERROR] initialize -> getMarketRate -> err = " + err.message); @@ -1261,6 +1119,10 @@ return marketRate; } + function getTicker() { + return ticker; + } + function sendMessage(pRelevance, pTitle, pBody) { context.newHistoryRecord.messageRelevance = pRelevance; diff --git a/Blob Storage.js b/Blob Storage.js index 1985846ba..4d29517a2 100644 --- a/Blob Storage.js +++ b/Blob Storage.js @@ -29,7 +29,7 @@ exports.newBlobStorage = function newBlobStorage(BOT) { let blobService; let containerName = 'aamasters'; let dataOwner; - let ambient = global.STORAGE_CONN_STRING_FOLDER; + let environment = global.STORAGE_CONN_STRING_FOLDER; return thisObject; @@ -44,9 +44,9 @@ exports.newBlobStorage = function newBlobStorage(BOT) { dataOwner = pDataOwner.devTeam; logger.fileName = MODULE_NAME + '.' + pDataOwner.devTeam + '.' + pDataOwner.bot + '.' + containerName; - if (pDataOwner.ambient !== undefined) { + if (pDataOwner.environment !== undefined) { - ambient = pDataOwner.ambient; + environment = pDataOwner.environment; containerName = pDataOwner.devTeam.toLowerCase(); logger.fileName = MODULE_NAME + '.' + pDataOwner.devTeam + '.' + pDataOwner.bot + '.' + containerName; } @@ -96,7 +96,7 @@ exports.newBlobStorage = function newBlobStorage(BOT) { try { let fs = require('fs'); - filePath = '../' + 'Connection-Strings' + '/' + ambient + '/' + dataOwner + '.azure.storage.connstring'; + filePath = '../' + 'Connection-Strings' + '/' + environment + '/' + dataOwner + '.azure.storage.connstring'; let connObj = JSON.parse(fs.readFileSync(filePath, 'utf8')); callBack(global.DEFAULT_OK_RESPONSE, connObj); diff --git a/ExchangeAPI.js b/ExchangeAPI.js index 3a6c78ef1..bad5bf8a4 100644 --- a/ExchangeAPI.js +++ b/ExchangeAPI.js @@ -15,7 +15,8 @@ getOpenPositions: getOpenPositions, getExecutedTrades: getExecutedTrades, putPosition: putPosition, - movePosition: movePosition + movePosition: movePosition, + getTicker: getTicker }; let bot = BOT; @@ -334,4 +335,66 @@ } } + function getTicker(pMarket, callBackFunction) { + + try { + + if (FULL_LOG === true) { logger.write("[INFO] getTicker -> Entering function."); } + + poloniexApiClient.returnTicker(onExchangeCallReturned); + + function onExchangeCallReturned(err, exchangeResponse) { + + if (FULL_LOG === true) { logger.write("[INFO] movePosition -> onExchangeCallReturned -> Entering function."); } + if (FULL_LOG === true) { logger.write("[INFO] movePosition -> onExchangeCallReturned -> err = " + err); } + if (FULL_LOG === true) { logger.write("[INFO] movePosition -> onExchangeCallReturned -> exchangeResponse = " + JSON.stringify(exchangeResponse)); } + + try { + + poloniexApiClient.analizeResponse(logger, err, exchangeResponse, callBackFunction, onResponseOk); + + function onResponseOk() { + + /* + + This is what we can receive from the exchange. + + {"BTC_LTC":{ "last":"0.0251", + "lowestAsk":"0.02589999", + "highestBid":"0.0251", + "percentChange":"0.02390438", + "baseVolume":"6.16485315", + "quoteVolume":"245.82513926" + }, + "BTC_NXT":{ "last":"0.00005730", + "lowestAsk":"0.00005710", + "highestBid":"0.00004903", + "percentChange":"0.16701570", + "baseVolume":"0.45347489", + "quoteVolume":"9094" + }, + ... } + + */ + + let ticker = { + bid: Number(exchangeResponse[pMarket].highestBid), + ask: Number(exchangeResponse[pMarket].lowestAsk), + last: Number(exchangeResponse[pMarket].last) + }; + + callBackFunction(global.DEFAULT_OK_RESPONSE, ticker); + } + } + catch (err) { + logger.write("[ERROR] movePosition -> onExchangeCallReturned -> Error = " + err.message); + callBackFunction(global.DEFAULT_FAIL_RESPONSE); + } + } + + } catch (err) { + logger.write("[ERROR] movePosition -> err = " + err.message); + callBackFunction(global.DEFAULT_FAIL_RESPONSE); + } + } }; \ No newline at end of file diff --git a/this.config.json b/this.config.json index b7f4c1dd7..b5e5223c5 100644 --- a/this.config.json +++ b/this.config.json @@ -7,7 +7,7 @@ }, "executionList": [ { - "enabled": "false", + "enabled": "true", "botPath": "../Bots/AAMasters/AAMariam-Trading-Bot", "process": "Trading-Process" }, @@ -27,7 +27,7 @@ "process": "One-Min-Daily-Candles-Volumes" }, { - "enabled": "true", + "enabled": "false", "botPath": "../Bots/AAMasters/AACharly-Extraction-Bot", "process": "Poloniex-Hole-Fixing" }, @@ -43,17 +43,6 @@ } ], "stopGracefully": "false", - "storageConnStringFolder": "Testnet", - "maxLogLoops": 5, - "marketRateProvider": { - "devTeam": "AAMasters", - "bot": "AABruce", - "botVersion": { - "major": 1, - "minor": 0 - }, - "product": "Candles", - "dataSet": "One-Min", - "dataSetVersion": "dataSet.V1" - } + "storageConnStringFolder": "Develop", + "maxLogLoops": 5 } \ No newline at end of file