API CodeBase general mantainance: let thisObject missing fixed

This commit is contained in:
Luis Fernando Molina committed 2021-05-18 16:52:13 +02:00
1 parent adcd2f8169
commit 29702850b5
62 files changed
+1758 -73

No files matched your search

@@ -1,5 +1,5 @@
function newEthereumFunctionLibraryAccounts() {
thisObject = {
let thisObject = {
createWalletAccount: createWalletAccount
}
+1 -1
View File
@@ -1,5 +1,5 @@
function newEthereumGlobalsChainIds() {
thisObject = {
let thisObject = {
chainNameById: chainNameById
}
return thisObject
@@ -1,5 +1,5 @@
function newEthereumUtilitiesRouteToClient() {
thisObject = {
let thisObject = {
buildRouteToClient: buildRouteToClient
}
@@ -1,7 +1,7 @@
function newMastersPlottersBollingerBandsBollingerBandsBollingerBandsPanel() {
var thisObject = {
let thisObject = {
fitFunction: undefined,
onRecordChange: onRecordChange,
container: undefined,
@@ -3,7 +3,7 @@ exports.newSuperalgosBotModulesFetchingProcess = function (processIndex) {
const MODULE_NAME = "Fetching Process";
thisObject = {
let thisObject = {
initialize: initialize,
start: start
};
@@ -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
};
@@ -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
}
@@ -6,7 +6,7 @@
const VOLUMES_FOLDER_NAME = "Volumes";
const VOLUMES_ONE_MIN = "One-Min";
thisObject = {
let thisObject = {
initialize: initialize,
start: start
}
@@ -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();
@@ -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)
}
}
}
@@ -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)
}
}
}
@@ -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
@@ -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
@@ -5,7 +5,7 @@
*/
const MODULE_NAME = "Learning Process"
thisObject = {
let thisObject = {
start: start
}
@@ -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
};
@@ -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
};
@@ -5,7 +5,7 @@
*/
const MODULE_NAME = "Trading Process"
thisObject = {
let thisObject = {
start: start
}
@@ -1,5 +1,5 @@
function newSuperalgosFunctionLibraryChainAttachDetach() {
thisObject = {
let thisObject = {
chainDetachNode: chainDetachNode,
chainAttachNode: chainAttachNode
}
@@ -1,5 +1,5 @@
function newSuperalgosFunctionLibraryChartingSpaceFunctions() {
thisObject = {
let thisObject = {
addAllLayerPanels: addAllLayerPanels,
addAllLayerPolygons: addAllLayerPolygons,
addAllMineLayers: addAllMineLayers,
@@ -1,5 +1,5 @@
function newSuperalgosFunctionLibraryCryptoEcosystemFunctions() {
thisObject = {
let thisObject = {
addMissingExchanges: addMissingExchanges,
addMissingAssets: addMissingAssets,
addMissingMarkets: addMissingMarkets,
@@ -1,5 +1,5 @@
function newSuperalgosFunctionLibraryDataStorageFunctions() {
thisObject = {
let thisObject = {
addAllDataProducts: addAllDataProducts,
addAllDataMineProducts: addAllDataMineProducts,
addAllTradingMineProducts: addAllTradingMineProducts,
@@ -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
}
@@ -1,5 +1,5 @@
function newSuperalgosFunctionLibraryLearningSessionFunctions() {
thisObject = {
let thisObject = {
syncronizeSessionWithBackEnd: syncronizeSessionWithBackEnd,
runSession: runSession,
stopSession: stopSession
@@ -1,5 +1,5 @@
function newSuperalgosFunctionLibraryMineFunctions() {
thisObject = {
let thisObject = {
addAllOutputDatasets: addAllOutputDatasets,
addAllDataDependencies: addAllDataDependencies,
addAllDataMineDataDependencies: addAllDataMineDataDependencies
@@ -1,5 +1,5 @@
function newNodeChildren() {
thisObject = {
let thisObject = {
childrenCount: childrenCount
}
@@ -4,7 +4,7 @@ function newSuperalgosFunctionLibraryNodeCloning() {
const logger = newWebDebugLog()
thisObject = {
let thisObject = {
getNodeClone: getNodeClone
}
return thisObject
@@ -1,5 +1,5 @@
function newSuperalgosFunctionLibraryNodeDeleter() {
thisObject = {
let thisObject = {
deleteWorkspace: deleteWorkspace,
deleteUIObject: deleteUIObject
}
@@ -1,5 +1,5 @@
function newSuperalgosFunctionLibraryNodePath() {
thisObject = {
let thisObject = {
getNodePath: getNodePath
}
@@ -1,5 +1,5 @@
function newSuperalgosFunctionLibraryOnFocus() {
thisObject = {
let thisObject = {
getNodeThatIsOnFocus: getNodeThatIsOnFocus
}
return thisObject
@@ -1,5 +1,5 @@
function newSuperalgosFunctionLibraryPluginsFunctions() {
thisObject = {
let thisObject = {
pluginMissingProjects: pluginMissingProjects,
pluginMissingDataMines: pluginMissingDataMines,
pluginMissingTradingMines: pluginMissingTradingMines,
@@ -4,7 +4,7 @@ function newSuperalgosFunctionLibraryProtocolNode() {
const logger = newWebDebugLog()
thisObject = {
let thisObject = {
getProtocolNode: getProtocolNode
}
return thisObject
@@ -1,5 +1,5 @@
function newSuperalgosFunctionLibraryAttachDetach() {
thisObject = {
let thisObject = {
referenceDetachNode: referenceDetachNode,
referenceAttachNode: referenceAttachNode
}
@@ -1,5 +1,5 @@
function newSuperalgosFunctionLibraryShortcutKeys() {
thisObject = {
let thisObject = {
getNodeByShortcutKey: getNodeByShortcutKey
}
return thisObject
@@ -1,5 +1,5 @@
function newSuperalgosFunctionLibrarySocialBotsFunctions() {
thisObject = {
let thisObject = {
sendTelegramTestMessage: sendTelegramTestMessage,
sendDiscordTestMessage: sendDiscordTestMessage,
sendSlackTestMessage: sendSlackTestMessage
@@ -1,5 +1,5 @@
function newSuperalgosFunctionLibrarySuperScriptsFunctions() {
thisObject = {
let thisObject = {
runSuperScript: runSuperScript
}
@@ -1,5 +1,5 @@
function newSuperalgosFunctionLibraryTaskFunctions() {
thisObject = {
let thisObject = {
syncronizeTaskWithBackEnd: syncronizeTaskWithBackEnd,
runTask: runTask,
@@ -1,5 +1,5 @@
function newSuperalgosFunctionLibraryTradingSessionFunctions() {
thisObject = {
let thisObject = {
syncronizeSessionWithBackEnd: syncronizeSessionWithBackEnd,
runSession: runSession,
stopSession: stopSession
@@ -1,5 +1,5 @@
function newSuperalgosFunctionLibraryUiObjectsFromNodes() {
thisObject = {
let thisObject = {
syncronizeTasksFoundAtWorkspaceWithBackEnd: syncronizeTasksFoundAtWorkspaceWithBackEnd,
syncronizeTradingSessionsFoundAtWorkspaceWithBackEnd: syncronizeTradingSessionsFoundAtWorkspaceWithBackEnd,
syncronizeLearningSessionsFoundAtWorkspaceWithBackEnd: syncronizeLearningSessionsFoundAtWorkspaceWithBackEnd,
@@ -1,5 +1,5 @@
function newSuperalgosFunctionLibraryWebhookFunctions() {
thisObject = {
let thisObject = {
sendTestMessage: sendTestMessage
}
@@ -1,5 +1,5 @@
function newSuperalgosFunctionLibraryWorkspaceFunctions() {
thisObject = {
let thisObject = {
addMissingWorkspaceProjects: addMissingWorkspaceProjects
}
+1 -1
View File
@@ -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',
+1 -1
View File
@@ -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,
+1 -1
View File
@@ -1,5 +1,5 @@
function newSuperalgosUtilitiesBranches() {
thisObject = {
let thisObject = {
nodeBranchToArray: nodeBranchToArray,
findInBranch: findInBranch
}
@@ -1,5 +1,5 @@
function newSuperalgosUtilitiesClipboard() {
thisObject = {
let thisObject = {
fallbackCopyTextToClipboard: fallbackCopyTextToClipboard,
copyTextToClipboard: copyTextToClipboard
}
@@ -1,5 +1,5 @@
function newSuperalgosUtilitiesCoordinateTransformations() {
thisObject = {
let thisObject = {
transformThisPoint: transformThisPoint,
unTransformThisPoint: unTransformThisPoint
}
@@ -1,5 +1,5 @@
function newSuperalgosUtilitiesDateRateTransformations() {
thisObject = {
let thisObject = {
getDateFromPointAtBrowserCanvas: getDateFromPointAtBrowserCanvas,
getDateFromPointAtChartsSpace: getDateFromPointAtChartsSpace,
getDateFromPointAtContainer: getDateFromPointAtContainer,
+1 -1
View File
@@ -1,5 +1,5 @@
function newSuperalgosUtilitiesDates() {
thisObject = {
let thisObject = {
formatDate: formatDate
}
+1 -1
View File
@@ -1,5 +1,5 @@
function newSuperalgosUtilitiesDocs() {
thisObject = {
let thisObject = {
buildOrderedPageIndex: buildOrderedPageIndex,
addWarningIfTranslationIsOutdated: addWarningIfTranslationIsOutdated,
getTextBasedOnLanguage: getTextBasedOnLanguage,
+1 -1
View File
@@ -1,5 +1,5 @@
function newSuperalgosUtilitiesDownload() {
thisObject = {
let thisObject = {
downloadText: downloadText,
downloadCanvas: downloadCanvas,
downloadPanorama: downloadPanorama,
@@ -1,5 +1,5 @@
function newSuperalgosUtilitiesDrawPrint() {
thisObject = {
let thisObject = {
roundedCornersBackground: roundedCornersBackground,
drawLabel: drawLabel,
drawIcon: drawIcon,
+1 -1
View File
@@ -1,5 +1,5 @@
function newSuperalgosUtilitiesFolders() {
thisObject = {
let thisObject = {
asymetricalFolderStructureCloning: asymetricalFolderStructureCloning
}
@@ -1,5 +1,5 @@
function newSuperalgosUtilitiesGitBranches() {
thisObject = {
let thisObject = {
getBranchLabel: getBranchLabel
}
@@ -1,5 +1,5 @@
function newSuperalgosUtilitiesHierarchy() {
thisObject = {
let thisObject = {
getHiriarchyMap: getHiriarchyMap,
getHiriarchyHead: getHiriarchyHead,
getNodeNameTypePath: getNodeNameTypePath
@@ -1,5 +1,5 @@
function newSuperalgosUtilitiesLanguages() {
thisObject = {
let thisObject = {
getLaguageLabel: getLaguageLabel
}
@@ -1,5 +1,5 @@
function newSuperalgosUtilitiesLoadSaveFrame() {
thisObject = {
let thisObject = {
saveFrame: saveFrame,
loadFrame: loadFrame
}
+1 -1
View File
@@ -1,5 +1,5 @@
function newSuperalgosUtilitiesMenu() {
thisObject = {
let thisObject = {
menuClickOfNodeArray: menuClickOfNodeArray,
menuClick: menuClick
}
+1 -1
View File
@@ -1,5 +1,5 @@
function newSuperalgosUtilitiesMeshes() {
thisObject = {
let thisObject = {
findNodeInNodeMesh: findNodeInNodeMesh
}
@@ -1,5 +1,5 @@
function newSuperalgosUtilitiesNodeChildren() {
thisObject = {
let thisObject = {
isMissingChildren: isMissingChildren,
findChildReferencingThisNode: findChildReferencingThisNode,
findOrCreateChildWithReference: findOrCreateChildWithReference,
@@ -1,5 +1,5 @@
function newSuperalgosUtilitiesNodeConfig() {
thisObject = {
let thisObject = {
savePropertyAtNodeConfig: savePropertyAtNodeConfig,
loadPropertyFromNodeConfig: loadPropertyFromNodeConfig
}
@@ -1,5 +1,5 @@
function newSuperalgosUtilitiesStatusBar() {
thisObject = {
let thisObject = {
changeStatus: changeStatus
}
+1 -1
View File
@@ -1,5 +1,5 @@
function newSuperalgosUtilitiesStrings() {
thisObject = {
let thisObject = {
allWordsToUpper: allWordsToUpper,
fromCamelCaseToUpperWithSpaces: fromCamelCaseToUpperWithSpaces,
isCamelCase: isCamelCase,
+1 -1
View File
@@ -1,5 +1,5 @@
function newSuperalgosUtilitiesTutorial() {
thisObject = {
let thisObject = {
saveTutorial: saveTutorial,
loadTutorial: loadTutorial
}