From 91dfa45b614b0765c0908610fc7f79cd9df842f5 Mon Sep 17 00:00:00 2001 From: Luis Fernando Molina Date: Thu, 8 Mar 2018 09:22:44 +0100 Subject: [PATCH] TRADING_BOT MAIN LOOP introduced --- .vs/AACloudPlatform/v15/.suo | Bin 73216 -> 74752 bytes AACloudPlatform.njsproj | 2 +- Azure File Storage.js | 17 +++++++++ Context.js | 41 +++++++++++----------- Datasource.js | 4 +-- Debug Log.js | 14 +++++--- Run.js | 8 ++--- TradingBot.js => Trading Bot Main Loop.js | 18 +++++++++- logs/Dummy File.txt | 0 9 files changed, 70 insertions(+), 34 deletions(-) rename TradingBot.js => Trading Bot Main Loop.js (90%) delete mode 100644 logs/Dummy File.txt diff --git a/.vs/AACloudPlatform/v15/.suo b/.vs/AACloudPlatform/v15/.suo index aac30a4db7bf776b26a2f22ff7a3122bd00985e8..262877a6a71acd0a9c54f86caba1d32d0e010357 100644 GIT binary patch delta 3770 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 aHa!ZT9Zf5E4Kj;zkke=I^~STq`kw(nqVUfE diff --git a/AACloudPlatform.njsproj b/AACloudPlatform.njsproj index 0099752c7..df7231810 100644 --- a/AACloudPlatform.njsproj +++ b/AACloudPlatform.njsproj @@ -38,7 +38,7 @@ - + Code diff --git a/Azure File Storage.js b/Azure File Storage.js index 88838ed24..518cf0080 100644 --- a/Azure File Storage.js +++ b/Azure File Storage.js @@ -252,6 +252,23 @@ exports.newAzureFileStorage = function newAzureFileStorage(BOT) { } } + if (err.code = "ParentNotFound") { + + /* This is how Azure tell us the folder where the file was supposed to be does not exist. We map this to our own response. */ + + let customResponse = { + result: global.DEFAULT_FAIL_RESPONSE.result, + message: "Folder does not exist." + }; + + logger.write("[ERROR] getTextFile -> onFileReceived -> Custom Response -> message = " + customResponse.message); + + callBackFunction(customResponse); + return; + + } + + logger.write("[ERROR] getTextFile -> onFileReceived -> Dont know what to do here. Cancelling operation. "); callBackFunction(global.DEFAULT_FAIL_RESPONSE); diff --git a/Context.js b/Context.js index a861fb5f5..e395b8231 100644 --- a/Context.js +++ b/Context.js @@ -139,15 +139,22 @@ if (FULL_LOG === true) { logger.write("[INFO] initialize -> getStatusReport -> Entering function."); } - /* If the process run and was interrupted, there should be a status report that allows us to resume execution. */ - let fileName = "Status.Report.json" - let filePath = EXCHANGE_NAME + "/" + bot.codeName + "/" + bot.dataSetVersion + "/Processes/" + bot.process; + let filePath = bot.devTeam + "/" + bot.codeName + "/" + bot.version + "/" + bot.dataSetVersion + "/Processes/" + bot.process + "/" + EXCHANGE_NAME; cloudStorage.getTextFile(filePath, fileName, onFileReceived); function onFileReceived(err, text) { + if (err.result === global.DEFAULT_FAIL_RESPONSE.result && err.message === 'Folder does not exist.') { + logger.write("[INFO] initialize -> getStatusReport -> onFileReceived -> err = " + err.message); + + /* In this case we can assume that this is the first execution ever of this bot.*/ + + createConext(callBack); + return; + } + if (err.result !== global.DEFAULT_OK_RESPONSE.result) { logger.write("[ERROR] initialize -> getStatusReport -> onFileReceived -> err = " + err.message); callBack(err); @@ -161,25 +168,17 @@ try { thisObject.statusReport = JSON.parse(text); - - if (thisObject.statusReport.lastExecution === undefined) { - createConext(callBack); - } else { - getExecutionHistory(callBack); - } + getExecutionHistory(callBack); } catch (err) { /* - - It might happen that the file content is corrupt or it does not exist. The bot can not run without an Execution Context, - since it is risky to ignore its own context, so even for first time execution, a file with the right format - is needed. - + It might happen that the file content is corrupt. We will consider this as a temporary situation, since sometimes the file + is being updated at the moment of the read. The bot can not run without a valid Status Report but we can request the platform to retry later. */ - logger.write("[ERROR] initialize -> getStatusReport -> onFileReceived -> Bot cannot execute without the Status report. -> Err = " + err.message); - callBack(global.DEFAULT_FAIL_RESPONSE); + logger.write("[ERROR] initialize -> getStatusReport -> onFileReceived -> Bot cannot execute without a valid Status report. -> Err = " + err.message); + callBack(global.DEFAULT_RETRY_RESPONSE); } } @@ -195,7 +194,7 @@ if (FULL_LOG === true) { logger.write("[INFO] initialize -> getExecutionHistory -> Entering function."); } let fileName = "Execution.History.json" - let filePath = EXCHANGE_NAME + "/" + bot.codeName + "/" + bot.dataSetVersion + "/Output/" + bot.process; + let filePath = bot.devTeam + "/" + bot.codeName + "/" + bot.version + "/" + bot.dataSetVersion + "/Output/" + bot.process + "/" + EXCHANGE_NAME; cloudStorage.getTextFile(filePath, fileName, onFileReceived); @@ -246,7 +245,7 @@ let fileName = "Execution.Context.json" let dateForPath = date.getUTCFullYear() + '/' + utilities.pad(date.getUTCMonth() + 1, 2) + '/' + utilities.pad(date.getUTCDate(), 2) + '/' + utilities.pad(date.getUTCHours(), 2) + '/' + utilities.pad(date.getUTCMinutes(), 2); - let filePath = EXCHANGE_NAME + "/" + bot.codeName + "/" + bot.dataSetVersion + "/Output/" + bot.process + "/" + dateForPath; + let filePath = bot.devTeam + "/" + bot.codeName + "/" + bot.version + "/" + bot.dataSetVersion + "/Output/" + bot.process + "/" + EXCHANGE_NAME + "/" + dateForPath; cloudStorage.getTextFile(filePath, fileName, onFileReceived); @@ -374,7 +373,7 @@ let fileName = "Execution.Context.json" let dateForPath = processDatetime.getUTCFullYear() + '/' + utilities.pad(processDatetime.getUTCMonth() + 1, 2) + '/' + utilities.pad(processDatetime.getUTCDate(), 2) + '/' + utilities.pad(processDatetime.getUTCHours(), 2) + '/' + utilities.pad(processDatetime.getUTCMinutes(), 2); - let filePath = EXCHANGE_NAME + "/" + bot.codeName + "/" + bot.dataSetVersion + "/Output/" + bot.process + "/" + dateForPath; + let filePath = bot.devTeam + "/" + bot.codeName + "/" + bot.version + "/" + bot.dataSetVersion + "/Output/" + bot.process + "/" + EXCHANGE_NAME + "/" + dateForPath; utilities.createFolderIfNeeded(filePath, cloudStorage, onFolderCreated); @@ -429,7 +428,7 @@ try { let fileName = "Execution.History.json" - let filePath = EXCHANGE_NAME + "/" + bot.codeName + "/" + bot.dataSetVersion + "/Output/" + bot.process; + let filePath = bot.devTeam + "/" + bot.codeName + "/" + bot.version + "/" + bot.dataSetVersion + "/Output/" + bot.process + "/" + EXCHANGE_NAME; utilities.createFolderIfNeeded(filePath, cloudStorage, onFolderCreated); @@ -494,7 +493,7 @@ try { let fileName = "Status.Report.json" - let filePath = EXCHANGE_NAME + "/" + bot.codeName + "/" + bot.dataSetVersion + "/Processes/" + bot.process; + let filePath = bot.devTeam + "/" + bot.codeName + "/" + bot.version + "/" + bot.dataSetVersion + "/Processes/" + bot.process + "/" + EXCHANGE_NAME; utilities.createFolderIfNeeded(filePath, cloudStorage, onFolderCreated); diff --git a/Datasource.js b/Datasource.js index 4190d36cd..40f23674a 100644 --- a/Datasource.js +++ b/Datasource.js @@ -68,7 +68,7 @@ function initializeOliviaStorage() { - oliviaAzureFileStorage.initialize("Olivia", onInizialized); + oliviaAzureFileStorage.initialize("AAOlivia", onInizialized); function onInizialized(err) { if (err.result === global.DEFAULT_OK_RESPONSE.result) { @@ -82,7 +82,7 @@ function initializeTomStorage() { - tomAzureFileStorage.initialize("Tom", onInizialized); + tomAzureFileStorage.initialize("AATom", onInizialized); function onInizialized(err) { if (err.result === global.DEFAULT_OK_RESPONSE.result) { diff --git a/Debug Log.js b/Debug Log.js index 788099f3d..2abaf5cdd 100644 --- a/Debug Log.js +++ b/Debug Log.js @@ -24,23 +24,27 @@ try { - folderPath = thisObject.bot.devTeam; + folderPath = '../../Logs'; createFolderSync(folderPath); - folderPath = thisObject.bot.devTeam + "/" + thisObject.bot.type; + folderPath = '../../Logs/' + thisObject.bot.devTeam; createFolderSync(folderPath); - folderPath = thisObject.bot.devTeam + "/" + thisObject.bot.type + "/" + thisObject.bot.codeName; + folderPath = '../../Logs/' + thisObject.bot.devTeam + "/" + thisObject.bot.type; createFolderSync(folderPath); - folderPath = thisObject.bot.devTeam + "/" + thisObject.bot.type + "/" + thisObject.bot.codeName + "/" + thisObject.bot.version; + folderPath = '../../Logs/' + thisObject.bot.devTeam + "/" + thisObject.bot.type + "/" + thisObject.bot.codeName; createFolderSync(folderPath); - folderPath = thisObject.bot.devTeam + "/" + thisObject.bot.type + "/" + thisObject.bot.codeName + "/" + thisObject.bot.version + "/" + thisObject.bot.process; + folderPath = '../../Logs/' + thisObject.bot.devTeam + "/" + thisObject.bot.type + "/" + thisObject.bot.codeName + "/" + thisObject.bot.version; + + createFolderSync(folderPath); + + folderPath = '../../Logs/' + thisObject.bot.devTeam + "/" + thisObject.bot.type + "/" + thisObject.bot.codeName + "/" + thisObject.bot.version + "/" + thisObject.bot.process; createFolderSync(folderPath); diff --git a/Run.js b/Run.js index 62ec40e08..d596fb612 100644 --- a/Run.js +++ b/Run.js @@ -87,7 +87,7 @@ const START_ALL_MONTHS = false; const START_ONE_MONTH = true; const INTERVAL_EXECUTOR_MODULE = require('./Interval Executor'); -const TRADING_BOT_MODULE = require('./TradingBot'); +const TRADING_BOT_MAIN_LOOP_MODULE = require('./Trading Bot Main Loop'); /* Now we will see which are the script Arguments. We expect the name of the process to run, since that is what it should be defined at the Task Scheduller. */ @@ -194,14 +194,14 @@ function runTradingBot(pProcessConfig) { try { if (FULL_LOG === true) { logger.write("[INFO] runTradingBot -> Entering function."); } - let tradingBot = TRADING_BOT_MODULE.newTradingBot(botConfig); - tradingBot.initialize(vmConfig.bot.path, pProcessConfig, onInitializeReady); + let tradingBotMainLoop = TRADING_BOT_MAIN_LOOP_MODULE.newTradingBotMainLoop(botConfig); + tradingBotMainLoop.initialize(vmConfig.bot.path, pProcessConfig, onInitializeReady); function onInitializeReady(err) { if (err.result === global.DEFAULT_OK_RESPONSE.result) { - tradingBot.run(whenRunFinishes); + tradingBotMainLoop.run(whenRunFinishes); function whenRunFinishes(err) { diff --git a/TradingBot.js b/Trading Bot Main Loop.js similarity index 90% rename from TradingBot.js rename to Trading Bot Main Loop.js index cd85d020c..1fe7316b4 100644 --- a/TradingBot.js +++ b/Trading Bot Main Loop.js @@ -1,4 +1,4 @@ -exports.newTradingBot = function newTradingBot(BOT) { +exports.newTradingBotMainLoop = function newTradingBotMainLoop(BOT) { let bot = BOT; const ROOT_DIR = './'; @@ -80,6 +80,8 @@ function initializeContext() { + if (FULL_LOG === true) { logger.write("[INFO] run -> loop -> initializeContext -> Entering function."); } + context = CONTEXT.newContext(bot, DEBUG_MODULE, AZURE_FILE_STORAGE); context.initialize(processDatetime, onInizialized); @@ -96,6 +98,8 @@ function initializeDatasource() { + if (FULL_LOG === true) { logger.write("[INFO] run -> loop -> initializeDatasource -> Entering function."); } + datasource = DATASOURCE.newDatasource(bot, DEBUG_MODULE, AZURE_FILE_STORAGE); datasource.initialize(onInizialized); @@ -112,6 +116,8 @@ function initializeExchangeAPI() { + if (FULL_LOG === true) { logger.write("[INFO] run -> loop -> initializeExchangeAPI -> Entering function."); } + exchangeAPI = EXCHANGE_API.newExchangeAPI(bot, DEBUG_MODULE, POLONIEX_CLIENT_MODULE); exchangeAPI.initialize(onInizialized); @@ -128,6 +134,8 @@ function initializeAssistant() { + if (FULL_LOG === true) { logger.write("[INFO] run -> loop -> initializeAssistant -> Entering function."); } + assistant = ASSISTANT.newAssistant(bot, DEBUG_MODULE); assistant.initialize(processDatetime, context, exchangeAPI, onInizialized); @@ -144,6 +152,8 @@ function initializeUserBot() { + if (FULL_LOG === true) { logger.write("[INFO] run -> loop -> initializeUserBot -> Entering function."); } + usertBot = USER_BOT_MODULE.newUserBot(bot, DEBUG_MODULE); let platform = { @@ -168,6 +178,8 @@ function startUserBot() { + if (FULL_LOG === true) { logger.write("[INFO] run -> loop -> startUserBot -> Entering function."); } + usertBot.run(platform, onFinished); function onFinished(err) { @@ -197,6 +209,8 @@ function saveContext() { + if (FULL_LOG === true) { logger.write("[INFO] run -> loop -> saveContext -> Entering function."); } + context.saveThemAll(onFinished); function onFinished(err) { @@ -218,6 +232,8 @@ function loopControl(nextWaitTime) { + if (FULL_LOG === true) { logger.write("[INFO] run -> loopControl -> nextWaitTime = " + nextWaitTime); } + /* Trading bots are going to be executed after a configured period of time after the last execution ended. This is to avoid overlapping executions. */ switch (nextWaitTime) { diff --git a/logs/Dummy File.txt b/logs/Dummy File.txt deleted file mode 100644 index e69de29bb..000000000