Build Data Function Implemented

This commit is contained in:
Luis Fernando Molina committed 2019-11-13 18:23:22 +01:00
1 parent 8eaff70835
commit 5e91af82d4
3 files changed
+217 -479

No files matched your search

+102 -428
View File
@@ -10,10 +10,7 @@
let thisObject = {
jsonifyDataFile: jsonifyDataFile,
calculationsProcedure: calculationsProcedure,
buildStandardChannels: buildStandardChannels,
buildSubChannels: buildSubChannels,
buildStandardSubChannels: buildStandardSubChannels,
buildRecords: buildRecords
dataBuildingProcedure: dataBuildingProcedure
};
return thisObject;
@@ -54,26 +51,39 @@
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 amond different code blocks and formulas.
let resultingArray = []
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) {
eval(calculationsProcedure.initialization.code.code)
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 i = 0; i < jsonArray.length; i++) {
for (let index = 0; index < jsonArray.length; index++) {
let indicator = {}
indicator[variableName] = jsonArray[i]
let product = {}
product[variableName] = jsonArray[index]
/* This is Loop Code */
eval(calculationsProcedure.loop.code.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++) {
@@ -81,8 +91,16 @@
if (property.code.isCalculated === true) {
if (property.formula !== undefined) {
if (property.formula.code !== undefined) {
let newValue = eval(property.formula.code)
let currentRecord = indicator[variableName]
let newValue
try {
newvalue = eval(property.formula.code)
} 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.")
}
let currentRecord = product[variableName]
currentRecord[property.code.codeName] = newValue
}
}
@@ -90,440 +108,96 @@
}
/* Adding the new element to the resulting array */
resultingArray.push(indicator.bollingerBand);
results.push(product[variableName]);
}
}
}
return resultingArray
return results
}
function addCalculatedProperties(dependencyArray, variableName, timePeriod) {
function dataBuildingProcedure(products, mainDependency, recordDefinition, dataBuildingProcedure, variableName, timePeriod) {
let dependecyArray = []
/*
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 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 */
let lastMovingAverage = 0;
const SIDE_TOLERANCE = 0.5 * timePeriod / ONE_DAY_IN_MILISECONDS;
const SMALL_SLOPE = 1.0 * timePeriod / ONE_DAY_IN_MILISECONDS;
const MEDIUM_SLOPE = 2.0 * timePeriod / ONE_DAY_IN_MILISECONDS;
const HIGH_SLOPE = 4.0 * timePeriod / ONE_DAY_IN_MILISECONDS;
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.")
}
}
}
/* This is Initialization Code */
if (dataBuildingProcedure.loop !== undefined) {
if (dataBuildingProcedure.loop.code !== undefined) {
for (let index = 0; index < mainDependency.length; index++) {
for (let i = 0; i < dataFile.length; i++) {
let record = {
previous: mainDependency[index-1],
current: mainDependency[index],
next: mainDependency[index+1]
}
let indicator = {}
indicator[variableName] = dataFile[i]
let product = {}
product[variableName] = {}
/* This is Add Properties Code */
if (lastMovingAverage > indicator.bollingerBand.movingAverage) { indicator.bollingerBand.direction = 'Down'; }
if (lastMovingAverage < indicator.bollingerBand.movingAverage) { indicator.bollingerBand.direction = 'Up'; }
if (lastMovingAverage === indicator.bollingerBand.movingAverage) { indicator.bollingerBand.direction = 'Side'; }
/* 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.")
}
let delta = Math.abs(indicator.bollingerBand.movingAverage - lastMovingAverage);
indicator.bollingerBand.slope = 'Extreme';
if (delta < indicator.bollingerBand.movingAverage * HIGH_SLOPE / 100) { indicator.bollingerBand.slope = 'Steep'; }
if (delta < indicator.bollingerBand.movingAverage * MEDIUM_SLOPE / 100) { indicator.bollingerBand.slope = 'Medium'; }
if (delta < indicator.bollingerBand.movingAverage * SMALL_SLOPE / 100) { indicator.bollingerBand.slope = 'Gentle'; }
if (delta < indicator.bollingerBand.movingAverage * SIDE_TOLERANCE / 100) { indicator.bollingerBand.slope = 'Side'; }
lastMovingAverage = indicator.bollingerBand.movingAverage;
/* This is Add Properties Code */
dependecyArray.push(indicator.bollingerBand);
}
return dependecyArray
}
function buildRecords(dataDependency, recordDefinition) {
let records = []
/* Initialization Code */
let period = 1
/* Initialization Code */
for (let i = 0; i < dataDependency.bollinerBands.length; i++) {
/* Calculations Code*/
if (i === 0) {continue}
let currentBand = dataDependency.bollinerBands[i];
let previousBand = dataDependency.bollinerBands[i - 1];
if (currentBand.direction === previousBand.direction) {
period++
} else {
period = 1
}
/* Calculations Code*/
let record = {
begin: currentBand.begin, /* Property Formula Code */
end: currentBand.end, /* Property Formula Code */
direction: currentBand.direction, /* Property Formula Code */
period: period /* Property Formula Code */
};
records.push(record)
}
return records
}
function buildBandsArray(dataFile, bands, timePeriod, callBackFunction) {
try {
let lastMovingAverage = 0;
const SIDE_TOLERANCE = 0.5 * timePeriod / ONE_DAY_IN_MILISECONDS;
const SMALL_SLOPE = 1.0 * timePeriod / ONE_DAY_IN_MILISECONDS;
const MEDIUM_SLOPE = 2.0 * timePeriod / ONE_DAY_IN_MILISECONDS;
const HIGH_SLOPE = 4.0 * timePeriod / ONE_DAY_IN_MILISECONDS;
for (let i = 0; i < dataFile.length; i++) {
let band = {
begin: undefined,
end: undefined,
movingAverage: 10000000000000,
standardDeviation: 0,
deviation: undefined
};
band.begin = dataFile[i][0];
band.end = dataFile[i][1];
band.movingAverage = dataFile[i][2];
band.standardDeviation = dataFile[i][3];
band.deviation = dataFile[i][4];
if (lastMovingAverage > band.movingAverage) { band.direction = 'Down'; }
if (lastMovingAverage < band.movingAverage) { band.direction = 'Up'; }
if (lastMovingAverage === band.movingAverage) { band.direction = 'Side'; }
let delta = Math.abs(band.movingAverage - lastMovingAverage);
band.slope = 'Extreme';
if (delta < band.movingAverage * HIGH_SLOPE / 100) { band.slope = 'Steep'; }
if (delta < band.movingAverage * MEDIUM_SLOPE / 100) { band.slope = 'Medium'; }
if (delta < band.movingAverage * SMALL_SLOPE / 100) { band.slope = 'Gentle'; }
if (delta < band.movingAverage * SIDE_TOLERANCE / 100) { band.slope = 'Side'; }
bands.push(band);
lastMovingAverage = band.movingAverage;
}
}
catch (err) {
callBackFunction(global.DEFAULT_FAIL_RESPONSE);
}
}
function buildChannels(bands, channels, callBackFunction) {
if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] buildChannels -> Entering function."); }
try {
let channel;
for (let i = 0; i < bands.length; i++) {
let currentBand = bands[i];
let nextBand;
if (i < bands.length - 1) {
nextBand = bands[i + 1];
if (
currentBand.direction === nextBand.direction) {
if (channel === undefined) {
channel = {
begin: undefined,
end: undefined,
direction: undefined,
period: 0,
firstMovingAverage: 0,
lastMovingAverage: 0,
firstDeviation: 0,
lastDeviation: 0
};
channel.direction = currentBand.direction;
channel.period = 2;
channel.begin = currentBand.begin;
channel.end = nextBand.end;
channel.firstMovingAverage = currentBand.movingAverage;
channel.lastMovingAverage = nextBand.movingAverage;
channel.firstDeviation = currentBand.deviation;
channel.lastDeviation = nextBand.deviation;
} else {
channel.period++;
channel.end = nextBand.end;
channel.lastMovingAverage = nextBand.movingAverage;
channel.lastDeviation = nextBand.deviation;
}
} else {
if (channel !== undefined) {
channels.push(channel);
channel = undefined;
} else {
/* The channel has only one period */
channel = {};
channel.direction = currentBand.direction;
channel.period = 1;
channel.begin = currentBand.begin;
channel.end = currentBand.end;
channel.firstMovingAverage = currentBand.movingAverage;
channel.lastMovingAverage = currentBand.movingAverage;
channel.firstDeviation = currentBand.deviation;
channel.lastDeviation = currentBand.deviation;
channels.push(channel);
channel = undefined;
/* 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) {
let newValue
try {
newvalue = eval(property.formula.code)
} 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.")
}
let currentRecord = product[variableName]
currentRecord[property.code.codeName] = newValue
}
}
}
}
} else {
if (channel !== undefined) {
channel.period++;
channel.end = currentBand.end;
channel.lastMovingAverage = currentBand.movingAverage;
channel.lastDeviation = currentBand.deviation;
channels.push(channel);
channel = undefined;
} else {
/* The channel has only one period */
channel = {};
channel.direction = currentBand.direction;
channel.period = 1;
channel.begin = currentBand.begin;
channel.end = currentBand.end;
channel.firstMovingAverage = currentBand.movingAverage;
channel.lastMovingAverage = currentBand.movingAverage;
channel.firstDeviation = currentBand.deviation;
channel.lastDeviation = currentBand.deviation;
channels.push(channel);
channel = undefined;
/* If within the code the new data structure was not yet pushed to the results array, we do it */
if (dataBuildingProcedure.loop.code.code.indexOf('results.push') < 0) {
/* Adding the new element to the resulting array */
results.push(product[variableName]);
}
}
}
}
catch (err) {
logger.write(MODULE_NAME, "[ERROR] buildChannels -> err = " + err.stack);
callBackFunction(global.DEFAULT_FAIL_RESPONSE);
}
}
function buildStandardChannels(bands, standardChannels, callBackFunction) {
if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] buildStandardChannels -> Entering function."); }
try {
let period = 1
for (let i = 1; i < bands.length; i++) {
let channel;
let currentBand = bands[i];
let previousBand = bands[i - 1];
if (currentBand.direction === previousBand.direction) {
period++
} else {
period = 1
}
channel = {
begin: currentBand.begin,
end: currentBand.end,
direction: currentBand.direction,
period: period
};
standardChannels.push(channel)
}
}
catch (err) {
logger.write(MODULE_NAME, "[ERROR] buildStandardChannels -> err = " + err.stack);
callBackFunction(global.DEFAULT_FAIL_RESPONSE);
}
}
function buildSubChannels(bands, subChannels, callBackFunction) {
if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] buildSubChannels -> Entering function."); }
try {
let channel;
for (let i = 0; i < bands.length; i++) {
let currentBand = bands[i];
let nextBand;
if (i < bands.length - 1) {
nextBand = bands[i + 1];
if (
currentBand.direction === nextBand.direction &&
currentBand.slope === nextBand.slope) {
if (channel === undefined) {
channel = {
begin: undefined,
end: undefined,
direction: undefined,
slope: undefined,
period: 0,
firstMovingAverage: 0,
lastMovingAverage: 0,
firstDeviation: 0,
lastDeviation: 0
};
channel.direction = currentBand.direction;
channel.slope = currentBand.slope;
channel.period = 2;
channel.begin = currentBand.begin;
channel.end = nextBand.end;
channel.firstMovingAverage = currentBand.movingAverage;
channel.lastMovingAverage = nextBand.movingAverage;
channel.firstDeviation = currentBand.deviation;
channel.lastDeviation = nextBand.deviation;
} else {
channel.period++;
channel.end = nextBand.end;
channel.lastMovingAverage = nextBand.movingAverage;
channel.lastDeviation = nextBand.deviation;
}
} else {
if (channel !== undefined) {
subChannels.push(channel);
channel = undefined;
} else {
/* The channel has only one period */
channel = {};
channel.direction = currentBand.direction;
channel.slope = currentBand.slope;
channel.period = 1;
channel.begin = currentBand.begin;
channel.end = currentBand.end;
channel.firstMovingAverage = currentBand.movingAverage;
channel.lastMovingAverage = currentBand.movingAverage;
channel.firstDeviation = currentBand.deviation;
channel.lastDeviation = currentBand.deviation;
subChannels.push(channel);
channel = undefined;
}
}
} else {
if (channel !== undefined) {
channel.period++;
channel.end = currentBand.end;
channel.lastMovingAverage = currentBand.movingAverage;
channel.lastDeviation = currentBand.deviation;
subChannels.push(channel);
channel = undefined;
} else {
/* The channel has only one period */
channel = {};
channel.direction = currentBand.direction;
channel.slope = currentBand.slope;
channel.period = 1;
channel.begin = currentBand.begin;
channel.end = currentBand.end;
channel.firstMovingAverage = currentBand.movingAverage;
channel.lastMovingAverage = currentBand.movingAverage;
channel.firstDeviation = currentBand.deviation;
channel.lastDeviation = currentBand.deviation;
subChannels.push(channel);
channel = undefined;
}
}
}
}
catch (err) {
logger.write(MODULE_NAME, "[ERROR] buildSubChannels -> err = " + err.stack);
callBackFunction(global.DEFAULT_FAIL_RESPONSE);
}
}
function buildStandardSubChannels(bands, standardSubChannels, callBackFunction) {
if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] buildStandardSubChannels -> Entering function."); }
try {
let period = 1
for (let i = 1; i < bands.length; i++) {
let channel;
let currentBand = bands[i];
let previousBand = bands[i - 1];
if (currentBand.direction === previousBand.direction && currentBand.slope === previousBand.slope) {
period++
} else {
period = 1
}
channel = {
begin: currentBand.begin,
end: currentBand.end,
direction: currentBand.direction,
slope: currentBand.slope,
period: period
};
standardSubChannels.push(channel)
}
}
catch (err) {
logger.write(MODULE_NAME, "[ERROR] buildStandardSubChannels -> err = " + err.stack);
callBackFunction(global.DEFAULT_FAIL_RESPONSE);
}
return results
}
};
+67 -10
View File
@@ -48,6 +48,8 @@
if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] start -> Entering function."); }
let market = global.MARKET;
let products = {}
let mainDependency
let dataDependencies = bot.processNode.referenceParent.processDependencies.dataDependencies
for (let i = 0; i < dataDependencies.length; i++) {
@@ -56,7 +58,7 @@
let dataFile = dataFiles[i]
let jsonData // Datafile converted into Json objects
let inputData // Includes calculated properties
let variableName // name of the variable for this product
let singularVariableName // name of the variable for this product
let recordDefinition
/*
@@ -66,8 +68,13 @@
*/
/* Basic validations to see if we have everything we need. */
if (dataset.parentNode.code.variableName === undefined) {
logger.write(MODULE_NAME, "[ERROR] start -> Product Definition without a Variable Name defined. Product Definition = " + JSON.stringify(dataset.parentNode));
if (dataset.parentNode.code.singularVariableName === undefined) {
logger.write(MODULE_NAME, "[ERROR] start -> Product Definition without a Single Variable Name defined. Product Definition = " + JSON.stringify(dataset.parentNode));
callBackFunction(global.DEFAULT_FAIL_RESPONSE);
return
}
if (dataset.parentNode.code.pluralVariableName === undefined) {
logger.write(MODULE_NAME, "[ERROR] start -> Product Definition without a Plural Variable Name defined. Product Definition = " + JSON.stringify(dataset.parentNode));
callBackFunction(global.DEFAULT_FAIL_RESPONSE);
return
}
@@ -76,8 +83,52 @@
callBackFunction(global.DEFAULT_FAIL_RESPONSE);
return
}
if (dataset.parentNode.calculations === undefined) {
logger.write(MODULE_NAME, "[ERROR] start -> Product Definition without a Calculations Procedure. Product Definition = " + JSON.stringify(dataset.parentNode));
recordDefinition = dataset.parentNode.record
singularVariableName = dataset.parentNode.code.singularVariableName
/* Transform the raw data into JSON objects */
jsonData = commons.jsonifyDataFile(dataFile, recordDefinition)
/* Add the calculated properties */
if (dataset.parentNode.calculations !== undefined) {
inputData = commons.calculationsProcedure(jsonData, recordDefinition, dataset.parentNode.calculations, singularVariableName, timePeriod)
} else {
inputData = jsonData
}
products[dataset.parentNode.code.pluralVariableName] = inputData
/* The main dependency is defined as the first dependency processed. */
if (mainDependency === undefined) {
mainDependency = inputData
}
}
/* During the next phase, we need to generate the data of the different products this process produces an output */
let outputDatasets = bot.processNode.referenceParent.processOutput.outputDatasets
for (let i = 0; i < outputDatasets.length; i++) {
let dataset = outputDatasets[i].referenceParent
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
/*
For each dataset in our process output, we will build the information based on our input products.
*/
/* Basic validations to see if we have everything we need. */
if (dataset.parentNode.code.singularVariableName === undefined) {
logger.write(MODULE_NAME, "[ERROR] start -> Product Definition without a Single Variable Name defined. Product Definition = " + JSON.stringify(dataset.parentNode));
callBackFunction(global.DEFAULT_FAIL_RESPONSE);
return
}
if (dataset.parentNode.code.pluralVariableName === undefined) {
logger.write(MODULE_NAME, "[ERROR] start -> Product Definition without a Plural Variable Name defined. Product Definition = " + JSON.stringify(dataset.parentNode));
callBackFunction(global.DEFAULT_FAIL_RESPONSE);
return
}
if (dataset.parentNode.record === undefined) {
logger.write(MODULE_NAME, "[ERROR] start -> Product Definition without a Record Definition. Product Definition = " + JSON.stringify(dataset.parentNode));
callBackFunction(global.DEFAULT_FAIL_RESPONSE);
return
}
@@ -88,16 +139,22 @@
}
recordDefinition = dataset.parentNode.record
variableName = dataset.parentNode.code.variableName
/* Transform the raw data into JSON objects */
jsonData = commons.jsonifyDataFile(dataFile, recordDefinition)
singularVariableName = dataset.parentNode.code.singularVariableName
/* Build the data */
jsonData = commons.dataBuildingProcedure(products, mainDependency, recordDefinition, dataset.parentNode.dataBuilding, singularVariableName, timePeriod)
/* Add the calculated properties */
if (dataset.parentNode.calculations !== undefined) {
inputData = commons.calculationsProcedure(jsonData, recordDefinition, dataset.parentNode.calculations, variableName, timePeriod)
outputData = commons.calculationsProcedure(jsonData, recordDefinition, dataset.parentNode.calculations, singularVariableName, timePeriod)
} else {
outputData = jsonData
}
products[dataset.parentNode.code.pluralVariableName] = outputData
}
/* During the next phase, we need to generate the data of the different products this process produces an output */
+48 -41
View File
@@ -53,46 +53,6 @@ process.on('exit', function (code) {
console.log('[INFO] Task Server -> server -> process.on.exit -> About to exit -> code = ' + code)
})
/*
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.TASK_NODE = process.argv[2]
if (global.TASK_NODE !== undefined) {
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)
}
}
else { // I use this section to debug in standalone mode.
global.TASK_NODE = { "type": "Task", "name": "Generates Bollinger Channels & Sub-Channels", "bot": { "type": "Indicator Bot Instance", "name": "Paula", "code": { "team": "AAMasters", "bot": "AAPaula", "repo": "AAPaula-Indicator-Bot" }, "processes": [{ "type": "Process Instance", "subType": "Indicator Process Instance", "name": "Market", "code": { "process": "Multi-Period-Market" }, "id": "6ddd81e2-d6db-4814-9c6c-96538a74824c", "referenceParent": { "type": "Process Definition", "name": "Multi-Period-Market", "code": { "codeName": "Multi-Period-Market", "description": "Produces for each market two files with bollinger channels respectively.", "startMode": { "allMonths": { "run": "false", "minYear": "", "maxYear": "" }, "oneMonth": { "run": "false", "year": "", "month": "" }, "noTime": { "run": "true" }, "fixedInterval": { "run": "false", "interval": 0 } }, "deadWaitTime": 0, "normalWaitTime": 0, "retryWaitTime": 10000, "sleepWaitTime": 3600000, "comaWaitTime": 86400000, "framework": { "name": "Multi-Period-Market", "startDate": {}, "endDate": {} } }, "id": "28be432d-80ca-46b3-859a-55541e24b2b4", "processOutput": { "type": "Process Output", "name": "New Process Output", "outputDatasets": [{ "type": "Output Dataset", "name": "Bollinger Channels", "id": "d804e799-7c12-42f5-8de2-52a3a7d5daa4", "referenceParent": { "type": "Dataset Definition", "name": "Market", "code": { "codeName": "Multi-Period-Market", "type": "Market Files", "validPeriods": ["24-hs", "12-hs", "08-hs", "06-hs", "04-hs", "03-hs", "02-hs", "01-hs"], "filePath": "AAMasters/AAPaula.1.0/AACloud.1.1/@Exchange/dataSet.V1/Output/Bollinger-Channels/Multi-Period-Market/@Period", "fileName": "@AssetA_@AssetB.json" }, "parentNode": { "type": "Product Definition", "name": "Bollinger Channels", "code": { "codeName": "Bollinger-Channels", "displayName": "Bollinger-Channels", "description": "Two sets of files per period that contains Bollinger-Bands-Channels-Patterns.", "shareWith": "Public" }, "datasets": [], "record": { "type": "Record Definition", "name": "New Record Definition", "properties": [{ "type": "Record Property", "name": "Begin", "code": { "codeName": "begin", "isNumeric": true }, "formula": { "type": "Formula", "code": "// Write your formula here", "id": "caf8122c-3a07-4263-a56f-ffb05df281d6" }, "id": "06edb099-ff64-4528-b8c6-599154bc2ddf" }, { "type": "Record Property", "name": "End", "code": { "codeName": "end", "isNumeric": true }, "formula": { "type": "Formula", "code": "// Write your formula here", "id": "c8ec0868-8413-468c-88d5-3e43169395e0" }, "id": "94656d1f-508a-4e94-a8d2-013690aac596" }, { "type": "Record Property", "name": "Direction", "code": { "codeName": "direction", "isNumeric": false }, "formula": { "type": "Formula", "code": "// Write your formula here", "id": "e913afe9-b610-4777-bc9e-6349d436a90a" }, "id": "edc0f697-f5e2-446f-bae8-8db7adf91d23" }, { "type": "Record Property", "name": "Period", "code": { "codeName": "period", "isNumeric": true }, "formula": { "type": "Formula", "code": "// Write your formula here", "id": "83fce657-a0bb-41ee-80d1-9e2ab980c472" }, "id": "eb733f85-6cf5-485e-9bd3-2bf78733c492" }, { "type": "Record Property", "name": "First Moving Average", "code": { "codeName": "firstMovingAverage", "isNumeric": true }, "formula": { "type": "Formula", "code": "// Write your formula here", "id": "52490460-35e3-469a-824f-5b139571d4a0" }, "id": "a67a15ee-6f7f-48bd-9d55-82c57efc993b" }, { "type": "Record Property", "name": "Last Moving Average", "code": { "codeName": "lastMovingAverage", "isNumeric": true }, "formula": { "type": "Formula", "code": "// Write your formula here", "id": "41edc1ef-293a-4ceb-bf67-8042e8fdc4eb" }, "id": "0f05bffe-d668-4d25-ab67-d55a4a7c8f5d" }, { "type": "Record Property", "name": "First Deviation", "code": { "codeName": "firstDeviation", "isNumeric": true }, "formula": { "type": "Formula", "code": "// Write your formula here", "id": "5af02103-9bc9-4e6c-9684-5a612adfa495" }, "id": "eae84509-b689-4a76-9277-eed72af491dd" }, { "type": "Record Property", "name": "Last Deviation", "code": { "codeName": "lastDeviation", "isNumeric": true }, "formula": { "type": "Formula", "code": "// Write your formula here", "id": "bc82d292-e71a-4367-9b07-a0e3982ad60d" }, "id": "d5c32d1f-9e3c-48e8-8025-a17d57c0812e" }], "id": "6c3e68b0-b781-4c53-9ff7-67c3f747ac8a" }, "parentNode": { "type": "Indicator Bot", "name": "Paula", "code": { "codeName": "AAPaula" }, "processes": [], "products": [], "parentNode": { "type": "Team", "name": "Masters", "code": { "codeName": "AAMasters" }, "sensorBots": [], "indicatorBots": [], "tradingBots": [], "plotters": [], "id": "35be7b1c-a0f7-4b5f-9ee1-8fb51595e959" }, "id": "bd0f325d-6f98-468b-8b7b-99a42a175d80" }, "id": "1f111f72-624f-4166-9f99-ab8d785d5267" }, "id": "610cd062-ab88-4892-b711-0fb430305c61" } }, { "type": "Output Dataset", "name": "Bollinger Standard Channels", "id": "e524685d-8da0-41f6-839d-9a4100e6e3fe", "referenceParent": { "type": "Dataset Definition", "name": "Line truncated
}
require('dotenv').config();
global.WRITE_LOGS_TO_FILES = process.env.WRITE_LOGS_TO_FILES
/* Default parameters can be changed by the execution configuration */
global.EXCHANGE_NAME = 'Poloniex'
global.MARKET = { assetA: 'USDT', assetB: 'BTC' }
global.CLONE_EXECUTOR = { codeName: 'AACloud', version: '1.1' } // NOTE: To refactor the name of this variable you would need to go through the bots code that are using it.
/*
We need to count how many process instances we deployd and how many of them have already finished their job, either
because they just finished or because there was a request to stop the proceses. In this way, once we reach the
amount of instances started, we can safelly destroy the rest of the objects running and let this nodejs process die.
*/
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') {
@@ -133,14 +93,61 @@ global.EXIT_NODE_PROCESS = function exitProcess() {
setTimeout(process.exit, 10000) // We will give 10 seconds to logs be written on file
}
require('dotenv').config();
global.WRITE_LOGS_TO_FILES = process.env.WRITE_LOGS_TO_FILES
/* Default parameters can be changed by the execution configuration */
global.EXCHANGE_NAME = 'Poloniex'
global.MARKET = { assetA: 'USDT', assetB: 'BTC' }
global.CLONE_EXECUTOR = { codeName: 'AACloud', version: '1.1' } // NOTE: To refactor the name of this variable you would need to go through the bots code that are using it.
/*
We need to count how many process instances we deployd and how many of them have already finished their job, either
because they just finished or because there was a request to stop the proceses. In this way, once we reach the
amount of instances started, we can safelly destroy the rest of the objects running and let this nodejs process die.
*/
global.ENDED_PROCESSES_COUNTER = 0
global.TOTAL_PROCESS_INSTANCES_CREATED = 0
/*
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.
*/
global.TASK_NODE = process.argv[2]
/* 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 (global.TASK_NODE !== undefined) {
/* The Task Manager sent the info via a process argument. */
try {
global.TASK_NODE = JSON.parse(global.TASK_NODE)
console.log('[INFO] Task Server -> server -> preLoader -> global.TASK_NODE = ' + JSON.stringify(global.TASK_NODE))
} catch (err) {
console.log('[ERROR] Task Server -> server -> preLoader -> vglobal.TASK_NODE -> ' + err.stack)
}
bootLoader()
}
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 */
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 = JSON.parse(message.event.definition)
bootLoader()
}
}
}
function bootLoader() {
/* Heartbeat sent to the UI */