diff --git a/CloneExecutor.sln b/CloneExecutor.sln deleted file mode 100644 index a21837e88..000000000 --- a/CloneExecutor.sln +++ /dev/null @@ -1,25 +0,0 @@ - -Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio 15 -VisualStudioVersion = 15.0.27130.2027 -MinimumVisualStudioVersion = 10.0.40219.1 -Project("{9092AA53-FB77-4645-B42D-1CCCA6BD08BD}") = "Project", "Project.njsproj", "{AE0A3FE2-7021-4CC2-9922-A887CA5CDD7C}" -EndProject -Global - GlobalSection(SolutionConfigurationPlatforms) = preSolution - Debug|Any CPU = Debug|Any CPU - Release|Any CPU = Release|Any CPU - EndGlobalSection - GlobalSection(ProjectConfigurationPlatforms) = postSolution - {AE0A3FE2-7021-4CC2-9922-A887CA5CDD7C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {AE0A3FE2-7021-4CC2-9922-A887CA5CDD7C}.Debug|Any CPU.Build.0 = Debug|Any CPU - {AE0A3FE2-7021-4CC2-9922-A887CA5CDD7C}.Release|Any CPU.ActiveCfg = Release|Any CPU - {AE0A3FE2-7021-4CC2-9922-A887CA5CDD7C}.Release|Any CPU.Build.0 = Release|Any CPU - EndGlobalSection - GlobalSection(SolutionProperties) = preSolution - HideSolutionNode = FALSE - EndGlobalSection - GlobalSection(ExtensibilityGlobals) = postSolution - SolutionGuid = {9128DF06-8CA5-497C-8BF7-B924571C5394} - EndGlobalSection -EndGlobal diff --git a/Context.js b/Context.js index dfa757cba..c3e7a9b6a 100644 --- a/Context.js +++ b/Context.js @@ -165,7 +165,7 @@ let fileName = "Execution.History." + bot.startMode + "." + runIndex + ".json"; let filePath = bot.filePathRoot + "/Output/Trading-Process/" + fileName; - fileStorage.getTextFile(global.DEV_TEAM, filePath, onFileReceived); + fileStorage.getTextFile(bot.devTeam, filePath, onFileReceived); function onFileReceived(err, text) { @@ -226,7 +226,7 @@ let dateForPath = date.getUTCFullYear() + '/' + utilities.pad(date.getUTCMonth() + 1, 2) + '/' + utilities.pad(date.getUTCDate(), 2) + '/' + utilities.pad(date.getUTCHours(), 2) + '/' + utilities.pad(date.getUTCMinutes(), 2); let filePath = bot.filePathRoot + "/Output/Trading-Process/" + dateForPath + fileName; - fileStorage.getTextFile(global.DEV_TEAM, filePath, onFileReceived); + fileStorage.getTextFile(bot.devTeam, filePath, onFileReceived); function onFileReceived(err, text) { @@ -408,7 +408,7 @@ if (global.LOG_CONTROL[MODULE_NAME].logContent === true) { logger.write(MODULE_NAME, "[INFO] saveThemAll -> writeExecutionContext -> fileContent = " + fileContent); } - fileStorage.createTextFile(global.DEV_TEAM, filePath, fileContent + '\n', onFileCreated); + fileStorage.createTextFile(bot.devTeam, filePath, fileContent + '\n', onFileCreated); function onFileCreated(err) { @@ -469,7 +469,7 @@ let fileContent = JSON.stringify(thisObject.executionHistory); - fileStorage.createTextFile(global.DEV_TEAM, filePath, fileContent + '\n', onFileCreated); + fileStorage.createTextFile(bot.devTeam, filePath, fileContent + '\n', onFileCreated); function onFileCreated(err) { @@ -491,7 +491,7 @@ fileName = "Execution.History." + bot.startMode + "." + "Sequence" + ".json"; filePath = bot.filePathRoot + "/Output/Trading-Process/" + fileName; - fileStorage.createTextFile(global.DEV_TEAM, filePath, fileContent + '\n', onSequenceFileCreated); + fileStorage.createTextFile(bot.devTeam, filePath, fileContent + '\n', onSequenceFileCreated); function onSequenceFileCreated(err) { diff --git a/DebugLog.js b/DebugLog.js index 5112b0882..baa9fc203 100644 --- a/DebugLog.js +++ b/DebugLog.js @@ -89,7 +89,7 @@ exports.newDebugLog = function newDebugLog() { function writeLog() { - fileStorage.createTextFile(global.DEV_TEAM, filePath + '/' + fileName, contentToPersist + '\r\n' + "]", onFileCreated); + fileStorage.createTextFile(thisObject.bot.devTeam, filePath + '/' + fileName, contentToPersist + '\r\n' + "]", onFileCreated); function onFileCreated(err) { diff --git a/IndicatorBotProcessMainLoop.js b/IndicatorBotProcessMainLoop.js index a1bfe1ef8..30f83007b 100644 --- a/IndicatorBotProcessMainLoop.js +++ b/IndicatorBotProcessMainLoop.js @@ -25,30 +25,28 @@ }; let processConfig; - let UI_COMMANDS; return thisObject; - function initialize(pUI_COMMANDS, pProcessConfig, callBackFunction) { + function initialize(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 + let filePath = bot.devTeam + "/" + "bots" + "/" + bot.repo + "/" + pProcessConfig.name filePath += "/User.Bot.js" - fileStorage.getTextFile(global.DEV_TEAM, filePath, onBotDownloaded); + fileStorage.getTextFile(bot.devTeam, 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); + parentLogger.write(MODULE_NAME, "[ERROR] initialize -> onInizialized -> onBotDownloaded -> err = " + err.message); callBackFunction(global.DEFAULT_FAIL_RESPONSE); return; } @@ -56,10 +54,10 @@ USER_BOT_MODULE = {} USER_BOT_MODULE.newUserBot = eval(text); // TODO This needs to be changed function - filePath = global.DEV_TEAM + "/" + "bots" + "/" + bot.repo; + filePath = bot.devTeam + "/" + "bots" + "/" + bot.repo; filePath += "/Commons.js" - fileStorage.getTextFile(global.DEV_TEAM, filePath, onCommonsDownloaded); + fileStorage.getTextFile(bot.devTeam, filePath, onCommonsDownloaded); function onCommonsDownloaded(err, text) { @@ -192,7 +190,7 @@ } 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.write(MODULE_NAME, "[ERROR] run -> loop -> initializeStatusDependencies -> onInizialized -> Unhandled err.result received. -> err = " + err.message); logger.persist(); clearInterval(fixedTimeLoopIntervalHandle); @@ -295,7 +293,7 @@ } 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.write(MODULE_NAME, "[ERROR] run -> loop -> initializeDataDependencies -> onInizialized -> Unhandled err.result received. -> err = " + err.message); logger.persist(); clearInterval(fixedTimeLoopIntervalHandle); @@ -383,7 +381,7 @@ return; } default: { - logger.write(MODULE_NAME, "[ERROR] run -> loop -> initializeUserBot -> onInizialized > Unhandled custom response received. -> err.message = " + err.message); + logger.write(MODULE_NAME, "[ERROR] run -> loop -> initializeUserBot -> onInizialized > Unhandled custom response received. -> err = " + err.message); logger.persist(); clearInterval(fixedTimeLoopIntervalHandle); clearTimeout(nextLoopTimeoutHandle); @@ -396,7 +394,7 @@ } 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.write(MODULE_NAME, "[ERROR] run -> loop -> initializeUserBot -> onInizialized -> Unhandled err.result received. -> err = " + err.message); logger.persist(); clearInterval(fixedTimeLoopIntervalHandle); @@ -513,7 +511,7 @@ return; } default: { - logger.write(MODULE_NAME, "[ERROR] run -> loop -> startUserBot -> onFinished -> Unhandled custom response received. -> err.message = " + err.message); + logger.write(MODULE_NAME, "[ERROR] run -> loop -> startUserBot -> onFinished -> Unhandled custom response received. -> err = " + err.message); logger.persist(); clearInterval(fixedTimeLoopIntervalHandle); clearTimeout(nextLoopTimeoutHandle); @@ -526,7 +524,7 @@ } 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.write(MODULE_NAME, "[ERROR] run -> loop -> startUserBot -> onFinished -> Unhandled err.result received. -> err = " + err.message); logger.persist(); clearInterval(fixedTimeLoopIntervalHandle); @@ -612,7 +610,7 @@ return; } default: { - logger.write(MODULE_NAME, "[ERROR] run -> loop -> intitializeProcessFramework -> onInizialized > Unhandled custom response received. -> err.message = " + err.message); + logger.write(MODULE_NAME, "[ERROR] run -> loop -> intitializeProcessFramework -> onInizialized > Unhandled custom response received. -> err = " + err.message); logger.persist(); clearInterval(fixedTimeLoopIntervalHandle); clearTimeout(nextLoopTimeoutHandle); @@ -625,7 +623,7 @@ } default: { logger.write(MODULE_NAME, "[ERROR] run -> loop -> intitializeProcessFramework -> onInizialized -> Unhandled err.result received. -> err.result = " + err.result); - logger.write(MODULE_NAME, "[ERROR] run -> loop -> intitializeProcessFramework -> onInizialized -> Unhandled err.result received. -> err.message = " + err.message); + logger.write(MODULE_NAME, "[ERROR] run -> loop -> intitializeProcessFramework -> onInizialized -> Unhandled err.result received. -> err = " + err.message); logger.persist(); clearInterval(fixedTimeLoopIntervalHandle); @@ -672,6 +670,8 @@ try { if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] run -> loop -> startProcessFramework -> onFinished -> Entering function."); } + processFramework.finalize() + processFramework = undefined switch (err.result) { case global.DEFAULT_OK_RESPONSE.result: { @@ -742,7 +742,7 @@ return; } default: { - logger.write(MODULE_NAME, "[ERROR] run -> loop -> startProcessFramework -> onFinished -> Unhandled custom response received. -> err.message = " + err.message); + logger.write(MODULE_NAME, "[ERROR] run -> loop -> startProcessFramework -> onFinished -> Unhandled custom response received. -> err = " + err.message); logger.persist(); clearInterval(fixedTimeLoopIntervalHandle); clearTimeout(nextLoopTimeoutHandle); @@ -755,7 +755,7 @@ } default: { logger.write(MODULE_NAME, "[ERROR] run -> loop -> startProcessFramework -> onFinished -> Unhandled err.result received. -> err.result = " + err.result); - logger.write(MODULE_NAME, "[ERROR] run -> loop -> startProcessFramework -> onFinished -> Unhandled err.result received. -> err.message = " + err.message); + logger.write(MODULE_NAME, "[ERROR] run -> loop -> startProcessFramework -> onFinished -> Unhandled err.result received. -> err = " + err.message); logger.persist(); clearInterval(fixedTimeLoopIntervalHandle); @@ -826,7 +826,9 @@ switch (nextWaitTime) { case 'Normal': { if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] run -> loop -> loopControl -> Restarting Loop in " + (processConfig.normalWaitTime / 1000) + " seconds."); } - checkLoopHealthHandle = setTimeout(checkLoopHealth, processConfig.deadWaitTime * 5, bot.loopCounter); + if (processConfig.deadWaitTime > 0) { + checkLoopHealthHandle = setTimeout(checkLoopHealth, processConfig.deadWaitTime, bot.loopCounter); + } nextLoopTimeoutHandle = setTimeout(loop, processConfig.normalWaitTime); if(global.WRITE_LOGS_TO_FILES === 'true'){ logger.persist(); @@ -835,7 +837,9 @@ break; case 'Retry': { if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] run -> loop -> loopControl -> Restarting Loop in " + (processConfig.retryWaitTime / 1000) + " seconds."); } - checkLoopHealthHandle = setTimeout(checkLoopHealth, processConfig.retryWaitTime * 5, bot.loopCounter); + if (processConfig.deadWaitTime > 0) { + checkLoopHealthHandle = setTimeout(checkLoopHealth, processConfig.deadWaitTime, bot.loopCounter); + } nextLoopTimeoutHandle = setTimeout(loop, processConfig.retryWaitTime); logger.persist(); } @@ -900,7 +904,7 @@ stopCallBack(); } } catch (err) { - logger.write(MODULE_NAME, "[ERROR] run -> loop -> shallWeStop -> err.message = " + err.message); + logger.write(MODULE_NAME, "[ERROR] run -> loop -> shallWeStop -> err = " + err.stack); logger.persist(); clearInterval(fixedTimeLoopIntervalHandle); clearTimeout(nextLoopTimeoutHandle); @@ -921,7 +925,7 @@ } function hearBeat() { - 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 key = global.TASK_NODE.bot.processes[bot.processIndex].name + '-' + global.TASK_NODE.bot.processes[bot.processIndex].type + '-' + global.TASK_NODE.bot.processes[bot.processIndex].id let event = { seconds: (new Date()).getSeconds() diff --git a/Integrations/FileStorage.js b/Integrations/FileStorage.js index 699797ddd..481f10264 100644 --- a/Integrations/FileStorage.js +++ b/Integrations/FileStorage.js @@ -28,6 +28,14 @@ exports.newFileStorage = function newFileStorage(logger) { 'EAI_AGAIN' ] + if (logger === undefined) { + logger = {} + function write() { + + } + logger.write = write + } + return { getTextFile, createTextFile @@ -115,72 +123,55 @@ exports.newFileStorage = function newFileStorage(logger) { } } - async function createTextFile(container, filePath, fileContent, callBackFunction) { + function createTextFile(container, filePath, fileContent, callBackFunction) { - try { - let host = await getDevTeamHost(container) - - if (host.url.indexOf('localhost') !== -1) { - let fileLocation - - if (filePath.indexOf("/Logs/") > 0) { - fileLocation = process.env.LOG_PATH + '/' + container + '/' + filePath - } else { - fileLocation = process.env.STORAGE_PATH + '/' + container + '/' + filePath - } - - logInfo('createTextFile: ' + fileLocation) - //console.log('createTextFile: ' + fileLocation) - - let directoryPath = fileLocation.substring(0, fileLocation.lastIndexOf('/') + 1); - mkDirByPathSync(directoryPath) - await writeFileAsync(fileLocation, fileContent) - callBackFunction(global.DEFAULT_OK_RESPONSE) - } else { - let response = await axios({ - url: process.env.GATEWAY_ENDPOINT_K8S, - method: 'post', - data: { - query: ` - mutation web_CreateFile($file: web_FileInput){ - web_CreateFile(file: $file) - } - `, - variables: { - file: { - container: container.toLowerCase(), - filePath, - storage: 'localStorage', - accessKey: host.ownerKey, - fileContent - } - } - } - }) - - if (!response || response.data.errors) { - let customErr = { - result: global.CUSTOM_FAIL_RESPONSE.result, - message: response.data.errors[0] - } - callBackFunction(customErr) + /* Choose path for either logs or data */ + let fileLocation + if (filePath.indexOf("/Logs/") > 0) { + fileLocation = process.env.LOG_PATH + '/' + container + '/' + filePath } else { - callBackFunction(global.DEFAULT_OK_RESPONSE) + fileLocation = process.env.STORAGE_PATH + '/' + container + '/' + filePath } - } - } catch (err) { - if (verifyRetry(err.code) && currentRetryWriteTextFile < MAX_RETRY) { - currentRetryWriteTextFile++ - logInfo('createTextFile -> Retrying connection to the server because received error: ' + err.code + '. Retry #: ' + currentRetryWriteTextFile) - createTextFile(container, filePath, fileContent, callBackFunction) - } else { - currentRetryWriteTextFile = 0 - logError('createTextFile -> error = ' + err.message) - callBackFunction(global.DEFAULT_FAIL_RESPONSE) - } + try { + + logger.write(MODULE_NAME, '[INFO] FileStorage -> createTextFile -> fileLocation: ' + fileLocation) + + /* If necesary a folder or folders are created before writing the file to disk. */ + let directoryPath = fileLocation.substring(0, fileLocation.lastIndexOf('/') + 1); + mkDirByPathSync(directoryPath) + + /* Here we actually write the file. */ + fs.writeFile(fileLocation, fileContent, onFileWriten) + + function onFileWriten(err) { + if (err) { + logger.write(MODULE_NAME, '[ERROR] FileStorage -> createTextFile -> onFileWrite -> Error writing file -> file = ' + fileLocation) + logger.write(MODULE_NAME, '[ERROR] FileStorage -> createTextFile -> onFileWrite -> Error writing file -> err = ' + err.stack) + retry() + } else { + callBackFunction(global.DEFAULT_OK_RESPONSE) + } + } + + } catch (err) { + logger.write(MODULE_NAME, '[ERROR] FileStorage -> createTextFile -> Error writing file -> file = ' + fileLocation) + logger.write(MODULE_NAME, '[ERROR] FileStorage -> createTextFile -> Error writing file -> err = ' + err.stack) + retry() + } + + function retry() { + if (currentRetryWriteTextFile < MAX_RETRY) { + currentRetryWriteTextFile++ + logger.write(MODULE_NAME, '[WARN] FileStorage -> createTextFile -> retry -> Will try to write the file again -> Retry #: ' + currentRetryWriteTextFile) + createTextFile(container, filePath, fileContent, callBackFunction) + } else { + currentRetryWriteTextFile = 0 + logger.write(MODULE_NAME, '[ERROR] FileStorage -> createTextFile -> retry -> Max retries reached. Giving up.') + callBackFunction(global.DEFAULT_FAIL_RESPONSE) + } + } } - } async function getDevTeamHost(devTeamName) { let ecosystem = await Ecosystem.getEcosystem() diff --git a/MultiPeriod.js b/MultiPeriod.js index c1faa087f..6a6d44f2e 100644 --- a/MultiPeriod.js +++ b/MultiPeriod.js @@ -8,6 +8,7 @@ thisObject = { initialize: initialize, + finalize: finalize, start: start }; @@ -68,6 +69,19 @@ } } + function finalize() { + storages = undefined + dataFiles = undefined + multiPeriodDataFiles = undefined + statusDependencies = undefined + dataDependencies = undefined + usertBot.finalize() + usertBot = undefined + fileStorage = undefined + processConfig = undefined + thisObject = undefined + } + function start(callBackFunction) { try { @@ -115,6 +129,8 @@ /* We look first for the bot who knows the begining of the marke in order to get when the market starts. + IMPORTANT NOTE: When this module is used by Trading Engine Bots it nevers comes through this path since there is allways a ficed start date. + This code would be used by some indicator that is. */ let botWhoKnowsTheBeginingOfTheMarket = statusDependencies.config[processConfig.framework.startDate.takeItFromStatusDependency]; @@ -151,7 +167,7 @@ return; } - contextVariables.dateBeginOfMarket = new Date(thisReport.lastFile.year + "-" + thisReport.lastFile.month + "-" + thisReport.lastFile.days + " " + thisReport.lastFile.hours + ":" + thisReport.lastFile.minutes + GMT_SECONDS); + contextVariables.dateBeginOfMarket = new Date(thisReport.lastFile); } @@ -490,7 +506,7 @@ bot.multiPeriodDailyProcessDatetime = new Date(bot.multiPeriodDailyProcessDatetime.valueOf() + ONE_DAY_IN_MILISECONDS); previousDay = new Date(bot.multiPeriodDailyProcessDatetime.valueOf() - ONE_DAY_IN_MILISECONDS); - console.log(new Date().toISOString() + " " + pad(bot.codeName, 20) + " " + pad(bot.process, 30) + " " + " bot.multiPeriodDailyProcessDatetime = " + bot.multiPeriodDailyProcessDatetime.toISOString()); + console.log(new Date().toISOString() + " " + pad(bot.codeName, 20) + " " + pad(bot.process, 30) + " " + "bot.multiPeriodDailyProcessDatetime = " + bot.multiPeriodDailyProcessDatetime.toISOString()); if (global.WRITE_LOGS_TO_FILES === 'true') { logger.newInternalLoop(bot.codeName, bot.process); @@ -853,7 +869,7 @@ try { if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] start -> processTimePeriodsDailyFiles -> callTheBot -> Entering function."); } - + usertBot.start( multiPeriodDataFiles, currentTimePeriod, @@ -878,7 +894,8 @@ botNeverRan = false; if (currentTimePeriod > global.dailyFilePeriods[0][0]) { - writeMarketStatusReport(onMarketStatusReport); + writeMarketStatusReport(onMarketStatusReport) + } else { writeDataRanges(onWritten); } @@ -895,7 +912,7 @@ return; } - writeDailyStatusReport(bot.multiPeriodDailyProcessDatetime, advanceTime); + writeDailyStatusReport(bot.multiPeriodDailyProcessDatetime, onDailyStatusReport); } catch (err) { logger.write(MODULE_NAME, "[ERROR] start -> processTimePeriodsDailyFiles -> callTheBot -> onBotFinished -> onWritten -> err = " + err.stack); @@ -903,9 +920,29 @@ } } + + function onDailyStatusReport() { + try { + if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] start -> processTimePeriodsDailyFiles -> callTheBot -> onBotFinished -> onDailyStatusReport -> Entering function."); } + + /* The next run we need the process to continue at the date it finished. */ + processConfig.framework.startDate.resumeExecution = true; + + advanceTime(); + } catch (err) { + logger.write(MODULE_NAME, "[ERROR] start -> processTimePeriodsDailyFiles -> callTheBot -> onBotFinished -> onDailyStatusReport -> err = " + err.stack); + callBackFunction(global.DEFAULT_FAIL_RESPONSE); + } + } + function onMarketStatusReport() { try { if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] start -> processTimePeriodsDailyFiles -> callTheBot -> onBotFinished -> onMarketStatusReport -> Entering function."); } + + if (bot.startMode === "Backtest") { + global.STOP_PROCESSING = true + } + callBackFunction(global.DEFAULT_OK_RESPONSE); } catch (err) { logger.write(MODULE_NAME, "[ERROR] start -> processTimePeriodsDailyFiles -> callTheBot -> onBotFinished -> onMarketStatusReport -> err = " + err.stack); @@ -981,7 +1018,7 @@ let fileName = '/Data.Range.' + market.assetA + '_' + market.assetB + '.json'; let filePath = bot.filePathRoot + "/Output/" + pProductFolder + "/" + 'Multi-Period-Daily' + fileName; - fileStorage.createTextFile(global.DEV_TEAM, filePath, fileContent + '\n', onFileCreated); + fileStorage.createTextFile(bot.devTeam, filePath, fileContent + '\n', onFileCreated); function onFileCreated(err) { @@ -1023,9 +1060,6 @@ bot.hasTheBotJustStarted = false; - /* Emit event that signals that this process finished */ - global.SYSTEM_EVENT_HANDLER.raiseEvent('Jason-Multi-Period', 'Status Report Updated', { lastProcessedDay: lastFileDate }) - } catch (err) { logger.write(MODULE_NAME, "[ERROR] start -> writeDailyStatusReport -> err = " + err.stack); diff --git a/MultiPeriodDaily.js b/MultiPeriodDaily.js index b3ce60d62..cbe350560 100644 --- a/MultiPeriodDaily.js +++ b/MultiPeriodDaily.js @@ -8,6 +8,7 @@ thisObject = { initialize: initialize, + finalize: finalize, start: start }; @@ -67,6 +68,17 @@ } } + function finalize() { + storages = undefined + dataFiles = undefined + statusDependencies = undefined + dataDependencies = undefined + usertBot = undefined + fileStorage = undefined + processConfig = undefined + thisObject = undefined + } + function start(callBackFunction) { try { @@ -298,7 +310,7 @@ bot.multiPeriodDailyProcessDatetime = new Date(bot.multiPeriodDailyProcessDatetime.valueOf() + ONE_DAY_IN_MILISECONDS); previousDay = new Date(bot.multiPeriodDailyProcessDatetime.valueOf() - ONE_DAY_IN_MILISECONDS); - console.log(new Date().toISOString() + " " + pad(bot.codeName, 20) + " " + pad(bot.process, 30) + " " + " bot.multiPeriodDailyProcessDatetime = " + bot.multiPeriodDailyProcessDatetime.toISOString()); + console.log(new Date().toISOString() + " " + pad(bot.codeName, 20) + " " + pad(bot.process, 30) + " " + "bot.multiPeriodDailyProcessDatetime = " + bot.multiPeriodDailyProcessDatetime.toISOString()); if (global.WRITE_LOGS_TO_FILES === 'true') { logger.newInternalLoop(bot.codeName, bot.process); @@ -710,7 +722,7 @@ let fileName = '/Data.Range.' + market.assetA + '_' + market.assetB + '.json'; let filePath = bot.filePathRoot + "/Output/" + pProductFolder + "/" + bot.process + fileName; - fileStorage.createTextFile(global.DEV_TEAM, filePath, fileContent + '\n', onFileCreated); + fileStorage.createTextFile(bot.devTeam, filePath, fileContent + '\n', onFileCreated); function onFileCreated(err) { diff --git a/MultiPeriodMarket.js b/MultiPeriodMarket.js index c03f1420a..d3dfe3ac1 100644 --- a/MultiPeriodMarket.js +++ b/MultiPeriodMarket.js @@ -6,6 +6,7 @@ thisObject = { initialize: initialize, + finalize: finalize, start: start }; @@ -65,6 +66,17 @@ } } + function finalize() { + storages = undefined + dataFiles = undefined + statusDependencies = undefined + dataDependencies = undefined + usertBot = undefined + fileStorage = undefined + processConfig = undefined + thisObject = undefined + } + function start(callBackFunction) { try { diff --git a/Root.js b/Root.js index b26b69501..0a06b1132 100644 --- a/Root.js +++ b/Root.js @@ -46,11 +46,10 @@ const FULL_LOG = true; let logDisplace = "Task Server" + " "; - let UI_COMMANDS; return thisObject; - function initialize(pUI_COMMANDS, callBackFunction) { + function initialize(callBackFunction) { try { console.log(logDisplace + "Root : [INFO] initialize -> Entering function. "); @@ -95,13 +94,11 @@ } }; - UI_COMMANDS = pUI_COMMANDS; - callBackFunction(); } catch (err) { - console.log(logDisplace + "Root : [ERROR] initialize -> err.message = " + err.message); + console.log(logDisplace + "Root : [ERROR] initialize -> err = " + err.stack); return; } } @@ -126,9 +123,6 @@ const TRADING_ENGINE_MAIN_LOOP_MODULE = require('./TradingEngineProcessMainLoop'); /* Loop through all the processes configured to be run by this Node.js Instance. */ - - let cloneToExecute = global.EXECUTION_CONFIG.cloneToExecute; - /* Now we will read the config of the bot from the path we obtained at the Task Server config. */ let botConfig; @@ -143,9 +137,9 @@ const FILE_STORAGE = require('./Integrations/FileStorage.js'); let fileStorage = FILE_STORAGE.newFileStorage(); - let filePath = global.DEV_TEAM + '/bots/' + global.CURRENT_BOT_REPO + '/this.bot.config.json'; + let filePath = global.TASK_NODE.bot.processes[processIndex].code.team + '/bots/' + global.TASK_NODE.bot.processes[processIndex].code.repo + '/this.bot.config.json'; - fileStorage.getTextFile(global.DEV_TEAM, filePath, onFileReceived); + fileStorage.getTextFile(global.TASK_NODE.bot.processes[processIndex].code.team, filePath, onFileReceived); function onFileReceived(err, text) { @@ -157,7 +151,7 @@ try { botConfig = JSON.parse(text); - botConfig.repo = cloneToExecute.repo; + botConfig.repo = global.TASK_NODE.bot.processes[processIndex].code.repo; findProcess(processIndex); } catch (err) { console.log(logDisplace + "Root : [ERROR] start -> getBotConfig -> onInizialized -> onFileReceived -> err = " + JSON.stringify(err)); @@ -166,7 +160,7 @@ } } catch (err) { - console.log(logDisplace + "Root : [ERROR] start -> getBotConfig -> err.message = " + err.message); + console.log(logDisplace + "Root : [ERROR] start -> getBotConfig -> err = " + err.stack); return; } } @@ -176,7 +170,7 @@ try { if (FULL_LOG === true) { console.log(logDisplace + "Root : [INFO] start -> findProcess -> Entering function. "); } - botConfig.process = cloneToExecute.process; + botConfig.process = global.TASK_NODE.bot.processes[processIndex].code.process; botConfig.debug = {}; botConfig.processIndex = processIndex @@ -196,18 +190,13 @@ for (let i = 0; i < botConfig.processes.length; i++) { - if (botConfig.processes[i].name === cloneToExecute.process) { + if (botConfig.processes[i].name === global.TASK_NODE.bot.processes[processIndex].code.process) { processFound = true; - if (FULL_LOG === true) { console.log(logDisplace + "Root : [INFO] start -> findProcess -> Process found at the bot configuration file. -> cloneToExecute.process = " + cloneToExecute.process); } + if (FULL_LOG === true) { console.log(logDisplace + "Root : [INFO] start -> findProcess -> Process found at the bot configuration file. -> process = " + global.TASK_NODE.bot.processes[processIndex].code.process); } let processConfig = botConfig.processes[i]; - if (global.EXECUTION_CONFIG.timePeriod) { - processConfig.timePeriod = global.EXECUTION_CONFIG.timePeriod - } - - if (processConfig.framework !== undefined) { if (processConfig.framework.name === "Multi-Period-Daily" || processConfig.framework.name === "Multi-Period-Market" || processConfig.framework.name === "Multi-Period") { processConfig.framework.startDate.resumeExecution = true; @@ -338,7 +327,7 @@ runIndicatorBot(botConfig, processConfig, month, year); break; } - case 'Trading-Engine': { + case 'Trading Engine': { runTradingEngine(botConfig, processConfig); break; } @@ -388,7 +377,7 @@ } switch (botConfig.type) { - case 'Trading-Engine': { + case 'Trading Engine': { runTradingEngine(botConfig, processConfig); break; } @@ -400,7 +389,7 @@ } } catch (err) { - console.log(logDisplace + "Root : [ERROR] start -> findProcess -> Unexpected exception. -> err.message = " + err.message); + console.log(logDisplace + "Root : [ERROR] start -> findProcess -> Unexpected exception. -> err = " + err.stack); } } } @@ -408,7 +397,7 @@ if (processFound === false) { 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); + console.log(logDisplace + "Root : [ERROR] start -> findProcess -> process = " + global.TASK_NODE.bot.processes[processIndex].code.process); } @@ -428,7 +417,7 @@ if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] start -> findProcess -> runSensorBot -> pYear = " + pYear); } let extractionBotMainLoop = SENSOR_BOT_MAIN_LOOP_MODULE.newSensorBotProcessMainLoop(pBotConfig, logger); - extractionBotMainLoop.initialize(UI_COMMANDS, pProcessConfig, onInitializeReady); + extractionBotMainLoop.initialize(pProcessConfig, onInitializeReady); function onInitializeReady(err) { @@ -458,7 +447,7 @@ } else { - logger.write(MODULE_NAME, "[ERROR] start -> findProcess -> runSensorBot -> onInitializeReady -> whenStartFinishes -> err = " + err.stack); + logger.write(MODULE_NAME, "[ERROR] start -> findProcess -> runSensorBot -> onInitializeReady -> whenStartFinishes -> err = " + err.message); logger.write(MODULE_NAME, "[ERROR] start -> findProcess -> runSensorBot -> onInitializeReady -> whenStartFinishes -> Execution will be stopped. "); logger.write(MODULE_NAME, "[ERROR] start -> findProcess -> runSensorBot -> onInitializeReady -> whenStartFinishes -> Bye."); logger.write(MODULE_NAME, "[ERROR] start -> findProcess -> runSensorBot -> onInitializeReady -> whenStartFinishes -> Bot Id = " + botId); @@ -471,9 +460,9 @@ } } else { - logger.write(MODULE_NAME, "[ERROR] start -> findProcess -> runSensorBot -> onInitializeReady -> err = " + err.stack); + logger.write(MODULE_NAME, "[ERROR] start -> findProcess -> runSensorBot -> onInitializeReady -> err = " + err.message); logger.write(MODULE_NAME, "[ERROR] start -> findProcess -> runSensorBot -> onInitializeReady -> Bot will not be started. "); - console.log(logDisplace + "Root : [ERROR] start -> findProcess -> runSensorBot -> onInitializeReady -> err = " + err.stack); + console.log(logDisplace + "Root : [ERROR] start -> findProcess -> runSensorBot -> onInitializeReady -> err = " + err.message); logger.persist(); exitProcessInstance() @@ -502,7 +491,7 @@ if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] start -> findProcess -> runIndicatorBot -> pYear = " + pYear); } let indicatorBotMainLoop = INDICATOR_BOT_MAIN_LOOP_MODULE.newIndicatorBotProcessMainLoop(pBotConfig, logger); - indicatorBotMainLoop.initialize(UI_COMMANDS, pProcessConfig, onInitializeReady); + indicatorBotMainLoop.initialize(pProcessConfig, onInitializeReady); function onInitializeReady(err) { @@ -532,7 +521,7 @@ } else { - logger.write(MODULE_NAME, "[ERROR] start -> findProcess -> runIndicatorBot -> onInitializeReady -> whenStartFinishes -> err = " + err.stack); + logger.write(MODULE_NAME, "[ERROR] start -> findProcess -> runIndicatorBot -> onInitializeReady -> whenStartFinishes -> err = " + err.message); logger.write(MODULE_NAME, "[ERROR] start -> findProcess -> runIndicatorBot -> onInitializeReady -> whenStartFinishes -> Execution will be stopped. "); logger.write(MODULE_NAME, "[ERROR] start -> findProcess -> runIndicatorBot -> onInitializeReady -> whenStartFinishes -> Bye."); logger.write(MODULE_NAME, "[ERROR] start -> findProcess -> runIndicatorBot -> onInitializeReady -> whenStartFinishes -> Bot Id = " + botId); @@ -543,9 +532,9 @@ } } else { - logger.write(MODULE_NAME, "[ERROR] start -> findProcess -> runIndicatorBot -> onInitializeReady -> err = " + err.stack); + logger.write(MODULE_NAME, "[ERROR] start -> findProcess -> runIndicatorBot -> onInitializeReady -> err = " + err.message); 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); + console.log(logDisplace + "Root : [ERROR] start -> findProcess -> runIndicatorBot -> onInitializeReady -> err = " + err.message); logger.persist(); exitProcessInstance() } @@ -571,7 +560,7 @@ if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] start -> findProcess -> runTradingEngine -> Entering function."); } let tradingEngineMainLoop = TRADING_ENGINE_MAIN_LOOP_MODULE.newTradingEngineProcessMainLoop(pBotConfig, logger); - tradingEngineMainLoop.initialize(UI_COMMANDS, pProcessConfig, onInitializeReady); + tradingEngineMainLoop.initialize(pProcessConfig, onInitializeReady); function onInitializeReady(err) { @@ -598,7 +587,7 @@ } else { - logger.write(MODULE_NAME, "[ERROR] start -> findProcess -> runTradingEngine -> onInitializeReady -> whenStartFinishes -> err = " + err.stack); + logger.write(MODULE_NAME, "[ERROR] start -> findProcess -> runTradingEngine -> onInitializeReady -> whenStartFinishes -> err = " + err.message); logger.write(MODULE_NAME, "[ERROR] start -> findProcess -> runTradingEngine -> onInitializeReady -> whenStartFinishes -> Execution will be stopped. "); logger.write(MODULE_NAME, "[ERROR] start -> findProcess -> runTradingEngine -> onInitializeReady -> whenStartFinishes -> Bye."); logger.write(MODULE_NAME, "[ERROR] start -> findProcess -> runTradingEngine -> onInitializeReady -> whenStartFinishes -> Bot Id = " + botId); @@ -609,9 +598,9 @@ } } else { - logger.write(MODULE_NAME, "[ERROR] start -> findProcess -> runTradingEngine -> onInitializeReady -> err = " + err.stack); + logger.write(MODULE_NAME, "[ERROR] start -> findProcess -> runTradingEngine -> onInitializeReady -> err = " + err.message); 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); + console.log(logDisplace + "Root : [ERROR] start -> findProcess -> runTradingEngine -> onInitializeReady -> err = " + err.message); logger.persist(); exitProcessInstance() } @@ -624,7 +613,7 @@ } } catch (err) { - console.log(logDisplace + "Root : [ERROR] start -> findProcess -> err.message = " + err.message); + console.log(logDisplace + "Root : [ERROR] start -> findProcess -> err = " + err.stack); exitProcessInstance() } } @@ -632,14 +621,14 @@ function exitProcessInstance() { global.ENDED_PROCESSES_COUNTER++ - console.log("[INFO] Task Server -> " + global.USER_DEFINITION.name + " -> exitProcessInstance -> Process #" + global.ENDED_PROCESSES_COUNTER + " from " + global.TOTAL_PROCESS_INSTANCES_CREATED + " exiting."); + console.log("[INFO] Task Server -> " + global.TASK_NODE.name + " -> exitProcessInstance -> Process #" + global.ENDED_PROCESSES_COUNTER + " from " + global.TOTAL_PROCESS_INSTANCES_CREATED + " exiting."); if (global.ENDED_PROCESSES_COUNTER === global.TOTAL_PROCESS_INSTANCES_CREATED) { global.EXIT_NODE_PROCESS() } } } catch (err) { - console.log("[ERROR] Task Server -> " + global.USER_DEFINITION.name + " -> Root -> Start -> Err = " + err.stack); + console.log("[ERROR] Task Server -> " + global.TASK_NODE.name + " -> Root -> Start -> Err = " + err.stack); } } } diff --git a/SensorBotProcessMainLoop.js b/SensorBotProcessMainLoop.js index dda3a4a8f..4fd528f22 100644 --- a/SensorBotProcessMainLoop.js +++ b/SensorBotProcessMainLoop.js @@ -23,30 +23,28 @@ }; let processConfig; - let UI_COMMANDS; return thisObject; - function initialize(pUI_COMMANDS, pProcessConfig, callBackFunction) { + function initialize(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; + let filePath = bot.devTeam + "/" + "bots" + "/" + bot.repo + "/" + pProcessConfig.name; filePath += "/User.Bot.js" - fileStorage.getTextFile(global.DEV_TEAM, filePath, onBotDownloaded); + fileStorage.getTextFile(bot.devTeam, 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); + parentLogger.write(MODULE_NAME, "[ERROR] initialize -> onInizialized -> onBotDownloaded -> err = " + err.message); callBackFunction(global.DEFAULT_FAIL_RESPONSE); return; } @@ -56,10 +54,10 @@ } USER_BOT_MODULE.newUserBot = eval(text); // TODO This needs to be changed function - filePath = global.DEV_TEAM + "/" + "bots" + "/" + bot.repo; + filePath = bot.devTeam + "/" + "bots" + "/" + bot.repo; filePath += "/Commons.js" - fileStorage.getTextFile(global.DEV_TEAM, filePath, onCommonsDownloaded); + fileStorage.getTextFile(bot.devTeam, filePath, onCommonsDownloaded); function onCommonsDownloaded(err, text) { @@ -191,7 +189,7 @@ } 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.write(MODULE_NAME, "[ERROR] run -> loop -> initializeStatusDependencies -> onInizialized -> Unhandled err.result received. -> err = " + err.message); logger.persist(); clearInterval(fixedTimeLoopIntervalHandle); @@ -265,7 +263,7 @@ } 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.write(MODULE_NAME, "[ERROR] run -> loop -> initializeExchangeAPI -> onInizialized -> Unhandled err.result received. -> err = " + err.message); logger.persist(); clearInterval(fixedTimeLoopIntervalHandle); @@ -361,7 +359,7 @@ return; } default: { - logger.write(MODULE_NAME, "[ERROR] run -> loop -> initializeUserBot -> onInizialized > Unhandled custom response received. -> err.message = " + err.message); + logger.write(MODULE_NAME, "[ERROR] run -> loop -> initializeUserBot -> onInizialized > Unhandled custom response received. -> err = " + err.message); logger.persist(); clearInterval(fixedTimeLoopIntervalHandle); clearTimeout(nextLoopTimeoutHandle); @@ -374,7 +372,7 @@ } 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.write(MODULE_NAME, "[ERROR] run -> loop -> initializeUserBot -> onInizialized > Unhandled err.result received. -> err = " + err.message); logger.persist(); clearInterval(fixedTimeLoopIntervalHandle); @@ -491,7 +489,7 @@ return; } default: { - logger.write(MODULE_NAME, "[ERROR] run -> loop -> startUserBot -> onFinished > Unhandled custom response received. -> err.message = " + err.message); + logger.write(MODULE_NAME, "[ERROR] run -> loop -> startUserBot -> onFinished > Unhandled custom response received. -> err = " + err.message); logger.persist(); clearInterval(fixedTimeLoopIntervalHandle); clearTimeout(nextLoopTimeoutHandle); @@ -504,7 +502,7 @@ } 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.write(MODULE_NAME, "[ERROR] run -> loop -> startUserBot -> onFinished > Unhandled err.result received. -> err = " + err.message); logger.persist(); clearInterval(fixedTimeLoopIntervalHandle); @@ -580,14 +578,18 @@ case 'Normal': { 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 (processConfig.deadWaitTime > 0) { + checkLoopHealthHandle = setTimeout(checkLoopHealth, processConfig.deadWaitTime, bot.loopCounter); + } 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.deadWaitTime * 5, bot.loopCounter); + if (processConfig.deadWaitTime > 0) { + checkLoopHealthHandle = setTimeout(checkLoopHealth, processConfig.deadWaitTime, bot.loopCounter); + } nextLoopTimeoutHandle = setTimeout(loop, processConfig.normalWaitTime); if(global.WRITE_LOGS_TO_FILES === 'true'){ logger.persist(); @@ -674,7 +676,7 @@ stopCallBack(); } } catch (err) { - logger.write(MODULE_NAME, "[ERROR] run -> loop -> shallWeStop -> err.message = " + err.message); + logger.write(MODULE_NAME, "[ERROR] run -> loop -> shallWeStop -> err = " + err.stack); logger.persist(); clearInterval(fixedTimeLoopIntervalHandle); clearTimeout(nextLoopTimeoutHandle); @@ -696,7 +698,7 @@ } function hearBeat() { - 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 key = global.TASK_NODE.bot.processes[bot.processIndex].name + '-' + global.TASK_NODE.bot.processes[bot.processIndex].type + '-' + global.TASK_NODE.bot.processes[bot.processIndex].id let event = { seconds: (new Date()).getSeconds() diff --git a/StatusDependencies.js b/StatusDependencies.js index 75b273431..ae1230e2c 100644 --- a/StatusDependencies.js +++ b/StatusDependencies.js @@ -66,7 +66,7 @@ } case "Status Report was never created.": { - logger.write(MODULE_NAME, "[WARN] initialize -> onLoad -> err.message = " + err.message); + logger.write(MODULE_NAME, "[WARN] initialize -> onLoad -> err = " + err.stack); logger.write(MODULE_NAME, "[WARN] initialize -> onLoad -> Report Not Found. -> bot = " + pStatusDependenciesConfig[i].bot); logger.write(MODULE_NAME, "[WARN] initialize -> onLoad -> Report Not Found. -> process = " + pStatusDependenciesConfig[i].process); addReport(); @@ -75,7 +75,7 @@ case "Status Report is corrupt.": { - logger.write(MODULE_NAME, "[WARN] initialize -> onLoad -> err.message = " + err.message); + logger.write(MODULE_NAME, "[WARN] initialize -> onLoad -> err = " + err.stack); logger.write(MODULE_NAME, "[WARN] initialize -> onLoad -> Report Not Found. -> bot = " + pStatusDependenciesConfig[i].bot); logger.write(MODULE_NAME, "[WARN] initialize -> onLoad -> Report Not Found. -> process = " + pStatusDependenciesConfig[i].process); addReport(); diff --git a/StatusReport.js b/StatusReport.js index 51d4778ff..7f6fcc120 100644 --- a/StatusReport.js +++ b/StatusReport.js @@ -71,11 +71,6 @@ function responseCallBack(message) { if (message.result !== global.DEFAULT_OK_RESPONSE.result) { - logger.write(MODULE_NAME, "[ERROR] initialize -> Could not register event listener for event 'Status Report Updated' -> Message = " + message); - let event = { - reason: 'This process depends on ' + key + ' which is currently not running.' - } - global.SYSTEM_EVENT_HANDLER.raiseEvent(key, 'Process Terminated', event) callBackFunction(global.DEFAULT_FAIL_RESPONSE); } } diff --git a/SystemEventHandler.js b/SystemEventHandler.js index 7620ca72e..f86270062 100644 --- a/SystemEventHandler.js +++ b/SystemEventHandler.js @@ -48,10 +48,11 @@ 'message', // here is where all incomming messages are processed. function (data) { ipc.log('Got a message from Superalgos Event Server: '.debug, data); - + let message = JSON.parse(data) if (message.action === 'Event Raised') { + let key if (message.callerId) { key = message.eventHandlerName + '-' + message.eventType + '-' + message.callerId diff --git a/TradingEngineProcessMainLoop.js b/TradingEngineProcessMainLoop.js index 69fc465e5..da2c27630 100644 --- a/TradingEngineProcessMainLoop.js +++ b/TradingEngineProcessMainLoop.js @@ -27,30 +27,28 @@ }; let processConfig; - let UI_COMMANDS; return thisObject; - function initialize(pUI_COMMANDS, pProcessConfig, callBackFunction) { + function initialize(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 + let filePath = bot.devTeam + "/" + "bots" + "/" + bot.repo + "/" + pProcessConfig.name filePath += "/User.Bot.js" - fileStorage.getTextFile(global.DEV_TEAM, filePath, onBotDownloaded); + fileStorage.getTextFile(bot.devTeam, 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); + parentLogger.write(MODULE_NAME, "[ERROR] initialize -> onInizialized -> onBotDownloaded -> err = " + err.message); callBackFunction(global.DEFAULT_FAIL_RESPONSE); return; } @@ -59,10 +57,10 @@ //USER_BOT_MODULE.newUserBot = require(process.env.BOTS_PATH + '/aamasters/AAMasters/bots/AAJason-Trading-Engine-Bot/Multi-Period/User.Bot').newUserBot // Use this for a better debugging experience. You need to bring this js module to this folder in order to work. USER_BOT_MODULE.newUserBot = eval(text); // Use this for production - filePath = global.DEV_TEAM + "/" + "bots" + "/" + bot.repo; + filePath = bot.devTeam + "/" + "bots" + "/" + bot.repo; filePath += "/Commons.js" - fileStorage.getTextFile(global.DEV_TEAM, filePath, onCommonsDownloaded); + fileStorage.getTextFile(bot.devTeam, filePath, onCommonsDownloaded); function onCommonsDownloaded(err, text) { @@ -109,6 +107,7 @@ processConfig.framework.startDate.resumeExecution = false; global.STOP_PROCESSING = false bot.hasTheBotJustStarted = true + setInitialBalance() /* If we can not get for any reason the initial date of the backtest, we will start at present time. */ processConfig.framework.startDate.fixedDate = new Date() @@ -140,6 +139,7 @@ } } } + bot.multiPeriodDailyProcessDatetime = processConfig.framework.startDate.fixedDate } function startLiveTrading(message) { @@ -147,17 +147,86 @@ /* We are going to run the Definition comming at the event. */ global.DEFINITION = JSON.parse(message.event.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 + + } + } + } + } + } + + if (process.env.KEY === undefined || process.env.SECRET === undefined) { + if (FULL_LOG === true) { logger.write(MODULE_NAME, "[WARN] run -> startLiveTrading -> Key name or Secret not provided, not possible to run the process in Live mode."); } + return + } + bot.startMode = "Live" processConfig.framework.startDate.fixedDate = new Date() processConfig.framework.startDate.resumeExecution = false; + bot.multiPeriodDailyProcessDatetime = processConfig.framework.startDate.fixedDate global.STOP_PROCESSING = false bot.hasTheBotJustStarted = true + setInitialBalance() } function stopRequested() { global.STOP_PROCESSING = true } + function setInitialBalance() { + if (global.DEFINITION !== undefined) { + + /* Get the initial balance from the global.DEFINITION */ + let tradingSystem = global.DEFINITION.tradingSystem + + if (tradingSystem) { + if (tradingSystem.parameters !== undefined) { + if (tradingSystem.parameters.baseAsset !== undefined) { + let code + try { + code = JSON.parse(tradingSystem.parameters.baseAsset.code); + + if (code.name !== undefined) { + baseAsset = code.name; + if (baseAsset !== 'BTC' && baseAsset !== 'USDT') { + /* using BTC as default */ + baseAsset = 'BTC' + } + } + + if (baseAsset === 'BTC') { // NOTE: POLONIEX, the only exchange working so far, has Asset A and B inverted. We need to fix this. + if (code.initialBalance !== undefined) { + process.env.INITIAL_BALANCE_ASSET_B = code.initialBalance; + process.env.INITIAL_BALANCE_ASSET_A = 0 + } + } else { + if (code.initialBalance !== undefined) { + process.env.INITIAL_BALANCE_ASSET_A = code.initialBalance; + process.env.INITIAL_BALANCE_ASSET_B = 0 + } + } + } catch (err) { + 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 + + } + } + } + } + } + } + loop(); function loop() { @@ -183,6 +252,7 @@ let nextWaitTime; /* Loop Heartbeat sent to the UI */ + bot.hearBeat = hearBeat // allow the bot itself to produce a heartbeat hearBeat() /* We define here all the modules that the rest of the infraestructure, including the bots themselves can consume. */ @@ -208,7 +278,12 @@ /* Checking if we should process this loop or not.*/ if (global.STOP_PROCESSING === true) { if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] run -> loop -> We are going to skip this Loop bacause we were requested to stop or never asked to start."); } - console.log("[INFO] run -> loop -> We are going to skip this Loop bacause we were requested to stop or never asked to start.") + + console.log(new Date().toISOString() + " " + pad(bot.codeName, 20) + " " + pad(bot.process, 30) + + " We are going to skip this Loop bacause we were requested to stop or never asked to start. "); + + global.SYSTEM_EVENT_HANDLER.raiseEvent('Jason-Multi-Period', 'Process Stopped') + nextWaitTime = 'Normal'; loopControl(nextWaitTime); return @@ -264,7 +339,7 @@ } 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.write(MODULE_NAME, "[ERROR] run -> loop -> initializeStatusDependencies -> onInizialized -> Unhandled err.result received. -> err = " + err.message); logger.persist(); clearInterval(fixedTimeLoopIntervalHandle); @@ -338,7 +413,7 @@ } 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.write(MODULE_NAME, "[ERROR] run -> loop -> initializeDataDependencies -> onInizialized -> Unhandled err.result received. -> err = " + err.message); logger.persist(); clearInterval(fixedTimeLoopIntervalHandle); @@ -411,7 +486,7 @@ } 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.write(MODULE_NAME, "[ERROR] run -> loop -> initializeContext -> onInizialized -> Unhandled err.result received. -> err = " + err.message); logger.persist(); clearInterval(fixedTimeLoopIntervalHandle); @@ -485,7 +560,7 @@ } 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.write(MODULE_NAME, "[ERROR] run -> loop -> initializeExchangeAPI -> onInizialized -> Unhandled err.result received. -> err = " + err.message); logger.persist(); clearInterval(fixedTimeLoopIntervalHandle); @@ -592,7 +667,7 @@ } 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.write(MODULE_NAME, "[ERROR] run -> loop -> initializeAssistant -> onInizialized -> Unhandled err.result received. -> err = " + err.message); logger.persist(); clearInterval(fixedTimeLoopIntervalHandle); @@ -678,7 +753,7 @@ return; } default: { - logger.write(MODULE_NAME, "[ERROR] run -> loop -> intitializeProcessFramework -> onInizialized > Unhandled custom response received. -> err.message = " + err.message); + logger.write(MODULE_NAME, "[ERROR] run -> loop -> intitializeProcessFramework -> onInizialized > Unhandled custom response received. -> err = " + err.message); logger.persist(); clearInterval(fixedTimeLoopIntervalHandle); clearTimeout(nextLoopTimeoutHandle); @@ -691,7 +766,7 @@ } default: { logger.write(MODULE_NAME, "[ERROR] run -> loop -> intitializeProcessFramework -> onInizialized -> Unhandled err.result received. -> err.result = " + err.result); - logger.write(MODULE_NAME, "[ERROR] run -> loop -> intitializeProcessFramework -> onInizialized -> Unhandled err.result received. -> err.message = " + err.message); + logger.write(MODULE_NAME, "[ERROR] run -> loop -> intitializeProcessFramework -> onInizialized -> Unhandled err.result received. -> err = " + err.message); logger.persist(); clearInterval(fixedTimeLoopIntervalHandle); @@ -738,6 +813,8 @@ try { if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] run -> loop -> startProcessFramework -> onFinished -> Entering function."); } + processFramework.finalize() + processFramework = undefined switch (err.result) { case global.DEFAULT_OK_RESPONSE.result: { @@ -808,7 +885,7 @@ return; } default: { - logger.write(MODULE_NAME, "[ERROR] run -> loop -> startProcessFramework -> onFinished -> Unhandled custom response received. -> err.message = " + err.message); + logger.write(MODULE_NAME, "[ERROR] run -> loop -> startProcessFramework -> onFinished -> Unhandled custom response received. -> err = " + err.message); logger.persist(); clearInterval(fixedTimeLoopIntervalHandle); clearTimeout(nextLoopTimeoutHandle); @@ -821,7 +898,7 @@ } default: { logger.write(MODULE_NAME, "[ERROR] run -> loop -> startProcessFramework -> onFinished -> Unhandled err.result received. -> err.result = " + err.result); - logger.write(MODULE_NAME, "[ERROR] run -> loop -> startProcessFramework -> onFinished -> Unhandled err.result received. -> err.message = " + err.message); + logger.write(MODULE_NAME, "[ERROR] run -> loop -> startProcessFramework -> onFinished -> Unhandled err.result received. -> err = " + err.message); logger.persist(); clearInterval(fixedTimeLoopIntervalHandle); @@ -898,7 +975,7 @@ } 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.write(MODULE_NAME, "[ERROR] run -> loop -> saveContext -> onFinished -> Unhandled err.result received. -> err = " + err.message); logger.persist(); clearInterval(fixedTimeLoopIntervalHandle); @@ -955,6 +1032,8 @@ logger.persist(); } + global.SYSTEM_EVENT_HANDLER.raiseEvent('Jason-Multi-Period', 'Process Stopped') + callBackFunction(global.DEFAULT_OK_RESPONSE); return; @@ -969,7 +1048,9 @@ switch (nextWaitTime) { case 'Normal': { if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] run -> loop -> loopControl -> Restarting Loop in " + (processConfig.normalWaitTime / 1000) + " seconds."); } - checkLoopHealthHandle = setTimeout(checkLoopHealth, processConfig.deadWaitTime * 5, bot.loopCounter); + if (processConfig.deadWaitTime > 0) { + checkLoopHealthHandle = setTimeout(checkLoopHealth, processConfig.deadWaitTime, bot.loopCounter); + } nextLoopTimeoutHandle = setTimeout(loop, processConfig.normalWaitTime); if (global.WRITE_LOGS_TO_FILES === 'true') { logger.persist(); @@ -978,7 +1059,9 @@ break; case 'Retry': { if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] run -> loop -> loopControl -> Restarting Loop in " + (processConfig.retryWaitTime / 1000) + " seconds."); } - checkLoopHealthHandle = setTimeout(checkLoopHealth, processConfig.retryWaitTime * 5, bot.loopCounter); + if (processConfig.deadWaitTime > 0) { + checkLoopHealthHandle = setTimeout(checkLoopHealth, processConfig.deadWaitTime, bot.loopCounter); + } nextLoopTimeoutHandle = setTimeout(loop, processConfig.retryWaitTime); logger.persist(); } @@ -1043,7 +1126,7 @@ stopCallBack(); } } catch (err) { - logger.write(MODULE_NAME, "[ERROR] run -> loop -> shallWeStop -> err.message = " + err.message); + logger.write(MODULE_NAME, "[ERROR] run -> loop -> shallWeStop -> err = " + err.stack); logger.persist(); clearInterval(fixedTimeLoopIntervalHandle); clearTimeout(nextLoopTimeoutHandle); @@ -1065,13 +1148,14 @@ } function hearBeat() { - 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 key = global.TASK_NODE.bot.processes[bot.processIndex].name + '-' + global.TASK_NODE.bot.processes[bot.processIndex].type + '-' + global.TASK_NODE.bot.processes[bot.processIndex].id let event = { seconds: (new Date()).getSeconds() } global.SYSTEM_EVENT_HANDLER.raiseEvent(key, 'Heartbeat', event) } + } catch (err) { parentLogger.write(MODULE_NAME, "[ERROR] run -> err = "+ err.stack); clearInterval(fixedTimeLoopIntervalHandle); diff --git a/server.js b/server.js index ac33d8bd6..d007d0daa 100644 --- a/server.js +++ b/server.js @@ -40,50 +40,53 @@ process.on('unhandledRejection', (reason, p) => { }) process.on('exit', function (code) { + + /* We send an event signaling that the Task is being terminated. */ + + let key = global.TASK_NODE.name + '-' + global.TASK_NODE.type + '-' + global.TASK_NODE.id + + global.SYSTEM_EVENT_HANDLER.raiseEvent(key, 'Stopped') // Meaning Task Stopped + global.SYSTEM_EVENT_HANDLER.deleteEventHandler(key) + global.SYSTEM_EVENT_HANDLER.finalize() + global.SYSTEM_EVENT_HANDLER = undefined + console.log('[INFO] Task Server -> server -> process.on.exit -> About to exit -> code = ' + code) }) -/* Local Variables */ - -let sequenceList = [] -let heartBeatInterval - /* We read the first string sent as an argument when the process was created by the Task Manager. Ther we will find the information of the identity of this Task and know exactly what to run within this server instance. */ -global.USER_DEFINITION = process.argv[2] +global.TASK_NODE = process.argv[2] -if (global.USER_DEFINITION !== undefined) { - console.log('[INFO] Task Server -> server -> global.USER_DEFINITION = ' + global.USER_DEFINITION) +if (global.TASK_NODE !== undefined) { + console.log('[INFO] Task Server -> server -> global.TASK_NODE = ' + global.TASK_NODE) try { - global.USER_DEFINITION = JSON.parse(global.USER_DEFINITION) + global.TASK_NODE = JSON.parse(global.TASK_NODE) } catch (err) { - console.log('[ERROR] Task Server -> server -> global.USER_DEFINITION -> ' + err.stack) + console.log('[ERROR] Task Server -> server -> global.TASK_NODE -> ' + err.stack) } } else { // I use this section to debug in standalone mode. - let argument = ' {"type":"Task","name":"Runs Backtests, Fordwardtests & Live Trades ","bot":{"type":"Trading Engine","processes":[{"type":"Process","name":"Multi Period","code":{"devTeam":"AAMasters","bot":"AAJason","mode":"live","resumeExecution":true,"type":"Trading-Engine","exchangeName":"Poloniex","process":"Multi-Period-Daily","beginDatetime":"2019-08-01T08:00:00.000Z","timePeriod":"05-min"},"id":"1bfce24d-8c05-4be9-bd25-328f07c85265"}]},"id":"cbb13086-608d-4bb4-960a-17a81038877b"}' + let argument = '{"type":"Task","name":"Runs Backtests, Fordwardtests & Live Trades ","bot":{"type":"Trading Engine","processes":[{"type":"Process","name":"Multi Period","code":{"team":"AAMasters","bot":"AAJason","process":"Multi-Period","repo":"AAJason-Trading-Engine-Bot"},"id":"4748c8c4-4d19-4076-96b2-e9c06524fbb3"}]},"id":"561bac18-fc78-464a-90c5-79fd821fc633"}' try { - global.USER_DEFINITION = JSON.parse(argument) + global.TASK_NODE = JSON.parse(argument) } catch (err) { console.log(err.stack) } } - 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.EXCHANGE_NAME = 'Poloniex' global.MARKET = { assetA: 'USDT', assetB: 'BTC' } -global.CLONE_EXECUTOR = { codeName: 'AACloud', version: '1.1' } +global.CLONE_EXECUTOR = { codeName: 'AACloud', version: '1.1' } // NOTE: To refactor the name of this variable you would need to go through the bots code that are using it. /* We need to count how many process instances we deployd and how many of them have already finished their job, either @@ -105,8 +108,8 @@ process.on('message', message => { There are some process that might no be able to end grafully, for example the ones schedulle to process information in a future day or month. In order to be sure that the process will be terminated, we schedulle one forced exit in 2 minutes from now. */ - console.log('[INFO] Task Server -> server -> process.on -> Executing order received from Task Manager to Stop this Task. Nodejs process will be exited in less than 2 minutes.') - setTimeout(global.EXIT_NODE_PROCESS, 120000); + console.log('[INFO] Task Server -> server -> process.on -> Executing order received from Task Manager to Stop this Task. Nodejs process will be exited in less than 1 minutes.') + setTimeout(global.EXIT_NODE_PROCESS, 60000); } }); @@ -115,22 +118,22 @@ global.EXIT_NODE_PROCESS = function exitProcess() { /* 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 + for (let i = 0; i < global.TASK_NODE.bot.processes.length; i++) { + let code = global.TASK_NODE.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) + let key = code.team + "-" + code.bot + "-" + code.process + global.SYSTEM_EVENT_HANDLER.deleteEventHandler(key) + + let process = global.TASK_NODE.bot.processes[i] + + key = process.name + '-' + process.type + '-' + process.id + global.SYSTEM_EVENT_HANDLER.raiseEvent(key, 'Stopped') // Meaning Process Stopped } - global.SYSTEM_EVENT_HANDLER.finalize() - global.SYSTEM_EVENT_HANDLER = undefined - console.log("[INFO] Task Server -> " + global.USER_DEFINITION.name + " -> EXIT_NODE_PROCESS -> Task Server Stopped."); + console.log("[INFO] Task Server -> " + global.TASK_NODE.name + " -> EXIT_NODE_PROCESS -> Task Server Stopped."); process.exit() } @@ -143,27 +146,16 @@ const EVENT_HANDLER_MODULE = require('./SystemEventHandler.js'); const IPC = require('node-ipc'); global.SYSTEM_EVENT_HANDLER = EVENT_HANDLER_MODULE.newSystemEventHandler(IPC) global.SYSTEM_EVENT_HANDLER.initialize('Task Server', bootLoader) - +global.STOP_TASK_GRACEFULLY = false; function bootLoader() { - for (let i = 0; i < global.USER_DEFINITION.bot.processes.length; i++) { - let code = global.USER_DEFINITION.bot.processes[i].code - - /* Add to the execution sequence list. */ - sequenceList.push(code) - - /* Create the event handler for each process. This event handlers are where the status reports updated events are raised. */ - - let key = code.devTeam + "-" + code.bot + "-" + code.process - global.SYSTEM_EVENT_HANDLER.createEventHandler(key) - } - /* Heartbeat sent to the UI */ - let key = global.USER_DEFINITION.name + '-' + global.USER_DEFINITION.type + '-' + global.USER_DEFINITION.id + let key = global.TASK_NODE.name + '-' + global.TASK_NODE.type + '-' + global.TASK_NODE.id global.SYSTEM_EVENT_HANDLER.createEventHandler(key) + global.SYSTEM_EVENT_HANDLER.raiseEvent(key, 'Running') // Meaning Task Running global.HEARTBEAT_INTERVAL_HANDLER = setInterval(hearBeat, 1000) function hearBeat() { @@ -175,197 +167,50 @@ function bootLoader() { global.SYSTEM_EVENT_HANDLER.raiseEvent(key, 'Heartbeat', event) } - startSequence() -} + for (let processIndex = 0; processIndex < global.TASK_NODE.bot.processes.length; processIndex++) { + let code = global.TASK_NODE.bot.processes[processIndex].code -/* Old Run.js code follows... */ + /* Validate that the minimun amount of parameters required are defined. */ -function startSequence() { - - for (let processIndex = 0; processIndex < global.USER_DEFINITION.bot.processes.length; processIndex++) { - let execution = sequenceList[processIndex]; - - global.STOP_TASK_GRACEFULLY = false; - execution.devTeam ? process.env.DEV_TEAM = execution.devTeam : undefined; - execution.bot ? process.env.BOT = execution.bot : undefined; - execution.resumeExecution = true; - execution.type ? process.env.TYPE = execution.type : undefined; - execution.process ? process.env.PROCESS = execution.process : 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 (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 - - } - } - } - } - } + if (global.TASK_NODE.bot.processes[processIndex].code.bot === undefined) { + console.log("[INFO] Task Server -> server -> bootLoader -> Parameter 'bot' is undefined. This process will not be executed. -> Process = " + global.TASK_NODE.bot.processes[processIndex].name); + continue } - readExecutionConfiguration(execution, processIndex); - } -} - -async function readExecutionConfiguration(execution, processIndex) { - try { - console.log("[INFO] Task Server -> server -> readExecutionConfiguration -> Entering function. "); - - let botProcess - - if (execution.type === 'Trading-Engine') { - - /* The Trading Engine only resumes its execution after the first sequence was completed. */ - if (notFirstSequence === false) { - execution.resumeExecution = false - } - - if (global.DEFINITION !== undefined) { - - botProcess = "Multi-Period" - - /* Get the initial balance from the global.DEFINITION */ - let tradingSystem = global.DEFINITION.tradingSystem - - if (tradingSystem) { - if (tradingSystem.parameters !== undefined) { - if (tradingSystem.parameters.baseAsset !== undefined) { - let code - try { - code = JSON.parse(tradingSystem.parameters.baseAsset.code); - - if (code.name !== undefined) { - baseAsset = code.name; - if (baseAsset !== 'BTC' && baseAsset !== 'USDT') { - /* using BTC as default */ - baseAsset = 'BTC' - } - } - - if (baseAsset === 'BTC') { // NOTE: POLONIEX, the only exchange working so far, has Asset A and B inverted. We need to fix this. - if (code.initialBalance !== undefined) { - process.env.INITIAL_BALANCE_ASSET_B = code.initialBalance; - process.env.INITIAL_BALANCE_ASSET_A = 0 - } - } else { - if (code.initialBalance !== undefined) { - process.env.INITIAL_BALANCE_ASSET_A = code.initialBalance; - process.env.INITIAL_BALANCE_ASSET_B = 0 - } - } - } catch (err) { - 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 - - } - } - } - } - } + if (global.TASK_NODE.bot.processes[processIndex].code.team === undefined) { + console.log("[INFO] Task Server -> server -> bootLoader -> Parameter 'team' is undefined. This process will not be executed. -> Process = " + global.TASK_NODE.bot.processes[processIndex].name); + continue } - // General Financial Being Configuration - global.DEV_TEAM = process.env.DEV_TEAM - global.CURRENT_BOT_REPO = process.env.BOT + "-" + process.env.TYPE + "-Bot" - - if (botProcess === undefined) { botProcess = process.env.PROCESS } // Only use the .env when nothing comes at Definition.json - let cloneToExecute = { - enabled: "true", - devTeam: process.env.DEV_TEAM, - bot: process.env.BOT, - process: botProcess, - repo: global.CURRENT_BOT_REPO + if (global.TASK_NODE.bot.processes[processIndex].code.process === undefined) { + console.log("[INFO] Task Server -> server -> bootLoader -> Parameter 'process' is undefined. This process will not be executed. -> Process = " + global.TASK_NODE.bot.processes[processIndex].name); + continue } - - global.EXECUTION_CONFIG = { - cloneToExecute: cloneToExecute - }; + /* Create the event handler for each process. This event handlers are where the status reports updated events are raised. */ - global.CLONE_EXECUTOR = { - codeName: 'AACloud', - version: '1.1' + let key = code.team + "-" + code.bot + "-" + code.process + global.SYSTEM_EVENT_HANDLER.createEventHandler(key) + + if (global.TASK_NODE.bot.processes[processIndex].code.repo === undefined) { + global.TASK_NODE.bot.processes[processIndex].code.repo = global.TASK_NODE.bot.processes[processIndex].code.bot + "-" + global.TASK_NODE.bot.type + "-Bot" } startRoot(processIndex); } - - catch (err) { - console.log("[ERROR] readExecutionConfiguration -> err = " + err.stack); - console.log("[ERROR] readExecutionConfiguration -> Please verify that the Start Mode for the type of Bot configured applies to that type."); - } -} - - -function getTimePeriod(timePeriod) { - if (timePeriod !== undefined) { - try { - let timePeriodMap = new Map() - timePeriodMap.set('24-hs', 86400000) - timePeriodMap.set('12-hs', 43200000) - timePeriodMap.set('08-hs', 28800000) - timePeriodMap.set('06-hs', 21600000) - timePeriodMap.set('04-hs', 14400000) - timePeriodMap.set('03-hs', 10800000) - timePeriodMap.set('02-hs', 7200000) - timePeriodMap.set('01-hs', 3600000) - timePeriodMap.set('45-min', 2700000) - timePeriodMap.set('40-min', 2400000) - timePeriodMap.set('30-min', 1800000) - timePeriodMap.set('20-min', 1200000) - timePeriodMap.set('15-min', 900000) - timePeriodMap.set('10-min', 600000) - timePeriodMap.set('05-min', 300000) - timePeriodMap.set('04-min', 240000) - timePeriodMap.set('03-min', 180000) - timePeriodMap.set('02-min', 120000) - timePeriodMap.set('01-min', 60000) - return timePeriodMap.get(timePeriod) - } catch (error) { - console.log('[WARN] Task Server -> server -> readExecutionConfiguration -> getTimePeriod -> Error: ', error) - } - } else { - return undefined - } } function startRoot(processIndex) { + console.log('[INFO] Task Server -> server -> startRoot -> Entering function. ') - const ROOT_DIR = './' - const ROOT_MODULE = require(ROOT_DIR + 'Root') + const ROOT_MODULE = require('./Root') let root = ROOT_MODULE.newRoot() - let UI_COMMANDS = { - beginDatetime: undefined, - endDatetime: undefined, - timePeriod: undefined, - startMode: undefined, - eventHandler: undefined - } - - root.initialize(UI_COMMANDS, onInitialized) + root.initialize(onInitialized) function onInitialized() { console.log('[INFO] Task Server -> server -> startRoot -> onInitialized -> Entering function. ') - root.start(processIndex) } }