diff --git a/IndicatorBotProcessMainLoop.js b/IndicatorBotProcessMainLoop.js index b1bdfc5d1..6891951ed 100644 --- a/IndicatorBotProcessMainLoop.js +++ b/IndicatorBotProcessMainLoop.js @@ -808,7 +808,7 @@ if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] run -> loop -> loopControl -> onStop -> Stopping the Loop Gracefully. See you next time!"); } - if(global.FULL_LOG === 'true'){ + if(global.WRITE_LOGS_TO_FILES === 'true'){ logger.persist(); } @@ -828,7 +828,7 @@ if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] run -> loop -> loopControl -> Restarting Loop in " + (processConfig.normalWaitTime / 1000) + " seconds."); } checkLoopHealthHandle = setTimeout(checkLoopHealth, processConfig.normalWaitTime * 5, bot.loopCounter); nextLoopTimeoutHandle = setTimeout(loop, processConfig.normalWaitTime); - if(global.FULL_LOG === 'true'){ + if(global.WRITE_LOGS_TO_FILES === 'true'){ logger.persist(); } } @@ -869,7 +869,7 @@ let now = new Date().valueOf(); - if (now - bot.loopStartTime > processConfig.normalWaitTime) { + if (now - bot.loopStartTime > processConfig.deadWaitTime) { logger.write(MODULE_NAME, "[ERROR] run -> loop -> checkLoopHealth -> Dead loop found -> pLastLoop = " + pLastLoop); console.log((new Date().toISOString() + " [ERROR] run -> loop -> checkLoopHealth -> " + pad(bot.codeName,20) + " " + pad(bot.process,30) + " Loop # " + pad(Number(bot.loopCounter),5) + " found dead. Resurrecting it now.")); @@ -898,7 +898,7 @@ if (process.env.STOP_GRACEFULLY !== undefined) stop = JSON.parse(process.env.STOP_GRACEFULLY) - if (!stop && global.SHALL_BOT_STOP === false) { + if (!stop) { continueCallBack(); } else { stopCallBack(); @@ -925,7 +925,7 @@ } function hearBeat() { - let key = global.USER_DEFINITION.bot.processes[global.sequenceStep - 1].name + '-' + global.USER_DEFINITION.bot.processes[global.sequenceStep - 1].type + '-' + global.USER_DEFINITION.bot.processes[global.sequenceStep - 1].id + let key = global.USER_DEFINITION.bot.processes[bot.processIndex].name + '-' + global.USER_DEFINITION.bot.processes[bot.processIndex].type + '-' + global.USER_DEFINITION.bot.processes[bot.processIndex].id let event = { seconds: (new Date()).getSeconds() diff --git a/Integrations/Definition.js b/Integrations/Definition.js deleted file mode 100644 index 3dbbc46eb..000000000 --- a/Integrations/Definition.js +++ /dev/null @@ -1,51 +0,0 @@ -const axios = require('axios') -let fs = require('fs') -const { promisify } = require('util') -const readFileAsync = promisify(fs.readFile) - -exports.getDefinition = async function () { - try { - if (!global.DEFINITION) { - let executionOnCloud = false - if (process.env.ON_CLOUD !== undefined) { - executionOnCloud = JSON.parse(process.env.ON_CLOUD) - } - - if (executionOnCloud) { - const strategizerResponse = await axios({ - url: process.env.GATEWAY_ENDPOINT_K8S, - method: 'post', - data: { - query: ` - query($fbSlug: String!){ - strategizer_TradingSystemByFb(fbSlug: $fbSlug){ - data - } - } - `, - variables: { - fbSlug: process.env.BOT - } - }, - headers: { - authorization: process.env.AUTHORIZATION - } - }) - - if (strategizerResponse.data.errors) { - throw new Error(strategizerResponse.data.errors[0].message) - } - - global.DEFINITION = strategizerResponse.data.data.strategizer_TradingSystemByFb.data - } else { - let fileLocation = process.env.INTER_PROCESS_FILES_PATH + '/definition.json' - let definition = readFile(fileLocation, { encoding: 'utf8' }) - global.DEFINITION = JSON.parse(definition) - } - } - - return global.DEFINITION - } catch (error) { - throw new Error('There has been an error getting the definition: ', JSON.stringify(error)) - } -} diff --git a/MultiPeriod.js b/MultiPeriod.js index 56cd5480e..d464c00dd 100644 --- a/MultiPeriod.js +++ b/MultiPeriod.js @@ -496,7 +496,7 @@ console.log(new Date().toISOString() + " " + pad(bot.codeName, 20) + " " + pad(bot.process, 30) + " " + " bot.multiPeriodDailyProcessDatetime = " + bot.multiPeriodDailyProcessDatetime.toISOString()); - if (global.FULL_LOG === 'true') { + if (global.WRITE_LOGS_TO_FILES === 'true') { logger.newInternalLoop(bot.codeName, bot.process); } diff --git a/MultiPeriodDaily.js b/MultiPeriodDaily.js index 09f870f6c..968ad329c 100644 --- a/MultiPeriodDaily.js +++ b/MultiPeriodDaily.js @@ -300,7 +300,7 @@ console.log(new Date().toISOString() + " " + pad(bot.codeName, 20) + " " + pad(bot.process, 30) + " " + " bot.multiPeriodDailyProcessDatetime = " + bot.multiPeriodDailyProcessDatetime.toISOString()); - if (global.FULL_LOG === 'true') { + if (global.WRITE_LOGS_TO_FILES === 'true') { logger.newInternalLoop(bot.codeName, bot.process); } diff --git a/Project.njsproj b/Project.njsproj index 2d9bfbc32..8db0453a3 100644 --- a/Project.njsproj +++ b/Project.njsproj @@ -27,7 +27,6 @@ - Code @@ -69,9 +68,6 @@ Code - - Code - diff --git a/Root.js b/Root.js index 1e031b898..d57d59ae2 100644 --- a/Root.js +++ b/Root.js @@ -45,7 +45,7 @@ const FULL_LOG = true; - let logDisplace = "CloneExecutor" + " "; + let logDisplace = "Task Server" + " "; let UI_COMMANDS; return thisObject; @@ -106,7 +106,7 @@ } } - function start(callback) { + function start(processIndex) { /* Now we will run according to what we see at the config file. */ @@ -119,7 +119,6 @@ /* Process Loops Declarations. */ - const TRADING_BOT_MAIN_LOOP_MODULE = require('./TradingBotProcessMainLoop'); const INDICATOR_BOT_MAIN_LOOP_MODULE = require('./IndicatorBotProcessMainLoop'); const EXTRACTION_BOT_MAIN_LOOP_MODULE = require('./SensorBotProcessMainLoop'); const TRADING_ENGINE_MAIN_LOOP_MODULE = require('./TradingEngineProcessMainLoop'); @@ -128,7 +127,7 @@ let cloneToExecute = global.EXECUTION_CONFIG.cloneToExecute; - /* Now we will read the config of the bot from the path we obtained at the CloneExecutor config. */ + /* Now we will read the config of the bot from the path we obtained at the Task Server config. */ let botConfig; @@ -157,7 +156,7 @@ try { botConfig = JSON.parse(text); botConfig.repo = cloneToExecute.repo; - findProcess(); + findProcess(processIndex); } catch (err) { console.log(logDisplace + "Root : [ERROR] start -> getBotConfig -> onInizialized -> onFileReceived -> err = " + JSON.stringify(err)); return; @@ -170,13 +169,14 @@ } } - function findProcess() { + function findProcess(processIndex) { try { if (FULL_LOG === true) { console.log(logDisplace + "Root : [INFO] start -> findProcess -> Entering function. "); } botConfig.process = cloneToExecute.process; botConfig.debug = {}; + botConfig.processIndex = processIndex /* Loop Counter */ @@ -395,10 +395,6 @@ } switch (botConfig.type) { - case 'Trading': { - runTradingBot(botConfig, processConfig); - break; - } case 'Trading-Engine': { runTradingEngine(botConfig, processConfig); break; @@ -424,10 +420,6 @@ botConfig.hasTheBotJustStarted = true; switch (botConfig.type) { - case 'Trading': { - runTradingBot(botConfig, processConfig); - break; - } case 'Trading-Engine': { runTradingEngine(botConfig, processConfig); break; @@ -439,33 +431,6 @@ } } - if (processConfig.startMode.competition !== undefined) { - - if (processConfig.startMode.competition.run === "true") { - - botConfig.startMode = "Competition"; - console.log(logDisplace + "Root : [INFO] start -> findProcess -> Process found at the bot configuration file. -> Start Mode = " + botConfig.startMode); - - botConfig.competition = processConfig.startMode.competition; - - if (processConfig.startMode.competition.resumeExecution === false) { - botConfig.hasTheBotJustStarted = true; - } else { - botConfig.hasTheBotJustStarted = false; - } - - switch (botConfig.type) { - case 'Trading': { - runTradingBot(botConfig, processConfig); - break; - } - default: { - console.log(logDisplace + "Root : [ERROR] start -> findProcess -> Unexpected bot type. -> botConfig.type = " + botConfig.type); - } - } - } - } - } catch (err) { console.log(logDisplace + "Root : [ERROR] start -> findProcess -> Unexpected exception. -> err.message = " + err.message); } @@ -474,7 +439,7 @@ if (processFound === false) { - console.log(logDisplace + "Root : [ERROR] start -> findProcess -> Process listed at the configuration file of CloneExecutor not found at the configuration file of the bot."); + console.log(logDisplace + "Root : [ERROR] start -> findProcess -> Process listed at the configuration file of Task Server not found at the configuration file of the bot."); console.log(logDisplace + "Root : [ERROR] start -> findProcess -> cloneToExecute.process = " + cloneToExecute.process); } @@ -520,7 +485,6 @@ console.log(logDisplace + "Root : [INFO] start -> findProcess -> runSensorBot -> onInitializeReady -> whenStartFinishes -> botId = " + botId); console.log(logDisplace + "Root : [INFO] start -> findProcess -> runSensorBot -> onInitializeReady -> whenStartFinishes -> Bot execution finished sucessfully."); - logger.persist(); } else { @@ -534,7 +498,7 @@ console.log(logDisplace + "Root : [ERROR] start -> findProcess -> runSensorBot -> onInitializeReady -> whenStartFinishes -> Bot execution was aborted."); logger.persist(); } - callback(err, pBotConfig.devTeam + "." + pBotConfig.codeName + "." + pBotConfig.process) + exitProcess() } } else { @@ -543,11 +507,13 @@ console.log(logDisplace + "Root : [ERROR] start -> findProcess -> runSensorBot -> onInitializeReady -> err = "+ err.stack); logger.persist(); + exitProcess() } } } catch (err) { - console.log(logDisplace + "Root : [ERROR] start -> findProcess -> runSensorBot -> err = "+ err.stack); + console.log(logDisplace + "Root : [ERROR] start -> findProcess -> runSensorBot -> err = " + err.stack); + exitProcess() } } @@ -591,7 +557,6 @@ console.log(logDisplace + "Root : [INFO] start -> findProcess -> runIndicatorBot -> onInitializeReady -> whenStartFinishes -> botId = " + botId); console.log(logDisplace + "Root : [INFO] start -> findProcess -> runIndicatorBot -> onInitializeReady -> whenStartFinishes -> Bot execution finished sucessfully."); - logger.persist(); } else { @@ -603,7 +568,7 @@ console.log(logDisplace + "Root : [ERROR] start -> findProcess -> runIndicatorBot -> onInitializeReady -> whenStartFinishes -> Bot execution finished with errors. Please check the logs."); logger.persist(); } - callback(err, pBotConfig.devTeam + "." + pBotConfig.codeName + "." + pBotConfig.process) + exitProcess() } } else { @@ -611,191 +576,13 @@ logger.write(MODULE_NAME, "[ERROR] start -> findProcess -> runIndicatorBot -> onInitializeReady -> Failed to initialize the bot. "); console.log(logDisplace + "Root : [ERROR] start -> findProcess -> runIndicatorBot -> onInitializeReady -> err = "+ err.stack); logger.persist(); + exitProcess() } } } catch (err) { console.log(logDisplace + "Root : [ERROR] start -> findProcess -> runIndicatorBot -> err = "+ err.stack); - - } - } - - function runTradingBot(pBotConfig, pProcessConfig) { - - try { - - if (FULL_LOG === true) { console.log(logDisplace + "[INFO] start -> findProcess -> runTradingBot -> Entering function."); } - - if (pBotConfig.genes !== undefined) { - - /* Here, based on the gene we will create one instance for each combination of genes */ - - let valueMatrix = []; - - for (let i = 0; i < pBotConfig.genes.length; i++) { - - let gene = pBotConfig.genes[i]; - - let possibleValues = []; - - for (let j = gene.lowerLimit; j <= gene.upperLimit; j++) { - - possibleValues.push(j); - - } - - valueMatrix.push(possibleValues); - - } - - /* - Now we have all the possible genes values in a multi-dimensional matrix. - We will go thorugh each of the elements of each dimension and get each combination possible with the other dimmensions. - */ - - let combinations = []; - let combination = []; - let dimensionIndex = 0; - - calculateCombinations(dimensionIndex, combination); - - function calculateCombinations(pDimensionIndex, pCombination) { - - let dimension = valueMatrix[pDimensionIndex]; - - for (let j = 0; j < dimension.length; j++) { - - let copy = JSON.parse(JSON.stringify(pCombination)); - - let value = dimension[j]; - copy.push(value); - - if (pDimensionIndex < valueMatrix.length - 1) { - - calculateCombinations(pDimensionIndex + 1, copy); - - } else { - - combinations.push(copy); - - } - } - } - - /* At this point we have an array with all the possible combinations, we just need to create an instance for each one and set the genes according to that. */ - - for (let i = 0; i < combinations.length; i++) { - - let botConfig = JSON.parse(JSON.stringify(pBotConfig)); - let combination = combinations[i]; - let genes = {}; - let clonKey = ""; - - for (let j = 0; j < botConfig.genes.length; j++) { - - genes[botConfig.genes[j].name] = combination[j]; - clonKey = clonKey + "." + combination[j]; - - } - - let clonName = botConfig.codeName + "-" + "Clon" + clonKey; - clonName += ".1.0"; - clonName += "-" + process.env.CLONE_ID; - - botConfig.filePathRoot = botConfig.devTeam + "/" + clonName + "/" + global.CLONE_EXECUTOR.codeName + "." + global.CLONE_EXECUTOR.version + "/" + global.EXCHANGE_NAME + "/" + botConfig.dataSetVersion; - - botConfig.instance = clonName; - botConfig.instanceIndex = i; - - setTimeout(execute, i * Math.random() * 10 * 1000); - - function execute() { - - createBotInstance(genes, combinations.length, botConfig); - - } - } - } else { - - /* If the bot does not have any genes at all */ - - let genes = {}; - let clonName = botConfig.codeName; - clonName += "-" + process.env.CLONE_ID; - clonName += ".1.0"; - - botConfig.filePathRoot = botConfig.devTeam + "/" + clonName + "/" + global.CLONE_EXECUTOR.codeName + "." + global.CLONE_EXECUTOR.version + "/" + global.EXCHANGE_NAME + "/" + botConfig.dataSetVersion; - - pBotConfig.instance = clonName; - pBotConfig.instanceIndex = 0; - - createBotInstance(genes, 1, pBotConfig); - - } - - - function createBotInstance(pGenes, pTotalInstances, pBotConfig) { - - const DEBUG_MODULE = require(ROOT_DIR + 'DebugLog'); - let logger; - - logger = DEBUG_MODULE.newDebugLog(); - logger.bot = pBotConfig; - pBotConfig.timePeriodFileStorage = global.EXECUTION_CONFIG.timePeriodFileStorage - pBotConfig.dataSet = global.EXECUTION_CONFIG.dataSet - - if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] start -> findProcess -> runTradingBot -> createBotInstance -> Entering function."); } - - let tradingBotMainLoop = TRADING_BOT_MAIN_LOOP_MODULE.newTradingBotProcessMainLoop(pBotConfig, logger); - tradingBotMainLoop.initialize(UI_COMMANDS, pProcessConfig, onInitializeReady); - - function onInitializeReady(err) { - - if (err.result === global.DEFAULT_OK_RESPONSE.result) { - - tradingBotMainLoop.run(pGenes, whenRunFinishes); - - function whenRunFinishes(err) { - - pBotConfig.loopCounter = 0; - - let botId; - - botId = pBotConfig.devTeam + "." + pBotConfig.codeName + "." + pBotConfig.instance + "." + pBotConfig.process; - - if (err.result === global.DEFAULT_OK_RESPONSE.result) { - - logger.write(MODULE_NAME, "[INFO] start -> findProcess -> runTradingBot -> createBotInstance -> onInitializeReady -> whenStartFinishes -> Bot execution finished sucessfully."); - logger.write(MODULE_NAME, "[INFO] start -> findProcess -> runTradingBot -> createBotInstance -> onInitializeReady -> whenStartFinishes -> Bot Id = " + botId); - - console.log(logDisplace + "Root : [INFO] start -> findProcess -> runTradingBot -> createBotInstance -> onInitializeReady -> whenStartFinishes -> botId = " + botId); - console.log(logDisplace + "Root : [INFO] start -> findProcess -> runTradingBot -> createBotInstance -> onInitializeReady -> whenStartFinishes -> Bot execution finished sucessfully."); - logger.persist(); - - } else { - - logger.write(MODULE_NAME, "[ERROR] start -> findProcess -> runTradingBot -> createBotInstance -> onInitializeReady -> whenStartFinishes -> err = "+ err.stack); - logger.write(MODULE_NAME, "[ERROR] start -> findProcess -> runTradingBot -> createBotInstance -> onInitializeReady -> whenStartFinishes -> Execution will be stopped. "); - logger.write(MODULE_NAME, "[ERROR] start -> findProcess -> runTradingBot -> createBotInstance -> onInitializeReady -> whenStartFinishes -> Bye."); - logger.write(MODULE_NAME, "[ERROR] start -> findProcess -> runTradingBot -> createBotInstance -> onInitializeReady -> whenStartFinishes -> Bot Id = " + botId); - console.log(logDisplace + "Root : [ERROR] start -> findProcess -> runTradingBot -> createBotInstance -> onInitializeReady -> whenStartFinishes -> Bot execution finished with errors. Please check the logs."); - logger.persist(); - } - callback(err, pBotConfig.devTeam + "." + pBotConfig.codeName + "." + pBotConfig.process) - } - - } else { - logger.write(MODULE_NAME, "[ERROR] start -> findProcess -> runTradingBot -> createBotInstance -> onInitializeReady -> err = "+ err.stack); - logger.write(MODULE_NAME, "[ERROR] start -> findProcess -> runTradingBot -> createBotInstance -> onInitializeReady -> Bot will not be started. "); - console.log(logDisplace + "Root : [ERROR] start -> findProcess -> runTradingBot -> createBotInstance -> onInitializeReady -> err = "+ err.stack); - - logger.persist(); - } - } - } - } - catch (err) { - console.log(logDisplace + "Root : [ERROR] start -> findProcess -> runTradingBot -> err = "+ err.stack); + exitProcess() } } @@ -834,7 +621,6 @@ console.log(logDisplace + "Root : [INFO] start -> findProcess -> runTradingEngine -> onInitializeReady -> whenStartFinishes -> botId = " + botId); console.log(logDisplace + "Root : [INFO] start -> findProcess -> runTradingEngine -> onInitializeReady -> whenStartFinishes -> Bot execution finished sucessfully."); - logger.persist(); } else { @@ -846,7 +632,7 @@ console.log(logDisplace + "Root : [ERROR] start -> findProcess -> runTradingEngine -> onInitializeReady -> whenStartFinishes -> Bot execution finished with errors. Please check the logs."); logger.persist(); } - callback(err, pBotConfig.devTeam + "." + pBotConfig.codeName + "." + pBotConfig.process) + exitProcess() } } else { @@ -854,22 +640,49 @@ logger.write(MODULE_NAME, "[ERROR] start -> findProcess -> runTradingEngine -> onInitializeReady -> Failed to initialize the bot. "); console.log(logDisplace + "Root : [ERROR] start -> findProcess -> runTradingEngine -> onInitializeReady -> err = "+ err.stack); logger.persist(); + exitProcess() } } } catch (err) { console.log(logDisplace + "Root : [ERROR] start -> findProcess -> runTradingEngine -> err = "+ err.stack); - + exitProcess() } } - } catch (err) { console.log(logDisplace + "Root : [ERROR] start -> findProcess -> err.message = " + err.message); - return; + exitProcess() } } + function exitProcess() { + + global.ENDED_PROCESSES_COUNTER++ + console.log("[INFO] Task Server -> exitProcess -> Process #" + global.ENDED_PROCESSES_COUNTER + " exiting."); + + if (global.ENDED_PROCESSES_COUNTER === global.USER_DEFINITION.bot.processes.length) { + /* Cleaning Before Exiting. */ + clearInterval(global.HEARTBEAT_INTERVAL_HANDLER) + + for (let i = 0; i < global.USER_DEFINITION.bot.processes.length; i++) { + let code = global.USER_DEFINITION.bot.processes[i].code + + /* Delete the event handler for each process. */ + + let key = code.devTeam + "-" + code.codeName + "-" + code.process + let event = { + reason: 'Signal Received to Terminate this Process.' + } + global.SYSTEM_EVENT_HANDLER.raiseEvent(key, 'Process Terminated', event) + global.SYSTEM_EVENT_HANDLER.deleteEventHandler(key) + } + + global.SYSTEM_EVENT_HANDLER.finalize() + global.SYSTEM_EVENT_HANDLER = undefined + console.log("[INFO] Task Server -> exitProcess -> Task Server Stopped."); + } + } } } diff --git a/SensorBotProcessMainLoop.js b/SensorBotProcessMainLoop.js index a025be6d0..c98cd05d7 100644 --- a/SensorBotProcessMainLoop.js +++ b/SensorBotProcessMainLoop.js @@ -557,7 +557,7 @@ if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] run -> loop -> loopControl -> onStop -> Stopping the Loop Gracefully. See you next time!"); } - if(global.FULL_LOG === 'true'){ + if(global.WRITE_LOGS_TO_FILES === 'true'){ logger.persist(); } @@ -581,15 +581,15 @@ if (bot.runAtFixedInterval === true) { if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] run -> loop -> loopControl -> Fixed Interval Normal exit point reached."); } checkLoopHealthHandle = setTimeout(checkLoopHealth, bot.fixedInterval * 5, bot.loopCounter); - if(global.FULL_LOG === 'true'){ + if(global.WRITE_LOGS_TO_FILES === 'true'){ logger.persist(); } return; } else { if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] run -> loop -> loopControl -> Restarting Loop in " + (processConfig.normalWaitTime / 1000) + " seconds."); } - checkLoopHealthHandle = setTimeout(checkLoopHealth, processConfig.normalWaitTime * 5, bot.loopCounter); + checkLoopHealthHandle = setTimeout(checkLoopHealth, processConfig.deadWaitTime * 5, bot.loopCounter); nextLoopTimeoutHandle = setTimeout(loop, processConfig.normalWaitTime); - if(global.FULL_LOG === 'true'){ + if(global.WRITE_LOGS_TO_FILES === 'true'){ logger.persist(); } } @@ -643,7 +643,7 @@ let now = new Date().valueOf(); - if (now - bot.loopStartTime > processConfig.normalWaitTime) { + if (now - bot.loopStartTime > processConfig.deadWaitTime) { logger.write(MODULE_NAME, "[ERROR] run -> loop -> checkLoopHealth -> Dead loop found -> pLastLoop = " + pLastLoop); console.log((new Date().toISOString() + " [ERROR] run -> loop -> checkLoopHealth -> " + pad(bot.codeName, 20) + " " + pad(bot.process, 30) + " Loop # " + pad(Number(bot.loopCounter), 5) + " found dead. Resurrecting it now.")); @@ -672,7 +672,7 @@ if (process.env.STOP_GRACEFULLY !== undefined) stop = JSON.parse(process.env.STOP_GRACEFULLY) - if (!stop && global.SHALL_BOT_STOP === false) { + if (!stop) { continueCallBack(); } else { stopCallBack(); @@ -700,7 +700,7 @@ } function hearBeat() { - let key = global.USER_DEFINITION.bot.processes[global.sequenceStep - 1].name + '-' + global.USER_DEFINITION.bot.processes[global.sequenceStep - 1].type + '-' + global.USER_DEFINITION.bot.processes[global.sequenceStep - 1].id + let key = global.USER_DEFINITION.bot.processes[bot.processIndex].name + '-' + global.USER_DEFINITION.bot.processes[bot.processIndex].type + '-' + global.USER_DEFINITION.bot.processes[bot.processIndex].id let event = { seconds: (new Date()).getSeconds() diff --git a/TradingBotProcessMainLoop.js b/TradingBotProcessMainLoop.js deleted file mode 100644 index 6db2d7c29..000000000 --- a/TradingBotProcessMainLoop.js +++ /dev/null @@ -1,1036 +0,0 @@ -exports.newTradingBotProcessMainLoop = function newTradingBotProcessMainLoop(bot, parentLogger) { - - const ROOT_DIR = './'; - - const MODULE_NAME = "Trading Bot Process Main Loop"; - const FULL_LOG = true; - - let USER_BOT_MODULE; - let COMMONS_MODULE; - - const DEBUG_MODULE = require(ROOT_DIR + 'DebugLog'); - const FILE_STORAGE = require('./Integrations/FileStorage.js'); - let fileStorage = FILE_STORAGE.newFileStorage(parentLogger); - let logger; // We need this here in order for the loopHealth function to work and be able to rescue the loop when it gets in trouble. - - let nextLoopTimeoutHandle; - let checkLoopHealthHandle; - - let thisObject = { - initialize: initialize, - run: run - }; - - bot["botCache"] = new Map(); - let processConfig; - let UI_COMMANDS; - - return thisObject; - - function initialize(pUI_COMMANDS, pProcessConfig, callBackFunction) { - - /* This function is exactly the same in the 3 modules representing the 2 different bot types loops. */ - - try { - if (FULL_LOG === true) { parentLogger.write(MODULE_NAME, "[INFO] initialize -> Entering function."); } - - UI_COMMANDS = pUI_COMMANDS; - processConfig = pProcessConfig; - - let filePath = global.DEV_TEAM + "/" + "bots" + "/" + bot.repo + "/" + pProcessConfig.name - filePath += "/User.Bot.js" - - fileStorage.getTextFile(global.DEV_TEAM, filePath, onBotDownloaded); - - function onBotDownloaded(err, text) { - - if (err.result !== global.DEFAULT_OK_RESPONSE.result) { - - parentLogger.write(MODULE_NAME, "[ERROR] initialize -> onInizialized -> onBotDownloaded -> err.message = " + err.message); - callBackFunction(global.DEFAULT_FAIL_RESPONSE); - return; - } - USER_BOT_MODULE = {} - USER_BOT_MODULE.newUserBot = eval(text); // TODO This needs to be changed function - - filePath = global.DEV_TEAM + "/" + "bots" + "/" + bot.repo; - filePath += "/Commons.js" - - fileStorage.getTextFile(global.DEV_TEAM, filePath, onCommonsDownloaded); - - function onCommonsDownloaded(err, text) { - - if (err.result !== global.DEFAULT_OK_RESPONSE.result) { - parentLogger.write(MODULE_NAME, "[WARN] initialize -> onBotDownloaded -> onCommonsDownloaded -> Commons not found: " + err.code || err.message); - callBackFunction(global.DEFAULT_OK_RESPONSE); - return; - } - COMMONS_MODULE = {} - COMMONS_MODULE.newCommons = eval(text); // TODO This needs to be changed function - - callBackFunction(global.DEFAULT_OK_RESPONSE); - } - } - } catch (err) { - parentLogger.write(MODULE_NAME, "[ERROR] initialize -> err = "+ err.stack); - callBackFunction(global.DEFAULT_FAIL_RESPONSE); - } - } - - function run(pGenes, callBackFunction) { - - let context; - - try { - if (FULL_LOG === true) { parentLogger.write(MODULE_NAME, "[INFO] run -> Entering function."); } - - bot.enableCheckLoopHealth = true; - - let fixedTimeLoopIntervalHandle; - - if (bot.runAtFixedInterval === true) { - - fixedTimeLoopIntervalHandle = setInterval(loop, bot.fixedInterval); - - } else { - - loop(); - - } - - function loop() { - - try { - - function pad(str, max) { - str = str.toString(); - return str.length < max ? pad(" " + str, max) : str; - } - - /* For each loop we want to create a new log file. */ - - logger = DEBUG_MODULE.newDebugLog(); - logger.bot = bot; - logger.initialize(); - - bot.loopCounter++; - bot.loopStartTime = new Date().valueOf(); - - if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] run -> loop -> Entering function."); } - - /* 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('@superalgos/exchange-gateway'); - const CONTEXT = require(ROOT_DIR + 'Context'); - const ASSISTANT = require(ROOT_DIR + 'Assistant'); - const STATUS_REPORT = require(ROOT_DIR + 'StatusReport'); - const DATA_SET = require(ROOT_DIR + 'DataSet'); - const STATUS_DEPENDENCIES = require(ROOT_DIR + 'StatusDependencies'); - const DATA_DEPENDENCIES = require(ROOT_DIR + 'DataDependencies'); - - /* Waitime Variable */ - - let nextWaitTime; - - /* We define the datetime for the process that we are running now. This will be the official processing time for both the infraestructure and the bot. */ - - switch (bot.startMode) { - case 'Live': { - - if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] run -> loop -> Live Mode detected."); } - - if(process.env.WAIT_TIME !== undefined) - processConfig.normalWaitTime = process.env.WAIT_TIME - - // This will be considered the process date and time, so as to have it consistenly all over the execution. - - let localDate = new Date(); - - bot.processDatetime = new Date(Date.UTC( - localDate.getUTCFullYear(), - localDate.getUTCMonth(), - localDate.getUTCDate(), - localDate.getUTCHours(), - localDate.getUTCMinutes(), - localDate.getUTCSeconds(), - localDate.getUTCMilliseconds())); - - if (UI_COMMANDS.eventHandler !== undefined) { - - UI_COMMANDS.eventHandler.raiseEvent('Bot Execution Changed Datetime', bot.processDatetime); - - } - - break; - } - case 'Backtest': { - - if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] run -> loop -> Backtesting Mode detected."); } - - if(process.env.WAIT_TIME !== undefined) { - processConfig.normalWaitTime = JSON.parse(process.env.WAIT_TIME) - } - - if (bot.hasTheBotJustStarted === true) { - if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] run -> loop -> Setting initial datetime."); } - bot.processDatetime = new Date(bot.backtest.beginDatetime); // Set the starting time as the configured beginDatetime. - } else { - bot.processDatetime = new Date(bot.processDatetime.valueOf() + 60000); // We advance time here. - let endDatetime = new Date(bot.backtest.endDatetime); - - if (bot.processDatetime.valueOf() > endDatetime.valueOf()) { - if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] run -> loop -> End of Backtesting Period reached. Exiting Bot Process Loop."); } - logger.persist(); - clearInterval(fixedTimeLoopIntervalHandle); - clearTimeout(nextLoopTimeoutHandle); - clearTimeout(checkLoopHealthHandle); - bot.enableCheckLoopHealth = false; - callBackFunction(global.DEFAULT_OK_RESPONSE); - return; - } - } - break; - } - case 'Competition': { - - if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] run -> loop -> Competition Mode detected."); } - - if(process.env.WAIT_TIME !== undefined) { - processConfig.normalWaitTime = process.env.WAIT_TIME - } - - let localDate = new Date(); - - bot.processDatetime = new Date(Date.UTC( - localDate.getUTCFullYear(), - localDate.getUTCMonth(), - localDate.getUTCDate(), - localDate.getUTCHours(), - localDate.getUTCMinutes(), - localDate.getUTCSeconds(), - localDate.getUTCMilliseconds())); - - if (UI_COMMANDS.eventHandler !== undefined) { - - UI_COMMANDS.eventHandler.raiseEvent('Bot Execution Changed Datetime', bot.processDatetime); - - } - - let beginDatetime = new Date(bot.competition.beginDatetime); - - if (bot.processDatetime.valueOf() < beginDatetime.valueOf()) { - - if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] run -> loop -> Competition not started yet. Wainting for the competition to start."); } - - nextWaitTime = 'Normal'; - loopControl(nextWaitTime); - return; - } - - let endDatetime = new Date(bot.competition.endDatetime); - - if (bot.processDatetime.valueOf() > endDatetime.valueOf()) { - - if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] run -> loop -> End of Competition Period reached. Exiting Bot Process Loop."); } - - logger.persist(); - clearInterval(fixedTimeLoopIntervalHandle); - clearTimeout(nextLoopTimeoutHandle); - clearTimeout(checkLoopHealthHandle); - bot.enableCheckLoopHealth = false; - callBackFunction(global.DEFAULT_OK_RESPONSE); - return; - } - - break; - } - default: { - logger.write(MODULE_NAME, "[ERROR] run -> loop -> Unexpected bot.startMode."); - logger.write(MODULE_NAME, "[ERROR] run -> loop -> bot.startMode = " + bot.startMode); - logger.persist(); - clearInterval(fixedTimeLoopIntervalHandle); - clearTimeout(nextLoopTimeoutHandle); - clearTimeout(checkLoopHealthHandle); - bot.enableCheckLoopHealth = false; - callBackFunction(global.DEFAULT_FAIL_RESPONSE); - return; - } - } - - if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] run -> loop -> bot.processDatetime = " + bot.processDatetime.toISOString()); } - - - /* High level log entry */ - - console.log(new Date().toISOString() + " " + pad(bot.codeName, 20) + " " + pad(bot.devTeam, 20) + " " + pad(bot.process, 30) - + " " + bot.startMode + " Entered into Main Loop # " + pad(Number(bot.loopCounter), 8) + " bot.processDatetime = " + bot.processDatetime.toISOString()); - - /* We will prepare first the infraestructure needed for the bot to run. There are 3 modules we need to sucessfullly initialize first. */ - - let exchangeAPI; - let assistant; - let userBot; - let statusDependencies; - let dataDependencies; - - initializeStatusDependencies(); - - function initializeStatusDependencies() { - - try { - - if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] run -> loop -> initializeStatusDependencies -> Entering function."); } - - statusDependencies = STATUS_DEPENDENCIES.newStatusDependencies(bot, logger, STATUS_REPORT, UTILITIES); - - statusDependencies.initialize(processConfig.statusDependencies, undefined, undefined, onInizialized); - - function onInizialized(err) { - - try { - - if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] run -> loop -> initializeStatusDependencies -> onInizialized -> Entering function."); } - - switch (err.result) { - case global.DEFAULT_OK_RESPONSE.result: { - if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] run -> loop -> initializeStatusDependencies -> onInizialized -> Execution finished well."); } - initializeDataDependencies(); - return; - } - case global.DEFAULT_RETRY_RESPONSE.result: { // Something bad happened, but if we retry in a while it might go through the next time. - logger.write(MODULE_NAME, "[ERROR] run -> loop -> initializeStatusDependencies -> onInizialized -> Retry Later. Requesting Execution Retry."); - nextWaitTime = 'Retry'; - loopControl(nextWaitTime); - return; - } - case global.DEFAULT_FAIL_RESPONSE.result: { // This is an unexpected exception that we do not know how to handle. - logger.write(MODULE_NAME, "[ERROR] run -> loop -> initializeStatusDependencies -> onInizialized -> Operation Failed. Aborting the process."); - logger.persist(); - clearInterval(fixedTimeLoopIntervalHandle); - clearTimeout(nextLoopTimeoutHandle); - clearTimeout(checkLoopHealthHandle); - bot.enableCheckLoopHealth = false; - callBackFunction(err); - return; - } - default: { - logger.write(MODULE_NAME, "[ERROR] run -> loop -> initializeStatusDependencies -> onInizialized -> Unhandled err.result received. -> err.result = " + err.result); - logger.write(MODULE_NAME, "[ERROR] run -> loop -> initializeStatusDependencies -> onInizialized -> Unhandled err.result received. -> err.message = " + err.message); - - logger.persist(); - clearInterval(fixedTimeLoopIntervalHandle); - clearTimeout(nextLoopTimeoutHandle); - clearTimeout(checkLoopHealthHandle); - bot.enableCheckLoopHealth = false; - callBackFunction(global.DEFAULT_FAIL_RESPONSE); - return; - } - } - - } catch (err) { - logger.write(MODULE_NAME, "[ERROR] run -> loop -> initializeStatusDependencies -> onInizialized -> err = "+ err.stack); - logger.persist(); - clearInterval(fixedTimeLoopIntervalHandle); - clearTimeout(nextLoopTimeoutHandle); - clearTimeout(checkLoopHealthHandle); - bot.enableCheckLoopHealth = false; - callBackFunction(err); - } - } - - } catch (err) { - logger.write(MODULE_NAME, "[ERROR] run -> loop -> initializeStatusDependencies -> err = "+ err.stack); - logger.persist(); - clearInterval(fixedTimeLoopIntervalHandle); - clearTimeout(nextLoopTimeoutHandle); - clearTimeout(checkLoopHealthHandle); - bot.enableCheckLoopHealth = false; - callBackFunction(err); - } - } - - function initializeDataDependencies() { - - try { - - if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] run -> loop -> initializeDataDependencies -> Entering function."); } - - dataDependencies = DATA_DEPENDENCIES.newDataDependencies(bot, logger, DATA_SET); - - dataDependencies.initialize(processConfig.dataDependencies, onInizialized); - - function onInizialized(err) { - - try { - - if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] run -> loop -> initializeDataDependencies -> onInizialized -> Entering function."); } - - switch (err.result) { - case global.DEFAULT_OK_RESPONSE.result: { - if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] run -> loop -> initializeDataDependencies -> onInizialized -> Execution finished well."); } - initializeContext(); - return; - } - case global.DEFAULT_RETRY_RESPONSE.result: { // Something bad happened, but if we retry in a while it might go through the next time. - logger.write(MODULE_NAME, "[ERROR] run -> loop -> initializeDataDependencies -> onInizialized -> Retry Later. Requesting Execution Retry."); - nextWaitTime = 'Retry'; - loopControl(nextWaitTime); - return; - } - case global.DEFAULT_FAIL_RESPONSE.result: { // This is an unexpected exception that we do not know how to handle. - logger.write(MODULE_NAME, "[ERROR] run -> loop -> initializeDataDependencies -> onInizialized -> Operation Failed. Aborting the process."); - logger.persist(); - clearInterval(fixedTimeLoopIntervalHandle); - clearTimeout(nextLoopTimeoutHandle); - clearTimeout(checkLoopHealthHandle); - bot.enableCheckLoopHealth = false; - callBackFunction(err); - return; - } - default: { - logger.write(MODULE_NAME, "[ERROR] run -> loop -> initializeDataDependencies -> onInizialized -> Unhandled err.result received. -> err.result = " + err.result); - logger.write(MODULE_NAME, "[ERROR] run -> loop -> initializeDataDependencies -> onInizialized -> Unhandled err.result received. -> err.message = " + err.message); - - logger.persist(); - clearInterval(fixedTimeLoopIntervalHandle); - clearTimeout(nextLoopTimeoutHandle); - clearTimeout(checkLoopHealthHandle); - bot.enableCheckLoopHealth = false; - callBackFunction(global.DEFAULT_FAIL_RESPONSE); - return; - } - } - - } catch (err) { - logger.write(MODULE_NAME, "[ERROR] run -> loop -> initializeDataDependencies -> onInizialized -> err = "+ err.stack); - logger.persist(); - clearInterval(fixedTimeLoopIntervalHandle); - clearTimeout(nextLoopTimeoutHandle); - clearTimeout(checkLoopHealthHandle); - bot.enableCheckLoopHealth = false; - callBackFunction(err); - } - } - - } catch (err) { - logger.write(MODULE_NAME, "[ERROR] run -> loop -> initializeDataDependencies -> err = "+ err.stack); - logger.persist(); - clearInterval(fixedTimeLoopIntervalHandle); - clearTimeout(nextLoopTimeoutHandle); - clearTimeout(checkLoopHealthHandle); - bot.enableCheckLoopHealth = false; - callBackFunction(err); - } - } - - function initializeContext() { - - try { - - if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] run -> loop -> initializeContext -> Entering function."); } - - context = CONTEXT.newContext(bot, logger, UTILITIES); - context.initialize(statusDependencies, onInizialized); - - function onInizialized(err) { - - try { - - if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] run -> loop -> initializeContext -> onInizialized -> Entering function."); } - - switch (err.result) { - case global.DEFAULT_OK_RESPONSE.result: { - if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] run -> loop -> initializeContext -> onInizialized -> Execution finished well."); } - initializeExchangeAPI(); - return; - } - case global.DEFAULT_RETRY_RESPONSE.result: { // Something bad happened, but if we retry in a while it might go through the next time. - logger.write(MODULE_NAME, "[ERROR] run -> loop -> initializeContext -> onInizialized -> Retry Later. Requesting Execution Retry."); - nextWaitTime = 'Retry'; - loopControl(nextWaitTime); - return; - } - case global.DEFAULT_FAIL_RESPONSE.result: { // This is an unexpected exception that we do not know how to handle. - logger.write(MODULE_NAME, "[ERROR] run -> loop -> initializeContext -> onInizialized -> Operation Failed. Aborting the process."); - logger.persist(); - clearInterval(fixedTimeLoopIntervalHandle); - clearTimeout(nextLoopTimeoutHandle); - clearTimeout(checkLoopHealthHandle); - bot.enableCheckLoopHealth = false; - callBackFunction(err); - return; - } - default: { - logger.write(MODULE_NAME, "[ERROR] run -> loop -> initializeContext -> onInizialized -> Unhandled err.result received. -> err.result = " + err.result); - logger.write(MODULE_NAME, "[ERROR] run -> loop -> initializeContext -> onInizialized -> Unhandled err.result received. -> err.message = " + err.message); - - logger.persist(); - clearInterval(fixedTimeLoopIntervalHandle); - clearTimeout(nextLoopTimeoutHandle); - clearTimeout(checkLoopHealthHandle); - bot.enableCheckLoopHealth = false; - callBackFunction(global.DEFAULT_FAIL_RESPONSE); - return; - } - } - - } catch (err) { - logger.write(MODULE_NAME, "[ERROR] run -> loop -> initializeContext -> onInizialized -> err = "+ err.stack); - logger.persist(); - clearInterval(fixedTimeLoopIntervalHandle); - clearTimeout(nextLoopTimeoutHandle); - clearTimeout(checkLoopHealthHandle); - bot.enableCheckLoopHealth = false; - callBackFunction(err); - } - } - - } catch (err) { - logger.write(MODULE_NAME, "[ERROR] run -> loop -> initializeContext -> err = "+ err.stack); - logger.persist(); - clearInterval(fixedTimeLoopIntervalHandle); - clearTimeout(nextLoopTimeoutHandle); - clearTimeout(checkLoopHealthHandle); - bot.enableCheckLoopHealth = false; - callBackFunction(err); - } - } - - function initializeExchangeAPI() { - - try { - - if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] run -> loop -> initializeExchangeAPI -> Entering function."); } - - exchangeAPI = EXCHANGE_API.newExchangeAPI(logger, global.EXCHANGE_NAME); - - exchangeAPI.initialize(onInizialized); - - function onInizialized(err) { - - try { - - if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] run -> loop -> initializeContext -> onInizialized -> onInizialized -> Entering function."); } - - switch (err.result) { - case global.DEFAULT_OK_RESPONSE.result: { - if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] run -> loop -> initializeExchangeAPI -> onInizialized -> Execution finished well."); } - initializeAssistant(); - return; - } - case global.DEFAULT_RETRY_RESPONSE.result: { // Something bad happened, but if we retry in a while it might go through the next time. - logger.write(MODULE_NAME, "[ERROR] run -> loop -> initializeExchangeAPI -> onInizialized -> Retry Later. Requesting Execution Retry."); - nextWaitTime = 'Retry'; - loopControl(nextWaitTime); - return; - } - case global.DEFAULT_FAIL_RESPONSE.result: { // This is an unexpected exception that we do not know how to handle. - logger.write(MODULE_NAME, "[ERROR] run -> loop -> initializeExchangeAPI -> onInizialized -> Operation Failed. Aborting the process."); - logger.persist(); - clearInterval(fixedTimeLoopIntervalHandle); - clearTimeout(nextLoopTimeoutHandle); - clearTimeout(checkLoopHealthHandle); - bot.enableCheckLoopHealth = false; - callBackFunction(err); - return; - } - default: { - logger.write(MODULE_NAME, "[ERROR] run -> loop -> initializeExchangeAPI -> onInizialized -> Unhandled err.result received. -> err.result = " + err.result); - logger.write(MODULE_NAME, "[ERROR] run -> loop -> initializeExchangeAPI -> onInizialized -> Unhandled err.result received. -> err.message = " + err.message); - - logger.persist(); - clearInterval(fixedTimeLoopIntervalHandle); - clearTimeout(nextLoopTimeoutHandle); - clearTimeout(checkLoopHealthHandle); - bot.enableCheckLoopHealth = false; - callBackFunction(global.DEFAULT_FAIL_RESPONSE); - return; - } - } - - } catch (err) { - logger.write(MODULE_NAME, "[ERROR] run -> loop -> initializeContext -> onInizialized -> onInizialized -> err = "+ err.stack); - logger.persist(); - clearInterval(fixedTimeLoopIntervalHandle); - clearTimeout(nextLoopTimeoutHandle); - clearTimeout(checkLoopHealthHandle); - bot.enableCheckLoopHealth = false; - callBackFunction(err); - } - } - - } catch (err) { - logger.write(MODULE_NAME, "[ERROR] run -> loop -> initializeExchangeAPI -> err = "+ err.stack); - logger.persist(); - clearInterval(fixedTimeLoopIntervalHandle); - clearTimeout(nextLoopTimeoutHandle); - clearTimeout(checkLoopHealthHandle); - bot.enableCheckLoopHealth = false; - callBackFunction(err); - } - } - - function initializeAssistant() { - - try { - - if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] run -> loop -> initializeAssistant -> Entering function."); } - - assistant = ASSISTANT.newAssistant(bot, logger, UTILITIES); - assistant.initialize(context, exchangeAPI, dataDependencies, onInizialized); - - function onInizialized(err) { - - try { - - if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] run -> loop -> initializeAssistant -> onInizialized -> Entering function."); } - - switch (err.result) { - case global.DEFAULT_OK_RESPONSE.result: { - if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] run -> loop -> initializeAssistant -> onInizialized -> Execution finished well."); } - initializeUserBot(); - return; - } - case global.DEFAULT_RETRY_RESPONSE.result: { // Something bad happened, but if we retry in a while it might go through the next time. - logger.write(MODULE_NAME, "[ERROR] run -> loop -> initializeAssistant -> onInizialized -> Retry Later. Requesting Execution Retry."); - nextWaitTime = 'Retry'; - loopControl(nextWaitTime); - return; - } - case global.DEFAULT_FAIL_RESPONSE.result: { // This is an unexpected exception that we do not know how to handle. - logger.write(MODULE_NAME, "[ERROR] run -> loop -> initializeAssistant -> onInizialized -> Operation Failed. Aborting the process."); - logger.persist(); - clearInterval(fixedTimeLoopIntervalHandle); - clearTimeout(nextLoopTimeoutHandle); - clearTimeout(checkLoopHealthHandle); - bot.enableCheckLoopHealth = false; - callBackFunction(err); - return; - } - default: { - logger.write(MODULE_NAME, "[ERROR] run -> loop -> initializeAssistant -> onInizialized -> Unhandled err.result received. -> err.result = " + err.result); - logger.write(MODULE_NAME, "[ERROR] run -> loop -> initializeAssistant -> onInizialized -> Unhandled err.result received. -> err.message = " + err.message); - - logger.persist(); - clearInterval(fixedTimeLoopIntervalHandle); - clearTimeout(nextLoopTimeoutHandle); - clearTimeout(checkLoopHealthHandle); - bot.enableCheckLoopHealth = false; - callBackFunction(global.DEFAULT_FAIL_RESPONSE); - return; - } - } - - } catch (err) { - logger.write(MODULE_NAME, "[ERROR] run -> loop -> initializeAssistant -> onInizialized -> err = "+ err.stack); - logger.persist(); - clearInterval(fixedTimeLoopIntervalHandle); - clearTimeout(nextLoopTimeoutHandle); - clearTimeout(checkLoopHealthHandle); - bot.enableCheckLoopHealth = false; - callBackFunction(err); - } - } - - } catch (err) { - logger.write(MODULE_NAME, "[ERROR] run -> loop -> initializeAssistant -> err = "+ err.stack); - logger.persist(); - clearInterval(fixedTimeLoopIntervalHandle); - clearTimeout(nextLoopTimeoutHandle); - clearTimeout(checkLoopHealthHandle); - bot.enableCheckLoopHealth = false; - callBackFunction(err); - } - } - - function initializeUserBot() { - - try { - - if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] run -> loop -> initializeUserBot -> Entering function."); } - - usertBot = USER_BOT_MODULE.newUserBot(bot, logger, COMMONS_MODULE); - - usertBot.initialize(assistant, pGenes, onInizialized); - - function onInizialized(err) { - - try { - - if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] run -> loop -> initializeUserBot -> onInizialized -> Entering function."); } - - switch (err.result) { - case global.DEFAULT_OK_RESPONSE.result: { - if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] run -> loop -> initializeUserBot -> onInizialized -> Execution finished well."); } - startUserBot(); - return; - } - case global.DEFAULT_RETRY_RESPONSE.result: { // Something bad happened, but if we retry in a while it might go through the next time. - logger.write(MODULE_NAME, "[ERROR] run -> loop -> initializeUserBot -> onInizialized -> Retry Later. Requesting Execution Retry."); - nextWaitTime = 'Retry'; - loopControl(nextWaitTime); - return; - } - case global.DEFAULT_FAIL_RESPONSE.result: { // This is an unexpected exception that we do not know how to handle. - logger.write(MODULE_NAME, "[ERROR] run -> loop -> initializeUserBot -> onInizialized -> Operation Failed. Aborting the process."); - logger.persist(); - clearInterval(fixedTimeLoopIntervalHandle); - clearTimeout(nextLoopTimeoutHandle); - clearTimeout(checkLoopHealthHandle); - bot.enableCheckLoopHealth = false; - callBackFunction(err); - return; - } - default: { - logger.write(MODULE_NAME, "[ERROR] run -> loop -> initializeUserBot -> onInizialized -> Unhandled err.result received. -> err.result = " + err.result); - logger.write(MODULE_NAME, "[ERROR] run -> loop -> initializeUserBot -> onInizialized -> Unhandled err.result received. -> err.message = " + err.message); - - logger.persist(); - clearInterval(fixedTimeLoopIntervalHandle); - clearTimeout(nextLoopTimeoutHandle); - clearTimeout(checkLoopHealthHandle); - bot.enableCheckLoopHealth = false; - callBackFunction(global.DEFAULT_FAIL_RESPONSE); - return; - } - } - - } catch (err) { - logger.write(MODULE_NAME, "[ERROR] run -> loop -> initializeUserBot -> onInizialized -> err = "+ err.stack); - logger.persist(); - clearInterval(fixedTimeLoopIntervalHandle); - clearTimeout(nextLoopTimeoutHandle); - clearTimeout(checkLoopHealthHandle); - bot.enableCheckLoopHealth = false; - callBackFunction(err); - } - } - - } catch (err) { - logger.write(MODULE_NAME, "[ERROR] run -> loop -> initializeUserBot -> err = "+ err.stack); - logger.persist(); - clearInterval(fixedTimeLoopIntervalHandle); - clearTimeout(nextLoopTimeoutHandle); - clearTimeout(checkLoopHealthHandle); - bot.enableCheckLoopHealth = false; - callBackFunction(err); - } - } - - function startUserBot() { - - try { - - if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] run -> loop -> startUserBot -> Entering function."); } - - usertBot.start(onFinished); - - function onFinished(err) { - - try { - - if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] run -> loop -> startUserBot -> onFinished -> Entering function."); } - - switch (err.result) { - case global.DEFAULT_OK_RESPONSE.result: { - if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] run -> loop -> startUserBot -> onFinished -> Execution finished well."); } - saveContext(); - return; - } - case global.DEFAULT_RETRY_RESPONSE.result: { // Something bad happened, but if we retry in a while it might go through the next time. - logger.write(MODULE_NAME, "[ERROR] run -> loop -> startUserBot -> onFinished -> Retry Later. Requesting Execution Retry."); - nextWaitTime = 'Retry'; - loopControl(nextWaitTime); - return; - } - case global.DEFAULT_FAIL_RESPONSE.result: { // This is an unexpected exception that we do not know how to handle. - logger.write(MODULE_NAME, "[ERROR] run -> loop -> startUserBot -> onFinished -> Operation Failed. Aborting the process."); - logger.persist(); - clearInterval(fixedTimeLoopIntervalHandle); - clearTimeout(nextLoopTimeoutHandle); - clearTimeout(checkLoopHealthHandle); - bot.enableCheckLoopHealth = false; - callBackFunction(err); - return; - } - default: { - logger.write(MODULE_NAME, "[ERROR] run -> loop -> startUserBot -> onFinished -> Unhandled err.result received. -> err.result = " + err.result); - logger.write(MODULE_NAME, "[ERROR] run -> loop -> startUserBot -> onFinished -> Unhandled err.result received. -> err.message = " + err.message); - - logger.persist(); - clearInterval(fixedTimeLoopIntervalHandle); - clearTimeout(nextLoopTimeoutHandle); - clearTimeout(checkLoopHealthHandle); - bot.enableCheckLoopHealth = false; - callBackFunction(global.DEFAULT_FAIL_RESPONSE); - return; - } - } - - } catch (err) { - logger.write(MODULE_NAME, "[ERROR] run -> loop -> startUserBot -> onFinished -> err = "+ err.stack); - logger.persist(); - clearInterval(fixedTimeLoopIntervalHandle); - clearTimeout(nextLoopTimeoutHandle); - clearTimeout(checkLoopHealthHandle); - bot.enableCheckLoopHealth = false; - callBackFunction(err); - } - } - - } catch (err) { - logger.write(MODULE_NAME, "[ERROR] run -> loop -> startUserBot -> err = "+ err.stack); - logger.persist(); - clearInterval(fixedTimeLoopIntervalHandle); - clearTimeout(nextLoopTimeoutHandle); - clearTimeout(checkLoopHealthHandle); - bot.enableCheckLoopHealth = false; - callBackFunction(err); - } - } - - function saveContext() { - - try { - - if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] run -> loop -> saveContext -> Entering function."); } - - context.saveThemAll(onFinished); - - function onFinished(err) { - - try { - - if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] run -> loop -> saveContext -> onFinished -> Entering function."); } - - switch (err.result) { - case global.DEFAULT_OK_RESPONSE.result: { - if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] run -> loop -> saveContext -> onFinished -> Execution finished well."); } - nextWaitTime = 'Normal'; - updateClonesModule(); - return; - } - case global.DEFAULT_RETRY_RESPONSE.result: { // Something bad happened, but if we retry in a while it might go through the next time. - logger.write(MODULE_NAME, "[ERROR] run -> loop -> saveContext -> onFinished -> Can not retry at this point."); - logger.persist(); - clearInterval(fixedTimeLoopIntervalHandle); - clearTimeout(nextLoopTimeoutHandle); - clearTimeout(checkLoopHealthHandle); - bot.enableCheckLoopHealth = false; - callBackFunction(global.DEFAULT_FAIL_RESPONSE); - return; - } - case global.DEFAULT_FAIL_RESPONSE.result: { // This is an unexpected exception that we do not know how to handle. - logger.write(MODULE_NAME, "[ERROR] run -> loop -> saveContext -> onFinished -> Operation Failed. Aborting the process."); - logger.persist(); - clearInterval(fixedTimeLoopIntervalHandle); - clearTimeout(nextLoopTimeoutHandle); - clearTimeout(checkLoopHealthHandle); - bot.enableCheckLoopHealth = false; - callBackFunction(err); - return; - } - default: { - logger.write(MODULE_NAME, "[ERROR] run -> loop -> saveContext -> onFinished -> Unhandled err.result received. -> err.result = " + err.result); - logger.write(MODULE_NAME, "[ERROR] run -> loop -> saveContext -> onFinished -> Unhandled err.result received. -> err.message = " + err.message); - - logger.persist(); - clearInterval(fixedTimeLoopIntervalHandle); - clearTimeout(nextLoopTimeoutHandle); - clearTimeout(checkLoopHealthHandle); - bot.enableCheckLoopHealth = false; - callBackFunction(global.DEFAULT_FAIL_RESPONSE); - return; - } - } - - } catch (err) { - logger.write(MODULE_NAME, "[ERROR] run -> loop -> saveContext -> onFinished -> err = "+ err.stack); - logger.persist(); - clearInterval(fixedTimeLoopIntervalHandle); - clearTimeout(nextLoopTimeoutHandle); - clearTimeout(checkLoopHealthHandle); - bot.enableCheckLoopHealth = false; - callBackFunction(err); - } - } - - } catch (err) { - logger.write(MODULE_NAME, "[ERROR] run -> loop -> saveContext -> err = "+ err.stack); - logger.persist(); - clearInterval(fixedTimeLoopIntervalHandle); - clearTimeout(nextLoopTimeoutHandle); - clearTimeout(checkLoopHealthHandle); - bot.enableCheckLoopHealth = false; - callBackFunction(err); - } - } - - async function updateClonesModule() { - - try { - - if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] run -> loop -> updateClonesModule -> Entering function."); } - - nextWaitTime = 'Normal'; - loopControl(nextWaitTime); - - } catch (err) { - logger.write(MODULE_NAME, "[ERROR] run -> loop -> updateClonesModule -> err = "+ err.stack); - logger.write(MODULE_NAME, "[ERROR] run -> loop -> updateClonesModule -> Execution will continue anyways. "); - nextWaitTime = 'Normal'; - loopControl(nextWaitTime); - } - } - - function loopControl(nextWaitTime) { - - if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] run -> loop -> loopControl -> Entering function."); } - if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] run -> loop -> loopControl -> nextWaitTime = " + nextWaitTime); } - - /* Here we check if we must stop the loop gracefully. */ - - shallWeStop(onStop, onContinue); - - function onStop() { - - if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] run -> loop -> loopControl -> onStop -> Entering function."); } - - if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] run -> loop -> loopControl -> onStop -> Stopping the Loop Gracefully. See you next time!"); } - - if (global.FULL_LOG === 'true' || bot.startMode === 'Competition') { - logger.persist(); - } - - clearInterval(fixedTimeLoopIntervalHandle); - clearTimeout(nextLoopTimeoutHandle); - clearTimeout(checkLoopHealthHandle); - bot.enableCheckLoopHealth = false; - callBackFunction(global.DEFAULT_OK_RESPONSE); - return; - - } - - function onContinue() { - - if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] run -> loop -> loopControl -> onContinue -> Entering function."); } - - /* 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) { - case 'Normal': { - if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] run -> loop -> loopControl -> Normal -> Restarting Loop in " + (processConfig.normalWaitTime / 1000) + " seconds."); } - checkLoopHealthHandle = setTimeout(checkLoopHealth, processConfig.normalWaitTime * 5, bot.loopCounter); - nextLoopTimeoutHandle = setTimeout(loop, processConfig.normalWaitTime); - if (global.FULL_LOG === 'true' || bot.startMode === 'Competition') { - logger.persist(); - } - } - break; - case 'Retry': { - if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] run -> loop -> loopControl -> Retry -> Restarting Loop in " + (processConfig.retryWaitTime / 1000) + " seconds."); } - checkLoopHealthHandle = setTimeout(checkLoopHealth, processConfig.retryWaitTime * 5, bot.loopCounter); - nextLoopTimeoutHandle = setTimeout(loop, processConfig.retryWaitTime); - logger.persist(); - } - break; - case 'Sleep': { - if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] run -> loop -> loopControl -> Sleep -> Restarting Loop in " + (processConfig.sleepWaitTime / 60000) + " minutes."); } - nextLoopTimeoutHandle = setTimeout(loop, processConfig.sleepWaitTime); - logger.persist(); - } - break; - case 'Coma': { - if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] run -> loop -> loopControl -> Coma -> Restarting Loop in " + (processConfig.comaWaitTime / 3600000) + " hours."); } - nextLoopTimeoutHandle = setTimeout(loop, processConfig.comaWaitTime); - logger.persist(); - } - break; - } - } - } - - function checkLoopHealth(pLastLoop) { - - if (bot.startMode === 'Backtest') { return; } - - if (bot.enableCheckLoopHealth === false) { - - logger.write(MODULE_NAME, "[WARN] run -> loop -> checkLoopHealth -> bot.enableCheckLoopHealth = " + bot.enableCheckLoopHealth); - - return; - } // This gets disabled anytime the Main Loop is shut down by any condition. - - if (bot.loopCounter <= pLastLoop + 1) { // This means that the next loop started but also stopped executing abruptally. - - let now = new Date().valueOf(); - - if (now - bot.loopStartTime > processConfig.normalWaitTime) { - - logger.write(MODULE_NAME, "[ERROR] run -> loop -> checkLoopHealth -> Dead loop found -> pLastLoop = " + pLastLoop); - console.log((new Date().toISOString() + " [ERROR] run -> loop -> checkLoopHealth -> " + pad(bot.codeName, 20) + " " + pad(bot.instance, 20) + " " + pad(bot.process, 30) + " Loop # " + pad(Number(bot.loopCounter), 5) + " found dead. Resurrecting it now.")); - - logger.persist(); // We persist the logs of the failed execution. - clearTimeout(nextLoopTimeoutHandle); // We cancel the timeout in case the original loop was still running and schedulled to reexecute. - loop(); // We restart the loop so that the processing can continue. - - } else { - - console.log((new Date().toISOString() + " [WARN] run -> loop -> checkLoopHealth -> " + pad(bot.codeName, 20) + " " + pad(bot.instance, 20) + " " + pad(bot.process, 30) + " Loop # " + pad(Number(bot.loopCounter), 5) + " found delayed but still alive. No action taken.")); - - } - } - } - - function shallWeStop(stopCallBack, continueCallBack) { - - try { - - /* IMPORTANT: This function is exactly the same on the 3 modules. */ - - if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] run -> loop -> shallWeStop -> Entering function. "); } - - let stop = false - if (process.env.STOP_GRACEFULLY !== undefined) - stop = JSON.parse(process.env.STOP_GRACEFULLY) - - if (!stop && global.SHALL_BOT_STOP === false) { - continueCallBack(); - } else { - stopCallBack(); - } - } catch (err) { - logger.write(MODULE_NAME, "[ERROR] run -> loop -> shallWeStop -> err.message = " + err.message); - logger.persist(); - clearInterval(fixedTimeLoopIntervalHandle); - clearTimeout(nextLoopTimeoutHandle); - clearTimeout(checkLoopHealthHandle); - bot.enableCheckLoopHealth = false; - callBackFunction(global.DEFAULT_FAIL_RESPONSE); - return; - } - } - - } catch (err) { - parentLogger.write(MODULE_NAME, "[ERROR] run -> loop -> err = " + err.stack); - clearInterval(fixedTimeLoopIntervalHandle); - clearTimeout(nextLoopTimeoutHandle); - clearTimeout(checkLoopHealthHandle); - bot.enableCheckLoopHealth = false; - callBackFunction(err); - } - } - - } - - catch (err) { - parentLogger.write(MODULE_NAME, "[ERROR] run -> err = "+ err.stack); - clearInterval(fixedTimeLoopIntervalHandle); - clearTimeout(nextLoopTimeoutHandle); - clearTimeout(checkLoopHealthHandle); - bot.enableCheckLoopHealth = false; - callBackFunction(global.DEFAULT_FAIL_RESPONSE); - } - } -}; diff --git a/TradingEngineProcessMainLoop.js b/TradingEngineProcessMainLoop.js index a8df4efef..50021a60c 100644 --- a/TradingEngineProcessMainLoop.js +++ b/TradingEngineProcessMainLoop.js @@ -887,7 +887,7 @@ if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] run -> loop -> loopControl -> onStop -> Stopping the Loop Gracefully. See you next time!"); } - if (global.FULL_LOG === 'true') { + if (global.WRITE_LOGS_TO_FILES === 'true') { logger.persist(); } @@ -907,7 +907,7 @@ if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] run -> loop -> loopControl -> Restarting Loop in " + (processConfig.normalWaitTime / 1000) + " seconds."); } checkLoopHealthHandle = setTimeout(checkLoopHealth, processConfig.normalWaitTime * 5, bot.loopCounter); nextLoopTimeoutHandle = setTimeout(loop, processConfig.normalWaitTime); - if (global.FULL_LOG === 'true') { + if (global.WRITE_LOGS_TO_FILES === 'true') { logger.persist(); } } @@ -948,7 +948,7 @@ let now = new Date().valueOf(); - if (now - bot.loopStartTime > processConfig.normalWaitTime) { + if (now - bot.loopStartTime > processConfig.deadWaitTime) { logger.write(MODULE_NAME, "[ERROR] run -> loop -> checkLoopHealth -> Dead loop found -> pLastLoop = " + pLastLoop); console.log((new Date().toISOString() + " [ERROR] run -> loop -> checkLoopHealth -> " + pad(bot.codeName, 20) + " " + pad(bot.process, 30) + " Loop # " + pad(Number(bot.loopCounter), 5) + " found dead. Resurrecting it now.")); @@ -977,7 +977,7 @@ if (process.env.STOP_GRACEFULLY !== undefined) stop = JSON.parse(process.env.STOP_GRACEFULLY) - if (!stop && global.SHALL_BOT_STOP === false) { + if (!stop) { continueCallBack(); } else { stopCallBack(); @@ -1005,7 +1005,7 @@ } function hearBeat() { - let key = global.USER_DEFINITION.bot.processes[global.sequenceStep - 1].name + '-' + global.USER_DEFINITION.bot.processes[global.sequenceStep - 1].type + '-' + global.USER_DEFINITION.bot.processes[global.sequenceStep - 1].id + let key = global.USER_DEFINITION.bot.processes[bot.processIndex].name + '-' + global.USER_DEFINITION.bot.processes[bot.processIndex].type + '-' + global.USER_DEFINITION.bot.processes[bot.processIndex].id let event = { seconds: (new Date()).getSeconds() diff --git a/server.js b/server.js index 3e7984bc6..65deed103 100644 --- a/server.js +++ b/server.js @@ -66,7 +66,7 @@ if (global.USER_DEFINITION !== undefined) { } else { // I use this section to debug in standalone mode. - let argument = '{"type":"Task","name":"Extract Trades from Poloniex","bot":{"type":"Sensor","name":"Charly","processes":[{"type":"Process","name":"Live-Trades","code":{"devTeam":"AAMasters","bot":"AACharly","mode":"noTime","resumeExecution":true,"type":"Sensor","exchangeName":"Poloniex","process":"Live-Trades"}},{"type":"Process","name":"Hole-Fixing","code":{"devTeam":"AAMasters","bot":"AACharly","mode":"oneMonth","resumeExecution":true,"type":"Sensor","exchangeName":"Poloniex","process":"Hole-Fixing","startYear":2019,"endYear":2019,"month":9}}]}}' + let argument = '{"type":"Task","name":"Brings Trades Records from the Exchange","bot":{"type":"Sensor","name":"Charly","processes":[{"type":"Process","name":"Live Trades","code":{"devTeam":"AAMasters","bot":"AACharly","mode":"noTime","resumeExecution":true,"type":"Sensor","exchangeName":"Poloniex","process":"Live-Trades"},"id":"3aae75f5-67ae-4ae5-9586-ec5640f79b18"}]},"id":"54444b07-eee2-4fa8-9183-8fea3b5ff9de"}' try { global.USER_DEFINITION = JSON.parse(argument) } catch (err) { @@ -75,11 +75,35 @@ else { // I use this section to debug in standalone mode. } +require('dotenv').config(); + +global.DEFINITION = require(process.env.INTER_PROCESS_FILES_PATH + '/Definition'); +global.WRITE_LOGS_TO_FILES = process.env.WRITE_LOGS_TO_FILES + +/* Default parameters can be changed by the execution configuration */ +global.EXCHANGE_NAME = process.env.EXCHANGE_NAME +global.MARKET = { assetA: 'USDT', assetB: 'BTC' } +global.CLONE_EXECUTOR = { codeName: 'AACloud', version: '1.1' } +global.ENDED_PROCESSES_COUNTER = 0 + +/* Here we listen for the message to stop this Task / Process comming from the Task Manager, which is the paret of this node js process. */ +process.on('message', message => { + if (message === 'Stop this Task') { + + process.env.STOP_GRACEFULLY = true; + + } +}); + +let notFirstSequence = false; + +/* Setting up the global Event Handler */ + const EVENT_HANDLER_MODULE = require('../Libraries/SystemEventsClient/SystemEventHandler.js'); global.SYSTEM_EVENT_HANDLER = EVENT_HANDLER_MODULE.newSystemEventHandler() - global.SYSTEM_EVENT_HANDLER.initialize('Task Server', bootLoader) + function bootLoader() { //global.SYSTEM_EVENT_HANDLER.createEventHandler(global.USER_DEFINITION.name) @@ -89,7 +113,7 @@ function bootLoader() { function tryToListenToCockpit() { - global.SYSTEM_EVENT_HANDLER.listenToEvent('Cockpit-Restart-Simulation', 'Simulation Started', undefined, 'Clone Executor Boot Loader', onResponse, startSequence) + global.SYSTEM_EVENT_HANDLER.listenToEvent('Cockpit-Restart-Simulation', 'Simulation Started', undefined, 'Task Server Boot Loader', onResponse, startSequence) function onResponse(message) { if (message.result !== global.DEFAULT_OK_RESPONSE.result) { @@ -112,7 +136,7 @@ function bootLoader() { } /* Heartbeat sent to the UI */ - heartBeatInterval = setInterval(hearBeat, 1000) + global.HEARTBEAT_INTERVAL_HANDLER = setInterval(hearBeat, 1000) function hearBeat() { @@ -127,146 +151,58 @@ function bootLoader() { startSequence() } - /* Old Run.js code follows... */ -require('dotenv').config(); +function startSequence() { -global.DEFINITION = require(process.env.INTER_PROCESS_FILES_PATH + '/Definition'); -const definition = global.DEFINITION -const path = require('path'); + for (let processIndex = 0; processIndex < global.USER_DEFINITION.bot.processes.length; processIndex++) { + let execution = sequenceList[processIndex]; -global.SHALL_BOT_STOP = false + process.env.STOP_GRACEFULLY = false; + execution.devTeam ? process.env.DEV_TEAM = execution.devTeam : undefined; + execution.bot ? process.env.BOT = execution.bot : undefined; + execution.mode ? process.env.START_MODE = execution.mode : undefined; + execution.resumeExecution = true; + execution.type ? process.env.TYPE = execution.type : undefined; + execution.process ? process.env.PROCESS = execution.process : undefined; + execution.startYear ? process.env.MIN_YEAR = execution.startYear : undefined; + execution.endYear ? process.env.MAX_YEAR = execution.endYear : undefined; + execution.month ? process.env.MONTH = execution.month : undefined; + execution.beginDatetime ? process.env.BEGIN_DATE_TIME = execution.beginDatetime : undefined; + execution.endDatetime ? process.env.END_DATE_TIME = execution.endDatetime : undefined; + execution.dataSet ? process.env.DATA_SET = execution.dataSet : undefined; + execution.timePeriod ? process.env.TIME_PERIOD = execution.timePeriod : undefined; + execution.baseAsset ? process.env.BASE_ASSET = execution.baseAsset : undefined; + execution.balanceAssetA ? process.env.INITIAL_BALANCE_ASSET_A = execution.balanceAssetA : undefined; + execution.balanceAssetB ? process.env.INITIAL_BALANCE_ASSET_B = execution.balanceAssetB : undefined; + execution.type === 'Trading' ? process.env.CLONE_ID = 1 : undefined; -global.FULL_LOG = process.env.FULL_LOG + execution.exchangeName ? global.EXCHANGE_NAME = execution.exchangeName : undefined; -/* Default parameters can be changed by the execution configuration */ -global.EXCHANGE_NAME = process.env.EXCHANGE_NAME -global.MARKET = { assetA: 'USDT', assetB: 'BTC' } -global.CLONE_EXECUTOR = { codeName: 'AACloud', version: '1.1' } + if (global.DEFINITION) { + if (global.DEFINITION.personalData) { + if (global.DEFINITION.personalData.exchangeAccounts) { + if (global.DEFINITION.personalData.exchangeAccounts.length > 0) { + let exchangeAccount = global.DEFINITION.personalData.exchangeAccounts[0] + if (exchangeAccount.keys) { + if (exchangeAccount.keys.length > 0) { + let key = exchangeAccount.keys[0] + process.env.KEY = key.name + process.env.SECRET = key.code - - - -let isRunSequence = false; -global.sequenceStep = 0; -let processedSteps = new Map(); -let notFirstSequence = false; -let runClonExecutor = true; - -if (process.env.RUN_SEQUENCE !== undefined) { - isRunSequence = JSON.parse(process.env.RUN_SEQUENCE) -} - -function startSequence () { - if (isRunSequence) { - process.on('message', message => { - if (message === 'Stop this Task') { - runClonExecutor = false; - - /* Cleaning Before Exiting. */ - clearInterval(heartBeatInterval) - - for (let i = 0; i < global.USER_DEFINITION.bot.processes.length; i++) { - let code = global.USER_DEFINITION.bot.processes[i].code - - /* Delete the event handler for each process. */ - - let key = code.devTeam + "-" + code.codeName + "-" + code.process - let event = { - reason: 'Signal Received to Terminate this Process.' - } - global.SYSTEM_EVENT_HANDLER.raiseEvent(key, 'Process Terminated', event) - global.SYSTEM_EVENT_HANDLER.deleteEventHandler(key) - } - - global.SYSTEM_EVENT_HANDLER.finalize() - global.SYSTEM_EVENT_HANDLER = undefined - console.log("[INFO] CloneExecutor -> Clone Executor Stopped."); - } - }); - sequenceExecution(sequenceStep) - } else { - readExecutionConfiguration() - } -} - - -async function sequenceExecution(currentStep) { - - let execution = sequenceList[currentStep]; - - process.env.STOP_GRACEFULLY = true; - execution.devTeam ? process.env.DEV_TEAM = execution.devTeam : undefined; - execution.bot ? process.env.BOT = execution.bot : undefined; - execution.mode ? process.env.START_MODE = execution.mode : undefined; - execution.resumeExecution = true; - execution.type ? process.env.TYPE = execution.type : undefined; - execution.process ? process.env.PROCESS = execution.process : undefined; - execution.startYear ? process.env.MIN_YEAR = execution.startYear : undefined; - execution.endYear ? process.env.MAX_YEAR = execution.endYear : undefined; - execution.month ? process.env.MONTH = execution.month : undefined; - execution.beginDatetime ? process.env.BEGIN_DATE_TIME = execution.beginDatetime : undefined; - execution.endDatetime ? process.env.END_DATE_TIME = execution.endDatetime : undefined; - execution.dataSet ? process.env.DATA_SET = execution.dataSet : undefined; - execution.timePeriod ? process.env.TIME_PERIOD = execution.timePeriod : undefined; - execution.baseAsset ? process.env.BASE_ASSET = execution.baseAsset : undefined; - execution.balanceAssetA ? process.env.INITIAL_BALANCE_ASSET_A = execution.balanceAssetA : undefined; - execution.balanceAssetB ? process.env.INITIAL_BALANCE_ASSET_B = execution.balanceAssetB : undefined; - execution.type === 'Trading' ? process.env.CLONE_ID = 1 : undefined; - - execution.exchangeName ? global.EXCHANGE_NAME = execution.exchangeName : undefined; - - if (definition) { - if (definition.personalData) { - if (definition.personalData.exchangeAccounts) { - if (definition.personalData.exchangeAccounts.length > 0) { - let exchangeAccount = definition.personalData.exchangeAccounts[0] - if (exchangeAccount.keys) { - if (exchangeAccount.keys.length > 0) { - let key = exchangeAccount.keys[0] - - process.env.KEY = key.name - process.env.SECRET = key.code - + } } } } } } - } - let stepKey = execution.devTeam + '.' + execution.bot + '.' + execution.process; - if (processedSteps.has(stepKey)) { - processedSteps.set(stepKey, processedSteps.get(stepKey) + 1); - } else { - processedSteps.set(stepKey, 0); + readExecutionConfiguration(execution, processIndex); } - - readExecutionConfiguration(execution); - sequenceStep++; } -function onExecutionFinish(result, finishStepKey) { - if (global.sequenceStep < sequenceList.length && runClonExecutor) { - sequenceExecution(sequenceStep); - } else { - setTimeout(function () { - if (runClonExecutor) { - console.log("[INFO] onExecutionFinish -> New round for sequence execution started."); - - global.sequenceStep = 0; - processedSteps = new Map(); - notFirstSequence = true; - sequenceExecution(sequenceStep); - } - }, process.env.EXECUTION_LOOP_DELAY); - } - -} - -async function readExecutionConfiguration(execution) { +async function readExecutionConfiguration(execution, processIndex) { try { console.log("[INFO] Task Server -> server -> readExecutionConfiguration -> Entering function. "); @@ -291,31 +227,31 @@ async function readExecutionConfiguration(execution) { process.env.START_MODE = "live" // If we have keys, then we are in live mode. } - if (definition !== undefined) { - if (definition.simulationParams !== undefined) { - if (definition.simulationParams.beginDatetime !== undefined) { - initialDatetime = new Date(definition.simulationParams.beginDatetime) /* The first override occurs here, with the simulation parameters */ + if (global.DEFINITION !== undefined) { + if (global.DEFINITION.simulationParams !== undefined) { + if (global.DEFINITION.simulationParams.beginDatetime !== undefined) { + initialDatetime = new Date(global.DEFINITION.simulationParams.beginDatetime) /* The first override occurs here, with the simulation parameters */ } /* Here we only look for one timePeriod, in the future we will be able to process the whole array, but not for now. */ - if (definition.simulationParams.timePeriodDailyArray !== undefined) { - if (definition.simulationParams.timePeriodDailyArray.length === 1) { - timePeriodFilter = definition.simulationParams.timePeriodDailyArray[0] + if (global.DEFINITION.simulationParams.timePeriodDailyArray !== undefined) { + if (global.DEFINITION.simulationParams.timePeriodDailyArray.length === 1) { + timePeriodFilter = global.DEFINITION.simulationParams.timePeriodDailyArray[0] botProcess = "Multi-Period" } } - if (definition.simulationParams.timePeriodMarketArray !== undefined) { - if (definition.simulationParams.timePeriodMarketArray.length === 1) { - timePeriodFilter = definition.simulationParams.timePeriodMarketArray[0] + if (global.DEFINITION.simulationParams.timePeriodMarketArray !== undefined) { + if (global.DEFINITION.simulationParams.timePeriodMarketArray.length === 1) { + timePeriodFilter = global.DEFINITION.simulationParams.timePeriodMarketArray[0] botProcess = "Multi-Period" } } } - if (definition.tradingSystem !== undefined) { - if (definition.tradingSystem.parameters !== undefined) { - if (definition.tradingSystem.parameters.timeRange !== undefined) { - if (definition.tradingSystem.parameters.timeRange.code !== undefined) { + if (global.DEFINITION.tradingSystem !== undefined) { + if (global.DEFINITION.tradingSystem.parameters !== undefined) { + if (global.DEFINITION.tradingSystem.parameters.timeRange !== undefined) { + if (global.DEFINITION.tradingSystem.parameters.timeRange.code !== undefined) { try { - let code = JSON.parse(definition.tradingSystem.parameters.timeRange.code) + let code = JSON.parse(global.DEFINITION.tradingSystem.parameters.timeRange.code) if (code.initialDatetime !== undefined) { initialDatetime = code.initialDatetime /* The second override occurs here, with the date explicitelly defined by the user */ } @@ -323,14 +259,14 @@ async function readExecutionConfiguration(execution) { finalDatetime = code.finalDatetime } } catch (err) { - definition.tradingSystem.parameters.timeRange.error = err.message + global.DEFINITION.tradingSystem.parameters.timeRange.error = err.message } } } } } - /* Get the initial balance from the definition */ - let tradingSystem = definition.tradingSystem + /* Get the initial balance from the global.DEFINITION */ + let tradingSystem = global.DEFINITION.tradingSystem if (tradingSystem) { if (tradingSystem.parameters !== undefined) { @@ -359,7 +295,7 @@ async function readExecutionConfiguration(execution) { } } } catch (err) { - definition.tradingSystem.parameters.baseAsset.error = err.message + global.DEFINITION.tradingSystem.parameters.baseAsset.error = err.message process.env.INITIAL_BALANCE_ASSET_A = 0 // default process.env.INITIAL_BALANCE_ASSET_B = 0.001 // default @@ -381,7 +317,7 @@ async function readExecutionConfiguration(execution) { let live = { run: 'false', resumeExecution: execution.resumeExecution, - beginDatetime: new Date(definition.simulationParams.timestamp).toISOString(), + beginDatetime: new Date(global.DEFINITION.simulationParams.timestamp).toISOString(), endDatetime: finalDatetime } @@ -471,7 +407,7 @@ async function readExecutionConfiguration(execution) { version: '1.1' } - startRoot(); + startRoot(processIndex); } catch (err) { @@ -513,7 +449,7 @@ function getTimePeriod(timePeriod) { } } -function startRoot() { +function startRoot(processIndex) { console.log('[INFO] Task Server -> server -> startRoot -> Entering function. ') const ROOT_DIR = './' @@ -533,7 +469,7 @@ function startRoot() { function onInitialized() { console.log('[INFO] Task Server -> server -> startRoot -> onInitialized -> Entering function. ') - root.start(onExecutionFinish) + root.start(processIndex) } }