diff --git a/Projects/Superalgos/TS/Bot-Modules/Indicator-Bot/SingleMarketIndicatorBot.js b/Projects/Superalgos/TS/Bot-Modules/Indicator-Bot/SingleMarketIndicatorBot.js index 97b4630ec..c9093782a 100644 --- a/Projects/Superalgos/TS/Bot-Modules/Indicator-Bot/SingleMarketIndicatorBot.js +++ b/Projects/Superalgos/TS/Bot-Modules/Indicator-Bot/SingleMarketIndicatorBot.js @@ -15,7 +15,20 @@ function initialize(callBackFunction) { try { + /* We will check that we have received all the nodes needed to run this bot. */ + if (TS.projects.superalgos.functionLibraries.singleMarketFunctions.checkUpstreamOfTaskNode(processIndex) === false) { + callBackFunction(TS.projects.superalgos.globals.standardResponses.DEFAULT_FAIL_RESPONSE) + return + } + /* Here we setup the path prefix that will be used when writting data or logs to disk. */ + TS.projects.superalgos.functionLibraries.singleMarketFunctions.initializeFilePathRoot(processIndex) + + /* + Bots can be defined at the UI, using one of the available existing frameworks for that, + or they might be coded at a bot module. In the later case, the name of the botModule + must be specified at the bot process config. + */ if (TS.projects.superalgos.globals.taskConstants.TASK_NODE.bot.processes[processIndex].referenceParent.config.botModule === undefined) { /* The code of the bot is defined at the UI. No need to load a file with the code. */ callBackFunction(TS.projects.superalgos.globals.standardResponses.DEFAULT_OK_RESPONSE); diff --git a/Projects/Superalgos/TS/Bot-Modules/Sensor-Bot/SingleMarketSensorBot.js b/Projects/Superalgos/TS/Bot-Modules/Sensor-Bot/SingleMarketSensorBot.js index 84b589ae1..11839b70f 100644 --- a/Projects/Superalgos/TS/Bot-Modules/Sensor-Bot/SingleMarketSensorBot.js +++ b/Projects/Superalgos/TS/Bot-Modules/Sensor-Bot/SingleMarketSensorBot.js @@ -18,6 +18,20 @@ function initialize(callBackFunction) { /* This function is exactly the same in the 3 modules representing the 2 different bot types loops. */ try { + /* We will check that we have received all the nodes needed to run this bot. */ + if (TS.projects.superalgos.functionLibraries.singleMarketFunctions.checkUpstreamOfTaskNode(processIndex) === false) { + callBackFunction(TS.projects.superalgos.globals.standardResponses.DEFAULT_FAIL_RESPONSE) + return + } + + /* Here we setup the path prefix that will be used when writting data or logs to disk. */ + TS.projects.superalgos.functionLibraries.singleMarketFunctions.initializeFilePathRoot(processIndex) + + /* + Bots can be defined at the UI, using one of the available existing frameworks for that, + or they might be coded at a bot module. In the later case, the name of the botModule + must be specified at the bot process config. + */ if (TS.projects.superalgos.globals.taskConstants.TASK_NODE.bot.processes[processIndex].referenceParent.config.botModule === undefined) { /* The code of the bot is defined at the UI. No need to load a module for this. */ callBackFunction(TS.projects.superalgos.globals.standardResponses.DEFAULT_OK_RESPONSE); @@ -41,7 +55,7 @@ } catch (err) { TS.projects.superalgos.globals.loggerVariables.VARIABLES_BY_PROCESS_INDEX_MAP.get(processIndex).PROCESS_INSTANCE_LOGGER_MODULE.write(MODULE_NAME, "[ERROR] initialize -> err = " + err.stack); - callBackFunction(TS.projects.superalgos.globals.standardResponses.DEFAULT_FAIL_RESPONSE); + callBackFunction(TS.projects.superalgos.globals.standardResponses.DEFAULT_FAIL_RESPONSE) } } diff --git a/Projects/Superalgos/TS/Bot-Modules/Trading-Bot/SingleMarketTradingBot.js b/Projects/Superalgos/TS/Bot-Modules/Trading-Bot/SingleMarketTradingBot.js index 1c02f6320..310245d72 100644 --- a/Projects/Superalgos/TS/Bot-Modules/Trading-Bot/SingleMarketTradingBot.js +++ b/Projects/Superalgos/TS/Bot-Modules/Trading-Bot/SingleMarketTradingBot.js @@ -1,7 +1,7 @@ exports.newSuperalgosBotModulesSingleMarketTradingBot = function (processIndex) { const MODULE_NAME = "Trading Bot"; - + let session = TS.projects.superalgos.botModules.tradingSession.newSuperalgosBotModulesTradingSession(processIndex) let nextLoopTimeoutHandle; @@ -13,13 +13,18 @@ return thisObject; function initialize(callBackFunction) { - /* This function is exactly the same in the 3 modules representing the 2 different bot types loops. */ try { - if (TS.projects.superalgos.globals.taskConstants.TASK_NODE.bot.processes[processIndex].referenceParent.parentNode.config.repo === undefined) { - /* The code of the bot is defined at the UI. No need to load a file with the code. */ - session.initialize(callBackFunction) + /* We will check that we have received all the nodes needed to run this bot. */ + if (TS.projects.superalgos.functionLibraries.singleMarketFunctions.checkUpstreamOfTaskNode(processIndex) === false) { + callBackFunction(TS.projects.superalgos.globals.standardResponses.DEFAULT_FAIL_RESPONSE) + return } + /* Here we setup the path prefix that will be used when writting data or logs to disk. */ + TS.projects.superalgos.functionLibraries.singleMarketFunctions.initializeFilePathRoot(processIndex) + + session.initialize(callBackFunction) + } catch (err) { TS.projects.superalgos.globals.loggerVariables.VARIABLES_BY_PROCESS_INDEX_MAP.get(processIndex).PROCESS_INSTANCE_LOGGER_MODULE.write(MODULE_NAME, "[ERROR] initialize -> err = " + err.stack); callBackFunction(TS.projects.superalgos.globals.standardResponses.DEFAULT_FAIL_RESPONSE); diff --git a/Projects/Superalgos/TS/Function-Libraries/LoggerFunctions.js b/Projects/Superalgos/TS/Function-Libraries/LoggerFunctions.js deleted file mode 100644 index e69de29bb..000000000 diff --git a/Projects/Superalgos/TS/Function-Libraries/SingleMarketFunctions.js b/Projects/Superalgos/TS/Function-Libraries/SingleMarketFunctions.js index 4b7c57c49..62bd14806 100644 --- a/Projects/Superalgos/TS/Function-Libraries/SingleMarketFunctions.js +++ b/Projects/Superalgos/TS/Function-Libraries/SingleMarketFunctions.js @@ -9,7 +9,9 @@ dataBuildingProcedure: dataBuildingProcedure, calculationsProcedure: calculationsProcedure, generateFileContent: generateFileContent, - writeFile: writeFile + writeFile: writeFile, + checkUpstreamOfTaskNode: checkUpstreamOfTaskNode, + initializeFilePathRoot: initializeFilePathRoot }; return thisObject; @@ -123,21 +125,21 @@ callBackFunction(TS.projects.superalgos.globals.standardResponses.DEFAULT_FAIL_RESPONSE); return } - } + } } else { if (tradingMineNode.config.codeName === undefined) { TS.projects.superalgos.globals.loggerVariables.VARIABLES_BY_PROCESS_INDEX_MAP.get(processIndex).BOT_MAIN_LOOP_LOGGER_MODULE.write(MODULE_NAME, "[ERROR] start -> Trading Mine witn no codeName defined."); callBackFunction(TS.projects.superalgos.globals.standardResponses.DEFAULT_FAIL_RESPONSE); return } - } + } } else { if (dataMineNode.config.codeName === undefined) { TS.projects.superalgos.globals.loggerVariables.VARIABLES_BY_PROCESS_INDEX_MAP.get(processIndex).BOT_MAIN_LOOP_LOGGER_MODULE.write(MODULE_NAME, "[ERROR] start -> Data Mine witn no codeName defined."); callBackFunction(TS.projects.superalgos.globals.standardResponses.DEFAULT_FAIL_RESPONSE); return } - } + } } return true } @@ -283,7 +285,7 @@ } function dataBuildingProcedure( - processIndex, + processIndex, products, mainDependency, recordDefinition, @@ -553,5 +555,107 @@ callBackFunction(TS.projects.superalgos.globals.standardResponses.DEFAULT_FAIL_RESPONSE); } } + + function checkUpstreamOfTaskNode(processIndex) { + /* + Here we check that the Task Node received, comes with all the upstream nodes that will be + needed to run this task in the context of a Single Market Bot. + */ + /* Validate that the minimun amount of input required are defined. */ + if (TS.projects.superalgos.globals.taskConstants.TASK_NODE.parentNode === undefined) { + TS.projects.superalgos.globals.loggerVariables.VARIABLES_BY_PROCESS_INDEX_MAP.get(processIndex).PROCESS_INSTANCE_LOGGER_MODULE.write(MODULE_NAME, + "[ERROR] checkUpstreamOfTaskNode -> Task without a Task Manager. This bot process will not run. -> Process Instance = " + JSON.stringify(TS.projects.superalgos.globals.taskConstants.TASK_NODE.bot.processes[processIndex])); + return false + } + + if (TS.projects.superalgos.globals.taskConstants.TASK_NODE.parentNode.parentNode === undefined) { + TS.projects.superalgos.globals.loggerVariables.VARIABLES_BY_PROCESS_INDEX_MAP.get(processIndex).PROCESS_INSTANCE_LOGGER_MODULE.write(MODULE_NAME, + "[ERROR] checkUpstreamOfTaskNode -> Task Manager without parent Mine Tasks. This bot process will not run. -> Process Instance = " + JSON.stringify(TS.projects.superalgos.globals.taskConstants.TASK_NODE.bot.processes[processIndex])); + return false + } + + if (TS.projects.superalgos.globals.taskConstants.TASK_NODE.parentNode.parentNode.parentNode === undefined) { + TS.projects.superalgos.globals.loggerVariables.VARIABLES_BY_PROCESS_INDEX_MAP.get(processIndex).PROCESS_INSTANCE_LOGGER_MODULE.write(MODULE_NAME, + "[ERROR] checkUpstreamOfTaskNode -> Mine Tasks without parent Market Tasks. This bot process will not run. -> Process Instance = " + JSON.stringify(TS.projects.superalgos.globals.taskConstants.TASK_NODE.bot.processes[processIndex])); + return false + } + + if (TS.projects.superalgos.globals.taskConstants.TASK_NODE.parentNode.parentNode.parentNode === undefined) { + TS.projects.superalgos.globals.loggerVariables.VARIABLES_BY_PROCESS_INDEX_MAP.get(processIndex).PROCESS_INSTANCE_LOGGER_MODULE.write(MODULE_NAME, + "[ERROR] checkUpstreamOfTaskNode -> Market Tasks without parent Exchange Tasks. This bot process will not run. -> Process Instance = " + JSON.stringify(TS.projects.superalgos.globals.taskConstants.TASK_NODE.bot.processes[processIndex])); + return false + } + /* + Checking the Market that is referenced. + */ + if (TS.projects.superalgos.globals.taskConstants.TASK_NODE.parentNode.parentNode.parentNode.referenceParent === undefined) { + TS.projects.superalgos.globals.loggerVariables.VARIABLES_BY_PROCESS_INDEX_MAP.get(processIndex).PROCESS_INSTANCE_LOGGER_MODULE.write(MODULE_NAME, + "[ERROR] checkUpstreamOfTaskNode -> Market Tasks without a Market. This bot process will not run. -> Process Instance = " + JSON.stringify(TS.projects.superalgos.globals.taskConstants.TASK_NODE.bot.processes[processIndex])); + return false + } + + let marketNode = TS.projects.superalgos.globals.taskConstants.TASK_NODE.parentNode.parentNode.parentNode.referenceParent + + if (marketNode.parentNode === undefined) { + TS.projects.superalgos.globals.loggerVariables.VARIABLES_BY_PROCESS_INDEX_MAP.get(processIndex).PROCESS_INSTANCE_LOGGER_MODULE.write(MODULE_NAME, + "[ERROR] checkUpstreamOfTaskNode -> Market without a Parent. This bot process will not run. -> Received = " + JSON.stringify(marketNode)); + return false + } + + if (marketNode.parentNode.parentNode === undefined) { + TS.projects.superalgos.globals.loggerVariables.VARIABLES_BY_PROCESS_INDEX_MAP.get(processIndex).PROCESS_INSTANCE_LOGGER_MODULE.write(MODULE_NAME, + "[ERROR] checkUpstreamOfTaskNode -> Exchange Markets without a Parent. This bot process will not run. -> Received = " + JSON.stringify(marketNode.parentNode)); + return false + } + + if (marketNode.baseAsset === undefined) { + TS.projects.superalgos.globals.loggerVariables.VARIABLES_BY_PROCESS_INDEX_MAP.get(processIndex).PROCESS_INSTANCE_LOGGER_MODULE.write(MODULE_NAME, + "[ERROR] checkUpstreamOfTaskNode -> Market without a Base Asset. This bot process will not run. -> Received = " + JSON.stringify(marketNode)); + return false + } + + if (marketNode.quotedAsset === undefined) { + TS.projects.superalgos.globals.loggerVariables.VARIABLES_BY_PROCESS_INDEX_MAP.get(processIndex).PROCESS_INSTANCE_LOGGER_MODULE.write(MODULE_NAME, + "[ERROR] checkUpstreamOfTaskNode -> Market without a Quoted Asset. This bot process will not run. -> Received = " + JSON.stringify(marketNode)); + return false + } + + if (marketNode.baseAsset.referenceParent === undefined) { + TS.projects.superalgos.globals.loggerVariables.VARIABLES_BY_PROCESS_INDEX_MAP.get(processIndex).PROCESS_INSTANCE_LOGGER_MODULE.write(MODULE_NAME, + "[ERROR] checkUpstreamOfTaskNode -> Base Asset without a Reference Parent. This bot process will not run. -> Received = " + JSON.stringify(marketNode.baseAsset)); + return false + } + + if (marketNode.quotedAsset.referenceParent === undefined) { + TS.projects.superalgos.globals.loggerVariables.VARIABLES_BY_PROCESS_INDEX_MAP.get(processIndex).PROCESS_INSTANCE_LOGGER_MODULE.write(MODULE_NAME, + "[ERROR] checkUpstreamOfTaskNode -> Quoted Asset without a Reference Parent. This bot process will not run. -> Received = " + JSON.stringify(marketNode.quotedAsset)); + return false + } + return true + } + + function initializeFilePathRoot(processIndex) { + /* + For Single Market Files, the Root Path for files takes an specific structure + which includes the exchange and market. Here that structure is defined. + */ + TS.projects.superalgos.globals.processVariables.VARIABLES_BY_PROCESS_INDEX_MAP.get(processIndex).FILE_PATH_ROOT = + 'Project/' + + TS.projects.superalgos.globals.taskConstants.PROJECT_DEFINITION_NODE.config.codeName + + "/" + + TS.projects.superalgos.globals.taskConstants.TASK_NODE.bot.processes[processIndex].referenceParent.parentNode.parentNode.type.replace(' ', '-') + + "/" + + TS.projects.superalgos.globals.taskConstants.TASK_NODE.bot.processes[processIndex].referenceParent.parentNode.parentNode.config.codeName + + "/" + + TS.projects.superalgos.globals.taskConstants.TASK_NODE.bot.processes[processIndex].referenceParent.parentNode.config.codeName + + '/' + + TS.projects.superalgos.globals.taskConstants.TASK_NODE.parentNode.parentNode.parentNode.referenceParent.parentNode.parentNode.name + + "/" + + TS.projects.superalgos.globals.taskConstants.TASK_NODE.parentNode.parentNode.parentNode.referenceParent.baseAsset.referenceParent.config.codeName + + "-" + + TS.projects.superalgos.globals.taskConstants.TASK_NODE.parentNode.parentNode.parentNode.referenceParent.quotedAsset.referenceParent.config.codeName + + } + } diff --git a/TaskServer/ProcessInstance.js b/TaskServer/ProcessInstance.js index 75863e55e..1259095f6 100644 --- a/TaskServer/ProcessInstance.js +++ b/TaskServer/ProcessInstance.js @@ -13,7 +13,6 @@ function start(processIndex) { try { let botModuleObject - let botConfig = TS.projects.superalgos.globals.taskConstants.TASK_NODE.bot.processes[processIndex].referenceParent.parentNode.config let VARIABLES_BY_PROCESS_INDEX /* We will use a logger for what happens before and after the bot main loop. @@ -47,25 +46,6 @@ */ let MODULE_OBJECTS_BY_PROCESS_INDEX = {} TS.projects.superalgos.globals.processModuleObjects.MODULE_OBJECTS_BY_PROCESS_INDEX_MAP.set(processIndex, MODULE_OBJECTS_BY_PROCESS_INDEX) - - /* File Path Root */ - TS.projects.superalgos.globals.processVariables.VARIABLES_BY_PROCESS_INDEX_MAP.get(processIndex).FILE_PATH_ROOT = - 'Project/' + - TS.projects.superalgos.globals.taskConstants.PROJECT_DEFINITION_NODE.config.codeName + - "/" + - TS.projects.superalgos.globals.taskConstants.TASK_NODE.bot.processes[processIndex].referenceParent.parentNode.parentNode.type.replace(' ', '-') + - "/" + - TS.projects.superalgos.globals.taskConstants.TASK_NODE.bot.processes[processIndex].referenceParent.parentNode.parentNode.config.codeName + - "/" + - botConfig.codeName + - '/' + - TS.projects.superalgos.globals.taskConstants.TASK_NODE.parentNode.parentNode.parentNode.referenceParent.parentNode.parentNode.name + - "/" + - TS.projects.superalgos.globals.taskConstants.TASK_NODE.parentNode.parentNode.parentNode.referenceParent.baseAsset.referenceParent.config.codeName + - "-" + - TS.projects.superalgos.globals.taskConstants.TASK_NODE.parentNode.parentNode.parentNode.referenceParent.quotedAsset.referenceParent.config.codeName - - /* We will scan the project schema until we find the module that will run the bot associated to this process. Note that for being able to find the module that represents @@ -104,7 +84,7 @@ TS.projects.superalgos.globals.processVariables.VARIABLES_BY_PROCESS_INDEX_MAP.get(processIndex).MAIN_LOOP_COUNTER = 0; - let botId = TS.projects.superalgos.globals.taskConstants.TASK_NODE.bot.processes[processIndex].referenceParent.parentNode.parentNode.config.codeName + "." + botConfig.codeName + "." + TS.projects.superalgos.globals.taskConstants.TASK_NODE.bot.processes[processIndex].referenceParent.config.codeName; + let botId = TS.projects.superalgos.globals.taskConstants.TASK_NODE.bot.processes[processIndex].referenceParent.parentNode.parentNode.config.codeName + "." + TS.projects.superalgos.globals.taskConstants.TASK_NODE.bot.processes[processIndex].referenceParent.parentNode.config.codeName + "." + TS.projects.superalgos.globals.taskConstants.TASK_NODE.bot.processes[processIndex].referenceParent.config.codeName; if (err.result === TS.projects.superalgos.globals.standardResponses.DEFAULT_OK_RESPONSE.result) { TS.projects.superalgos.globals.loggerVariables.VARIABLES_BY_PROCESS_INDEX_MAP.get(processIndex).PROCESS_INSTANCE_LOGGER_MODULE.write(MODULE_NAME, "[INFO] start -> onInitializeReady -> whenStartFinishes -> Bot execution finished sucessfully."); diff --git a/TaskServer/Task.js b/TaskServer/Task.js index 4b7a448d9..586227236 100644 --- a/TaskServer/Task.js +++ b/TaskServer/Task.js @@ -140,67 +140,6 @@ function bootingProcess() { } for (let processIndex = 0; processIndex < TS.projects.superalgos.globals.taskConstants.TASK_NODE.bot.processes.length; processIndex++) { - - /* Validate that the minimun amount of input required are defined. */ - if (TS.projects.superalgos.globals.taskConstants.TASK_NODE.parentNode === undefined) { - console.log("[ERROR] Task Server -> Task -> bootingProcess -> Task without a Task Manager. This process will not be executed. -> Process Instance = " + JSON.stringify(TS.projects.superalgos.globals.taskConstants.TASK_NODE.bot.processes[processIndex])); - continue - } - - if (TS.projects.superalgos.globals.taskConstants.TASK_NODE.parentNode.parentNode === undefined) { - console.log("[ERROR] Task Server -> Task -> bootingProcess -> Task Manager without parent Mine Tasks. This process will not be executed. -> Process Instance = " + JSON.stringify(TS.projects.superalgos.globals.taskConstants.TASK_NODE.bot.processes[processIndex])); - continue - } - - if (TS.projects.superalgos.globals.taskConstants.TASK_NODE.parentNode.parentNode.parentNode === undefined) { - console.log("[ERROR] Task Server -> Task -> bootingProcess -> Mine Tasks without parent Market Tasks. This process will not be executed. -> Process Instance = " + JSON.stringify(TS.projects.superalgos.globals.taskConstants.TASK_NODE.bot.processes[processIndex])); - continue - } - - if (TS.projects.superalgos.globals.taskConstants.TASK_NODE.parentNode.parentNode.parentNode === undefined) { - console.log("[ERROR] Task Server -> Task -> bootingProcess -> Market Tasks without parent Exchange Tasks. This process will not be executed. -> Process Instance = " + JSON.stringify(TS.projects.superalgos.globals.taskConstants.TASK_NODE.bot.processes[processIndex])); - continue - } - /* - Checking the Market that is referenced. - */ - if (TS.projects.superalgos.globals.taskConstants.TASK_NODE.parentNode.parentNode.parentNode.referenceParent === undefined) { - console.log("[ERROR] Task Server -> Task -> bootingProcess -> Market Tasks without a Market. This process will not be executed. -> Process Instance = " + JSON.stringify(TS.projects.superalgos.globals.taskConstants.TASK_NODE.bot.processes[processIndex])); - continue - } - - global.MARKET_NODE = TS.projects.superalgos.globals.taskConstants.TASK_NODE.parentNode.parentNode.parentNode.referenceParent - - if (global.MARKET_NODE.parentNode === undefined) { - console.log("[ERROR] Task Server -> Task -> bootingProcess -> Market without a Parent. This process will not be executed. -> Process Instance = " + JSON.stringify(global.MARKET_NODE)); - continue - } - - if (global.MARKET_NODE.parentNode.parentNode === undefined) { - console.log("[ERROR] Task Server -> Task -> bootingProcess -> Exchange Markets without a Parent. This process will not be executed. -> Process Instance = " + JSON.stringify(global.MARKET_NODE.parentNode)); - continue - } - - if (global.MARKET_NODE.baseAsset === undefined) { - console.log("[ERROR] Task Server -> Task -> bootingProcess -> Market without a Base Asset. This process will not be executed. -> Process Instance = " + JSON.stringify(global.MARKET_NODE)); - continue - } - - if (global.MARKET_NODE.quotedAsset === undefined) { - console.log("[ERROR] Task Server -> Task -> bootingProcess -> Market without a Quoted Asset. This process will not be executed. -> Process Instance = " + JSON.stringify(global.MARKET_NODE)); - continue - } - - if (global.MARKET_NODE.baseAsset.referenceParent === undefined) { - console.log("[ERROR] Task Server -> Task -> bootingProcess -> Base Asset without a Reference Parent. This process will not be executed. -> Process Instance = " + JSON.stringify(global.MARKET_NODE.baseAsset)); - continue - } - - if (global.MARKET_NODE.quotedAsset.referenceParent === undefined) { - console.log("[ERROR] Task Server -> Task -> bootingProcess -> Quoted Asset without a Reference Parent. This process will not be executed. -> Process Instance = " + JSON.stringify(global.MARKET_NODE.quotedAsset)); - continue - } - /* Here we will validate that the process is connected all the way to a Mine and that nodes in the middle have whatever config is mandatory.