From 8d33a3f143de5823a7ee6df58e180187a023c3d5 Mon Sep 17 00:00:00 2001 From: Luis Fernando Molina Date: Mon, 22 Jul 2019 23:01:11 +0200 Subject: [PATCH] Trading Engine Main Loop --- MultiPeriodDaily.js | 22 ++++----- Root.js | 6 +++ Run.js | 4 +- TradingEngineProcessMainLoop.js | 79 ++++++++++++++++++++++++++++++++- 4 files changed, 98 insertions(+), 13 deletions(-) diff --git a/MultiPeriodDaily.js b/MultiPeriodDaily.js index 06e4edcd3..c8e9b7590 100644 --- a/MultiPeriodDaily.js +++ b/MultiPeriodDaily.js @@ -284,7 +284,7 @@ let n; let botNeverRan = true; - bot.processDatetime = new Date(contextVariables.lastFile.valueOf() - ONE_DAY_IN_MILISECONDS); // Go back one day to start well when we advance time at the begining of the loop. + bot.multiPeriodDailyProcessDatetime = new Date(contextVariables.lastFile.valueOf() - ONE_DAY_IN_MILISECONDS); // Go back one day to start well when we advance time at the begining of the loop. advanceTime(); @@ -294,21 +294,21 @@ if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] start -> processTimePeriods -> advanceTime -> Entering function."); } - bot.processDatetime = new Date(bot.processDatetime.valueOf() + ONE_DAY_IN_MILISECONDS); - previousDay = new Date(bot.processDatetime.valueOf() - ONE_DAY_IN_MILISECONDS); + 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.processDatetime = " + bot.processDatetime.toISOString()); + console.log(new Date().toISOString() + " " + pad(bot.codeName, 20) + " " + pad(bot.process, 30) + " " + " bot.multiPeriodDailyProcessDatetime = " + bot.multiPeriodDailyProcessDatetime.toISOString()); if(global.FULL_LOG === 'true'){ logger.newInternalLoop(bot.codeName, bot.process); } - if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] start -> processTimePeriods -> advanceTime -> bot.processDatetime = " + bot.processDatetime); } + if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] start -> processTimePeriods -> advanceTime -> bot.multiPeriodDailyProcessDatetime = " + bot.multiPeriodDailyProcessDatetime); } if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] start -> processTimePeriods -> advanceTime -> previousDay = " + previousDay); } /* Validation that we are not going past the head of the market. */ - if (bot.processDatetime.valueOf() > contextVariables.dateEndOfMarket.valueOf()) { + if (bot.multiPeriodDailyProcessDatetime.valueOf() > contextVariables.dateEndOfMarket.valueOf()) { const logText = "Head of the market found @ " + previousDay.getUTCFullYear() + "/" + (previousDay.getUTCMonth() + 1) + "/" + previousDay.getUTCDate() + "."; if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] start -> processTimePeriods -> advanceTime -> " + logText); } @@ -395,7 +395,7 @@ let previousFile; let currentFile; - if (bot.processDatetime.valueOf() > contextVariables.dateBeginOfMarket.valueOf()) { + if (bot.multiPeriodDailyProcessDatetime.valueOf() > contextVariables.dateBeginOfMarket.valueOf()) { getPreviousFile(); } else { previousFile = []; @@ -473,7 +473,7 @@ if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] start -> processTimePeriods -> periodsLoopBody -> dependencyLoopBody -> getCurrentFile -> Entering function."); } - let dateForPath = bot.processDatetime.getUTCFullYear() + '/' + utilities.pad(bot.processDatetime.getUTCMonth() + 1, 2) + '/' + utilities.pad(bot.processDatetime.getUTCDate(), 2); + let dateForPath = bot.multiPeriodDailyProcessDatetime.getUTCFullYear() + '/' + utilities.pad(bot.multiPeriodDailyProcessDatetime.getUTCMonth() + 1, 2) + '/' + utilities.pad(bot.multiPeriodDailyProcessDatetime.getUTCDate(), 2); let filePath = dependency.product + '/' + "Multi-Period-Daily" + "/" + outputPeriodLabel + "/" + dateForPath; let fileName = market.assetA + '_' + market.assetB + ".json"; @@ -563,7 +563,7 @@ dataFiles, timePeriod, outputPeriodLabel, - bot.processDatetime, + bot.multiPeriodDailyProcessDatetime, contextVariables.dateBeginOfMarket, contextVariables.dateEndOfMarket, interExecutionMemoryArray[n], @@ -632,7 +632,7 @@ return; } - writeStatusReport(bot.processDatetime, advanceTime); + writeStatusReport(bot.multiPeriodDailyProcessDatetime, advanceTime); } catch (err) { logger.write(MODULE_NAME, "[ERROR] start -> processTimePeriods -> controlLoop -> onWritten -> err = ", err); @@ -667,7 +667,7 @@ let folderName = bot.products[productIndex].codeName; - writeDataRange(contextVariables.dateBeginOfMarket, bot.processDatetime, folderName, controlLoop); + writeDataRange(contextVariables.dateBeginOfMarket, bot.multiPeriodDailyProcessDatetime, folderName, controlLoop); } function controlLoop() { diff --git a/Root.js b/Root.js index 4d239d6a6..1c230da11 100644 --- a/Root.js +++ b/Root.js @@ -243,6 +243,12 @@ processConfig.framework.startDate.resumeExecution = false; } } + if (processConfig.startMode.live !== undefined) { + if (processConfig.startMode.live.beginDatetime !== undefined) { + processConfig.framework.startDate.fixedDate = processConfig.startMode.live.beginDatetime; + processConfig.framework.startDate.resumeExecution = false; + } + } } } diff --git a/Run.js b/Run.js index d24efc791..bbbb3cb21 100644 --- a/Run.js +++ b/Run.js @@ -41,7 +41,9 @@ function readExecutionConfiguration() { if (process.env.TYPE === 'Trading' || process.env.TYPE === 'Trading-Engine') { let live = { run: "false", - resumeExecution: process.env.RESUME_EXECUTION + resumeExecution: process.env.RESUME_EXECUTION, + beginDatetime: process.env.BEGIN_DATE_TIME, + endDatetime: process.env.END_DATE_TIME } let backtest = { diff --git a/TradingEngineProcessMainLoop.js b/TradingEngineProcessMainLoop.js index c18976064..a156cf1c1 100644 --- a/TradingEngineProcessMainLoop.js +++ b/TradingEngineProcessMainLoop.js @@ -666,7 +666,7 @@ case global.DEFAULT_OK_RESPONSE.result: { logger.write(MODULE_NAME, "[INFO] run -> loop -> startProcessFramework -> onFinished -> Execution finished well."); nextWaitTime = 'Normal'; - loopControl(nextWaitTime); + 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. @@ -778,6 +778,83 @@ } } + 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'; + loopControl(nextWaitTime); + 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); + 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); + logger.persist(); + clearInterval(fixedTimeLoopIntervalHandle); + clearTimeout(nextLoopTimeoutHandle); + clearTimeout(checkLoopHealthHandle); + bot.enableCheckLoopHealth = false; + callBackFunction(err); + } + } + function loopControl(nextWaitTime) { if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] run -> loop -> loopControl -> Entering function."); }