Merge pull request #945 from Luis-Fernando-Molina/develop
Contribution: API CodeBase general mantainance: let thisObject missing fixed
This commit is contained in:
62 files changed
+1758
-73
No files matched your search
@@ -1,5 +1,5 @@
|
||||
function newEthereumFunctionLibraryAccounts() {
|
||||
thisObject = {
|
||||
let thisObject = {
|
||||
createWalletAccount: createWalletAccount
|
||||
}
|
||||
|
||||
|
||||
@@ -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
-1
@@ -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
|
||||
};
|
||||
|
||||
+1
-1
@@ -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
|
||||
};
|
||||
|
||||
+1
-1
@@ -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
|
||||
}
|
||||
|
||||
+1
-1
@@ -6,7 +6,7 @@
|
||||
const VOLUMES_FOLDER_NAME = "Volumes";
|
||||
const VOLUMES_ONE_MIN = "One-Min";
|
||||
|
||||
thisObject = {
|
||||
let thisObject = {
|
||||
initialize: initialize,
|
||||
start: start
|
||||
}
|
||||
|
||||
+25
-14
@@ -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
|
||||
|
||||
+1
-1
@@ -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
|
||||
};
|
||||
|
||||
+1
-1
@@ -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,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,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,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,5 +1,5 @@
|
||||
function newSuperalgosUtilitiesDates() {
|
||||
thisObject = {
|
||||
let thisObject = {
|
||||
formatDate: formatDate
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
function newSuperalgosUtilitiesDocs() {
|
||||
thisObject = {
|
||||
let thisObject = {
|
||||
buildOrderedPageIndex: buildOrderedPageIndex,
|
||||
addWarningIfTranslationIsOutdated: addWarningIfTranslationIsOutdated,
|
||||
getTextBasedOnLanguage: getTextBasedOnLanguage,
|
||||
|
||||
@@ -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,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,5 +1,5 @@
|
||||
function newSuperalgosUtilitiesMenu() {
|
||||
thisObject = {
|
||||
let thisObject = {
|
||||
menuClickOfNodeArray: menuClickOfNodeArray,
|
||||
menuClick: menuClick
|
||||
}
|
||||
|
||||
@@ -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,5 +1,5 @@
|
||||
function newSuperalgosUtilitiesStrings() {
|
||||
thisObject = {
|
||||
let thisObject = {
|
||||
allWordsToUpper: allWordsToUpper,
|
||||
fromCamelCaseToUpperWithSpaces: fromCamelCaseToUpperWithSpaces,
|
||||
isCamelCase: isCamelCase,
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
function newSuperalgosUtilitiesTutorial() {
|
||||
thisObject = {
|
||||
let thisObject = {
|
||||
saveTutorial: saveTutorial,
|
||||
loadTutorial: loadTutorial
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user