22 files changed
+6624
-684
No files matched your search
+515
@@ -0,0 +1,515 @@
|
||||
exports.newCommons = function newCommons(bot, logger, UTILITIES, FILE_STORAGE) {
|
||||
|
||||
const FULL_LOG = true;
|
||||
const LOG_FILE_CONTENT = false;
|
||||
const ONE_DAY_IN_MILISECONDS = 24 * 60 * 60 * 1000;
|
||||
|
||||
const MODULE_NAME = "Commons";
|
||||
|
||||
let thisObject = {
|
||||
validateDataDependencies: validateDataDependencies,
|
||||
validateOutputDatasets: validateOutputDatasets,
|
||||
inflateDatafiles: inflateDatafiles,
|
||||
dataBuildingProcedure: dataBuildingProcedure,
|
||||
calculationsProcedure: calculationsProcedure,
|
||||
generateFileContent: generateFileContent,
|
||||
writeFile: writeFile
|
||||
};
|
||||
|
||||
let utilities = UTILITIES.newCloudUtilities(logger);
|
||||
let fileStorage = FILE_STORAGE.newFileStorage(logger);
|
||||
|
||||
return thisObject;
|
||||
|
||||
function validateDataDependencies(dataDependencies, callBackFunction) {
|
||||
for (let i = 0; i < dataDependencies.length; i++) {
|
||||
|
||||
let dataDependencyNode = dataDependencies[i]
|
||||
|
||||
/* Basic validations to see if we have everything we need. */
|
||||
if (dataDependencyNode.referenceParent.parentNode.code.singularVariableName === undefined) {
|
||||
logger.write(MODULE_NAME, "[ERROR] start -> Product Definition without a Single Variable Name defined. Product Definition = " + JSON.stringify(dataDependencyNode.referenceParent.parentNode));
|
||||
callBackFunction(global.DEFAULT_FAIL_RESPONSE);
|
||||
return
|
||||
}
|
||||
if (dataDependencyNode.referenceParent.parentNode.code.pluralVariableName === undefined) {
|
||||
logger.write(MODULE_NAME, "[ERROR] start -> Product Definition without a Plural Variable Name defined. Product Definition = " + JSON.stringify(dataDependencyNode.referenceParent.parentNode));
|
||||
callBackFunction(global.DEFAULT_FAIL_RESPONSE);
|
||||
return
|
||||
}
|
||||
if (dataDependencyNode.referenceParent.parentNode.record === undefined) {
|
||||
logger.write(MODULE_NAME, "[ERROR] start -> Product Definition without a Record Definition. Product Definition = " + JSON.stringify(dataDependencyNode.referenceParent.parentNode));
|
||||
callBackFunction(global.DEFAULT_FAIL_RESPONSE);
|
||||
return
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
function validateOutputDatasets(outputDatasets, callBackFunction) {
|
||||
for (let i = 0; i < outputDatasets.length; i++) {
|
||||
let outputDatasetNode = outputDatasets[i]
|
||||
|
||||
if (outputDatasetNode.referenceParent === undefined) {
|
||||
logger.write(MODULE_NAME, "[ERROR] start -> Output Dataset without Reference Parent. Output Dataset = " + JSON.stringify(outputDatasetNode));
|
||||
callBackFunction(global.DEFAULT_FAIL_RESPONSE);
|
||||
return
|
||||
}
|
||||
if (outputDatasetNode.referenceParent.parentNode.code.singularVariableName === undefined) {
|
||||
logger.write(MODULE_NAME, "[ERROR] start -> Product Definition without a Single Variable Name defined. Product Definition = " + JSON.stringify(outputDatasetNode.referenceParent.parentNode));
|
||||
callBackFunction(global.DEFAULT_FAIL_RESPONSE);
|
||||
return
|
||||
}
|
||||
if (outputDatasetNode.referenceParent.parentNode.code.pluralVariableName === undefined) {
|
||||
logger.write(MODULE_NAME, "[ERROR] start -> Product Definition without a Plural Variable Name defined. Product Definition = " + JSON.stringify(outputDatasetNode.referenceParent.parentNode));
|
||||
callBackFunction(global.DEFAULT_FAIL_RESPONSE);
|
||||
return
|
||||
}
|
||||
if (outputDatasetNode.referenceParent.parentNode.record === undefined) {
|
||||
logger.write(MODULE_NAME, "[ERROR] start -> Product Definition without a Record Definition. Product Definition = " + JSON.stringify(outputDatasetNode.referenceParent.parentNode));
|
||||
callBackFunction(global.DEFAULT_FAIL_RESPONSE);
|
||||
return
|
||||
}
|
||||
if (outputDatasetNode.referenceParent.parentNode.dataBuilding === undefined) {
|
||||
logger.write(MODULE_NAME, "[WARN] start -> Product Definition without a Data Building Procedure. Product Definition = " + JSON.stringify(outputDatasetNode.referenceParent.parentNode));
|
||||
}
|
||||
if (outputDatasetNode.referenceParent.code.codeName === undefined) {
|
||||
logger.write(MODULE_NAME, "[ERROR] start -> Dataset witn no codeName defined. Product Dataset = " + JSON.stringify(outputDatasetNode.referenceParent));
|
||||
callBackFunction(global.DEFAULT_FAIL_RESPONSE);
|
||||
return
|
||||
}
|
||||
|
||||
if (outputDatasetNode.referenceParent.parentNode === undefined) {
|
||||
logger.write(MODULE_NAME, "[ERROR] start -> Dataset not attached to a Product Definition. Dataset = " + JSON.stringify(outputDatasetNode.referenceParent));
|
||||
callBackFunction(global.DEFAULT_FAIL_RESPONSE);
|
||||
return
|
||||
}
|
||||
|
||||
if (outputDatasetNode.referenceParent.parentNode.code.codeName === undefined) {
|
||||
logger.write(MODULE_NAME, "[ERROR] start -> Product Definition witn no codeName defined. Product Definition = " + JSON.stringify(outputDatasetNode.referenceParent.parentNode));
|
||||
callBackFunction(global.DEFAULT_FAIL_RESPONSE);
|
||||
return
|
||||
}
|
||||
|
||||
if (outputDatasetNode.referenceParent.parentNode.parentNode === undefined) {
|
||||
logger.write(MODULE_NAME, "[ERROR] start -> Product Definition not attached to a Bot. Product Definition = " + JSON.stringify(outputDatasetNode.referenceParent.parentNode));
|
||||
callBackFunction(global.DEFAULT_FAIL_RESPONSE);
|
||||
return
|
||||
}
|
||||
|
||||
if (outputDatasetNode.referenceParent.parentNode.parentNode.code.codeName === undefined) {
|
||||
logger.write(MODULE_NAME, "[ERROR] start -> Bot witn no codeName defined. Bot = " + JSON.stringify(outputDatasetNode.referenceParent.parentNode.parentNode));
|
||||
callBackFunction(global.DEFAULT_FAIL_RESPONSE);
|
||||
return
|
||||
}
|
||||
|
||||
if (outputDatasetNode.referenceParent.parentNode.parentNode.parentNode === undefined) {
|
||||
logger.write(MODULE_NAME, "[ERROR] start -> Bot not attached to a Team. Bot = " + JSON.stringify(outputDatasetNode.referenceParent.parentNode.parentNode));
|
||||
callBackFunction(global.DEFAULT_FAIL_RESPONSE);
|
||||
return
|
||||
}
|
||||
|
||||
if (outputDatasetNode.referenceParent.parentNode.parentNode.parentNode.code.codeName === undefined) {
|
||||
logger.write(MODULE_NAME, "[ERROR] start -> Team witn no codeName defined. Team = " + JSON.stringify(outputDatasetNode.referenceParent.parentNode.parentNode.parentNode));
|
||||
callBackFunction(global.DEFAULT_FAIL_RESPONSE);
|
||||
return
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
function inflateDatafiles(dataFiles, dataDependencies, products, mainDependency, timePeriod) {
|
||||
/*
|
||||
For each dataDependencyNode in our data dependencies, we should have a dataFile containing the records needed as an imput for this process.
|
||||
What we need to do first is transform those records into JSON objects that can be used by user-defined formulas.
|
||||
The first step does that but with the not calculated properties, the second step adds the calculated properties.
|
||||
*/
|
||||
for (let i = 0; i < dataDependencies.length; i++) {
|
||||
|
||||
let dataFile
|
||||
let jsonData // Datafile converted into Json objects
|
||||
let inputData // Includes calculated properties
|
||||
let singularVariableName // name of the variable for this product
|
||||
let recordDefinition
|
||||
|
||||
let dataDependencyNode = dataDependencies[i]
|
||||
dataFile = dataFiles.get(dataDependencyNode.id)
|
||||
|
||||
if (dataFile === undefined) { continue } // When a datafile is not found it might be because we are processing market or daily and at the dependency array there are both types mixed up.
|
||||
|
||||
recordDefinition = dataDependencyNode.referenceParent.parentNode.record
|
||||
singularVariableName = dataDependencyNode.referenceParent.parentNode.code.singularVariableName
|
||||
/* Transform the raw data into JSON objects */
|
||||
jsonData = jsonifyDataFile(dataFile, recordDefinition)
|
||||
/* Add the calculated properties */
|
||||
if (dataDependencyNode.referenceParent.parentNode.calculations !== undefined) {
|
||||
inputData = calculationsProcedure(jsonData, recordDefinition, dataDependencyNode.referenceParent.parentNode.calculations, singularVariableName, timePeriod)
|
||||
} else {
|
||||
inputData = jsonData
|
||||
}
|
||||
products[dataDependencyNode.referenceParent.parentNode.code.pluralVariableName] = inputData
|
||||
|
||||
/* The main dependency is defined as the first dependency processed. */
|
||||
if (mainDependency.records === undefined) {
|
||||
mainDependency.records = inputData
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function jsonifyDataFile(dataFile, recordDefinition) {
|
||||
|
||||
/*
|
||||
This function has as an input the raw data on files and creates with it an array of JSON objects
|
||||
with not calculated properties for later being consumed by Formulas
|
||||
*/
|
||||
|
||||
let jsonifiedArray = []
|
||||
let previous;
|
||||
|
||||
for (let i = 0; i < dataFile.length; i++) {
|
||||
|
||||
let record = {}
|
||||
for (let j = 0; j < recordDefinition.properties.length; j++) {
|
||||
let property = recordDefinition.properties[j]
|
||||
if (property.code.isCalculated !== true) {
|
||||
record[property.code.codeName] = dataFile[i][j]
|
||||
}
|
||||
}
|
||||
|
||||
record.previous = previous;
|
||||
jsonifiedArray.push(record);
|
||||
previous = record;
|
||||
}
|
||||
|
||||
return jsonifiedArray
|
||||
}
|
||||
|
||||
function calculationsProcedure(jsonArray, recordDefinition, calculationsProcedure, variableName, timePeriod) {
|
||||
|
||||
/*
|
||||
This function has as an input an array of JSON objects, and it adds calculated properties to
|
||||
complete the set of properties that will be available for Formulas.
|
||||
*/
|
||||
|
||||
let system = { // These are the available system variables to be used in User Code and Formulas
|
||||
timePeriod: timePeriod,
|
||||
ONE_DAY_IN_MILISECONDS: ONE_DAY_IN_MILISECONDS
|
||||
}
|
||||
let variable = {} // This is the structure where the user will define its own variables that will be shared across different code blocks and formulas.
|
||||
let results = []
|
||||
|
||||
/* This is Initialization Code */
|
||||
if (calculationsProcedure.initialization !== undefined) {
|
||||
if (calculationsProcedure.initialization.code !== undefined) {
|
||||
try {
|
||||
eval(calculationsProcedure.initialization.code.code)
|
||||
} catch (err) {
|
||||
logger.write(MODULE_NAME, "[ERROR] calculationsProcedure -> initialization -> Error executing User Code. Error = " + err.stack)
|
||||
logger.write(MODULE_NAME, "[ERROR] calculationsProcedure -> initialization -> Error executing User Code. Code = " + calculationsProcedure.initialization.code.code);
|
||||
throw ("Error Executing User Code.")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* This is Initialization Code */
|
||||
if (calculationsProcedure.loop !== undefined) {
|
||||
if (calculationsProcedure.loop.code !== undefined) {
|
||||
for (let index = 0; index < jsonArray.length; index++) {
|
||||
|
||||
let product = {}
|
||||
product[variableName] = jsonArray[index]
|
||||
|
||||
/* This is Loop Code */
|
||||
try {
|
||||
eval(calculationsProcedure.loop.code.code)
|
||||
} catch (err) {
|
||||
logger.write(MODULE_NAME, "[ERROR] calculationsProcedure -> loop -> Error executing User Code. Error = " + err.stack)
|
||||
logger.write(MODULE_NAME, "[ERROR] calculationsProcedure -> loop -> Error executing User Code. product = " + JSON.stringify(product))
|
||||
logger.write(MODULE_NAME, "[ERROR] calculationsProcedure -> loop -> Error executing User Code. Code = " + calculationsProcedure.loop.code.code);
|
||||
throw ("Error Executing User Code.")
|
||||
}
|
||||
|
||||
/* For each calculated property we apply its formula*/
|
||||
for (let j = 0; j < recordDefinition.properties.length; j++) {
|
||||
let property = recordDefinition.properties[j]
|
||||
if (property.code.isCalculated === true) {
|
||||
if (property.formula !== undefined) {
|
||||
if (property.formula.code !== undefined) {
|
||||
try {
|
||||
let newValue = eval(property.formula.code)
|
||||
let currentRecord = product[variableName]
|
||||
currentRecord[property.code.codeName] = newValue
|
||||
} catch (err) {
|
||||
logger.write(MODULE_NAME, "[ERROR] calculationsProcedure -> loop -> formula -> Error executing User Code. Error = " + err.stack)
|
||||
logger.write(MODULE_NAME, "[ERROR] calculationsProcedure -> loop -> formula -> Error executing User Code. product = " + JSON.stringify(product))
|
||||
logger.write(MODULE_NAME, "[ERROR] calculationsProcedure -> loop -> formula -> Error executing User Code. Code = " + property.formula.code);
|
||||
throw ("Error Executing User Code.")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Adding the new element to the resulting array */
|
||||
results.push(product[variableName]);
|
||||
}
|
||||
}
|
||||
}
|
||||
return results
|
||||
}
|
||||
|
||||
function dataBuildingProcedure(
|
||||
products,
|
||||
mainDependency,
|
||||
recordDefinition,
|
||||
dataBuildingProcedure,
|
||||
variableName,
|
||||
timePeriod,
|
||||
timePeriodLabel,
|
||||
resultsWithIrregularPeriods,
|
||||
interExecutionMemory,
|
||||
processingDailyFiles,
|
||||
currentDay
|
||||
) {
|
||||
|
||||
/*
|
||||
This function has as an input the products object, with all the information
|
||||
of all products calculated so far by the process. Based on that information
|
||||
the function will evaluate user supplied code and formulas in order to build
|
||||
a new set of information.
|
||||
*/
|
||||
|
||||
let lastInstantOfTheDay
|
||||
let yesterday = {}
|
||||
let system = { // These are the available system variables to be used in User Code and Formulas
|
||||
timePeriod: timePeriod,
|
||||
ONE_DAY_IN_MILISECONDS: ONE_DAY_IN_MILISECONDS
|
||||
}
|
||||
let variable = {} // This is the structure where the user will define its own variables that will be shared across different code blocks and formulas.
|
||||
let results = []
|
||||
|
||||
/* This is Initialization Code */
|
||||
if (dataBuildingProcedure.initialization !== undefined) {
|
||||
if (dataBuildingProcedure.initialization.code !== undefined) {
|
||||
try {
|
||||
eval(dataBuildingProcedure.initialization.code.code)
|
||||
} catch (err) {
|
||||
logger.write(MODULE_NAME, "[ERROR] dataBuildingProcedure -> initialization -> Error executing User Code. Error = " + err.stack)
|
||||
logger.write(MODULE_NAME, "[ERROR] dataBuildingProcedure -> initialization -> Error executing User Code. Code = " + dataBuildingProcedure.initialization.code.code);
|
||||
throw ("Error Executing User Code.")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (processingDailyFiles) {
|
||||
/* Initialization of Last Instance */
|
||||
lastInstantOfTheDay = currentDay.valueOf() + ONE_DAY_IN_MILISECONDS - 1;
|
||||
|
||||
if (interExecutionMemory.variable === undefined) {
|
||||
/* The first time the intialization variables goes to the Inter Execution Memory. */
|
||||
interExecutionMemory.variable = JSON.parse(JSON.stringify(variable))
|
||||
}
|
||||
else {
|
||||
/* We override the initialization, since the valid stuff is already at the Inter Execution Memory */
|
||||
variable = JSON.parse(JSON.stringify(interExecutionMemory.variable))
|
||||
}
|
||||
}
|
||||
|
||||
/* This is Initialization Code */
|
||||
if (dataBuildingProcedure.loop !== undefined) {
|
||||
if (dataBuildingProcedure.loop.code !== undefined) {
|
||||
let lastRecord
|
||||
for (let index = 0; index < mainDependency.records.length; index++) {
|
||||
|
||||
let record = {
|
||||
previous: mainDependency.records[index - 1],
|
||||
current: mainDependency.records[index],
|
||||
next: mainDependency.records[index + 1]
|
||||
}
|
||||
lastRecord = record
|
||||
let product = {}
|
||||
product[variableName] = {}
|
||||
|
||||
/* Here is how we know if we are processing Yesterday. */
|
||||
let positionedAtYesterday = false
|
||||
if (processingDailyFiles) {
|
||||
positionedAtYesterday = (record.current.end < currentDay.valueOf())
|
||||
}
|
||||
|
||||
/* This is Loop Code */
|
||||
try {
|
||||
eval(dataBuildingProcedure.loop.code.code)
|
||||
} catch (err) {
|
||||
logger.write(MODULE_NAME, "[ERROR] dataBuildingProcedure -> loop -> Error executing User Code. Error = " + err.stack)
|
||||
logger.write(MODULE_NAME, "[ERROR] dataBuildingProcedure -> loop -> Error executing User Code. product = " + JSON.stringify(product))
|
||||
logger.write(MODULE_NAME, "[ERROR] dataBuildingProcedure -> loop -> Error executing User Code. Code = " + dataBuildingProcedure.loop.code.code);
|
||||
throw ("Error Executing User Code.")
|
||||
}
|
||||
|
||||
/* For each non-calculated property we apply its formula*/
|
||||
for (let j = 0; j < recordDefinition.properties.length; j++) {
|
||||
let property = recordDefinition.properties[j]
|
||||
if (property.code.isCalculated !== true) {
|
||||
if (property.formula !== undefined) {
|
||||
if (property.formula.code !== undefined) {
|
||||
try {
|
||||
let newValue = eval(property.formula.code)
|
||||
let currentRecord = product[variableName]
|
||||
currentRecord[property.code.codeName] = newValue
|
||||
} catch (err) {
|
||||
logger.write(MODULE_NAME, "[ERROR] dataBuildingProcedure -> loop -> formula -> Error executing User Code. Error = " + err.stack)
|
||||
logger.write(MODULE_NAME, "[ERROR] dataBuildingProcedure -> loop -> formula -> Error executing User Code. product = " + JSON.stringify(product))
|
||||
logger.write(MODULE_NAME, "[ERROR] dataBuildingProcedure -> loop -> formula -> Error executing User Code. Code = " + property.formula.code);
|
||||
throw ("Error Executing User Code.")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* If within the code the new data structure was not yet pushed to the results array, we do it */
|
||||
if (resultsWithIrregularPeriods !== true) {
|
||||
/* Adding the new element to the resulting array */
|
||||
results.push(product[variableName]);
|
||||
}
|
||||
|
||||
/* While we are positioned at Yesterday, we keey updating this data structure. */
|
||||
if (processingDailyFiles) {
|
||||
if (positionedAtYesterday) {
|
||||
yesterday.variable = JSON.parse(JSON.stringify(variable))
|
||||
}
|
||||
}
|
||||
}
|
||||
/*
|
||||
Before returning we need to see if we have to record some of our counters at the interExecutionMemory.
|
||||
To do that, the condition to be met is that this execution must include all candles of the current day.
|
||||
*/
|
||||
if (processingDailyFiles) {
|
||||
if (lastRecord.current.end === lastInstantOfTheDay && yesterday.variable !== undefined) {
|
||||
interExecutionMemory.variable = JSON.parse(JSON.stringify(yesterday.variable))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return results
|
||||
}
|
||||
|
||||
function generateFileContent(records, recordDefinition, resultsWithIrregularPeriods, processingDailyFiles, currentDay, callBackFunction) {
|
||||
|
||||
try {
|
||||
|
||||
if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] start -> generateFileContent -> Entering function."); }
|
||||
|
||||
let fileContent = "";
|
||||
let recordSeparator = "";
|
||||
|
||||
for (let i = 0; i < records.length; i++) {
|
||||
let record = records[i];
|
||||
|
||||
if (processingDailyFiles === true) {
|
||||
|
||||
if (resultsWithIrregularPeriods === true) {
|
||||
/*
|
||||
Here we have an special problem that occurs when an object spans several time peridos. If not taken care of
|
||||
it can happen that the object gets splitted between 2 days, which we dont want since it would loose some of
|
||||
its properties.
|
||||
|
||||
To solve this issue, we wont save objects which ends at the last candle of the day, because we will save it
|
||||
at the next day, in whole, even if it starts in the previous day.
|
||||
*/
|
||||
|
||||
let lastInstantOdDay = currentDay.valueOf() + ONE_DAY_IN_MILISECONDS - 1;
|
||||
|
||||
if (record.end < currentDay.valueOf() - 1) { continue; }
|
||||
if (record.end === lastInstantOdDay) { continue; }
|
||||
} else {
|
||||
/*
|
||||
The normal situation is that objects are respecting the time size of its main dependency, in which case we only
|
||||
care of not adding objects of the previous day we are currently processing (while on daily files)
|
||||
*/
|
||||
if (record.end < currentDay.valueOf()) { continue; }
|
||||
}
|
||||
}
|
||||
|
||||
fileContent = fileContent + recordSeparator + '['
|
||||
let propertySeparator = ""
|
||||
for (let j = 0; j < recordDefinition.properties.length; j++) {
|
||||
let property = recordDefinition.properties[j]
|
||||
if (property.code.isCalculated !== true) {
|
||||
fileContent = fileContent + propertySeparator
|
||||
if (property.code.isString === true) {
|
||||
fileContent = fileContent + '"'
|
||||
}
|
||||
fileContent = fileContent + record[property.code.codeName]
|
||||
if (property.code.isString === true) {
|
||||
fileContent = fileContent + '"'
|
||||
}
|
||||
if (propertySeparator === "") { propertySeparator = ","; }
|
||||
}
|
||||
}
|
||||
fileContent = fileContent + ']'
|
||||
if (recordSeparator === "") { recordSeparator = ","; }
|
||||
}
|
||||
fileContent = "[" + fileContent + "]";
|
||||
return fileContent
|
||||
}
|
||||
catch (err) {
|
||||
logger.write(MODULE_NAME, "[ERROR] start -> generateFileContent -> err = " + err.stack);
|
||||
callBackFunction(global.DEFAULT_FAIL_RESPONSE);
|
||||
}
|
||||
}
|
||||
|
||||
function writeFile(contextSummary, fileContent, anotherFileWritten, processingDailyFiles, timePeriodLabel, currentDay, callBackFunction) {
|
||||
|
||||
try {
|
||||
|
||||
if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] start -> writeFile -> Entering function."); }
|
||||
|
||||
let market = global.MARKET;
|
||||
let fileName = '' + market.assetA + '_' + market.assetB + '.json';
|
||||
let dateForPath = ''
|
||||
|
||||
if (processingDailyFiles === true) {
|
||||
dateForPath = "/" + currentDay.getUTCFullYear() + '/' + utilities.pad(currentDay.getUTCMonth() + 1, 2) + '/' + utilities.pad(currentDay.getUTCDate(), 2);
|
||||
}
|
||||
|
||||
let filePathRoot = contextSummary.devTeam + "/" + contextSummary.bot + "." + contextSummary.botVersion.major + "." + contextSummary.botVersion.minor + "/" + global.CLONE_EXECUTOR.codeName + "." + global.CLONE_EXECUTOR.version + "/" + global.EXCHANGE_NAME + "/" + contextSummary.dataSetVersion;
|
||||
let filePath = filePathRoot + "/Output/" + contextSummary.product + "/" + contextSummary.dataset + "/" + timePeriodLabel + dateForPath;
|
||||
filePath += '/' + fileName
|
||||
|
||||
fileStorage.createTextFile(contextSummary.devTeam, filePath, fileContent + '\n', onFileCreated);
|
||||
|
||||
function onFileCreated(err) {
|
||||
|
||||
try {
|
||||
|
||||
if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] start -> writeFile -> onFileCreated -> Entering function."); }
|
||||
if (LOG_FILE_CONTENT === true) { logger.write(MODULE_NAME, "[INFO] start -> writeFile -> onFileCreated -> fileContent = " + fileContent); }
|
||||
|
||||
if (err.result !== global.DEFAULT_OK_RESPONSE.result) {
|
||||
|
||||
logger.write(MODULE_NAME, "[ERROR] start -> writeFile -> onFileCreated -> err = " + err.stack);
|
||||
logger.write(MODULE_NAME, "[ERROR] start -> writeFile -> onFileCreated -> filePath = " + filePath);
|
||||
logger.write(MODULE_NAME, "[ERROR] start -> writeFile -> onFileCreated -> market = " + market.assetA + "_" + market.assetB);
|
||||
|
||||
callBackFunction(err);
|
||||
return;
|
||||
|
||||
}
|
||||
|
||||
anotherFileWritten();
|
||||
|
||||
}
|
||||
catch (err) {
|
||||
logger.write(MODULE_NAME, "[ERROR] start -> writeFile -> onFileCreated -> err = " + err.stack);
|
||||
callBackFunction(global.DEFAULT_FAIL_RESPONSE);
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (err) {
|
||||
logger.write(MODULE_NAME, "[ERROR] start -> writeFile -> err = " + err.stack);
|
||||
callBackFunction(global.DEFAULT_FAIL_RESPONSE);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+24
-10
@@ -2,11 +2,12 @@
|
||||
|
||||
const FULL_LOG = true;
|
||||
const LOG_FILE_CONTENT = false;
|
||||
|
||||
const MODULE_NAME = "Data Dependencies";
|
||||
|
||||
let bot = BOT
|
||||
|
||||
let thisObject = {
|
||||
config: undefined,
|
||||
nodeArray: undefined,
|
||||
dataSets: new Map(),
|
||||
initialize: initialize,
|
||||
keys: []
|
||||
@@ -15,15 +16,28 @@
|
||||
|
||||
return thisObject;
|
||||
|
||||
function initialize(pDataDependenciesConfig, callBackFunction) {
|
||||
function initialize(callBackFunction) {
|
||||
|
||||
try {
|
||||
|
||||
if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] initialize -> Entering function."); }
|
||||
|
||||
thisObject.config = pDataDependenciesConfig;
|
||||
/* Basic Valdidations */
|
||||
if (bot.processNode.referenceParent.processDependencies !== undefined) {
|
||||
if (bot.processNode.referenceParent.processDependencies.dataDependencies !== undefined) {
|
||||
thisObject.nodeArray = bot.processNode.referenceParent.processDependencies.dataDependencies
|
||||
} else {
|
||||
logger.write(MODULE_NAME, "[ERROR] initialize -> onInitilized -> It is not possible to not have data dependencies at all.");
|
||||
callBackFunction(global.DEFAULT_OK_RESPONSE)
|
||||
return
|
||||
}
|
||||
} else {
|
||||
logger.write(MODULE_NAME, "[ERROR] initialize -> onInitilized -> It is not possible to not have process dependencies, which means not data dependencies.");
|
||||
callBackFunction(global.DEFAULT_OK_RESPONSE)
|
||||
return
|
||||
}
|
||||
|
||||
if (thisObject.config === undefined) {
|
||||
if (thisObject.nodeArray.length === 0) {
|
||||
|
||||
// We allow old indicators not to declare their data dependencies.
|
||||
|
||||
@@ -32,17 +46,17 @@
|
||||
}
|
||||
/*
|
||||
|
||||
For each dependency declared at the bot config, we will initialize a DataSet as part of this initialization process.
|
||||
For each dependency declared at the nodeArray, we will initialize a DataSet as part of this initialization process.
|
||||
|
||||
*/
|
||||
let alreadyCalledBack = false;
|
||||
let addCount = 0;
|
||||
|
||||
for (let i = 0; i < thisObject.config.length; i++) {
|
||||
for (let i = 0; i < thisObject.nodeArray.length; i++) {
|
||||
|
||||
let dataSetModule = DATA_SET.newDataSet(BOT, logger);
|
||||
|
||||
dataSetModule.initialize(thisObject.config[i], onInitilized);
|
||||
dataSetModule.initialize(thisObject.nodeArray[i], onInitilized);
|
||||
|
||||
function onInitilized(err) {
|
||||
|
||||
@@ -65,14 +79,14 @@
|
||||
|
||||
let key;
|
||||
|
||||
key = thisObject.config[i].devTeam + "-" + thisObject.config[i].bot + "-" + thisObject.config[i].product + "-" + thisObject.config[i].dataSet + "-" + thisObject.config[i].dataSetVersion;
|
||||
key = thisObject.nodeArray[i].devTeam + "-" + thisObject.nodeArray[i].bot + "-" + thisObject.nodeArray[i].product + "-" + thisObject.nodeArray[i].dataSet + "-" + thisObject.nodeArray[i].dataSetVersion;
|
||||
|
||||
thisObject.keys.push(key);
|
||||
thisObject.dataSets.set(key, dataSetModule);
|
||||
|
||||
if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] initialize -> addDataSet -> DataSet added to Map. -> key = " + key); }
|
||||
|
||||
if (addCount === thisObject.config.length) {
|
||||
if (addCount === thisObject.nodeArray.length) {
|
||||
if (alreadyCalledBack === false) {
|
||||
alreadyCalledBack = true
|
||||
callBackFunction(global.DEFAULT_OK_RESPONSE);
|
||||
|
||||
+71
-11
@@ -1,6 +1,6 @@
|
||||
exports.newDataSet = function newDataSet(BOT, logger) {
|
||||
|
||||
const MODULE_NAME = "Data Set";
|
||||
const MODULE_NAME = "Dataset";
|
||||
|
||||
let bot = BOT;
|
||||
|
||||
@@ -10,7 +10,7 @@ exports.newDataSet = function newDataSet(BOT, logger) {
|
||||
createTextFile: createTextFile
|
||||
};
|
||||
|
||||
let dependencyConfig;
|
||||
let dataDependencyNode;
|
||||
|
||||
/* Storage account to be used here. */
|
||||
|
||||
@@ -19,16 +19,76 @@ exports.newDataSet = function newDataSet(BOT, logger) {
|
||||
|
||||
return thisObject;
|
||||
|
||||
function initialize(pDependencyConfig, callBackFunction) {
|
||||
function initialize(pDataDependencyNode, callBackFunction) {
|
||||
|
||||
try {
|
||||
|
||||
|
||||
if (global.LOG_CONTROL[MODULE_NAME].logInfo === true) { logger.write(MODULE_NAME, "[INFO] initialize -> Entering function."); }
|
||||
|
||||
logger.fileName = MODULE_NAME + "." + pDependencyConfig.bot + "." + pDependencyConfig.product + "." + pDependencyConfig.dataSet;
|
||||
dataDependencyNode = pDataDependencyNode;
|
||||
logger.fileName = MODULE_NAME + "." + dataDependencyNode.type + "." + dataDependencyNode.name + "." + dataDependencyNode.id;
|
||||
|
||||
dependencyConfig = pDependencyConfig;
|
||||
/* Some very basic validations that we have all the information needed. */
|
||||
if (dataDependencyNode.referenceParent === undefined) {
|
||||
logger.write(MODULE_NAME, "[ERROR] initialize -> Data Dependency without Reference Parent. Data Dependency = " + JSON.stringify(dataDependencyNode));
|
||||
callBackFunction(global.DEFAULT_FAIL_RESPONSE);
|
||||
return
|
||||
}
|
||||
|
||||
if (dataDependencyNode.referenceParent.code.codeName === undefined) {
|
||||
logger.write(MODULE_NAME, "[ERROR] initialize -> Dataset witn no codeName defined. Product Dataset = " + JSON.stringify(dataDependencyNode.referenceParent));
|
||||
callBackFunction(global.DEFAULT_FAIL_RESPONSE);
|
||||
return
|
||||
}
|
||||
|
||||
if (dataDependencyNode.referenceParent.parentNode === undefined) {
|
||||
logger.write(MODULE_NAME, "[ERROR] initialize -> Dataset not attached to a Product Definition. Dataset = " + JSON.stringify(dataDependencyNode.referenceParent));
|
||||
callBackFunction(global.DEFAULT_FAIL_RESPONSE);
|
||||
return
|
||||
}
|
||||
|
||||
if (dataDependencyNode.referenceParent.parentNode.code.codeName === undefined) {
|
||||
logger.write(MODULE_NAME, "[ERROR] initialize -> Product Definition witn no codeName defined. Product Definition = " + JSON.stringify(dataDependencyNode.referenceParent.parentNode));
|
||||
callBackFunction(global.DEFAULT_FAIL_RESPONSE);
|
||||
return
|
||||
}
|
||||
|
||||
if (dataDependencyNode.referenceParent.parentNode.parentNode === undefined) {
|
||||
logger.write(MODULE_NAME, "[ERROR] initialize -> Product Definition not attached to a Bot. Product Definition = " + JSON.stringify(dataDependencyNode.referenceParent.parentNode));
|
||||
callBackFunction(global.DEFAULT_FAIL_RESPONSE);
|
||||
return
|
||||
}
|
||||
|
||||
if (dataDependencyNode.referenceParent.parentNode.parentNode.code.codeName === undefined) {
|
||||
logger.write(MODULE_NAME, "[ERROR] initialize -> Bot witn no codeName defined. Bot = " + JSON.stringify(dataDependencyNode.referenceParent.parentNode.parentNode));
|
||||
callBackFunction(global.DEFAULT_FAIL_RESPONSE);
|
||||
return
|
||||
}
|
||||
|
||||
if (dataDependencyNode.referenceParent.parentNode.parentNode.parentNode === undefined) {
|
||||
logger.write(MODULE_NAME, "[ERROR] initialize -> Bot not attached to a Team. Bot = " + JSON.stringify(dataDependencyNode.referenceParent.parentNode.parentNode));
|
||||
callBackFunction(global.DEFAULT_FAIL_RESPONSE);
|
||||
return
|
||||
}
|
||||
|
||||
if (dataDependencyNode.referenceParent.parentNode.parentNode.parentNode.code.codeName === undefined) {
|
||||
logger.write(MODULE_NAME, "[ERROR] initialize -> Team witn no codeName defined. Team = " + JSON.stringify(dataDependencyNode.referenceParent.parentNode.parentNode.parentNode));
|
||||
callBackFunction(global.DEFAULT_FAIL_RESPONSE);
|
||||
return
|
||||
}
|
||||
|
||||
/* Simplifying the access to basic info */
|
||||
dataDependencyNode.dataSet = dataDependencyNode.referenceParent.code.codeName
|
||||
dataDependencyNode.product = dataDependencyNode.referenceParent.parentNode.code.codeName
|
||||
dataDependencyNode.bot = dataDependencyNode.referenceParent.parentNode.parentNode.code.codeName
|
||||
dataDependencyNode.devTeam = dataDependencyNode.referenceParent.parentNode.parentNode.parentNode.code.codeName
|
||||
|
||||
/* This stuff is still hardcoded and unresolved. */
|
||||
dataDependencyNode.botVersion = {
|
||||
"major": 1,
|
||||
"minor": 0
|
||||
}
|
||||
dataDependencyNode.dataSetVersion = "dataSet.V1"
|
||||
|
||||
callBackFunction(global.DEFAULT_OK_RESPONSE);
|
||||
|
||||
@@ -44,11 +104,11 @@ exports.newDataSet = function newDataSet(BOT, logger) {
|
||||
|
||||
if (global.LOG_CONTROL[MODULE_NAME].logInfo === true) { logger.write(MODULE_NAME, "[INFO] getTextFile -> Entering function."); }
|
||||
|
||||
let filePathRoot = dependencyConfig.devTeam + "/" + dependencyConfig.bot + "." + dependencyConfig.botVersion.major + "." + dependencyConfig.botVersion.minor + "/" + global.CLONE_EXECUTOR.codeName + "." + global.CLONE_EXECUTOR.version + "/" + global.EXCHANGE_NAME + "/" + dependencyConfig.dataSetVersion;
|
||||
let filePathRoot = dataDependencyNode.devTeam + "/" + dataDependencyNode.bot + "." + dataDependencyNode.botVersion.major + "." + dataDependencyNode.botVersion.minor + "/" + global.CLONE_EXECUTOR.codeName + "." + global.CLONE_EXECUTOR.version + "/" + global.EXCHANGE_NAME + "/" + dataDependencyNode.dataSetVersion;
|
||||
let filePath = filePathRoot + "/Output/" + pFolderPath;
|
||||
filePath += '/' + pFileName
|
||||
|
||||
fileStorage.getTextFile(dependencyConfig.devTeam, filePath, onFileReceived);
|
||||
fileStorage.getTextFile(dataDependencyNode.devTeam, filePath, onFileReceived);
|
||||
|
||||
function onFileReceived(err, text) {
|
||||
|
||||
@@ -72,7 +132,7 @@ exports.newDataSet = function newDataSet(BOT, logger) {
|
||||
if (global.LOG_CONTROL[MODULE_NAME].logInfo === true) { logger.write(MODULE_NAME, "[INFO] createTextFile -> pFolderPath = " + pFolderPath); }
|
||||
if (global.LOG_CONTROL[MODULE_NAME].logInfo === true) { logger.write(MODULE_NAME, "[INFO] createTextFile -> pFileName = " + pFileName); }
|
||||
|
||||
let ownerId = dependencyConfig.devTeam + "-" + dependencyConfig.bot + "-" + dependencyConfig.botVersion.major + "-" + dependencyConfig.botVersion.minor + "-" + dependencyConfig.dataSetVersion;
|
||||
let ownerId = dataDependencyNode.devTeam + "-" + dataDependencyNode.bot + "-" + dataDependencyNode.botVersion.major + "-" + dataDependencyNode.botVersion.minor + "-" + dataDependencyNode.dataSetVersion;
|
||||
let botId = bot.devTeam + "-" + bot.codeName + "-" + bot.version.major + "-" + bot.version.minor + "-" + bot.dataSetVersion;
|
||||
|
||||
if (ownerId !== botId) {
|
||||
@@ -86,10 +146,10 @@ exports.newDataSet = function newDataSet(BOT, logger) {
|
||||
return;
|
||||
}
|
||||
|
||||
let filePathRoot = dependencyConfig.devTeam + "/" + dependencyConfig.bot + "." + dependencyConfig.botVersion.major + "." + dependencyConfig.botVersion.minor + "/" + global.CLONE_EXECUTOR.codeName + "." + global.CLONE_EXECUTOR.version + "/" + global.EXCHANGE_NAME + "/" + dependencyConfig.dataSetVersion;
|
||||
let filePathRoot = dataDependencyNode.devTeam + "/" + dataDependencyNode.bot + "." + dataDependencyNode.botVersion.major + "." + dataDependencyNode.botVersion.minor + "/" + global.CLONE_EXECUTOR.codeName + "." + global.CLONE_EXECUTOR.version + "/" + global.EXCHANGE_NAME + "/" + dataDependencyNode.dataSetVersion;
|
||||
let filePath = filePathRoot + "/Output/" + pFolderPath + '/' + pFileName;
|
||||
|
||||
fileStorage.createTextFile(dependencyConfig.devTeam, filePath, pFileContent, onFileCreated);
|
||||
fileStorage.createTextFile(dataDependencyNode.devTeam, filePath, pFileContent, onFileCreated);
|
||||
|
||||
function onFileCreated(err) {
|
||||
|
||||
|
||||
+12
-13
@@ -21,9 +21,7 @@ exports.newDebugLog = function newDebugLog() {
|
||||
};
|
||||
|
||||
let accumulatedLog = "[";
|
||||
|
||||
let disableLogging;
|
||||
|
||||
let internalLoopCounter = -1;
|
||||
|
||||
return thisObject;
|
||||
@@ -80,35 +78,32 @@ exports.newDebugLog = function newDebugLog() {
|
||||
}
|
||||
|
||||
let fileName;
|
||||
|
||||
if (internalLoopCounter >= 0) {
|
||||
|
||||
fileName = "Loop." + pad(thisObject.bot.loopCounter, 8) + "." + pad(internalLoopCounter, 4) + ".json";
|
||||
|
||||
} else {
|
||||
|
||||
fileName = "Loop." + pad(thisObject.bot.loopCounter, 8) + ".json";
|
||||
|
||||
}
|
||||
|
||||
writeLog();
|
||||
|
||||
/* This is the implementation of the mechanism to auto-mantain logs. */
|
||||
thisObject.bot.LOGS_TO_DELETE_QUEUE.push(filePath + '/' + fileName)
|
||||
if (thisObject.bot.LOGS_TO_DELETE_QUEUE.length > thisObject.bot.DELETE_QUEUE_SIZE) {
|
||||
let fileToDelete = thisObject.bot.LOGS_TO_DELETE_QUEUE[0]
|
||||
thisObject.bot.LOGS_TO_DELETE_QUEUE.splice(0,1)
|
||||
fileStorage.deleteTextFile(thisObject.bot.devTeam, fileToDelete);
|
||||
}
|
||||
|
||||
function writeLog() {
|
||||
|
||||
fileStorage.createTextFile(thisObject.bot.devTeam, filePath + '/' + fileName, contentToPersist + '\r\n' + "]", onFileCreated);
|
||||
|
||||
function onFileCreated(err) {
|
||||
|
||||
if (err.result !== global.DEFAULT_OK_RESPONSE.result) {
|
||||
|
||||
console.log("[ERROR] DebugLog -> persist -> onInizialized -> onFileCreated -> err = "+ err.message);
|
||||
|
||||
setTimeout(writeLog, 10000); // Lets retry until we make it.
|
||||
return;
|
||||
}
|
||||
|
||||
contentToPersist = "";
|
||||
//thisObject = {};
|
||||
}
|
||||
}
|
||||
} catch (err) {
|
||||
@@ -126,6 +121,10 @@ exports.newDebugLog = function newDebugLog() {
|
||||
|
||||
if (thisObject.bot === undefined) { return; }
|
||||
|
||||
if (pModule === "") { // For debugging purposes
|
||||
console.log(pMessage)
|
||||
}
|
||||
|
||||
let newDate = new Date();
|
||||
newDate = newDate.toISOString();
|
||||
|
||||
|
||||
+56
-1
@@ -19,7 +19,8 @@ exports.newFileStorage = function newFileStorage(logger) {
|
||||
|
||||
let thisObject = {
|
||||
getTextFile: getTextFile,
|
||||
createTextFile: createTextFile
|
||||
createTextFile: createTextFile,
|
||||
deleteTextFile: deleteTextFile
|
||||
}
|
||||
|
||||
return thisObject
|
||||
@@ -207,6 +208,60 @@ exports.newFileStorage = function newFileStorage(logger) {
|
||||
}
|
||||
}
|
||||
|
||||
function deleteTextFile(container, filePath, callBackFunction) {
|
||||
|
||||
logger.write(MODULE_NAME, '[INFO] FileStorage -> deleteTextFile -> Entering Function.')
|
||||
|
||||
container = container.toLowerCase()
|
||||
|
||||
/* Choose path for either logs or data */
|
||||
let fileLocation
|
||||
if (filePath.indexOf("/Logs/") > 0) {
|
||||
fileLocation = process.env.LOG_PATH + '/' + container + '/' + filePath
|
||||
} else {
|
||||
fileLocation = process.env.STORAGE_PATH + '/' + container + '/' + filePath
|
||||
}
|
||||
|
||||
try {
|
||||
|
||||
logger.write(MODULE_NAME, '[INFO] FileStorage -> deleteTextFile -> fileLocation: ' + fileLocation)
|
||||
|
||||
const fs = require('fs')
|
||||
fs.unlink(fileLocation, onUnlinked)
|
||||
|
||||
function onUnlinked(err) {
|
||||
if (err) {
|
||||
if (callBackFunction !== undefined) {
|
||||
callBackFunction(global.DEFAULT_FAIL_RESPONSE)
|
||||
}
|
||||
} else {
|
||||
if (callBackFunction !== undefined) {
|
||||
callBackFunction(global.DEFAULT_OK_RESPONSE)
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (err) {
|
||||
logger.write(MODULE_NAME, '[WARN] FileStorage -> deleteTextFile -> Error writing file -> file = ' + fileLocation)
|
||||
logger.write(MODULE_NAME, '[WARN] FileStorage -> deleteTextFile -> Error writing file -> err = ' + err.stack)
|
||||
if (callBackFunction !== undefined) {
|
||||
callBackFunction(global.DEFAULT_FAIL_RESPONSE)
|
||||
}
|
||||
}
|
||||
|
||||
function retry() {
|
||||
if (currentRetryWriteTextFile < MAX_RETRY) {
|
||||
currentRetryWriteTextFile++
|
||||
logger.write(MODULE_NAME, '[WARN] FileStorage -> createTextFile -> retry -> Will try to write the file again -> Retry #: ' + currentRetryWriteTextFile)
|
||||
createTextFile(container, filePath, fileContent, callBackFunction)
|
||||
} else {
|
||||
currentRetryWriteTextFile = 0
|
||||
logger.write(MODULE_NAME, '[ERROR] FileStorage -> createTextFile -> retry -> Max retries reached writting a file. Giving up.')
|
||||
logger.write(MODULE_NAME, '[ERROR] FileStorage -> createTextFile -> retry -> file = ' + fileLocation)
|
||||
callBackFunction(global.DEFAULT_FAIL_RESPONSE)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Function to create folders of missing folders at any path. */
|
||||
|
||||
function mkDirByPathSync(targetDir, { isRelativeToScript = false } = {}) {
|
||||
|
||||
+164
@@ -0,0 +1,164 @@
|
||||
exports.newIndicatorBot = function newIndicatorBot(bot, logger, UTILITIES, FILE_STORAGE) {
|
||||
|
||||
const FULL_LOG = true;
|
||||
const LOG_FILE_CONTENT = false;
|
||||
const ONE_DAY_IN_MILISECONDS = 24 * 60 * 60 * 1000;
|
||||
|
||||
const MODULE_NAME = "Indicator Bot";
|
||||
|
||||
let thisObject = {
|
||||
initialize: initialize,
|
||||
finalize: finalize,
|
||||
start: start
|
||||
};
|
||||
|
||||
let utilities = UTILITIES.newCloudUtilities(logger);
|
||||
let fileStorage = FILE_STORAGE.newFileStorage(logger);
|
||||
|
||||
const COMMONS = require('./Commons.js');
|
||||
let commons = COMMONS.newCommons(bot, logger, UTILITIES, FILE_STORAGE);
|
||||
|
||||
return thisObject;
|
||||
|
||||
function finalize() {
|
||||
thisObject = undefined
|
||||
utilities = undefined
|
||||
fileStorage = undefined
|
||||
commons = undefined
|
||||
}
|
||||
|
||||
function initialize(callBackFunction) {
|
||||
|
||||
try {
|
||||
|
||||
logger.fileName = MODULE_NAME;
|
||||
logger.initialize();
|
||||
|
||||
if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] initialize -> Entering function."); }
|
||||
|
||||
callBackFunction(global.DEFAULT_OK_RESPONSE);
|
||||
|
||||
} catch (err) {
|
||||
logger.write(MODULE_NAME, "[ERROR] initialize -> err = " + err.stack);
|
||||
callBackFunction(global.DEFAULT_FAIL_RESPONSE);
|
||||
}
|
||||
}
|
||||
|
||||
function start(dataFiles, timePeriod, timePeriodLabel, currentDay, interExecutionMemory, callBackFunction) {
|
||||
|
||||
try {
|
||||
|
||||
if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] start -> Entering function."); }
|
||||
|
||||
let products = {}
|
||||
let mainDependency = {}
|
||||
let processingDailyFiles
|
||||
|
||||
if (currentDay !== undefined) {
|
||||
processingDailyFiles = true
|
||||
} else {
|
||||
processingDailyFiles = false
|
||||
}
|
||||
|
||||
/* The first phase here is about checking that we have everything we need at the definition level. */
|
||||
let dataDependencies = bot.processNode.referenceParent.processDependencies.dataDependencies
|
||||
if (commons.validateDataDependencies(dataDependencies, callBackFunction) !== true) { return }
|
||||
|
||||
let outputDatasets = bot.processNode.referenceParent.processOutput.outputDatasets
|
||||
if (commons.validateOutputDatasets(outputDatasets, callBackFunction) !== true) { return }
|
||||
|
||||
/* The second phase is about transforming the inputs into a format that can be used to apply the user defined code. */
|
||||
commons.inflateDatafiles(dataFiles, dataDependencies, products, mainDependency, timePeriod)
|
||||
|
||||
/* During the third phase, we need to generate the data of the different products this process produces an output */
|
||||
for (let i = 0; i < outputDatasets.length; i++) {
|
||||
|
||||
let outputDatasetNode = outputDatasets[i]
|
||||
let jsonData // Just build data as Json objects
|
||||
let outputData // Data built as a result of applying user defined code and formulas at the Data Building Procedure
|
||||
let singularVariableName // Name of the variable for this product
|
||||
let recordDefinition // Record as defined by the user at the UI
|
||||
let fileContent // Here we store the contents of the new data built just before writing it to a file.
|
||||
let resultsWithIrregularPeriods // A product will have irregular periods when the User Code inserts new result records at will, in contrast with normal procedure where the platform insert one record per loop execution.
|
||||
|
||||
/*
|
||||
For each outputDatasetNode in our process output, we will build the information based on our input products.
|
||||
*/
|
||||
|
||||
recordDefinition = outputDatasetNode.referenceParent.parentNode.record
|
||||
singularVariableName = outputDatasetNode.referenceParent.parentNode.code.singularVariableName
|
||||
|
||||
/* Check Irregular Periods */
|
||||
if (outputDatasetNode.referenceParent.parentNode.dataBuilding.loop.code.code.indexOf('results.push') >= 0) {
|
||||
resultsWithIrregularPeriods = true
|
||||
}
|
||||
|
||||
/* Build the data */
|
||||
jsonData = commons.dataBuildingProcedure(
|
||||
products,
|
||||
mainDependency,
|
||||
recordDefinition,
|
||||
outputDatasetNode.referenceParent.parentNode.dataBuilding,
|
||||
singularVariableName,
|
||||
timePeriod,
|
||||
timePeriodLabel,
|
||||
resultsWithIrregularPeriods,
|
||||
interExecutionMemory,
|
||||
processingDailyFiles,
|
||||
currentDay
|
||||
)
|
||||
|
||||
/* Add the calculated properties */
|
||||
if (outputDatasetNode.referenceParent.parentNode.calculations !== undefined) {
|
||||
outputData = commons.calculationsProcedure(jsonData, recordDefinition, outputDatasetNode.referenceParent.parentNode.calculations, singularVariableName, timePeriod)
|
||||
} else {
|
||||
outputData = jsonData
|
||||
}
|
||||
products[outputDatasetNode.referenceParent.parentNode.code.pluralVariableName] = outputData
|
||||
}
|
||||
|
||||
/*At the fourth and last phase, we will save the new information generated into files corresponding to each output outputDatasetNode.*/
|
||||
let totalFilesWritten = 0
|
||||
for (let i = 0; i < outputDatasets.length; i++) {
|
||||
let outputDatasetNode = outputDatasets[i]
|
||||
let outputData = products[outputDatasetNode.referenceParent.parentNode.code.pluralVariableName]
|
||||
let resultsWithIrregularPeriods // A product will have irregular periods when the User Code inserts new result records at will, in contrast with normal procedure where the platform insert one record per loop execution.
|
||||
let contextSummary = {}
|
||||
|
||||
/* Check Irregular Periods */
|
||||
if (outputDatasetNode.referenceParent.parentNode.dataBuilding.loop.code.code.indexOf('results.push') >= 0) {
|
||||
resultsWithIrregularPeriods = true
|
||||
}
|
||||
|
||||
/* Simplifying the access to basic info */
|
||||
|
||||
contextSummary.dataset = outputDatasetNode.referenceParent.code.codeName
|
||||
contextSummary.product = outputDatasetNode.referenceParent.parentNode.code.codeName
|
||||
contextSummary.bot = outputDatasetNode.referenceParent.parentNode.parentNode.code.codeName
|
||||
contextSummary.devTeam = outputDatasetNode.referenceParent.parentNode.parentNode.parentNode.code.codeName
|
||||
|
||||
/* This stuff is still hardcoded and unresolved. */
|
||||
contextSummary.botVersion = {
|
||||
"major": 1,
|
||||
"minor": 0
|
||||
}
|
||||
contextSummary.dataSetVersion = "dataSet.V1"
|
||||
|
||||
let fileContent = commons.generateFileContent(outputData, outputDatasetNode.referenceParent.parentNode.record, resultsWithIrregularPeriods, processingDailyFiles, currentDay, callBackFunction)
|
||||
commons.writeFile(contextSummary, fileContent, anotherFileWritten, processingDailyFiles, timePeriodLabel, currentDay, callBackFunction)
|
||||
}
|
||||
|
||||
|
||||
function anotherFileWritten() {
|
||||
totalFilesWritten++
|
||||
if (totalFilesWritten === outputDatasets.length) {
|
||||
callBackFunction(global.DEFAULT_OK_RESPONSE);
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (err) {
|
||||
logger.write(MODULE_NAME, "[ERROR] start -> err = " + err.stack);
|
||||
callBackFunction(global.DEFAULT_FAIL_RESPONSE);
|
||||
}
|
||||
}
|
||||
};
|
||||
+320
-14
@@ -29,15 +29,21 @@
|
||||
return thisObject;
|
||||
|
||||
function initialize(pProcessConfig, callBackFunction) {
|
||||
|
||||
/* This function is exactly the same in the 3 modules representing the 2 different bot types loops. */
|
||||
|
||||
|
||||
try {
|
||||
if (FULL_LOG === true) { parentLogger.write(MODULE_NAME, "[INFO] initialize -> Entering function."); }
|
||||
|
||||
processConfig = pProcessConfig;
|
||||
|
||||
let filePath = bot.devTeam + "/" + "bots" + "/" + bot.repo + "/" + pProcessConfig.name
|
||||
if (bot.definedByUI === true) {
|
||||
/* The code of the bot is defined at the UI. No need to load a file with the code. */
|
||||
callBackFunction(global.DEFAULT_OK_RESPONSE);
|
||||
return
|
||||
}
|
||||
|
||||
/* This bot is not ready for taking its code from the UI, then we need to load it from its repo. */
|
||||
|
||||
let filePath = bot.devTeam + "/" + "bots" + "/" + bot.repo + "/" + pProcessConfig.codeName
|
||||
filePath += "/User.Bot.js"
|
||||
|
||||
fileStorage.getTextFile(bot.devTeam, filePath, onBotDownloaded);
|
||||
@@ -47,6 +53,7 @@
|
||||
if (err.result !== global.DEFAULT_OK_RESPONSE.result) {
|
||||
|
||||
parentLogger.write(MODULE_NAME, "[ERROR] initialize -> onInizialized -> onBotDownloaded -> err = " + err.message);
|
||||
parentLogger.write(MODULE_NAME, "[ERROR] initialize -> onInizialized -> onBotDownloaded -> filePath = " + filePath);
|
||||
callBackFunction(global.DEFAULT_FAIL_RESPONSE);
|
||||
return;
|
||||
}
|
||||
@@ -129,6 +136,8 @@
|
||||
const STATUS_DEPENDENCIES = require(ROOT_DIR + 'StatusDependencies');
|
||||
const DATA_DEPENDENCIES = require(ROOT_DIR + 'DataDependencies');
|
||||
const DATA_SET = require(ROOT_DIR + 'DataSet');
|
||||
const PROCESS_EXECUTION_EVENTS = require(ROOT_DIR + 'ProcessExecutionEvents');
|
||||
const PROCESS_OUTPUT = require(ROOT_DIR + 'ProcessOutput');
|
||||
|
||||
/* We define the datetime for the process that we are running now. This will be the official processing time for both the infraestructure and the bot. */
|
||||
|
||||
@@ -141,6 +150,8 @@
|
||||
|
||||
/* We will prepare first the infraestructure needed for the bot to run. There are 3 modules we need to sucessfullly initialize first. */
|
||||
|
||||
let processOutput
|
||||
let processExecutionEvents
|
||||
let userBot;
|
||||
let processFramework;
|
||||
let statusDependencies;
|
||||
@@ -148,7 +159,155 @@
|
||||
|
||||
let nextWaitTime;
|
||||
|
||||
initializeStatusDependencies();
|
||||
initializeProcessExecutionEvents();
|
||||
|
||||
function initializeProcessExecutionEvents() {
|
||||
|
||||
try {
|
||||
|
||||
if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] run -> loop -> initializeProcessExecutionEvents -> Entering function."); }
|
||||
|
||||
processExecutionEvents = PROCESS_EXECUTION_EVENTS.newProcessExecutionEvents(bot, logger)
|
||||
|
||||
processExecutionEvents.initialize(pMonth, pYear, onInizialized);
|
||||
|
||||
function onInizialized(err) {
|
||||
|
||||
try {
|
||||
|
||||
if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] run -> loop -> initializeProcessExecutionEvents -> onInizialized -> Entering function."); }
|
||||
|
||||
switch (err.result) {
|
||||
case global.DEFAULT_OK_RESPONSE.result: {
|
||||
logger.write(MODULE_NAME, "[INFO] run -> loop -> initializeProcessExecutionEvents -> onInizialized -> Execution finished well.");
|
||||
startProcessExecutionEvents()
|
||||
return;
|
||||
}
|
||||
case global.DEFAULT_RETRY_RESPONSE.result: { // Something bad happened, but if we retry in a while it might go through the next time.
|
||||
logger.write(MODULE_NAME, "[WARN] run -> loop -> initializeProcessExecutionEvents -> onInizialized -> Retry Later. Requesting Execution Retry.");
|
||||
nextWaitTime = 'Retry';
|
||||
loopControl(nextWaitTime);
|
||||
return;
|
||||
}
|
||||
case global.DEFAULT_FAIL_RESPONSE.result: { // This is an unexpected exception that we do not know how to handle.
|
||||
processStopped()
|
||||
logger.write(MODULE_NAME, "[ERROR] run -> loop -> initializeProcessExecutionEvents -> onInizialized -> Operation Failed. Aborting the process.");
|
||||
logger.persist();
|
||||
clearInterval(fixedTimeLoopIntervalHandle);
|
||||
clearTimeout(nextLoopTimeoutHandle);
|
||||
clearTimeout(checkLoopHealthHandle);
|
||||
bot.enableCheckLoopHealth = false;
|
||||
callBackFunction(err);
|
||||
return;
|
||||
}
|
||||
default: {
|
||||
logger.write(MODULE_NAME, "[ERROR] run -> loop -> initializeProcessExecutionEvents -> onInizialized -> Unhandled err.result received. -> err.result = " + err.result);
|
||||
logger.write(MODULE_NAME, "[ERROR] run -> loop -> initializeProcessExecutionEvents -> onInizialized -> Unhandled err.result received. -> err = " + err.message);
|
||||
|
||||
logger.persist();
|
||||
clearInterval(fixedTimeLoopIntervalHandle);
|
||||
clearTimeout(nextLoopTimeoutHandle);
|
||||
clearTimeout(checkLoopHealthHandle);
|
||||
bot.enableCheckLoopHealth = false;
|
||||
callBackFunction(global.DEFAULT_FAIL_RESPONSE);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
} catch (err) {
|
||||
logger.write(MODULE_NAME, "[ERROR] run -> loop -> initializeProcessExecutionEvents -> onInizialized -> err = " + err.stack);
|
||||
logger.persist();
|
||||
clearInterval(fixedTimeLoopIntervalHandle);
|
||||
clearTimeout(nextLoopTimeoutHandle);
|
||||
clearTimeout(checkLoopHealthHandle);
|
||||
bot.enableCheckLoopHealth = false;
|
||||
callBackFunction(err);
|
||||
}
|
||||
}
|
||||
|
||||
} catch (err) {
|
||||
logger.write(MODULE_NAME, "[ERROR] run -> loop -> initializeProcessExecutionEvents -> err = " + err.stack);
|
||||
logger.persist();
|
||||
clearInterval(fixedTimeLoopIntervalHandle);
|
||||
clearTimeout(nextLoopTimeoutHandle);
|
||||
clearTimeout(checkLoopHealthHandle);
|
||||
bot.enableCheckLoopHealth = false;
|
||||
callBackFunction(err);
|
||||
}
|
||||
}
|
||||
|
||||
function startProcessExecutionEvents() {
|
||||
|
||||
try {
|
||||
|
||||
if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] run -> loop -> startProcessExecutionEvents -> Entering function."); }
|
||||
|
||||
processExecutionEvents.start(onStarted);
|
||||
|
||||
function onStarted(err) {
|
||||
|
||||
try {
|
||||
|
||||
if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] run -> loop -> startProcessExecutionEvents -> onStarted -> Entering function."); }
|
||||
|
||||
switch (err.result) {
|
||||
case global.DEFAULT_OK_RESPONSE.result: {
|
||||
logger.write(MODULE_NAME, "[INFO] run -> loop -> startProcessExecutionEvents -> onStarted -> Execution finished well.");
|
||||
initializeStatusDependencies();
|
||||
return;
|
||||
}
|
||||
case global.DEFAULT_RETRY_RESPONSE.result: { // Something bad happened, but if we retry in a while it might go through the next time.
|
||||
logger.write(MODULE_NAME, "[WARN] run -> loop -> startProcessExecutionEvents -> onStarted -> Retry Later. Requesting Execution Retry.");
|
||||
nextWaitTime = 'Retry';
|
||||
loopControl(nextWaitTime);
|
||||
return;
|
||||
}
|
||||
case global.DEFAULT_FAIL_RESPONSE.result: { // This is an unexpected exception that we do not know how to handle.
|
||||
processStopped()
|
||||
logger.write(MODULE_NAME, "[ERROR] run -> loop -> startProcessExecutionEvents -> onStarted -> Operation Failed. Aborting the process.");
|
||||
logger.persist();
|
||||
clearInterval(fixedTimeLoopIntervalHandle);
|
||||
clearTimeout(nextLoopTimeoutHandle);
|
||||
clearTimeout(checkLoopHealthHandle);
|
||||
bot.enableCheckLoopHealth = false;
|
||||
callBackFunction(err);
|
||||
return;
|
||||
}
|
||||
default: {
|
||||
logger.write(MODULE_NAME, "[ERROR] run -> loop -> startProcessExecutionEvents -> onStarted -> Unhandled err.result received. -> err.result = " + err.result);
|
||||
logger.write(MODULE_NAME, "[ERROR] run -> loop -> startProcessExecutionEvents -> onStarted -> Unhandled err.result received. -> err = " + err.message);
|
||||
|
||||
logger.persist();
|
||||
clearInterval(fixedTimeLoopIntervalHandle);
|
||||
clearTimeout(nextLoopTimeoutHandle);
|
||||
clearTimeout(checkLoopHealthHandle);
|
||||
bot.enableCheckLoopHealth = false;
|
||||
callBackFunction(global.DEFAULT_FAIL_RESPONSE);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
} catch (err) {
|
||||
logger.write(MODULE_NAME, "[ERROR] run -> loop -> startProcessExecutionEvents -> onStarted -> err = " + err.stack);
|
||||
logger.persist();
|
||||
clearInterval(fixedTimeLoopIntervalHandle);
|
||||
clearTimeout(nextLoopTimeoutHandle);
|
||||
clearTimeout(checkLoopHealthHandle);
|
||||
bot.enableCheckLoopHealth = false;
|
||||
callBackFunction(err);
|
||||
}
|
||||
}
|
||||
|
||||
} catch (err) {
|
||||
logger.write(MODULE_NAME, "[ERROR] run -> loop -> startProcessExecutionEvents -> err = " + err.stack);
|
||||
logger.persist();
|
||||
clearInterval(fixedTimeLoopIntervalHandle);
|
||||
clearTimeout(nextLoopTimeoutHandle);
|
||||
clearTimeout(checkLoopHealthHandle);
|
||||
bot.enableCheckLoopHealth = false;
|
||||
callBackFunction(err);
|
||||
}
|
||||
}
|
||||
|
||||
function initializeStatusDependencies() {
|
||||
|
||||
@@ -158,7 +317,7 @@
|
||||
|
||||
statusDependencies = STATUS_DEPENDENCIES.newStatusDependencies(bot, logger, STATUS_REPORT, UTILITIES);
|
||||
|
||||
statusDependencies.initialize(processConfig.statusDependencies, pMonth, pYear, onInizialized);
|
||||
statusDependencies.initialize(pMonth, pYear, onInizialized);
|
||||
|
||||
function onInizialized(err) {
|
||||
|
||||
@@ -233,7 +392,7 @@
|
||||
|
||||
dataDependencies = DATA_DEPENDENCIES.newDataDependencies(bot, logger, DATA_SET);
|
||||
|
||||
dataDependencies.initialize(processConfig.dataDependencies, onInizialized);
|
||||
dataDependencies.initialize(onInizialized);
|
||||
|
||||
function onInizialized(err) {
|
||||
|
||||
@@ -253,12 +412,12 @@
|
||||
|
||||
switch (processConfig.framework.name) {
|
||||
case 'Multi-Period-Market': {
|
||||
processFramework = MULTI_PERIOD_MARKET.newMultiPeriodMarket(bot, logger, COMMONS_MODULE, UTILITIES, USER_BOT_MODULE, COMMONS_MODULE);
|
||||
processFramework = MULTI_PERIOD_MARKET.newMultiPeriodMarket(bot, logger, UTILITIES, FILE_STORAGE);
|
||||
intitializeProcessFramework();
|
||||
break;
|
||||
}
|
||||
case 'Multi-Period-Daily': {
|
||||
processFramework = MULTI_PERIOD_DAILY.newMultiPeriodDaily(bot, logger, COMMONS_MODULE, UTILITIES, USER_BOT_MODULE, COMMONS_MODULE);
|
||||
processFramework = MULTI_PERIOD_DAILY.newMultiPeriodDaily(bot, logger, UTILITIES, FILE_STORAGE);
|
||||
intitializeProcessFramework();
|
||||
break;
|
||||
}
|
||||
@@ -448,8 +607,7 @@
|
||||
switch (err.result) {
|
||||
case global.DEFAULT_OK_RESPONSE.result: {
|
||||
logger.write(MODULE_NAME, "[INFO] run -> loop -> startUserBot -> onFinished -> Execution finished well.");
|
||||
nextWaitTime = 'Normal';
|
||||
loopControl(nextWaitTime);
|
||||
raiseEventsProcessOutput()
|
||||
return;
|
||||
}
|
||||
case global.DEFAULT_RETRY_RESPONSE.result: { // Something bad happened, but if we retry in a while it might go through the next time.
|
||||
@@ -568,7 +726,7 @@
|
||||
|
||||
if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] run -> loop -> intitializeProcessFramework -> Entering function."); }
|
||||
|
||||
processFramework.initialize(processConfig, statusDependencies, dataDependencies, undefined, onInizialized);
|
||||
processFramework.initialize(processConfig, statusDependencies, dataDependencies, onInizialized);
|
||||
|
||||
function onInizialized(err) {
|
||||
|
||||
@@ -681,8 +839,7 @@
|
||||
switch (err.result) {
|
||||
case global.DEFAULT_OK_RESPONSE.result: {
|
||||
logger.write(MODULE_NAME, "[INFO] run -> loop -> startProcessFramework -> onFinished -> Execution finished well.");
|
||||
nextWaitTime = 'Normal';
|
||||
loopControl(nextWaitTime);
|
||||
raiseEventsProcessOutput()
|
||||
return;
|
||||
}
|
||||
case global.DEFAULT_RETRY_RESPONSE.result: { // Something bad happened, but if we retry in a while it might go through the next time.
|
||||
@@ -795,6 +952,155 @@
|
||||
}
|
||||
}
|
||||
|
||||
function raiseEventsProcessOutput() {
|
||||
|
||||
try {
|
||||
|
||||
if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] run -> loop -> raiseEventsProcessOutput -> Entering function."); }
|
||||
|
||||
processOutput = PROCESS_OUTPUT.newProcessOutput(bot, logger)
|
||||
|
||||
processOutput.raiseEvents(statusDependencies, onFinished);
|
||||
|
||||
function onFinished(err) {
|
||||
|
||||
try {
|
||||
|
||||
if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] run -> loop -> raiseEventsProcessOutput -> onFinished -> Entering function."); }
|
||||
|
||||
switch (err.result) {
|
||||
case global.DEFAULT_OK_RESPONSE.result: {
|
||||
logger.write(MODULE_NAME, "[INFO] run -> loop -> raiseEventsProcessOutput -> onFinished -> Execution finished well.");
|
||||
finishProcessExecutionEvents()
|
||||
return;
|
||||
}
|
||||
case global.DEFAULT_RETRY_RESPONSE.result: { // Something bad happened, but if we retry in a while it might go through the next time.
|
||||
logger.write(MODULE_NAME, "[WARN] run -> loop -> raiseEventsProcessOutput -> onFinished -> Retry Later. Requesting Execution Retry.");
|
||||
nextWaitTime = 'Retry';
|
||||
loopControl(nextWaitTime);
|
||||
return;
|
||||
}
|
||||
case global.DEFAULT_FAIL_RESPONSE.result: { // This is an unexpected exception that we do not know how to handle.
|
||||
processStopped()
|
||||
logger.write(MODULE_NAME, "[ERROR] run -> loop -> raiseEventsProcessOutput -> onFinished -> Operation Failed. Aborting the process.");
|
||||
logger.persist();
|
||||
clearInterval(fixedTimeLoopIntervalHandle);
|
||||
clearTimeout(nextLoopTimeoutHandle);
|
||||
clearTimeout(checkLoopHealthHandle);
|
||||
bot.enableCheckLoopHealth = false;
|
||||
callBackFunction(err);
|
||||
return;
|
||||
}
|
||||
default: {
|
||||
logger.write(MODULE_NAME, "[ERROR] run -> loop -> raiseEventsProcessOutput -> onFinished -> Unhandled err.result received. -> err.result = " + err.result);
|
||||
logger.write(MODULE_NAME, "[ERROR] run -> loop -> raiseEventsProcessOutput -> onFinished -> Unhandled err.result received. -> err = " + err.message);
|
||||
|
||||
logger.persist();
|
||||
clearInterval(fixedTimeLoopIntervalHandle);
|
||||
clearTimeout(nextLoopTimeoutHandle);
|
||||
clearTimeout(checkLoopHealthHandle);
|
||||
bot.enableCheckLoopHealth = false;
|
||||
callBackFunction(global.DEFAULT_FAIL_RESPONSE);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
} catch (err) {
|
||||
logger.write(MODULE_NAME, "[ERROR] run -> loop -> raiseEventsProcessOutput -> onFinished -> err = " + err.stack);
|
||||
logger.persist();
|
||||
clearInterval(fixedTimeLoopIntervalHandle);
|
||||
clearTimeout(nextLoopTimeoutHandle);
|
||||
clearTimeout(checkLoopHealthHandle);
|
||||
bot.enableCheckLoopHealth = false;
|
||||
callBackFunction(err);
|
||||
}
|
||||
}
|
||||
|
||||
} catch (err) {
|
||||
logger.write(MODULE_NAME, "[ERROR] run -> loop -> raiseEventsProcessOutput -> err = " + err.stack);
|
||||
logger.persist();
|
||||
clearInterval(fixedTimeLoopIntervalHandle);
|
||||
clearTimeout(nextLoopTimeoutHandle);
|
||||
clearTimeout(checkLoopHealthHandle);
|
||||
bot.enableCheckLoopHealth = false;
|
||||
callBackFunction(err);
|
||||
}
|
||||
}
|
||||
|
||||
function finishProcessExecutionEvents() {
|
||||
|
||||
try {
|
||||
|
||||
if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] run -> loop -> finishProcessExecutionEvents -> Entering function."); }
|
||||
|
||||
processExecutionEvents.finish(onFinished);
|
||||
|
||||
function onFinished(err) {
|
||||
|
||||
try {
|
||||
|
||||
if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] run -> loop -> finishProcessExecutionEvents -> onFinished -> Entering function."); }
|
||||
|
||||
switch (err.result) {
|
||||
case global.DEFAULT_OK_RESPONSE.result: {
|
||||
logger.write(MODULE_NAME, "[INFO] run -> loop -> finishProcessExecutionEvents -> onFinished -> Execution finished well.");
|
||||
nextWaitTime = 'Normal';
|
||||
loopControl(nextWaitTime);
|
||||
return;
|
||||
}
|
||||
case global.DEFAULT_RETRY_RESPONSE.result: { // Something bad happened, but if we retry in a while it might go through the next time.
|
||||
logger.write(MODULE_NAME, "[WARN] run -> loop -> finishProcessExecutionEvents -> onFinished -> Retry Later. Requesting Execution Retry.");
|
||||
nextWaitTime = 'Retry';
|
||||
loopControl(nextWaitTime);
|
||||
return;
|
||||
}
|
||||
case global.DEFAULT_FAIL_RESPONSE.result: { // This is an unexpected exception that we do not know how to handle.
|
||||
processStopped()
|
||||
logger.write(MODULE_NAME, "[ERROR] run -> loop -> finishProcessExecutionEvents -> onFinished -> Operation Failed. Aborting the process.");
|
||||
logger.persist();
|
||||
clearInterval(fixedTimeLoopIntervalHandle);
|
||||
clearTimeout(nextLoopTimeoutHandle);
|
||||
clearTimeout(checkLoopHealthHandle);
|
||||
bot.enableCheckLoopHealth = false;
|
||||
callBackFunction(err);
|
||||
return;
|
||||
}
|
||||
default: {
|
||||
logger.write(MODULE_NAME, "[ERROR] run -> loop -> finishProcessExecutionEvents -> onFinished -> Unhandled err.result received. -> err.result = " + err.result);
|
||||
logger.write(MODULE_NAME, "[ERROR] run -> loop -> finishProcessExecutionEvents -> onFinished -> Unhandled err.result received. -> err = " + err.message);
|
||||
|
||||
logger.persist();
|
||||
clearInterval(fixedTimeLoopIntervalHandle);
|
||||
clearTimeout(nextLoopTimeoutHandle);
|
||||
clearTimeout(checkLoopHealthHandle);
|
||||
bot.enableCheckLoopHealth = false;
|
||||
callBackFunction(global.DEFAULT_FAIL_RESPONSE);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
} catch (err) {
|
||||
logger.write(MODULE_NAME, "[ERROR] run -> loop -> finishProcessExecutionEvents -> onFinished -> err = " + err.stack);
|
||||
logger.persist();
|
||||
clearInterval(fixedTimeLoopIntervalHandle);
|
||||
clearTimeout(nextLoopTimeoutHandle);
|
||||
clearTimeout(checkLoopHealthHandle);
|
||||
bot.enableCheckLoopHealth = false;
|
||||
callBackFunction(err);
|
||||
}
|
||||
}
|
||||
|
||||
} catch (err) {
|
||||
logger.write(MODULE_NAME, "[ERROR] run -> loop -> finishProcessExecutionEvents -> err = " + err.stack);
|
||||
logger.persist();
|
||||
clearInterval(fixedTimeLoopIntervalHandle);
|
||||
clearTimeout(nextLoopTimeoutHandle);
|
||||
clearTimeout(checkLoopHealthHandle);
|
||||
bot.enableCheckLoopHealth = false;
|
||||
callBackFunction(err);
|
||||
}
|
||||
}
|
||||
|
||||
function loopControl(nextWaitTime) {
|
||||
|
||||
if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] run -> loop -> loopControl -> Entering function."); }
|
||||
|
||||
+52
-60
@@ -1,4 +1,4 @@
|
||||
exports.newMultiPeriod = function newMultiPeriod(bot, logger, COMMONS, UTILITIES, USER_BOT_MODULE, COMMONS_MODULE) {
|
||||
exports.newMultiPeriod = function newMultiPeriod(bot, logger, UTILITIES, USER_BOT_MODULE, USER_BOT_COMMONS) {
|
||||
|
||||
const FULL_LOG = true;
|
||||
const LOG_FILE_CONTENT = false;
|
||||
@@ -16,11 +16,11 @@
|
||||
|
||||
let statusDependencies;
|
||||
let dataDependencies;
|
||||
let storages = [];
|
||||
let dataFiles = [];
|
||||
let datasets = [];
|
||||
let dataFiles = new Map();
|
||||
let multiPeriodDataFiles = new Map();
|
||||
|
||||
let usertBot;
|
||||
let botInstance;
|
||||
|
||||
const FILE_STORAGE = require('./FileStorage.js');
|
||||
let fileStorage = FILE_STORAGE.newFileStorage(logger);
|
||||
@@ -42,11 +42,11 @@
|
||||
dataDependencies = pDataDependencies;
|
||||
processConfig = pProcessConfig;
|
||||
|
||||
for (let i = 0; i < dataDependencies.config.length; i++) {
|
||||
for (let i = 0; i < dataDependencies.nodeArray.length; i++) {
|
||||
|
||||
let key;
|
||||
let storage;
|
||||
let dependency = dataDependencies.config[i];
|
||||
let dataset;
|
||||
let dependency = dataDependencies.nodeArray[i];
|
||||
|
||||
key = dependency.devTeam + "-" +
|
||||
dependency.bot + "-" +
|
||||
@@ -54,14 +54,16 @@
|
||||
dependency.dataSet + "-" +
|
||||
dependency.dataSetVersion
|
||||
|
||||
storage = dataDependencies.dataSets.get(key);
|
||||
dataset = dataDependencies.dataSets.get(key);
|
||||
|
||||
storages.push(storage);
|
||||
datasets.push(dataset);
|
||||
|
||||
}
|
||||
|
||||
usertBot = USER_BOT_MODULE.newUserBot(bot, logger, COMMONS_MODULE, UTILITIES, fileStorage);
|
||||
usertBot.initialize(callBackFunction, pAssistant);
|
||||
let USER_BOT_MODULE = require("./TradingBot")
|
||||
|
||||
botInstance = USER_BOT_MODULE.newTradingBot(bot, logger, UTILITIES, FILE_STORAGE);
|
||||
botInstance.initialize(pAssistant, callBackFunction);
|
||||
|
||||
} catch (err) {
|
||||
logger.write(MODULE_NAME, "[ERROR] initialize -> err = " + err.stack);
|
||||
@@ -70,13 +72,13 @@
|
||||
}
|
||||
|
||||
function finalize() {
|
||||
storages = undefined
|
||||
datasets = undefined
|
||||
dataFiles = undefined
|
||||
multiPeriodDataFiles = undefined
|
||||
statusDependencies = undefined
|
||||
dataDependencies = undefined
|
||||
usertBot.finalize()
|
||||
usertBot = undefined
|
||||
botInstance.finalize()
|
||||
botInstance = undefined
|
||||
fileStorage = undefined
|
||||
processConfig = undefined
|
||||
thisObject = undefined
|
||||
@@ -125,12 +127,7 @@
|
||||
Here we get the status report from the bot who knows which is the end of the market.
|
||||
*/
|
||||
|
||||
let botWhoKnowsTheEndOfTheMarket = statusDependencies.config[processConfig.framework.endDate.takeItFromStatusDependency];
|
||||
|
||||
reportKey = botWhoKnowsTheEndOfTheMarket.devTeam + "-" + botWhoKnowsTheEndOfTheMarket.bot + "-" + botWhoKnowsTheEndOfTheMarket.process + "-" + "dataSet.V1";
|
||||
if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] start -> getContextVariables -> reportKey = " + reportKey); }
|
||||
|
||||
statusReport = statusDependencies.statusReports.get(reportKey);
|
||||
statusReport = statusDependencies.reportsByMainUtility.get("Market Ending Point")
|
||||
|
||||
if (statusReport === undefined) { // This means the status report does not exist, that could happen for instance at the begining of a month.
|
||||
logger.write(MODULE_NAME, "[WARN] start -> getContextVariables -> Status Report does not exist. Retrying Later. ");
|
||||
@@ -144,7 +141,7 @@
|
||||
return;
|
||||
}
|
||||
|
||||
thisReport = statusDependencies.statusReports.get(reportKey).file;
|
||||
thisReport = statusReport.file;
|
||||
|
||||
if (thisReport.lastFile === undefined) {
|
||||
logger.write(MODULE_NAME, "[WARN] start -> getContextVariables -> Undefined Last File. -> reportKey = " + reportKey);
|
||||
@@ -174,10 +171,7 @@
|
||||
|
||||
/* Finally we get our own Status Report. */
|
||||
|
||||
reportKey = bot.devTeam + "-" + bot.codeName + "-" + "Multi-Period" + "-" + "dataSet.V1";
|
||||
if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] start -> getContextVariables -> reportKey = " + reportKey); }
|
||||
|
||||
statusReport = statusDependencies.statusReports.get(reportKey);
|
||||
statusReport = statusDependencies.reportsByMainUtility.get("Self Reference")
|
||||
|
||||
if (statusReport === undefined) { // This means the status report does not exist, that could happen for instance at the begining of a month.
|
||||
logger.write(MODULE_NAME, "[WARN] start -> getContextVariables -> Status Report does not exist. Retrying Later. ");
|
||||
@@ -191,7 +185,7 @@
|
||||
return;
|
||||
}
|
||||
|
||||
thisReport = statusDependencies.statusReports.get(reportKey).file;
|
||||
thisReport = statusReport.file;
|
||||
|
||||
if (thisReport.lastFile !== undefined) {
|
||||
|
||||
@@ -290,12 +284,12 @@
|
||||
if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] start -> processTimePeriodsMarketFiles -> periodsLoopBody -> Entering function."); }
|
||||
|
||||
const timePeriod = global.marketFilesPeriods[n][0];
|
||||
const outputPeriodLabel = global.marketFilesPeriods[n][1];
|
||||
const timePeriodLabel = global.marketFilesPeriods[n][1];
|
||||
|
||||
let dependencyIndex = 0;
|
||||
dataFiles = [];
|
||||
dataFiles = new Map();
|
||||
|
||||
if (bot.VALUES_TO_USE.timePeriod === outputPeriodLabel) {
|
||||
if (bot.VALUES_TO_USE.timePeriod === timePeriodLabel) {
|
||||
currentTimePeriod = global.marketFilesPeriods[n][0];
|
||||
currentOutputPeriodName = global.marketFilesPeriods[n][1];
|
||||
}
|
||||
@@ -307,8 +301,8 @@
|
||||
|
||||
if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] start -> processTimePeriodsMarketFiles -> periodsLoopBody -> dependencyLoopBody -> Entering function."); }
|
||||
|
||||
let dependency = dataDependencies.config[dependencyIndex];
|
||||
let storage = storages[dependencyIndex];
|
||||
let dependency = dataDependencies.nodeArray[dependencyIndex];
|
||||
let dataset = datasets[dependencyIndex];
|
||||
|
||||
getFile();
|
||||
|
||||
@@ -326,9 +320,9 @@
|
||||
return
|
||||
}
|
||||
|
||||
let filePath = dependency.product + '/' + dependency.dataSet + "/" + outputPeriodLabel;
|
||||
let filePath = dependency.product + '/' + dependency.dataSet + "/" + timePeriodLabel;
|
||||
|
||||
storage.getTextFile(filePath, fileName, onFileReceived);
|
||||
dataset.getTextFile(filePath, fileName, onFileReceived);
|
||||
|
||||
function onFileReceived(err, text) {
|
||||
|
||||
@@ -345,7 +339,7 @@
|
||||
}
|
||||
|
||||
let dataFile = JSON.parse(text);
|
||||
dataFiles.push(dataFile);
|
||||
dataFiles.set(dependency.id, dataFile);
|
||||
|
||||
dependencyControlLoop();
|
||||
|
||||
@@ -377,7 +371,7 @@
|
||||
|
||||
dependencyIndex++;
|
||||
|
||||
if (dependencyIndex < dataDependencies.config.length) {
|
||||
if (dependencyIndex < dataDependencies.nodeArray.length) {
|
||||
|
||||
dependencyLoopBody();
|
||||
|
||||
@@ -581,28 +575,28 @@
|
||||
if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] start -> processTimePeriodsDailyFiles -> periodsLoopBody -> Entering function."); }
|
||||
|
||||
const timePeriod = global.dailyFilePeriods[n][0];
|
||||
const outputPeriodLabel = global.dailyFilePeriods[n][1];
|
||||
const timePeriodLabel = global.dailyFilePeriods[n][1];
|
||||
|
||||
if (processConfig.framework.validPeriods !== undefined) {
|
||||
let validPeriod = false;
|
||||
for (let i = 0; i < processConfig.framework.validPeriods.length; i++) {
|
||||
let period = processConfig.framework.validPeriods[i];
|
||||
if (period === outputPeriodLabel) { validPeriod = true }
|
||||
if (period === timePeriodLabel) { validPeriod = true }
|
||||
}
|
||||
if (validPeriod === false) {
|
||||
if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] start -> processTimePeriodsDailyFiles -> periodsLoopBody -> Discarding period for not being listed as a valid period. -> outputPeriodLabel = " + outputPeriodLabel); }
|
||||
if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] start -> processTimePeriodsDailyFiles -> periodsLoopBody -> Discarding period for not being listed as a valid period. -> timePeriodLabel = " + timePeriodLabel); }
|
||||
periodsControlLoop();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (bot.VALUES_TO_USE.timePeriod === outputPeriodLabel) {
|
||||
if (bot.VALUES_TO_USE.timePeriod === timePeriodLabel) {
|
||||
currentTimePeriod = global.dailyFilePeriods[n][0];
|
||||
currentOutputPeriodName = global.dailyFilePeriods[n][1];
|
||||
}
|
||||
|
||||
let dependencyIndex = 0;
|
||||
dataFiles = [];
|
||||
dataFiles = new Map();
|
||||
dependencyLoopBody();
|
||||
|
||||
function dependencyLoopBody() {
|
||||
@@ -611,8 +605,8 @@
|
||||
|
||||
if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] start -> processTimePeriodsDailyFiles -> periodsLoopBody -> dependencyLoopBody -> Entering function."); }
|
||||
|
||||
let dependency = dataDependencies.config[dependencyIndex];
|
||||
let storage = storages[dependencyIndex];
|
||||
let dependency = dataDependencies.nodeArray[dependencyIndex];
|
||||
let dataset = datasets[dependencyIndex];
|
||||
|
||||
let previousFile;
|
||||
let currentFile;
|
||||
@@ -640,13 +634,13 @@
|
||||
let filePath
|
||||
|
||||
if (dependency.dataSet === "Multi-Period-Daily") {
|
||||
filePath = dependency.product + '/' + dependency.dataSet + "/" + outputPeriodLabel + "/" + dateForPath;
|
||||
filePath = dependency.product + '/' + dependency.dataSet + "/" + timePeriodLabel + "/" + dateForPath;
|
||||
} else {
|
||||
filePath = dependency.product + '/' + dependency.dataSet + "/" + dateForPath;
|
||||
}
|
||||
let fileName = market.assetA + '_' + market.assetB + ".json";
|
||||
|
||||
storage.getTextFile(filePath, fileName, onFileReceived);
|
||||
dataset.getTextFile(filePath, fileName, onFileReceived);
|
||||
|
||||
function onFileReceived(err, text) {
|
||||
|
||||
@@ -716,13 +710,13 @@
|
||||
let dateForPath = bot.multiPeriodProcessDatetime.getUTCFullYear() + '/' + utilities.pad(bot.multiPeriodProcessDatetime.getUTCMonth() + 1, 2) + '/' + utilities.pad(bot.multiPeriodProcessDatetime.getUTCDate(), 2);
|
||||
let filePath
|
||||
if (dependency.dataSet === "Multi-Period-Daily") {
|
||||
filePath = dependency.product + '/' + dependency.dataSet + "/" + outputPeriodLabel + "/" + dateForPath;
|
||||
filePath = dependency.product + '/' + dependency.dataSet + "/" + timePeriodLabel + "/" + dateForPath;
|
||||
} else {
|
||||
filePath = dependency.product + '/' + dependency.dataSet + "/" + dateForPath;
|
||||
}
|
||||
let fileName = market.assetA + '_' + market.assetB + ".json";
|
||||
|
||||
storage.getTextFile(filePath, fileName, onFileReceived);
|
||||
dataset.getTextFile(filePath, fileName, onFileReceived);
|
||||
|
||||
function onFileReceived(err, text) {
|
||||
|
||||
@@ -754,7 +748,7 @@
|
||||
|
||||
let dataFile = previousFile.concat(currentFile);
|
||||
|
||||
dataFiles.push(dataFile);
|
||||
dataFiles.set(dependency.id, dataFile);
|
||||
|
||||
dependencyControlLoop();
|
||||
|
||||
@@ -785,7 +779,7 @@
|
||||
|
||||
dependencyIndex++;
|
||||
|
||||
if (dependencyIndex < dataDependencies.config.length) {
|
||||
if (dependencyIndex < dataDependencies.nodeArray.length) {
|
||||
|
||||
dependencyLoopBody();
|
||||
|
||||
@@ -847,7 +841,7 @@
|
||||
|
||||
if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] start -> processTimePeriodsDailyFiles -> callTheBot -> Entering function."); }
|
||||
|
||||
usertBot.start(
|
||||
botInstance.start(
|
||||
multiPeriodDataFiles,
|
||||
currentTimePeriod,
|
||||
currentOutputPeriodName,
|
||||
@@ -959,21 +953,19 @@
|
||||
|
||||
if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] start -> writeDataRanges -> Entering function."); }
|
||||
|
||||
let productIndex = 0;
|
||||
productLoopBody();
|
||||
let outputDatasetIndex = -1;
|
||||
controlLoop();
|
||||
|
||||
function productLoopBody() {
|
||||
|
||||
let product = bot.products[productIndex];
|
||||
|
||||
writeDataRange(contextVariables.dateBeginOfMarket, bot.multiPeriodProcessDatetime, product, currentOutputPeriodName, controlLoop);
|
||||
let productCodeName = bot.processNode.referenceParent.processOutput.outputDatasets[outputDatasetIndex].referenceParent.parentNode.code.codeName;
|
||||
writeDataRange(contextVariables.dateBeginOfMarket, bot.multiPeriodProcessDatetime, productCodeName, currentOutputPeriodName, controlLoop);
|
||||
}
|
||||
|
||||
function controlLoop() {
|
||||
|
||||
productIndex++;
|
||||
outputDatasetIndex++;
|
||||
|
||||
if (productIndex < bot.products.length) {
|
||||
if (outputDatasetIndex < bot.processNode.referenceParent.processOutput.outputDatasets.length) {
|
||||
productLoopBody();
|
||||
} else {
|
||||
callBack(global.DEFAULT_OK_RESPONSE);
|
||||
@@ -987,7 +979,7 @@
|
||||
|
||||
}
|
||||
|
||||
function writeDataRange(pBegin, pEnd, product, currentOutputPeriodName, callBack) {
|
||||
function writeDataRange(pBegin, pEnd, productCodeName, currentOutputPeriodName, callBack) {
|
||||
|
||||
try {
|
||||
|
||||
@@ -1001,7 +993,7 @@
|
||||
let fileContent = JSON.stringify(dataRange);
|
||||
|
||||
let fileName = '/Data.Range.' + market.assetA + '_' + market.assetB + '.json';
|
||||
let filePath = bot.filePathRoot + "/Output/" + bot.SESSION.folderName + "/" + product.codeName + "/" + 'Multi-Period-Daily' + fileName;
|
||||
let filePath = bot.filePathRoot + "/Output/" + bot.SESSION.folderName + "/" + productCodeName + "/" + 'Multi-Period-Daily' + fileName;
|
||||
|
||||
fileStorage.createTextFile(bot.devTeam, filePath, fileContent + '\n', onFileCreated);
|
||||
|
||||
@@ -1019,7 +1011,7 @@
|
||||
logger.write(MODULE_NAME, "[INFO] start -> writeDataRange -> onFileCreated -> Content written = " + fileContent);
|
||||
}
|
||||
|
||||
let key = bot.devTeam + "-" + bot.codeName + "-" + product.codeName + "-" + currentOutputPeriodName
|
||||
let key = bot.devTeam + "-" + bot.codeName + "-" + productCodeName + "-" + currentOutputPeriodName
|
||||
let event = {
|
||||
dateRange: dataRange
|
||||
}
|
||||
|
||||
+46
-62
@@ -1,4 +1,4 @@
|
||||
exports.newMultiPeriodDaily = function newMultiPeriodDaily(bot, logger, COMMONS, UTILITIES, USER_BOT_MODULE, COMMONS_MODULE) {
|
||||
exports.newMultiPeriodDaily = function newMultiPeriodDaily(bot, logger, UTILITIES, FILE_STORAGE) {
|
||||
|
||||
const FULL_LOG = true;
|
||||
const LOG_FILE_CONTENT = false;
|
||||
@@ -16,12 +16,11 @@
|
||||
|
||||
let statusDependencies;
|
||||
let dataDependencies;
|
||||
let storages = [];
|
||||
let dataFiles = [];
|
||||
let datasets = [];
|
||||
let dataFiles = new Map;
|
||||
|
||||
let usertBot;
|
||||
let botInstance;
|
||||
|
||||
const FILE_STORAGE = require('./FileStorage.js');
|
||||
let fileStorage = FILE_STORAGE.newFileStorage(logger);
|
||||
|
||||
let bootstrappingTheProcess = false
|
||||
@@ -30,7 +29,7 @@
|
||||
|
||||
return thisObject;
|
||||
|
||||
function initialize(pProcessConfig, pStatusDependencies, pDataDependencies, pAssistant, callBackFunction) {
|
||||
function initialize(pProcessConfig, pStatusDependencies, pDataDependencies, callBackFunction) {
|
||||
|
||||
try {
|
||||
|
||||
@@ -43,11 +42,11 @@
|
||||
dataDependencies = pDataDependencies;
|
||||
processConfig = pProcessConfig;
|
||||
|
||||
for (let i = 0; i < dataDependencies.config.length; i++) {
|
||||
for (let i = 0; i < dataDependencies.nodeArray.length; i++) {
|
||||
|
||||
let key;
|
||||
let storage;
|
||||
let dependency = dataDependencies.config[i];
|
||||
let dataset;
|
||||
let dependency = dataDependencies.nodeArray[i];
|
||||
|
||||
key = dependency.devTeam + "-" +
|
||||
dependency.bot + "-" +
|
||||
@@ -55,14 +54,16 @@
|
||||
dependency.dataSet + "-" +
|
||||
dependency.dataSetVersion
|
||||
|
||||
storage = dataDependencies.dataSets.get(key);
|
||||
dataset = dataDependencies.dataSets.get(key);
|
||||
|
||||
storages.push(storage);
|
||||
datasets.push(dataset);
|
||||
|
||||
}
|
||||
|
||||
usertBot = USER_BOT_MODULE.newUserBot(bot, logger, COMMONS_MODULE, UTILITIES, fileStorage);
|
||||
usertBot.initialize(dataDependencies, callBackFunction, pAssistant);
|
||||
let USER_BOT_MODULE = require("./IndicatorBot")
|
||||
|
||||
botInstance = USER_BOT_MODULE.newIndicatorBot(bot, logger, UTILITIES, FILE_STORAGE);
|
||||
botInstance.initialize(callBackFunction);
|
||||
|
||||
} catch (err) {
|
||||
logger.write(MODULE_NAME, "[ERROR] initialize -> err = "+ err.stack);
|
||||
@@ -71,11 +72,11 @@
|
||||
}
|
||||
|
||||
function finalize() {
|
||||
storages = undefined
|
||||
datasets = undefined
|
||||
dataFiles = undefined
|
||||
statusDependencies = undefined
|
||||
dataDependencies = undefined
|
||||
usertBot = undefined
|
||||
botInstance = undefined
|
||||
fileStorage = undefined
|
||||
processConfig = undefined
|
||||
thisObject = undefined
|
||||
@@ -126,12 +127,7 @@
|
||||
We look first for the bot who knows the begining of the marke in order to get when the market starts.
|
||||
*/
|
||||
|
||||
let botWhoKnowsTheBeginingOfTheMarket = statusDependencies.config[processConfig.framework.startDate.takeItFromStatusDependency];
|
||||
|
||||
reportKey = botWhoKnowsTheBeginingOfTheMarket.devTeam + "-" + botWhoKnowsTheBeginingOfTheMarket.bot + "-" + botWhoKnowsTheBeginingOfTheMarket.process + "-" + "dataSet.V1";
|
||||
if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] start -> getContextVariables -> reportKey = " + reportKey); }
|
||||
|
||||
statusReport = statusDependencies.statusReports.get(reportKey);
|
||||
statusReport = statusDependencies.reportsByMainUtility.get("Market Starting Point")
|
||||
|
||||
if (statusReport === undefined) { // This means the status report does not exist, that could happen for instance at the begining of a month.
|
||||
logger.write(MODULE_NAME, "[WARN] start -> getContextVariables -> Status Report does not exist. Retrying Later. ");
|
||||
@@ -145,7 +141,7 @@
|
||||
return;
|
||||
}
|
||||
|
||||
thisReport = statusDependencies.statusReports.get(reportKey).file;
|
||||
thisReport = statusReport.file;
|
||||
|
||||
if (thisReport.lastFile === undefined) {
|
||||
logger.write(MODULE_NAME, "[WARN] start -> getContextVariables -> Undefined Last File. -> reportKey = " + reportKey);
|
||||
@@ -168,7 +164,7 @@
|
||||
|
||||
/* The ending date is fixed, we will end there. */
|
||||
if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] start -> getContextVariables -> We have got a user defined endDate. -> endDate = " + processConfig.framework.endDate.fixedDate); }
|
||||
contextVariables.dateEndOfMarket = new Date(processConfig.framework.endDate.fixedDate);
|
||||
contextVariables.dateEndOfMarket = new Date(processConfig.framework.endDate.fixedDate);
|
||||
|
||||
} else {
|
||||
|
||||
@@ -176,12 +172,7 @@
|
||||
Here we get the status report from the bot who knows which is the end of the market.
|
||||
*/
|
||||
|
||||
let botWhoKnowsTheEndOfTheMarket = statusDependencies.config[processConfig.framework.endDate.takeItFromStatusDependency];
|
||||
|
||||
reportKey = botWhoKnowsTheEndOfTheMarket.devTeam + "-" + botWhoKnowsTheEndOfTheMarket.bot + "-" + botWhoKnowsTheEndOfTheMarket.process + "-" + "dataSet.V1";
|
||||
if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] start -> getContextVariables -> reportKey = " + reportKey); }
|
||||
|
||||
statusReport = statusDependencies.statusReports.get(reportKey);
|
||||
statusReport = statusDependencies.reportsByMainUtility.get("Market Ending Point")
|
||||
|
||||
if (statusReport === undefined) { // This means the status report does not exist, that could happen for instance at the begining of a month.
|
||||
logger.write(MODULE_NAME, "[WARN] start -> getContextVariables -> Status Report does not exist. Retrying Later. ");
|
||||
@@ -195,7 +186,7 @@
|
||||
return;
|
||||
}
|
||||
|
||||
thisReport = statusDependencies.statusReports.get(reportKey).file;
|
||||
thisReport = statusReport.file;
|
||||
|
||||
if (thisReport.lastFile === undefined) {
|
||||
logger.write(MODULE_NAME, "[WARN] start -> getContextVariables -> Undefined Last File. -> reportKey = " + reportKey);
|
||||
@@ -214,10 +205,7 @@
|
||||
|
||||
/* Finally we get our own Status Report. */
|
||||
|
||||
reportKey = bot.devTeam + "-" + bot.codeName + "-" + "Multi-Period-Daily" + "-" + "dataSet.V1";
|
||||
if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] start -> getContextVariables -> reportKey = " + reportKey); }
|
||||
|
||||
statusReport = statusDependencies.statusReports.get(reportKey);
|
||||
statusReport = statusDependencies.reportsByMainUtility.get("Self Reference")
|
||||
|
||||
if (statusReport === undefined) { // This means the status report does not exist, that could happen for instance at the begining of a month.
|
||||
logger.write(MODULE_NAME, "[WARN] start -> getContextVariables -> Status Report does not exist. Retrying Later. ");
|
||||
@@ -231,7 +219,7 @@
|
||||
return;
|
||||
}
|
||||
|
||||
thisReport = statusDependencies.statusReports.get(reportKey).file;
|
||||
thisReport = statusReport.file;
|
||||
|
||||
if (thisReport.lastFile !== undefined) {
|
||||
|
||||
@@ -382,23 +370,23 @@
|
||||
if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] start -> processTimePeriods -> periodsLoopBody -> Entering function."); }
|
||||
|
||||
const timePeriod = global.dailyFilePeriods[n][0];
|
||||
const outputPeriodLabel = global.dailyFilePeriods[n][1];
|
||||
const timePeriodLabel = global.dailyFilePeriods[n][1];
|
||||
|
||||
if (processConfig.framework.validPeriods !== undefined) {
|
||||
let validPeriod = false;
|
||||
for (let i = 0; i < processConfig.framework.validPeriods.length; i++) {
|
||||
let period = processConfig.framework.validPeriods[i];
|
||||
if (period === outputPeriodLabel) { validPeriod = true }
|
||||
if (period === timePeriodLabel) { validPeriod = true }
|
||||
}
|
||||
if (validPeriod === false) {
|
||||
if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] start -> processTimePeriods -> periodsLoopBody -> Discarding period for not being listed as a valid period. -> outputPeriodLabel = " + outputPeriodLabel); }
|
||||
if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] start -> processTimePeriods -> periodsLoopBody -> Discarding period for not being listed as a valid period. -> timePeriodLabel = " + timePeriodLabel); }
|
||||
periodsControlLoop();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
let dependencyIndex = 0;
|
||||
dataFiles = [];
|
||||
dataFiles = new Map();
|
||||
|
||||
dependencyLoopBody();
|
||||
|
||||
@@ -408,8 +396,8 @@
|
||||
|
||||
if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] start -> processTimePeriods -> periodsLoopBody -> dependencyLoopBody -> Entering function."); }
|
||||
|
||||
let dependency = dataDependencies.config[dependencyIndex];
|
||||
let storage = storages[dependencyIndex];
|
||||
let dependency = dataDependencies.nodeArray[dependencyIndex];
|
||||
let dataset = datasets[dependencyIndex];
|
||||
|
||||
let previousFile;
|
||||
let currentFile;
|
||||
@@ -430,13 +418,13 @@
|
||||
let dateForPath = previousDay.getUTCFullYear() + '/' + utilities.pad(previousDay.getUTCMonth() + 1, 2) + '/' + utilities.pad(previousDay.getUTCDate(), 2);
|
||||
let filePath
|
||||
if (dependency.dataSet === "Multi-Period-Daily") {
|
||||
filePath = dependency.product + '/' + dependency.dataSet + "/" + outputPeriodLabel + "/" + dateForPath;
|
||||
filePath = dependency.product + '/' + dependency.dataSet + "/" + timePeriodLabel + "/" + dateForPath;
|
||||
} else {
|
||||
filePath = dependency.product + '/' + dependency.dataSet + "/" + dateForPath;
|
||||
}
|
||||
let fileName = market.assetA + '_' + market.assetB + ".json";
|
||||
|
||||
storage.getTextFile(filePath, fileName, onFileReceived);
|
||||
dataset.getTextFile(filePath, fileName, onFileReceived);
|
||||
|
||||
function onFileReceived(err, text) {
|
||||
|
||||
@@ -500,13 +488,13 @@
|
||||
let dateForPath = bot.multiPeriodDailyProcessDatetime.getUTCFullYear() + '/' + utilities.pad(bot.multiPeriodDailyProcessDatetime.getUTCMonth() + 1, 2) + '/' + utilities.pad(bot.multiPeriodDailyProcessDatetime.getUTCDate(), 2);
|
||||
let filePath
|
||||
if (dependency.dataSet === "Multi-Period-Daily") {
|
||||
filePath = dependency.product + '/' + dependency.dataSet + "/" + outputPeriodLabel + "/" + dateForPath;
|
||||
filePath = dependency.product + '/' + dependency.dataSet + "/" + timePeriodLabel + "/" + dateForPath;
|
||||
} else {
|
||||
filePath = dependency.product + '/' + dependency.dataSet + "/" + dateForPath;
|
||||
}
|
||||
let fileName = market.assetA + '_' + market.assetB + ".json";
|
||||
|
||||
storage.getTextFile(filePath, fileName, onFileReceived);
|
||||
dataset.getTextFile(filePath, fileName, onFileReceived);
|
||||
|
||||
function onFileReceived(err, text) {
|
||||
|
||||
@@ -545,7 +533,7 @@
|
||||
|
||||
let dataFile = previousFile.concat(currentFile);
|
||||
|
||||
dataFiles.push(dataFile);
|
||||
dataFiles.set(dependency.id, dataFile);
|
||||
dependencyControlLoop();
|
||||
|
||||
}
|
||||
@@ -575,7 +563,7 @@
|
||||
|
||||
dependencyIndex++;
|
||||
|
||||
if (dependencyIndex < dataDependencies.config.length) {
|
||||
if (dependencyIndex < dataDependencies.nodeArray.length) {
|
||||
|
||||
dependencyLoopBody();
|
||||
|
||||
@@ -598,15 +586,13 @@
|
||||
if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] start -> processTimePeriods -> periodsLoopBody -> callTheBot -> Entering function."); }
|
||||
|
||||
const timePeriod = global.dailyFilePeriods[n][0];
|
||||
const outputPeriodLabel = global.dailyFilePeriods[n][1];
|
||||
const timePeriodLabel = global.dailyFilePeriods[n][1];
|
||||
|
||||
usertBot.start(
|
||||
botInstance.start(
|
||||
dataFiles,
|
||||
timePeriod,
|
||||
outputPeriodLabel,
|
||||
timePeriodLabel,
|
||||
bot.multiPeriodDailyProcessDatetime,
|
||||
contextVariables.dateBeginOfMarket,
|
||||
contextVariables.dateEndOfMarket,
|
||||
interExecutionMemoryArray[n],
|
||||
onBotFinished);
|
||||
|
||||
@@ -701,21 +687,19 @@
|
||||
|
||||
if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] start -> writeDataRanges -> Entering function."); }
|
||||
|
||||
let productIndex = 0;
|
||||
productLoopBody();
|
||||
let outputDatasetIndex = -1;
|
||||
controlLoop();
|
||||
|
||||
function productLoopBody() {
|
||||
|
||||
let folderName = bot.products[productIndex].codeName;
|
||||
|
||||
writeDataRange(contextVariables.dateBeginOfMarket, bot.multiPeriodDailyProcessDatetime, folderName, controlLoop);
|
||||
let productCodeName = bot.processNode.referenceParent.processOutput.outputDatasets[outputDatasetIndex].referenceParent.parentNode.code.codeName;
|
||||
writeDataRange(contextVariables.dateBeginOfMarket, bot.multiPeriodDailyProcessDatetime, productCodeName, controlLoop);
|
||||
}
|
||||
|
||||
function controlLoop() {
|
||||
|
||||
productIndex++;
|
||||
outputDatasetIndex++;
|
||||
|
||||
if (productIndex < bot.products.length) {
|
||||
if (outputDatasetIndex < bot.processNode.referenceParent.processOutput.outputDatasets.length) {
|
||||
productLoopBody();
|
||||
} else {
|
||||
callBack(global.DEFAULT_OK_RESPONSE);
|
||||
@@ -729,7 +713,7 @@
|
||||
|
||||
}
|
||||
|
||||
function writeDataRange(pBegin, pEnd, pProductFolder, callBack) {
|
||||
function writeDataRange(pBegin, pEnd, productCodeName, callBack) {
|
||||
|
||||
try {
|
||||
|
||||
@@ -743,7 +727,7 @@
|
||||
let fileContent = JSON.stringify(dataRange);
|
||||
|
||||
let fileName = '/Data.Range.' + market.assetA + '_' + market.assetB + '.json';
|
||||
let filePath = bot.filePathRoot + "/Output/" + pProductFolder + "/" + bot.process + fileName;
|
||||
let filePath = bot.filePathRoot + "/Output/" + productCodeName + "/" + bot.process + fileName;
|
||||
|
||||
fileStorage.createTextFile(bot.devTeam, filePath, fileContent + '\n', onFileCreated);
|
||||
|
||||
|
||||
+29
-31
@@ -1,4 +1,4 @@
|
||||
exports.newMultiPeriodMarket = function newMultiPeriodMarket(bot, logger, COMMONS, UTILITIES, USER_BOT_MODULE, COMMONS_MODULE) {
|
||||
exports.newMultiPeriodMarket = function newMultiPeriodMarket(bot, logger, UTILITIES, FILE_STORAGE) {
|
||||
|
||||
const FULL_LOG = true;
|
||||
const LOG_FILE_CONTENT = false;
|
||||
@@ -14,19 +14,16 @@
|
||||
|
||||
let statusDependencies;
|
||||
let dataDependencies;
|
||||
let storages = [];
|
||||
let dataFiles = [];
|
||||
let datasets = [];
|
||||
let dataFiles = new Map();
|
||||
|
||||
let usertBot;
|
||||
|
||||
const FILE_STORAGE = require('./FileStorage.js');
|
||||
let fileStorage = FILE_STORAGE.newFileStorage(logger);
|
||||
let botInstance;
|
||||
|
||||
let processConfig;
|
||||
|
||||
return thisObject;
|
||||
|
||||
function initialize(pProcessConfig, pStatusDependencies, pDataDependencies, pAssistant, callBackFunction) {
|
||||
function initialize(pProcessConfig, pStatusDependencies, pDataDependencies, callBackFunction) {
|
||||
|
||||
try {
|
||||
|
||||
@@ -39,11 +36,11 @@
|
||||
dataDependencies = pDataDependencies;
|
||||
processConfig = pProcessConfig;
|
||||
|
||||
for (let i = 0; i < dataDependencies.config.length; i++) {
|
||||
for (let i = 0; i < dataDependencies.nodeArray.length; i++) {
|
||||
|
||||
let key;
|
||||
let storage;
|
||||
let dependency = dataDependencies.config[i];
|
||||
let dataset;
|
||||
let dependency = dataDependencies.nodeArray[i];
|
||||
|
||||
key = dependency.devTeam + "-" +
|
||||
dependency.bot + "-" +
|
||||
@@ -51,14 +48,16 @@
|
||||
dependency.dataSet + "-" +
|
||||
dependency.dataSetVersion
|
||||
|
||||
storage = dataDependencies.dataSets.get(key);
|
||||
dataset = dataDependencies.dataSets.get(key);
|
||||
|
||||
storages.push(storage);
|
||||
datasets.push(dataset);
|
||||
|
||||
}
|
||||
|
||||
usertBot = USER_BOT_MODULE.newUserBot(bot, logger, COMMONS_MODULE, UTILITIES, fileStorage);
|
||||
usertBot.initialize(dataDependencies, callBackFunction, pAssistant);
|
||||
let USER_BOT_MODULE = require("./IndicatorBot")
|
||||
|
||||
botInstance = USER_BOT_MODULE.newIndicatorBot(bot, logger, UTILITIES, FILE_STORAGE);
|
||||
botInstance.initialize(callBackFunction);
|
||||
|
||||
} catch (err) {
|
||||
logger.write(MODULE_NAME, "[ERROR] initialize -> err = "+ err.stack);
|
||||
@@ -67,12 +66,11 @@
|
||||
}
|
||||
|
||||
function finalize() {
|
||||
storages = undefined
|
||||
datasets = undefined
|
||||
dataFiles = undefined
|
||||
statusDependencies = undefined
|
||||
dataDependencies = undefined
|
||||
usertBot = undefined
|
||||
fileStorage = undefined
|
||||
botInstance = undefined
|
||||
processConfig = undefined
|
||||
thisObject = undefined
|
||||
}
|
||||
@@ -150,10 +148,10 @@
|
||||
if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] start -> processTimePeriods -> periodsLoopBody -> Entering function."); }
|
||||
|
||||
const timePeriod = global.marketFilesPeriods[n][0];
|
||||
const outputPeriodLabel = global.marketFilesPeriods[n][1];
|
||||
const timePeriodLabel = global.marketFilesPeriods[n][1];
|
||||
|
||||
let dependencyIndex = 0;
|
||||
dataFiles = [];
|
||||
dataFiles = new Map;
|
||||
|
||||
dependencyLoopBody();
|
||||
|
||||
@@ -163,8 +161,8 @@
|
||||
|
||||
if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] start -> processTimePeriods -> periodsLoopBody -> dependencyLoopBody -> Entering function."); }
|
||||
|
||||
let dependency = dataDependencies.config[dependencyIndex];
|
||||
let storage = storages[dependencyIndex];
|
||||
let dependency = dataDependencies.nodeArray[dependencyIndex];
|
||||
let dataset = datasets[dependencyIndex];
|
||||
|
||||
getFile();
|
||||
|
||||
@@ -179,11 +177,11 @@
|
||||
|
||||
let filePath
|
||||
if (dependency.dataSet === "Multi-Period-Market") {
|
||||
filePath = dependency.product + '/' + dependency.dataSet + "/" + outputPeriodLabel;
|
||||
filePath = dependency.product + '/' + dependency.dataSet + "/" + timePeriodLabel;
|
||||
} else {
|
||||
filePath = dependency.product + '/' + dependency.dataSet + "/" + dateForPath;
|
||||
}
|
||||
storage.getTextFile(filePath, fileName, onFileReceived);
|
||||
dataset.getTextFile(filePath, fileName, onFileReceived);
|
||||
|
||||
function onFileReceived(err, text) {
|
||||
|
||||
@@ -200,7 +198,7 @@
|
||||
}
|
||||
|
||||
let dataFile = JSON.parse(text);
|
||||
dataFiles.push(dataFile);
|
||||
dataFiles.set(dependency.id, dataFile);
|
||||
|
||||
dependencyControlLoop();
|
||||
|
||||
@@ -232,7 +230,7 @@
|
||||
|
||||
dependencyIndex++;
|
||||
|
||||
if (dependencyIndex < dataDependencies.config.length) {
|
||||
if (dependencyIndex < dataDependencies.nodeArray.length) {
|
||||
|
||||
dependencyLoopBody();
|
||||
|
||||
@@ -255,14 +253,14 @@
|
||||
if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] start -> processTimePeriods -> periodsLoopBody -> callTheBot -> Entering function."); }
|
||||
|
||||
const timePeriod = global.marketFilesPeriods[n][0];
|
||||
const outputPeriodLabel = global.marketFilesPeriods[n][1];
|
||||
const timePeriodLabel = global.marketFilesPeriods[n][1];
|
||||
|
||||
usertBot.start(
|
||||
botInstance.start(
|
||||
dataFiles,
|
||||
timePeriod,
|
||||
outputPeriodLabel,
|
||||
contextVariables.dateBeginOfMarket,
|
||||
contextVariables.dateEndOfMarket,
|
||||
timePeriodLabel,
|
||||
undefined,
|
||||
undefined,
|
||||
onBotFinished);
|
||||
|
||||
function onBotFinished(err) {
|
||||
|
||||
@@ -0,0 +1,170 @@
|
||||
exports.newProcessExecutionEvents = function newProcessExecutionEvents(BOT, logger) {
|
||||
|
||||
/*
|
||||
|
||||
Here we manage the process execution events. This allow us to emit events when the process starts and finishes. Also to wait for a dependent event
|
||||
of another process.
|
||||
|
||||
*/
|
||||
|
||||
const MODULE_NAME = "Process Execution Events";
|
||||
|
||||
let bot = BOT;
|
||||
|
||||
let thisObject = {
|
||||
initialize, initialize,
|
||||
start: start,
|
||||
finish: finish
|
||||
};
|
||||
|
||||
let processThisDependsOn; // This is the process this process needs to wait for it to finishes in order to start.
|
||||
|
||||
let month;
|
||||
let year;
|
||||
let currentProcessKey
|
||||
let datetimeForLogs = ''
|
||||
|
||||
return thisObject;
|
||||
|
||||
function initialize(pMonth, pYear, callBackFunction) {
|
||||
|
||||
try {
|
||||
if (global.LOG_CONTROL[MODULE_NAME].logInfo === true) { logger.write(MODULE_NAME, "[INFO] initialize -> Entering function."); }
|
||||
|
||||
month = pMonth;
|
||||
year = pYear;
|
||||
|
||||
if (month && year) {
|
||||
datetimeForLogs = "Month: " + month + " Year: " + year
|
||||
}
|
||||
|
||||
let name = 'Not Depends on any Process'
|
||||
|
||||
if (bot.processNode.referenceParent !== undefined) {
|
||||
|
||||
currentProcessKey = bot.processNode.referenceParent.name + "-" + bot.processNode.referenceParent.type + "-" + bot.processNode.referenceParent.id
|
||||
|
||||
if (bot.processNode.referenceParent.executionStartedEvent !== undefined) {
|
||||
if (bot.processNode.referenceParent.executionStartedEvent.referenceParent !== undefined) {
|
||||
if (bot.processNode.referenceParent.executionStartedEvent.referenceParent.parentNode !== undefined) {
|
||||
processThisDependsOn = bot.processNode.referenceParent.executionStartedEvent.referenceParent.parentNode
|
||||
|
||||
name = processThisDependsOn.name
|
||||
if (processThisDependsOn.code.monthlyInstances === true) {
|
||||
logger.fileName = MODULE_NAME + "." + name + "." + year + "." + month;
|
||||
}
|
||||
if (global.LOG_CONTROL[MODULE_NAME].logInfo === true) { logger.write(MODULE_NAME, "[INFO] initialize -> " + currentProcessKey + datetimeForLogs + " depends on " + name); }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
logger.fileName = MODULE_NAME + "." + name;
|
||||
callBackFunction(global.DEFAULT_OK_RESPONSE);
|
||||
|
||||
} catch (err) {
|
||||
logger.write(MODULE_NAME, "[ERROR] initialize -> err = " + err.stack);
|
||||
callBackFunction(global.DEFAULT_FAIL_RESPONSE);
|
||||
}
|
||||
}
|
||||
|
||||
function start(callBackFunction) {
|
||||
|
||||
try {
|
||||
|
||||
if (processThisDependsOn !== undefined) {
|
||||
|
||||
if (global.LOG_CONTROL[MODULE_NAME].logInfo === true) { logger.write(MODULE_NAME, "[INFO] start -> waitForDependantProcess -> Entering Code Block."); }
|
||||
|
||||
/* This forces this process to wait until the process that this one depends on, emits its event signaling that the process execution has finished. */
|
||||
|
||||
let extraCallerId = '-' + Math.trunc(Math.random() * 10000) + '-'
|
||||
if (month) { extraCallerId = extraCallerId + '-' + month }
|
||||
if (year) { extraCallerId = extraCallerId + '-' + year }
|
||||
|
||||
let key = processThisDependsOn.name + "-" + processThisDependsOn.type + "-" + processThisDependsOn.id
|
||||
let callerId = bot.devTeam + "-" + bot.codeName + "-" + bot.process + extraCallerId
|
||||
|
||||
let subscriptionId
|
||||
|
||||
if (global.LOG_CONTROL[MODULE_NAME].logInfo === true) { logger.write(MODULE_NAME, "[INFO] start -> waitForDependantProcess -> started listening to Process Execution Finished. "); }
|
||||
if (global.LOG_CONTROL[MODULE_NAME].logInfo === true) { logger.write(MODULE_NAME, "[INFO] start -> waitForDependantProcess -> key = " + key); }
|
||||
if (global.LOG_CONTROL[MODULE_NAME].logInfo === true) { logger.write(MODULE_NAME, "[INFO] start -> waitForDependantProcess -> callerId = " + callerId); }
|
||||
|
||||
global.SYSTEM_EVENT_HANDLER.listenToEvent(key, 'Process Execution Finished', undefined, callerId, responseCallBack, eventsCallBack)
|
||||
|
||||
function responseCallBack(message) {
|
||||
if (message.result !== global.DEFAULT_OK_RESPONSE.result) {
|
||||
logger.write(MODULE_NAME, "[ERROR] start -> responseCallBack -> message = " + JSON.stringify(message))
|
||||
callBackFunction(global.DEFAULT_FAIL_RESPONSE);
|
||||
} else {
|
||||
subscriptionId = message.eventSubscriptionId
|
||||
if (global.LOG_CONTROL[MODULE_NAME].logInfo === true) { logger.write(MODULE_NAME, "[INFO] start -> waitForDependantProcess -> subscriptionId = " + subscriptionId); }
|
||||
}
|
||||
}
|
||||
|
||||
function eventsCallBack(message) {
|
||||
if (global.LOG_CONTROL[MODULE_NAME].logInfo === true) { logger.write(MODULE_NAME, "[INFO] start -> eventsCallBack -> Entering function."); }
|
||||
if (global.LOG_CONTROL[MODULE_NAME].logInfo === true) { logger.write(MODULE_NAME, "[INFO] start -> eventsCallBack -> message = " + JSON.stringify(message)); }
|
||||
|
||||
/* We continue the normal flow after we learn the dependent process has finished its execution. */
|
||||
if (global.LOG_CONTROL[MODULE_NAME].logInfo === true) { logger.write(MODULE_NAME, "[INFO] start -> eventsCallBack -> stopListening to Process Execution Finished. "); }
|
||||
if (global.LOG_CONTROL[MODULE_NAME].logInfo === true) { logger.write(MODULE_NAME, "[INFO] start -> eventsCallBack -> subscriptionId = " + subscriptionId); }
|
||||
global.SYSTEM_EVENT_HANDLER.stopListening(key, 'Process Execution Finished', subscriptionId)
|
||||
|
||||
if (message.event.err.result === global.DEFAULT_OK_RESPONSE.result) {
|
||||
/* We emit our own event that the process started. */
|
||||
let event = {
|
||||
err: global.DEFAULT_OK_RESPONSE
|
||||
}
|
||||
global.SYSTEM_EVENT_HANDLER.createEventHandler(currentProcessKey, 'Process Execution Started')
|
||||
global.SYSTEM_EVENT_HANDLER.raiseEvent(currentProcessKey, 'Process Execution Started', event)
|
||||
|
||||
if (global.LOG_CONTROL[MODULE_NAME].logInfo === true) { logger.write(MODULE_NAME, "[INFO] start -> eventsCallBack -> " + currentProcessKey + " Process Execution Started because " + key + datetimeForLogs + " Finished."); }
|
||||
}
|
||||
|
||||
callBackFunction(message.event.err);
|
||||
}
|
||||
} else {
|
||||
/* In this case, the Process does not depends on a process which needs to wait for. */
|
||||
/* We emit our own event that the process started. */
|
||||
let event = {
|
||||
err: global.DEFAULT_OK_RESPONSE
|
||||
}
|
||||
global.SYSTEM_EVENT_HANDLER.createEventHandler(currentProcessKey, 'Process Execution Started')
|
||||
global.SYSTEM_EVENT_HANDLER.raiseEvent(currentProcessKey, 'Process Execution Started', event)
|
||||
|
||||
if (global.LOG_CONTROL[MODULE_NAME].logInfo === true) { logger.write(MODULE_NAME, "[INFO] start -> " + currentProcessKey + " Process Execution Started " + datetimeForLogs); }
|
||||
|
||||
callBackFunction(global.DEFAULT_OK_RESPONSE);
|
||||
}
|
||||
|
||||
} catch (err) {
|
||||
logger.write(MODULE_NAME, "[ERROR] start -> err = " + err.stack);
|
||||
callBackFunction(global.DEFAULT_FAIL_RESPONSE);
|
||||
}
|
||||
}
|
||||
|
||||
function finish(callBackFunction) {
|
||||
|
||||
try {
|
||||
|
||||
if (global.LOG_CONTROL[MODULE_NAME].logInfo === true) { logger.write(MODULE_NAME, "[INFO] finish -> Entering function."); }
|
||||
|
||||
let event = {
|
||||
err: global.DEFAULT_OK_RESPONSE
|
||||
}
|
||||
|
||||
global.SYSTEM_EVENT_HANDLER.createEventHandler(currentProcessKey, 'Process Execution Finished')
|
||||
global.SYSTEM_EVENT_HANDLER.raiseEvent(currentProcessKey, 'Process Execution Finished', event)
|
||||
if (global.LOG_CONTROL[MODULE_NAME].logInfo === true) { logger.write(MODULE_NAME, "[INFO] finish -> " + currentProcessKey + " Process Execution Finished " + datetimeForLogs); }
|
||||
|
||||
callBackFunction(global.DEFAULT_OK_RESPONSE);
|
||||
|
||||
} catch (err) {
|
||||
logger.write(MODULE_NAME, "[ERROR] finish -> err = " + err.stack);
|
||||
callBackFunction(global.DEFAULT_FAIL_RESPONSE);
|
||||
}
|
||||
}
|
||||
|
||||
};
|
||||
@@ -0,0 +1,104 @@
|
||||
exports.newProcessOutput = function newProcessOutput(BOT, logger) {
|
||||
|
||||
/*
|
||||
Here we emit the events that signals that a Dataset was updated.
|
||||
*/
|
||||
|
||||
const MODULE_NAME = "Process Output";
|
||||
|
||||
let bot = BOT;
|
||||
|
||||
let thisObject = {
|
||||
raiseEvents, raiseEvents
|
||||
};
|
||||
|
||||
return thisObject;
|
||||
|
||||
function raiseEvents(statusDependencies, callBackFunction) {
|
||||
|
||||
try {
|
||||
if (global.LOG_CONTROL[MODULE_NAME].logInfo === true) { logger.write(MODULE_NAME, "[INFO] raiseEvents -> Entering function."); }
|
||||
|
||||
/* We will reaise the events for the datasets impacted by the process that just finished. */
|
||||
|
||||
if (bot.processNode.referenceParent.processOutput !== undefined) {
|
||||
if (bot.processNode.referenceParent.processOutput.outputDatasets !== undefined) {
|
||||
let outputDatasets = bot.processNode.referenceParent.processOutput.outputDatasets
|
||||
|
||||
for (let j = 0; j < outputDatasets.length; j++) {
|
||||
let outputDataset = outputDatasets[j]
|
||||
|
||||
/* Some validations to verify that everything is in place. */
|
||||
if (outputDataset.referenceParent !== undefined) {
|
||||
if (outputDataset.referenceParent.code.codeName === undefined) {
|
||||
logger.write(MODULE_NAME, "[ERROR] raiseEvents -> codeName at Dataset Definition not defined. Dataset Definition = " + JSON.stringify(outputDataset.referenceParent));
|
||||
callBackFunction(global.DEFAULT_FAIL_RESPONSE);
|
||||
return
|
||||
}
|
||||
if (outputDataset.referenceParent.parentNode !== undefined) {
|
||||
if (outputDataset.referenceParent.parentNode.code.codeName === undefined) {
|
||||
logger.write(MODULE_NAME, "[ERROR] raiseEvents -> codeName at Product not defined. Product = " + JSON.stringify(outputDataset.referenceParent.parentNode));
|
||||
callBackFunction(global.DEFAULT_FAIL_RESPONSE);
|
||||
return
|
||||
}
|
||||
if (outputDataset.referenceParent.parentNode.parentNode !== undefined) {
|
||||
if (outputDataset.referenceParent.parentNode.parentNode.code.codeName === undefined) {
|
||||
logger.write(MODULE_NAME, "[ERROR] raiseEvents -> codeName at Bot not defined. Bot = " + JSON.stringify(outputDataset.referenceParent.parentNode.parentNode));
|
||||
callBackFunction(global.DEFAULT_FAIL_RESPONSE);
|
||||
return
|
||||
}
|
||||
if (outputDataset.referenceParent.parentNode.parentNode.parentNode !== undefined) {
|
||||
if (outputDataset.referenceParent.parentNode.parentNode.parentNode.code.codeName === undefined) {
|
||||
logger.write(MODULE_NAME, "[ERROR] raiseEvents -> codeName at Team not defined. Team = " + JSON.stringify(outputDataset.referenceParent.parentNode.parentNode.parentNode));
|
||||
callBackFunction(global.DEFAULT_FAIL_RESPONSE);
|
||||
return
|
||||
}
|
||||
} else {
|
||||
logger.write(MODULE_NAME, "[ERROR] raiseEvents -> Bot not attached to a Team. Bot = " + JSON.stringify(outputDataset.referenceParent.parentNode.parentNode));
|
||||
callBackFunction(global.DEFAULT_FAIL_RESPONSE);
|
||||
return
|
||||
}
|
||||
} else {
|
||||
logger.write(MODULE_NAME, "[ERROR] raiseEvents -> Product not attached to a Bot. Product = " + JSON.stringify(outputDataset.referenceParent.parentNode));
|
||||
callBackFunction(global.DEFAULT_FAIL_RESPONSE);
|
||||
return
|
||||
}
|
||||
} else {
|
||||
logger.write(MODULE_NAME, "[ERROR] raiseEvents -> Dataset Definition not attached to a Product. Dataset Definition = " + JSON.stringify(outputDataset.referenceParent));
|
||||
callBackFunction(global.DEFAULT_FAIL_RESPONSE);
|
||||
return
|
||||
}
|
||||
} else {
|
||||
logger.write(MODULE_NAME, "[ERROR] raiseEvents -> Output Dataset with no reference to a Dataset Definition. Output Dataset = " + JSON.stringify(outputDataset));
|
||||
callBackFunction(global.DEFAULT_FAIL_RESPONSE);
|
||||
return
|
||||
}
|
||||
|
||||
/* All good, lets emit the event. */
|
||||
|
||||
let devTeam = outputDataset.referenceParent.parentNode.parentNode.parentNode.code.codeName
|
||||
let botName = outputDataset.referenceParent.parentNode.parentNode.code.codeName
|
||||
let product = outputDataset.referenceParent.parentNode.code.codeName
|
||||
let dataset = outputDataset.referenceParent.code.codeName
|
||||
|
||||
let statusReport = statusDependencies.reportsByMainUtility.get("Self Reference")
|
||||
|
||||
key = devTeam + "-" + botName + "-" + product + "-" + dataset
|
||||
let event = {
|
||||
lastFile: statusReport.file.lastFile
|
||||
}
|
||||
global.SYSTEM_EVENT_HANDLER.createEventHandler(key, 'Dataset Updated')
|
||||
global.SYSTEM_EVENT_HANDLER.raiseEvent(key, 'Dataset Updated', event)
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
callBackFunction(global.DEFAULT_OK_RESPONSE);
|
||||
|
||||
} catch (err) {
|
||||
logger.write(MODULE_NAME, "[ERROR] raiseEvents -> err = " + err.stack);
|
||||
callBackFunction(global.DEFAULT_FAIL_RESPONSE);
|
||||
}
|
||||
}
|
||||
};
|
||||
+17
-1
@@ -25,6 +25,10 @@
|
||||
<Compile Include="Assistant.js">
|
||||
<SubType>Code</SubType>
|
||||
</Compile>
|
||||
<Compile Include="Commons.js">
|
||||
<SubType>Code</SubType>
|
||||
</Compile>
|
||||
<Compile Include="IndicatorBot.js" />
|
||||
<Compile Include="Integrations\Ecosystem.js" />
|
||||
<Compile Include="FileStorage.js" />
|
||||
<Compile Include="MultiPeriod.js">
|
||||
@@ -36,10 +40,22 @@
|
||||
<Compile Include="MultiPeriodMarket.js">
|
||||
<SubType>Code</SubType>
|
||||
</Compile>
|
||||
<Compile Include="ProcessExecutionEvents.js">
|
||||
<SubType>Code</SubType>
|
||||
</Compile>
|
||||
<Compile Include="ProcessOutput.js">
|
||||
<SubType>Code</SubType>
|
||||
</Compile>
|
||||
<Compile Include="Session.js">
|
||||
<SubType>Code</SubType>
|
||||
</Compile>
|
||||
<Compile Include="TradingEngineProcessMainLoop.js">
|
||||
<Compile Include="TradingBot.js">
|
||||
<SubType>Code</SubType>
|
||||
</Compile>
|
||||
<Compile Include="TradingBotProcessMainLoop.js">
|
||||
<SubType>Code</SubType>
|
||||
</Compile>
|
||||
<Compile Include="TradingSimulation.js">
|
||||
<SubType>Code</SubType>
|
||||
</Compile>
|
||||
<Compile Include="utils\logger.js">
|
||||
|
||||
@@ -79,7 +79,7 @@
|
||||
logContent: false,
|
||||
intensiveLogging: false
|
||||
},
|
||||
"Data Set": {
|
||||
"Dataset": {
|
||||
logInfo: true,
|
||||
logWarnings: false,
|
||||
logErrors: true,
|
||||
@@ -92,6 +92,20 @@
|
||||
logErrors: true,
|
||||
logContent: false,
|
||||
intensiveLogging: false
|
||||
},
|
||||
"Process Execution Events": {
|
||||
logInfo: true,
|
||||
logWarnings: false,
|
||||
logErrors: true,
|
||||
logContent: false,
|
||||
intensiveLogging: false
|
||||
},
|
||||
"Process Output": {
|
||||
logInfo: true,
|
||||
logWarnings: false,
|
||||
logErrors: true,
|
||||
logContent: false,
|
||||
intensiveLogging: false
|
||||
}
|
||||
};
|
||||
|
||||
@@ -121,292 +135,300 @@
|
||||
|
||||
const INDICATOR_BOT_MAIN_LOOP_MODULE = require('./IndicatorBotProcessMainLoop');
|
||||
const SENSOR_BOT_MAIN_LOOP_MODULE = require('./SensorBotProcessMainLoop');
|
||||
const TRADING_ENGINE_MAIN_LOOP_MODULE = require('./TradingEngineProcessMainLoop');
|
||||
|
||||
/* Loop through all the processes configured to be run by this Node.js Instance. */
|
||||
/* Now we will read the config of the bot from the path we obtained at the Task Server config. */
|
||||
const TRADING_ENGINE_MAIN_LOOP_MODULE = require('./TradingBotProcessMainLoop');
|
||||
|
||||
let botConfig;
|
||||
let processInstance = global.TASK_NODE.bot.processes[processIndex]
|
||||
|
||||
getBotConfig();
|
||||
/* Here we will check if we need to load the configuration and code of the bot from a file or we will take that from the UI. */
|
||||
if (
|
||||
processInstance.referenceParent.code.framework !== undefined &&
|
||||
( processInstance.referenceParent.code.framework.name === 'Multi-Period-Market' ||
|
||||
processInstance.referenceParent.code.framework.name === 'Multi-Period-Daily' ||
|
||||
processInstance.referenceParent.code.framework.name === 'Multi-Period')
|
||||
) {
|
||||
botConfig = processInstance.referenceParent.parentNode.code
|
||||
botConfig.definedByUI = true
|
||||
bootingBot(processIndex)
|
||||
return
|
||||
} else {
|
||||
getBotConfigFromFile();
|
||||
return
|
||||
}
|
||||
|
||||
function getBotConfig() {
|
||||
function getBotConfigFromFile() {
|
||||
|
||||
try {
|
||||
console.log(logDisplace + "Root : [INFO] start -> getBotConfig -> Entering function. ");
|
||||
console.log(logDisplace + "Root : [INFO] start -> getBotConfigFromFile -> Entering function. ");
|
||||
|
||||
const FILE_STORAGE = require('./FileStorage.js');
|
||||
let fileStorage = FILE_STORAGE.newFileStorage();
|
||||
|
||||
let filePath = global.TASK_NODE.bot.code.team + '/bots/' + global.TASK_NODE.bot.code.repo + '/this.bot.config.json';
|
||||
let filePath = global.TASK_NODE.bot.processes[processIndex].referenceParent.parentNode.parentNode.code.codeName + '/bots/' + global.TASK_NODE.bot.code.repo + '/this.bot.config.json';
|
||||
|
||||
fileStorage.getTextFile(global.TASK_NODE.bot.code.team, filePath, onFileReceived);
|
||||
fileStorage.getTextFile(global.TASK_NODE.bot.processes[processIndex].referenceParent.parentNode.parentNode.code.codeName, filePath, onFileReceived);
|
||||
|
||||
function onFileReceived(err, text) {
|
||||
|
||||
if (err.result !== global.DEFAULT_OK_RESPONSE.result) {
|
||||
console.log(logDisplace + "Root : [ERROR] start -> getBotConfig -> onInizialized -> onFileReceived -> err = " + JSON.stringify(err));
|
||||
|
||||
console.log(logDisplace + "Root : [ERROR] start -> getBotConfigFromFile -> onInizialized -> onFileReceived -> err = " + JSON.stringify(err));
|
||||
console.log(logDisplace + "Root : [ERROR] start -> getBotConfigFromFile -> onInizialized -> onFileReceived -> filePath = " + filePath);
|
||||
console.log(logDisplace + "Root : [ERROR] start -> getBotConfigFromFile -> onInizialized -> onFileReceived -> team = " + global.TASK_NODE.bot.processes[processIndex].referenceParent.parentNode.parentNode.code.codeName);
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
botConfig = JSON.parse(text);
|
||||
botConfig.repo = global.TASK_NODE.bot.code.repo;
|
||||
findProcess(processIndex);
|
||||
bootingBot(processIndex);
|
||||
} catch (err) {
|
||||
console.log(logDisplace + "Root : [ERROR] start -> getBotConfig -> onInizialized -> onFileReceived -> err = " + JSON.stringify(err));
|
||||
console.log(logDisplace + "Root : [ERROR] start -> getBotConfigFromFile -> onInizialized -> onFileReceived -> err = " + JSON.stringify(err));
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (err) {
|
||||
console.log(logDisplace + "Root : [ERROR] start -> getBotConfig -> err = " + err.stack);
|
||||
console.log(logDisplace + "Root : [ERROR] start -> getBotConfigFromFile -> err = " + err.stack);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
function findProcess(processIndex) {
|
||||
function bootingBot(processIndex) {
|
||||
|
||||
try {
|
||||
if (FULL_LOG === true) { console.log(logDisplace + "Root : [INFO] start -> findProcess -> Entering function. "); }
|
||||
if (FULL_LOG === true) { console.log(logDisplace + "Root : [INFO] start -> bootingBot -> Entering function. "); }
|
||||
|
||||
botConfig.process = global.TASK_NODE.bot.processes[processIndex].code.process;
|
||||
botConfig.process = global.TASK_NODE.bot.processes[processIndex].referenceParent.code.codeName
|
||||
botConfig.debug = {};
|
||||
botConfig.processIndex = processIndex
|
||||
botConfig.processNode = global.TASK_NODE.bot.processes[processIndex]
|
||||
|
||||
/* Loop Counter */
|
||||
/* Logs Mantainance Stuff */
|
||||
botConfig.LOGS_TO_DELETE_QUEUE = []
|
||||
botConfig.DELETE_QUEUE_SIZE = 10 // This number represents how many log files can be at the queue at any point in time, which means how many logs are not still deleted.
|
||||
|
||||
botConfig.loopCounter = 0;
|
||||
/* Simplifying the access to basic info */
|
||||
botConfig.devTeam = global.TASK_NODE.bot.processes[processIndex].referenceParent.parentNode.parentNode.code.codeName
|
||||
|
||||
/* This stuff is still hardcoded and unresolved. */
|
||||
botConfig.version = {
|
||||
"major": 1,
|
||||
"minor": 0
|
||||
}
|
||||
botConfig.dataSetVersion = "dataSet.V1"
|
||||
|
||||
/* Loop Counter */
|
||||
botConfig.loopCounter = 0;
|
||||
|
||||
/* File Path Root */
|
||||
|
||||
botConfig.filePathRoot = botConfig.devTeam + "/" + botConfig.codeName + "." + botConfig.version.major + "." + botConfig.version.minor + "/" + global.CLONE_EXECUTOR.codeName + "." + global.CLONE_EXECUTOR.version + "/" + global.EXCHANGE_NAME + "/" + botConfig.dataSetVersion;
|
||||
|
||||
/* Process Key */
|
||||
|
||||
botConfig.processKey = global.TASK_NODE.bot.processes[processIndex].name + '-' + global.TASK_NODE.bot.processes[processIndex].type + '-' + global.TASK_NODE.bot.processes[processIndex].id
|
||||
|
||||
if (FULL_LOG === true) { console.log(logDisplace + "Root : [INFO] start -> findProcess -> filePathRoot = " + botConfig.filePathRoot); }
|
||||
/* Bot Type */
|
||||
botConfig.type = global.TASK_NODE.bot.processes[processIndex].referenceParent.parentNode.type
|
||||
|
||||
/* Now we loop throug all the configured processes at each bots configuration until we find the one we are supposed to run at this Node.js process. */
|
||||
if (FULL_LOG === true) { console.log(logDisplace + "Root : [INFO] start -> bootingBot -> filePathRoot = " + botConfig.filePathRoot); }
|
||||
if (FULL_LOG === true) { console.log(logDisplace + "Root : [INFO] start -> bootingBot -> Process found at the bot configuration file. -> process = " + global.TASK_NODE.bot.processes[processIndex].referenceParent.code.codeName); }
|
||||
|
||||
let processFound = false;
|
||||
let processConfig = global.TASK_NODE.bot.processes[processIndex].referenceParent.code
|
||||
|
||||
for (let i = 0; i < botConfig.processes.length; i++) {
|
||||
|
||||
if (botConfig.processes[i].name === global.TASK_NODE.bot.processes[processIndex].code.process) {
|
||||
|
||||
processFound = true;
|
||||
if (FULL_LOG === true) { console.log(logDisplace + "Root : [INFO] start -> findProcess -> Process found at the bot configuration file. -> process = " + global.TASK_NODE.bot.processes[processIndex].code.process); }
|
||||
|
||||
let processConfig = botConfig.processes[i];
|
||||
|
||||
if (processConfig.framework !== undefined) {
|
||||
if (processConfig.framework.name === "Multi-Period-Daily" || processConfig.framework.name === "Multi-Period-Market" || processConfig.framework.name === "Multi-Period") {
|
||||
processConfig.framework.startDate.resumeExecution = true;
|
||||
if (processConfig.startMode.noTime !== undefined) {
|
||||
if (processConfig.startMode.noTime.run === "true") {
|
||||
if (processConfig.startMode.noTime.beginDatetime !== undefined) {
|
||||
processConfig.framework.startDate.fixedDate = processConfig.startMode.noTime.beginDatetime;
|
||||
processConfig.framework.startDate.resumeExecution = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (processConfig.startMode.userDefined !== undefined) {
|
||||
if (processConfig.startMode.userDefined.run === "true") {
|
||||
if (processConfig.startMode.userDefined.beginDatetime !== undefined) {
|
||||
processConfig.framework.startDate.fixedDate = processConfig.startMode.userDefined.beginDatetime;
|
||||
processConfig.framework.startDate.resumeExecution = processConfig.startMode.userDefined.resumeExecution;
|
||||
}
|
||||
}
|
||||
if (processConfig.framework !== undefined) {
|
||||
if (processConfig.framework.name === "Multi-Period-Daily" || processConfig.framework.name === "Multi-Period-Market" || processConfig.framework.name === "Multi-Period") {
|
||||
processConfig.framework.startDate.resumeExecution = true;
|
||||
if (processConfig.startMode.noTime !== undefined) {
|
||||
if (processConfig.startMode.noTime.run === "true") {
|
||||
if (processConfig.startMode.noTime.beginDatetime !== undefined) {
|
||||
processConfig.framework.startDate.fixedDate = processConfig.startMode.noTime.beginDatetime;
|
||||
processConfig.framework.startDate.resumeExecution = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
|
||||
/* We test each type of start Mode to get what to run and how. */
|
||||
|
||||
if (processConfig.startMode.allMonths !== undefined) {
|
||||
|
||||
if (processConfig.startMode.allMonths.run === "true") {
|
||||
|
||||
if (FULL_LOG === true) { console.log(logDisplace + "Root : [INFO] start -> findProcess -> allMonths start mode detected. "); }
|
||||
|
||||
for (let year = processConfig.startMode.allMonths.maxYear; year >= processConfig.startMode.allMonths.minYear; year--) {
|
||||
|
||||
for (let month = 12; month > 0; month--) {
|
||||
|
||||
let padMonth = pad(month, 2)
|
||||
|
||||
let newInstanceBotConfig = JSON.parse(JSON.stringify(botConfig));
|
||||
|
||||
newInstanceBotConfig.debug = {
|
||||
month: pad(month, 2),
|
||||
year: pad(year, 4)
|
||||
};
|
||||
|
||||
let timeDelay = Math.random() * 10 * 1000; // We introduce a short delay so as to not overload the machine.
|
||||
setTimeout(startProcess, timeDelay);
|
||||
|
||||
function startProcess() {
|
||||
|
||||
if (FULL_LOG === true) { console.log(logDisplace + "Root : [INFO] start -> findProcess -> startProcess -> Ready to start process."); }
|
||||
|
||||
switch (botConfig.type) {
|
||||
case 'Sensor': {
|
||||
runSensorBot(newInstanceBotConfig, processConfig, padMonth, year);
|
||||
break;
|
||||
}
|
||||
case 'Indicator': {
|
||||
runIndicatorBot(newInstanceBotConfig, processConfig, padMonth, year);
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
console.log(logDisplace + "Root : [ERROR] start -> findProcess -> startProcess -> Unexpected bot type. -> botConfig.type = " + botConfig.type);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (processConfig.startMode.userDefined !== undefined) {
|
||||
if (processConfig.startMode.userDefined.run === "true") {
|
||||
if (processConfig.startMode.userDefined.beginDatetime !== undefined) {
|
||||
processConfig.framework.startDate.fixedDate = processConfig.startMode.userDefined.beginDatetime;
|
||||
processConfig.framework.startDate.resumeExecution = processConfig.startMode.userDefined.resumeExecution;
|
||||
}
|
||||
}
|
||||
|
||||
if (processConfig.startMode.oneMonth !== undefined) {
|
||||
|
||||
if (processConfig.startMode.oneMonth.run === "true") {
|
||||
|
||||
if (FULL_LOG === true) { console.log(logDisplace + "Root : [INFO] start -> findProcess -> oneMonth start mode detected. "); }
|
||||
|
||||
startProcess();
|
||||
|
||||
function startProcess() {
|
||||
|
||||
if (FULL_LOG === true) { console.log(logDisplace + "Root : [INFO] start -> findProcess -> startProcess -> Ready to start process."); }
|
||||
|
||||
let month = pad(processConfig.startMode.oneMonth.month, 2);
|
||||
let year = processConfig.startMode.oneMonth.year;
|
||||
|
||||
botConfig.debug = {
|
||||
month: pad(month, 2),
|
||||
year: pad(year, 4)
|
||||
};
|
||||
|
||||
switch (botConfig.type) {
|
||||
case 'Sensor': {
|
||||
runSensorBot(botConfig, processConfig, month, year);
|
||||
break;
|
||||
}
|
||||
case 'Indicator': {
|
||||
runIndicatorBot(botConfig, processConfig, month, year);
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
console.log(logDisplace + "Root : [ERROR] start -> findProcess -> startProcess -> Unexpected bot type. -> botConfig.type = " + botConfig.type);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (processConfig.startMode.noTime !== undefined) {
|
||||
|
||||
if (processConfig.startMode.noTime.run === "true") {
|
||||
|
||||
let month = pad((new Date()).getUTCMonth() + 1, 2);
|
||||
let year = (new Date()).getUTCFullYear();
|
||||
|
||||
if (processConfig.startMode.noTime.resumeExecution === true) {
|
||||
botConfig.hasTheBotJustStarted = false;
|
||||
} else {
|
||||
botConfig.hasTheBotJustStarted = true;
|
||||
}
|
||||
|
||||
switch (botConfig.type) {
|
||||
case 'Sensor': {
|
||||
runSensorBot(botConfig, processConfig, month, year);
|
||||
break;
|
||||
}
|
||||
case 'Indicator': {
|
||||
runIndicatorBot(botConfig, processConfig, month, year);
|
||||
break;
|
||||
}
|
||||
case 'Trading Engine': {
|
||||
runTradingEngine(botConfig, processConfig);
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
console.log(logDisplace + "Root : [ERROR] start -> findProcess -> Unexpected bot type. -> botConfig.type = " + botConfig.type);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (processConfig.startMode.fixedInterval !== undefined) {
|
||||
|
||||
if (processConfig.startMode.fixedInterval.run === "true") {
|
||||
|
||||
botConfig.runAtFixedInterval = true;
|
||||
botConfig.fixedInterval = processConfig.startMode.fixedInterval.interval;
|
||||
|
||||
let month = pad((new Date()).getUTCMonth() + 1, 2);
|
||||
let year = (new Date()).getUTCFullYear();
|
||||
|
||||
switch (botConfig.type) {
|
||||
case 'Sensor': {
|
||||
runSensorBot(botConfig, processConfig, month, year);
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
console.log(logDisplace + "Root : [ERROR] start -> findProcess -> Unexpected bot type. -> botConfig.type = " + botConfig.type);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (processConfig.startMode.userDefined !== undefined) {
|
||||
|
||||
if (processConfig.startMode.userDefined.run === "true") {
|
||||
|
||||
botConfig.startMode = "User Defined";
|
||||
console.log(logDisplace + "Root : [INFO] start -> findProcess -> Process found at the bot configuration file. -> Start Mode = " + botConfig.startMode);
|
||||
|
||||
let month = pad((new Date()).getUTCMonth() + 1, 2);
|
||||
let year = (new Date()).getUTCFullYear();
|
||||
|
||||
if (processConfig.startMode.userDefined.resumeExecution === true) {
|
||||
botConfig.hasTheBotJustStarted = false;
|
||||
} else {
|
||||
botConfig.hasTheBotJustStarted = true;
|
||||
}
|
||||
|
||||
switch (botConfig.type) {
|
||||
case 'Trading Engine': {
|
||||
runTradingEngine(botConfig, processConfig);
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
console.log(logDisplace + "Root : [ERROR] start -> findProcess -> Unexpected bot type. -> botConfig.type = " + botConfig.type);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} catch (err) {
|
||||
console.log(logDisplace + "Root : [ERROR] start -> findProcess -> Unexpected exception. -> err = " + err.stack);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (processFound === false) {
|
||||
try {
|
||||
|
||||
console.log(logDisplace + "Root : [ERROR] start -> findProcess -> Process listed at the configuration file of Task Server not found at the configuration file of the bot.");
|
||||
console.log(logDisplace + "Root : [ERROR] start -> findProcess -> process = " + global.TASK_NODE.bot.processes[processIndex].code.process);
|
||||
/* We test each type of start Mode to get what to run and how. */
|
||||
|
||||
if (processConfig.startMode.allMonths !== undefined) {
|
||||
|
||||
if (processConfig.startMode.allMonths.run === "true") {
|
||||
|
||||
if (FULL_LOG === true) { console.log(logDisplace + "Root : [INFO] start -> bootingBot -> allMonths start mode detected. "); }
|
||||
|
||||
for (let year = processConfig.startMode.allMonths.maxYear; year >= processConfig.startMode.allMonths.minYear; year--) {
|
||||
|
||||
for (let month = 12; month > 0; month--) {
|
||||
|
||||
let padMonth = pad(month, 2)
|
||||
|
||||
let newInstanceBotConfig = JSON.parse(JSON.stringify(botConfig));
|
||||
|
||||
newInstanceBotConfig.debug = {
|
||||
month: pad(month, 2),
|
||||
year: pad(year, 4)
|
||||
};
|
||||
|
||||
let timeDelay = Math.random() * 10 * 1000; // We introduce a short delay so as to not overload the machine.
|
||||
setTimeout(startProcess, timeDelay);
|
||||
|
||||
function startProcess() {
|
||||
|
||||
if (FULL_LOG === true) { console.log(logDisplace + "Root : [INFO] start -> bootingBot -> startProcess -> Ready to start process."); }
|
||||
|
||||
switch (botConfig.type) {
|
||||
case 'Sensor Bot': {
|
||||
runSensorBot(newInstanceBotConfig, processConfig, padMonth, year);
|
||||
break;
|
||||
}
|
||||
case 'Indicator Bot': {
|
||||
runIndicatorBot(newInstanceBotConfig, processConfig, padMonth, year);
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
console.log(logDisplace + "Root : [ERROR] start -> bootingBot -> startProcess -> Unexpected bot type. -> botConfig.type = " + botConfig.type);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (processConfig.startMode.oneMonth !== undefined) {
|
||||
|
||||
if (processConfig.startMode.oneMonth.run === "true") {
|
||||
|
||||
if (FULL_LOG === true) { console.log(logDisplace + "Root : [INFO] start -> bootingBot -> oneMonth start mode detected. "); }
|
||||
|
||||
startProcess();
|
||||
|
||||
function startProcess() {
|
||||
|
||||
if (FULL_LOG === true) { console.log(logDisplace + "Root : [INFO] start -> bootingBot -> startProcess -> Ready to start process."); }
|
||||
|
||||
let month = pad(processConfig.startMode.oneMonth.month, 2);
|
||||
let year = processConfig.startMode.oneMonth.year;
|
||||
|
||||
botConfig.debug = {
|
||||
month: pad(month, 2),
|
||||
year: pad(year, 4)
|
||||
};
|
||||
|
||||
switch (botConfig.type) {
|
||||
case 'Sensor Bot': {
|
||||
runSensorBot(botConfig, processConfig, month, year);
|
||||
break;
|
||||
}
|
||||
case 'Indicator Bot': {
|
||||
runIndicatorBot(botConfig, processConfig, month, year);
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
console.log(logDisplace + "Root : [ERROR] start -> bootingBot -> startProcess -> Unexpected bot type. -> botConfig.type = " + botConfig.type);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (processConfig.startMode.noTime !== undefined) {
|
||||
|
||||
if (processConfig.startMode.noTime.run === "true") {
|
||||
|
||||
let month = pad((new Date()).getUTCMonth() + 1, 2);
|
||||
let year = (new Date()).getUTCFullYear();
|
||||
|
||||
if (processConfig.startMode.noTime.resumeExecution === true) {
|
||||
botConfig.hasTheBotJustStarted = false;
|
||||
} else {
|
||||
botConfig.hasTheBotJustStarted = true;
|
||||
}
|
||||
|
||||
switch (botConfig.type) {
|
||||
case 'Sensor Bot': {
|
||||
runSensorBot(botConfig, processConfig, month, year);
|
||||
break;
|
||||
}
|
||||
case 'Indicator Bot': {
|
||||
runIndicatorBot(botConfig, processConfig, month, year);
|
||||
break;
|
||||
}
|
||||
case 'Trading Bot': {
|
||||
runTradingBot(botConfig, processConfig);
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
console.log(logDisplace + "Root : [ERROR] start -> bootingBot -> Unexpected bot type. -> botConfig.type = " + botConfig.type);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (processConfig.startMode.fixedInterval !== undefined) {
|
||||
|
||||
if (processConfig.startMode.fixedInterval.run === "true") {
|
||||
|
||||
botConfig.runAtFixedInterval = true;
|
||||
botConfig.fixedInterval = processConfig.startMode.fixedInterval.interval;
|
||||
|
||||
let month = pad((new Date()).getUTCMonth() + 1, 2);
|
||||
let year = (new Date()).getUTCFullYear();
|
||||
|
||||
switch (botConfig.type) {
|
||||
case 'Sensor Bot': {
|
||||
runSensorBot(botConfig, processConfig, month, year);
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
console.log(logDisplace + "Root : [ERROR] start -> bootingBot -> Unexpected bot type. -> botConfig.type = " + botConfig.type);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (processConfig.startMode.userDefined !== undefined) {
|
||||
|
||||
if (processConfig.startMode.userDefined.run === "true") {
|
||||
|
||||
botConfig.startMode = "User Defined";
|
||||
console.log(logDisplace + "Root : [INFO] start -> bootingBot -> Process found at the bot configuration file. -> Start Mode = " + botConfig.startMode);
|
||||
|
||||
let month = pad((new Date()).getUTCMonth() + 1, 2);
|
||||
let year = (new Date()).getUTCFullYear();
|
||||
|
||||
if (processConfig.startMode.userDefined.resumeExecution === true) {
|
||||
botConfig.hasTheBotJustStarted = false;
|
||||
} else {
|
||||
botConfig.hasTheBotJustStarted = true;
|
||||
}
|
||||
|
||||
switch (botConfig.type) {
|
||||
case 'Trading Bot': {
|
||||
runTradingBot(botConfig, processConfig);
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
console.log(logDisplace + "Root : [ERROR] start -> bootingBot -> Unexpected bot type. -> botConfig.type = " + botConfig.type);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} catch (err) {
|
||||
console.log(logDisplace + "Root : [ERROR] start -> bootingBot -> Unexpected exception. -> err = " + err.stack);
|
||||
}
|
||||
|
||||
|
||||
function runSensorBot(pBotConfig, pProcessConfig, pMonth, pYear) {
|
||||
|
||||
try {
|
||||
@@ -418,9 +440,9 @@
|
||||
logger = DEBUG_MODULE.newDebugLog();
|
||||
logger.bot = pBotConfig;
|
||||
|
||||
if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] start -> findProcess -> runSensorBot -> Entering function."); }
|
||||
if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] start -> findProcess -> runSensorBot -> pMonth = " + pMonth); }
|
||||
if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] start -> findProcess -> runSensorBot -> pYear = " + pYear); }
|
||||
if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] start -> bootingBot -> runSensorBot -> Entering function."); }
|
||||
if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] start -> bootingBot -> runSensorBot -> pMonth = " + pMonth); }
|
||||
if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] start -> bootingBot -> runSensorBot -> pYear = " + pYear); }
|
||||
|
||||
let extractionBotMainLoop = SENSOR_BOT_MAIN_LOOP_MODULE.newSensorBotProcessMainLoop(pBotConfig, logger);
|
||||
extractionBotMainLoop.initialize(pProcessConfig, onInitializeReady);
|
||||
@@ -444,31 +466,31 @@
|
||||
|
||||
if (err.result === global.DEFAULT_OK_RESPONSE.result) {
|
||||
|
||||
logger.write(MODULE_NAME, "[INFO] start -> findProcess -> runSensorBot -> onInitializeReady -> whenStartFinishes -> Bot execution finished sucessfully.");
|
||||
logger.write(MODULE_NAME, "[INFO] start -> findProcess -> runSensorBot -> onInitializeReady -> whenStartFinishes -> Bot Id = " + botId);
|
||||
logger.write(MODULE_NAME, "[INFO] start -> bootingBot -> runSensorBot -> onInitializeReady -> whenStartFinishes -> Bot execution finished sucessfully.");
|
||||
logger.write(MODULE_NAME, "[INFO] start -> bootingBot -> runSensorBot -> onInitializeReady -> whenStartFinishes -> Bot Id = " + botId);
|
||||
|
||||
console.log(logDisplace + "Root : [INFO] start -> findProcess -> runSensorBot -> onInitializeReady -> whenStartFinishes -> botId = " + botId);
|
||||
console.log(logDisplace + "Root : [INFO] start -> findProcess -> runSensorBot -> onInitializeReady -> whenStartFinishes -> Bot execution finished sucessfully.");
|
||||
console.log(logDisplace + "Root : [INFO] start -> bootingBot -> runSensorBot -> onInitializeReady -> whenStartFinishes -> botId = " + botId);
|
||||
console.log(logDisplace + "Root : [INFO] start -> bootingBot -> runSensorBot -> onInitializeReady -> whenStartFinishes -> Bot execution finished sucessfully.");
|
||||
logger.persist();
|
||||
|
||||
} else {
|
||||
|
||||
logger.write(MODULE_NAME, "[ERROR] start -> findProcess -> runSensorBot -> onInitializeReady -> whenStartFinishes -> err = " + err.message);
|
||||
logger.write(MODULE_NAME, "[ERROR] start -> findProcess -> runSensorBot -> onInitializeReady -> whenStartFinishes -> Execution will be stopped. ");
|
||||
logger.write(MODULE_NAME, "[ERROR] start -> findProcess -> runSensorBot -> onInitializeReady -> whenStartFinishes -> Bye.");
|
||||
logger.write(MODULE_NAME, "[ERROR] start -> findProcess -> runSensorBot -> onInitializeReady -> whenStartFinishes -> Bot Id = " + botId);
|
||||
logger.write(MODULE_NAME, "[ERROR] start -> bootingBot -> runSensorBot -> onInitializeReady -> whenStartFinishes -> err = " + err.message);
|
||||
logger.write(MODULE_NAME, "[ERROR] start -> bootingBot -> runSensorBot -> onInitializeReady -> whenStartFinishes -> Execution will be stopped. ");
|
||||
logger.write(MODULE_NAME, "[ERROR] start -> bootingBot -> runSensorBot -> onInitializeReady -> whenStartFinishes -> Bye.");
|
||||
logger.write(MODULE_NAME, "[ERROR] start -> bootingBot -> runSensorBot -> onInitializeReady -> whenStartFinishes -> Bot Id = " + botId);
|
||||
|
||||
console.log(logDisplace + "Root : [ERROR] start -> findProcess -> runSensorBot -> onInitializeReady -> whenStartFinishes -> botId = " + botId);
|
||||
console.log(logDisplace + "Root : [ERROR] start -> findProcess -> runSensorBot -> onInitializeReady -> whenStartFinishes -> Bot execution was aborted.");
|
||||
console.log(logDisplace + "Root : [ERROR] start -> bootingBot -> runSensorBot -> onInitializeReady -> whenStartFinishes -> botId = " + botId);
|
||||
console.log(logDisplace + "Root : [ERROR] start -> bootingBot -> runSensorBot -> onInitializeReady -> whenStartFinishes -> Bot execution was aborted.");
|
||||
logger.persist();
|
||||
}
|
||||
setTimeout(exitProcessInstance, WAIT_TIME_FOR_ALL_PROCESS_INSTANCES_TO_START)
|
||||
}
|
||||
|
||||
} else {
|
||||
logger.write(MODULE_NAME, "[ERROR] start -> findProcess -> runSensorBot -> onInitializeReady -> err = " + err.message);
|
||||
logger.write(MODULE_NAME, "[ERROR] start -> findProcess -> runSensorBot -> onInitializeReady -> Bot will not be started. ");
|
||||
console.log(logDisplace + "Root : [ERROR] start -> findProcess -> runSensorBot -> onInitializeReady -> err = " + err.message);
|
||||
logger.write(MODULE_NAME, "[ERROR] start -> bootingBot -> runSensorBot -> onInitializeReady -> err = " + err.message);
|
||||
logger.write(MODULE_NAME, "[ERROR] start -> bootingBot -> runSensorBot -> onInitializeReady -> Bot will not be started. ");
|
||||
console.log(logDisplace + "Root : [ERROR] start -> bootingBot -> runSensorBot -> onInitializeReady -> err = " + err.message);
|
||||
|
||||
logger.persist();
|
||||
setTimeout(exitProcessInstance, WAIT_TIME_FOR_ALL_PROCESS_INSTANCES_TO_START)
|
||||
@@ -476,7 +498,7 @@
|
||||
}
|
||||
}
|
||||
catch (err) {
|
||||
console.log(logDisplace + "Root : [ERROR] start -> findProcess -> runSensorBot -> err = " + err.stack);
|
||||
console.log(logDisplace + "Root : [ERROR] start -> bootingBot -> runSensorBot -> err = " + err.stack);
|
||||
setTimeout(exitProcessInstance, WAIT_TIME_FOR_ALL_PROCESS_INSTANCES_TO_START)
|
||||
}
|
||||
}
|
||||
@@ -492,9 +514,9 @@
|
||||
logger = DEBUG_MODULE.newDebugLog();
|
||||
logger.bot = pBotConfig;
|
||||
|
||||
if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] start -> findProcess -> runIndicatorBot -> Entering function."); }
|
||||
if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] start -> findProcess -> runIndicatorBot -> pMonth = " + pMonth); }
|
||||
if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] start -> findProcess -> runIndicatorBot -> pYear = " + pYear); }
|
||||
if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] start -> bootingBot -> runIndicatorBot -> Entering function."); }
|
||||
if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] start -> bootingBot -> runIndicatorBot -> pMonth = " + pMonth); }
|
||||
if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] start -> bootingBot -> runIndicatorBot -> pYear = " + pYear); }
|
||||
|
||||
let indicatorBotMainLoop = INDICATOR_BOT_MAIN_LOOP_MODULE.newIndicatorBotProcessMainLoop(pBotConfig, logger);
|
||||
indicatorBotMainLoop.initialize(pProcessConfig, onInitializeReady);
|
||||
@@ -518,41 +540,41 @@
|
||||
|
||||
if (err.result === global.DEFAULT_OK_RESPONSE.result) {
|
||||
|
||||
logger.write(MODULE_NAME, "[INFO] start -> findProcess -> runIndicatorBot -> onInitializeReady -> whenStartFinishes -> Bot execution finished sucessfully.");
|
||||
logger.write(MODULE_NAME, "[INFO] start -> findProcess -> runIndicatorBot -> onInitializeReady -> whenStartFinishes -> Bot Id = " + botId);
|
||||
logger.write(MODULE_NAME, "[INFO] start -> bootingBot -> runIndicatorBot -> onInitializeReady -> whenStartFinishes -> Bot execution finished sucessfully.");
|
||||
logger.write(MODULE_NAME, "[INFO] start -> bootingBot -> runIndicatorBot -> onInitializeReady -> whenStartFinishes -> Bot Id = " + botId);
|
||||
|
||||
console.log(logDisplace + "Root : [INFO] start -> findProcess -> runIndicatorBot -> onInitializeReady -> whenStartFinishes -> botId = " + botId);
|
||||
console.log(logDisplace + "Root : [INFO] start -> findProcess -> runIndicatorBot -> onInitializeReady -> whenStartFinishes -> Bot execution finished sucessfully.");
|
||||
console.log(logDisplace + "Root : [INFO] start -> bootingBot -> runIndicatorBot -> onInitializeReady -> whenStartFinishes -> botId = " + botId);
|
||||
console.log(logDisplace + "Root : [INFO] start -> bootingBot -> runIndicatorBot -> onInitializeReady -> whenStartFinishes -> Bot execution finished sucessfully.");
|
||||
logger.persist();
|
||||
|
||||
} else {
|
||||
|
||||
logger.write(MODULE_NAME, "[ERROR] start -> findProcess -> runIndicatorBot -> onInitializeReady -> whenStartFinishes -> err = " + err.message);
|
||||
logger.write(MODULE_NAME, "[ERROR] start -> findProcess -> runIndicatorBot -> onInitializeReady -> whenStartFinishes -> Execution will be stopped. ");
|
||||
logger.write(MODULE_NAME, "[ERROR] start -> findProcess -> runIndicatorBot -> onInitializeReady -> whenStartFinishes -> Bye.");
|
||||
logger.write(MODULE_NAME, "[ERROR] start -> findProcess -> runIndicatorBot -> onInitializeReady -> whenStartFinishes -> Bot Id = " + botId);
|
||||
console.log(logDisplace + "Root : [ERROR] start -> findProcess -> runIndicatorBot -> onInitializeReady -> whenStartFinishes -> Bot execution finished with errors. Please check the logs.");
|
||||
logger.write(MODULE_NAME, "[ERROR] start -> bootingBot -> runIndicatorBot -> onInitializeReady -> whenStartFinishes -> err = " + err.message);
|
||||
logger.write(MODULE_NAME, "[ERROR] start -> bootingBot -> runIndicatorBot -> onInitializeReady -> whenStartFinishes -> Execution will be stopped. ");
|
||||
logger.write(MODULE_NAME, "[ERROR] start -> bootingBot -> runIndicatorBot -> onInitializeReady -> whenStartFinishes -> Bye.");
|
||||
logger.write(MODULE_NAME, "[ERROR] start -> bootingBot -> runIndicatorBot -> onInitializeReady -> whenStartFinishes -> Bot Id = " + botId);
|
||||
console.log(logDisplace + "Root : [ERROR] start -> bootingBot -> runIndicatorBot -> onInitializeReady -> whenStartFinishes -> Bot execution finished with errors. Please check the logs.");
|
||||
logger.persist();
|
||||
}
|
||||
setTimeout(exitProcessInstance, WAIT_TIME_FOR_ALL_PROCESS_INSTANCES_TO_START)
|
||||
}
|
||||
|
||||
} else {
|
||||
logger.write(MODULE_NAME, "[ERROR] start -> findProcess -> runIndicatorBot -> onInitializeReady -> err = " + err.message);
|
||||
logger.write(MODULE_NAME, "[ERROR] start -> findProcess -> runIndicatorBot -> onInitializeReady -> Failed to initialize the bot. ");
|
||||
console.log(logDisplace + "Root : [ERROR] start -> findProcess -> runIndicatorBot -> onInitializeReady -> err = " + err.message);
|
||||
logger.write(MODULE_NAME, "[ERROR] start -> bootingBot -> runIndicatorBot -> onInitializeReady -> err = " + err.message);
|
||||
logger.write(MODULE_NAME, "[ERROR] start -> bootingBot -> runIndicatorBot -> onInitializeReady -> Failed to initialize the bot. ");
|
||||
console.log(logDisplace + "Root : [ERROR] start -> bootingBot -> runIndicatorBot -> onInitializeReady -> err = " + err.message);
|
||||
logger.persist();
|
||||
setTimeout(exitProcessInstance, WAIT_TIME_FOR_ALL_PROCESS_INSTANCES_TO_START)
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (err) {
|
||||
console.log(logDisplace + "Root : [ERROR] start -> findProcess -> runIndicatorBot -> err = " + err.stack);
|
||||
console.log(logDisplace + "Root : [ERROR] start -> bootingBot -> runIndicatorBot -> err = " + err.stack);
|
||||
setTimeout(exitProcessInstance, WAIT_TIME_FOR_ALL_PROCESS_INSTANCES_TO_START)
|
||||
}
|
||||
}
|
||||
|
||||
function runTradingEngine(pBotConfig, pProcessConfig) {
|
||||
function runTradingBot(pBotConfig, pProcessConfig) {
|
||||
|
||||
global.TOTAL_PROCESS_INSTANCES_CREATED++
|
||||
|
||||
@@ -563,16 +585,16 @@
|
||||
logger = DEBUG_MODULE.newDebugLog();
|
||||
logger.bot = pBotConfig;
|
||||
|
||||
if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] start -> findProcess -> runTradingEngine -> Entering function."); }
|
||||
if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] start -> bootingBot -> runTradingBot -> Entering function."); }
|
||||
|
||||
let tradingEngineMainLoop = TRADING_ENGINE_MAIN_LOOP_MODULE.newTradingEngineProcessMainLoop(pBotConfig, logger);
|
||||
tradingEngineMainLoop.initialize(pProcessConfig, onInitializeReady);
|
||||
let tradingBotMainLoop = TRADING_ENGINE_MAIN_LOOP_MODULE.newTradingBotProcessMainLoop(pBotConfig, logger);
|
||||
tradingBotMainLoop.initialize(pProcessConfig, onInitializeReady);
|
||||
|
||||
function onInitializeReady(err) {
|
||||
|
||||
if (err.result === global.DEFAULT_OK_RESPONSE.result) {
|
||||
|
||||
tradingEngineMainLoop.run(whenRunFinishes);
|
||||
tradingBotMainLoop.run(whenRunFinishes);
|
||||
|
||||
function whenRunFinishes(err) {
|
||||
|
||||
@@ -584,42 +606,42 @@
|
||||
|
||||
if (err.result === global.DEFAULT_OK_RESPONSE.result) {
|
||||
|
||||
logger.write(MODULE_NAME, "[INFO] start -> findProcess -> runTradingEngine -> onInitializeReady -> whenStartFinishes -> Bot execution finished sucessfully.");
|
||||
logger.write(MODULE_NAME, "[INFO] start -> findProcess -> runTradingEngine -> onInitializeReady -> whenStartFinishes -> Bot Id = " + botId);
|
||||
logger.write(MODULE_NAME, "[INFO] start -> bootingBot -> runTradingBot -> onInitializeReady -> whenStartFinishes -> Bot execution finished sucessfully.");
|
||||
logger.write(MODULE_NAME, "[INFO] start -> bootingBot -> runTradingBot -> onInitializeReady -> whenStartFinishes -> Bot Id = " + botId);
|
||||
|
||||
console.log(logDisplace + "Root : [INFO] start -> findProcess -> runTradingEngine -> onInitializeReady -> whenStartFinishes -> botId = " + botId);
|
||||
console.log(logDisplace + "Root : [INFO] start -> findProcess -> runTradingEngine -> onInitializeReady -> whenStartFinishes -> Bot execution finished sucessfully.");
|
||||
console.log(logDisplace + "Root : [INFO] start -> bootingBot -> runTradingBot -> onInitializeReady -> whenStartFinishes -> botId = " + botId);
|
||||
console.log(logDisplace + "Root : [INFO] start -> bootingBot -> runTradingBot -> onInitializeReady -> whenStartFinishes -> Bot execution finished sucessfully.");
|
||||
logger.persist();
|
||||
|
||||
} else {
|
||||
|
||||
logger.write(MODULE_NAME, "[ERROR] start -> findProcess -> runTradingEngine -> onInitializeReady -> whenStartFinishes -> err = " + err.message);
|
||||
logger.write(MODULE_NAME, "[ERROR] start -> findProcess -> runTradingEngine -> onInitializeReady -> whenStartFinishes -> Execution will be stopped. ");
|
||||
logger.write(MODULE_NAME, "[ERROR] start -> findProcess -> runTradingEngine -> onInitializeReady -> whenStartFinishes -> Bye.");
|
||||
logger.write(MODULE_NAME, "[ERROR] start -> findProcess -> runTradingEngine -> onInitializeReady -> whenStartFinishes -> Bot Id = " + botId);
|
||||
console.log(logDisplace + "Root : [ERROR] start -> findProcess -> runTradingEngine -> onInitializeReady -> whenStartFinishes -> Bot execution finished with errors. Please check the logs.");
|
||||
logger.write(MODULE_NAME, "[ERROR] start -> bootingBot -> runTradingBot -> onInitializeReady -> whenStartFinishes -> err = " + err.message);
|
||||
logger.write(MODULE_NAME, "[ERROR] start -> bootingBot -> runTradingBot -> onInitializeReady -> whenStartFinishes -> Execution will be stopped. ");
|
||||
logger.write(MODULE_NAME, "[ERROR] start -> bootingBot -> runTradingBot -> onInitializeReady -> whenStartFinishes -> Bye.");
|
||||
logger.write(MODULE_NAME, "[ERROR] start -> bootingBot -> runTradingBot -> onInitializeReady -> whenStartFinishes -> Bot Id = " + botId);
|
||||
console.log(logDisplace + "Root : [ERROR] start -> bootingBot -> runTradingBot -> onInitializeReady -> whenStartFinishes -> Bot execution finished with errors. Please check the logs.");
|
||||
logger.persist();
|
||||
}
|
||||
setTimeout(exitProcessInstance, WAIT_TIME_FOR_ALL_PROCESS_INSTANCES_TO_START)
|
||||
}
|
||||
|
||||
} else {
|
||||
logger.write(MODULE_NAME, "[ERROR] start -> findProcess -> runTradingEngine -> onInitializeReady -> err = " + err.message);
|
||||
logger.write(MODULE_NAME, "[ERROR] start -> findProcess -> runTradingEngine -> onInitializeReady -> Failed to initialize the bot. ");
|
||||
console.log(logDisplace + "Root : [ERROR] start -> findProcess -> runTradingEngine -> onInitializeReady -> err = " + err.message);
|
||||
logger.write(MODULE_NAME, "[ERROR] start -> bootingBot -> runTradingBot -> onInitializeReady -> err = " + err.message);
|
||||
logger.write(MODULE_NAME, "[ERROR] start -> bootingBot -> runTradingBot -> onInitializeReady -> Failed to initialize the bot. ");
|
||||
console.log(logDisplace + "Root : [ERROR] start -> bootingBot -> runTradingBot -> onInitializeReady -> err = " + err.message);
|
||||
logger.persist();
|
||||
setTimeout(exitProcessInstance, WAIT_TIME_FOR_ALL_PROCESS_INSTANCES_TO_START)
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (err) {
|
||||
console.log(logDisplace + "Root : [ERROR] start -> findProcess -> runTradingEngine -> err = " + err.stack);
|
||||
console.log(logDisplace + "Root : [ERROR] start -> bootingBot -> runTradingBot -> err = " + err.stack);
|
||||
setTimeout(exitProcessInstance, WAIT_TIME_FOR_ALL_PROCESS_INSTANCES_TO_START)
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (err) {
|
||||
console.log(logDisplace + "Root : [ERROR] start -> findProcess -> err = " + err.stack);
|
||||
console.log(logDisplace + "Root : [ERROR] start -> bootingBot -> err = " + err.stack);
|
||||
setTimeout(exitProcessInstance, WAIT_TIME_FOR_ALL_PROCESS_INSTANCES_TO_START)
|
||||
}
|
||||
}
|
||||
|
||||
+313
-6
@@ -35,7 +35,13 @@
|
||||
|
||||
processConfig = pProcessConfig;
|
||||
|
||||
let filePath = bot.devTeam + "/" + "bots" + "/" + bot.repo + "/" + pProcessConfig.name;
|
||||
if (bot.definedByUI === true) {
|
||||
/* The code of the bot is defined at the UI. No need to load a file with the code. */
|
||||
callBackFunction(global.DEFAULT_OK_RESPONSE);
|
||||
return
|
||||
}
|
||||
|
||||
let filePath = bot.devTeam + "/" + "bots" + "/" + bot.repo + "/" + pProcessConfig.codeName
|
||||
filePath += "/User.Bot.js"
|
||||
|
||||
fileStorage.getTextFile(bot.devTeam, filePath, onBotDownloaded);
|
||||
@@ -45,6 +51,7 @@
|
||||
if (err.result !== global.DEFAULT_OK_RESPONSE.result) {
|
||||
|
||||
parentLogger.write(MODULE_NAME, "[ERROR] initialize -> onInizialized -> onBotDownloaded -> err = " + err.message);
|
||||
parentLogger.write(MODULE_NAME, "[ERROR] initialize -> onInizialized -> onBotDownloaded -> filePath = " + filePath);
|
||||
callBackFunction(global.DEFAULT_FAIL_RESPONSE);
|
||||
return;
|
||||
}
|
||||
@@ -130,6 +137,8 @@
|
||||
const STATUS_REPORT = require(ROOT_DIR + 'StatusReport');
|
||||
const EXCHANGE_API = require('@superalgos/exchange-gateway');
|
||||
const STATUS_DEPENDENCIES = require(ROOT_DIR + 'StatusDependencies');
|
||||
const PROCESS_EXECUTION_EVENTS = require(ROOT_DIR + 'ProcessExecutionEvents');
|
||||
const PROCESS_OUTPUT = require(ROOT_DIR + 'ProcessOutput');
|
||||
|
||||
/* We define the datetime for the process that we are running now. This will be the official processing time for both the infraestructure and the bot. */
|
||||
|
||||
@@ -140,15 +149,165 @@
|
||||
console.log(new Date().toISOString() + " " + pad(bot.codeName, 20) + " " + pad(bot.process, 30) + " " + pad(pMonth, 2) + "/" + pad(pYear, 4)
|
||||
+ " Entered into Main Loop # " + pad(Number(bot.loopCounter), 8) + " bot.processDatetime = " + bot.processDatetime.toISOString());
|
||||
|
||||
/* We will prepare first the infraestructure needed for the bot to run. There are 3 modules we need to sucessfullly initialize first. */
|
||||
/* We will prepare first the infraestructure needed for the bot to run. There are 4 modules we need to sucessfullly initialize first. */
|
||||
|
||||
let processOutput
|
||||
let processExecutionEvents
|
||||
let userBot;
|
||||
let statusDependencies;
|
||||
let exchangeAPI;
|
||||
|
||||
let nextWaitTime;
|
||||
|
||||
initializeStatusDependencies();
|
||||
initializeProcessExecutionEvents();
|
||||
|
||||
function initializeProcessExecutionEvents() {
|
||||
|
||||
try {
|
||||
|
||||
if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] run -> loop -> initializeProcessExecutionEvents -> Entering function."); }
|
||||
|
||||
processExecutionEvents = PROCESS_EXECUTION_EVENTS.newProcessExecutionEvents(bot, logger)
|
||||
|
||||
processExecutionEvents.initialize(pMonth, pYear, onInizialized);
|
||||
|
||||
function onInizialized(err) {
|
||||
|
||||
try {
|
||||
|
||||
if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] run -> loop -> initializeProcessExecutionEvents -> onInizialized -> Entering function."); }
|
||||
|
||||
switch (err.result) {
|
||||
case global.DEFAULT_OK_RESPONSE.result: {
|
||||
logger.write(MODULE_NAME, "[INFO] run -> loop -> initializeProcessExecutionEvents -> onInizialized -> Execution finished well.");
|
||||
startProcessExecutionEvents()
|
||||
return;
|
||||
}
|
||||
case global.DEFAULT_RETRY_RESPONSE.result: { // Something bad happened, but if we retry in a while it might go through the next time.
|
||||
logger.write(MODULE_NAME, "[WARN] run -> loop -> initializeProcessExecutionEvents -> onInizialized -> Retry Later. Requesting Execution Retry.");
|
||||
nextWaitTime = 'Retry';
|
||||
loopControl(nextWaitTime);
|
||||
return;
|
||||
}
|
||||
case global.DEFAULT_FAIL_RESPONSE.result: { // This is an unexpected exception that we do not know how to handle.
|
||||
processStopped()
|
||||
logger.write(MODULE_NAME, "[ERROR] run -> loop -> initializeProcessExecutionEvents -> onInizialized -> Operation Failed. Aborting the process.");
|
||||
logger.persist();
|
||||
clearInterval(fixedTimeLoopIntervalHandle);
|
||||
clearTimeout(nextLoopTimeoutHandle);
|
||||
clearTimeout(checkLoopHealthHandle);
|
||||
bot.enableCheckLoopHealth = false;
|
||||
callBackFunction(err);
|
||||
return;
|
||||
}
|
||||
default: {
|
||||
logger.write(MODULE_NAME, "[ERROR] run -> loop -> initializeProcessExecutionEvents -> onInizialized -> Unhandled err.result received. -> err.result = " + err.result);
|
||||
logger.write(MODULE_NAME, "[ERROR] run -> loop -> initializeProcessExecutionEvents -> onInizialized -> Unhandled err.result received. -> err = " + err.message);
|
||||
|
||||
logger.persist();
|
||||
clearInterval(fixedTimeLoopIntervalHandle);
|
||||
clearTimeout(nextLoopTimeoutHandle);
|
||||
clearTimeout(checkLoopHealthHandle);
|
||||
bot.enableCheckLoopHealth = false;
|
||||
callBackFunction(global.DEFAULT_FAIL_RESPONSE);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
} catch (err) {
|
||||
logger.write(MODULE_NAME, "[ERROR] run -> loop -> initializeProcessExecutionEvents -> onInizialized -> err = " + err.stack);
|
||||
logger.persist();
|
||||
clearInterval(fixedTimeLoopIntervalHandle);
|
||||
clearTimeout(nextLoopTimeoutHandle);
|
||||
clearTimeout(checkLoopHealthHandle);
|
||||
bot.enableCheckLoopHealth = false;
|
||||
callBackFunction(err);
|
||||
}
|
||||
}
|
||||
|
||||
} catch (err) {
|
||||
logger.write(MODULE_NAME, "[ERROR] run -> loop -> initializeProcessExecutionEvents -> err = " + err.stack);
|
||||
logger.persist();
|
||||
clearInterval(fixedTimeLoopIntervalHandle);
|
||||
clearTimeout(nextLoopTimeoutHandle);
|
||||
clearTimeout(checkLoopHealthHandle);
|
||||
bot.enableCheckLoopHealth = false;
|
||||
callBackFunction(err);
|
||||
}
|
||||
}
|
||||
|
||||
function startProcessExecutionEvents() {
|
||||
|
||||
try {
|
||||
|
||||
if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] run -> loop -> startProcessExecutionEvents -> Entering function."); }
|
||||
|
||||
processExecutionEvents.start(onStarted);
|
||||
|
||||
function onStarted(err) {
|
||||
|
||||
try {
|
||||
|
||||
if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] run -> loop -> startProcessExecutionEvents -> onStarted -> Entering function."); }
|
||||
|
||||
switch (err.result) {
|
||||
case global.DEFAULT_OK_RESPONSE.result: {
|
||||
logger.write(MODULE_NAME, "[INFO] run -> loop -> startProcessExecutionEvents -> onStarted -> Execution finished well.");
|
||||
initializeStatusDependencies();
|
||||
return;
|
||||
}
|
||||
case global.DEFAULT_RETRY_RESPONSE.result: { // Something bad happened, but if we retry in a while it might go through the next time.
|
||||
logger.write(MODULE_NAME, "[WARN] run -> loop -> startProcessExecutionEvents -> onStarted -> Retry Later. Requesting Execution Retry.");
|
||||
nextWaitTime = 'Retry';
|
||||
loopControl(nextWaitTime);
|
||||
return;
|
||||
}
|
||||
case global.DEFAULT_FAIL_RESPONSE.result: { // This is an unexpected exception that we do not know how to handle.
|
||||
processStopped()
|
||||
logger.write(MODULE_NAME, "[ERROR] run -> loop -> startProcessExecutionEvents -> onStarted -> Operation Failed. Aborting the process.");
|
||||
logger.persist();
|
||||
clearInterval(fixedTimeLoopIntervalHandle);
|
||||
clearTimeout(nextLoopTimeoutHandle);
|
||||
clearTimeout(checkLoopHealthHandle);
|
||||
bot.enableCheckLoopHealth = false;
|
||||
callBackFunction(err);
|
||||
return;
|
||||
}
|
||||
default: {
|
||||
logger.write(MODULE_NAME, "[ERROR] run -> loop -> startProcessExecutionEvents -> onStarted -> Unhandled err.result received. -> err.result = " + err.result);
|
||||
logger.write(MODULE_NAME, "[ERROR] run -> loop -> startProcessExecutionEvents -> onStarted -> Unhandled err.result received. -> err = " + err.message);
|
||||
|
||||
logger.persist();
|
||||
clearInterval(fixedTimeLoopIntervalHandle);
|
||||
clearTimeout(nextLoopTimeoutHandle);
|
||||
clearTimeout(checkLoopHealthHandle);
|
||||
bot.enableCheckLoopHealth = false;
|
||||
callBackFunction(global.DEFAULT_FAIL_RESPONSE);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
} catch (err) {
|
||||
logger.write(MODULE_NAME, "[ERROR] run -> loop -> startProcessExecutionEvents -> onStarted -> err = " + err.stack);
|
||||
logger.persist();
|
||||
clearInterval(fixedTimeLoopIntervalHandle);
|
||||
clearTimeout(nextLoopTimeoutHandle);
|
||||
clearTimeout(checkLoopHealthHandle);
|
||||
bot.enableCheckLoopHealth = false;
|
||||
callBackFunction(err);
|
||||
}
|
||||
}
|
||||
|
||||
} catch (err) {
|
||||
logger.write(MODULE_NAME, "[ERROR] run -> loop -> startProcessExecutionEvents -> err = " + err.stack);
|
||||
logger.persist();
|
||||
clearInterval(fixedTimeLoopIntervalHandle);
|
||||
clearTimeout(nextLoopTimeoutHandle);
|
||||
clearTimeout(checkLoopHealthHandle);
|
||||
bot.enableCheckLoopHealth = false;
|
||||
callBackFunction(err);
|
||||
}
|
||||
}
|
||||
|
||||
function initializeStatusDependencies() {
|
||||
|
||||
@@ -158,7 +317,7 @@
|
||||
|
||||
statusDependencies = STATUS_DEPENDENCIES.newStatusDependencies(bot, logger, STATUS_REPORT, UTILITIES);
|
||||
|
||||
statusDependencies.initialize(processConfig.statusDependencies, pMonth, pYear, onInizialized);
|
||||
statusDependencies.initialize(pMonth, pYear, onInizialized);
|
||||
|
||||
function onInizialized(err) {
|
||||
|
||||
@@ -427,8 +586,7 @@
|
||||
switch (err.result) {
|
||||
case global.DEFAULT_OK_RESPONSE.result: {
|
||||
logger.write(MODULE_NAME, "[INFO] run -> loop -> startUserBot -> onFinished > Execution finished well.");
|
||||
nextWaitTime = 'Normal';
|
||||
loopControl(nextWaitTime);
|
||||
raiseEventsProcessOutput()
|
||||
return;
|
||||
}
|
||||
case global.DEFAULT_RETRY_RESPONSE.result: { // Something bad happened, but if we retry in a while it might go through the next time.
|
||||
@@ -541,6 +699,155 @@
|
||||
}
|
||||
}
|
||||
|
||||
function raiseEventsProcessOutput() {
|
||||
|
||||
try {
|
||||
|
||||
if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] run -> loop -> raiseEventsProcessOutput -> Entering function."); }
|
||||
|
||||
processOutput = PROCESS_OUTPUT.newProcessOutput(bot, logger)
|
||||
|
||||
processOutput.raiseEvents(statusDependencies, onFinished);
|
||||
|
||||
function onFinished(err) {
|
||||
|
||||
try {
|
||||
|
||||
if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] run -> loop -> raiseEventsProcessOutput -> onFinished -> Entering function."); }
|
||||
|
||||
switch (err.result) {
|
||||
case global.DEFAULT_OK_RESPONSE.result: {
|
||||
logger.write(MODULE_NAME, "[INFO] run -> loop -> raiseEventsProcessOutput -> onFinished -> Execution finished well.");
|
||||
finishProcessExecutionEvents()
|
||||
return;
|
||||
}
|
||||
case global.DEFAULT_RETRY_RESPONSE.result: { // Something bad happened, but if we retry in a while it might go through the next time.
|
||||
logger.write(MODULE_NAME, "[WARN] run -> loop -> raiseEventsProcessOutput -> onFinished -> Retry Later. Requesting Execution Retry.");
|
||||
nextWaitTime = 'Retry';
|
||||
loopControl(nextWaitTime);
|
||||
return;
|
||||
}
|
||||
case global.DEFAULT_FAIL_RESPONSE.result: { // This is an unexpected exception that we do not know how to handle.
|
||||
processStopped()
|
||||
logger.write(MODULE_NAME, "[ERROR] run -> loop -> raiseEventsProcessOutput -> onFinished -> Operation Failed. Aborting the process.");
|
||||
logger.persist();
|
||||
clearInterval(fixedTimeLoopIntervalHandle);
|
||||
clearTimeout(nextLoopTimeoutHandle);
|
||||
clearTimeout(checkLoopHealthHandle);
|
||||
bot.enableCheckLoopHealth = false;
|
||||
callBackFunction(err);
|
||||
return;
|
||||
}
|
||||
default: {
|
||||
logger.write(MODULE_NAME, "[ERROR] run -> loop -> raiseEventsProcessOutput -> onFinished -> Unhandled err.result received. -> err.result = " + err.result);
|
||||
logger.write(MODULE_NAME, "[ERROR] run -> loop -> raiseEventsProcessOutput -> onFinished -> Unhandled err.result received. -> err = " + err.message);
|
||||
|
||||
logger.persist();
|
||||
clearInterval(fixedTimeLoopIntervalHandle);
|
||||
clearTimeout(nextLoopTimeoutHandle);
|
||||
clearTimeout(checkLoopHealthHandle);
|
||||
bot.enableCheckLoopHealth = false;
|
||||
callBackFunction(global.DEFAULT_FAIL_RESPONSE);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
} catch (err) {
|
||||
logger.write(MODULE_NAME, "[ERROR] run -> loop -> raiseEventsProcessOutput -> onFinished -> err = " + err.stack);
|
||||
logger.persist();
|
||||
clearInterval(fixedTimeLoopIntervalHandle);
|
||||
clearTimeout(nextLoopTimeoutHandle);
|
||||
clearTimeout(checkLoopHealthHandle);
|
||||
bot.enableCheckLoopHealth = false;
|
||||
callBackFunction(err);
|
||||
}
|
||||
}
|
||||
|
||||
} catch (err) {
|
||||
logger.write(MODULE_NAME, "[ERROR] run -> loop -> raiseEventsProcessOutput -> err = " + err.stack);
|
||||
logger.persist();
|
||||
clearInterval(fixedTimeLoopIntervalHandle);
|
||||
clearTimeout(nextLoopTimeoutHandle);
|
||||
clearTimeout(checkLoopHealthHandle);
|
||||
bot.enableCheckLoopHealth = false;
|
||||
callBackFunction(err);
|
||||
}
|
||||
}
|
||||
|
||||
function finishProcessExecutionEvents() {
|
||||
|
||||
try {
|
||||
|
||||
if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] run -> loop -> finishProcessExecutionEvents -> Entering function."); }
|
||||
|
||||
processExecutionEvents.finish(onFinished);
|
||||
|
||||
function onFinished(err) {
|
||||
|
||||
try {
|
||||
|
||||
if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] run -> loop -> finishProcessExecutionEvents -> onFinished -> Entering function."); }
|
||||
|
||||
switch (err.result) {
|
||||
case global.DEFAULT_OK_RESPONSE.result: {
|
||||
logger.write(MODULE_NAME, "[INFO] run -> loop -> finishProcessExecutionEvents -> onFinished -> Execution finished well.");
|
||||
nextWaitTime = 'Normal';
|
||||
loopControl(nextWaitTime);
|
||||
return;
|
||||
}
|
||||
case global.DEFAULT_RETRY_RESPONSE.result: { // Something bad happened, but if we retry in a while it might go through the next time.
|
||||
logger.write(MODULE_NAME, "[WARN] run -> loop -> finishProcessExecutionEvents -> onFinished -> Retry Later. Requesting Execution Retry.");
|
||||
nextWaitTime = 'Retry';
|
||||
loopControl(nextWaitTime);
|
||||
return;
|
||||
}
|
||||
case global.DEFAULT_FAIL_RESPONSE.result: { // This is an unexpected exception that we do not know how to handle.
|
||||
processStopped()
|
||||
logger.write(MODULE_NAME, "[ERROR] run -> loop -> finishProcessExecutionEvents -> onFinished -> Operation Failed. Aborting the process.");
|
||||
logger.persist();
|
||||
clearInterval(fixedTimeLoopIntervalHandle);
|
||||
clearTimeout(nextLoopTimeoutHandle);
|
||||
clearTimeout(checkLoopHealthHandle);
|
||||
bot.enableCheckLoopHealth = false;
|
||||
callBackFunction(err);
|
||||
return;
|
||||
}
|
||||
default: {
|
||||
logger.write(MODULE_NAME, "[ERROR] run -> loop -> finishProcessExecutionEvents -> onFinished -> Unhandled err.result received. -> err.result = " + err.result);
|
||||
logger.write(MODULE_NAME, "[ERROR] run -> loop -> finishProcessExecutionEvents -> onFinished -> Unhandled err.result received. -> err = " + err.message);
|
||||
|
||||
logger.persist();
|
||||
clearInterval(fixedTimeLoopIntervalHandle);
|
||||
clearTimeout(nextLoopTimeoutHandle);
|
||||
clearTimeout(checkLoopHealthHandle);
|
||||
bot.enableCheckLoopHealth = false;
|
||||
callBackFunction(global.DEFAULT_FAIL_RESPONSE);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
} catch (err) {
|
||||
logger.write(MODULE_NAME, "[ERROR] run -> loop -> finishProcessExecutionEvents -> onFinished -> err = " + err.stack);
|
||||
logger.persist();
|
||||
clearInterval(fixedTimeLoopIntervalHandle);
|
||||
clearTimeout(nextLoopTimeoutHandle);
|
||||
clearTimeout(checkLoopHealthHandle);
|
||||
bot.enableCheckLoopHealth = false;
|
||||
callBackFunction(err);
|
||||
}
|
||||
}
|
||||
|
||||
} catch (err) {
|
||||
logger.write(MODULE_NAME, "[ERROR] run -> loop -> finishProcessExecutionEvents -> err = " + err.stack);
|
||||
logger.persist();
|
||||
clearInterval(fixedTimeLoopIntervalHandle);
|
||||
clearTimeout(nextLoopTimeoutHandle);
|
||||
clearTimeout(checkLoopHealthHandle);
|
||||
bot.enableCheckLoopHealth = false;
|
||||
callBackFunction(err);
|
||||
}
|
||||
}
|
||||
|
||||
function loopControl(nextWaitTime) {
|
||||
|
||||
if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] run -> loop -> loopControl -> Entering function."); }
|
||||
|
||||
+4
-4
@@ -44,7 +44,7 @@
|
||||
return
|
||||
|
||||
function runSession(message) {
|
||||
|
||||
|
||||
/* We are going to run the Definition comming at the event. */
|
||||
bot.DEFINITION = JSON.parse(message.event.definition)
|
||||
bot.SESSION = JSON.parse(message.event.session)
|
||||
@@ -491,9 +491,9 @@
|
||||
if (socialBot.type === code.botType && socialBot.id === code.botId) {
|
||||
if (socialBot.type === "Telegram Bot") {
|
||||
if (announcement.formulaValue !== undefined) {
|
||||
socialBot.botInstance.telegramAPI.sendMessage(socialBot.botInstance.chatId, announcement.formulaValue)
|
||||
socialBot.botInstance.telegramAPI.sendMessage(socialBot.botInstance.chatId, announcement.formulaValue).catch(err => parentLogger.write(MODULE_NAME, "[WARN] initialize -> setUpSocialBots -> announce -> Telegram API error -> err = " + err))
|
||||
} else {
|
||||
socialBot.botInstance.telegramAPI.sendMessage(socialBot.botInstance.chatId, code.text)
|
||||
socialBot.botInstance.telegramAPI.sendMessage(socialBot.botInstance.chatId, code.text).catch(err => parentLogger.write(MODULE_NAME, "[WARN] initialize -> setUpSocialBots -> announce -> Telegram API error -> err = " + err))
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -523,7 +523,7 @@
|
||||
const Telegram = require('telegraf/telegram')
|
||||
let telegramAPI
|
||||
telegramAPI = new Telegram(botToken)
|
||||
telegramAPI.sendMessage(chatId, bot.SESSION.type + " '" + bot.SESSION.name + "' was Started.")
|
||||
telegramAPI.sendMessage(chatId, bot.SESSION.type + " '" + bot.SESSION.name + "' was Started.").catch(err => parentLogger.write(MODULE_NAME, "[WARN] initialize -> setUpTelegramBot -> Telegram API error -> err = " + err))
|
||||
|
||||
let botInstance = {
|
||||
telegramBot: telegramBot,
|
||||
|
||||
+61
-20
@@ -2,40 +2,78 @@
|
||||
|
||||
const FULL_LOG = true;
|
||||
const LOG_FILE_CONTENT = false;
|
||||
|
||||
const MODULE_NAME = "Status Dependencies";
|
||||
|
||||
let bot = BOT
|
||||
|
||||
let thisObject = {
|
||||
config: undefined,
|
||||
nodeArray: undefined,
|
||||
statusReports: new Map(),
|
||||
reportsByMainUtility: new Map(),
|
||||
initialize: initialize,
|
||||
keys: []
|
||||
};
|
||||
|
||||
return thisObject;
|
||||
|
||||
function initialize(pStatusDependenciesConfig, pMonth, pYear, callBackFunction) {
|
||||
function initialize(pMonth, pYear, callBackFunction) {
|
||||
|
||||
try {
|
||||
|
||||
if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] initialize -> Entering function."); }
|
||||
|
||||
thisObject.config = pStatusDependenciesConfig;
|
||||
/* Basic Valdidations */
|
||||
if (bot.processNode.referenceParent.processDependencies !== undefined) {
|
||||
if (bot.processNode.referenceParent.processDependencies.statusDependencies !== undefined) {
|
||||
thisObject.nodeArray = bot.processNode.referenceParent.processDependencies.statusDependencies
|
||||
} else {
|
||||
logger.write(MODULE_NAME, "[ERROR] initialize -> onInitilized -> It is not possible to not have status dependencies at all.");
|
||||
callBackFunction(global.DEFAULT_OK_RESPONSE)
|
||||
return
|
||||
}
|
||||
} else {
|
||||
logger.write(MODULE_NAME, "[ERROR] initialize -> onInitilized -> It is not possible to not have process dependencies, which means not status dependencies.");
|
||||
callBackFunction(global.DEFAULT_FAIL_RESPONSE)
|
||||
return
|
||||
}
|
||||
|
||||
/*
|
||||
/*For each dependency we will initialize the status report, and load it as part of this initialization process.*/
|
||||
|
||||
For each dependency declared at the bot config, we will initialize the status report, and load it as part of this initialization process.
|
||||
|
||||
*/
|
||||
let alreadyCalledBack = false;
|
||||
let loadCount = 0;
|
||||
let dependenciesToProcess = []
|
||||
for (let i = 0; i < thisObject.nodeArray.length; i++) {
|
||||
let statusDependency = {
|
||||
dependency: thisObject.nodeArray[i],
|
||||
month: pMonth,
|
||||
year: pYear
|
||||
}
|
||||
|
||||
dependenciesToProcess.push(statusDependency)
|
||||
|
||||
for (let i = 0; i < pStatusDependenciesConfig.length; i++) {
|
||||
/*
|
||||
For the special case that the statusDependency is a Self Reference AND this process is sliced in different
|
||||
instances for each month, we will add the main self reference status report that is month/year independent.
|
||||
*/
|
||||
|
||||
if (statusDependency.dependency.code.mainUtility === "Self Reference" && pMonth !== undefined && pYear !== undefined) {
|
||||
let mainDependency = {
|
||||
dependency: thisObject.nodeArray[i],
|
||||
month: undefined,
|
||||
year: undefined
|
||||
}
|
||||
|
||||
dependenciesToProcess.push(mainDependency)
|
||||
}
|
||||
}
|
||||
|
||||
for (let i = 0; i < dependenciesToProcess.length; i++) {
|
||||
|
||||
let statusReportModule = STATUS_REPORT.newStatusReport(BOT, logger, UTILITIES);
|
||||
|
||||
logger.write(MODULE_NAME, "[INFO] initialize -> onInitilized -> Initializing Status Report # " + (i + 1));
|
||||
statusReportModule.initialize(pStatusDependenciesConfig[i], pMonth, pYear, onInitilized);
|
||||
let statusDependency = dependenciesToProcess[i]
|
||||
statusReportModule.initialize(statusDependency.dependency, statusDependency.month, statusDependency.year, onInitilized);
|
||||
|
||||
function onInitilized(err) {
|
||||
|
||||
@@ -66,8 +104,7 @@
|
||||
switch (err.message) {
|
||||
case global.DEFAULT_OK_RESPONSE.message: {
|
||||
|
||||
if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] initialize -> onLoad -> Execution finished well. -> bot = " + pStatusDependenciesConfig[i].bot); }
|
||||
if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] initialize -> onLoad -> Execution finished well. -> process = " + pStatusDependenciesConfig[i].process); }
|
||||
if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] initialize -> onLoad -> Execution finished well. -> Status Dependency = " + JSON.stringify(statusDependency.dependency)) }
|
||||
|
||||
addReport();
|
||||
return;
|
||||
@@ -75,8 +112,8 @@
|
||||
case "Status Report was never created.": {
|
||||
|
||||
logger.write(MODULE_NAME, "[WARN] initialize -> onLoad -> err = " + err.stack);
|
||||
logger.write(MODULE_NAME, "[WARN] initialize -> onLoad -> Report Not Found. -> bot = " + pStatusDependenciesConfig[i].bot);
|
||||
logger.write(MODULE_NAME, "[WARN] initialize -> onLoad -> Report Not Found. -> process = " + pStatusDependenciesConfig[i].process);
|
||||
logger.write(MODULE_NAME, "[WARN] initialize -> onLoad -> Report Not Found. -> Status Dependency = " + JSON.stringify(statusDependency.dependency))
|
||||
|
||||
addReport();
|
||||
return;
|
||||
}
|
||||
@@ -84,8 +121,8 @@
|
||||
case "Status Report is corrupt.": {
|
||||
|
||||
logger.write(MODULE_NAME, "[WARN] initialize -> onLoad -> err = " + err.stack);
|
||||
logger.write(MODULE_NAME, "[WARN] initialize -> onLoad -> Report Not Found. -> bot = " + pStatusDependenciesConfig[i].bot);
|
||||
logger.write(MODULE_NAME, "[WARN] initialize -> onLoad -> Report Not Found. -> process = " + pStatusDependenciesConfig[i].process);
|
||||
logger.write(MODULE_NAME, "[WARN] initialize -> onLoad -> Report Not Found. -> Status Dependency = " + JSON.stringify(statusDependency.dependency))
|
||||
|
||||
addReport();
|
||||
return;
|
||||
}
|
||||
@@ -117,18 +154,22 @@
|
||||
|
||||
let key;
|
||||
|
||||
if (pStatusDependenciesConfig[i].dataSetSection === "Month") {
|
||||
key = pStatusDependenciesConfig[i].devTeam + "-" + pStatusDependenciesConfig[i].bot + "-" + pStatusDependenciesConfig[i].process + "-" + pStatusDependenciesConfig[i].dataSetVersion + "-" + pYear + "-" + pMonth;
|
||||
if (statusDependency.dependency.processRunMonthly === true && statusDependency.month !== undefined && statusDependency.year !== undefined) {
|
||||
key = statusDependency.dependency.devTeam + "-" + statusDependency.dependency.bot + "-" + statusDependency.dependency.process + "-" + statusDependency.dependency.dataSetVersion + "-" + statusDependency.year + "-" + statusDependency.month;
|
||||
} else {
|
||||
key = pStatusDependenciesConfig[i].devTeam + "-" + pStatusDependenciesConfig[i].bot + "-" + pStatusDependenciesConfig[i].process + "-" + pStatusDependenciesConfig[i].dataSetVersion;
|
||||
key = statusDependency.dependency.devTeam + "-" + statusDependency.dependency.bot + "-" + statusDependency.dependency.process + "-" + statusDependency.dependency.dataSetVersion;
|
||||
}
|
||||
|
||||
thisObject.keys.push(key);
|
||||
thisObject.statusReports.set(key, statusReportModule);
|
||||
|
||||
if (statusReportModule.mainUtility !== undefined) {
|
||||
thisObject.reportsByMainUtility.set(statusReportModule.mainUtility, statusReportModule)
|
||||
}
|
||||
|
||||
if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] initialize -> addReport -> Report added to Map. -> key = " + key); }
|
||||
|
||||
if (loadCount === pStatusDependenciesConfig.length) {
|
||||
if (loadCount === dependenciesToProcess.length) {
|
||||
if (alreadyCalledBack === false) {
|
||||
alreadyCalledBack = true
|
||||
callBackFunction(global.DEFAULT_OK_RESPONSE);
|
||||
|
||||
+95
-78
@@ -13,6 +13,7 @@
|
||||
let bot = BOT;
|
||||
|
||||
let thisObject = {
|
||||
mainUtility: undefined,
|
||||
file: undefined, // Here we have the JSON object representing the file content.
|
||||
initialize: initialize,
|
||||
load: load,
|
||||
@@ -21,7 +22,7 @@
|
||||
verifyMarketComplete: verifyMarketComplete
|
||||
};
|
||||
|
||||
let owner; // This is the bot owner of the Status Report. Only owners can save the report and override the existing content.
|
||||
let statusDependencyNode;
|
||||
|
||||
/* Utilities needed. */
|
||||
|
||||
@@ -39,63 +40,103 @@
|
||||
|
||||
return thisObject;
|
||||
|
||||
function initialize(pOwner, pMonth, pYear, callBackFunction) {
|
||||
function initialize(pStatusDependencyNode, pMonth, pYear, callBackFunction) {
|
||||
|
||||
try {
|
||||
if (global.LOG_CONTROL[MODULE_NAME].logInfo === true) { logger.write(MODULE_NAME, "[INFO] initialize -> Entering function."); }
|
||||
|
||||
logger.fileName = MODULE_NAME + "." + pOwner.bot + "." + pOwner.process;
|
||||
statusDependencyNode = pStatusDependencyNode;
|
||||
logger.fileName = MODULE_NAME + "." + statusDependencyNode.type + "." + statusDependencyNode.name + "." + statusDependencyNode.id;
|
||||
|
||||
owner = pOwner;
|
||||
month = pMonth;
|
||||
year = pYear;
|
||||
|
||||
if (bot.SESSION !== undefined && pOwner.type === "Trading Engine") {
|
||||
/* Some very basic validations that we have all the information needed. */
|
||||
if (statusDependencyNode.referenceParent === undefined) {
|
||||
logger.write(MODULE_NAME, "[ERROR] initialize -> Status Dependency without Reference Parent. Status Dependency = " + JSON.stringify(statusDependencyNode));
|
||||
callBackFunction(global.DEFAULT_FAIL_RESPONSE);
|
||||
return
|
||||
}
|
||||
|
||||
if (statusDependencyNode.referenceParent.parentNode === undefined) {
|
||||
logger.write(MODULE_NAME, "[ERROR] initialize -> Status Report not attached to a Process Definition. Status Report = " + JSON.stringify(statusDependencyNode.referenceParent));
|
||||
callBackFunction(global.DEFAULT_FAIL_RESPONSE);
|
||||
return
|
||||
}
|
||||
|
||||
if (statusDependencyNode.referenceParent.parentNode.code.codeName === undefined) {
|
||||
logger.write(MODULE_NAME, "[ERROR] initialize -> Process Definition witn no codeName defined. Process Definition = " + JSON.stringify(statusDependencyNode.referenceParent.parentNode));
|
||||
callBackFunction(global.DEFAULT_FAIL_RESPONSE);
|
||||
return
|
||||
}
|
||||
|
||||
if (statusDependencyNode.referenceParent.parentNode.parentNode === undefined) {
|
||||
logger.write(MODULE_NAME, "[ERROR] initialize -> Process Definition not attached to a Bot. Process Definition = " + JSON.stringify(statusDependencyNode.referenceParent.parentNode));
|
||||
callBackFunction(global.DEFAULT_FAIL_RESPONSE);
|
||||
return
|
||||
}
|
||||
|
||||
if (statusDependencyNode.referenceParent.parentNode.parentNode.code.codeName === undefined) {
|
||||
logger.write(MODULE_NAME, "[ERROR] initialize -> Bot witn no codeName defined. Bot = " + JSON.stringify(statusDependencyNode.referenceParent.parentNode.parentNode));
|
||||
callBackFunction(global.DEFAULT_FAIL_RESPONSE);
|
||||
return
|
||||
}
|
||||
|
||||
if (statusDependencyNode.referenceParent.parentNode.parentNode.parentNode === undefined) {
|
||||
logger.write(MODULE_NAME, "[ERROR] initialize -> Bot not attached to a Team. Bot = " + JSON.stringify(statusDependencyNode.referenceParent.parentNode.parentNode));
|
||||
callBackFunction(global.DEFAULT_FAIL_RESPONSE);
|
||||
return
|
||||
}
|
||||
|
||||
if (statusDependencyNode.referenceParent.parentNode.parentNode.parentNode.code.codeName === undefined) {
|
||||
logger.write(MODULE_NAME, "[ERROR] initialize -> Team witn no codeName defined. Team = " + JSON.stringify(statusDependencyNode.referenceParent.parentNode.parentNode.parentNode));
|
||||
callBackFunction(global.DEFAULT_FAIL_RESPONSE);
|
||||
return
|
||||
}
|
||||
|
||||
/* Simplifying the access to basic info */
|
||||
statusDependencyNode.bot = statusDependencyNode.referenceParent.parentNode.parentNode.code.codeName
|
||||
statusDependencyNode.process = statusDependencyNode.referenceParent.parentNode.code.codeName
|
||||
statusDependencyNode.type = statusDependencyNode.referenceParent.parentNode.parentNode.type
|
||||
statusDependencyNode.devTeam = statusDependencyNode.referenceParent.parentNode.parentNode.parentNode.code.codeName
|
||||
|
||||
/* Let's see if the process is run monthly or not. */
|
||||
if (statusDependencyNode.referenceParent.parentNode.code.startMode !== undefined) {
|
||||
if (statusDependencyNode.referenceParent.parentNode.code.startMode.allMonths !== undefined) {
|
||||
if (statusDependencyNode.referenceParent.parentNode.code.startMode.oneMonth !== undefined) {
|
||||
if (statusDependencyNode.referenceParent.parentNode.code.startMode.allMonths.run === "true" || statusDependencyNode.referenceParent.parentNode.code.startMode.oneMonth.run === "true") {
|
||||
statusDependencyNode.processRunMonthly = true
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* We retrieve the report main utility */
|
||||
if (statusDependencyNode.code !== undefined) {
|
||||
if (statusDependencyNode.code.mainUtility !== undefined) {
|
||||
thisObject.mainUtility = statusDependencyNode.code.mainUtility
|
||||
}
|
||||
}
|
||||
|
||||
/* This stuff is still hardcoded and unresolved. */
|
||||
statusDependencyNode.botVersion = {
|
||||
"major": 1,
|
||||
"minor": 0
|
||||
}
|
||||
statusDependencyNode.dataSetVersion = "dataSet.V1"
|
||||
|
||||
|
||||
|
||||
if (bot.SESSION !== undefined && statusDependencyNode.type === "Trading Bot Instance") {
|
||||
sessionPath = bot.SESSION.folderName + "/"
|
||||
}
|
||||
|
||||
if (owner.dataSetSection === "Month") {
|
||||
logger.fileName = MODULE_NAME + "." + pOwner.bot + "." + pOwner.process + "." + year + "." + month;
|
||||
if (statusDependencyNode.processRunMonthly === true && month !== undefined && year !== undefined) {
|
||||
logger.fileName = MODULE_NAME + "." + statusDependencyNode.bot + "." + statusDependencyNode.process + "." + year + "." + month;
|
||||
timePath = "/" + year + "/" + month;
|
||||
}
|
||||
|
||||
if (owner.waitUntilNextUpdate === true) {
|
||||
|
||||
if (global.LOG_CONTROL[MODULE_NAME].logInfo === true) { logger.write(MODULE_NAME, "[INFO] initialize -> waitUntilNextUpdate -> Entering Code Block."); }
|
||||
|
||||
/* This forces this process to wait until the process that this one depends on, updates its status report. */
|
||||
|
||||
let extraCallerId = ''
|
||||
if (pMonth) { extraCallerId = extraCallerId + '-' + pMonth }
|
||||
if (pYear) { extraCallerId = extraCallerId + '-' + pYear }
|
||||
|
||||
let key = owner.devTeam + "-" + owner.bot + "-" + owner.process
|
||||
let callerId = bot.devTeam + "-" + bot.codeName + "-" + bot.process + extraCallerId
|
||||
|
||||
let subscriptionIdStatusReport
|
||||
|
||||
global.SYSTEM_EVENT_HANDLER.listenToEvent(key, 'Status Report Updated', undefined, callerId, responseCallBack, eventsCallBack)
|
||||
|
||||
function responseCallBack(message) {
|
||||
if (message.result !== global.DEFAULT_OK_RESPONSE.result) {
|
||||
logger.write(MODULE_NAME, "[ERROR] initialize -> responseCallBack -> message = " + JSON.stringify(message))
|
||||
callBackFunction(global.DEFAULT_FAIL_RESPONSE);
|
||||
} else {
|
||||
subscriptionIdStatusReport = message.eventSubscriptionId
|
||||
}
|
||||
}
|
||||
|
||||
function eventsCallBack() {
|
||||
if (global.LOG_CONTROL[MODULE_NAME].logInfo === true) { logger.write(MODULE_NAME, "[INFO] initialize -> eventsCallBack -> Entering function."); }
|
||||
|
||||
/* We continue the normal flow after we learn the dependent process has updated its status report. */
|
||||
global.SYSTEM_EVENT_HANDLER.stopListening(key, 'Status Report Updated', subscriptionIdStatusReport)
|
||||
callBackFunction(global.DEFAULT_OK_RESPONSE);
|
||||
}
|
||||
} else {
|
||||
/* In this case, the Status Report does not depends on a process which needs to wait for. */
|
||||
callBackFunction(global.DEFAULT_OK_RESPONSE);
|
||||
}
|
||||
callBackFunction(global.DEFAULT_OK_RESPONSE);
|
||||
|
||||
} catch (err) {
|
||||
logger.write(MODULE_NAME, "[ERROR] initialize -> err = "+ err.stack);
|
||||
@@ -112,23 +153,23 @@
|
||||
let fileName = "Status.Report." + global.MARKET.assetA + '_' + global.MARKET.assetB + ".json";
|
||||
let filePath;
|
||||
|
||||
let ownerId = owner.devTeam + "-" + owner.bot + "-" + owner.botVersion.major + "-" + owner.botVersion.minor + "-" + owner.process + "-" + owner.dataSetVersion;
|
||||
let ownerId = statusDependencyNode.devTeam + "-" + statusDependencyNode.bot + "-" + statusDependencyNode.botVersion.major + "-" + statusDependencyNode.botVersion.minor + "-" + statusDependencyNode.process + "-" + statusDependencyNode.dataSetVersion;
|
||||
let botId = bot.devTeam + "-" + bot.codeName + "-" + bot.version.major + "-" + bot.version.minor + "-" + bot.process + "-" + bot.dataSetVersion;
|
||||
|
||||
if (ownerId !== botId) {
|
||||
let rootPath = owner.devTeam + "/" + owner.bot + "." + owner.botVersion.major + "." + owner.botVersion.minor + "/" + global.CLONE_EXECUTOR.codeName + "." + global.CLONE_EXECUTOR.version + "/" + global.EXCHANGE_NAME + "/" + owner.dataSetVersion;
|
||||
filePath = rootPath + "/Reports/" + sessionPath + owner.process + timePath;
|
||||
let rootPath = statusDependencyNode.devTeam + "/" + statusDependencyNode.bot + "." + statusDependencyNode.botVersion.major + "." + statusDependencyNode.botVersion.minor + "/" + global.CLONE_EXECUTOR.codeName + "." + global.CLONE_EXECUTOR.version + "/" + global.EXCHANGE_NAME + "/" + statusDependencyNode.dataSetVersion;
|
||||
filePath = rootPath + "/Reports/" + sessionPath + statusDependencyNode.process + timePath;
|
||||
} else {
|
||||
filePath = bot.filePathRoot + "/Reports/" + sessionPath + owner.process + timePath;
|
||||
filePath = bot.filePathRoot + "/Reports/" + sessionPath + statusDependencyNode.process + timePath;
|
||||
}
|
||||
|
||||
if (owner.type === 'Trading') {
|
||||
if (statusDependencyNode.type === 'Trading') {
|
||||
fileName = bot.startMode + "." + fileName;
|
||||
}
|
||||
|
||||
filePath += '/' + fileName
|
||||
|
||||
fileStorage.getTextFile(owner.devTeam, filePath, onFileReceived);
|
||||
fileStorage.getTextFile(statusDependencyNode.devTeam, filePath, onFileReceived);
|
||||
|
||||
function onFileReceived(err, text) {
|
||||
|
||||
@@ -196,10 +237,10 @@
|
||||
|
||||
if (global.LOG_CONTROL[MODULE_NAME].logInfo === true) { logger.write(MODULE_NAME, "[INFO] save -> Entering function."); }
|
||||
|
||||
let ownerId = owner.devTeam + "-" + owner.bot + "-" + owner.botVersion.major + "-" + owner.botVersion.minor + "-" + owner.process + "-" + owner.dataSetVersion;
|
||||
let ownerId = statusDependencyNode.devTeam + "-" + statusDependencyNode.bot + "-" + statusDependencyNode.botVersion.major + "-" + statusDependencyNode.botVersion.minor + "-" + statusDependencyNode.process + "-" + statusDependencyNode.dataSetVersion;
|
||||
let botId = bot.devTeam + "-" + bot.codeName + "-" + bot.version.major + "-" + bot.version.minor + "-" + bot.process + "-" + bot.dataSetVersion;
|
||||
|
||||
if (ownerId !== botId && owner.process !== "Context") { // Context is a special case where the report is created by the Context.js module itself.
|
||||
if (ownerId !== botId && statusDependencyNode.process !== "Context") { // Context is a special case where the report is created by the Context.js module itself.
|
||||
|
||||
let customErr = {
|
||||
result: global.CUSTOM_FAIL_RESPONSE.result,
|
||||
@@ -211,7 +252,7 @@
|
||||
}
|
||||
|
||||
let fileName = "Status.Report." + global.MARKET.assetA + '_' + global.MARKET.assetB + ".json";
|
||||
let filePath = bot.filePathRoot + "/Reports/" + sessionPath + owner.process + timePath;
|
||||
let filePath = bot.filePathRoot + "/Reports/" + sessionPath + statusDependencyNode.process + timePath;
|
||||
|
||||
if (bot.type === 'Trading' ) {
|
||||
fileName = bot.startMode + "." + fileName;
|
||||
@@ -220,7 +261,7 @@
|
||||
filePath += '/' + fileName
|
||||
let fileContent = JSON.stringify(thisObject.file);
|
||||
|
||||
fileStorage.createTextFile(owner.devTeam, filePath, fileContent + '\n', onFileCreated);
|
||||
fileStorage.createTextFile(statusDependencyNode.devTeam, filePath, fileContent + '\n', onFileCreated);
|
||||
|
||||
function onFileCreated(err) {
|
||||
|
||||
@@ -236,30 +277,6 @@
|
||||
logger.write(MODULE_NAME, "[INFO] save -> onFileCreated -> Content written = " + fileContent);
|
||||
}
|
||||
|
||||
/* Here we raise the event stating that this status report was updated. */
|
||||
let key = bot.devTeam + "-" + bot.codeName + "-" + bot.process
|
||||
global.SYSTEM_EVENT_HANDLER.raiseEvent(key, 'Status Report Updated')
|
||||
|
||||
/* We will also reaise the events for the datasets impacted by the process that just finished. */
|
||||
for (let j = 0; j < bot.processes.length; j++) {
|
||||
let process = bot.processes[j]
|
||||
if (process.name === bot.process) {
|
||||
let updatesDatasets = process.updatesDatasets
|
||||
if (updatesDatasets !== undefined) {
|
||||
for (let i = 0; i < updatesDatasets.length; i++) {
|
||||
let updatedDataSet = updatesDatasets[i]
|
||||
|
||||
key = bot.devTeam + "-" + bot.codeName + "-" + updatedDataSet.product + "-" + updatedDataSet.dataSet
|
||||
let event = {
|
||||
lastFile: thisObject.file.lastFile
|
||||
}
|
||||
global.SYSTEM_EVENT_HANDLER.raiseEvent(key, 'Dataset Updated', event)
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
callBackFunction(global.DEFAULT_OK_RESPONSE);
|
||||
return;
|
||||
}
|
||||
|
||||
+973
@@ -0,0 +1,973 @@
|
||||
exports.newTradingBot = function newTradingBot(bot, logger, UTILITIES, FILE_STORAGE) {
|
||||
|
||||
const FULL_LOG = true;
|
||||
const LOG_FILE_CONTENT = false;
|
||||
const ONE_DAY_IN_MILISECONDS = 24 * 60 * 60 * 1000;
|
||||
|
||||
const MODULE_NAME = "Trading Bot";
|
||||
|
||||
let thisObject = {
|
||||
initialize: initialize,
|
||||
finalize: finalize,
|
||||
start: start
|
||||
};
|
||||
|
||||
let utilities = UTILITIES.newCloudUtilities(logger);
|
||||
let fileStorage = FILE_STORAGE.newFileStorage(logger);
|
||||
|
||||
const COMMONS = require('./Commons.js');
|
||||
let commons = COMMONS.newCommons(bot, logger, UTILITIES, FILE_STORAGE);
|
||||
|
||||
let assistant;
|
||||
|
||||
return thisObject;
|
||||
|
||||
function finalize() {
|
||||
thisObject = undefined
|
||||
utilities = undefined
|
||||
fileStorage = undefined
|
||||
commons = undefined
|
||||
}
|
||||
|
||||
function initialize(pAssistant, callBackFunction) {
|
||||
|
||||
try {
|
||||
|
||||
logger.fileName = MODULE_NAME;
|
||||
logger.initialize();
|
||||
|
||||
if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] initialize -> Entering function."); }
|
||||
|
||||
assistant = pAssistant;
|
||||
callBackFunction(global.DEFAULT_OK_RESPONSE);
|
||||
|
||||
} catch (err) {
|
||||
logger.write(MODULE_NAME, "[ERROR] initialize -> err = " + err.stack);
|
||||
callBackFunction(global.DEFAULT_FAIL_RESPONSE);
|
||||
}
|
||||
}
|
||||
|
||||
function start(multiPeriodDataFiles, timePeriod, timePeriodLabel, currentDay, interExecutionMemory, callBackFunction) {
|
||||
|
||||
try {
|
||||
|
||||
if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] start -> Entering function."); }
|
||||
|
||||
let chart = {}
|
||||
let mainDependency = {}
|
||||
let processingDailyFiles
|
||||
|
||||
if (currentDay !== undefined) {
|
||||
processingDailyFiles = true
|
||||
} else {
|
||||
processingDailyFiles = false
|
||||
}
|
||||
|
||||
/* The first phase here is about checking that we have everything we need at the definition level. */
|
||||
let dataDependencies = bot.processNode.referenceParent.processDependencies.dataDependencies
|
||||
if (commons.validateDataDependencies(dataDependencies, callBackFunction) !== true) {return}
|
||||
|
||||
let outputDatasets = bot.processNode.referenceParent.processOutput.outputDatasets
|
||||
if (commons.validateOutputDatasets(outputDatasets, callBackFunction) !== true) { return }
|
||||
|
||||
/* The second phase is about transforming the inputs into a format that can be used to apply the user defined code. */
|
||||
for (let j = 0; j < global.marketFilesPeriods.length; j++) {
|
||||
|
||||
let timePeriodLabel = marketFilesPeriods[j][1]
|
||||
let dataFiles = multiPeriodDataFiles.get(timePeriodLabel)
|
||||
let products = {}
|
||||
|
||||
if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] start -> Inflating Data Files for timePeriod = " + timePeriodLabel); }
|
||||
|
||||
if (dataFiles !== undefined) {
|
||||
commons.inflateDatafiles(dataFiles, dataDependencies, products, mainDependency, timePeriod)
|
||||
|
||||
let propertyName = 'at' + timePeriodLabel.replace('-', '');
|
||||
chart[propertyName] = products
|
||||
}
|
||||
}
|
||||
|
||||
for (let j = 0; j < global.dailyFilePeriods.length; j++) {
|
||||
|
||||
let timePeriodLabel = global.dailyFilePeriods[j][1]
|
||||
let dataFiles = multiPeriodDataFiles.get(timePeriodLabel)
|
||||
let products = {}
|
||||
|
||||
if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] start -> Inflating Data Files for timePeriod = " + timePeriodLabel); }
|
||||
|
||||
if (dataFiles !== undefined) {
|
||||
commons.inflateDatafiles(dataFiles, dataDependencies, products, mainDependency, timePeriod)
|
||||
|
||||
let propertyName = 'at' + timePeriodLabel.replace('-', '');
|
||||
chart[propertyName] = products
|
||||
}
|
||||
}
|
||||
|
||||
/* From here we have more or less the same we used to have at JASON */
|
||||
const TRADING_SIMULATION = require('./TradingSimulation.js');
|
||||
let tradingSimulation = TRADING_SIMULATION.newTradingSimulation(bot, logger, UTILITIES);
|
||||
|
||||
let market = global.MARKET;
|
||||
|
||||
const SIMULATED_RECORDS_FOLDER_NAME = "Trading-Simulation";
|
||||
const CONDITIONS_FOLDER_NAME = "Simulation-Conditions";
|
||||
const STRATEGIES_FOLDER_NAME = "Simulation-Strategies";
|
||||
const TRADES_FOLDER_NAME = "Simulation-Trades";
|
||||
|
||||
const ONE_DAY_IN_MILISECONDS = 24 * 60 * 60 * 1000;
|
||||
|
||||
let recordsArray
|
||||
let conditionsArray
|
||||
let strategiesArray
|
||||
let tradesArray
|
||||
|
||||
let tradingSystem = {};
|
||||
|
||||
tradingSimulation.runSimulation(
|
||||
chart,
|
||||
dataDependencies,
|
||||
timePeriod,
|
||||
timePeriodLabel,
|
||||
currentDay,
|
||||
interExecutionMemory,
|
||||
assistant,
|
||||
writeFiles,
|
||||
callBackFunction)
|
||||
|
||||
function writeFiles(pTradingSystem, pRecordsArray, pConditionsArray, pStrategiesArray, pTradesArray) {
|
||||
|
||||
tradingSystem = pTradingSystem
|
||||
recordsArray = pRecordsArray
|
||||
conditionsArray = pConditionsArray
|
||||
strategiesArray = pStrategiesArray
|
||||
tradesArray = pTradesArray
|
||||
|
||||
if (timePeriod > global.dailyFilePeriods[0][0]) {
|
||||
writeMarketFiles()
|
||||
} else {
|
||||
writeDailyFiles()
|
||||
}
|
||||
}
|
||||
|
||||
function writeMarketFiles() {
|
||||
if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] start -> writeDailyFiles -> Entering function."); }
|
||||
|
||||
writeRecordsFile();
|
||||
|
||||
function writeRecordsFile() {
|
||||
|
||||
try {
|
||||
|
||||
if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] start -> writeMarketFiles -> writeRecordsFile -> Entering function."); }
|
||||
|
||||
let separator = "";
|
||||
let fileRecordCounter = 0;
|
||||
|
||||
let fileContent = "";
|
||||
|
||||
for (let i = 0; i < recordsArray.length; i++) {
|
||||
|
||||
let record = recordsArray[i];
|
||||
|
||||
fileContent = fileContent + separator + '[' +
|
||||
record.begin + "," +
|
||||
record.end + "," +
|
||||
record.type + "," +
|
||||
record.marketRate + "," +
|
||||
record.amount + "," +
|
||||
record.balanceA + "," +
|
||||
record.balanceB + "," +
|
||||
record.profit + "," +
|
||||
record.lastTradeProfitLoss + "," +
|
||||
record.stopLoss + "," +
|
||||
record.roundtrips + "," +
|
||||
record.hits + "," +
|
||||
record.fails + "," +
|
||||
record.hitRatio + "," +
|
||||
record.ROI + "," +
|
||||
record.periods + "," +
|
||||
record.days + "," +
|
||||
record.anualizedRateOfReturn + "," +
|
||||
record.positionRate + "," +
|
||||
record.lastTradeROI + "," +
|
||||
record.strategy + "," +
|
||||
record.strategyStageNumber + "," +
|
||||
record.takeProfit + "," +
|
||||
record.stopLossPhase + "," +
|
||||
record.takeProfitPhase + "," +
|
||||
JSON.stringify(record.executionRecord) + "," +
|
||||
record.positionSize + "," +
|
||||
record.initialBalanceA + "," +
|
||||
record.minimumBalanceA + "," +
|
||||
record.maximumBalanceA + "," +
|
||||
record.initialBalanceB + "," +
|
||||
record.minimumBalanceB + "," +
|
||||
record.maximumBalanceB + "," +
|
||||
record.baseAsset + "," +
|
||||
record.positionPeriods + "," +
|
||||
record.positionDays + "," +
|
||||
record.distanceToLastTriggerOn + "," +
|
||||
record.distanceToLastTriggerOff + "," +
|
||||
record.distanceToLastTakePosition + "," +
|
||||
record.distanceToLastClosePosition + "]";
|
||||
|
||||
if (separator === "") { separator = ","; }
|
||||
|
||||
fileRecordCounter++;
|
||||
|
||||
}
|
||||
|
||||
fileContent = "[" + fileContent + "]";
|
||||
|
||||
let fileName = '' + market.assetA + '_' + market.assetB + '.json';
|
||||
|
||||
let filePathRoot = bot.devTeam + "/" + bot.codeName + "." + bot.version.major + "." + bot.version.minor + "/" + global.CLONE_EXECUTOR.codeName + "." + global.CLONE_EXECUTOR.version + "/" + global.EXCHANGE_NAME + "/" + bot.dataSetVersion;
|
||||
let filePath = filePathRoot + "/Output/" + bot.SESSION.folderName + "/" + SIMULATED_RECORDS_FOLDER_NAME + "/" + "Multi-Period-Market" + "/" + timePeriodLabel;
|
||||
filePath += '/' + fileName
|
||||
|
||||
fileStorage.createTextFile(bot.devTeam, filePath, fileContent + '\n', onFileCreated);
|
||||
|
||||
function onFileCreated(err) {
|
||||
|
||||
try {
|
||||
|
||||
if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] start -> writeMarketFiles -> writeRecordsFile -> onFileCreated -> Entering function."); }
|
||||
if (LOG_FILE_CONTENT === true) { logger.write(MODULE_NAME, "[INFO] start -> writeMarketFiles -> writeRecordsFile -> onFileCreated -> fileContent = " + fileContent); }
|
||||
|
||||
if (err.result !== global.DEFAULT_OK_RESPONSE.result) {
|
||||
|
||||
logger.write(MODULE_NAME, "[ERROR] start -> writeMarketFiles -> writeRecordsFile -> onFileCreated -> err = " + err.stack);
|
||||
logger.write(MODULE_NAME, "[ERROR] start -> writeMarketFiles -> writeRecordsFile -> onFileCreated -> filePath = " + filePath);
|
||||
logger.write(MODULE_NAME, "[ERROR] start -> writeMarketFiles -> writeRecordsFile -> onFileCreated -> market = " + market.assetA + "_" + market.assetB);
|
||||
|
||||
callBackFunction(err);
|
||||
return;
|
||||
|
||||
}
|
||||
|
||||
writeConditionsFile();
|
||||
|
||||
}
|
||||
catch (err) {
|
||||
logger.write(MODULE_NAME, "[ERROR] start -> writeMarketFiles -> writeRecordsFile -> onFileCreated -> err = " + err.stack);
|
||||
callBackFunction(global.DEFAULT_FAIL_RESPONSE);
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (err) {
|
||||
logger.write(MODULE_NAME, "[ERROR] start -> writeMarketFiles -> writeRecordsFile -> err = " + err.stack);
|
||||
callBackFunction(global.DEFAULT_FAIL_RESPONSE);
|
||||
}
|
||||
}
|
||||
|
||||
function writeConditionsFile() {
|
||||
|
||||
try {
|
||||
|
||||
if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] start -> writeMarketFiles -> writeConditionsFile -> Entering function."); }
|
||||
|
||||
let separator = "";
|
||||
let fileRecordCounter = 0;
|
||||
|
||||
let fileContent = "";
|
||||
|
||||
for (let i = 0; i < conditionsArray.length; i++) {
|
||||
|
||||
let record = conditionsArray[i];
|
||||
|
||||
let conditions = "";
|
||||
let conditionsSeparator = "";
|
||||
|
||||
for (let j = 0; j < record.length - 3; j++) {
|
||||
conditions = conditions + conditionsSeparator + record[j];
|
||||
if (conditionsSeparator === "") { conditionsSeparator = ","; }
|
||||
}
|
||||
|
||||
conditions = conditions + conditionsSeparator + '[' + record[record.length - 3] + ']'; // The last item contains an Array of condition values.
|
||||
conditions = conditions + conditionsSeparator + '[' + record[record.length - 2] + ']'; // The last item contains an Array of formulaErrors.
|
||||
conditions = conditions + conditionsSeparator + '[' + record[record.length - 1] + ']'; // The last item contains an Array of formulaValues.
|
||||
|
||||
fileContent = fileContent + separator + '[' + conditions + ']';
|
||||
|
||||
if (separator === "") { separator = ","; }
|
||||
|
||||
fileRecordCounter++;
|
||||
|
||||
}
|
||||
|
||||
fileContent = "[" + fileContent + "]";
|
||||
fileContent = "[" + JSON.stringify(tradingSystem) + "," + fileContent + "]";
|
||||
let fileName = '' + market.assetA + '_' + market.assetB + '.json';
|
||||
|
||||
let filePathRoot = bot.devTeam + "/" + bot.codeName + "." + bot.version.major + "." + bot.version.minor + "/" + global.CLONE_EXECUTOR.codeName + "." + global.CLONE_EXECUTOR.version + "/" + global.EXCHANGE_NAME + "/" + bot.dataSetVersion;
|
||||
let filePath = filePathRoot + "/Output/" + bot.SESSION.folderName + "/" + CONDITIONS_FOLDER_NAME + "/" + "Multi-Period-Market" + "/" + timePeriodLabel;
|
||||
filePath += '/' + fileName
|
||||
|
||||
fileStorage.createTextFile(bot.devTeam, filePath, fileContent + '\n', onFileCreated);
|
||||
|
||||
function onFileCreated(err) {
|
||||
|
||||
try {
|
||||
|
||||
if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] start -> writeMarketFiles -> writeConditionsFile -> onFileCreated -> Entering function."); }
|
||||
if (LOG_FILE_CONTENT === true) { logger.write(MODULE_NAME, "[INFO] start -> writeMarketFiles -> writeConditionsFile -> onFileCreated -> fileContent = " + fileContent); }
|
||||
|
||||
if (err.result !== global.DEFAULT_OK_RESPONSE.result) {
|
||||
|
||||
logger.write(MODULE_NAME, "[ERROR] start -> writeMarketFiles -> writeConditionsFile -> onFileCreated -> err = " + err.stack);
|
||||
logger.write(MODULE_NAME, "[ERROR] start -> writeMarketFiles -> writeConditionsFile -> onFileCreated -> filePath = " + filePath);
|
||||
logger.write(MODULE_NAME, "[ERROR] start -> writeMarketFiles -> writeConditionsFile -> onFileCreated -> market = " + market.assetA + "_" + market.assetB);
|
||||
|
||||
callBackFunction(err);
|
||||
return;
|
||||
|
||||
}
|
||||
|
||||
writeStrategiesFile();
|
||||
|
||||
}
|
||||
catch (err) {
|
||||
logger.write(MODULE_NAME, "[ERROR] start -> writeMarketFiles -> writeConditionsFile -> onFileCreated -> err = " + err.stack);
|
||||
callBackFunction(global.DEFAULT_FAIL_RESPONSE);
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (err) {
|
||||
logger.write(MODULE_NAME, "[ERROR] start -> writeMarketFiles -> writeConditionsFile -> err = " + err.stack);
|
||||
callBackFunction(global.DEFAULT_FAIL_RESPONSE);
|
||||
}
|
||||
}
|
||||
|
||||
function writeStrategiesFile() {
|
||||
|
||||
try {
|
||||
|
||||
if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] start -> writeMarketFiles -> writeStrategiesFile -> Entering function."); }
|
||||
|
||||
let separator = "";
|
||||
let fileRecordCounter = 0;
|
||||
|
||||
let fileContent = "";
|
||||
|
||||
for (let i = 0; i < strategiesArray.length; i++) {
|
||||
let record = strategiesArray[i];
|
||||
|
||||
fileContent = fileContent + separator + '[' +
|
||||
record.begin + "," +
|
||||
record.end + "," +
|
||||
record.status + "," +
|
||||
record.number + "," +
|
||||
record.beginRate + "," +
|
||||
record.endRate + "]";
|
||||
|
||||
if (separator === "") { separator = ","; }
|
||||
|
||||
fileRecordCounter++;
|
||||
|
||||
}
|
||||
|
||||
fileContent = "[" + fileContent + "]";
|
||||
let fileName = '' + market.assetA + '_' + market.assetB + '.json';
|
||||
|
||||
let filePathRoot = bot.devTeam + "/" + bot.codeName + "." + bot.version.major + "." + bot.version.minor + "/" + global.CLONE_EXECUTOR.codeName + "." + global.CLONE_EXECUTOR.version + "/" + global.EXCHANGE_NAME + "/" + bot.dataSetVersion;
|
||||
let filePath = filePathRoot + "/Output/" + bot.SESSION.folderName + "/" + STRATEGIES_FOLDER_NAME + "/" + "Multi-Period-Market" + "/" + timePeriodLabel;
|
||||
filePath += '/' + fileName
|
||||
|
||||
fileStorage.createTextFile(bot.devTeam, filePath, fileContent + '\n', onFileCreated);
|
||||
|
||||
function onFileCreated(err) {
|
||||
|
||||
try {
|
||||
|
||||
if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] start -> writeMarketFiles -> writeStrategiesFile -> onFileCreated -> Entering function."); }
|
||||
if (LOG_FILE_CONTENT === true) { logger.write(MODULE_NAME, "[INFO] start -> writeMarketFiles -> writeStrategiesFile -> onFileCreated -> fileContent = " + fileContent); }
|
||||
|
||||
if (err.result !== global.DEFAULT_OK_RESPONSE.result) {
|
||||
|
||||
logger.write(MODULE_NAME, "[ERROR] start -> writeMarketFiles -> writeStrategiesFile -> onFileCreated -> err = " + err.stack);
|
||||
logger.write(MODULE_NAME, "[ERROR] start -> writeMarketFiles -> writeStrategiesFile -> onFileCreated -> filePath = " + filePath);
|
||||
logger.write(MODULE_NAME, "[ERROR] start -> writeMarketFiles -> writeStrategiesFile -> onFileCreated -> market = " + market.assetA + "_" + market.assetB);
|
||||
|
||||
callBackFunction(err);
|
||||
return;
|
||||
|
||||
}
|
||||
|
||||
writeTradesFile();
|
||||
|
||||
}
|
||||
catch (err) {
|
||||
logger.write(MODULE_NAME, "[ERROR] start -> writeMarketFiles -> writeStrategiesFile -> onFileCreated -> err = " + err.stack);
|
||||
callBackFunction(global.DEFAULT_FAIL_RESPONSE);
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (err) {
|
||||
logger.write(MODULE_NAME, "[ERROR] start -> writeMarketFiles -> writeStrategiesFile -> err = " + err.stack);
|
||||
callBackFunction(global.DEFAULT_FAIL_RESPONSE);
|
||||
}
|
||||
}
|
||||
|
||||
function writeTradesFile() {
|
||||
|
||||
try {
|
||||
|
||||
if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] start -> writeMarketFiles -> writeTradesFile -> Entering function."); }
|
||||
|
||||
let separator = "";
|
||||
let fileRecordCounter = 0;
|
||||
|
||||
let fileContent = "";
|
||||
|
||||
for (let i = 0; i < tradesArray.length; i++) {
|
||||
|
||||
let record = tradesArray[i];
|
||||
if (record.stopRate === undefined) { record.stopRate = 0 }
|
||||
|
||||
fileContent = fileContent + separator + '[' +
|
||||
record.begin + "," +
|
||||
record.end + "," +
|
||||
record.status + "," +
|
||||
record.lastTradeROI + "," +
|
||||
record.beginRate + "," +
|
||||
record.endRate + "," +
|
||||
record.exitType + "]";
|
||||
|
||||
if (separator === "") { separator = ","; }
|
||||
|
||||
fileRecordCounter++;
|
||||
|
||||
}
|
||||
|
||||
fileContent = "[" + fileContent + "]";
|
||||
let fileName = '' + market.assetA + '_' + market.assetB + '.json';
|
||||
|
||||
let filePathRoot = bot.devTeam + "/" + bot.codeName + "." + bot.version.major + "." + bot.version.minor + "/" + global.CLONE_EXECUTOR.codeName + "." + global.CLONE_EXECUTOR.version + "/" + global.EXCHANGE_NAME + "/" + bot.dataSetVersion;
|
||||
let filePath = filePathRoot + "/Output/" + bot.SESSION.folderName + "/" + TRADES_FOLDER_NAME + "/" + "Multi-Period-Market" + "/" + timePeriodLabel;
|
||||
filePath += '/' + fileName
|
||||
|
||||
fileStorage.createTextFile(bot.devTeam, filePath, fileContent + '\n', onFileCreated);
|
||||
|
||||
function onFileCreated(err) {
|
||||
|
||||
try {
|
||||
|
||||
if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] start -> writeMarketFiles -> writeTradesFile -> onFileCreated -> Entering function."); }
|
||||
if (LOG_FILE_CONTENT === true) { logger.write(MODULE_NAME, "[INFO] start -> writeMarketFiles -> writeTradesFile -> onFileCreated -> fileContent = " + fileContent); }
|
||||
|
||||
if (err.result !== global.DEFAULT_OK_RESPONSE.result) {
|
||||
|
||||
logger.write(MODULE_NAME, "[ERROR] start -> writeMarketFiles -> writeTradesFile -> onFileCreated -> err = " + err.stack);
|
||||
logger.write(MODULE_NAME, "[ERROR] start -> writeMarketFiles -> writeTradesFile -> onFileCreated -> filePath = " + filePath);
|
||||
logger.write(MODULE_NAME, "[ERROR] start -> writeMarketFiles -> writeTradesFile -> onFileCreated -> market = " + market.assetA + "_" + market.assetB);
|
||||
|
||||
callBackFunction(err);
|
||||
return;
|
||||
|
||||
}
|
||||
|
||||
/* Emit event that signals that simulation files were updated */
|
||||
global.SYSTEM_EVENT_HANDLER.raiseEvent('Jason-Multi-Period', 'Simulation Files Updated')
|
||||
|
||||
callBackFunction(global.DEFAULT_OK_RESPONSE);
|
||||
|
||||
}
|
||||
catch (err) {
|
||||
logger.write(MODULE_NAME, "[ERROR] start -> writeMarketFiles -> writeTradesFile -> onFileCreated -> err = " + err.stack);
|
||||
callBackFunction(global.DEFAULT_FAIL_RESPONSE);
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (err) {
|
||||
logger.write(MODULE_NAME, "[ERROR] start -> writeMarketFiles -> writeTradesFile -> err = " + err.stack);
|
||||
callBackFunction(global.DEFAULT_FAIL_RESPONSE);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
function writeDailyFiles() {
|
||||
if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] start -> writeDailyFiles -> Entering function."); }
|
||||
|
||||
writeRecordsFile();
|
||||
|
||||
/* TODO : NEXT function is a work in progress, not used today */
|
||||
function writeFinalResults() {
|
||||
|
||||
try {
|
||||
|
||||
if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] start -> writeDailyFiles -> writeFinalResults -> Entering function."); }
|
||||
|
||||
if ( // We only write this file if we are at the head of the market.
|
||||
Math.trunc(currentDay.valueOf() / ONE_DAY_IN_MILISECONDS) * ONE_DAY_IN_MILISECONDS
|
||||
!==
|
||||
Math.trunc((new Date()).valueOf() / ONE_DAY_IN_MILISECONDS) * ONE_DAY_IN_MILISECONDS
|
||||
) {
|
||||
writeRecordsFile();
|
||||
return;
|
||||
}
|
||||
|
||||
let separator = "";
|
||||
let fileRecordCounter = 0;
|
||||
|
||||
let fileContent = "";
|
||||
|
||||
for (let i = 0; i < recordsArray.length; i++) {
|
||||
|
||||
let record = recordsArray[i];
|
||||
|
||||
/* Will only add to the file the records of the current day */
|
||||
|
||||
if (record.begin < currentDay.valueOf()) { continue; }
|
||||
|
||||
fileContent = fileContent + separator + '[' +
|
||||
record.begin + "," +
|
||||
record.end + "," +
|
||||
record.type + "," +
|
||||
record.marketRate + "," +
|
||||
record.amount + "," +
|
||||
record.balanceA + "," +
|
||||
record.balanceB + "," +
|
||||
record.profit + "," +
|
||||
record.lastTradeProfitLoss + "," +
|
||||
record.stopLoss + "," +
|
||||
record.roundtrips + "," +
|
||||
record.hits + "," +
|
||||
record.fails + "," +
|
||||
record.hitRatio + "," +
|
||||
record.ROI + "," +
|
||||
record.periods + "," +
|
||||
record.days + "," +
|
||||
record.anualizedRateOfReturn + "," +
|
||||
record.positionRate + "," +
|
||||
record.lastTradeROI + "," +
|
||||
record.strategy + "," +
|
||||
record.strategyStageNumber + "," +
|
||||
record.takeProfit + "," +
|
||||
record.stopLossPhase + "," +
|
||||
record.takeProfitPhase + "," +
|
||||
JSON.stringify(record.executionRecord) + "," +
|
||||
record.positionSize + "," +
|
||||
record.initialBalanceA + "," +
|
||||
record.minimumBalanceA + "," +
|
||||
record.maximumBalanceA + "," +
|
||||
record.initialBalanceB + "," +
|
||||
record.minimumBalanceB + "," +
|
||||
record.maximumBalanceB + "," +
|
||||
record.baseAsset + "," +
|
||||
record.positionPeriods + "," +
|
||||
record.positionDays + "]";
|
||||
|
||||
if (separator === "") { separator = ","; }
|
||||
|
||||
fileRecordCounter++;
|
||||
|
||||
}
|
||||
|
||||
fileContent = "[" + fileContent + "]";
|
||||
|
||||
let fileName = '' + market.assetA + '_' + market.assetB + '.json';
|
||||
|
||||
let filePathRoot = bot.devTeam + "/" + bot.codeName + "." + bot.version.major + "." + bot.version.minor + "/" + global.CLONE_EXECUTOR.codeName + "." + global.CLONE_EXECUTOR.version + "/" + global.EXCHANGE_NAME + "/" + bot.dataSetVersion;
|
||||
let filePath = filePathRoot + "/Output/" + bot.SESSION.folderName + "/" + SIMULATED_RECORDS_FOLDER_NAME + "/" + "Multi-Period-Daily" + "/" + timePeriodLabel;
|
||||
filePath += '/' + fileName
|
||||
|
||||
fileStorage.createTextFile(bot.devTeam, filePath, fileContent + '\n', onFileCreated);
|
||||
|
||||
function onFileCreated(err) {
|
||||
|
||||
try {
|
||||
|
||||
if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] start -> writeDailyFiles -> writeFinalResults -> onFileCreated -> Entering function."); }
|
||||
if (LOG_FILE_CONTENT === true) { logger.write(MODULE_NAME, "[INFO] start -> writeDailyFiles -> writeFinalResults -> onFileCreated -> fileContent = " + fileContent); }
|
||||
|
||||
if (err.result !== global.DEFAULT_OK_RESPONSE.result) {
|
||||
|
||||
logger.write(MODULE_NAME, "[ERROR] start -> writeDailyFiles -> writeFinalResults -> onFileCreated -> err = " + err.stack);
|
||||
logger.write(MODULE_NAME, "[ERROR] start -> writeDailyFiles -> writeFinalResults -> onFileCreated -> filePath = " + filePath);
|
||||
logger.write(MODULE_NAME, "[ERROR] start -> writeDailyFiles -> writeFinalResults -> onFileCreated -> market = " + market.assetA + "_" + market.assetB);
|
||||
|
||||
callBackFunction(err);
|
||||
return;
|
||||
|
||||
}
|
||||
|
||||
writeRecordsFile();
|
||||
|
||||
}
|
||||
catch (err) {
|
||||
logger.write(MODULE_NAME, "[ERROR] start -> writeDailyFiles -> writeFinalResults -> onFileCreated -> err = " + err.stack);
|
||||
callBackFunction(global.DEFAULT_FAIL_RESPONSE);
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (err) {
|
||||
logger.write(MODULE_NAME, "[ERROR] start -> writeDailyFiles -> writeFinalResults -> err = " + err.stack);
|
||||
callBackFunction(global.DEFAULT_FAIL_RESPONSE);
|
||||
}
|
||||
}
|
||||
|
||||
function writeRecordsFile() {
|
||||
|
||||
try {
|
||||
|
||||
if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] start -> writeDailyFiles -> writeRecordsFile -> Entering function."); }
|
||||
|
||||
let separator = "";
|
||||
let fileRecordCounter = 0;
|
||||
|
||||
let fileContent = "";
|
||||
|
||||
for (let i = 0; i < recordsArray.length; i++) {
|
||||
|
||||
let record = recordsArray[i];
|
||||
|
||||
/* Will only add to the file the records of the current day */
|
||||
|
||||
if (record.begin < currentDay.valueOf()) { continue; }
|
||||
|
||||
fileContent = fileContent + separator + '[' +
|
||||
record.begin + "," +
|
||||
record.end + "," +
|
||||
record.type + "," +
|
||||
record.marketRate + "," +
|
||||
record.amount + "," +
|
||||
record.balanceA + "," +
|
||||
record.balanceB + "," +
|
||||
record.profit + "," +
|
||||
record.lastTradeProfitLoss + "," +
|
||||
record.stopLoss + "," +
|
||||
record.roundtrips + "," +
|
||||
record.hits + "," +
|
||||
record.fails + "," +
|
||||
record.hitRatio + "," +
|
||||
record.ROI + "," +
|
||||
record.periods + "," +
|
||||
record.days + "," +
|
||||
record.anualizedRateOfReturn + "," +
|
||||
record.positionRate + "," +
|
||||
record.lastTradeROI + "," +
|
||||
record.strategy + "," +
|
||||
record.strategyStageNumber + "," +
|
||||
record.takeProfit + "," +
|
||||
record.stopLossPhase + "," +
|
||||
record.takeProfitPhase + "," +
|
||||
JSON.stringify(record.executionRecord) + "," +
|
||||
record.positionSize + "," +
|
||||
record.initialBalanceA + "," +
|
||||
record.minimumBalanceA + "," +
|
||||
record.maximumBalanceA + "," +
|
||||
record.initialBalanceB + "," +
|
||||
record.minimumBalanceB + "," +
|
||||
record.maximumBalanceB + "," +
|
||||
record.baseAsset + "," +
|
||||
record.positionPeriods + "," +
|
||||
record.positionDays + "]";
|
||||
|
||||
if (separator === "") { separator = ","; }
|
||||
|
||||
fileRecordCounter++;
|
||||
|
||||
}
|
||||
|
||||
fileContent = "[" + fileContent + "]";
|
||||
|
||||
let dateForPath = currentDay.getUTCFullYear() + '/' + utilities.pad(currentDay.getUTCMonth() + 1, 2) + '/' + utilities.pad(currentDay.getUTCDate(), 2);
|
||||
let fileName = '' + market.assetA + '_' + market.assetB + '.json';
|
||||
|
||||
let filePathRoot = bot.devTeam + "/" + bot.codeName + "." + bot.version.major + "." + bot.version.minor + "/" + global.CLONE_EXECUTOR.codeName + "." + global.CLONE_EXECUTOR.version + "/" + global.EXCHANGE_NAME + "/" + bot.dataSetVersion;
|
||||
let filePath = filePathRoot + "/Output/" + bot.SESSION.folderName + "/" + SIMULATED_RECORDS_FOLDER_NAME + "/" + "Multi-Period-Daily" + "/" + timePeriodLabel + "/" + dateForPath;
|
||||
filePath += '/' + fileName
|
||||
|
||||
fileStorage.createTextFile(bot.devTeam, filePath, fileContent + '\n', onFileCreated);
|
||||
|
||||
function onFileCreated(err) {
|
||||
|
||||
try {
|
||||
|
||||
if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] start -> writeDailyFiles -> writeRecordsFile -> onFileCreated -> Entering function."); }
|
||||
if (LOG_FILE_CONTENT === true) { logger.write(MODULE_NAME, "[INFO] start -> writeDailyFiles -> writeRecordsFile -> onFileCreated -> fileContent = " + fileContent); }
|
||||
|
||||
if (err.result !== global.DEFAULT_OK_RESPONSE.result) {
|
||||
|
||||
logger.write(MODULE_NAME, "[ERROR] start -> writeDailyFiles -> writeRecordsFile -> onFileCreated -> err = " + err.stack);
|
||||
logger.write(MODULE_NAME, "[ERROR] start -> writeDailyFiles -> writeRecordsFile -> onFileCreated -> filePath = " + filePath);
|
||||
logger.write(MODULE_NAME, "[ERROR] start -> writeDailyFiles -> writeRecordsFile -> onFileCreated -> market = " + market.assetA + "_" + market.assetB);
|
||||
|
||||
callBackFunction(err);
|
||||
return;
|
||||
|
||||
}
|
||||
|
||||
writeConditionsFile();
|
||||
|
||||
}
|
||||
catch (err) {
|
||||
logger.write(MODULE_NAME, "[ERROR] start -> writeDailyFiles -> writeRecordsFile -> onFileCreated -> err = " + err.stack);
|
||||
callBackFunction(global.DEFAULT_FAIL_RESPONSE);
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (err) {
|
||||
logger.write(MODULE_NAME, "[ERROR] start -> writeDailyFiles -> writeRecordsFile -> err = " + err.stack);
|
||||
callBackFunction(global.DEFAULT_FAIL_RESPONSE);
|
||||
}
|
||||
}
|
||||
|
||||
function writeConditionsFile() {
|
||||
|
||||
try {
|
||||
|
||||
if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] start -> writeDailyFiles -> writeConditionsFile -> Entering function."); }
|
||||
|
||||
let separator = "";
|
||||
let fileRecordCounter = 0;
|
||||
|
||||
let fileContent = "";
|
||||
|
||||
for (let i = 0; i < conditionsArray.length; i++) {
|
||||
|
||||
let record = conditionsArray[i];
|
||||
|
||||
/* Will only add to the file the records of the current day */
|
||||
|
||||
if (record.begin < currentDay.valueOf()) { continue; }
|
||||
|
||||
let conditions = "";
|
||||
let conditionsSeparator = "";
|
||||
|
||||
/* Will only add to the file the records of the current day */
|
||||
|
||||
if (record.begin < currentDay.valueOf()) { continue; }
|
||||
|
||||
for (let j = 0; j < record.length - 3; j++) {
|
||||
conditions = conditions + conditionsSeparator + record[j];
|
||||
if (conditionsSeparator === "") { conditionsSeparator = ","; }
|
||||
}
|
||||
|
||||
conditions = conditions + conditionsSeparator + '[' + record[record.length - 3] + ']'; // The last item contains an Array of condition values.
|
||||
conditions = conditions + conditionsSeparator + '[' + record[record.length - 2] + ']'; // The last item contains an Array of formulaErrors.
|
||||
conditions = conditions + conditionsSeparator + '[' + record[record.length - 1] + ']'; // The last item contains an Array of formulaValues.
|
||||
|
||||
fileContent = fileContent + separator + '[' + conditions + ']';
|
||||
|
||||
if (separator === "") { separator = ","; }
|
||||
|
||||
fileRecordCounter++;
|
||||
|
||||
}
|
||||
|
||||
fileContent = "[" + fileContent + "]";
|
||||
fileContent = "[" + JSON.stringify(tradingSystem) + "," + fileContent + "]";
|
||||
|
||||
let dateForPath = currentDay.getUTCFullYear() + '/' + utilities.pad(currentDay.getUTCMonth() + 1, 2) + '/' + utilities.pad(currentDay.getUTCDate(), 2);
|
||||
let fileName = '' + market.assetA + '_' + market.assetB + '.json';
|
||||
|
||||
let filePathRoot = bot.devTeam + "/" + bot.codeName + "." + bot.version.major + "." + bot.version.minor + "/" + global.CLONE_EXECUTOR.codeName + "." + global.CLONE_EXECUTOR.version + "/" + global.EXCHANGE_NAME + "/" + bot.dataSetVersion;
|
||||
let filePath = filePathRoot + "/Output/" + bot.SESSION.folderName + "/" + CONDITIONS_FOLDER_NAME + "/" + "Multi-Period-Daily" + "/" + timePeriodLabel + "/" + dateForPath;
|
||||
filePath += '/' + fileName
|
||||
|
||||
fileStorage.createTextFile(bot.devTeam, filePath, fileContent + '\n', onFileCreated);
|
||||
|
||||
function onFileCreated(err) {
|
||||
|
||||
try {
|
||||
|
||||
if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] start -> writeDailyFiles -> writeConditionsFile -> onFileCreated -> Entering function."); }
|
||||
if (LOG_FILE_CONTENT === true) { logger.write(MODULE_NAME, "[INFO] start -> writeDailyFiles -> writeConditionsFile -> onFileCreated -> fileContent = " + fileContent); }
|
||||
|
||||
if (err.result !== global.DEFAULT_OK_RESPONSE.result) {
|
||||
|
||||
logger.write(MODULE_NAME, "[ERROR] start -> writeDailyFiles -> writeConditionsFile -> onFileCreated -> err = " + err.stack);
|
||||
logger.write(MODULE_NAME, "[ERROR] start -> writeDailyFiles -> writeConditionsFile -> onFileCreated -> filePath = " + filePath);
|
||||
logger.write(MODULE_NAME, "[ERROR] start -> writeDailyFiles -> writeConditionsFile -> onFileCreated -> market = " + market.assetA + "_" + market.assetB);
|
||||
|
||||
callBackFunction(err);
|
||||
return;
|
||||
|
||||
}
|
||||
|
||||
writeStrategiesFile();
|
||||
|
||||
}
|
||||
catch (err) {
|
||||
logger.write(MODULE_NAME, "[ERROR] start -> writeDailyFiles -> writeConditionsFile -> onFileCreated -> err = " + err.stack);
|
||||
callBackFunction(global.DEFAULT_FAIL_RESPONSE);
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (err) {
|
||||
logger.write(MODULE_NAME, "[ERROR] start -> writeDailyFiles -> writeConditionsFile -> err = " + err.stack);
|
||||
callBackFunction(global.DEFAULT_FAIL_RESPONSE);
|
||||
}
|
||||
}
|
||||
|
||||
function writeStrategiesFile() {
|
||||
|
||||
try {
|
||||
|
||||
if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] start -> writeDailyFiles -> writeStrategiesFile -> Entering function."); }
|
||||
|
||||
let separator = "";
|
||||
let fileRecordCounter = 0;
|
||||
|
||||
let fileContent = "";
|
||||
|
||||
for (let i = 0; i < strategiesArray.length; i++) {
|
||||
let record = strategiesArray[i];
|
||||
|
||||
/* Will only add to the file the records of the current day. In this case since objects can span more than one day, we add all of the objects that ends
|
||||
at the current date. */
|
||||
|
||||
if (record.end < currentDay.valueOf()) { continue; }
|
||||
|
||||
fileContent = fileContent + separator + '[' +
|
||||
record.begin + "," +
|
||||
record.end + "," +
|
||||
record.status + "," +
|
||||
record.number + "," +
|
||||
record.beginRate + "," +
|
||||
record.endRate + "]";
|
||||
|
||||
if (separator === "") { separator = ","; }
|
||||
|
||||
fileRecordCounter++;
|
||||
|
||||
}
|
||||
|
||||
fileContent = "[" + fileContent + "]";
|
||||
|
||||
let dateForPath = currentDay.getUTCFullYear() + '/' + utilities.pad(currentDay.getUTCMonth() + 1, 2) + '/' + utilities.pad(currentDay.getUTCDate(), 2);
|
||||
let fileName = '' + market.assetA + '_' + market.assetB + '.json';
|
||||
|
||||
let filePathRoot = bot.devTeam + "/" + bot.codeName + "." + bot.version.major + "." + bot.version.minor + "/" + global.CLONE_EXECUTOR.codeName + "." + global.CLONE_EXECUTOR.version + "/" + global.EXCHANGE_NAME + "/" + bot.dataSetVersion;
|
||||
let filePath = filePathRoot + "/Output/" + bot.SESSION.folderName + "/" + STRATEGIES_FOLDER_NAME + "/" + "Multi-Period-Daily" + "/" + timePeriodLabel + "/" + dateForPath;
|
||||
filePath += '/' + fileName
|
||||
|
||||
fileStorage.createTextFile(bot.devTeam, filePath, fileContent + '\n', onFileCreated);
|
||||
|
||||
function onFileCreated(err) {
|
||||
|
||||
try {
|
||||
|
||||
if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] start -> writeDailyFiles -> writeStrategiesFile -> onFileCreated -> Entering function."); }
|
||||
if (LOG_FILE_CONTENT === true) { logger.write(MODULE_NAME, "[INFO] start -> writeDailyFiles -> writeStrategiesFile -> onFileCreated -> fileContent = " + fileContent); }
|
||||
|
||||
if (err.result !== global.DEFAULT_OK_RESPONSE.result) {
|
||||
|
||||
logger.write(MODULE_NAME, "[ERROR] start -> writeDailyFiles -> writeStrategiesFile -> onFileCreated -> err = " + err.stack);
|
||||
logger.write(MODULE_NAME, "[ERROR] start -> writeDailyFiles -> writeStrategiesFile -> onFileCreated -> filePath = " + filePath);
|
||||
logger.write(MODULE_NAME, "[ERROR] start -> writeDailyFiles -> writeStrategiesFile -> onFileCreated -> market = " + market.assetA + "_" + market.assetB);
|
||||
|
||||
callBackFunction(err);
|
||||
return;
|
||||
|
||||
}
|
||||
|
||||
writeTradesFile();
|
||||
|
||||
}
|
||||
catch (err) {
|
||||
logger.write(MODULE_NAME, "[ERROR] start -> writeDailyFiles -> writeStrategiesFile -> onFileCreated -> err = " + err.stack);
|
||||
callBackFunction(global.DEFAULT_FAIL_RESPONSE);
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (err) {
|
||||
logger.write(MODULE_NAME, "[ERROR] start -> writeDailyFiles -> writeStrategiesFile -> err = " + err.stack);
|
||||
callBackFunction(global.DEFAULT_FAIL_RESPONSE);
|
||||
}
|
||||
}
|
||||
|
||||
function writeTradesFile() {
|
||||
|
||||
try {
|
||||
|
||||
if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] start -> writeDailyFiles -> writeTradesFile -> Entering function."); }
|
||||
|
||||
let separator = "";
|
||||
let fileRecordCounter = 0;
|
||||
|
||||
let fileContent = "";
|
||||
|
||||
for (let i = 0; i < tradesArray.length; i++) {
|
||||
|
||||
let record = tradesArray[i];
|
||||
|
||||
/* Will only add to the file the records of the current day. In this case since objects can span more than one day, we add all of the objects that ends
|
||||
at the current date. */
|
||||
|
||||
if (record.end < currentDay.valueOf()) { continue; }
|
||||
if (record.stopRate === undefined) { record.stopRate = 0 }
|
||||
|
||||
fileContent = fileContent + separator + '[' +
|
||||
record.begin + "," +
|
||||
record.end + "," +
|
||||
record.status + "," +
|
||||
record.lastTradeROI + "," +
|
||||
record.beginRate + "," +
|
||||
record.endRate + "," +
|
||||
record.exitType + "]";
|
||||
|
||||
if (separator === "") { separator = ","; }
|
||||
|
||||
fileRecordCounter++;
|
||||
|
||||
}
|
||||
|
||||
fileContent = "[" + fileContent + "]";
|
||||
|
||||
let dateForPath = currentDay.getUTCFullYear() + '/' + utilities.pad(currentDay.getUTCMonth() + 1, 2) + '/' + utilities.pad(currentDay.getUTCDate(), 2);
|
||||
let fileName = '' + market.assetA + '_' + market.assetB + '.json';
|
||||
|
||||
let filePathRoot = bot.devTeam + "/" + bot.codeName + "." + bot.version.major + "." + bot.version.minor + "/" + global.CLONE_EXECUTOR.codeName + "." + global.CLONE_EXECUTOR.version + "/" + global.EXCHANGE_NAME + "/" + bot.dataSetVersion;
|
||||
let filePath = filePathRoot + "/Output/" + bot.SESSION.folderName + "/" + TRADES_FOLDER_NAME + "/" + "Multi-Period-Daily" + "/" + timePeriodLabel + "/" + dateForPath;
|
||||
filePath += '/' + fileName
|
||||
|
||||
fileStorage.createTextFile(bot.devTeam, filePath, fileContent + '\n', onFileCreated);
|
||||
|
||||
function onFileCreated(err) {
|
||||
|
||||
try {
|
||||
|
||||
if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] start -> writeDailyFiles -> writeTradesFile -> onFileCreated -> Entering function."); }
|
||||
if (LOG_FILE_CONTENT === true) { logger.write(MODULE_NAME, "[INFO] start -> writeDailyFiles -> writeTradesFile -> onFileCreated -> fileContent = " + fileContent); }
|
||||
|
||||
if (err.result !== global.DEFAULT_OK_RESPONSE.result) {
|
||||
|
||||
logger.write(MODULE_NAME, "[ERROR] start -> writeDailyFiles -> writeTradesFile -> onFileCreated -> err = " + err.stack);
|
||||
logger.write(MODULE_NAME, "[ERROR] start -> writeDailyFiles -> writeTradesFile -> onFileCreated -> filePath = " + filePath);
|
||||
logger.write(MODULE_NAME, "[ERROR] start -> writeDailyFiles -> writeTradesFile -> onFileCreated -> market = " + market.assetA + "_" + market.assetB);
|
||||
|
||||
callBackFunction(err);
|
||||
return;
|
||||
|
||||
}
|
||||
|
||||
/* Emit event that signals that simulation files were updated */
|
||||
global.SYSTEM_EVENT_HANDLER.raiseEvent('Jason-Multi-Period', 'Simulation Files Updated')
|
||||
|
||||
callBackFunction(global.DEFAULT_OK_RESPONSE);
|
||||
|
||||
}
|
||||
catch (err) {
|
||||
logger.write(MODULE_NAME, "[ERROR] start -> writeDailyFiles -> writeTradesFile -> onFileCreated -> err = " + err.stack);
|
||||
callBackFunction(global.DEFAULT_FAIL_RESPONSE);
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (err) {
|
||||
logger.write(MODULE_NAME, "[ERROR] start -> writeDailyFiles -> writeTradesFile -> err = " + err.stack);
|
||||
callBackFunction(global.DEFAULT_FAIL_RESPONSE);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
catch (err) {
|
||||
logger.write(MODULE_NAME, "[ERROR] start -> err = " + err.stack);
|
||||
callBackFunction(global.DEFAULT_FAIL_RESPONSE);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
exports.newTradingEngineProcessMainLoop = function newTradingEngineProcessMainLoop(bot, parentLogger) {
|
||||
exports.newTradingBotProcessMainLoop = function newTradingBotProcessMainLoop(bot, parentLogger) {
|
||||
|
||||
const ROOT_DIR = './';
|
||||
|
||||
const MODULE_NAME = "Trading Engine Process Main Loop";
|
||||
const MODULE_NAME = "Trading Process Main Loop";
|
||||
const FULL_LOG = true;
|
||||
|
||||
let USER_BOT_MODULE;
|
||||
let COMMONS_MODULE;
|
||||
let USER_BOT_COMMONS;
|
||||
|
||||
const MULTI_PERIOD_MARKET = require(ROOT_DIR + 'MultiPeriodMarket');
|
||||
const MULTI_PERIOD_DAILY = require(ROOT_DIR + 'MultiPeriodDaily');
|
||||
@@ -40,9 +40,20 @@
|
||||
if (FULL_LOG === true) { parentLogger.write(MODULE_NAME, "[INFO] initialize -> Entering function."); }
|
||||
|
||||
processConfig = pProcessConfig;
|
||||
|
||||
if (bot.definedByUI === true) {
|
||||
/* The code of the bot is defined at the UI. No need to load a file with the code. */
|
||||
session.initialize(onSessionInitialized)
|
||||
|
||||
function onSessionInitialized(err) {
|
||||
callBackFunction(err);
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
bot.resumeExecution = processConfig.framework.startDate.resumeExecution // We are inherating this from root, but from here we need it at bot
|
||||
|
||||
let filePath = bot.devTeam + "/" + "bots" + "/" + bot.repo + "/" + pProcessConfig.name
|
||||
let filePath = bot.devTeam + "/" + "bots" + "/" + bot.repo + "/" + pProcessConfig.codeName
|
||||
filePath += "/User.Bot.js"
|
||||
|
||||
fileStorage.getTextFile(bot.devTeam, filePath, onBotDownloaded);
|
||||
@@ -52,6 +63,7 @@
|
||||
if (err.result !== global.DEFAULT_OK_RESPONSE.result) {
|
||||
|
||||
parentLogger.write(MODULE_NAME, "[ERROR] initialize -> onInizialized -> onBotDownloaded -> err = " + err.message);
|
||||
parentLogger.write(MODULE_NAME, "[ERROR] initialize -> onInizialized -> onBotDownloaded -> filePath = " + filePath);
|
||||
callBackFunction(global.DEFAULT_FAIL_RESPONSE);
|
||||
return;
|
||||
}
|
||||
@@ -73,9 +85,9 @@
|
||||
return;
|
||||
}
|
||||
|
||||
COMMONS_MODULE = {}
|
||||
//COMMONS_MODULE.newCommons = require(process.env.BOTS_PATH + '/aamasters/AAMasters/bots/AAJason-Trading-Engine-Bot/Commons').newCommons // Use this for a better debugging experience. You need to bring this js module to this folder in order to work.
|
||||
COMMONS_MODULE.newCommons = eval(text); // Use this for production
|
||||
USER_BOT_COMMONS = {}
|
||||
//USER_BOT_COMMONS.newCommons = require(process.env.BOTS_PATH + '/aamasters/AAMasters/bots/AAJason-Trading-Engine-Bot/Commons').newCommons // Use this for a better debugging experience. You need to bring this js module to this folder in order to work.
|
||||
USER_BOT_COMMONS.newCommons = eval(text); // Use this for production
|
||||
|
||||
session.initialize(onSessionInitialized)
|
||||
|
||||
@@ -140,6 +152,8 @@
|
||||
const STATUS_DEPENDENCIES = require(ROOT_DIR + 'StatusDependencies');
|
||||
const DATA_DEPENDENCIES = require(ROOT_DIR + 'DataDependencies');
|
||||
const DATA_SET = require(ROOT_DIR + 'DataSet');
|
||||
const PROCESS_EXECUTION_EVENTS = require(ROOT_DIR + 'ProcessExecutionEvents');
|
||||
const PROCESS_OUTPUT = require(ROOT_DIR + 'ProcessOutput');
|
||||
|
||||
/* We define the datetime for the process that we are running now. This will be the official processing time for both the infraestructure and the bot. */
|
||||
|
||||
@@ -177,12 +191,162 @@
|
||||
|
||||
/* We will prepare first the infraestructure needed for the bot to run. There are 3 modules we need to sucessfullly initialize first. */
|
||||
|
||||
let processOutput
|
||||
let processExecutionEvents
|
||||
let userBot;
|
||||
let processFramework;
|
||||
let statusDependencies;
|
||||
let dataDependencies;
|
||||
|
||||
initializeStatusDependencies();
|
||||
initializeProcessExecutionEvents();
|
||||
|
||||
function initializeProcessExecutionEvents() {
|
||||
|
||||
try {
|
||||
|
||||
if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] run -> loop -> initializeProcessExecutionEvents -> Entering function."); }
|
||||
|
||||
processExecutionEvents = PROCESS_EXECUTION_EVENTS.newProcessExecutionEvents(bot, logger)
|
||||
|
||||
processExecutionEvents.initialize(undefined, undefined, onInizialized);
|
||||
|
||||
function onInizialized(err) {
|
||||
|
||||
try {
|
||||
|
||||
if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] run -> loop -> initializeProcessExecutionEvents -> onInizialized -> Entering function."); }
|
||||
|
||||
switch (err.result) {
|
||||
case global.DEFAULT_OK_RESPONSE.result: {
|
||||
logger.write(MODULE_NAME, "[INFO] run -> loop -> initializeProcessExecutionEvents -> onInizialized -> Execution finished well.");
|
||||
startProcessExecutionEvents()
|
||||
return;
|
||||
}
|
||||
case global.DEFAULT_RETRY_RESPONSE.result: { // Something bad happened, but if we retry in a while it might go through the next time.
|
||||
logger.write(MODULE_NAME, "[WARN] run -> loop -> initializeProcessExecutionEvents -> onInizialized -> Retry Later. Requesting Execution Retry.");
|
||||
nextWaitTime = 'Retry';
|
||||
loopControl(nextWaitTime);
|
||||
return;
|
||||
}
|
||||
case global.DEFAULT_FAIL_RESPONSE.result: { // This is an unexpected exception that we do not know how to handle.
|
||||
processStopped()
|
||||
logger.write(MODULE_NAME, "[ERROR] run -> loop -> initializeProcessExecutionEvents -> onInizialized -> Operation Failed. Aborting the process.");
|
||||
logger.persist();
|
||||
clearInterval(fixedTimeLoopIntervalHandle);
|
||||
clearTimeout(nextLoopTimeoutHandle);
|
||||
clearTimeout(checkLoopHealthHandle);
|
||||
bot.enableCheckLoopHealth = false;
|
||||
callBackFunction(err);
|
||||
return;
|
||||
}
|
||||
default: {
|
||||
logger.write(MODULE_NAME, "[ERROR] run -> loop -> initializeProcessExecutionEvents -> onInizialized -> Unhandled err.result received. -> err.result = " + err.result);
|
||||
logger.write(MODULE_NAME, "[ERROR] run -> loop -> initializeProcessExecutionEvents -> onInizialized -> Unhandled err.result received. -> err = " + err.message);
|
||||
|
||||
logger.persist();
|
||||
clearInterval(fixedTimeLoopIntervalHandle);
|
||||
clearTimeout(nextLoopTimeoutHandle);
|
||||
clearTimeout(checkLoopHealthHandle);
|
||||
bot.enableCheckLoopHealth = false;
|
||||
callBackFunction(global.DEFAULT_FAIL_RESPONSE);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
} catch (err) {
|
||||
logger.write(MODULE_NAME, "[ERROR] run -> loop -> initializeProcessExecutionEvents -> onInizialized -> err = " + err.stack);
|
||||
logger.persist();
|
||||
clearInterval(fixedTimeLoopIntervalHandle);
|
||||
clearTimeout(nextLoopTimeoutHandle);
|
||||
clearTimeout(checkLoopHealthHandle);
|
||||
bot.enableCheckLoopHealth = false;
|
||||
callBackFunction(err);
|
||||
}
|
||||
}
|
||||
|
||||
} catch (err) {
|
||||
logger.write(MODULE_NAME, "[ERROR] run -> loop -> initializeProcessExecutionEvents -> err = " + err.stack);
|
||||
logger.persist();
|
||||
clearInterval(fixedTimeLoopIntervalHandle);
|
||||
clearTimeout(nextLoopTimeoutHandle);
|
||||
clearTimeout(checkLoopHealthHandle);
|
||||
bot.enableCheckLoopHealth = false;
|
||||
callBackFunction(err);
|
||||
}
|
||||
}
|
||||
|
||||
function startProcessExecutionEvents() {
|
||||
|
||||
try {
|
||||
|
||||
if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] run -> loop -> startProcessExecutionEvents -> Entering function."); }
|
||||
|
||||
processExecutionEvents.start(onStarted);
|
||||
|
||||
function onStarted(err) {
|
||||
|
||||
try {
|
||||
|
||||
if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] run -> loop -> startProcessExecutionEvents -> onStarted -> Entering function."); }
|
||||
|
||||
switch (err.result) {
|
||||
case global.DEFAULT_OK_RESPONSE.result: {
|
||||
logger.write(MODULE_NAME, "[INFO] run -> loop -> startProcessExecutionEvents -> onStarted -> Execution finished well.");
|
||||
initializeStatusDependencies();
|
||||
return;
|
||||
}
|
||||
case global.DEFAULT_RETRY_RESPONSE.result: { // Something bad happened, but if we retry in a while it might go through the next time.
|
||||
logger.write(MODULE_NAME, "[WARN] run -> loop -> startProcessExecutionEvents -> onStarted -> Retry Later. Requesting Execution Retry.");
|
||||
nextWaitTime = 'Retry';
|
||||
loopControl(nextWaitTime);
|
||||
return;
|
||||
}
|
||||
case global.DEFAULT_FAIL_RESPONSE.result: { // This is an unexpected exception that we do not know how to handle.
|
||||
processStopped()
|
||||
logger.write(MODULE_NAME, "[ERROR] run -> loop -> startProcessExecutionEvents -> onStarted -> Operation Failed. Aborting the process.");
|
||||
logger.persist();
|
||||
clearInterval(fixedTimeLoopIntervalHandle);
|
||||
clearTimeout(nextLoopTimeoutHandle);
|
||||
clearTimeout(checkLoopHealthHandle);
|
||||
bot.enableCheckLoopHealth = false;
|
||||
callBackFunction(err);
|
||||
return;
|
||||
}
|
||||
default: {
|
||||
logger.write(MODULE_NAME, "[ERROR] run -> loop -> startProcessExecutionEvents -> onStarted -> Unhandled err.result received. -> err.result = " + err.result);
|
||||
logger.write(MODULE_NAME, "[ERROR] run -> loop -> startProcessExecutionEvents -> onStarted -> Unhandled err.result received. -> err = " + err.message);
|
||||
|
||||
logger.persist();
|
||||
clearInterval(fixedTimeLoopIntervalHandle);
|
||||
clearTimeout(nextLoopTimeoutHandle);
|
||||
clearTimeout(checkLoopHealthHandle);
|
||||
bot.enableCheckLoopHealth = false;
|
||||
callBackFunction(global.DEFAULT_FAIL_RESPONSE);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
} catch (err) {
|
||||
logger.write(MODULE_NAME, "[ERROR] run -> loop -> startProcessExecutionEvents -> onStarted -> err = " + err.stack);
|
||||
logger.persist();
|
||||
clearInterval(fixedTimeLoopIntervalHandle);
|
||||
clearTimeout(nextLoopTimeoutHandle);
|
||||
clearTimeout(checkLoopHealthHandle);
|
||||
bot.enableCheckLoopHealth = false;
|
||||
callBackFunction(err);
|
||||
}
|
||||
}
|
||||
|
||||
} catch (err) {
|
||||
logger.write(MODULE_NAME, "[ERROR] run -> loop -> startProcessExecutionEvents -> err = " + err.stack);
|
||||
logger.persist();
|
||||
clearInterval(fixedTimeLoopIntervalHandle);
|
||||
clearTimeout(nextLoopTimeoutHandle);
|
||||
clearTimeout(checkLoopHealthHandle);
|
||||
bot.enableCheckLoopHealth = false;
|
||||
callBackFunction(err);
|
||||
}
|
||||
}
|
||||
|
||||
function initializeStatusDependencies() {
|
||||
|
||||
@@ -192,7 +356,7 @@
|
||||
|
||||
statusDependencies = STATUS_DEPENDENCIES.newStatusDependencies(bot, logger, STATUS_REPORT, UTILITIES);
|
||||
|
||||
statusDependencies.initialize(processConfig.statusDependencies, undefined, undefined, onInizialized);
|
||||
statusDependencies.initialize(undefined, undefined, onInizialized);
|
||||
|
||||
function onInizialized(err) {
|
||||
|
||||
@@ -268,7 +432,7 @@
|
||||
|
||||
dataDependencies = DATA_DEPENDENCIES.newDataDependencies(bot, logger, DATA_SET);
|
||||
|
||||
dataDependencies.initialize(processConfig.dataDependencies, onInizialized);
|
||||
dataDependencies.initialize(onInizialized);
|
||||
|
||||
function onInizialized(err) {
|
||||
|
||||
@@ -513,18 +677,8 @@
|
||||
}
|
||||
|
||||
switch (processConfig.framework.name) {
|
||||
case 'Multi-Period-Market': {
|
||||
processFramework = MULTI_PERIOD_MARKET.newMultiPeriodMarket(bot, logger, COMMONS_MODULE, UTILITIES, USER_BOT_MODULE, COMMONS_MODULE);
|
||||
intitializeProcessFramework();
|
||||
break;
|
||||
}
|
||||
case 'Multi-Period-Daily': {
|
||||
processFramework = MULTI_PERIOD_DAILY.newMultiPeriodDaily(bot, logger, COMMONS_MODULE, UTILITIES, USER_BOT_MODULE, COMMONS_MODULE);
|
||||
intitializeProcessFramework();
|
||||
break;
|
||||
}
|
||||
case 'Multi-Period': {
|
||||
processFramework = MULTI_PERIOD.newMultiPeriod(bot, logger, COMMONS_MODULE, UTILITIES, USER_BOT_MODULE, COMMONS_MODULE);
|
||||
processFramework = MULTI_PERIOD.newMultiPeriod(bot, logger, UTILITIES, USER_BOT_MODULE, USER_BOT_COMMONS);
|
||||
intitializeProcessFramework();
|
||||
break;
|
||||
}
|
||||
@@ -848,8 +1002,7 @@
|
||||
switch (err.result) {
|
||||
case global.DEFAULT_OK_RESPONSE.result: {
|
||||
if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] run -> loop -> saveContext -> onFinished -> Execution finished well."); }
|
||||
nextWaitTime = 'Normal';
|
||||
loopControl(nextWaitTime);
|
||||
raiseEventsProcessOutput()
|
||||
return;
|
||||
}
|
||||
case global.DEFAULT_RETRY_RESPONSE.result: { // Something bad happened, but if we retry in a while it might go through the next time.
|
||||
@@ -910,6 +1063,155 @@
|
||||
}
|
||||
}
|
||||
|
||||
function raiseEventsProcessOutput() {
|
||||
|
||||
try {
|
||||
|
||||
if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] run -> loop -> raiseEventsProcessOutput -> Entering function."); }
|
||||
|
||||
processOutput = PROCESS_OUTPUT.newProcessOutput(bot, logger)
|
||||
|
||||
processOutput.raiseEvents(statusDependencies, onFinished);
|
||||
|
||||
function onFinished(err) {
|
||||
|
||||
try {
|
||||
|
||||
if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] run -> loop -> raiseEventsProcessOutput -> onFinished -> Entering function."); }
|
||||
|
||||
switch (err.result) {
|
||||
case global.DEFAULT_OK_RESPONSE.result: {
|
||||
logger.write(MODULE_NAME, "[INFO] run -> loop -> raiseEventsProcessOutput -> onFinished -> Execution finished well.");
|
||||
finishProcessExecutionEvents()
|
||||
return;
|
||||
}
|
||||
case global.DEFAULT_RETRY_RESPONSE.result: { // Something bad happened, but if we retry in a while it might go through the next time.
|
||||
logger.write(MODULE_NAME, "[WARN] run -> loop -> raiseEventsProcessOutput -> onFinished -> Retry Later. Requesting Execution Retry.");
|
||||
nextWaitTime = 'Retry';
|
||||
loopControl(nextWaitTime);
|
||||
return;
|
||||
}
|
||||
case global.DEFAULT_FAIL_RESPONSE.result: { // This is an unexpected exception that we do not know how to handle.
|
||||
processStopped()
|
||||
logger.write(MODULE_NAME, "[ERROR] run -> loop -> raiseEventsProcessOutput -> onFinished -> Operation Failed. Aborting the process.");
|
||||
logger.persist();
|
||||
clearInterval(fixedTimeLoopIntervalHandle);
|
||||
clearTimeout(nextLoopTimeoutHandle);
|
||||
clearTimeout(checkLoopHealthHandle);
|
||||
bot.enableCheckLoopHealth = false;
|
||||
callBackFunction(err);
|
||||
return;
|
||||
}
|
||||
default: {
|
||||
logger.write(MODULE_NAME, "[ERROR] run -> loop -> raiseEventsProcessOutput -> onFinished -> Unhandled err.result received. -> err.result = " + err.result);
|
||||
logger.write(MODULE_NAME, "[ERROR] run -> loop -> raiseEventsProcessOutput -> onFinished -> Unhandled err.result received. -> err = " + err.message);
|
||||
|
||||
logger.persist();
|
||||
clearInterval(fixedTimeLoopIntervalHandle);
|
||||
clearTimeout(nextLoopTimeoutHandle);
|
||||
clearTimeout(checkLoopHealthHandle);
|
||||
bot.enableCheckLoopHealth = false;
|
||||
callBackFunction(global.DEFAULT_FAIL_RESPONSE);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
} catch (err) {
|
||||
logger.write(MODULE_NAME, "[ERROR] run -> loop -> raiseEventsProcessOutput -> onFinished -> err = " + err.stack);
|
||||
logger.persist();
|
||||
clearInterval(fixedTimeLoopIntervalHandle);
|
||||
clearTimeout(nextLoopTimeoutHandle);
|
||||
clearTimeout(checkLoopHealthHandle);
|
||||
bot.enableCheckLoopHealth = false;
|
||||
callBackFunction(err);
|
||||
}
|
||||
}
|
||||
|
||||
} catch (err) {
|
||||
logger.write(MODULE_NAME, "[ERROR] run -> loop -> raiseEventsProcessOutput -> err = " + err.stack);
|
||||
logger.persist();
|
||||
clearInterval(fixedTimeLoopIntervalHandle);
|
||||
clearTimeout(nextLoopTimeoutHandle);
|
||||
clearTimeout(checkLoopHealthHandle);
|
||||
bot.enableCheckLoopHealth = false;
|
||||
callBackFunction(err);
|
||||
}
|
||||
}
|
||||
|
||||
function finishProcessExecutionEvents() {
|
||||
|
||||
try {
|
||||
|
||||
if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] run -> loop -> finishProcessExecutionEvents -> Entering function."); }
|
||||
|
||||
processExecutionEvents.finish(onFinished);
|
||||
|
||||
function onFinished(err) {
|
||||
|
||||
try {
|
||||
|
||||
if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] run -> loop -> finishProcessExecutionEvents -> onFinished -> Entering function."); }
|
||||
|
||||
switch (err.result) {
|
||||
case global.DEFAULT_OK_RESPONSE.result: {
|
||||
logger.write(MODULE_NAME, "[INFO] run -> loop -> finishProcessExecutionEvents -> onFinished -> Execution finished well.");
|
||||
nextWaitTime = 'Normal';
|
||||
loopControl(nextWaitTime);
|
||||
return;
|
||||
}
|
||||
case global.DEFAULT_RETRY_RESPONSE.result: { // Something bad happened, but if we retry in a while it might go through the next time.
|
||||
logger.write(MODULE_NAME, "[WARN] run -> loop -> finishProcessExecutionEvents -> onFinished -> Retry Later. Requesting Execution Retry.");
|
||||
nextWaitTime = 'Retry';
|
||||
loopControl(nextWaitTime);
|
||||
return;
|
||||
}
|
||||
case global.DEFAULT_FAIL_RESPONSE.result: { // This is an unexpected exception that we do not know how to handle.
|
||||
processStopped()
|
||||
logger.write(MODULE_NAME, "[ERROR] run -> loop -> finishProcessExecutionEvents -> onFinished -> Operation Failed. Aborting the process.");
|
||||
logger.persist();
|
||||
clearInterval(fixedTimeLoopIntervalHandle);
|
||||
clearTimeout(nextLoopTimeoutHandle);
|
||||
clearTimeout(checkLoopHealthHandle);
|
||||
bot.enableCheckLoopHealth = false;
|
||||
callBackFunction(err);
|
||||
return;
|
||||
}
|
||||
default: {
|
||||
logger.write(MODULE_NAME, "[ERROR] run -> loop -> finishProcessExecutionEvents -> onFinished -> Unhandled err.result received. -> err.result = " + err.result);
|
||||
logger.write(MODULE_NAME, "[ERROR] run -> loop -> finishProcessExecutionEvents -> onFinished -> Unhandled err.result received. -> err = " + err.message);
|
||||
|
||||
logger.persist();
|
||||
clearInterval(fixedTimeLoopIntervalHandle);
|
||||
clearTimeout(nextLoopTimeoutHandle);
|
||||
clearTimeout(checkLoopHealthHandle);
|
||||
bot.enableCheckLoopHealth = false;
|
||||
callBackFunction(global.DEFAULT_FAIL_RESPONSE);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
} catch (err) {
|
||||
logger.write(MODULE_NAME, "[ERROR] run -> loop -> finishProcessExecutionEvents -> onFinished -> err = " + err.stack);
|
||||
logger.persist();
|
||||
clearInterval(fixedTimeLoopIntervalHandle);
|
||||
clearTimeout(nextLoopTimeoutHandle);
|
||||
clearTimeout(checkLoopHealthHandle);
|
||||
bot.enableCheckLoopHealth = false;
|
||||
callBackFunction(err);
|
||||
}
|
||||
}
|
||||
|
||||
} catch (err) {
|
||||
logger.write(MODULE_NAME, "[ERROR] run -> loop -> finishProcessExecutionEvents -> err = " + err.stack);
|
||||
logger.persist();
|
||||
clearInterval(fixedTimeLoopIntervalHandle);
|
||||
clearTimeout(nextLoopTimeoutHandle);
|
||||
clearTimeout(checkLoopHealthHandle);
|
||||
bot.enableCheckLoopHealth = false;
|
||||
callBackFunction(err);
|
||||
}
|
||||
}
|
||||
|
||||
function loopControl(nextWaitTime) {
|
||||
|
||||
if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] run -> loop -> loopControl -> Entering function."); }
|
||||
File diff suppressed because it is too large.
Load diff
@@ -53,35 +53,37 @@ process.on('exit', function (code) {
|
||||
console.log('[INFO] Task Server -> server -> process.on.exit -> About to exit -> code = ' + code)
|
||||
})
|
||||
|
||||
/*
|
||||
/* Here we listen for the message to stop this Task / Process comming from the Task Manager, which is the paret of this node js process. */
|
||||
process.on('message', message => {
|
||||
if (message === 'Stop this Task') {
|
||||
|
||||
We read the first string sent as an argument when the process was created by the Task Manager. Ther we will find the information of the identity
|
||||
of this Task and know exactly what to run within this server instance.
|
||||
global.STOP_TASK_GRACEFULLY = true;
|
||||
|
||||
*/
|
||||
global.TASK_NODE = process.argv[2]
|
||||
/*
|
||||
There are some process that might no be able to end grafully, for example the ones schedulle to process information in a future day or month.
|
||||
In order to be sure that the process will be terminated, we schedulle one forced exit in 2 minutes from now.
|
||||
*/
|
||||
console.log('[INFO] Task Server -> server -> process.on -> Executing order received from Task Manager to Stop this Task. Nodejs process will be exited in less than 1 minute.')
|
||||
setTimeout(global.EXIT_NODE_PROCESS, 60000);
|
||||
}
|
||||
});
|
||||
|
||||
if (global.TASK_NODE !== undefined) {
|
||||
global.EXIT_NODE_PROCESS = function exitProcess() {
|
||||
|
||||
try {
|
||||
global.TASK_NODE = JSON.parse(global.TASK_NODE)
|
||||
console.log('[INFO] Task Server -> server -> global.TASK_NODE = ' + JSON.stringify(global.TASK_NODE))
|
||||
} catch (err) {
|
||||
console.log('[ERROR] Task Server -> server -> global.TASK_NODE -> ' + err.stack)
|
||||
/* Cleaning Before Exiting. */
|
||||
clearInterval(global.HEARTBEAT_INTERVAL_HANDLER)
|
||||
|
||||
for (let i = 0; i < global.TASK_NODE.bot.processes.length; i++) {
|
||||
let code = global.TASK_NODE.bot.processes[i].code
|
||||
let process = global.TASK_NODE.bot.processes[i]
|
||||
|
||||
key = process.name + '-' + process.type + '-' + process.id
|
||||
global.SYSTEM_EVENT_HANDLER.raiseEvent(key, 'Stopped') // Meaning Process Stopped
|
||||
}
|
||||
|
||||
}
|
||||
else { // I use this section to debug in standalone mode.
|
||||
let argument = '{"type":"Task","name":"Runs Backtests","bot":{"type":"Trading Engine","code":{"team":"AAMasters","bot":"AAJason","repo":"AAJason-Trading-Engine-Bot"},"processes":[{"type":"Process","subType":"Trading Engine Process","name":"Multi Period","code":{"process":"Multi-Period"},"session":{"type":"Backtesting Session","name":"Backtest 01","code":{"folderName":"Backtest-01"},"parameters":{"type":"Parameters","name":"Parameters","baseAsset":{"type":"Base Asset","name":"Base Asset","code":{"name":"BTC","initialBalance":0.001,"minimumBalance":0.0001,"maximumBalance":1},"id":"666f6f10-2f17-4f5e-951c-b532bdb574d2"},"timeRange":{"type":"Time Range","name":"Time Range","code":{"initialDatetime":"2019-09-24T00:00:00.000Z","finalDatetime":"2019-09-27T00:00:00.000Z"},"id":"172958dd-b268-4444-8163-70979538ea6e"},"timePeriod":{"type":"Time Period","name":"Time Period","code":"10-min","id":"37ee839d-9a7c-410c-9251-c33b8f1b99f7"},"slippage":{"type":"Slippage","name":"Slippage","code":{"positionRate":0.1,"stopLoss":0.1,"takeProfit":0.1},"id":"86ebd973-6ad9-4070-aece-a87623f24c2e"},"feeStructure":{"type":"Fee Structure","name":"Fee Structure","code":{"maker":0.15,"taker":0.25},"id":"a0ec3f6f-6047-4740-87fe-393b1c714adb"},"key":{"type":"Exchange Account Key","name":"New Key","code":"Paste your exchange API secret key here and the put the key name as this key object title. Secret keys are filtered out and NOT exported when using the SHARE menu option on any object at your workspace. Secret keys ARE downloaded when using the download button.","id":"368f879d-e363-47c7-b55e-7b927d896b20"},"id":"09db5e1e-a7e8-468c-ad70-0d2ab1c8b8b8"},"layerManager":{"type":"Layer Manager","name":"New Layer Manager","layers":[{"type":"Layer","name":"Live","code":{"product":"Live-Trading-History"},"id":"0ec05e1c-230b-44a1-9f2c-fba0ea2ff9e2"},{"type":"Layer","name":"Trades","code":{"product":"Simulation-Trades"},"id":"6326e03a-96c0-4d21-b877-f2c6a0419fc5"},{"type":"Layer","name":"Strategies","code":{"product":"Simulation-Strategies"},"id":"bda1e06c-e569-4bd5-95fb-90154aafb003"},{"type":"Layer","name":"Simulation","code":{"product":"Trading-Simulation"},"id":"d58d8cd2-f125-4f0c-b241-08e2af8ac4be"},{"type":"Layer","name":"Formulas & Conditions","code":{"product":"Simulation-Conditions"},"id":"15dfeca0-acd9-40d3-afe0-4805654bf0d0"}],"id":"884c4dd7-4beb-43fb-bda5-d6097d58ae09"},"socialBots":{"type":"Social Bots","name":"New Social Bots","bots":[],"id":"281eb022-cf9f-4ac2-978b-c8358bee8fec"},"id":"121202ea-6735-4bf3-8a95-aaa55f00f6e7"},"id":"3f483482-d8a1-4755-ba50-7cac6296fa5f"}],"id":"25fe9099-b53d-4757-8a63-3f8a15875f33"},"id":"5b21d2d2-0f52-4408-83eb-ddaa844ec58c"}'
|
||||
/* charly argument = '{"type":"Task","name":"Brings Trades Records from the Exchange","bot":{"type":"Sensor","name":"Charly","processes":[{"type":"Process","name":"Live Trades","code":{"team":"AAMasters","bot":"AACharly","process":"Live-Trades"},"id":"5846ebc7-1979-4a80-9cc7-94bb4b8659dc"},{"type":"Process","name":"Hole Fixing","code":{"team":"AAMasters","bot":"AACharly","process":"Hole-Fixing"},"id":"31fc4f05-75d4-419a-9fb0-73e25e856f15"}]},"id":"5bfef4dc-54c1-44db-ace6-1ab27a86746e"}'
|
||||
// olivia argument = '{"type":"Task","name":"Generates 1 min to 24 hs Candles & Volumes","bot":{"type":"Indicator","name":"Olivia","processes":[{"type":"Process","name":"Daily","code":{"team":"AAMasters","bot":"AAOlivia","process":"Multi-Period-Daily"},"id":"68cc8e1b-e94a-477e-82d0-15ecc9f1b9e2"},{"type":"Process","name":"Market","code":{"team":"AAMasters","bot":"AAOlivia","process":"Multi-Period-Market"},"id":"e1ac5e3d-d491-4e90-baf4-d4e5b71a8b1a"}]},"id":"efe36e05-75ea-41b5-8d92-c6b27635c834"}'
|
||||
// bruce argument = ' {"type":"Task","name":"Converts Trades into 1 min Candles & Volumes","bot":{"type":"Indicator","name":"Bruce","processes":[{"type":"Process","name":"New Process","code":{"team":"AAMasters","bot":"AABruce","process":"Single-Period-Daily"},"id":"e184744f-5de0-41c1-ad4c-36960f4ced90"}]},"id":"42758590-a7bd-4712-a5c9-80a3a820c5b3"}'
|
||||
*/
|
||||
try {
|
||||
global.TASK_NODE = JSON.parse(argument)
|
||||
} catch (err) {
|
||||
console.log(err.stack)
|
||||
}
|
||||
console.log("[INFO] Task Server -> " + global.TASK_NODE.name + " -> EXIT_NODE_PROCESS -> Task Server will stop in 10 seconds.");
|
||||
|
||||
setTimeout(process.exit, 10000) // We will give 10 seconds to logs be written on file
|
||||
}
|
||||
|
||||
require('dotenv').config();
|
||||
@@ -102,54 +104,54 @@ amount of instances started, we can safelly destroy the rest of the objects runn
|
||||
global.ENDED_PROCESSES_COUNTER = 0
|
||||
global.TOTAL_PROCESS_INSTANCES_CREATED = 0
|
||||
|
||||
/* Here we listen for the message to stop this Task / Process comming from the Task Manager, which is the paret of this node js process. */
|
||||
process.on('message', message => {
|
||||
if (message === 'Stop this Task') {
|
||||
/*
|
||||
|
||||
global.STOP_TASK_GRACEFULLY = true;
|
||||
We read the first string sent as an argument when the process was created by the Task Manager. There we will find the information of the identity
|
||||
of this Task and know exactly what to run within this server instance.
|
||||
|
||||
/*
|
||||
There are some process that might no be able to end grafully, for example the ones schedulle to process information in a future day or month.
|
||||
In order to be sure that the process will be terminated, we schedulle one forced exit in 2 minutes from now.
|
||||
*/
|
||||
console.log('[INFO] Task Server -> server -> process.on -> Executing order received from Task Manager to Stop this Task. Nodejs process will be exited in less than 1 minute.')
|
||||
setTimeout(global.EXIT_NODE_PROCESS, 60000);
|
||||
}
|
||||
});
|
||||
|
||||
global.EXIT_NODE_PROCESS = function exitProcess() {
|
||||
|
||||
/* Cleaning Before Exiting. */
|
||||
clearInterval(global.HEARTBEAT_INTERVAL_HANDLER)
|
||||
|
||||
for (let i = 0; i < global.TASK_NODE.bot.processes.length; i++) {
|
||||
let code = global.TASK_NODE.bot.processes[i].code
|
||||
|
||||
/* Delete the event handler for each process. */
|
||||
|
||||
let key = global.TASK_NODE.bot.code.team + "-" + global.TASK_NODE.bot.code.bot + "-" + code.process
|
||||
|
||||
global.SYSTEM_EVENT_HANDLER.deleteEventHandler(key)
|
||||
|
||||
let process = global.TASK_NODE.bot.processes[i]
|
||||
|
||||
key = process.name + '-' + process.type + '-' + process.id
|
||||
global.SYSTEM_EVENT_HANDLER.raiseEvent(key, 'Stopped') // Meaning Process Stopped
|
||||
}
|
||||
|
||||
console.log("[INFO] Task Server -> " + global.TASK_NODE.name + " -> EXIT_NODE_PROCESS -> Task Server will stop in 10 seconds.");
|
||||
|
||||
setTimeout(process.exit, 10000) // We will give 10 seconds to logs be written on file
|
||||
}
|
||||
*/
|
||||
let taskId = process.argv[2] // reading what comes as an argument of the nodejs process.
|
||||
|
||||
/* Setting up the global Event Handler */
|
||||
|
||||
const EVENT_HANDLER_MODULE = require('./SystemEventHandler.js');
|
||||
const IPC = require('node-ipc');
|
||||
global.SYSTEM_EVENT_HANDLER = EVENT_HANDLER_MODULE.newSystemEventHandler(IPC)
|
||||
global.SYSTEM_EVENT_HANDLER.initialize('Task Server', bootLoader)
|
||||
global.SYSTEM_EVENT_HANDLER.initialize('Task Server', preLoader)
|
||||
global.STOP_TASK_GRACEFULLY = false;
|
||||
|
||||
function preLoader() {
|
||||
if (taskId !== undefined) {
|
||||
/* The Task Manager sent the info via a process argument. In this case we listen to an event with the Task Info that should be emitted at the UI */
|
||||
try {
|
||||
console.log('[INFO] Task Server -> server -> preLoader -> Listening to starting event -> key = ' + 'Task Server - ' + taskId)
|
||||
global.SYSTEM_EVENT_HANDLER.listenToEvent('Task Server - ' + taskId, 'Run Task', undefined, undefined, undefined, eventReceived)
|
||||
function eventReceived(message) {
|
||||
global.TASK_NODE = message
|
||||
global.TASK_NODE = JSON.parse(message.event.definition)
|
||||
bootLoader()
|
||||
}
|
||||
} catch (err) {
|
||||
console.log('[ERROR] Task Server -> server -> preLoader -> global.TASK_NODE -> ' + err.stack)
|
||||
console.log('[ERROR] Task Server -> server -> preLoader -> global.TASK_NODE = ' + JSON.stringify(global.TASK_NODE))
|
||||
}
|
||||
}
|
||||
else { /* This process was started not by the Task Manager, but independently (most likely for debugging purposes). In this case we listen to an event with the Task Info that should be emitted at the UI */
|
||||
try {
|
||||
console.log('[INFO] Task Server -> server -> preLoader -> Waiting for event to start debugging...')
|
||||
global.SYSTEM_EVENT_HANDLER.listenToEvent('Task Server', 'Debug Task Started', undefined, undefined, undefined, startDebugging)
|
||||
function startDebugging(message) {
|
||||
global.TASK_NODE = message
|
||||
global.TASK_NODE = JSON.parse(message.event.definition)
|
||||
bootLoader()
|
||||
}
|
||||
} catch (err) {
|
||||
console.log('[ERROR] Task Server -> server -> preLoader -> global.TASK_NODE -> ' + err.stack)
|
||||
console.log('[ERROR] Task Server -> server -> preLoader -> global.TASK_NODE = ' + JSON.stringify(global.TASK_NODE))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function bootLoader() {
|
||||
|
||||
/* Heartbeat sent to the UI */
|
||||
@@ -174,28 +176,34 @@ function bootLoader() {
|
||||
|
||||
/* Validate that the minimun amount of parameters required are defined. */
|
||||
|
||||
if (global.TASK_NODE.bot.code.bot === undefined) {
|
||||
console.log("[INFO] Task Server -> server -> bootLoader -> Parameter 'bot' at the Indicator | Sensor | Trading Engine is undefined. This process will not be executed. -> Process = " + global.TASK_NODE.bot.processes[processIndex].name);
|
||||
if (global.TASK_NODE.bot.processes[processIndex].referenceParent === undefined) {
|
||||
console.log("[INFO] Task Server -> server -> bootLoader -> Process Instance without a Reference Parent. This process will not be executed. -> Process Instance = " + JSON.stringify(global.TASK_NODE.bot.processes[processIndex]));
|
||||
continue
|
||||
}
|
||||
|
||||
if (global.TASK_NODE.bot.code.team === undefined) {
|
||||
console.log("[INFO] Task Server -> server -> bootLoader -> Parameter 'team' at the bot is undefined. This process will not be executed. -> Process = " + global.TASK_NODE.bot.processes[processIndex].name);
|
||||
if (global.TASK_NODE.bot.processes[processIndex].referenceParent.parentNode === undefined) {
|
||||
console.log("[INFO] Task Server -> server -> bootLoader -> Process Definition without parent Bot Definition. -> Process Definition = " + JSON.stringify(global.TASK_NODE.bot.processes[processIndex].referenceParent));
|
||||
continue
|
||||
}
|
||||
|
||||
if (global.TASK_NODE.bot.processes[processIndex].code.process === undefined) {
|
||||
console.log("[INFO] Task Server -> server -> bootLoader -> Parameter 'process' at object Process is undefined. This process will not be executed. -> Process = " + global.TASK_NODE.bot.processes[processIndex].name);
|
||||
if (global.TASK_NODE.bot.processes[processIndex].referenceParent.parentNode.parentNode === undefined) {
|
||||
console.log("[INFO] Task Server -> server -> bootLoader -> Bot Definition without parent Team. -> Bot Definition = " + JSON.stringify(global.TASK_NODE.bot.processes[processIndex].referenceParent.parentNode));
|
||||
continue
|
||||
}
|
||||
|
||||
/* Create the event handler for each process. This event handlers are where the status reports updated events are raised. */
|
||||
if (global.TASK_NODE.bot.processes[processIndex].referenceParent.code.codeName === undefined) {
|
||||
console.log("[INFO] Task Server -> server -> bootLoader -> Process Definition without a codeName defined. -> Process Definition = " + JSON.stringify(global.TASK_NODE.bot.processes[processIndex].referenceParent));
|
||||
continue
|
||||
}
|
||||
|
||||
let key = global.TASK_NODE.bot.code.team + "-" + global.TASK_NODE.bot.code.bot + "-" + code.process
|
||||
global.SYSTEM_EVENT_HANDLER.createEventHandler(key)
|
||||
if (global.TASK_NODE.bot.processes[processIndex].referenceParent.parentNode.code.codeName === undefined) {
|
||||
console.log("[INFO] Task Server -> server -> bootLoader -> Bot Definition without a codeName defined. -> Bot Definition = " + JSON.stringify(global.TASK_NODE.bot.processes[processIndex].referenceParent.parentNode));
|
||||
continue
|
||||
}
|
||||
|
||||
if (global.TASK_NODE.bot.code.repo === undefined) {
|
||||
global.TASK_NODE.bot.code.repo = global.TASK_NODE.bot.code.bot + "-" + global.TASK_NODE.bot.type + "-Bot"
|
||||
if (global.TASK_NODE.bot.processes[processIndex].referenceParent.parentNode.parentNode.code.codeName === undefined) {
|
||||
console.log("[INFO] Task Server -> server -> bootLoader -> Team without a codeName defined. -> Team Definition = " + JSON.stringify(global.TASK_NODE.bot.processes[processIndex].referenceParent.parentNode.parentNode));
|
||||
continue
|
||||
}
|
||||
|
||||
startRoot(processIndex);
|
||||
|
||||
Reference in new issue
Block a user