diff --git a/Projects/Ethereum/UI/Function-Libraries/Accounts.js b/Projects/Ethereum/UI/Function-Libraries/Accounts.js index 0b4ae2901..d84df1548 100644 --- a/Projects/Ethereum/UI/Function-Libraries/Accounts.js +++ b/Projects/Ethereum/UI/Function-Libraries/Accounts.js @@ -1,5 +1,5 @@ function newEthereumFunctionLibraryAccounts() { - thisObject = { + let thisObject = { createWalletAccount: createWalletAccount } diff --git a/Projects/Ethereum/UI/Globals/ChainIds.js b/Projects/Ethereum/UI/Globals/ChainIds.js index 7ad313118..e17cf4226 100644 --- a/Projects/Ethereum/UI/Globals/ChainIds.js +++ b/Projects/Ethereum/UI/Globals/ChainIds.js @@ -1,5 +1,5 @@ function newEthereumGlobalsChainIds() { - thisObject = { + let thisObject = { chainNameById: chainNameById } return thisObject diff --git a/Projects/Ethereum/UI/Utilities/RouteToClient.js b/Projects/Ethereum/UI/Utilities/RouteToClient.js index 870e82e51..a371b08b9 100644 --- a/Projects/Ethereum/UI/Utilities/RouteToClient.js +++ b/Projects/Ethereum/UI/Utilities/RouteToClient.js @@ -1,5 +1,5 @@ function newEthereumUtilitiesRouteToClient() { - thisObject = { + let thisObject = { buildRouteToClient: buildRouteToClient } diff --git a/Projects/Superalgos/Bots-Plotters-Code/Masters/plotters/Plotters-Bollinger-Bands/BollingerBandsPanel.js b/Projects/Superalgos/Bots-Plotters-Code/Masters/plotters/Plotters-Bollinger-Bands/BollingerBandsPanel.js index 0cf50836d..95820ef17 100644 --- a/Projects/Superalgos/Bots-Plotters-Code/Masters/plotters/Plotters-Bollinger-Bands/BollingerBandsPanel.js +++ b/Projects/Superalgos/Bots-Plotters-Code/Masters/plotters/Plotters-Bollinger-Bands/BollingerBandsPanel.js @@ -1,7 +1,7 @@  function newMastersPlottersBollingerBandsBollingerBandsBollingerBandsPanel() { - var thisObject = { + let thisObject = { fitFunction: undefined, onRecordChange: onRecordChange, container: undefined, diff --git a/Projects/Superalgos/TS/Bot-Modules/API-Data-Fetcher-Bot/FetchingProcess.js b/Projects/Superalgos/TS/Bot-Modules/API-Data-Fetcher-Bot/FetchingProcess.js index 8aeca5a58..9b64f7db6 100644 --- a/Projects/Superalgos/TS/Bot-Modules/API-Data-Fetcher-Bot/FetchingProcess.js +++ b/Projects/Superalgos/TS/Bot-Modules/API-Data-Fetcher-Bot/FetchingProcess.js @@ -3,7 +3,7 @@ exports.newSuperalgosBotModulesFetchingProcess = function (processIndex) { const MODULE_NAME = "Fetching Process"; - thisObject = { + let thisObject = { initialize: initialize, start: start }; diff --git a/Projects/Superalgos/TS/Bot-Modules/Indicator-Bot/Bollinger-Bands/BollingerBandsMultiPeriodDaily.js b/Projects/Superalgos/TS/Bot-Modules/Indicator-Bot/Bollinger-Bands/BollingerBandsMultiPeriodDaily.js index 3e2de2c82..6555f101a 100644 --- a/Projects/Superalgos/TS/Bot-Modules/Indicator-Bot/Bollinger-Bands/BollingerBandsMultiPeriodDaily.js +++ b/Projects/Superalgos/TS/Bot-Modules/Indicator-Bot/Bollinger-Bands/BollingerBandsMultiPeriodDaily.js @@ -5,7 +5,7 @@ const BOLLINGER_BANDS_FOLDER_NAME = "Bollinger-Bands" const PERCENTAGE_BANDWIDTH_FOLDER_NAME = "Percentage-Bandwidth" - thisObject = { + let thisObject = { initialize: initialize, start: start }; diff --git a/Projects/Superalgos/TS/Bot-Modules/Indicator-Bot/Bollinger-Bands/BollingerBandsMultiPeriodMarket.js b/Projects/Superalgos/TS/Bot-Modules/Indicator-Bot/Bollinger-Bands/BollingerBandsMultiPeriodMarket.js index 327d05ec8..f178fd35c 100644 --- a/Projects/Superalgos/TS/Bot-Modules/Indicator-Bot/Bollinger-Bands/BollingerBandsMultiPeriodMarket.js +++ b/Projects/Superalgos/TS/Bot-Modules/Indicator-Bot/Bollinger-Bands/BollingerBandsMultiPeriodMarket.js @@ -5,7 +5,7 @@ const BOLLINGER_BANDS_FOLDER_NAME = "Bollinger-Bands" const PERCENTAGE_BANDWIDTH_FOLDER_NAME = "Percentage-Bandwidth" - thisObject = { + let thisObject = { initialize: initialize, start: start } diff --git a/Projects/Superalgos/TS/Bot-Modules/Indicator-Bot/Candles-Volumes/CandlesVolumesMultiPeriodDaily.js b/Projects/Superalgos/TS/Bot-Modules/Indicator-Bot/Candles-Volumes/CandlesVolumesMultiPeriodDaily.js index a3b457058..c651d67ac 100644 --- a/Projects/Superalgos/TS/Bot-Modules/Indicator-Bot/Candles-Volumes/CandlesVolumesMultiPeriodDaily.js +++ b/Projects/Superalgos/TS/Bot-Modules/Indicator-Bot/Candles-Volumes/CandlesVolumesMultiPeriodDaily.js @@ -6,7 +6,7 @@ const VOLUMES_FOLDER_NAME = "Volumes"; const VOLUMES_ONE_MIN = "One-Min"; - thisObject = { + let thisObject = { initialize: initialize, start: start } diff --git a/Projects/Superalgos/TS/Bot-Modules/Indicator-Bot/Candles-Volumes/CandlesVolumesMultiPeriodMarket.js b/Projects/Superalgos/TS/Bot-Modules/Indicator-Bot/Candles-Volumes/CandlesVolumesMultiPeriodMarket.js index c364223c9..52b6da409 100644 --- a/Projects/Superalgos/TS/Bot-Modules/Indicator-Bot/Candles-Volumes/CandlesVolumesMultiPeriodMarket.js +++ b/Projects/Superalgos/TS/Bot-Modules/Indicator-Bot/Candles-Volumes/CandlesVolumesMultiPeriodMarket.js @@ -6,7 +6,7 @@ const VOLUMES_FOLDER_NAME = "Volumes" const VOLUMES_ONE_MIN = "One-Min" - thisObject = { + let thisObject = { initialize: initialize, start: start } @@ -270,8 +270,8 @@ try { let n = 0 // loop Variable representing each possible period as defined at the periods array. - let allPreviousCandles = []; - let allPreviousVolumes = []; + let allPreviousCandles = [] // Each item of this array is an array of candles for a certain time frame + let allPreviousVolumes = [] // Each item of this array is an array of volumes for a certain time frame loopBody() @@ -414,6 +414,12 @@ advanceTime() function advanceTime() { + /* + We position ourselves on the latest date that was added to the market files + since we are going to re-process that date, removing first the elements of that + date and then adding again all the elements found right now at that date and then + from there into the future. + */ contextVariables.datetimeLastProducedFile = new Date(contextVariables.datetimeLastProducedFile.valueOf() + TS.projects.superalgos.globals.timeConstants.ONE_DAY_IN_MILISECONDS); TS.projects.superalgos.globals.loggerVariables.VARIABLES_BY_PROCESS_INDEX_MAP.get(processIndex).BOT_MAIN_LOOP_LOGGER_MODULE_OBJECT.write(MODULE_NAME, @@ -453,8 +459,9 @@ loopBody() function loopBody() { - let previousCandles + let previousCandles // This is an array with all the elements already existing for a certain time frame. let previousVolumes + if (allPreviousCandles !== undefined) { previousCandles = allPreviousCandles[n]; previousVolumes = allPreviousVolumes[n]; @@ -464,17 +471,19 @@ const timeFrame = TS.projects.superalgos.globals.timeFrames.marketFilesPeriods()[n][1]; /* Here we are inside a Loop that is going to advance 1 day at the time, - at each pass, will read one of Exchange Raw Data's daily files and - add all its candles to our in memory arrays. At the first iteration - of this loop, we will add the candles that we are carrying + at each pass, we will read one of Exchange Raw Data's daily files and + add all its candles to our in memory arrays. + + At the first iteration of this loop, we will add the candles that we are carrying from our previous run, the ones we already have in-memory. - You can see below how we discard from those candles the ones that - are belonging to the first day we are processing at this run, - that it is exactly the same as the last day processed the privious + + You can see below how we discard the elements that + belong to the first day we are processing at this run, + that it is exactly the same as the last day processed the previous run. By discarding these candles, we are ready to run after that standard function that will just add ALL the candles found each day at Exchange Raw Data. */ - if (previousCandles !== undefined) { + if (previousCandles !== undefined && previousCandles.length !== 0) { for (let i = 0; i < previousCandles.length; i++) { let candle = { open: previousCandles[i][2], @@ -495,7 +504,7 @@ allPreviousCandles[n] = [] // erasing these so as not to duplicate them. } - if (previousVolumes !== undefined) { + if (previousVolumes !== undefined && previousVolumes.length !== 0) { for (let i = 0; i < previousVolumes.length; i++) { let volume = { @@ -517,8 +526,10 @@ allPreviousVolumes[n] = []; // erasing these so as not to duplicate them. } /* - From here on is where every iteration of the loop fully runs. Here is where we read Exchange Raw Data's files and add their content to whatever - we already have in our arrays in-memory. In this way the process will run as many days needed and it should only stop when it reaches + From here on is where every iteration of the loop fully runs. Here is where we + read Exchange Raw Data's files and add their content to whatever + we already have in our arrays in-memory. In this way the process will run as + many days needed and it should only stop when it reaches the head of the market. */ nextCandleFile(); diff --git a/Projects/Superalgos/TS/Bot-Modules/Indicator-Bot/FromOneMinToMultiPeriodDaily.js b/Projects/Superalgos/TS/Bot-Modules/Indicator-Bot/FromOneMinToMultiPeriodDaily.js new file mode 100644 index 000000000..8ba77e42e --- /dev/null +++ b/Projects/Superalgos/TS/Bot-Modules/Indicator-Bot/FromOneMinToMultiPeriodDaily.js @@ -0,0 +1,763 @@ +exports.newSuperalgosBotModulesCandlesVolumesMultiPeriodDaily = function (processIndex) { + + const MODULE_NAME = "Candles Volumes Multi Period Daily"; + const CANDLES_FOLDER_NAME = "Candles"; + const CANDLES_ONE_MIN = "One-Min"; + const VOLUMES_FOLDER_NAME = "Volumes"; + const VOLUMES_ONE_MIN = "One-Min"; + + let thisObject = { + initialize: initialize, + start: start + } + + let fileStorage = TS.projects.superalgos.taskModules.fileStorage.newFileStorage(processIndex) + let statusDependencies; + let beginingOfMarket + + return thisObject; + + function initialize(pStatusDependencies, callBackFunction) { + try { + statusDependencies = pStatusDependencies + callBackFunction(TS.projects.superalgos.globals.standardResponses.DEFAULT_OK_RESPONSE) + + } catch (err) { + TS.projects.superalgos.globals.processVariables.VARIABLES_BY_PROCESS_INDEX_MAP.get(processIndex).UNEXPECTED_ERROR = err + TS.projects.superalgos.globals.loggerVariables.VARIABLES_BY_PROCESS_INDEX_MAP.get(processIndex).BOT_MAIN_LOOP_LOGGER_MODULE_OBJECT.write(MODULE_NAME, + "[ERROR] initialize -> err = " + err.stack) + callBackFunction(TS.projects.superalgos.globals.standardResponses.DEFAULT_FAIL_RESPONSE) + } + } + /* + This process is going to do the following: + Read the candles and volumes from Exchange Raw Data and produce a + file for each day and for each period with candles and volumes. + */ + function start(callBackFunction) { + try { + /* Context Variables */ + let contextVariables = { + datetimeLastProducedFile: undefined, // Datetime of the last file files successfully produced by this process. + datetimeBeginingOfMarketFile: undefined, // Datetime of the first trade file in the whole market history. + datetimeLastAvailableDependencyFile: undefined // Datetime of the last file available to be used as an input of this process. + }; + + getContextVariables(); + + function getContextVariables() { + try { + let thisReport; + let reportKey; + let statusReport; + + /* We look first for Exchange Raw Data in order to get when the market starts. */ + reportKey = "Masters" + "-" + "Exchange-Raw-Data" + "-" + "Historic-OHLCVs" + TS.projects.superalgos.globals.loggerVariables.VARIABLES_BY_PROCESS_INDEX_MAP.get(processIndex).BOT_MAIN_LOOP_LOGGER_MODULE_OBJECT.write(MODULE_NAME, + "[INFO] start -> getContextVariables -> reportKey = " + reportKey) + + statusReport = statusDependencies.statusReports.get(reportKey); + if (statusReport === undefined) { // This means the status report does not exist, that could happen for instance at the begining of a month. + TS.projects.superalgos.globals.loggerVariables.VARIABLES_BY_PROCESS_INDEX_MAP.get(processIndex).BOT_MAIN_LOOP_LOGGER_MODULE_OBJECT.write(MODULE_NAME, + "[WARN] start -> getContextVariables -> Status Report does not exist. Retrying Later. "); + callBackFunction(TS.projects.superalgos.globals.standardResponses.DEFAULT_RETRY_RESPONSE); + return; + } + + if (statusReport.status === "Status Report is corrupt.") { + TS.projects.superalgos.globals.loggerVariables.VARIABLES_BY_PROCESS_INDEX_MAP.get(processIndex).BOT_MAIN_LOOP_LOGGER_MODULE_OBJECT.write(MODULE_NAME, + "[ERROR] start -> getContextVariables -> Can not continue because dependecy Status Report is corrupt. "); + callBackFunction(TS.projects.superalgos.globals.standardResponses.DEFAULT_RETRY_RESPONSE); + return; + } + + thisReport = statusDependencies.statusReports.get(reportKey).file; + if (thisReport.beginingOfMarket === undefined) { + TS.projects.superalgos.globals.loggerVariables.VARIABLES_BY_PROCESS_INDEX_MAP.get(processIndex).BOT_MAIN_LOOP_LOGGER_MODULE_OBJECT.write(MODULE_NAME, + "[WARN] start -> getContextVariables -> Undefined Last File. -> reportKey = " + reportKey); + TS.projects.superalgos.globals.loggerVariables.VARIABLES_BY_PROCESS_INDEX_MAP.get(processIndex).BOT_MAIN_LOOP_LOGGER_MODULE_OBJECT.write(MODULE_NAME, + "[HINT] start -> getContextVariables -> It is too early too run this process since the trade history of the market is not there yet."); + + let customOK = { + result: TS.projects.superalgos.globals.standardResponses.CUSTOM_OK_RESPONSE.result, + message: "Dependency does not exist." + } + TS.projects.superalgos.globals.loggerVariables.VARIABLES_BY_PROCESS_INDEX_MAP.get(processIndex).BOT_MAIN_LOOP_LOGGER_MODULE_OBJECT.write(MODULE_NAME, + "[WARN] start -> getContextVariables -> customOK = " + customOK.message) + callBackFunction(customOK) + return + } + + contextVariables.datetimeBeginingOfMarketFile = new Date( + thisReport.beginingOfMarket.year + "-" + + thisReport.beginingOfMarket.month + "-" + + thisReport.beginingOfMarket.days + " " + + thisReport.beginingOfMarket.hours + ":" + + thisReport.beginingOfMarket.minutes + + TS.projects.superalgos.globals.timeConstants.GMT_SECONDS) + + /* Second, we get the report from Exchange Raw Data, to know when the marted ends. */ + reportKey = "Masters" + "-" + "Exchange-Raw-Data" + "-" + "Historic-OHLCVs" + TS.projects.superalgos.globals.loggerVariables.VARIABLES_BY_PROCESS_INDEX_MAP.get(processIndex).BOT_MAIN_LOOP_LOGGER_MODULE_OBJECT.write(MODULE_NAME, + "[INFO] start -> getContextVariables -> reportKey = " + reportKey) + + statusReport = statusDependencies.statusReports.get(reportKey); + if (statusReport === undefined) { // This means the status report does not exist, that could happen for instance at the begining of a month. + TS.projects.superalgos.globals.loggerVariables.VARIABLES_BY_PROCESS_INDEX_MAP.get(processIndex).BOT_MAIN_LOOP_LOGGER_MODULE_OBJECT.write(MODULE_NAME, + "[WARN] start -> getContextVariables -> Status Report does not exist. Retrying Later. "); + callBackFunction(TS.projects.superalgos.globals.standardResponses.DEFAULT_RETRY_RESPONSE); + return + } + + if (statusReport.status === "Status Report is corrupt.") { + TS.projects.superalgos.globals.loggerVariables.VARIABLES_BY_PROCESS_INDEX_MAP.get(processIndex).BOT_MAIN_LOOP_LOGGER_MODULE_OBJECT.write(MODULE_NAME, + "[ERROR] start -> getContextVariables -> Can not continue because dependecy Status Report is corrupt. "); + callBackFunction(TS.projects.superalgos.globals.standardResponses.DEFAULT_RETRY_RESPONSE); + return + } + + thisReport = statusDependencies.statusReports.get(reportKey).file + if (thisReport.lastFile === undefined) { + TS.projects.superalgos.globals.loggerVariables.VARIABLES_BY_PROCESS_INDEX_MAP.get(processIndex).BOT_MAIN_LOOP_LOGGER_MODULE_OBJECT.write(MODULE_NAME, + "[WARN] start -> getContextVariables -> Undefined Last File. -> reportKey = " + reportKey); + + let customOK = { + result: TS.projects.superalgos.globals.standardResponses.CUSTOM_OK_RESPONSE.result, + message: "Dependency not ready." + } + TS.projects.superalgos.globals.loggerVariables.VARIABLES_BY_PROCESS_INDEX_MAP.get(processIndex).BOT_MAIN_LOOP_LOGGER_MODULE_OBJECT.write(MODULE_NAME, + "[WARN] start -> getContextVariables -> customOK = " + customOK.message) + callBackFunction(customOK) + return + } + + contextVariables.datetimeLastAvailableDependencyFile = new Date( + thisReport.lastFile.year + "-" + + thisReport.lastFile.month + "-" + + thisReport.lastFile.days + " " + "00:00" + + TS.projects.superalgos.globals.timeConstants.GMT_SECONDS) + + /* Finally we get our own Status Report. */ + + reportKey = "Masters" + "-" + "Candles-Volumes" + "-" + "Multi-Period-Daily" + TS.projects.superalgos.globals.loggerVariables.VARIABLES_BY_PROCESS_INDEX_MAP.get(processIndex).BOT_MAIN_LOOP_LOGGER_MODULE_OBJECT.write(MODULE_NAME, + "[INFO] start -> getContextVariables -> reportKey = " + reportKey) + + statusReport = statusDependencies.statusReports.get(reportKey) + + if (statusReport === undefined) { // This means the status report does not exist, that could happen for instance at the begining of a month. + TS.projects.superalgos.globals.loggerVariables.VARIABLES_BY_PROCESS_INDEX_MAP.get(processIndex).BOT_MAIN_LOOP_LOGGER_MODULE_OBJECT.write(MODULE_NAME, + "[WARN] start -> getContextVariables -> Status Report does not exist. Retrying Later. ") + callBackFunction(TS.projects.superalgos.globals.standardResponses.DEFAULT_RETRY_RESPONSE) + return + } + + if (statusReport.status === "Status Report is corrupt.") { + TS.projects.superalgos.globals.loggerVariables.VARIABLES_BY_PROCESS_INDEX_MAP.get(processIndex).BOT_MAIN_LOOP_LOGGER_MODULE_OBJECT.write(MODULE_NAME, + "[ERROR] start -> getContextVariables -> Can not continue because self dependecy Status Report is corrupt. Aborting Process.") + callBackFunction(TS.projects.superalgos.globals.standardResponses.DEFAULT_FAIL_RESPONSE) + return + } + + thisReport = statusDependencies.statusReports.get(reportKey).file; + if (thisReport.lastFile !== undefined) { + TS.projects.superalgos.globals.loggerVariables.VARIABLES_BY_PROCESS_INDEX_MAP.get(processIndex).BOT_MAIN_LOOP_LOGGER_MODULE_OBJECT.write(MODULE_NAME, + "[INFO] start -> getContextVariables -> Process Running not for the very first time. -> reportKey = " + reportKey) + + beginingOfMarket = new Date(thisReport.beginingOfMarket) + if (beginingOfMarket.valueOf() !== contextVariables.datetimeBeginingOfMarketFile.valueOf()) { // Reset Mechanism for Begining of the Market + TS.projects.superalgos.globals.loggerVariables.VARIABLES_BY_PROCESS_INDEX_MAP.get(processIndex).BOT_MAIN_LOOP_LOGGER_MODULE_OBJECT.write(MODULE_NAME, + "[INFO] start -> getContextVariables -> Reset Mechanism for Begining of the Market Activated. -> reportKey = " + reportKey); + + beginingOfMarket = new Date(contextVariables.datetimeBeginingOfMarketFile.getUTCFullYear() + "-" + (contextVariables.datetimeBeginingOfMarketFile.getUTCMonth() + 1) + "-" + contextVariables.datetimeBeginingOfMarketFile.getUTCDate() + " " + "00:00" + TS.projects.superalgos.globals.timeConstants.GMT_SECONDS); + contextVariables.datetimeLastProducedFile = new Date( + contextVariables.datetimeBeginingOfMarketFile.getUTCFullYear() + "-" + + (contextVariables.datetimeBeginingOfMarketFile.getUTCMonth() + 1) + "-" + + contextVariables.datetimeBeginingOfMarketFile.getUTCDate() + " " + "00:00" + + TS.projects.superalgos.globals.timeConstants.GMT_SECONDS) + contextVariables.datetimeLastProducedFile = new Date( + contextVariables.datetimeLastProducedFile.valueOf() - + TS.projects.superalgos.globals.timeConstants.ONE_DAY_IN_MILISECONDS) // Go back one day to start well. + + buildCandles() + return + } + + contextVariables.datetimeLastProducedFile = new Date(thisReport.lastFile); + /* + Here we assume that the last day written might contain incomplete information. + This actually happens every time the head of the market is reached. + For that reason we go back one day, the partial information is discarded + and added again with whatever new info is available. + */ + contextVariables.datetimeLastProducedFile = new Date(contextVariables.datetimeLastProducedFile.valueOf() - TS.projects.superalgos.globals.timeConstants.ONE_DAY_IN_MILISECONDS) + buildCandles() + return + + } else { + TS.projects.superalgos.globals.loggerVariables.VARIABLES_BY_PROCESS_INDEX_MAP.get(processIndex).BOT_MAIN_LOOP_LOGGER_MODULE_OBJECT.write(MODULE_NAME, + "[INFO] start -> getContextVariables -> Process Running for the very first time. -> reportKey = " + reportKey); + + beginingOfMarket = new Date( + contextVariables.datetimeBeginingOfMarketFile.getUTCFullYear() + "-" + + (contextVariables.datetimeBeginingOfMarketFile.getUTCMonth() + 1) + "-" + + contextVariables.datetimeBeginingOfMarketFile.getUTCDate() + " " + "00:00" + + TS.projects.superalgos.globals.timeConstants.GMT_SECONDS) + contextVariables.datetimeLastProducedFile = new Date( + contextVariables.datetimeBeginingOfMarketFile.getUTCFullYear() + "-" + + (contextVariables.datetimeBeginingOfMarketFile.getUTCMonth() + 1) + "-" + + contextVariables.datetimeBeginingOfMarketFile.getUTCDate() + " " + "00:00" + + TS.projects.superalgos.globals.timeConstants.GMT_SECONDS) + contextVariables.datetimeLastProducedFile = new Date(contextVariables.datetimeLastProducedFile.valueOf() - TS.projects.superalgos.globals.timeConstants.ONE_DAY_IN_MILISECONDS); // Go back one day to start well. + + buildCandles() + return + } + + } catch (err) { + TS.projects.superalgos.globals.processVariables.VARIABLES_BY_PROCESS_INDEX_MAP.get(processIndex).UNEXPECTED_ERROR = err + TS.projects.superalgos.globals.loggerVariables.VARIABLES_BY_PROCESS_INDEX_MAP.get(processIndex).BOT_MAIN_LOOP_LOGGER_MODULE_OBJECT.write(MODULE_NAME, + "[ERROR] start -> getContextVariables -> err = " + err.stack) + if (err.message === "Cannot read property 'file' of undefined") { + TS.projects.superalgos.globals.loggerVariables.VARIABLES_BY_PROCESS_INDEX_MAP.get(processIndex).BOT_MAIN_LOOP_LOGGER_MODULE_OBJECT.write(MODULE_NAME, + "[HINT] start -> getContextVariables -> Check the bot configuration to see if all of its statusDependencies declarations are correct. "); + TS.projects.superalgos.globals.loggerVariables.VARIABLES_BY_PROCESS_INDEX_MAP.get(processIndex).BOT_MAIN_LOOP_LOGGER_MODULE_OBJECT.write(MODULE_NAME, + "[HINT] start -> getContextVariables -> Dependencies loaded -> keys = " + JSON.stringify(statusDependencies.keys)) + } + callBackFunction(TS.projects.superalgos.globals.standardResponses.DEFAULT_FAIL_RESPONSE) + } + } + + function buildCandles() { + try { + let fromDate = new Date(contextVariables.datetimeLastProducedFile.valueOf()) + let lastDate = TS.projects.superalgos.utilities.dateTimeFunctions.removeTime(new Date()) + let outputCandles + let outputVolumes + + advanceTime() + + function advanceTime() { + contextVariables.datetimeLastProducedFile = new Date(contextVariables.datetimeLastProducedFile.valueOf() + TS.projects.superalgos.globals.timeConstants.ONE_DAY_IN_MILISECONDS); + + TS.projects.superalgos.globals.loggerVariables.VARIABLES_BY_PROCESS_INDEX_MAP.get(processIndex).BOT_MAIN_LOOP_LOGGER_MODULE_OBJECT.write(MODULE_NAME, + "[INFO] start -> buildCandles -> advanceTime -> New processing time @ " + contextVariables.datetimeLastProducedFile.getUTCFullYear() + "/" + (contextVariables.datetimeLastProducedFile.getUTCMonth() + 1) + "/" + contextVariables.datetimeLastProducedFile.getUTCDate() + ".") + + /* Validation that we are not going past the head of the market. */ + if (contextVariables.datetimeLastProducedFile.valueOf() > contextVariables.datetimeLastAvailableDependencyFile.valueOf()) { + TS.projects.superalgos.globals.loggerVariables.VARIABLES_BY_PROCESS_INDEX_MAP.get(processIndex).BOT_MAIN_LOOP_LOGGER_MODULE_OBJECT.write(MODULE_NAME, + "[INFO] start -> buildCandles -> advanceTime -> Head of the market found @ " + contextVariables.datetimeLastProducedFile.getUTCFullYear() + "/" + (contextVariables.datetimeLastProducedFile.getUTCMonth() + 1) + "/" + contextVariables.datetimeLastProducedFile.getUTCDate() + ".") + + callBackFunction(TS.projects.superalgos.globals.standardResponses.DEFAULT_OK_RESPONSE) // Here is where we finish processing and wait for the platform to run this module again. + return + } + /* Telling the world we are alive and doing well */ + let currentDateString = + contextVariables.datetimeLastProducedFile.getUTCFullYear() + '-' + + TS.projects.superalgos.utilities.miscellaneousFunctions.pad(contextVariables.datetimeLastProducedFile.getUTCMonth() + 1, 2) + '-' + + TS.projects.superalgos.utilities.miscellaneousFunctions.pad(contextVariables.datetimeLastProducedFile.getUTCDate(), 2) + let currentDate = new Date(contextVariables.datetimeLastProducedFile) + let percentage = TS.projects.superalgos.utilities.dateTimeFunctions.getPercentage(fromDate, currentDate, lastDate) + TS.projects.superalgos.functionLibraries.processFunctions.processHeartBeat(processIndex, currentDateString, percentage) + + if (TS.projects.superalgos.utilities.dateTimeFunctions.areTheseDatesEqual(currentDate, new Date()) === false) { + TS.projects.superalgos.globals.loggerVariables.VARIABLES_BY_PROCESS_INDEX_MAP.get(processIndex).BOT_MAIN_LOOP_LOGGER_MODULE_OBJECT.newInternalLoop(currentDate, percentage); + } + /* + We prepere the arrays that will accumulate all the information for each output file. + */ + outputCandles = [] + outputVolumes = [] + + for (let n = 0; n < TS.projects.superalgos.globals.timeFrames.dailyFilePeriods().length; n++) { + const emptyArray1 = [] + const emptyArray2 = [] + outputCandles.push(emptyArray1) + outputVolumes.push(emptyArray2) + } + timeframesLoop(); + } + + function timeframesLoop() { + /* + We will iterate through all posible time frames. + */ + let n = 0 // loop Variable representing each possible period as defined at the periods array. + loopBody(); + + function loopBody() { + const outputPeriod = TS.projects.superalgos.globals.timeFrames.dailyFilePeriods()[n][0] + const timeFrame = TS.projects.superalgos.globals.timeFrames.dailyFilePeriods()[n][1] + + nextCandleFile(); + + function nextCandleFile() { + let dateForPath = + contextVariables.datetimeLastProducedFile.getUTCFullYear() + '/' + + TS.projects.superalgos.utilities.miscellaneousFunctions.pad(contextVariables.datetimeLastProducedFile.getUTCMonth() + 1, 2) + '/' + + TS.projects.superalgos.utilities.miscellaneousFunctions.pad(contextVariables.datetimeLastProducedFile.getUTCDate(), 2) + let fileName = "Data.json" + + let filePathRoot = + 'Project/' + + TS.projects.superalgos.globals.taskConstants.PROJECT_DEFINITION_NODE.config.codeName + "/" + + TS.projects.superalgos.globals.taskConstants.TASK_NODE.bot.processes[processIndex].referenceParent.parentNode.parentNode.type.replace(' ', '-') + "/" + + TS.projects.superalgos.globals.taskConstants.TASK_NODE.bot.processes[processIndex].referenceParent.parentNode.parentNode.config.codeName + "/" + + "Exchange-Raw-Data" + '/' + + TS.projects.superalgos.globals.taskConstants.TASK_NODE.parentNode.parentNode.parentNode.referenceParent.parentNode.parentNode.config.codeName + "/" + + TS.projects.superalgos.globals.taskConstants.TASK_NODE.parentNode.parentNode.parentNode.referenceParent.baseAsset.referenceParent.config.codeName + "-" + + TS.projects.superalgos.globals.taskConstants.TASK_NODE.parentNode.parentNode.parentNode.referenceParent.quotedAsset.referenceParent.config.codeName + let filePath = filePathRoot + "/Output/" + CANDLES_FOLDER_NAME + '/' + CANDLES_ONE_MIN + '/' + dateForPath + filePath += '/' + fileName + + fileStorage.getTextFile(filePath, onFileReceived) + + TS.projects.superalgos.globals.loggerVariables.VARIABLES_BY_PROCESS_INDEX_MAP.get(processIndex).BOT_MAIN_LOOP_LOGGER_MODULE_OBJECT.write(MODULE_NAME, + "[INFO] start -> buildCandles -> timeframesLoop -> loopBody -> getting file at dateForPath = " + dateForPath) + + function onFileReceived(err, text) { + try { + let candlesFile; + + if (err.result === TS.projects.superalgos.globals.standardResponses.DEFAULT_OK_RESPONSE.result) { + try { + candlesFile = JSON.parse(text); + + } catch (err) { + TS.projects.superalgos.globals.loggerVariables.VARIABLES_BY_PROCESS_INDEX_MAP.get(processIndex).BOT_MAIN_LOOP_LOGGER_MODULE_OBJECT.write(MODULE_NAME, + "[ERROR] start -> buildCandles -> timeframesLoop -> loopBody -> nextCandleFile -> onFileReceived -> Error Parsing JSON -> err = " + err.stack) + TS.projects.superalgos.globals.loggerVariables.VARIABLES_BY_PROCESS_INDEX_MAP.get(processIndex).BOT_MAIN_LOOP_LOGGER_MODULE_OBJECT.write(MODULE_NAME, + "[ERROR] start -> buildCandles -> timeframesLoop -> loopBody -> nextCandleFile -> onFileReceived -> Asuming this is a temporary situation. Requesting a Retry."); + callBackFunction(TS.projects.superalgos.globals.standardResponses.DEFAULT_RETRY_RESPONSE) + return; + } + } else { + + if (err.message === 'File does not exist.' || err.code === 'The specified key does not exist.') { + + TS.projects.superalgos.globals.loggerVariables.VARIABLES_BY_PROCESS_INDEX_MAP.get(processIndex).BOT_MAIN_LOOP_LOGGER_MODULE_OBJECT.write(MODULE_NAME, + "[WARN] start -> buildCandles -> timeframesLoop -> loopBody -> nextCandleFile -> onFileReceived -> Dependency Not Ready -> err = " + err.stack) + TS.projects.superalgos.globals.loggerVariables.VARIABLES_BY_PROCESS_INDEX_MAP.get(processIndex).BOT_MAIN_LOOP_LOGGER_MODULE_OBJECT.write(MODULE_NAME, + "[WARN] start -> buildCandles -> timeframesLoop -> loopBody -> nextCandleFile -> onFileReceived -> Asuming this is a temporary situation. Requesting a Retry."); + callBackFunction(TS.projects.superalgos.globals.standardResponses.DEFAULT_RETRY_RESPONSE) + return + + } else { + TS.projects.superalgos.globals.loggerVariables.VARIABLES_BY_PROCESS_INDEX_MAP.get(processIndex).BOT_MAIN_LOOP_LOGGER_MODULE_OBJECT.write(MODULE_NAME, + "[ERROR] start -> buildCandles -> timeframesLoop -> loopBody -> nextCandleFile -> onFileReceived -> Error Received -> err = " + err.stack) + callBackFunction(err); + return + } + } + + const inputCandlesPerdiod = 60 * 1000; // 1 min + const inputFilePeriod = 24 * 60 * 60 * 1000; // 24 hs + + let totalOutputCandles = inputFilePeriod / outputPeriod; + let beginingOutputTime = contextVariables.datetimeLastProducedFile.valueOf(); + + for (let i = 0; i < totalOutputCandles; i++) { + + let outputCandle = { + open: 0, + close: 0, + min: 0, + max: 0, + begin: 0, + end: 0 + } + + let saveCandle = false; + + outputCandle.begin = beginingOutputTime + i * outputPeriod; + outputCandle.end = beginingOutputTime + (i + 1) * outputPeriod - 1; + + for (let j = 0; j < candlesFile.length; j++) { + + let candle = { + open: candlesFile[j][2], + close: candlesFile[j][3], + min: candlesFile[j][0], + max: candlesFile[j][1], + begin: candlesFile[j][4], + end: candlesFile[j][5] + }; + + /* Here we discard all the candles out of range. */ + if (candle.begin >= outputCandle.begin && candle.end <= outputCandle.end) { + + if (saveCandle === false) { // this will set the value only once. + outputCandle.open = candle.open; + outputCandle.min = candle.min + outputCandle.max = candle.max + } + + saveCandle = true; + outputCandle.close = candle.close; // only the last one will be saved + if (candle.min < outputCandle.min) { + outputCandle.min = candle.min + } + if (candle.max > outputCandle.max) { + outputCandle.max = candle.max + } + } + } + if (saveCandle === true) { // then we have a valid candle, otherwise it means there were no candles to fill this one in its time range. + outputCandles[n].push(outputCandle) + } + } + nextVolumeFile(); + } catch (err) { + TS.projects.superalgos.globals.processVariables.VARIABLES_BY_PROCESS_INDEX_MAP.get(processIndex).UNEXPECTED_ERROR = err + TS.projects.superalgos.globals.loggerVariables.VARIABLES_BY_PROCESS_INDEX_MAP.get(processIndex).BOT_MAIN_LOOP_LOGGER_MODULE_OBJECT.write(MODULE_NAME, + "[ERROR] start -> buildCandles -> timeframesLoop -> loopBody -> nextCandleFile -> onFileReceived -> err = " + err.stack); + callBackFunction(TS.projects.superalgos.globals.standardResponses.DEFAULT_FAIL_RESPONSE); + } + } + } + + function nextVolumeFile() { + try { + let dateForPath = contextVariables.datetimeLastProducedFile.getUTCFullYear() + '/' + TS.projects.superalgos.utilities.miscellaneousFunctions.pad(contextVariables.datetimeLastProducedFile.getUTCMonth() + 1, 2) + '/' + TS.projects.superalgos.utilities.miscellaneousFunctions.pad(contextVariables.datetimeLastProducedFile.getUTCDate(), 2); + let fileName = "Data.json" + let filePathRoot = + 'Project/' + + TS.projects.superalgos.globals.taskConstants.PROJECT_DEFINITION_NODE.config.codeName + "/" + + TS.projects.superalgos.globals.taskConstants.TASK_NODE.bot.processes[processIndex].referenceParent.parentNode.parentNode.type.replace(' ', '-') + "/" + + TS.projects.superalgos.globals.taskConstants.TASK_NODE.bot.processes[processIndex].referenceParent.parentNode.parentNode.config.codeName + "/" + + "Exchange-Raw-Data" + '/' + TS.projects.superalgos.globals.taskConstants.TASK_NODE.parentNode.parentNode.parentNode.referenceParent.parentNode.parentNode.config.codeName + "/" + + TS.projects.superalgos.globals.taskConstants.TASK_NODE.parentNode.parentNode.parentNode.referenceParent.baseAsset.referenceParent.config.codeName + "-" + + TS.projects.superalgos.globals.taskConstants.TASK_NODE.parentNode.parentNode.parentNode.referenceParent.quotedAsset.referenceParent.config.codeName + let filePath = + filePathRoot + + "/Output/" + + VOLUMES_FOLDER_NAME + '/' + + VOLUMES_ONE_MIN + '/' + + dateForPath + filePath += '/' + fileName + + fileStorage.getTextFile(filePath, onFileReceived); + + TS.projects.superalgos.globals.loggerVariables.VARIABLES_BY_PROCESS_INDEX_MAP.get(processIndex).BOT_MAIN_LOOP_LOGGER_MODULE_OBJECT.write(MODULE_NAME, + "[INFO] start -> buildCandles -> timeframesLoop -> loopBody -> nextVolumeFile -> getting file at dateForPath = " + dateForPath); + + function onFileReceived(err, text) { + let volumesFile + + if (err.result === TS.projects.superalgos.globals.standardResponses.DEFAULT_OK_RESPONSE.result) { + try { + volumesFile = JSON.parse(text); + } catch (err) { + TS.projects.superalgos.globals.loggerVariables.VARIABLES_BY_PROCESS_INDEX_MAP.get(processIndex).BOT_MAIN_LOOP_LOGGER_MODULE_OBJECT.write(MODULE_NAME, + "[ERROR] start -> buildCandles -> timeframesLoop -> loopBody -> nextVolumeFile -> onFileReceived -> Error Parsing JSON -> err = " + err.stack); + TS.projects.superalgos.globals.loggerVariables.VARIABLES_BY_PROCESS_INDEX_MAP.get(processIndex).BOT_MAIN_LOOP_LOGGER_MODULE_OBJECT.write(MODULE_NAME, + "[ERROR] start -> buildCandles -> timeframesLoop -> loopBody -> nextVolumeFile -> onFileReceived -> Asuming this is a temporary situation. Requesting a Retry.") + callBackFunction(TS.projects.superalgos.globals.standardResponses.DEFAULT_RETRY_RESPONSE) + return + } + } else { + TS.projects.superalgos.globals.loggerVariables.VARIABLES_BY_PROCESS_INDEX_MAP.get(processIndex).BOT_MAIN_LOOP_LOGGER_MODULE_OBJECT.write(MODULE_NAME, + "[ERROR] start -> buildCandles -> timeframesLoop -> loopBody -> nextVolumeFile -> onFileReceived -> Error Received -> err = " + err.stack) + callBackFunction(err) + return + } + + const inputVolumesPerdiod = 60 * 1000; // 1 min + const inputFilePeriod = 24 * 60 * 60 * 1000; // 24 hs + let totalOutputVolumes = inputFilePeriod / outputPeriod; // this should be 2 in this case. + let beginingOutputTime = contextVariables.datetimeLastProducedFile.valueOf(); + + for (let i = 0; i < totalOutputVolumes; i++) { + let outputVolume = { + buy: 0, + sell: 0, + begin: 0, + end: 0 + } + let saveVolume = false; + + outputVolume.begin = beginingOutputTime + i * outputPeriod; + outputVolume.end = beginingOutputTime + (i + 1) * outputPeriod - 1; + + for (let j = 0; j < volumesFile.length; j++) { + let volume = { + buy: volumesFile[j][0], + sell: volumesFile[j][1], + begin: volumesFile[j][2], + end: volumesFile[j][3] + } + + /* Here we discard all the Volumes out of range. */ + if (volume.begin >= outputVolume.begin && volume.end <= outputVolume.end) { + saveVolume = true + outputVolume.buy = outputVolume.buy + volume.buy + outputVolume.sell = outputVolume.sell + volume.sell + } + } + + if (saveVolume === true) { + outputVolumes[n].push(outputVolume); + } + } + writeFiles(outputCandles[n], outputVolumes[n], timeFrame, controlLoop) + } + } catch (err) { + TS.projects.superalgos.globals.processVariables.VARIABLES_BY_PROCESS_INDEX_MAP.get(processIndex).UNEXPECTED_ERROR = err + TS.projects.superalgos.globals.loggerVariables.VARIABLES_BY_PROCESS_INDEX_MAP.get(processIndex).BOT_MAIN_LOOP_LOGGER_MODULE_OBJECT.write(MODULE_NAME, + "[ERROR] start -> buildCandles -> timeframesLoop -> loopBody -> nextVolumeFile -> onFileReceived -> err = " + err.stack); + callBackFunction(TS.projects.superalgos.globals.standardResponses.DEFAULT_FAIL_RESPONSE); + } + } + } + + function controlLoop() { + n++; + if (n < TS.projects.superalgos.globals.timeFrames.dailyFilePeriods().length) { + loopBody() + } else { + writeDataRanges(onWritten); + + function onWritten(err) { + if (err.result !== TS.projects.superalgos.globals.standardResponses.DEFAULT_OK_RESPONSE.result) { + TS.projects.superalgos.globals.loggerVariables.VARIABLES_BY_PROCESS_INDEX_MAP.get(processIndex).BOT_MAIN_LOOP_LOGGER_MODULE_OBJECT.write(MODULE_NAME, + "[ERROR] writeDataRanges -> writeDataRanges -> onCandlesDataRangeWritten -> err = " + err.stack) + callBack(err) + return + } + writeStatusReport(contextVariables.datetimeLastProducedFile, advanceTime); + } + } + } + } + } + catch (err) { + TS.projects.superalgos.globals.processVariables.VARIABLES_BY_PROCESS_INDEX_MAP.get(processIndex).UNEXPECTED_ERROR = err + TS.projects.superalgos.globals.loggerVariables.VARIABLES_BY_PROCESS_INDEX_MAP.get(processIndex).BOT_MAIN_LOOP_LOGGER_MODULE_OBJECT.write(MODULE_NAME, + "[ERROR] start -> buildCandles -> err = " + err.stack); + callBackFunction(TS.projects.superalgos.globals.standardResponses.DEFAULT_FAIL_RESPONSE); + } + } + + function writeFiles(candles, volumes, timeFrame, callBack) { + /* + Here we will write the contents of the Candles and Volumens files. + */ + try { + writeCandles() + + function writeCandles() { + let separator = "" + let fileRecordCounter = 0 + let fileContent = "" + + for (let i = 0; i < candles.length; i++) { + let candle = candles[i] + fileContent = fileContent + separator + '[' + candles[i].min + "," + candles[i].max + "," + candles[i].open + "," + candles[i].close + "," + candles[i].begin + "," + candles[i].end + "]"; + if (separator === "") { separator = ","; } + fileRecordCounter++ + } + + fileContent = "[" + fileContent + "]"; + + let fileName = 'Data.json'; + let dateForPath = + contextVariables.datetimeLastProducedFile.getUTCFullYear() + '/' + + TS.projects.superalgos.utilities.miscellaneousFunctions.pad(contextVariables.datetimeLastProducedFile.getUTCMonth() + 1, 2) + '/' + + TS.projects.superalgos.utilities.miscellaneousFunctions.pad(contextVariables.datetimeLastProducedFile.getUTCDate(), 2) + let filePath = + TS.projects.superalgos.globals.processVariables.VARIABLES_BY_PROCESS_INDEX_MAP.get(processIndex).FILE_PATH_ROOT + + "/Output/" + + CANDLES_FOLDER_NAME + "/" + + TS.projects.superalgos.globals.taskConstants.TASK_NODE.bot.processes[processIndex].referenceParent.config.codeName + "/" + + timeFrame + "/" + + dateForPath + filePath += '/' + fileName + + fileStorage.createTextFile(filePath, fileContent + '\n', onFileCreated) + + TS.projects.superalgos.globals.loggerVariables.VARIABLES_BY_PROCESS_INDEX_MAP.get(processIndex).BOT_MAIN_LOOP_LOGGER_MODULE_OBJECT.write(MODULE_NAME, + "[INFO] start -> writeFiles -> writeCandles -> creating file at filePath = " + filePath); + + function onFileCreated(err) { + if (err.result !== TS.projects.superalgos.globals.standardResponses.DEFAULT_OK_RESPONSE.result) { + TS.projects.superalgos.globals.loggerVariables.VARIABLES_BY_PROCESS_INDEX_MAP.get(processIndex).BOT_MAIN_LOOP_LOGGER_MODULE_OBJECT.write(MODULE_NAME, + "[ERROR] start -> writeFiles -> writeCandles -> onFileCreated -> err = " + err.stack); + callBackFunction(err); + return; + } + + TS.projects.superalgos.globals.loggerVariables.VARIABLES_BY_PROCESS_INDEX_MAP.get(processIndex).BOT_MAIN_LOOP_LOGGER_MODULE_OBJECT.write(MODULE_NAME, + "[WARN] start -> writeFiles -> writeCandles -> onFileCreated -> Finished with File @ " + TS.projects.superalgos.globals.taskConstants.TASK_NODE.parentNode.parentNode.parentNode.referenceParent.baseAsset.referenceParent.config.codeName + "_" + TS.projects.superalgos.globals.taskConstants.TASK_NODE.parentNode.parentNode.parentNode.referenceParent.quotedAsset.referenceParent.config.codeName + ", " + fileRecordCounter + " records inserted into " + filePath + "/" + fileName); + + writeVolumes(); + } + } + + function writeVolumes() { + let separator = ""; + let fileRecordCounter = 0; + let fileContent = ""; + + for (let i = 0; i < volumes.length; i++) { + let candle = volumes[i]; + fileContent = fileContent + separator + '[' + volumes[i].buy + "," + volumes[i].sell + "," + volumes[i].begin + "," + volumes[i].end + "]"; + if (separator === "") { separator = ","; } + fileRecordCounter++ + } + + fileContent = "[" + fileContent + "]"; + + let fileName = 'Data.json'; + let dateForPath = + contextVariables.datetimeLastProducedFile.getUTCFullYear() + '/' + + TS.projects.superalgos.utilities.miscellaneousFunctions.pad(contextVariables.datetimeLastProducedFile.getUTCMonth() + 1, 2) + '/' + + TS.projects.superalgos.utilities.miscellaneousFunctions.pad(contextVariables.datetimeLastProducedFile.getUTCDate(), 2) + let filePath = + TS.projects.superalgos.globals.processVariables.VARIABLES_BY_PROCESS_INDEX_MAP.get(processIndex).FILE_PATH_ROOT + + "/Output/" + + VOLUMES_FOLDER_NAME + "/" + + TS.projects.superalgos.globals.taskConstants.TASK_NODE.bot.processes[processIndex].referenceParent.config.codeName + "/" + + timeFrame + "/" + dateForPath + filePath += '/' + fileName + + fileStorage.createTextFile(filePath, fileContent + '\n', onFileCreated); + + TS.projects.superalgos.globals.loggerVariables.VARIABLES_BY_PROCESS_INDEX_MAP.get(processIndex).BOT_MAIN_LOOP_LOGGER_MODULE_OBJECT.write(MODULE_NAME, + "[INFO] start -> writeFiles -> writeVolumes -> creating file at filePath = " + filePath); + + function onFileCreated(err) { + + if (err.result !== TS.projects.superalgos.globals.standardResponses.DEFAULT_OK_RESPONSE.result) { + TS.projects.superalgos.globals.loggerVariables.VARIABLES_BY_PROCESS_INDEX_MAP.get(processIndex).BOT_MAIN_LOOP_LOGGER_MODULE_OBJECT.write(MODULE_NAME, + "[ERROR] start -> writeFiles -> writeVolumes -> onFileCreated -> err = " + err.stack) + callBackFunction(err) + return + } + + TS.projects.superalgos.globals.loggerVariables.VARIABLES_BY_PROCESS_INDEX_MAP.get(processIndex).BOT_MAIN_LOOP_LOGGER_MODULE_OBJECT.write(MODULE_NAME, + "[WARN] start -> writeFiles -> writeVolumes -> onFileCreated -> Finished with File @ " + TS.projects.superalgos.globals.taskConstants.TASK_NODE.parentNode.parentNode.parentNode.referenceParent.baseAsset.referenceParent.config.codeName + "_" + TS.projects.superalgos.globals.taskConstants.TASK_NODE.parentNode.parentNode.parentNode.referenceParent.quotedAsset.referenceParent.config.codeName + ", " + fileRecordCounter + " records inserted into " + filePath + "/" + fileName); + + callBack() + } + } + } + catch (err) { + TS.projects.superalgos.globals.processVariables.VARIABLES_BY_PROCESS_INDEX_MAP.get(processIndex).UNEXPECTED_ERROR = err + TS.projects.superalgos.globals.loggerVariables.VARIABLES_BY_PROCESS_INDEX_MAP.get(processIndex).BOT_MAIN_LOOP_LOGGER_MODULE_OBJECT.write(MODULE_NAME, + "[ERROR] start -> writeFiles -> err = " + err.stack); + callBackFunction(TS.projects.superalgos.globals.standardResponses.DEFAULT_FAIL_RESPONSE); + } + } + + function writeDataRanges(callBack) { + try { + writeDataRange(contextVariables.datetimeBeginingOfMarketFile, contextVariables.datetimeLastProducedFile, CANDLES_FOLDER_NAME, onCandlesDataRangeWritten); + + function onCandlesDataRangeWritten(err) { + if (err.result !== TS.projects.superalgos.globals.standardResponses.DEFAULT_OK_RESPONSE.result) { + TS.projects.superalgos.globals.loggerVariables.VARIABLES_BY_PROCESS_INDEX_MAP.get(processIndex).BOT_MAIN_LOOP_LOGGER_MODULE_OBJECT.write(MODULE_NAME, + "[ERROR] writeDataRanges -> writeDataRanges -> onCandlesDataRangeWritten -> err = " + err.stack) + callBack(err) + return + } + + writeDataRange(contextVariables.datetimeBeginingOfMarketFile, contextVariables.datetimeLastProducedFile, VOLUMES_FOLDER_NAME, onVolumeDataRangeWritten); + + function onVolumeDataRangeWritten(err) { + if (err.result !== TS.projects.superalgos.globals.standardResponses.DEFAULT_OK_RESPONSE.result) { + TS.projects.superalgos.globals.loggerVariables.VARIABLES_BY_PROCESS_INDEX_MAP.get(processIndex).BOT_MAIN_LOOP_LOGGER_MODULE_OBJECT.write(MODULE_NAME, + "[ERROR] writeDataRanges -> writeDataRanges -> onVolumeDataRangeWritten -> err = " + err.stack) + callBack(err) + return + } + callBack(TS.projects.superalgos.globals.standardResponses.DEFAULT_OK_RESPONSE); + } + } + } + catch (err) { + TS.projects.superalgos.globals.processVariables.VARIABLES_BY_PROCESS_INDEX_MAP.get(processIndex).UNEXPECTED_ERROR = err + TS.projects.superalgos.globals.loggerVariables.VARIABLES_BY_PROCESS_INDEX_MAP.get(processIndex).BOT_MAIN_LOOP_LOGGER_MODULE_OBJECT.write(MODULE_NAME, + "[ERROR] start -> writeDataRanges -> err = " + err.stack); + callBack(TS.projects.superalgos.globals.standardResponses.DEFAULT_FAIL_RESPONSE); + } + + } + + function writeDataRange(pBegin, pEnd, pProductFolder, callBack) { + try { + let dataRange = { + begin: pBegin.valueOf(), + end: pEnd.valueOf() + TS.projects.superalgos.globals.timeConstants.ONE_DAY_IN_MILISECONDS + } + + let fileContent = JSON.stringify(dataRange); + + let fileName = 'Data.Range.json'; + let filePath = + TS.projects.superalgos.globals.processVariables.VARIABLES_BY_PROCESS_INDEX_MAP.get(processIndex).FILE_PATH_ROOT + "/Output/" + pProductFolder + "/" + + TS.projects.superalgos.globals.taskConstants.TASK_NODE.bot.processes[processIndex].referenceParent.config.codeName + filePath += '/' + fileName + + fileStorage.createTextFile(filePath, fileContent + '\n', onFileCreated); + + function onFileCreated(err) { + if (err.result !== TS.projects.superalgos.globals.standardResponses.DEFAULT_OK_RESPONSE.result) { + TS.projects.superalgos.globals.loggerVariables.VARIABLES_BY_PROCESS_INDEX_MAP.get(processIndex).BOT_MAIN_LOOP_LOGGER_MODULE_OBJECT.write(MODULE_NAME, + "[ERROR] start -> writeDataRange -> onFileCreated -> err = " + err.stack) + callBack(err) + return + } + + let key = + TS.projects.superalgos.globals.taskConstants.TASK_NODE.bot.processes[processIndex].referenceParent.parentNode.parentNode.config.codeName + "-" + + TS.projects.superalgos.globals.taskConstants.TASK_NODE.bot.processes[processIndex].referenceParent.parentNode.config.codeName + "-" + + pProductFolder + "-" + + TS.projects.superalgos.globals.taskConstants.TASK_NODE.parentNode.parentNode.parentNode.referenceParent.parentNode.parentNode.config.codeName + "-" + + TS.projects.superalgos.globals.taskConstants.TASK_NODE.parentNode.parentNode.parentNode.referenceParent.baseAsset.referenceParent.config.codeName + '/' + + TS.projects.superalgos.globals.taskConstants.TASK_NODE.parentNode.parentNode.parentNode.referenceParent.quotedAsset.referenceParent.config.codeName + let event = { + dateRange: dataRange + } + + TS.projects.superalgos.globals.taskConstants.EVENT_SERVER_CLIENT_MODULE_OBJECT.raiseEvent(key, 'Data Range Updated', event) + + callBack(TS.projects.superalgos.globals.standardResponses.DEFAULT_OK_RESPONSE); + } + } + catch (err) { + TS.projects.superalgos.globals.processVariables.VARIABLES_BY_PROCESS_INDEX_MAP.get(processIndex).UNEXPECTED_ERROR = err + TS.projects.superalgos.globals.loggerVariables.VARIABLES_BY_PROCESS_INDEX_MAP.get(processIndex).BOT_MAIN_LOOP_LOGGER_MODULE_OBJECT.write(MODULE_NAME, + "[ERROR] start -> writeDataRange -> err = " + err.stack) + callBack(TS.projects.superalgos.globals.standardResponses.DEFAULT_FAIL_RESPONSE) + } + } + + function writeStatusReport(lastFileDate, callBack) { + TS.projects.superalgos.globals.loggerVariables.VARIABLES_BY_PROCESS_INDEX_MAP.get(processIndex).BOT_MAIN_LOOP_LOGGER_MODULE_OBJECT.write(MODULE_NAME, + "[INFO] start -> writeStatusReport -> lastFileDate = " + lastFileDate) + try { + let reportKey = "Masters" + "-" + "Candles-Volumes" + "-" + "Multi-Period-Daily" + let thisReport = statusDependencies.statusReports.get(reportKey) + + thisReport.file.lastExecution = TS.projects.superalgos.globals.processVariables.VARIABLES_BY_PROCESS_INDEX_MAP.get(processIndex).PROCESS_DATETIME; + thisReport.file.lastFile = lastFileDate; + thisReport.file.beginingOfMarket = beginingOfMarket.toUTCString() + thisReport.save(callBack); + } + catch (err) { + TS.projects.superalgos.globals.processVariables.VARIABLES_BY_PROCESS_INDEX_MAP.get(processIndex).UNEXPECTED_ERROR = err + TS.projects.superalgos.globals.loggerVariables.VARIABLES_BY_PROCESS_INDEX_MAP.get(processIndex).BOT_MAIN_LOOP_LOGGER_MODULE_OBJECT.write(MODULE_NAME, + "[ERROR] start -> writeStatusReport -> err = " + err.stack); + callBackFunction(TS.projects.superalgos.globals.standardResponses.DEFAULT_FAIL_RESPONSE); + } + } + + } + catch (err) { + TS.projects.superalgos.globals.processVariables.VARIABLES_BY_PROCESS_INDEX_MAP.get(processIndex).UNEXPECTED_ERROR = err + TS.projects.superalgos.globals.loggerVariables.VARIABLES_BY_PROCESS_INDEX_MAP.get(processIndex).BOT_MAIN_LOOP_LOGGER_MODULE_OBJECT.write(MODULE_NAME, + "[ERROR] 'Start' - ERROR : " + err.stack); + callBackFunction(TS.projects.superalgos.globals.standardResponses.DEFAULT_FAIL_RESPONSE) + } + } +} diff --git a/Projects/Superalgos/TS/Bot-Modules/Indicator-Bot/FromOneMinToMultiPeriodMarket.js b/Projects/Superalgos/TS/Bot-Modules/Indicator-Bot/FromOneMinToMultiPeriodMarket.js new file mode 100644 index 000000000..fa3d355fb --- /dev/null +++ b/Projects/Superalgos/TS/Bot-Modules/Indicator-Bot/FromOneMinToMultiPeriodMarket.js @@ -0,0 +1,911 @@ +exports.newSuperalgosBotModulesFromOneMinToMultiPeriodMarket = function (processIndex) { + /* + This process is going to do the following: + + Read the elements (candles, volumens, bolllinger bands, news, asset metrics, etc.) from a + One-Min dataset (a dataset that is organized with elements spanning one min, like one min candles, + or elements with a timestamp captured approximatelly one minute from each other), and the dataset itself + organized in Daily Files. + + It is going to output a Market Files dataset for every Market Time Frame, aggregating the + input information into elements with a begin and end property. + + Everytime this process run, is be able to resume its job and process everything pending until + reaching the head of the market. To achieve that it will follow this strategy: + + 1. First it will read the last file written by this same process, and load all the information into + in-memory arrays. + + 2. Then it will append to these arrays the new information it gets from the data dependency. + + 3. It knows from it's status report which was the last DAY it processed. Since that day might not have been + full of that (maybe it was at the head of the market). The process will have to be carefull not to append candles + that are already there. To take care of that, it will discard all elements of the last processed day, + and then it will process that full day again adding all the elements found at the current run. + */ + const MODULE_NAME = "From One Min To Multi Period Market" + const DEPENDENCY_FOLDER_NAME = "Candles" + const DEPENDENCY_ONE_MIN = "One-Min" + const VOLUMES_FOLDER_NAME = "Volumes" + const VOLUMES_ONE_MIN = "One-Min" + + let thisObject = { + initialize: initialize, + start: start + } + + let fileStorage = TS.projects.superalgos.taskModules.fileStorage.newFileStorage(processIndex); + let statusDependencies; + let beginingOfMarket + + return thisObject; + + function initialize(pStatusDependencies, callBackFunction) { + try { + statusDependencies = pStatusDependencies; + callBackFunction(TS.projects.superalgos.globals.standardResponses.DEFAULT_OK_RESPONSE); + } catch (err) { + TS.projects.superalgos.globals.processVariables.VARIABLES_BY_PROCESS_INDEX_MAP.get(processIndex).UNEXPECTED_ERROR = err + TS.projects.superalgos.globals.loggerVariables.VARIABLES_BY_PROCESS_INDEX_MAP.get(processIndex).BOT_MAIN_LOOP_LOGGER_MODULE_OBJECT.write(MODULE_NAME, + "[ERROR] initialize -> err = " + err.stack); + callBackFunction(TS.projects.superalgos.globals.standardResponses.DEFAULT_FAIL_RESPONSE); + } + } + + function start(callBackFunction) { + + try { + /* Context Variables */ + let contextVariables = { + datetimeLastProducedFile: undefined, // Datetime of the last file files successfully produced by this process. + datetimeBeginingOfMarketFile: undefined, // Datetime of the first trade file in the whole market history. + datetimeLastAvailableDependencyFile: undefined // Datetime of the last file available to be used as an input of this process. + }; + + getContextVariables(); + + function getContextVariables() { + try { + let thisReport; + let reportKey; + let statusReport; + + /* We look first for Exchange Raw Data in order to get when the market starts. */ + + reportKey = "Masters" + "-" + "Exchange-Raw-Data" + "-" + "Historic-OHLCVs" + TS.projects.superalgos.globals.loggerVariables.VARIABLES_BY_PROCESS_INDEX_MAP.get(processIndex).BOT_MAIN_LOOP_LOGGER_MODULE_OBJECT.write(MODULE_NAME, + "[INFO] start -> getContextVariables -> reportKey = " + reportKey) + + statusReport = statusDependencies.statusReports.get(reportKey); + + if (statusReport === undefined) { // This means the status report does not exist, that could happen for instance at the begining of a month. + TS.projects.superalgos.globals.loggerVariables.VARIABLES_BY_PROCESS_INDEX_MAP.get(processIndex).BOT_MAIN_LOOP_LOGGER_MODULE_OBJECT.write(MODULE_NAME, + "[WARN] start -> getContextVariables -> Status Report does not exist. Retrying Later. "); + callBackFunction(TS.projects.superalgos.globals.standardResponses.DEFAULT_RETRY_RESPONSE); + return + } + + if (statusReport.status === "Status Report is corrupt.") { + TS.projects.superalgos.globals.loggerVariables.VARIABLES_BY_PROCESS_INDEX_MAP.get(processIndex).BOT_MAIN_LOOP_LOGGER_MODULE_OBJECT.write(MODULE_NAME, + "[ERROR] start -> getContextVariables -> Can not continue because dependecy Status Report is corrupt. "); + callBackFunction(TS.projects.superalgos.globals.standardResponses.DEFAULT_RETRY_RESPONSE); + return + } + + thisReport = statusDependencies.statusReports.get(reportKey).file; + + if (thisReport.beginingOfMarket === undefined) { + TS.projects.superalgos.globals.loggerVariables.VARIABLES_BY_PROCESS_INDEX_MAP.get(processIndex).BOT_MAIN_LOOP_LOGGER_MODULE_OBJECT.write(MODULE_NAME, + "[WARN] start -> getContextVariables -> Undefined Last File. -> reportKey = " + reportKey); + TS.projects.superalgos.globals.loggerVariables.VARIABLES_BY_PROCESS_INDEX_MAP.get(processIndex).BOT_MAIN_LOOP_LOGGER_MODULE_OBJECT.write(MODULE_NAME, + "[HINT] start -> getContextVariables -> It is too early too run this process since the trade history of the market is not there yet."); + + let customOK = { + result: TS.projects.superalgos.globals.standardResponses.CUSTOM_OK_RESPONSE.result, + message: "Dependency does not exist." + } + TS.projects.superalgos.globals.loggerVariables.VARIABLES_BY_PROCESS_INDEX_MAP.get(processIndex).BOT_MAIN_LOOP_LOGGER_MODULE_OBJECT.write(MODULE_NAME, + "[WARN] start -> getContextVariables -> customOK = " + customOK.message); + callBackFunction(customOK) + return + } + + contextVariables.datetimeBeginingOfMarketFile = new Date( + thisReport.beginingOfMarket.year + "-" + + thisReport.beginingOfMarket.month + "-" + + thisReport.beginingOfMarket.days + " " + + thisReport.beginingOfMarket.hours + ":" + + thisReport.beginingOfMarket.minutes + + TS.projects.superalgos.globals.timeConstants.GMT_SECONDS); + + /* Second, we get the report from Exchange Raw Data, to know when the marted ends. */ + reportKey = "Masters" + "-" + "Exchange-Raw-Data" + "-" + "Historic-OHLCVs" + TS.projects.superalgos.globals.loggerVariables.VARIABLES_BY_PROCESS_INDEX_MAP.get(processIndex).BOT_MAIN_LOOP_LOGGER_MODULE_OBJECT.write(MODULE_NAME, + "[INFO] start -> getContextVariables -> reportKey = " + reportKey) + + statusReport = statusDependencies.statusReports.get(reportKey); + + if (statusReport === undefined) { // This means the status report does not exist, that could happen for instance at the begining of a month. + TS.projects.superalgos.globals.loggerVariables.VARIABLES_BY_PROCESS_INDEX_MAP.get(processIndex).BOT_MAIN_LOOP_LOGGER_MODULE_OBJECT.write(MODULE_NAME, + "[WARN] start -> getContextVariables -> Status Report does not exist. Retrying Later. "); + callBackFunction(TS.projects.superalgos.globals.standardResponses.DEFAULT_RETRY_RESPONSE); + return; + } + + if (statusReport.status === "Status Report is corrupt.") { + TS.projects.superalgos.globals.loggerVariables.VARIABLES_BY_PROCESS_INDEX_MAP.get(processIndex).BOT_MAIN_LOOP_LOGGER_MODULE_OBJECT.write(MODULE_NAME, + "[ERROR] start -> getContextVariables -> Can not continue because dependecy Status Report is corrupt. "); + callBackFunction(TS.projects.superalgos.globals.standardResponses.DEFAULT_RETRY_RESPONSE); + return; + } + + thisReport = statusDependencies.statusReports.get(reportKey).file; + + if (thisReport.lastFile === undefined) { + TS.projects.superalgos.globals.loggerVariables.VARIABLES_BY_PROCESS_INDEX_MAP.get(processIndex).BOT_MAIN_LOOP_LOGGER_MODULE_OBJECT.write(MODULE_NAME, + "[WARN] start -> getContextVariables -> Undefined Last File. -> reportKey = " + reportKey); + + let customOK = { + result: TS.projects.superalgos.globals.standardResponses.CUSTOM_OK_RESPONSE.result, + message: "Dependency not ready." + } + TS.projects.superalgos.globals.loggerVariables.VARIABLES_BY_PROCESS_INDEX_MAP.get(processIndex).BOT_MAIN_LOOP_LOGGER_MODULE_OBJECT.write(MODULE_NAME, + "[WARN] start -> getContextVariables -> customOK = " + customOK.message); + callBackFunction(customOK); + return; + } + + contextVariables.datetimeLastAvailableDependencyFile = new Date( + thisReport.lastFile.year + "-" + + thisReport.lastFile.month + "-" + + thisReport.lastFile.days + " " + "00:00" + + TS.projects.superalgos.globals.timeConstants.GMT_SECONDS); + + /* Finally we get our own Status Report. */ + reportKey = "Masters" + "-" + "Candles-Volumes" + "-" + "Multi-Period-Market" + TS.projects.superalgos.globals.loggerVariables.VARIABLES_BY_PROCESS_INDEX_MAP.get(processIndex).BOT_MAIN_LOOP_LOGGER_MODULE_OBJECT.write(MODULE_NAME, + "[INFO] start -> getContextVariables -> reportKey = " + reportKey) + + statusReport = statusDependencies.statusReports.get(reportKey); + + if (statusReport === undefined) { // This means the status report does not exist, that could happen for instance at the begining of a month. + TS.projects.superalgos.globals.loggerVariables.VARIABLES_BY_PROCESS_INDEX_MAP.get(processIndex).BOT_MAIN_LOOP_LOGGER_MODULE_OBJECT.write(MODULE_NAME, + "[WARN] start -> getContextVariables -> Status Report does not exist. Retrying Later. "); + callBackFunction(TS.projects.superalgos.globals.standardResponses.DEFAULT_RETRY_RESPONSE); + return + } + + if (statusReport.status === "Status Report is corrupt.") { + TS.projects.superalgos.globals.loggerVariables.VARIABLES_BY_PROCESS_INDEX_MAP.get(processIndex).BOT_MAIN_LOOP_LOGGER_MODULE_OBJECT.write(MODULE_NAME, + "[ERROR] start -> getContextVariables -> Can not continue because self dependecy Status Report is corrupt. Aborting Process."); + callBackFunction(TS.projects.superalgos.globals.standardResponses.DEFAULT_FAIL_RESPONSE); + return + } + + thisReport = statusDependencies.statusReports.get(reportKey).file; + + if (thisReport.lastFile !== undefined) { + TS.projects.superalgos.globals.loggerVariables.VARIABLES_BY_PROCESS_INDEX_MAP.get(processIndex).BOT_MAIN_LOOP_LOGGER_MODULE_OBJECT.write(MODULE_NAME, + "[INFO] start -> getContextVariables -> Process Running not for the very first time. -> reportKey = " + reportKey); + + beginingOfMarket = new Date(thisReport.beginingOfMarket); + + if (beginingOfMarket.valueOf() !== contextVariables.datetimeBeginingOfMarketFile.valueOf()) { // Reset Mechanism for Begining of the Market + TS.projects.superalgos.globals.loggerVariables.VARIABLES_BY_PROCESS_INDEX_MAP.get(processIndex).BOT_MAIN_LOOP_LOGGER_MODULE_OBJECT.write(MODULE_NAME, + "[INFO] start -> getContextVariables -> Reset Mechanism for Begining of the Market Activated. -> reportKey = " + reportKey); + + beginingOfMarket = new Date( + contextVariables.datetimeBeginingOfMarketFile.getUTCFullYear() + "-" + + (contextVariables.datetimeBeginingOfMarketFile.getUTCMonth() + 1) + "-" + + contextVariables.datetimeBeginingOfMarketFile.getUTCDate() + " " + "00:00" + + TS.projects.superalgos.globals.timeConstants.GMT_SECONDS); + contextVariables.datetimeLastProducedFile = new Date( + contextVariables.datetimeBeginingOfMarketFile.getUTCFullYear() + "-" + + (contextVariables.datetimeBeginingOfMarketFile.getUTCMonth() + 1) + "-" + + contextVariables.datetimeBeginingOfMarketFile.getUTCDate() + " " + "00:00" + + TS.projects.superalgos.globals.timeConstants.GMT_SECONDS); + contextVariables.datetimeLastProducedFile = new Date( + contextVariables.datetimeLastProducedFile.valueOf() - + TS.projects.superalgos.globals.timeConstants.ONE_DAY_IN_MILISECONDS); // Go back one day to start well. + + buildCandles() + return + } + + contextVariables.datetimeLastProducedFile = new Date(thisReport.lastFile); + + /* + Here we assume that the last day written might contain incomplete information. + This actually happens every time the head of the market is reached. + For that reason we go back one day, the partial information is discarded and + added again with whatever new info is available. + */ + contextVariables.datetimeLastProducedFile = new Date(contextVariables.datetimeLastProducedFile.valueOf() - TS.projects.superalgos.globals.timeConstants.ONE_DAY_IN_MILISECONDS); + + findPreviousContent() + return + } else { + TS.projects.superalgos.globals.loggerVariables.VARIABLES_BY_PROCESS_INDEX_MAP.get(processIndex).BOT_MAIN_LOOP_LOGGER_MODULE_OBJECT.write(MODULE_NAME, + "[INFO] start -> getContextVariables -> Process Running for the very first time. -> reportKey = " + reportKey); + + beginingOfMarket = new Date( + contextVariables.datetimeBeginingOfMarketFile.getUTCFullYear() + "-" + + (contextVariables.datetimeBeginingOfMarketFile.getUTCMonth() + 1) + "-" + + contextVariables.datetimeBeginingOfMarketFile.getUTCDate() + " " + "00:00" + + TS.projects.superalgos.globals.timeConstants.GMT_SECONDS); + contextVariables.datetimeLastProducedFile = new Date( + contextVariables.datetimeBeginingOfMarketFile.getUTCFullYear() + "-" + + (contextVariables.datetimeBeginingOfMarketFile.getUTCMonth() + 1) + "-" + + contextVariables.datetimeBeginingOfMarketFile.getUTCDate() + " " + "00:00" + + TS.projects.superalgos.globals.timeConstants.GMT_SECONDS); + contextVariables.datetimeLastProducedFile = new Date( + contextVariables.datetimeLastProducedFile.valueOf() - + TS.projects.superalgos.globals.timeConstants.ONE_DAY_IN_MILISECONDS); // Go back one day to start well. + + buildCandles() + return + } + + } catch (err) { + TS.projects.superalgos.globals.processVariables.VARIABLES_BY_PROCESS_INDEX_MAP.get(processIndex).UNEXPECTED_ERROR = err + TS.projects.superalgos.globals.loggerVariables.VARIABLES_BY_PROCESS_INDEX_MAP.get(processIndex).BOT_MAIN_LOOP_LOGGER_MODULE_OBJECT.write(MODULE_NAME, + "[ERROR] start -> getContextVariables -> err = " + err.stack); + if (err.message === "Cannot read property 'file' of undefined") { + TS.projects.superalgos.globals.loggerVariables.VARIABLES_BY_PROCESS_INDEX_MAP.get(processIndex).BOT_MAIN_LOOP_LOGGER_MODULE_OBJECT.write(MODULE_NAME, + "[HINT] start -> getContextVariables -> Check the bot configuration to see if all of its statusDependencies declarations are correct. "); + TS.projects.superalgos.globals.loggerVariables.VARIABLES_BY_PROCESS_INDEX_MAP.get(processIndex).BOT_MAIN_LOOP_LOGGER_MODULE_OBJECT.write(MODULE_NAME, + "[HINT] start -> getContextVariables -> Dependencies loaded -> keys = " + JSON.stringify(statusDependencies.keys)); + TS.projects.superalgos.globals.loggerVariables.VARIABLES_BY_PROCESS_INDEX_MAP.get(processIndex).BOT_MAIN_LOOP_LOGGER_MODULE_OBJECT.write(MODULE_NAME, + "[HINT] start -> getContextVariables -> Dependencies loaded -> Double check that you are not running a process that only can be run at noTime mode at a certain month when it is not prepared to do so."); + } + callBackFunction(TS.projects.superalgos.globals.standardResponses.DEFAULT_FAIL_RESPONSE); + } + } + + function findPreviousContent() { + /* + This is where we read the current files we have produced at previous runs + of this same process. We just read all the content and organize it + in arrays and keep them in memory. + */ + try { + let n = 0 // loop Variable representing each possible period as defined at the periods array. + + let allPreviousCandles = [] // Each item of this array is an array of candles for a certain time frame + let allPreviousVolumes = [] // Each item of this array is an array of volumes for a certain time frame + + loopBody() + + function loopBody() { + let timeFrame = TS.projects.superalgos.globals.timeFrames.marketFilesPeriods()[n][1]; + TS.projects.superalgos.globals.loggerVariables.VARIABLES_BY_PROCESS_INDEX_MAP.get(processIndex).BOT_MAIN_LOOP_LOGGER_MODULE_OBJECT.write(MODULE_NAME, + "[INFO] start -> findPreviousContent -> loopBody -> timeFrame = " + timeFrame) + + let previousCandles + let previousVolumes + + getCandles() + + function getCandles() { + let fileName = 'Data.json'; + let filePath = + TS.projects.superalgos.globals.processVariables.VARIABLES_BY_PROCESS_INDEX_MAP.get(processIndex).FILE_PATH_ROOT + + "/Output/" + + DEPENDENCY_FOLDER_NAME + "/" + + TS.projects.superalgos.globals.taskConstants.TASK_NODE.bot.processes[processIndex].referenceParent.config.codeName + "/" + + timeFrame; + filePath += '/' + fileName + + fileStorage.getTextFile(filePath, onFileReceived); + + TS.projects.superalgos.globals.loggerVariables.VARIABLES_BY_PROCESS_INDEX_MAP.get(processIndex).BOT_MAIN_LOOP_LOGGER_MODULE_OBJECT.write(MODULE_NAME, + "[INFO] start -> findPreviousContent -> loopBody -> getCandles -> getting file."); + + function onFileReceived(err, text) { + let candlesFile + + if (err.result === TS.projects.superalgos.globals.standardResponses.DEFAULT_OK_RESPONSE.result) { + try { + candlesFile = JSON.parse(text); + previousCandles = candlesFile; + getVolumes(); + + } catch (err) { + TS.projects.superalgos.globals.loggerVariables.VARIABLES_BY_PROCESS_INDEX_MAP.get(processIndex).BOT_MAIN_LOOP_LOGGER_MODULE_OBJECT.write(MODULE_NAME, + "[ERROR] start -> findPreviousContent -> loopBody -> getCandles -> onFileReceived -> fileName = " + fileName); + TS.projects.superalgos.globals.loggerVariables.VARIABLES_BY_PROCESS_INDEX_MAP.get(processIndex).BOT_MAIN_LOOP_LOGGER_MODULE_OBJECT.write(MODULE_NAME, + "[ERROR] start -> findPreviousContent -> loopBody -> getCandles -> onFileReceived -> filePath = " + filePath); + TS.projects.superalgos.globals.loggerVariables.VARIABLES_BY_PROCESS_INDEX_MAP.get(processIndex).BOT_MAIN_LOOP_LOGGER_MODULE_OBJECT.write(MODULE_NAME, + "[ERROR] start -> findPreviousContent -> loopBody -> getCandles -> onFileReceived -> err = " + err.stack); + TS.projects.superalgos.globals.loggerVariables.VARIABLES_BY_PROCESS_INDEX_MAP.get(processIndex).BOT_MAIN_LOOP_LOGGER_MODULE_OBJECT.write(MODULE_NAME, + "[ERROR] start -> findPreviousContent -> loopBody -> getCandles -> onFileReceived -> Asuming this is a temporary situation. Requesting a Retry."); + callBackFunction(TS.projects.superalgos.globals.standardResponses.DEFAULT_RETRY_RESPONSE); + } + } else { + TS.projects.superalgos.globals.loggerVariables.VARIABLES_BY_PROCESS_INDEX_MAP.get(processIndex).BOT_MAIN_LOOP_LOGGER_MODULE_OBJECT.write(MODULE_NAME, + "[ERROR] start -> findPreviousContent -> loopBody -> getCandles -> onFileReceived -> err = " + err.stack); + callBackFunction(err); + } + } + } + + function getVolumes() { + let fileName = 'Data.json'; + let filePath = + TS.projects.superalgos.globals.processVariables.VARIABLES_BY_PROCESS_INDEX_MAP.get(processIndex).FILE_PATH_ROOT + + "/Output/" + + VOLUMES_FOLDER_NAME + "/" + + TS.projects.superalgos.globals.taskConstants.TASK_NODE.bot.processes[processIndex].referenceParent.config.codeName + "/" + + timeFrame; + filePath += '/' + fileName + + fileStorage.getTextFile(filePath, onFileReceived); + + TS.projects.superalgos.globals.loggerVariables.VARIABLES_BY_PROCESS_INDEX_MAP.get(processIndex).BOT_MAIN_LOOP_LOGGER_MODULE_OBJECT.write(MODULE_NAME, + "[INFO] start -> findPreviousContent -> loopBody -> getVolumes -> getting file."); + + function onFileReceived(err, text) { + let volumesFile + + if (err.result === TS.projects.superalgos.globals.standardResponses.DEFAULT_OK_RESPONSE.result) { + try { + volumesFile = JSON.parse(text); + previousVolumes = volumesFile; + allPreviousCandles.push(previousCandles); + allPreviousVolumes.push(previousVolumes); + + controlLoop(); + + } catch (err) { + TS.projects.superalgos.globals.loggerVariables.VARIABLES_BY_PROCESS_INDEX_MAP.get(processIndex).BOT_MAIN_LOOP_LOGGER_MODULE_OBJECT.write(MODULE_NAME, + "[ERROR] start -> findPreviousContent -> loopBody -> getVolumes -> onFileReceived -> fileName = " + fileName); + TS.projects.superalgos.globals.loggerVariables.VARIABLES_BY_PROCESS_INDEX_MAP.get(processIndex).BOT_MAIN_LOOP_LOGGER_MODULE_OBJECT.write(MODULE_NAME, + "[ERROR] start -> findPreviousContent -> loopBody -> getVolumes -> onFileReceived -> filePath = " + filePath); + TS.projects.superalgos.globals.loggerVariables.VARIABLES_BY_PROCESS_INDEX_MAP.get(processIndex).BOT_MAIN_LOOP_LOGGER_MODULE_OBJECT.write(MODULE_NAME, + "[ERROR] start -> findPreviousContent -> loopBody -> getVolumes -> onFileReceived -> err = " + err.stack); + TS.projects.superalgos.globals.loggerVariables.VARIABLES_BY_PROCESS_INDEX_MAP.get(processIndex).BOT_MAIN_LOOP_LOGGER_MODULE_OBJECT.write(MODULE_NAME, + "[ERROR] start -> findPreviousContent -> loopBody -> getVolumes -> onFileReceived -> Asuming this is a temporary situation. Requesting a Retry."); + callBackFunction(TS.projects.superalgos.globals.standardResponses.DEFAULT_RETRY_RESPONSE); + } + } else { + TS.projects.superalgos.globals.loggerVariables.VARIABLES_BY_PROCESS_INDEX_MAP.get(processIndex).BOT_MAIN_LOOP_LOGGER_MODULE_OBJECT.write(MODULE_NAME, + "[ERROR] start -> findPreviousContent -> loopBody -> getVolumes -> onFileReceived -> err = " + err.stack); + callBackFunction(err); + } + } + } + + } + + function controlLoop() { + n++ + if (n < TS.projects.superalgos.globals.timeFrames.marketFilesPeriods().length) { + loopBody() + } else { + buildCandles(allPreviousCandles, allPreviousVolumes); + } + } + } + catch (err) { + TS.projects.superalgos.globals.processVariables.VARIABLES_BY_PROCESS_INDEX_MAP.get(processIndex).UNEXPECTED_ERROR = err + TS.projects.superalgos.globals.loggerVariables.VARIABLES_BY_PROCESS_INDEX_MAP.get(processIndex).BOT_MAIN_LOOP_LOGGER_MODULE_OBJECT.write(MODULE_NAME, + "[ERROR] start -> findPreviousContent -> err = " + err.stack); + callBackFunction(TS.projects.superalgos.globals.standardResponses.DEFAULT_FAIL_RESPONSE); + } + } + + function buildCandles(allPreviousCandles, allPreviousVolumes) { + + try { + let fromDate = new Date(contextVariables.datetimeLastProducedFile.valueOf()) + let lastDate = TS.projects.superalgos.utilities.dateTimeFunctions.removeTime(new Date()) + /* + Firstly we prepere the arrays that will accumulate all the information for each output file. + */ + let outputCandles = []; + let outputVolumes = []; + + for (let n = 0; n < TS.projects.superalgos.globals.timeFrames.marketFilesPeriods().length; n++) { + const emptyArray1 = []; + const emptyArray2 = []; + outputCandles.push(emptyArray1); + outputVolumes.push(emptyArray2); + } + + advanceTime() + + function advanceTime() { + /* + We position ourselves on the latest date that was added to the market files + since we are going to re-process that date, removing first the elements of that + date and then adding again all the elements found right now at that date and then + from there into the future. + */ + contextVariables.datetimeLastProducedFile = new Date(contextVariables.datetimeLastProducedFile.valueOf() + TS.projects.superalgos.globals.timeConstants.ONE_DAY_IN_MILISECONDS); + + TS.projects.superalgos.globals.loggerVariables.VARIABLES_BY_PROCESS_INDEX_MAP.get(processIndex).BOT_MAIN_LOOP_LOGGER_MODULE_OBJECT.write(MODULE_NAME, + "[INFO] start -> buildCandles -> advanceTime -> New processing time @ " + contextVariables.datetimeLastProducedFile.getUTCFullYear() + "/" + (contextVariables.datetimeLastProducedFile.getUTCMonth() + 1) + "/" + contextVariables.datetimeLastProducedFile.getUTCDate() + ".") + + /* Validation that we are not going past the head of the market. */ + if (contextVariables.datetimeLastProducedFile.valueOf() > contextVariables.datetimeLastAvailableDependencyFile.valueOf()) { + + TS.projects.superalgos.globals.loggerVariables.VARIABLES_BY_PROCESS_INDEX_MAP.get(processIndex).BOT_MAIN_LOOP_LOGGER_MODULE_OBJECT.write(MODULE_NAME, + "[INFO] start -> buildCandles -> advanceTime -> Head of the market found @ " + contextVariables.datetimeLastProducedFile.getUTCFullYear() + "/" + (contextVariables.datetimeLastProducedFile.getUTCMonth() + 1) + "/" + contextVariables.datetimeLastProducedFile.getUTCDate() + ".") + + callBackFunction(TS.projects.superalgos.globals.standardResponses.DEFAULT_OK_RESPONSE); // Here is where we finish processing and wait for the platform to run this module again. + return + } + + /* Telling the world we are alive and doing well */ + let currentDateString = + contextVariables.datetimeLastProducedFile.getUTCFullYear() + '-' + + TS.projects.superalgos.utilities.miscellaneousFunctions.pad(contextVariables.datetimeLastProducedFile.getUTCMonth() + 1, 2) + '-' + + TS.projects.superalgos.utilities.miscellaneousFunctions.pad(contextVariables.datetimeLastProducedFile.getUTCDate(), 2); + let currentDate = new Date(contextVariables.datetimeLastProducedFile) + let percentage = TS.projects.superalgos.utilities.dateTimeFunctions.getPercentage(fromDate, currentDate, lastDate) + TS.projects.superalgos.functionLibraries.processFunctions.processHeartBeat(processIndex, currentDateString, percentage) + + if (TS.projects.superalgos.utilities.dateTimeFunctions.areTheseDatesEqual(currentDate, new Date()) === false) { + TS.projects.superalgos.globals.loggerVariables.VARIABLES_BY_PROCESS_INDEX_MAP.get(processIndex).BOT_MAIN_LOOP_LOGGER_MODULE_OBJECT.newInternalLoop(currentDate, percentage); + } + timeframesLoop() + } + + function timeframesLoop() { + /* + We will iterate through all posible time frames. + */ + let n = 0 // loop Variable representing each possible period as defined at the periods array. + + loopBody() + + function loopBody() { + let previousCandles // This is an array with all the elements already existing for a certain time frame. + let previousVolumes + + if (allPreviousCandles !== undefined) { + previousCandles = allPreviousCandles[n]; + previousVolumes = allPreviousVolumes[n]; + } + + const outputPeriod = TS.projects.superalgos.globals.timeFrames.marketFilesPeriods()[n][0]; + const timeFrame = TS.projects.superalgos.globals.timeFrames.marketFilesPeriods()[n][1]; + /* + Here we are inside a Loop that is going to advance 1 day at the time, + at each pass, we will read one of Exchange Raw Data's daily files and + add all its candles to our in memory arrays. + + At the first iteration of this loop, we will add the candles that we are carrying + from our previous run, the ones we already have in-memory. + + You can see below how we discard the elements that + belong to the first day we are processing at this run, + that it is exactly the same as the last day processed the previous + run. By discarding these candles, we are ready to run after that standard + function that will just add ALL the candles found each day at Exchange Raw Data. + */ + if (previousCandles !== undefined && previousCandles.length !== 0) { + for (let i = 0; i < previousCandles.length; i++) { + let candle = { + open: previousCandles[i][2], + close: previousCandles[i][3], + min: previousCandles[i][0], + max: previousCandles[i][1], + begin: previousCandles[i][4], + end: previousCandles[i][5] + } + + if (candle.end < contextVariables.datetimeLastProducedFile.valueOf()) { + outputCandles[n].push(candle); + } else { + TS.projects.superalgos.globals.loggerVariables.VARIABLES_BY_PROCESS_INDEX_MAP.get(processIndex).BOT_MAIN_LOOP_LOGGER_MODULE_OBJECT.write(MODULE_NAME, + "[INFO] start -> buildCandles -> timeframesLoop -> loopBody -> Candle # " + i + " @ " + timeFrame + " discarded for closing past the current process time.") + } + } + allPreviousCandles[n] = [] // erasing these so as not to duplicate them. + } + + if (previousVolumes !== undefined && previousVolumes.length !== 0) { + + for (let i = 0; i < previousVolumes.length; i++) { + let volume = { + begin: previousVolumes[i][2], + end: previousVolumes[i][3], + buy: previousVolumes[i][0], + sell: previousVolumes[i][1] + } + + if (volume.end < contextVariables.datetimeLastProducedFile.valueOf()) { + + outputVolumes[n].push(volume); + + } else { + TS.projects.superalgos.globals.loggerVariables.VARIABLES_BY_PROCESS_INDEX_MAP.get(processIndex).BOT_MAIN_LOOP_LOGGER_MODULE_OBJECT.write(MODULE_NAME, + "[INFO] start -> buildCandles -> timeframesLoop -> loopBody -> Volume # " + i + " @ " + timeFrame + " discarded for closing past the current process time.") + } + } + allPreviousVolumes[n] = []; // erasing these so as not to duplicate them. + } + /* + From here on is where every iteration of the loop fully runs. Here is where we + read Exchange Raw Data's files and add their content to whatever + we already have in our arrays in-memory. In this way the process will run as + many days needed and it should only stop when it reaches + the head of the market. + */ + nextCandleFile(); + + function nextCandleFile() { + let dateForPath = contextVariables.datetimeLastProducedFile.getUTCFullYear() + '/' + TS.projects.superalgos.utilities.miscellaneousFunctions.pad(contextVariables.datetimeLastProducedFile.getUTCMonth() + 1, 2) + '/' + TS.projects.superalgos.utilities.miscellaneousFunctions.pad(contextVariables.datetimeLastProducedFile.getUTCDate(), 2); + let fileName = "Data.json" + + let filePathRoot = + 'Project/' + + TS.projects.superalgos.globals.taskConstants.PROJECT_DEFINITION_NODE.config.codeName + "/" + + TS.projects.superalgos.globals.taskConstants.TASK_NODE.bot.processes[processIndex].referenceParent.parentNode.parentNode.type.replace(' ', '-') + "/" + + TS.projects.superalgos.globals.taskConstants.TASK_NODE.bot.processes[processIndex].referenceParent.parentNode.parentNode.config.codeName + "/" + + "Exchange-Raw-Data" + '/' + TS.projects.superalgos.globals.taskConstants.TASK_NODE.parentNode.parentNode.parentNode.referenceParent.parentNode.parentNode.config.codeName + "/" + + TS.projects.superalgos.globals.taskConstants.TASK_NODE.parentNode.parentNode.parentNode.referenceParent.baseAsset.referenceParent.config.codeName + "-" + + TS.projects.superalgos.globals.taskConstants.TASK_NODE.parentNode.parentNode.parentNode.referenceParent.quotedAsset.referenceParent.config.codeName + let filePath = filePathRoot + "/Output/" + DEPENDENCY_FOLDER_NAME + '/' + DEPENDENCY_ONE_MIN + '/' + dateForPath; + filePath += '/' + fileName + + fileStorage.getTextFile(filePath, onFileReceived); + + TS.projects.superalgos.globals.loggerVariables.VARIABLES_BY_PROCESS_INDEX_MAP.get(processIndex).BOT_MAIN_LOOP_LOGGER_MODULE_OBJECT.write(MODULE_NAME, + "[INFO] start -> buildCandles -> timeframesLoop -> loopBody -> nextCandleFile -> getting file at dateForPath = " + dateForPath); + + function onFileReceived(err, text) { + try { + let candlesFile + + if (err.result === TS.projects.superalgos.globals.standardResponses.DEFAULT_OK_RESPONSE.result) { + try { + candlesFile = JSON.parse(text); + } catch (err) { + TS.projects.superalgos.globals.loggerVariables.VARIABLES_BY_PROCESS_INDEX_MAP.get(processIndex).BOT_MAIN_LOOP_LOGGER_MODULE_OBJECT.write(MODULE_NAME, + "[ERROR] start -> buildCandles -> timeframesLoop -> loopBody -> nextCandleFile -> onFileReceived -> Error Parsing JSON -> err = " + err.stack); + TS.projects.superalgos.globals.loggerVariables.VARIABLES_BY_PROCESS_INDEX_MAP.get(processIndex).BOT_MAIN_LOOP_LOGGER_MODULE_OBJECT.write(MODULE_NAME, + "[ERROR] start -> buildCandles -> timeframesLoop -> loopBody -> nextCandleFile -> onFileReceived -> Asuming this is a temporary situation. Requesting a Retry."); + callBackFunction(TS.projects.superalgos.globals.standardResponses.DEFAULT_RETRY_RESPONSE); + return + } + } else { + + if (err.message === 'File does not exist.' || err.code === 'The specified key does not exist.') { + + TS.projects.superalgos.globals.loggerVariables.VARIABLES_BY_PROCESS_INDEX_MAP.get(processIndex).BOT_MAIN_LOOP_LOGGER_MODULE_OBJECT.write(MODULE_NAME, + "[WARN] start -> buildCandles -> timeframesLoop -> loopBody -> nextCandleFile -> onFileReceived -> Dependency Not Ready -> err = " + JSON.stringify(err)); + TS.projects.superalgos.globals.loggerVariables.VARIABLES_BY_PROCESS_INDEX_MAP.get(processIndex).BOT_MAIN_LOOP_LOGGER_MODULE_OBJECT.write(MODULE_NAME, + "[WARN] start -> buildCandles -> timeframesLoop -> loopBody -> nextCandleFile -> onFileReceived -> Asuming this is a temporary situation. Requesting a Retry."); + callBackFunction(TS.projects.superalgos.globals.standardResponses.DEFAULT_RETRY_RESPONSE); + return + + } else { + TS.projects.superalgos.globals.loggerVariables.VARIABLES_BY_PROCESS_INDEX_MAP.get(processIndex).BOT_MAIN_LOOP_LOGGER_MODULE_OBJECT.write(MODULE_NAME, + "[ERROR] start -> buildCandles -> timeframesLoop -> loopBody -> nextCandleFile -> onFileReceived -> Error Received -> err = " + err.stack); + callBackFunction(err) + return + } + } + + const inputCandlesPerdiod = 60 * 1000; // 1 min + const inputFilePeriod = 24 * 60 * 60 * 1000; // 24 hs + let totalOutputCandles = inputFilePeriod / outputPeriod; // this should be 2 in this case. + let beginingOutputTime = contextVariables.datetimeLastProducedFile.valueOf(); + /* + The algorithm that follows is going to agregate candles of 1 min timeFrame read from Exchange Raw Data, into candles of each timeFrame + that Candles Volumes generates. For market files those timePediods goes from 1h to 24hs. + */ + for (let i = 0; i < totalOutputCandles; i++) { + + let outputCandle = { + open: 0, + close: 0, + min: 0, + max: 0, + begin: 0, + end: 0 + }; + + let saveCandle = false; + outputCandle.begin = beginingOutputTime + i * outputPeriod; + outputCandle.end = beginingOutputTime + (i + 1) * outputPeriod - 1; + + for (let j = 0; j < candlesFile.length; j++) { + let candle = { + open: candlesFile[j][2], + close: candlesFile[j][3], + min: candlesFile[j][0], + max: candlesFile[j][1], + begin: candlesFile[j][4], + end: candlesFile[j][5] + } + /* Here we discard all the candles out of range. */ + if (candle.begin >= outputCandle.begin && candle.end <= outputCandle.end) { + + if (saveCandle === false) { // this will set the value only once. + outputCandle.open = candle.open; + outputCandle.min = candle.min; + outputCandle.max = candle.max; + } + + saveCandle = true; + outputCandle.close = candle.close; // only the last one will be saved + if (candle.min < outputCandle.min) { + outputCandle.min = candle.min; + } + if (candle.max > outputCandle.max) { + outputCandle.max = candle.max; + } + } + } + if (saveCandle === true) { // then we have a valid candle, otherwise it means there were no candles to fill this one in its time range. + outputCandles[n].push(outputCandle); + } + } + nextVolumeFile(); + + } catch (err) { + TS.projects.superalgos.globals.processVariables.VARIABLES_BY_PROCESS_INDEX_MAP.get(processIndex).UNEXPECTED_ERROR = err + TS.projects.superalgos.globals.loggerVariables.VARIABLES_BY_PROCESS_INDEX_MAP.get(processIndex).BOT_MAIN_LOOP_LOGGER_MODULE_OBJECT.write(MODULE_NAME, + "[ERROR] start -> buildCandles -> timeframesLoop -> loopBody -> nextCandleFile -> onFileReceived -> err = " + err.stack); + callBackFunction(TS.projects.superalgos.globals.standardResponses.DEFAULT_FAIL_RESPONSE); + } + } + } + + function nextVolumeFile() { + try { + TS.projects.superalgos.globals.loggerVariables.VARIABLES_BY_PROCESS_INDEX_MAP.get(processIndex).BOT_MAIN_LOOP_LOGGER_MODULE_OBJECT.write(MODULE_NAME, + "[INFO] start -> buildCandles -> timeframesLoop -> loopBody -> nextVolumeFile -> Entering function.") + + let dateForPath = + contextVariables.datetimeLastProducedFile.getUTCFullYear() + '/' + + TS.projects.superalgos.utilities.miscellaneousFunctions.pad(contextVariables.datetimeLastProducedFile.getUTCMonth() + 1, 2) + '/' + + TS.projects.superalgos.utilities.miscellaneousFunctions.pad(contextVariables.datetimeLastProducedFile.getUTCDate(), 2); + let fileName = "Data.json" + + let filePathRoot = + 'Project/' + + TS.projects.superalgos.globals.taskConstants.PROJECT_DEFINITION_NODE.config.codeName + "/" + + TS.projects.superalgos.globals.taskConstants.TASK_NODE.bot.processes[processIndex].referenceParent.parentNode.parentNode.type.replace(' ', '-') + "/" + + TS.projects.superalgos.globals.taskConstants.TASK_NODE.bot.processes[processIndex].referenceParent.parentNode.parentNode.config.codeName + "/" + + "Exchange-Raw-Data" + '/' + TS.projects.superalgos.globals.taskConstants.TASK_NODE.parentNode.parentNode.parentNode.referenceParent.parentNode.parentNode.config.codeName + "/" + + TS.projects.superalgos.globals.taskConstants.TASK_NODE.parentNode.parentNode.parentNode.referenceParent.baseAsset.referenceParent.config.codeName + "-" + + TS.projects.superalgos.globals.taskConstants.TASK_NODE.parentNode.parentNode.parentNode.referenceParent.quotedAsset.referenceParent.config.codeName + let filePath = filePathRoot + "/Output/" + VOLUMES_FOLDER_NAME + '/' + VOLUMES_ONE_MIN + '/' + dateForPath; + filePath += '/' + fileName + fileStorage.getTextFile(filePath, onFileReceived); + + TS.projects.superalgos.globals.loggerVariables.VARIABLES_BY_PROCESS_INDEX_MAP.get(processIndex).BOT_MAIN_LOOP_LOGGER_MODULE_OBJECT.write(MODULE_NAME, + "[INFO] start -> buildCandles -> timeframesLoop -> loopBody -> nextVolumeFile -> getting file at dateForPath = " + dateForPath); + + function onFileReceived(err, text) { + TS.projects.superalgos.globals.loggerVariables.VARIABLES_BY_PROCESS_INDEX_MAP.get(processIndex).BOT_MAIN_LOOP_LOGGER_MODULE_OBJECT.write(MODULE_NAME, + "[INFO] start -> buildCandles -> timeframesLoop -> loopBody -> nextVolumeFile -> onFileReceived -> Entering function.") + + let volumesFile + if (err.result === TS.projects.superalgos.globals.standardResponses.DEFAULT_OK_RESPONSE.result) { + try { + volumesFile = JSON.parse(text); + + } catch (err) { + TS.projects.superalgos.globals.loggerVariables.VARIABLES_BY_PROCESS_INDEX_MAP.get(processIndex).BOT_MAIN_LOOP_LOGGER_MODULE_OBJECT.write(MODULE_NAME, + "[ERROR] start -> buildCandles -> timeframesLoop -> loopBody -> nextVolumeFile -> onFileReceived -> Error Parsing JSON -> err = " + err.stack); + TS.projects.superalgos.globals.loggerVariables.VARIABLES_BY_PROCESS_INDEX_MAP.get(processIndex).BOT_MAIN_LOOP_LOGGER_MODULE_OBJECT.write(MODULE_NAME, + "[ERROR] start -> buildCandles -> timeframesLoop -> loopBody -> nextVolumeFile -> onFileReceived -> Asuming this is a temporary situation. Requesting a Retry."); + callBackFunction(TS.projects.superalgos.globals.standardResponses.DEFAULT_RETRY_RESPONSE); + return; + } + } else { + TS.projects.superalgos.globals.loggerVariables.VARIABLES_BY_PROCESS_INDEX_MAP.get(processIndex).BOT_MAIN_LOOP_LOGGER_MODULE_OBJECT.write(MODULE_NAME, + "[ERROR] start -> buildCandles -> timeframesLoop -> loopBody -> nextVolumeFile -> onFileReceived -> Error Received -> err = " + err.stack); + callBackFunction(err); + return; + } + const inputVolumesPerdiod = 60 * 1000; // 1 min + const inputFilePeriod = 24 * 60 * 60 * 1000; // 24 hs + + let totalOutputVolumes = inputFilePeriod / outputPeriod; // this should be 2 in this case. + let beginingOutputTime = contextVariables.datetimeLastProducedFile.valueOf(); + + for (let i = 0; i < totalOutputVolumes; i++) { + let outputVolume = { + buy: 0, + sell: 0, + begin: 0, + end: 0 + } + + let saveVolume = false; + outputVolume.begin = beginingOutputTime + i * outputPeriod; + outputVolume.end = beginingOutputTime + (i + 1) * outputPeriod - 1; + + for (let j = 0; j < volumesFile.length; j++) { + let volume = { + buy: volumesFile[j][0], + sell: volumesFile[j][1], + begin: volumesFile[j][2], + end: volumesFile[j][3] + } + + /* Here we discard all the Volumes out of range. */ + if (volume.begin >= outputVolume.begin && volume.end <= outputVolume.end) { + + saveVolume = true; + + outputVolume.buy = outputVolume.buy + volume.buy; + outputVolume.sell = outputVolume.sell + volume.sell; + } + } + + if (saveVolume === true) { + outputVolumes[n].push(outputVolume); + } + } + + writeFiles(outputCandles[n], outputVolumes[n], timeFrame, controlLoop); + } + } catch (err) { + TS.projects.superalgos.globals.processVariables.VARIABLES_BY_PROCESS_INDEX_MAP.get(processIndex).UNEXPECTED_ERROR = err + TS.projects.superalgos.globals.loggerVariables.VARIABLES_BY_PROCESS_INDEX_MAP.get(processIndex).BOT_MAIN_LOOP_LOGGER_MODULE_OBJECT.write(MODULE_NAME, + "[ERROR] start -> buildCandles -> timeframesLoop -> loopBody -> nextVolumeFile -> onFileReceived -> err = " + err.stack); + callBackFunction(TS.projects.superalgos.globals.standardResponses.DEFAULT_FAIL_RESPONSE); + } + } + } + + function controlLoop() { + + TS.projects.superalgos.globals.loggerVariables.VARIABLES_BY_PROCESS_INDEX_MAP.get(processIndex).BOT_MAIN_LOOP_LOGGER_MODULE_OBJECT.write(MODULE_NAME, + "[INFO] start -> buildCandles -> timeframesLoop -> controlLoop -> Entering function.") + n++ + if (n < TS.projects.superalgos.globals.timeFrames.marketFilesPeriods().length) { + loopBody() + } else { + writeStatusReport(contextVariables.datetimeLastProducedFile, advanceTime); + } + } + } + } + catch (err) { + TS.projects.superalgos.globals.loggerVariables.VARIABLES_BY_PROCESS_INDEX_MAP.get(processIndex).BOT_MAIN_LOOP_LOGGER_MODULE_OBJECT.write(MODULE_NAME, + "[ERROR] start -> buildCandles -> err = " + err.stack); + callBackFunction(TS.projects.superalgos.globals.standardResponses.DEFAULT_FAIL_RESPONSE); + } + } + + function writeFiles(candles, volumes, timeFrame, callBack) { + + TS.projects.superalgos.globals.loggerVariables.VARIABLES_BY_PROCESS_INDEX_MAP.get(processIndex).BOT_MAIN_LOOP_LOGGER_MODULE_OBJECT.write(MODULE_NAME, + "[INFO] start -> writeFiles -> Entering function.") + /* + Here we will write the contents of the Candles and Volumens files. + */ + try { + writeCandles() + + function writeCandles() { + + TS.projects.superalgos.globals.loggerVariables.VARIABLES_BY_PROCESS_INDEX_MAP.get(processIndex).BOT_MAIN_LOOP_LOGGER_MODULE_OBJECT.write(MODULE_NAME, + "[INFO] start -> writeFiles -> writeCandles -> Entering function.") + + let separator = "" + let fileRecordCounter = 0 + let fileContent = "" + + for (let i = 0; i < candles.length; i++) { + let candle = candles[i]; + fileContent = fileContent + separator + '[' + candles[i].min + "," + candles[i].max + "," + candles[i].open + "," + candles[i].close + "," + candles[i].begin + "," + candles[i].end + "]"; + if (separator === "") { separator = ","; } + fileRecordCounter++ + } + + fileContent = "[" + fileContent + "]"; + + let fileName = 'Data.json'; + let filePath = TS.projects.superalgos.globals.processVariables.VARIABLES_BY_PROCESS_INDEX_MAP.get(processIndex).FILE_PATH_ROOT + + "/Output/" + + DEPENDENCY_FOLDER_NAME + "/" + + TS.projects.superalgos.globals.taskConstants.TASK_NODE.bot.processes[processIndex].referenceParent.config.codeName + "/" + + timeFrame + filePath += '/' + fileName + + fileStorage.createTextFile(filePath, fileContent + '\n', onFileCreated); + + TS.projects.superalgos.globals.loggerVariables.VARIABLES_BY_PROCESS_INDEX_MAP.get(processIndex).BOT_MAIN_LOOP_LOGGER_MODULE_OBJECT.write(MODULE_NAME, + "[INFO] start -> writeFiles -> writeCandles -> creating file at filePath = " + filePath); + + function onFileCreated(err) { + TS.projects.superalgos.globals.loggerVariables.VARIABLES_BY_PROCESS_INDEX_MAP.get(processIndex).BOT_MAIN_LOOP_LOGGER_MODULE_OBJECT.write(MODULE_NAME, + "[INFO] start -> writeFiles -> writeCandles -> onFileCreated -> Entering function.") + + if (err.result !== TS.projects.superalgos.globals.standardResponses.DEFAULT_OK_RESPONSE.result) { + TS.projects.superalgos.globals.loggerVariables.VARIABLES_BY_PROCESS_INDEX_MAP.get(processIndex).BOT_MAIN_LOOP_LOGGER_MODULE_OBJECT.write(MODULE_NAME, + "[ERROR] start -> writeFiles -> writeCandles -> onFileCreated -> err = " + err.stack) + callBackFunction(err) + return + } + + TS.projects.superalgos.globals.loggerVariables.VARIABLES_BY_PROCESS_INDEX_MAP.get(processIndex).BOT_MAIN_LOOP_LOGGER_MODULE_OBJECT.write(MODULE_NAME, + "[WARN] start -> writeFiles -> writeCandles -> onFileCreated -> Finished with File @ " + TS.projects.superalgos.globals.taskConstants.TASK_NODE.parentNode.parentNode.parentNode.referenceParent.baseAsset.referenceParent.config.codeName + "_" + TS.projects.superalgos.globals.taskConstants.TASK_NODE.parentNode.parentNode.parentNode.referenceParent.quotedAsset.referenceParent.config.codeName + ", " + fileRecordCounter + " records inserted into " + filePath + "/" + fileName) + writeVolumes() + } + } + + function writeVolumes() { + let separator = ""; + let fileRecordCounter = 0; + let fileContent = ""; + + for (let i = 0; i < volumes.length; i++) { + let candle = volumes[i]; + fileContent = fileContent + separator + '[' + volumes[i].buy + "," + volumes[i].sell + "," + volumes[i].begin + "," + volumes[i].end + "]"; + if (separator === "") { separator = ","; } + fileRecordCounter++ + } + + fileContent = "[" + fileContent + "]"; + + let fileName = 'Data.json'; + let filePath = TS.projects.superalgos.globals.processVariables.VARIABLES_BY_PROCESS_INDEX_MAP.get(processIndex).FILE_PATH_ROOT + "/Output/" + VOLUMES_FOLDER_NAME + "/" + TS.projects.superalgos.globals.taskConstants.TASK_NODE.bot.processes[processIndex].referenceParent.config.codeName + "/" + timeFrame; + filePath += '/' + fileName + + fileStorage.createTextFile(filePath, fileContent + '\n', onFileCreated); + + TS.projects.superalgos.globals.loggerVariables.VARIABLES_BY_PROCESS_INDEX_MAP.get(processIndex).BOT_MAIN_LOOP_LOGGER_MODULE_OBJECT.write(MODULE_NAME, + "[INFO] start -> writeFiles -> writeVolumes -> creating file at filePath = " + filePath); + + function onFileCreated(err) { + if (err.result !== TS.projects.superalgos.globals.standardResponses.DEFAULT_OK_RESPONSE.result) { + TS.projects.superalgos.globals.loggerVariables.VARIABLES_BY_PROCESS_INDEX_MAP.get(processIndex).BOT_MAIN_LOOP_LOGGER_MODULE_OBJECT.write(MODULE_NAME, + "[ERROR] start -> writeFiles -> writeVolumes -> onFileCreated -> err = " + err.stack); + callBackFunction(err); + return; + } + + TS.projects.superalgos.globals.loggerVariables.VARIABLES_BY_PROCESS_INDEX_MAP.get(processIndex).BOT_MAIN_LOOP_LOGGER_MODULE_OBJECT.write(MODULE_NAME, + "[WARN] start -> writeFiles -> writeVolumes -> onFileCreated -> Finished with File @ " + TS.projects.superalgos.globals.taskConstants.TASK_NODE.parentNode.parentNode.parentNode.referenceParent.baseAsset.referenceParent.config.codeName + "_" + TS.projects.superalgos.globals.taskConstants.TASK_NODE.parentNode.parentNode.parentNode.referenceParent.quotedAsset.referenceParent.config.codeName + ", " + fileRecordCounter + " records inserted into " + filePath + "/" + fileName); + + callBack() + } + } + } + catch (err) { + TS.projects.superalgos.globals.processVariables.VARIABLES_BY_PROCESS_INDEX_MAP.get(processIndex).UNEXPECTED_ERROR = err + TS.projects.superalgos.globals.loggerVariables.VARIABLES_BY_PROCESS_INDEX_MAP.get(processIndex).BOT_MAIN_LOOP_LOGGER_MODULE_OBJECT.write(MODULE_NAME, + "[ERROR] start -> writeFiles -> err = " + err.stack); + callBackFunction(TS.projects.superalgos.globals.standardResponses.DEFAULT_FAIL_RESPONSE); + } + } + + function writeStatusReport(lastFileDate, callBack) { + TS.projects.superalgos.globals.loggerVariables.VARIABLES_BY_PROCESS_INDEX_MAP.get(processIndex).BOT_MAIN_LOOP_LOGGER_MODULE_OBJECT.write(MODULE_NAME, + "[INFO] start -> writeStatusReport -> lastFileDate = " + lastFileDate) + + try { + let reportKey = "Masters" + "-" + "Candles-Volumes" + "-" + "Multi-Period-Market" + let thisReport = statusDependencies.statusReports.get(reportKey) + + thisReport.file.lastExecution = TS.projects.superalgos.globals.processVariables.VARIABLES_BY_PROCESS_INDEX_MAP.get(processIndex).PROCESS_DATETIME + thisReport.file.lastFile = lastFileDate + thisReport.file.beginingOfMarket = beginingOfMarket.toUTCString() + thisReport.save(callBack) + } + catch (err) { + TS.projects.superalgos.globals.processVariables.VARIABLES_BY_PROCESS_INDEX_MAP.get(processIndex).UNEXPECTED_ERROR = err + TS.projects.superalgos.globals.loggerVariables.VARIABLES_BY_PROCESS_INDEX_MAP.get(processIndex).BOT_MAIN_LOOP_LOGGER_MODULE_OBJECT.write(MODULE_NAME, + "[ERROR] start -> writeStatusReport -> err = " + err.stack); + callBackFunction(TS.projects.superalgos.globals.standardResponses.DEFAULT_FAIL_RESPONSE) + } + } + } + catch (err) { + TS.projects.superalgos.globals.processVariables.VARIABLES_BY_PROCESS_INDEX_MAP.get(processIndex).UNEXPECTED_ERROR = err + TS.projects.superalgos.globals.loggerVariables.VARIABLES_BY_PROCESS_INDEX_MAP.get(processIndex).BOT_MAIN_LOOP_LOGGER_MODULE_OBJECT.write(MODULE_NAME, + "[ERROR] start -> err = " + err.stack); + callBackFunction(TS.projects.superalgos.globals.standardResponses.DEFAULT_FAIL_RESPONSE) + } + } +} diff --git a/Projects/Superalgos/TS/Bot-Modules/Indicator-Bot/MultiPeriodDaily.js b/Projects/Superalgos/TS/Bot-Modules/Indicator-Bot/MultiPeriodDaily.js index 7892b5bc8..79d75c321 100644 --- a/Projects/Superalgos/TS/Bot-Modules/Indicator-Bot/MultiPeriodDaily.js +++ b/Projects/Superalgos/TS/Bot-Modules/Indicator-Bot/MultiPeriodDaily.js @@ -4,7 +4,7 @@ This module deals with Daily Files, that are data files for Time Frames below 1 hour. It also assumes that the data dependencias are in Daily Files, one file for each Time Frame. */ - thisObject = { + let thisObject = { initialize: initialize, finalize: finalize, start: start diff --git a/Projects/Superalgos/TS/Bot-Modules/Indicator-Bot/MultiPeriodMarket.js b/Projects/Superalgos/TS/Bot-Modules/Indicator-Bot/MultiPeriodMarket.js index c7317b6b1..7c1e0ba5b 100644 --- a/Projects/Superalgos/TS/Bot-Modules/Indicator-Bot/MultiPeriodMarket.js +++ b/Projects/Superalgos/TS/Bot-Modules/Indicator-Bot/MultiPeriodMarket.js @@ -4,7 +4,7 @@ This module deals with Market Files, that are data files for Time Frames of 1 hour and above. It also assumes that the data dependencias are in Market Files, one file for each Time Frame. */ - thisObject = { + let thisObject = { initialize: initialize, finalize: finalize, start: start diff --git a/Projects/Superalgos/TS/Bot-Modules/Learning-Bot/Low-Frequency-Learning/LearningProcess.js b/Projects/Superalgos/TS/Bot-Modules/Learning-Bot/Low-Frequency-Learning/LearningProcess.js index fed726982..f70f749e2 100644 --- a/Projects/Superalgos/TS/Bot-Modules/Learning-Bot/Low-Frequency-Learning/LearningProcess.js +++ b/Projects/Superalgos/TS/Bot-Modules/Learning-Bot/Low-Frequency-Learning/LearningProcess.js @@ -5,7 +5,7 @@ */ const MODULE_NAME = "Learning Process" - thisObject = { + let thisObject = { start: start } diff --git a/Projects/Superalgos/TS/Bot-Modules/Sensor-Bot/Exchange-Raw-Data/HistoricOHLCVs.js b/Projects/Superalgos/TS/Bot-Modules/Sensor-Bot/Exchange-Raw-Data/HistoricOHLCVs.js index 4b7ede69d..516259b26 100644 --- a/Projects/Superalgos/TS/Bot-Modules/Sensor-Bot/Exchange-Raw-Data/HistoricOHLCVs.js +++ b/Projects/Superalgos/TS/Bot-Modules/Sensor-Bot/Exchange-Raw-Data/HistoricOHLCVs.js @@ -5,7 +5,7 @@ const VOLUMES_FOLDER_NAME = "Volumes/One-Min"; const OHLCVS_FOLDER_NAME = "OHLCVs/One-Min"; - thisObject = { + let thisObject = { initialize: initialize, start: start }; diff --git a/Projects/Superalgos/TS/Bot-Modules/Sensor-Bot/Webhooks/CheckWebhook.js b/Projects/Superalgos/TS/Bot-Modules/Sensor-Bot/Webhooks/CheckWebhook.js index 8a7b8b805..92022862d 100644 --- a/Projects/Superalgos/TS/Bot-Modules/Sensor-Bot/Webhooks/CheckWebhook.js +++ b/Projects/Superalgos/TS/Bot-Modules/Sensor-Bot/Webhooks/CheckWebhook.js @@ -4,7 +4,7 @@ exports.newSuperalgosBotModulesCheckWebhook = function (processIndex) { const MODULE_NAME = "Check Webhooks"; const FOLDER_NAME = "External-Signals"; - thisObject = { + let thisObject = { initialize: initialize, start: start }; diff --git a/Projects/Superalgos/TS/Bot-Modules/Trading-Bot/Low-Frequency-Trading/TradingProcess.js b/Projects/Superalgos/TS/Bot-Modules/Trading-Bot/Low-Frequency-Trading/TradingProcess.js index b52e4788e..cd630d553 100644 --- a/Projects/Superalgos/TS/Bot-Modules/Trading-Bot/Low-Frequency-Trading/TradingProcess.js +++ b/Projects/Superalgos/TS/Bot-Modules/Trading-Bot/Low-Frequency-Trading/TradingProcess.js @@ -5,7 +5,7 @@ */ const MODULE_NAME = "Trading Process" - thisObject = { + let thisObject = { start: start } diff --git a/Projects/Superalgos/UI/Function-Libraries/ChainAttachDetach.js b/Projects/Superalgos/UI/Function-Libraries/ChainAttachDetach.js index d995126c6..684d0edff 100644 --- a/Projects/Superalgos/UI/Function-Libraries/ChainAttachDetach.js +++ b/Projects/Superalgos/UI/Function-Libraries/ChainAttachDetach.js @@ -1,5 +1,5 @@ function newSuperalgosFunctionLibraryChainAttachDetach() { - thisObject = { + let thisObject = { chainDetachNode: chainDetachNode, chainAttachNode: chainAttachNode } diff --git a/Projects/Superalgos/UI/Function-Libraries/ChartingSpaceFunctions.js b/Projects/Superalgos/UI/Function-Libraries/ChartingSpaceFunctions.js index 6d59e94ec..7e2734508 100644 --- a/Projects/Superalgos/UI/Function-Libraries/ChartingSpaceFunctions.js +++ b/Projects/Superalgos/UI/Function-Libraries/ChartingSpaceFunctions.js @@ -1,5 +1,5 @@ function newSuperalgosFunctionLibraryChartingSpaceFunctions() { - thisObject = { + let thisObject = { addAllLayerPanels: addAllLayerPanels, addAllLayerPolygons: addAllLayerPolygons, addAllMineLayers: addAllMineLayers, diff --git a/Projects/Superalgos/UI/Function-Libraries/CryptoEcosystemFunctions.js b/Projects/Superalgos/UI/Function-Libraries/CryptoEcosystemFunctions.js index ec07cb184..c51c886a7 100644 --- a/Projects/Superalgos/UI/Function-Libraries/CryptoEcosystemFunctions.js +++ b/Projects/Superalgos/UI/Function-Libraries/CryptoEcosystemFunctions.js @@ -1,5 +1,5 @@ function newSuperalgosFunctionLibraryCryptoEcosystemFunctions() { - thisObject = { + let thisObject = { addMissingExchanges: addMissingExchanges, addMissingAssets: addMissingAssets, addMissingMarkets: addMissingMarkets, diff --git a/Projects/Superalgos/UI/Function-Libraries/DataStorageFunctions.js b/Projects/Superalgos/UI/Function-Libraries/DataStorageFunctions.js index a95c9967c..c2b74f7e2 100644 --- a/Projects/Superalgos/UI/Function-Libraries/DataStorageFunctions.js +++ b/Projects/Superalgos/UI/Function-Libraries/DataStorageFunctions.js @@ -1,5 +1,5 @@ function newSuperalgosFunctionLibraryDataStorageFunctions() { - thisObject = { + let thisObject = { addAllDataProducts: addAllDataProducts, addAllDataMineProducts: addAllDataMineProducts, addAllTradingMineProducts: addAllTradingMineProducts, diff --git a/Projects/Superalgos/UI/Function-Libraries/DependenciesFilter.js b/Projects/Superalgos/UI/Function-Libraries/DependenciesFilter.js index ad868af02..b8868569e 100644 --- a/Projects/Superalgos/UI/Function-Libraries/DependenciesFilter.js +++ b/Projects/Superalgos/UI/Function-Libraries/DependenciesFilter.js @@ -12,7 +12,7 @@ function newSuperalgosFunctionLibraryDependenciesFilter() { It is important to note that all nodes that are not of the type Javascript Code or Formula are going to be ignored. */ - thisObject = { + let thisObject = { createDependencyFilter: createDependencyFilter } diff --git a/Projects/Superalgos/UI/Function-Libraries/LearningSessionFunctions.js b/Projects/Superalgos/UI/Function-Libraries/LearningSessionFunctions.js index 6620c9b33..568a7c656 100644 --- a/Projects/Superalgos/UI/Function-Libraries/LearningSessionFunctions.js +++ b/Projects/Superalgos/UI/Function-Libraries/LearningSessionFunctions.js @@ -1,5 +1,5 @@ function newSuperalgosFunctionLibraryLearningSessionFunctions() { - thisObject = { + let thisObject = { syncronizeSessionWithBackEnd: syncronizeSessionWithBackEnd, runSession: runSession, stopSession: stopSession diff --git a/Projects/Superalgos/UI/Function-Libraries/MineFunctions.js b/Projects/Superalgos/UI/Function-Libraries/MineFunctions.js index db27639e1..3a8ed90fa 100644 --- a/Projects/Superalgos/UI/Function-Libraries/MineFunctions.js +++ b/Projects/Superalgos/UI/Function-Libraries/MineFunctions.js @@ -1,5 +1,5 @@ function newSuperalgosFunctionLibraryMineFunctions() { - thisObject = { + let thisObject = { addAllOutputDatasets: addAllOutputDatasets, addAllDataDependencies: addAllDataDependencies, addAllDataMineDataDependencies: addAllDataMineDataDependencies diff --git a/Projects/Superalgos/UI/Function-Libraries/NodeChildren.js b/Projects/Superalgos/UI/Function-Libraries/NodeChildren.js index 6a89a9660..ad585442e 100644 --- a/Projects/Superalgos/UI/Function-Libraries/NodeChildren.js +++ b/Projects/Superalgos/UI/Function-Libraries/NodeChildren.js @@ -1,5 +1,5 @@ function newNodeChildren() { - thisObject = { + let thisObject = { childrenCount: childrenCount } diff --git a/Projects/Superalgos/UI/Function-Libraries/NodeCloning.js b/Projects/Superalgos/UI/Function-Libraries/NodeCloning.js index 6f49d3d23..3b6372fac 100644 --- a/Projects/Superalgos/UI/Function-Libraries/NodeCloning.js +++ b/Projects/Superalgos/UI/Function-Libraries/NodeCloning.js @@ -4,7 +4,7 @@ function newSuperalgosFunctionLibraryNodeCloning() { const logger = newWebDebugLog() - thisObject = { + let thisObject = { getNodeClone: getNodeClone } return thisObject diff --git a/Projects/Superalgos/UI/Function-Libraries/NodeDeleter.js b/Projects/Superalgos/UI/Function-Libraries/NodeDeleter.js index 769966af1..d724e995e 100644 --- a/Projects/Superalgos/UI/Function-Libraries/NodeDeleter.js +++ b/Projects/Superalgos/UI/Function-Libraries/NodeDeleter.js @@ -1,5 +1,5 @@ function newSuperalgosFunctionLibraryNodeDeleter() { - thisObject = { + let thisObject = { deleteWorkspace: deleteWorkspace, deleteUIObject: deleteUIObject } diff --git a/Projects/Superalgos/UI/Function-Libraries/NodePath.js b/Projects/Superalgos/UI/Function-Libraries/NodePath.js index 9c92dafda..942b17fe0 100644 --- a/Projects/Superalgos/UI/Function-Libraries/NodePath.js +++ b/Projects/Superalgos/UI/Function-Libraries/NodePath.js @@ -1,5 +1,5 @@ function newSuperalgosFunctionLibraryNodePath() { - thisObject = { + let thisObject = { getNodePath: getNodePath } diff --git a/Projects/Superalgos/UI/Function-Libraries/OnFocus.js b/Projects/Superalgos/UI/Function-Libraries/OnFocus.js index 10e567514..d76bb185d 100644 --- a/Projects/Superalgos/UI/Function-Libraries/OnFocus.js +++ b/Projects/Superalgos/UI/Function-Libraries/OnFocus.js @@ -1,5 +1,5 @@ function newSuperalgosFunctionLibraryOnFocus() { - thisObject = { + let thisObject = { getNodeThatIsOnFocus: getNodeThatIsOnFocus } return thisObject diff --git a/Projects/Superalgos/UI/Function-Libraries/PluginsFunctions.js b/Projects/Superalgos/UI/Function-Libraries/PluginsFunctions.js index 40f66edf7..59f468203 100644 --- a/Projects/Superalgos/UI/Function-Libraries/PluginsFunctions.js +++ b/Projects/Superalgos/UI/Function-Libraries/PluginsFunctions.js @@ -1,5 +1,5 @@ function newSuperalgosFunctionLibraryPluginsFunctions() { - thisObject = { + let thisObject = { pluginMissingProjects: pluginMissingProjects, pluginMissingDataMines: pluginMissingDataMines, pluginMissingTradingMines: pluginMissingTradingMines, diff --git a/Projects/Superalgos/UI/Function-Libraries/ProtocolNode.js b/Projects/Superalgos/UI/Function-Libraries/ProtocolNode.js index ecf83a20b..1706d73bf 100644 --- a/Projects/Superalgos/UI/Function-Libraries/ProtocolNode.js +++ b/Projects/Superalgos/UI/Function-Libraries/ProtocolNode.js @@ -4,7 +4,7 @@ function newSuperalgosFunctionLibraryProtocolNode() { const logger = newWebDebugLog() - thisObject = { + let thisObject = { getProtocolNode: getProtocolNode } return thisObject diff --git a/Projects/Superalgos/UI/Function-Libraries/ReferenceAttachDetach.js b/Projects/Superalgos/UI/Function-Libraries/ReferenceAttachDetach.js index b9f9a1eec..f62491627 100644 --- a/Projects/Superalgos/UI/Function-Libraries/ReferenceAttachDetach.js +++ b/Projects/Superalgos/UI/Function-Libraries/ReferenceAttachDetach.js @@ -1,5 +1,5 @@ function newSuperalgosFunctionLibraryAttachDetach() { - thisObject = { + let thisObject = { referenceDetachNode: referenceDetachNode, referenceAttachNode: referenceAttachNode } diff --git a/Projects/Superalgos/UI/Function-Libraries/ShortcutKeys.js b/Projects/Superalgos/UI/Function-Libraries/ShortcutKeys.js index 0a1e866ea..ec07aca26 100644 --- a/Projects/Superalgos/UI/Function-Libraries/ShortcutKeys.js +++ b/Projects/Superalgos/UI/Function-Libraries/ShortcutKeys.js @@ -1,5 +1,5 @@ function newSuperalgosFunctionLibraryShortcutKeys() { - thisObject = { + let thisObject = { getNodeByShortcutKey: getNodeByShortcutKey } return thisObject diff --git a/Projects/Superalgos/UI/Function-Libraries/SocialBotsFunctions.js b/Projects/Superalgos/UI/Function-Libraries/SocialBotsFunctions.js index 4b20d5443..38e6118d5 100644 --- a/Projects/Superalgos/UI/Function-Libraries/SocialBotsFunctions.js +++ b/Projects/Superalgos/UI/Function-Libraries/SocialBotsFunctions.js @@ -1,5 +1,5 @@ function newSuperalgosFunctionLibrarySocialBotsFunctions() { - thisObject = { + let thisObject = { sendTelegramTestMessage: sendTelegramTestMessage, sendDiscordTestMessage: sendDiscordTestMessage, sendSlackTestMessage: sendSlackTestMessage diff --git a/Projects/Superalgos/UI/Function-Libraries/SuperScripts.js b/Projects/Superalgos/UI/Function-Libraries/SuperScripts.js index 8287d1be0..4b0be4cc9 100644 --- a/Projects/Superalgos/UI/Function-Libraries/SuperScripts.js +++ b/Projects/Superalgos/UI/Function-Libraries/SuperScripts.js @@ -1,5 +1,5 @@ function newSuperalgosFunctionLibrarySuperScriptsFunctions() { - thisObject = { + let thisObject = { runSuperScript: runSuperScript } diff --git a/Projects/Superalgos/UI/Function-Libraries/TaskFunctions.js b/Projects/Superalgos/UI/Function-Libraries/TaskFunctions.js index 96e0f3419..35d82e56a 100644 --- a/Projects/Superalgos/UI/Function-Libraries/TaskFunctions.js +++ b/Projects/Superalgos/UI/Function-Libraries/TaskFunctions.js @@ -1,5 +1,5 @@ function newSuperalgosFunctionLibraryTaskFunctions() { - thisObject = { + let thisObject = { syncronizeTaskWithBackEnd: syncronizeTaskWithBackEnd, runTask: runTask, diff --git a/Projects/Superalgos/UI/Function-Libraries/TradingSessionFunctions.js b/Projects/Superalgos/UI/Function-Libraries/TradingSessionFunctions.js index b8415eb4f..d70d32fb5 100644 --- a/Projects/Superalgos/UI/Function-Libraries/TradingSessionFunctions.js +++ b/Projects/Superalgos/UI/Function-Libraries/TradingSessionFunctions.js @@ -1,5 +1,5 @@ function newSuperalgosFunctionLibraryTradingSessionFunctions() { - thisObject = { + let thisObject = { syncronizeSessionWithBackEnd: syncronizeSessionWithBackEnd, runSession: runSession, stopSession: stopSession diff --git a/Projects/Superalgos/UI/Function-Libraries/UiObjectsFromNodes.js b/Projects/Superalgos/UI/Function-Libraries/UiObjectsFromNodes.js index 9d3874fa2..4f6cb128d 100644 --- a/Projects/Superalgos/UI/Function-Libraries/UiObjectsFromNodes.js +++ b/Projects/Superalgos/UI/Function-Libraries/UiObjectsFromNodes.js @@ -1,5 +1,5 @@ function newSuperalgosFunctionLibraryUiObjectsFromNodes() { - thisObject = { + let thisObject = { syncronizeTasksFoundAtWorkspaceWithBackEnd: syncronizeTasksFoundAtWorkspaceWithBackEnd, syncronizeTradingSessionsFoundAtWorkspaceWithBackEnd: syncronizeTradingSessionsFoundAtWorkspaceWithBackEnd, syncronizeLearningSessionsFoundAtWorkspaceWithBackEnd: syncronizeLearningSessionsFoundAtWorkspaceWithBackEnd, diff --git a/Projects/Superalgos/UI/Function-Libraries/WebhookFunctions.js b/Projects/Superalgos/UI/Function-Libraries/WebhookFunctions.js index 112b1347f..b12a3d032 100644 --- a/Projects/Superalgos/UI/Function-Libraries/WebhookFunctions.js +++ b/Projects/Superalgos/UI/Function-Libraries/WebhookFunctions.js @@ -1,5 +1,5 @@ function newSuperalgosFunctionLibraryWebhookFunctions() { - thisObject = { + let thisObject = { sendTestMessage: sendTestMessage } diff --git a/Projects/Superalgos/UI/Function-Libraries/WorkspaceFunctions.js b/Projects/Superalgos/UI/Function-Libraries/WorkspaceFunctions.js index 4c84a8947..3a99a2fb1 100644 --- a/Projects/Superalgos/UI/Function-Libraries/WorkspaceFunctions.js +++ b/Projects/Superalgos/UI/Function-Libraries/WorkspaceFunctions.js @@ -1,5 +1,5 @@ function newSuperalgosFunctionLibraryWorkspaceFunctions() { - thisObject = { + let thisObject = { addMissingWorkspaceProjects: addMissingWorkspaceProjects } diff --git a/Projects/Superalgos/UI/Globals/Docs.js b/Projects/Superalgos/UI/Globals/Docs.js index 2189e631e..2a91724d2 100644 --- a/Projects/Superalgos/UI/Globals/Docs.js +++ b/Projects/Superalgos/UI/Globals/Docs.js @@ -1,5 +1,5 @@ function newSuperalgosGlobalsDocs() { - thisObject = { + let thisObject = { NEW_PARAGRAPH_TEXT: "Right click and Edit to enter edit mode and change this text. ENTER to write new paragraphs. ESC to exit edit mode. Then you can use docs.save to save your changes and app.contribute to send it to the main repository.", DEFAULT_LANGUAGE: 'EN', DEFAULT_CURRENT_BRANCH: 'master', diff --git a/Projects/Superalgos/UI/Globals/Zoom.js b/Projects/Superalgos/UI/Globals/Zoom.js index 040b4952f..cff758be7 100644 --- a/Projects/Superalgos/UI/Globals/Zoom.js +++ b/Projects/Superalgos/UI/Globals/Zoom.js @@ -1,5 +1,5 @@ function newSuperalgosGlobalsZoom() { - thisObject = { + let thisObject = { DOUBLE_CLICK_ZOOM_OUT_LEVEL: 0, DOUBLE_CLICK_ZOOM_IN_LEVEL: 6, DOUBLE_CLICK_ZOOM_IN_IN_LEVEL: 7, diff --git a/Projects/Superalgos/UI/Utilities/Branches.js b/Projects/Superalgos/UI/Utilities/Branches.js index f77311ae2..79ce86889 100644 --- a/Projects/Superalgos/UI/Utilities/Branches.js +++ b/Projects/Superalgos/UI/Utilities/Branches.js @@ -1,5 +1,5 @@ function newSuperalgosUtilitiesBranches() { - thisObject = { + let thisObject = { nodeBranchToArray: nodeBranchToArray, findInBranch: findInBranch } diff --git a/Projects/Superalgos/UI/Utilities/Clipboard.js b/Projects/Superalgos/UI/Utilities/Clipboard.js index 877358cf3..f73646dd2 100644 --- a/Projects/Superalgos/UI/Utilities/Clipboard.js +++ b/Projects/Superalgos/UI/Utilities/Clipboard.js @@ -1,5 +1,5 @@ function newSuperalgosUtilitiesClipboard() { - thisObject = { + let thisObject = { fallbackCopyTextToClipboard: fallbackCopyTextToClipboard, copyTextToClipboard: copyTextToClipboard } diff --git a/Projects/Superalgos/UI/Utilities/CoordinateTransformations.js b/Projects/Superalgos/UI/Utilities/CoordinateTransformations.js index 00922e6fc..e49f3b2eb 100644 --- a/Projects/Superalgos/UI/Utilities/CoordinateTransformations.js +++ b/Projects/Superalgos/UI/Utilities/CoordinateTransformations.js @@ -1,5 +1,5 @@ function newSuperalgosUtilitiesCoordinateTransformations() { - thisObject = { + let thisObject = { transformThisPoint: transformThisPoint, unTransformThisPoint: unTransformThisPoint } diff --git a/Projects/Superalgos/UI/Utilities/DateRateTransformations.js b/Projects/Superalgos/UI/Utilities/DateRateTransformations.js index 1f17fef42..8164147c6 100644 --- a/Projects/Superalgos/UI/Utilities/DateRateTransformations.js +++ b/Projects/Superalgos/UI/Utilities/DateRateTransformations.js @@ -1,5 +1,5 @@ function newSuperalgosUtilitiesDateRateTransformations() { - thisObject = { + let thisObject = { getDateFromPointAtBrowserCanvas: getDateFromPointAtBrowserCanvas, getDateFromPointAtChartsSpace: getDateFromPointAtChartsSpace, getDateFromPointAtContainer: getDateFromPointAtContainer, diff --git a/Projects/Superalgos/UI/Utilities/Dates.js b/Projects/Superalgos/UI/Utilities/Dates.js index 44dad69c4..4065c3d8f 100644 --- a/Projects/Superalgos/UI/Utilities/Dates.js +++ b/Projects/Superalgos/UI/Utilities/Dates.js @@ -1,5 +1,5 @@ function newSuperalgosUtilitiesDates() { - thisObject = { + let thisObject = { formatDate: formatDate } diff --git a/Projects/Superalgos/UI/Utilities/Docs.js b/Projects/Superalgos/UI/Utilities/Docs.js index 81182f38d..72d33ac62 100644 --- a/Projects/Superalgos/UI/Utilities/Docs.js +++ b/Projects/Superalgos/UI/Utilities/Docs.js @@ -1,5 +1,5 @@ function newSuperalgosUtilitiesDocs() { - thisObject = { + let thisObject = { buildOrderedPageIndex: buildOrderedPageIndex, addWarningIfTranslationIsOutdated: addWarningIfTranslationIsOutdated, getTextBasedOnLanguage: getTextBasedOnLanguage, diff --git a/Projects/Superalgos/UI/Utilities/Download.js b/Projects/Superalgos/UI/Utilities/Download.js index 85be8aa43..d3f6c37aa 100644 --- a/Projects/Superalgos/UI/Utilities/Download.js +++ b/Projects/Superalgos/UI/Utilities/Download.js @@ -1,5 +1,5 @@ function newSuperalgosUtilitiesDownload() { - thisObject = { + let thisObject = { downloadText: downloadText, downloadCanvas: downloadCanvas, downloadPanorama: downloadPanorama, diff --git a/Projects/Superalgos/UI/Utilities/DrawPrint.js b/Projects/Superalgos/UI/Utilities/DrawPrint.js index d2ee1f489..028e8f1c5 100644 --- a/Projects/Superalgos/UI/Utilities/DrawPrint.js +++ b/Projects/Superalgos/UI/Utilities/DrawPrint.js @@ -1,5 +1,5 @@ function newSuperalgosUtilitiesDrawPrint() { - thisObject = { + let thisObject = { roundedCornersBackground: roundedCornersBackground, drawLabel: drawLabel, drawIcon: drawIcon, diff --git a/Projects/Superalgos/UI/Utilities/Folders.js b/Projects/Superalgos/UI/Utilities/Folders.js index 1c8dd5745..47d3901b5 100644 --- a/Projects/Superalgos/UI/Utilities/Folders.js +++ b/Projects/Superalgos/UI/Utilities/Folders.js @@ -1,5 +1,5 @@ function newSuperalgosUtilitiesFolders() { - thisObject = { + let thisObject = { asymetricalFolderStructureCloning: asymetricalFolderStructureCloning } diff --git a/Projects/Superalgos/UI/Utilities/GitBranches.js b/Projects/Superalgos/UI/Utilities/GitBranches.js index 5e066e022..0a51f4ed6 100644 --- a/Projects/Superalgos/UI/Utilities/GitBranches.js +++ b/Projects/Superalgos/UI/Utilities/GitBranches.js @@ -1,5 +1,5 @@ function newSuperalgosUtilitiesGitBranches() { - thisObject = { + let thisObject = { getBranchLabel: getBranchLabel } diff --git a/Projects/Superalgos/UI/Utilities/Hierarchy.js b/Projects/Superalgos/UI/Utilities/Hierarchy.js index 209d4cdf7..c1286881e 100644 --- a/Projects/Superalgos/UI/Utilities/Hierarchy.js +++ b/Projects/Superalgos/UI/Utilities/Hierarchy.js @@ -1,5 +1,5 @@ function newSuperalgosUtilitiesHierarchy() { - thisObject = { + let thisObject = { getHiriarchyMap: getHiriarchyMap, getHiriarchyHead: getHiriarchyHead, getNodeNameTypePath: getNodeNameTypePath diff --git a/Projects/Superalgos/UI/Utilities/Languages.js b/Projects/Superalgos/UI/Utilities/Languages.js index 00d7e2821..aaa308415 100644 --- a/Projects/Superalgos/UI/Utilities/Languages.js +++ b/Projects/Superalgos/UI/Utilities/Languages.js @@ -1,5 +1,5 @@ function newSuperalgosUtilitiesLanguages() { - thisObject = { + let thisObject = { getLaguageLabel: getLaguageLabel } diff --git a/Projects/Superalgos/UI/Utilities/LoadSaveFrame.js b/Projects/Superalgos/UI/Utilities/LoadSaveFrame.js index 6ee69da82..acd76df3c 100644 --- a/Projects/Superalgos/UI/Utilities/LoadSaveFrame.js +++ b/Projects/Superalgos/UI/Utilities/LoadSaveFrame.js @@ -1,5 +1,5 @@ function newSuperalgosUtilitiesLoadSaveFrame() { - thisObject = { + let thisObject = { saveFrame: saveFrame, loadFrame: loadFrame } diff --git a/Projects/Superalgos/UI/Utilities/Menu.js b/Projects/Superalgos/UI/Utilities/Menu.js index 74297e468..8e29b1ba0 100644 --- a/Projects/Superalgos/UI/Utilities/Menu.js +++ b/Projects/Superalgos/UI/Utilities/Menu.js @@ -1,5 +1,5 @@ function newSuperalgosUtilitiesMenu() { - thisObject = { + let thisObject = { menuClickOfNodeArray: menuClickOfNodeArray, menuClick: menuClick } diff --git a/Projects/Superalgos/UI/Utilities/Meshes.js b/Projects/Superalgos/UI/Utilities/Meshes.js index 8626c2a25..c05b120fa 100644 --- a/Projects/Superalgos/UI/Utilities/Meshes.js +++ b/Projects/Superalgos/UI/Utilities/Meshes.js @@ -1,5 +1,5 @@ function newSuperalgosUtilitiesMeshes() { - thisObject = { + let thisObject = { findNodeInNodeMesh: findNodeInNodeMesh } diff --git a/Projects/Superalgos/UI/Utilities/NodeChildren.js b/Projects/Superalgos/UI/Utilities/NodeChildren.js index cda8d0a42..3917c8233 100644 --- a/Projects/Superalgos/UI/Utilities/NodeChildren.js +++ b/Projects/Superalgos/UI/Utilities/NodeChildren.js @@ -1,5 +1,5 @@ function newSuperalgosUtilitiesNodeChildren() { - thisObject = { + let thisObject = { isMissingChildren: isMissingChildren, findChildReferencingThisNode: findChildReferencingThisNode, findOrCreateChildWithReference: findOrCreateChildWithReference, diff --git a/Projects/Superalgos/UI/Utilities/NodeConfig.js b/Projects/Superalgos/UI/Utilities/NodeConfig.js index 866a99a8e..5fd130ae0 100644 --- a/Projects/Superalgos/UI/Utilities/NodeConfig.js +++ b/Projects/Superalgos/UI/Utilities/NodeConfig.js @@ -1,5 +1,5 @@ function newSuperalgosUtilitiesNodeConfig() { - thisObject = { + let thisObject = { savePropertyAtNodeConfig: savePropertyAtNodeConfig, loadPropertyFromNodeConfig: loadPropertyFromNodeConfig } diff --git a/Projects/Superalgos/UI/Utilities/StatusBar.js b/Projects/Superalgos/UI/Utilities/StatusBar.js index 44a0ba035..9dc59cbad 100644 --- a/Projects/Superalgos/UI/Utilities/StatusBar.js +++ b/Projects/Superalgos/UI/Utilities/StatusBar.js @@ -1,5 +1,5 @@ function newSuperalgosUtilitiesStatusBar() { - thisObject = { + let thisObject = { changeStatus: changeStatus } diff --git a/Projects/Superalgos/UI/Utilities/Strings.js b/Projects/Superalgos/UI/Utilities/Strings.js index 6f3c955cc..d000aa90e 100644 --- a/Projects/Superalgos/UI/Utilities/Strings.js +++ b/Projects/Superalgos/UI/Utilities/Strings.js @@ -1,5 +1,5 @@ function newSuperalgosUtilitiesStrings() { - thisObject = { + let thisObject = { allWordsToUpper: allWordsToUpper, fromCamelCaseToUpperWithSpaces: fromCamelCaseToUpperWithSpaces, isCamelCase: isCamelCase, diff --git a/Projects/Superalgos/UI/Utilities/Tutorial.js b/Projects/Superalgos/UI/Utilities/Tutorial.js index a9571eeb4..596e24ed9 100644 --- a/Projects/Superalgos/UI/Utilities/Tutorial.js +++ b/Projects/Superalgos/UI/Utilities/Tutorial.js @@ -1,5 +1,5 @@ function newSuperalgosUtilitiesTutorial() { - thisObject = { + let thisObject = { saveTutorial: saveTutorial, loadTutorial: loadTutorial }