diff --git a/Commons.js b/Commons.js index bea993f51..5037502fe 100644 --- a/Commons.js +++ b/Commons.js @@ -2,8 +2,6 @@ const FULL_LOG = true; const LOG_FILE_CONTENT = false; - const ONE_DAY_IN_MILISECONDS = 24 * 60 * 60 * 1000; - const ONE_MIN_IN_MILISECONDS = 60 * 1000; const MODULE_NAME = "Commons"; @@ -199,7 +197,7 @@ let system = { // These are the available system variables to be used in User Code and Formulas timeFrame: timeFrame, - ONE_DAY_IN_MILISECONDS: ONE_DAY_IN_MILISECONDS + ONE_DAY_IN_MILISECONDS: global.ONE_DAY_IN_MILISECONDS } let variable = {} // This is the structure where the user will define its own variables that will be shared across different code blocks and formulas. let results = [] @@ -290,8 +288,8 @@ let yesterday = {} let system = { // These are the available system variables to be used in User Code and Formulas timeFrame: timeFrame, - ONE_DAY_IN_MILISECONDS: ONE_DAY_IN_MILISECONDS, - ONE_MIN_IN_MILISECONDS: ONE_MIN_IN_MILISECONDS + ONE_DAY_IN_MILISECONDS: global.ONE_DAY_IN_MILISECONDS, + ONE_MIN_IN_MILISECONDS: global.ONE_MIN_IN_MILISECONDS } let variable = {} // This is the structure where the user will define its own variables that will be shared across different code blocks and formulas. let results = [] @@ -340,7 +338,7 @@ if (processingDailyFiles) { /* Initialization of Last Instance */ - lastInstantOfTheDay = currentDay.valueOf() + ONE_DAY_IN_MILISECONDS - 1; + lastInstantOfTheDay = currentDay.valueOf() + global.ONE_DAY_IN_MILISECONDS - 1; if (interExecutionMemory[productName] === undefined) { /* The first time the intialization variables goes to the Inter Execution Memory. */ @@ -457,7 +455,7 @@ at the next day, in whole, even if it starts in the previous day. */ - let lastInstantOdDay = currentDay.valueOf() + ONE_DAY_IN_MILISECONDS - 1; + let lastInstantOdDay = currentDay.valueOf() + global.ONE_DAY_IN_MILISECONDS - 1; if (record.end < currentDay.valueOf() - 1) { continue; } if (record.end === lastInstantOdDay) { continue; } diff --git a/IndicatorOutput.js b/IndicatorOutput.js index 9a1a9b95b..3faa4052e 100644 --- a/IndicatorOutput.js +++ b/IndicatorOutput.js @@ -1,9 +1,5 @@ exports.newIndicatorOutput = function newIndicatorOutput(bot, logger, UTILITIES, FILE_STORAGE) { - const FULL_LOG = true; - const LOG_FILE_CONTENT = false; - const ONE_DAY_IN_MILISECONDS = 24 * 60 * 60 * 1000; - const MODULE_NAME = "Indicator Bot"; let thisObject = { diff --git a/LowFrequencyTrading/TradingEngine.js b/LowFrequencyTrading/TradingEngine.js index 4f61a7282..1c35bd47c 100644 --- a/LowFrequencyTrading/TradingEngine.js +++ b/LowFrequencyTrading/TradingEngine.js @@ -16,6 +16,7 @@ exports.newTradingEngine = function newTradingEngine(bot, logger) { } let tradingEngine + let sessionParameters return thisObject @@ -23,6 +24,7 @@ exports.newTradingEngine = function newTradingEngine(bot, logger) { /* Here we will go through all the nodes in the Trading Engine hiriarchy and apply the initial value to the value property when needed */ tradingEngine = bot.simulationState.tradingEngine + sessionParameters = bot.SESSION.parameters if (tradingEngine.isInitialized !== true || bot.RESUME === false) { tradingEngine.isInitialized = true @@ -32,6 +34,7 @@ exports.newTradingEngine = function newTradingEngine(bot, logger) { function finalize() { tradingEngine = undefined + sessionParameters = undefined } function setCurrentCandle(candle) { @@ -131,7 +134,7 @@ exports.newTradingEngine = function newTradingEngine(bot, logger) { function updateEpisodeCountersAndStatistics() { tradingEngine.episode.episodeCounters.periods++ - tradingEngine.episode.episodeStatistics.days = tradingEngine.episode.episodeCounters.periods * sessionParameters.timeFrame.config.value / ONE_DAY_IN_MILISECONDS + tradingEngine.episode.episodeStatistics.days = tradingEngine.episode.episodeCounters.periods * sessionParameters.timeFrame.config.value / global.ONE_DAY_IN_MILISECONDS } function updatePositionCountersAndStatistics() { @@ -144,7 +147,7 @@ exports.newTradingEngine = function newTradingEngine(bot, logger) { } tradingEngine.current.position.positionCounters.periods.value++ - tradingEngine.current.position.positionStatistics.days.value = tradingEngine.current.position.positionCounters.periods.value * sessionParameters.timeFrame.config.value / ONE_DAY_IN_MILISECONDS + tradingEngine.current.position.positionStatistics.days.value = tradingEngine.current.position.positionCounters.periods.value * sessionParameters.timeFrame.config.value / global.ONE_DAY_IN_MILISECONDS } else { tradingEngine.current.position.positionCounters.periods.value = 0 tradingEngine.current.position.positionStatistics.days.value = 0 diff --git a/LowFrequencyTrading/TradingExecution.js b/LowFrequencyTrading/TradingExecution.js index b8343c0d7..169b1f3b6 100644 --- a/LowFrequencyTrading/TradingExecution.js +++ b/LowFrequencyTrading/TradingExecution.js @@ -86,7 +86,7 @@ exports.newTradingExecution = function newTradingExecution(bot, logger) { /* We wont take a position unless we are withing the sessionParameters.timeRange.config.initialDatetime and the sessionParameters.timeRange.config.finalDatetime range */ if (sessionParameters.timeRange.config.initialDatetime !== undefined) { - if (candle.end < sessionParameters.timeRange.config.initialDatetime.valueOf()) { + if (candle.end < sessionParameters.timeRange.config.initialDatetime) { if (FULL_LOG === true) { logger.write(MODULE_NAME, '[INFO] runSimulation -> loop -> putOpeningOrder -> Not placing the trade at the exchange because current candle ends before the start date. -> sessionParameters.timeRange.config.initialDatetime = ' + sessionParameters.timeRange.config.initialDatetime) } takePositionAtSimulation() return @@ -95,7 +95,7 @@ exports.newTradingExecution = function newTradingExecution(bot, logger) { /* We wont take a position if we are past the final datetime */ if (sessionParameters.timeRange.config.finalDatetime !== undefined) { - if (candle.begin > sessionParameters.timeRange.config.finalDatetime.valueOf()) { + if (candle.begin > sessionParameters.timeRange.config.finalDatetime) { if (FULL_LOG === true) { logger.write(MODULE_NAME, '[INFO] runSimulation -> putOpeningOrder -> Not placing the trade at the exchange because current candle begins after the end date. -> sessionParameters.timeRange.config.finalDatetime = ' + sessionParameters.timeRange.config.finalDatetime) } takePositionAtSimulation() return @@ -115,8 +115,8 @@ exports.newTradingExecution = function newTradingExecution(bot, logger) { /* We are not going to place orders based on outdated information. The next filter prevents firing orders when backtesting. */ if (currentDay) { - let today = new Date(Math.trunc((new Date().valueOf()) / ONE_DAY_IN_MILISECONDS) * ONE_DAY_IN_MILISECONDS) - let processDay = new Date(Math.trunc(currentDay.valueOf() / ONE_DAY_IN_MILISECONDS) * ONE_DAY_IN_MILISECONDS) + let today = new Date(Math.trunc((new Date().valueOf()) / global.ONE_DAY_IN_MILISECONDS) * global.ONE_DAY_IN_MILISECONDS) + let processDay = new Date(Math.trunc(currentDay.valueOf() / global.ONE_DAY_IN_MILISECONDS) * global.ONE_DAY_IN_MILISECONDS) if (today.valueOf() !== processDay.valueOf()) { if (FULL_LOG === true) { logger.write(MODULE_NAME, '[INFO] runSimulation -> loop -> putOpeningOrder -> Not placing the trade at the exchange because the current candle belongs to the previous day and that is considered simulation and not live trading.') } if (FULL_LOG === true) { logger.write(MODULE_NAME, '[INFO] runSimulation -> loop -> putOpeningOrder -> today = ' + today) } diff --git a/LowFrequencyTrading/TradingProcess.js b/LowFrequencyTrading/TradingProcess.js index e900ade5c..b9a1c10f0 100644 --- a/LowFrequencyTrading/TradingProcess.js +++ b/LowFrequencyTrading/TradingProcess.js @@ -8,7 +8,6 @@ const LOG_FILE_CONTENT = false; const MODULE_NAME = "Trading Process"; const GMT_SECONDS = ':00.000 GMT+0000'; - const ONE_DAY_IN_MILISECONDS = 24 * 60 * 60 * 1000; thisObject = { initialize: initialize, @@ -125,7 +124,7 @@ contextVariables.dateEndOfMarket = new Date(thisReport.lastFile.valueOf()); /* Validation that the data is not up-to-date. */ - if (bot.tradingProcessDate.valueOf() - ONE_DAY_IN_MILISECONDS > contextVariables.dateEndOfMarket.valueOf() && bot.SESSION.type !== "Backtesting Session") { + if (bot.tradingProcessDate.valueOf() - global.ONE_DAY_IN_MILISECONDS > contextVariables.dateEndOfMarket.valueOf() && bot.SESSION.type !== "Backtesting Session") { if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] start -> getContextVariables -> " + "Head of the market is @ " + contextVariables.dateEndOfMarket); } if (FULL_LOG === true) { logger.write(MODULE_NAME, "[ERROR] start -> getContextVariables -> You need to UPDATE your datasets in order to run a " + bot.SESSION.type) } @@ -359,12 +358,12 @@ buildCharts() return } - bot.tradingProcessDate = 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.tradingProcessDate = new Date(contextVariables.lastFile.valueOf() - global.ONE_DAY_IN_MILISECONDS); // Go back one day to start well when we advance time at the begining of the loop. advanceTime(); function advanceTime() { - bot.tradingProcessDate = new Date(bot.tradingProcessDate.valueOf() + ONE_DAY_IN_MILISECONDS); - previousDay = new Date(bot.tradingProcessDate.valueOf() - ONE_DAY_IN_MILISECONDS); + bot.tradingProcessDate = new Date(bot.tradingProcessDate.valueOf() + global.ONE_DAY_IN_MILISECONDS); + previousDay = new Date(bot.tradingProcessDate.valueOf() - global.ONE_DAY_IN_MILISECONDS); if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] start -> processDailyFiles -> advanceTime -> bot.tradingProcessDate = " + bot.tradingProcessDate); } if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] start -> processDailyFiles -> advanceTime -> previousDay = " + previousDay); } @@ -381,7 +380,7 @@ } /* Validation that we are not going past the head of the market. */ - if (bot.tradingProcessDate.valueOf() > contextVariables.dateEndOfMarket.valueOf() + ONE_DAY_IN_MILISECONDS - 1) { + if (bot.tradingProcessDate.valueOf() > contextVariables.dateEndOfMarket.valueOf() + global.ONE_DAY_IN_MILISECONDS - 1) { const logText = "Head of the market found @ " + previousDay.getUTCFullYear() + "/" + (previousDay.getUTCMonth() + 1) + "/" + previousDay.getUTCDate() + "."; if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] start -> processDailyFiles -> advanceTime -> " + logText); } @@ -674,7 +673,7 @@ function writeDataRange(pBegin, pEnd, productCodeName, currentTimeFrameLabel, callBack) { let dataRange = { begin: pBegin.valueOf(), - end: pEnd.valueOf() + ONE_DAY_IN_MILISECONDS + end: pEnd.valueOf() + global.ONE_DAY_IN_MILISECONDS }; let fileContent = JSON.stringify(dataRange); diff --git a/LowFrequencyTrading/TradingSimulation.js b/LowFrequencyTrading/TradingSimulation.js index 77a0d7e63..59192b43d 100644 --- a/LowFrequencyTrading/TradingSimulation.js +++ b/LowFrequencyTrading/TradingSimulation.js @@ -1,6 +1,5 @@ exports.newTradingSimulation = function newTradingSimulation(bot, logger, UTILITIES) { const FULL_LOG = true - const ONE_DAY_IN_MILISECONDS = 24 * 60 * 60 * 1000 const MODULE_NAME = 'Trading Simulation -> ' + bot.SESSION.name let thisObject = { @@ -110,7 +109,7 @@ exports.newTradingSimulation = function newTradingSimulation(bot, logger, UTILIT } else { /* Estimate Initial Candle based on the timeRage configured for the session. */ let firstEnd = candles[0].end - let targetEnd = sessionParameters.timeRange.config.initialDatetime.valueOf() + let targetEnd = sessionParameters.timeRange.config.initialDatetime let diff = targetEnd - firstEnd let amount = diff / sessionParameters.timeFrame.config.value @@ -143,13 +142,13 @@ exports.newTradingSimulation = function newTradingSimulation(bot, logger, UTILIT return } - if (checkInitialAndFinalDatetime() === false) { + if (checkMinimunAndMaximunBalance() === false) { afterLoop() return } - if (checkMinimunAndMaximunBalance() === false) { - afterLoop() + if (checkInitialAndFinalDatetime() === false) { + controlLoop() return } @@ -276,15 +275,15 @@ exports.newTradingSimulation = function newTradingSimulation(bot, logger, UTILIT function heartBeat() { /* We will produce a simulation level heartbeat in order to inform the user this is running. */ - heartBeatDate = new Date(Math.trunc(candle.begin / ONE_DAY_IN_MILISECONDS) * ONE_DAY_IN_MILISECONDS) + heartBeatDate = new Date(Math.trunc(tradingEngine.current.candle.begin.value / global.ONE_DAY_IN_MILISECONDS) * global.ONE_DAY_IN_MILISECONDS) if (heartBeatDate.valueOf() !== previousheartBeatDate) { let processingDate = heartBeatDate.getUTCFullYear() + '-' + utilities.pad(heartBeatDate.getUTCMonth() + 1, 2) + '-' + utilities.pad(heartBeatDate.getUTCDate(), 2) if (FULL_LOG === true) { logger.write(MODULE_NAME, '[INFO] runSimulation -> loop -> Simulation ' + bot.sessionKey + ' Loop # ' + tradingEngine.current.candle.index.value + ' @ ' + processingDate) } /* Telling the world we are alive and doing well */ - let fromDate = new Date(sessionParameters.timeRange.config.initialDatetime.valueOf()) - let lastDate = new Date(sessionParameters.timeRange.config.finalDatetime.valueOf()) + let fromDate = new Date(sessionParameters.timeRange.config.initialDatetime) + let lastDate = new Date(sessionParameters.timeRange.config.finalDatetime) let currentDateString = heartBeatDate.getUTCFullYear() + '-' + utilities.pad(heartBeatDate.getUTCMonth() + 1, 2) + '-' + utilities.pad(heartBeatDate.getUTCDate(), 2) let currentDate = new Date(heartBeatDate) @@ -335,7 +334,7 @@ exports.newTradingSimulation = function newTradingSimulation(bot, logger, UTILIT if (dataDependencyNode.referenceParent.config.codeName !== 'Multi-Period-Market') { continue } let singularVariableName = dataDependencyNode.referenceParent.parentNode.config.singularVariableName let pluralVariableName = dataDependencyNode.referenceParent.parentNode.config.pluralVariableName - let currentElement = getElement(thisChart[pluralVariableName], candle, 'Market' + '-' + mapKey + '-' + pluralVariableName) + let currentElement = getElement(thisChart[pluralVariableName], 'Market' + '-' + mapKey + '-' + pluralVariableName) thisChart[singularVariableName] = currentElement } } @@ -358,22 +357,22 @@ exports.newTradingSimulation = function newTradingSimulation(bot, logger, UTILIT } } - function getElement(pArray, currentCandle, datasetName) { + function getElement(pArray, datasetName) { if (pArray === undefined) { return } try { let element for (let i = 0; i < pArray.length; i++) { element = pArray[i] - if (currentCandle.end === element.end) { // when there is an exact match at the end we take that element + if (tradingEngine.current.candle.end.value === element.end) { // when there is an exact match at the end we take that element return element } else { if ( i > 0 && - element.end > currentCandle.end + element.end > tradingEngine.current.candle.end.value ) { let previousElement = pArray[i - 1] - if (previousElement.end < currentCandle.end) { + if (previousElement.end < tradingEngine.current.candle.end.value) { return previousElement // If one elements goes into the future of currentCandle, then we stop and take the previous element. } else { return @@ -395,7 +394,7 @@ exports.newTradingSimulation = function newTradingSimulation(bot, logger, UTILIT when we are processing Market Files than when we are processing Daily Files. TODO Check that the procedure is good for Beta 6 */ if (bot.processingDailyFiles) { // We are processing Daily Files - let candlesPerDay = ONE_DAY_IN_MILISECONDS / sessionParameters.timeFrame.config.value + let candlesPerDay = global.ONE_DAY_IN_MILISECONDS / sessionParameters.timeFrame.config.value if (tradingEngine.current.candle.index.value === candles.length - 1) { if ((candles.length < candlesPerDay) || (candles.length > candlesPerDay && candles.length < candlesPerDay * 2)) { if (FULL_LOG === true) { logger.write(MODULE_NAME, '[INFO] runSimulation -> checkIfWeAreAtTheHeadOfTheMarket -> Skipping Candle because it is the last one and has not been closed yet.') } @@ -417,11 +416,11 @@ exports.newTradingSimulation = function newTradingSimulation(bot, logger, UTILIT function checkInitialAndFinalDatetime() { /* Here we check that the current candle is not outside of user-defined time range at the session parameters.*/ - if (tradingEngine.current.candle.end.value < sessionParameters.timeRange.config.initialDatetime.valueOf()) { + if (tradingEngine.current.candle.end.value < sessionParameters.timeRange.config.initialDatetime) { if (FULL_LOG === true) { logger.write(MODULE_NAME, '[INFO] runSimulation -> checkInitialAndFinalDatetime -> Skipping Candle before the sessionParameters.timeRange.config.initialDatetime.') } return false } - if (tradingEngine.current.candle.begin.value > sessionParameters.timeRange.config.finalDatetime.valueOf()) { + if (tradingEngine.current.candle.begin.value > sessionParameters.timeRange.config.finalDatetime) { if (FULL_LOG === true) { logger.write(MODULE_NAME, '[INFO] runSimulation -> checkInitialAndFinalDatetime -> Skipping Candle after the sessionParameters.timeRange.config.finalDatetime.') } return false } diff --git a/MultiPeriodDaily.js b/MultiPeriodDaily.js index b26ff1f15..66e2f586d 100644 --- a/MultiPeriodDaily.js +++ b/MultiPeriodDaily.js @@ -4,7 +4,6 @@ const LOG_FILE_CONTENT = false; const MODULE_NAME = "Multi Period Daily"; const GMT_SECONDS = ':00.000 GMT+0000'; - const ONE_DAY_IN_MILISECONDS = 24 * 60 * 60 * 1000; thisObject = { initialize: initialize, diff --git a/server.js b/server.js index b40e410e0..50f2d662c 100644 --- a/server.js +++ b/server.js @@ -27,7 +27,8 @@ global.CUSTOM_FAIL_RESPONSE = { global.ROOT_DIR = './'; -const ONE_DAY_IN_MILISECONDS = 24 * 60 * 60 * 1000; +global.ONE_DAY_IN_MILISECONDS = 24 * 60 * 60 * 1000 +global.ONE_MIN_IN_MILISECONDS = 60 * 1000 global.LOGGER_MAP = new Map() global.SESSION_MAP = new Map() @@ -316,9 +317,9 @@ function startRoot(processIndex) { } global.getPercentage = function (fromDate, currentDate, lastDate) { - let fromDays = Math.trunc(fromDate.valueOf() / ONE_DAY_IN_MILISECONDS) - let currentDays = Math.trunc(currentDate.valueOf() / ONE_DAY_IN_MILISECONDS) - let lastDays = Math.trunc(lastDate.valueOf() / ONE_DAY_IN_MILISECONDS) + let fromDays = Math.trunc(fromDate.valueOf() / global.ONE_DAY_IN_MILISECONDS) + let currentDays = Math.trunc(currentDate.valueOf() / global.ONE_DAY_IN_MILISECONDS) + let lastDays = Math.trunc(lastDate.valueOf() / global.ONE_DAY_IN_MILISECONDS) let percentage = (currentDays - fromDays) * 100 / (lastDays - fromDays) if ((lastDays - fromDays) === 0) { percentage = 100 @@ -327,8 +328,8 @@ global.getPercentage = function (fromDate, currentDate, lastDate) { } global.areEqualDates = function (date1, date2) { - let day1Days = Math.trunc(date1.valueOf() / ONE_DAY_IN_MILISECONDS) - let day2Days = Math.trunc(date2.valueOf() / ONE_DAY_IN_MILISECONDS) + let day1Days = Math.trunc(date1.valueOf() / global.ONE_DAY_IN_MILISECONDS) + let day2Days = Math.trunc(date2.valueOf() / global.ONE_DAY_IN_MILISECONDS) if (day1Days === day2Days) { return true