Indicator Bot Market Daily and Common Implemented

This commit is contained in:
Luis Fernando Molina committed 2019-10-25 12:51:54 +02:00
1 parent 9d16680022
commit 136be168a5
8 files changed
+1174 -11

No files matched your search

+377
View File
@@ -0,0 +1,377 @@
exports.newIndicatorBotCommons = function newIndicatorBotCommons(bot, logger, UTILITIES) {
const FULL_LOG = true;
const LOG_FILE_CONTENT = false;
const MODULE_NAME = "Commons";
const GMT_SECONDS = ':00.000 GMT+0000';
const ONE_DAY_IN_MILISECONDS = 24 * 60 * 60 * 1000;
let thisObject = {
buildBandsArray: buildBandsArray,
buildChannels: buildChannels,
buildStandardChannels: buildStandardChannels,
buildSubChannels: buildSubChannels,
buildStandardSubChannels: buildStandardSubChannels
};
return thisObject;
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;
}
}
} 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;
}
}
}
}
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);
}
}
};
+405
View File
@@ -0,0 +1,405 @@
exports.newIndicatorBotDaily = function newIndicatorBotDaily(bot, logger, COMMONS, UTILITIES, FILE_STORAGE) {
const FULL_LOG = true;
const LOG_FILE_CONTENT = false;
const ONE_DAY_IN_MILISECONDS = 24 * 60 * 60 * 1000;
const MODULE_NAME = "User Bot";
const BOLLINGER_CHANNELS_FOLDER_NAME = "Bollinger-Channels";
const BOLLINGER_STANDARD_CHANNELS_FOLDER_NAME = "Bollinger-Standard-Channels";
const BOLLINGER_SUB_CHANNELS_FOLDER_NAME = "Bollinger-Sub-Channels";
const BOLLINGER_STANDARD_SUB_CHANNELS_FOLDER_NAME = "Bollinger-Standard-Sub-Channels";
const commons = COMMONS.newIndicatorBotCommons(bot, logger, UTILITIES);
thisObject = {
initialize: initialize,
start: start
};
let utilities = UTILITIES.newCloudUtilities(bot, logger);
let dataDependencies;
let fileStorage = FILE_STORAGE.newFileStorage(logger);
return thisObject;
function initialize(pDataDependencies, callBackFunction) {
try {
logger.fileName = MODULE_NAME;
logger.initialize();
if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] initialize -> Entering function."); }
dataDependencies = pDataDependencies;
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, outputPeriodLabel, currentDay, startDate, endDate, interExecutionMemory, callBackFunction) {
try {
if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] start -> Entering function."); }
let market = global.MARKET;
let dataFile;
let bands = [];
let channels = [];
let standardChannels = [];
let subChannels = [];
let standardSubChannels = [];
dataFile = dataFiles[0]; // We only need the bollinger bands.
commons.buildBandsArray(dataFile, bands, timePeriod, callBackFunction);
commons.buildChannels(bands, channels, callBackFunction);
commons.buildStandardChannels(bands, standardChannels, callBackFunction);
commons.buildSubChannels(bands, subChannels, callBackFunction);
commons.buildStandardSubChannels(bands, standardSubChannels, callBackFunction);
writeChannelsFile();
function writeChannelsFile() {
try {
if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] start -> writeChannelsFile -> Entering function."); }
let separator = "";
let fileRecordCounter = 0;
let fileContent = "";
for (i = 0; i < channels.length; i++) {
let channel = channels[i];
/*
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 (channel.end < currentDay.valueOf() - 1) { continue; }
if (channel.end === lastInstantOdDay) { continue; }
fileContent = fileContent + separator + '[' +
channel.begin + "," +
channel.end + "," +
'"' + channel.direction + '"' + "," +
channel.period + "," +
channel.firstMovingAverage + "," +
channel.lastMovingAverage + "," +
channel.firstDeviation + "," +
channel.lastDeviation + "]";
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/" + BOLLINGER_CHANNELS_FOLDER_NAME + "/" + "Multi-Period-Daily" + "/" + outputPeriodLabel + "/" + 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 -> writeChannelsFile -> onFileCreated -> Entering function."); }
if (LOG_FILE_CONTENT === true) { logger.write(MODULE_NAME, "[INFO] start -> writeChannelsFile -> onFileCreated -> fileContent = " + fileContent); }
if (err.result !== global.DEFAULT_OK_RESPONSE.result) {
logger.write(MODULE_NAME, "[ERROR] start -> writeChannelsFile -> onFileCreated -> err = " + err.stack);
logger.write(MODULE_NAME, "[ERROR] start -> writeChannelsFile -> onFileCreated -> filePath = " + filePath);
logger.write(MODULE_NAME, "[ERROR] start -> writeChannelsFile -> onFileCreated -> market = " + market.assetA + "_" + market.assetB);
callBackFunction(err);
return;
}
writeStandardChannelsFile();
}
catch (err) {
logger.write(MODULE_NAME, "[ERROR] start -> writeChannelsFile -> onFileCreated -> err = " + err.stack);
callBackFunction(global.DEFAULT_FAIL_RESPONSE);
}
}
}
catch (err) {
logger.write(MODULE_NAME, "[ERROR] start -> writeChannelsFile -> err = " + err.stack);
callBackFunction(global.DEFAULT_FAIL_RESPONSE);
}
}
function writeStandardChannelsFile() {
try {
if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] start -> writeStandardChannelsFile -> Entering function."); }
let separator = "";
let fileRecordCounter = 0;
let fileContent = "";
for (i = 0; i < standardChannels.length; i++) {
let channel = standardChannels[i];
if (channel.end < currentDay.valueOf()) { continue; }
fileContent = fileContent + separator + '[' +
channel.begin + "," +
channel.end + "," +
'"' + channel.direction + '"' + "," +
channel.period + "]";
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/" + BOLLINGER_STANDARD_CHANNELS_FOLDER_NAME + "/" + "Multi-Period-Daily" + "/" + outputPeriodLabel + "/" + 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 -> writeStandardChannelsFile -> onFileCreated -> Entering function."); }
if (LOG_FILE_CONTENT === true) { logger.write(MODULE_NAME, "[INFO] start -> writeStandardChannelsFile -> onFileCreated -> fileContent = " + fileContent); }
if (err.result !== global.DEFAULT_OK_RESPONSE.result) {
logger.write(MODULE_NAME, "[ERROR] start -> writeStandardChannelsFile -> onFileCreated -> err = " + err.stack);
logger.write(MODULE_NAME, "[ERROR] start -> writeStandardChannelsFile -> onFileCreated -> filePath = " + filePath);
logger.write(MODULE_NAME, "[ERROR] start -> writeStandardChannelsFile -> onFileCreated -> market = " + market.assetA + "_" + market.assetB);
callBackFunction(err);
return;
}
writeSubChannelsFile();
}
catch (err) {
logger.write(MODULE_NAME, "[ERROR] start -> writeStandardChannelsFile -> onFileCreated -> err = " + err.stack);
callBackFunction(global.DEFAULT_FAIL_RESPONSE);
}
}
}
catch (err) {
logger.write(MODULE_NAME, "[ERROR] start -> writeStandardChannelsFile -> err = " + err.stack);
callBackFunction(global.DEFAULT_FAIL_RESPONSE);
}
}
function writeSubChannelsFile() {
try {
if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] start -> writeSubChannelsFile -> Entering function."); }
let separator = "";
let fileRecordCounter = 0;
let fileContent = "";
for (i = 0; i < subChannels.length; i++) {
let channel = subChannels[i];
/*
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 (channel.end < currentDay.valueOf() - 1) { continue; }
if (channel.end === lastInstantOdDay) { continue; }
fileContent = fileContent + separator + '[' +
channel.begin + "," +
channel.end + "," +
'"' + channel.direction + '"' + "," +
'"' + channel.slope + '"' + "," +
channel.period + "," +
channel.firstMovingAverage + "," +
channel.lastMovingAverage + "," +
channel.firstDeviation + "," +
channel.lastDeviation + "]";
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/" + BOLLINGER_SUB_CHANNELS_FOLDER_NAME + "/" + "Multi-Period-Daily" + "/" + outputPeriodLabel + "/" + 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 -> writeSubChannelsFile -> onFileCreated -> Entering function."); }
if (LOG_FILE_CONTENT === true) { logger.write(MODULE_NAME, "[INFO] start -> writeSubChannelsFile -> onFileCreated -> fileContent = " + fileContent); }
if (err.result !== global.DEFAULT_OK_RESPONSE.result) {
logger.write(MODULE_NAME, "[ERROR] start -> writeSubChannelsFile -> onFileCreated -> err = " + err.stack);
logger.write(MODULE_NAME, "[ERROR] start -> writeSubChannelsFile -> onFileCreated -> filePath = " + filePath);
logger.write(MODULE_NAME, "[ERROR] start -> writeSubChannelsFile -> onFileCreated -> market = " + market.assetA + "_" + market.assetB);
callBackFunction(err);
return;
}
writeStandardSubChannelsFile();
}
catch (err) {
logger.write(MODULE_NAME, "[ERROR] start -> writeSubChannelsFile -> onFileCreated -> err = " + err.stack);
callBackFunction(global.DEFAULT_FAIL_RESPONSE);
}
}
}
catch (err) {
logger.write(MODULE_NAME, "[ERROR] start -> writeSubChannelsFile -> err = " + err.stack);
callBackFunction(global.DEFAULT_FAIL_RESPONSE);
}
}
function writeStandardSubChannelsFile() {
try {
if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] start -> writeStandardSubChannelsFile -> Entering function."); }
let separator = "";
let fileRecordCounter = 0;
let fileContent = "";
for (i = 0; i < standardSubChannels.length; i++) {
let channel = standardSubChannels[i];
if (channel.end < currentDay.valueOf()) { continue; }
fileContent = fileContent + separator + '[' +
channel.begin + "," +
channel.end + "," +
'"' + channel.direction + '"' + "," +
'"' + channel.slope + '"' + "," +
channel.period + "]";
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/" + BOLLINGER_STANDARD_SUB_CHANNELS_FOLDER_NAME + "/" + "Multi-Period-Daily" + "/" + outputPeriodLabel + "/" + 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 -> writeStandardSubChannelsFile -> onFileCreated -> Entering function."); }
if (LOG_FILE_CONTENT === true) { logger.write(MODULE_NAME, "[INFO] start -> writeStandardSubChannelsFile -> onFileCreated -> fileContent = " + fileContent); }
if (err.result !== global.DEFAULT_OK_RESPONSE.result) {
logger.write(MODULE_NAME, "[ERROR] start -> writeStandardSubChannelsFile -> onFileCreated -> err = " + err.stack);
logger.write(MODULE_NAME, "[ERROR] start -> writeStandardSubChannelsFile -> onFileCreated -> filePath = " + filePath);
logger.write(MODULE_NAME, "[ERROR] start -> writeStandardSubChannelsFile -> onFileCreated -> market = " + market.assetA + "_" + market.assetB);
callBackFunction(err);
return;
}
callBackFunction(global.DEFAULT_OK_RESPONSE);
}
catch (err) {
logger.write(MODULE_NAME, "[ERROR] start -> writeStandardSubChannelsFile -> onFileCreated -> err = " + err.stack);
callBackFunction(global.DEFAULT_FAIL_RESPONSE);
}
}
}
catch (err) {
logger.write(MODULE_NAME, "[ERROR] start -> writeStandardSubChannelsFile -> err = " + err.stack);
callBackFunction(global.DEFAULT_FAIL_RESPONSE);
}
}
}
catch (err) {
logger.write(MODULE_NAME, "[ERROR] start -> err = " + err.stack);
callBackFunction(global.DEFAULT_FAIL_RESPONSE);
}
}
};
+369
View File
@@ -0,0 +1,369 @@
exports.newIndicatorBotMarket = function newIndicatorBotMarket(bot, logger, COMMONS, UTILITIES, FILE_STORAGE) {
const FULL_LOG = true;
const LOG_FILE_CONTENT = false;
const ONE_DAY_IN_MILISECONDS = 24 * 60 * 60 * 1000;
const MODULE_NAME = "User Bot";
const BOLLINGER_CHANNELS_FOLDER_NAME = "Bollinger-Channels";
const BOLLINGER_STANDARD_CHANNELS_FOLDER_NAME = "Bollinger-Standard-Channels";
const BOLLINGER_SUB_CHANNELS_FOLDER_NAME = "Bollinger-Sub-Channels";
const BOLLINGER_STANDARD_SUB_CHANNELS_FOLDER_NAME = "Bollinger-Standard-Sub-Channels";
const commons = COMMONS.newIndicatorBotCommons(bot, logger, UTILITIES);
thisObject = {
initialize: initialize,
start: start
};
let dataDependencies;
let fileStorage = FILE_STORAGE.newFileStorage(logger);
return thisObject;
function initialize(pDataDependencies, callBackFunction) {
try {
logger.fileName = MODULE_NAME;
logger.initialize();
if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] initialize -> Entering function."); }
dataDependencies = pDataDependencies;
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, outputPeriodLabel, startDate, endDate, callBackFunction) {
try {
if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] start -> Entering function."); }
let market = global.MARKET;
let dataFile;
let bands = [];
let channels = [];
let standardChannels = [];
let subChannels = [];
let standardSubChannels = [];
dataFile = dataFiles[0]; // We only need the bollinger bands.
commons.buildBandsArray(dataFile, bands, timePeriod, callBackFunction);
commons.buildChannels(bands, channels, callBackFunction);
commons.buildStandardChannels(bands, standardChannels, callBackFunction);
commons.buildSubChannels(bands, subChannels, callBackFunction);
commons.buildStandardSubChannels(bands, standardSubChannels, callBackFunction);
writeChannelsFile();
function writeChannelsFile() {
try {
if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] start -> writeChannelsFile -> Entering function."); }
let separator = "";
let fileRecordCounter = 0;
let fileContent = "";
for (i = 0; i < channels.length; i++) {
let channel = channels[i];
fileContent = fileContent + separator + '[' +
channel.begin + "," +
channel.end + "," +
'"' + channel.direction + '"' + "," +
channel.period + "," +
channel.firstMovingAverage + "," +
channel.lastMovingAverage + "," +
channel.firstDeviation + "," +
channel.lastDeviation + "]";
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/" + BOLLINGER_CHANNELS_FOLDER_NAME + "/" + "Multi-Period-Market" + "/" + outputPeriodLabel;
filePath += '/' + fileName
fileStorage.createTextFile(bot.devTeam, filePath, fileContent + '\n', onFileCreated);
function onFileCreated(err) {
try {
if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] start -> writeChannelsFile -> onFileCreated -> Entering function."); }
if (LOG_FILE_CONTENT === true) { logger.write(MODULE_NAME, "[INFO] start -> writeChannelsFile -> onFileCreated -> fileContent = " + fileContent); }
if (err.result !== global.DEFAULT_OK_RESPONSE.result) {
logger.write(MODULE_NAME, "[ERROR] start -> writeChannelsFile -> onFileCreated -> err = " + err.stack);
logger.write(MODULE_NAME, "[ERROR] start -> writeChannelsFile -> onFileCreated -> filePath = " + filePath);
logger.write(MODULE_NAME, "[ERROR] start -> writeChannelsFile -> onFileCreated -> market = " + market.assetA + "_" + market.assetB);
callBackFunction(err);
return;
}
writeStandardChannelsFile();
}
catch (err) {
logger.write(MODULE_NAME, "[ERROR] start -> writeChannelsFile -> onFileCreated -> err = " + err.stack);
callBackFunction(global.DEFAULT_FAIL_RESPONSE);
}
}
}
catch (err) {
logger.write(MODULE_NAME, "[ERROR] start -> writeChannelsFile -> err = " + err.stack);
callBackFunction(global.DEFAULT_FAIL_RESPONSE);
}
}
function writeStandardChannelsFile() {
try {
if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] start -> writeStandardChannelsFile -> Entering function."); }
let separator = "";
let fileRecordCounter = 0;
let fileContent = "";
for (i = 0; i < standardChannels.length; i++) {
let channel = standardChannels[i];
fileContent = fileContent + separator + '[' +
channel.begin + "," +
channel.end + "," +
'"' + channel.direction + '"' + "," +
channel.period + "]";
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/" + BOLLINGER_STANDARD_CHANNELS_FOLDER_NAME + "/" + "Multi-Period-Market" + "/" + outputPeriodLabel;
filePath += '/' + fileName
fileStorage.createTextFile(bot.devTeam, filePath, fileContent + '\n', onFileCreated);
function onFileCreated(err) {
try {
if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] start -> writeStandardChannelsFile -> onFileCreated -> Entering function."); }
if (LOG_FILE_CONTENT === true) { logger.write(MODULE_NAME, "[INFO] start -> writeStandardChannelsFile -> onFileCreated -> fileContent = " + fileContent); }
if (err.result !== global.DEFAULT_OK_RESPONSE.result) {
logger.write(MODULE_NAME, "[ERROR] start -> writeStandardChannelsFile -> onFileCreated -> err = " + err.stack);
logger.write(MODULE_NAME, "[ERROR] start -> writeStandardChannelsFile -> onFileCreated -> filePath = " + filePath);
logger.write(MODULE_NAME, "[ERROR] start -> writeStandardChannelsFile -> onFileCreated -> market = " + market.assetA + "_" + market.assetB);
callBackFunction(err);
return;
}
writeSubChannelsFile();
}
catch (err) {
logger.write(MODULE_NAME, "[ERROR] start -> writeStandardChannelsFile -> onFileCreated -> err = " + err.stack);
callBackFunction(global.DEFAULT_FAIL_RESPONSE);
}
}
}
catch (err) {
logger.write(MODULE_NAME, "[ERROR] start -> writeStandardChannelsFile -> err = " + err.stack);
callBackFunction(global.DEFAULT_FAIL_RESPONSE);
}
}
function writeSubChannelsFile() {
try {
if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] start -> writeSubChannelsFile -> Entering function."); }
let separator = "";
let fileRecordCounter = 0;
let fileContent = "";
for (i = 0; i < subChannels.length; i++) {
let channel = subChannels[i];
fileContent = fileContent + separator + '[' +
channel.begin + "," +
channel.end + "," +
'"' + channel.direction + '"' + "," +
'"' + channel.slope + '"' + "," +
channel.period + "," +
channel.firstMovingAverage + "," +
channel.lastMovingAverage + "," +
channel.firstDeviation + "," +
channel.lastDeviation + "]";
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/" + BOLLINGER_SUB_CHANNELS_FOLDER_NAME + "/" + "Multi-Period-Market" + "/" + outputPeriodLabel;
filePath += '/' + fileName
fileStorage.createTextFile(bot.devTeam, filePath, fileContent + '\n', onFileCreated);
function onFileCreated(err) {
try {
if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] start -> writeSubChannelsFile -> onFileCreated -> Entering function."); }
if (LOG_FILE_CONTENT === true) { logger.write(MODULE_NAME, "[INFO] start -> writeSubChannelsFile -> onFileCreated -> fileContent = " + fileContent); }
if (err.result !== global.DEFAULT_OK_RESPONSE.result) {
logger.write(MODULE_NAME, "[ERROR] start -> writeSubChannelsFile -> onFileCreated -> err = " + err.stack);
logger.write(MODULE_NAME, "[ERROR] start -> writeSubChannelsFile -> onFileCreated -> filePath = " + filePath);
logger.write(MODULE_NAME, "[ERROR] start -> writeSubChannelsFile -> onFileCreated -> market = " + market.assetA + "_" + market.assetB);
callBackFunction(err);
return;
}
writeStandardSubChannelsFile();
}
catch (err) {
logger.write(MODULE_NAME, "[ERROR] start -> writeSubChannelsFile -> onFileCreated -> err = " + err.stack);
callBackFunction(global.DEFAULT_FAIL_RESPONSE);
}
}
}
catch (err) {
logger.write(MODULE_NAME, "[ERROR] start -> writeSubChannelsFile -> err = " + err.stack);
callBackFunction(global.DEFAULT_FAIL_RESPONSE);
}
}
function writeStandardSubChannelsFile() {
try {
if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] start -> writeStandardSubChannelsFile -> Entering function."); }
let separator = "";
let fileRecordCounter = 0;
let fileContent = "";
for (i = 0; i < standardSubChannels.length; i++) {
let channel = standardSubChannels[i];
fileContent = fileContent + separator + '[' +
channel.begin + "," +
channel.end + "," +
'"' + channel.direction + '"' + "," +
'"' + channel.slope + '"' + "," +
channel.period + "]";
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/" + BOLLINGER_STANDARD_SUB_CHANNELS_FOLDER_NAME + "/" + "Multi-Period-Market" + "/" + outputPeriodLabel;
filePath += '/' + fileName
fileStorage.createTextFile(bot.devTeam, filePath, fileContent + '\n', onFileCreated);
function onFileCreated(err) {
try {
if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] start -> writeStandardSubChannelsFile -> onFileCreated -> Entering function."); }
if (LOG_FILE_CONTENT === true) { logger.write(MODULE_NAME, "[INFO] start -> writeStandardSubChannelsFile -> onFileCreated -> fileContent = " + fileContent); }
if (err.result !== global.DEFAULT_OK_RESPONSE.result) {
logger.write(MODULE_NAME, "[ERROR] start -> writeStandardSubChannelsFile -> onFileCreated -> err = " + err.stack);
logger.write(MODULE_NAME, "[ERROR] start -> writeStandardSubChannelsFile -> onFileCreated -> filePath = " + filePath);
logger.write(MODULE_NAME, "[ERROR] start -> writeStandardSubChannelsFile -> onFileCreated -> market = " + market.assetA + "_" + market.assetB);
callBackFunction(err);
return;
}
callBackFunction(global.DEFAULT_OK_RESPONSE);
}
catch (err) {
logger.write(MODULE_NAME, "[ERROR] start -> writeSubChannelsFile -> onFileCreated -> err = " + err.stack);
callBackFunction(global.DEFAULT_FAIL_RESPONSE);
}
}
}
catch (err) {
logger.write(MODULE_NAME, "[ERROR] start -> writeSubChannelsFile -> err = " + err.stack);
callBackFunction(global.DEFAULT_FAIL_RESPONSE);
}
}
}
catch (err) {
logger.write(MODULE_NAME, "[ERROR] start -> err = " + err.stack);
callBackFunction(global.DEFAULT_FAIL_RESPONSE);
}
}
};
+2 -2
View File
@@ -253,12 +253,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, COMMONS_MODULE, UTILITIES, USER_BOT_MODULE, COMMONS_MODULE, 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, COMMONS_MODULE, UTILITIES, USER_BOT_MODULE, COMMONS_MODULE, FILE_STORAGE);
intitializeProcessFramework();
break;
}
+5 -3
View File
@@ -1,4 +1,4 @@
exports.newMultiPeriodDaily = function newMultiPeriodDaily(bot, logger, COMMONS, UTILITIES, USER_BOT_MODULE, COMMONS_MODULE) {
exports.newMultiPeriodDaily = function newMultiPeriodDaily(bot, logger, COMMONS, UTILITIES, USER_BOT_MODULE, COMMONS_MODULE, FILE_STORAGE) {
const FULL_LOG = true;
const LOG_FILE_CONTENT = false;
@@ -21,7 +21,6 @@
let usertBot;
const FILE_STORAGE = require('./FileStorage.js');
let fileStorage = FILE_STORAGE.newFileStorage(logger);
let bootstrappingTheProcess = false
@@ -61,7 +60,10 @@
}
usertBot = USER_BOT_MODULE.newUserBot(bot, logger, COMMONS_MODULE, UTILITIES, fileStorage);
let COMMONS_MODULE = require("./IndicatorBotCommons")
let USER_BOT_MODULE = require("./IndicatorBotDaily")
usertBot = USER_BOT_MODULE.newIndicatorBotDaily(bot, logger, COMMONS_MODULE, UTILITIES, FILE_STORAGE);
usertBot.initialize(dataDependencies, callBackFunction, pAssistant);
} catch (err) {
+5 -6
View File
@@ -1,4 +1,4 @@
exports.newMultiPeriodMarket = function newMultiPeriodMarket(bot, logger, COMMONS, UTILITIES, USER_BOT_MODULE, COMMONS_MODULE) {
exports.newMultiPeriodMarket = function newMultiPeriodMarket(bot, logger, COMMONS, UTILITIES, USER_BOT_MODULE, COMMONS_MODULE, FILE_STORAGE) {
const FULL_LOG = true;
const LOG_FILE_CONTENT = false;
@@ -19,9 +19,6 @@
let usertBot;
const FILE_STORAGE = require('./FileStorage.js');
let fileStorage = FILE_STORAGE.newFileStorage(logger);
let processConfig;
return thisObject;
@@ -57,7 +54,10 @@
}
usertBot = USER_BOT_MODULE.newUserBot(bot, logger, COMMONS_MODULE, UTILITIES, fileStorage);
let COMMONS_MODULE = require("./IndicatorBotCommons")
let USER_BOT_MODULE = require("./IndicatorBotMarket")
usertBot = USER_BOT_MODULE.newIndicatorBotMarket(bot, logger, COMMONS_MODULE, UTILITIES, FILE_STORAGE);
usertBot.initialize(dataDependencies, callBackFunction, pAssistant);
} catch (err) {
@@ -72,7 +72,6 @@
statusDependencies = undefined
dataDependencies = undefined
usertBot = undefined
fileStorage = undefined
processConfig = undefined
thisObject = undefined
}
+9
View File
@@ -25,8 +25,17 @@
<Compile Include="Assistant.js">
<SubType>Code</SubType>
</Compile>
<Compile Include="IndicatorBotCommons.js">
<SubType>Code</SubType>
</Compile>
<Compile Include="IndicatorBotDaily.js">
<SubType>Code</SubType>
</Compile>
<Compile Include="Integrations\Ecosystem.js" />
<Compile Include="FileStorage.js" />
<Compile Include="IndicatorBotMarket.js">
<SubType>Code</SubType>
</Compile>
<Compile Include="MultiPeriod.js">
<SubType>Code</SubType>
</Compile>
+2
View File
@@ -77,6 +77,8 @@ else { // I use this section to debug in standalone mode.
// 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"}'
*/
argument = '{"type":"Task","name":"Generates Bollinger Channels & Sub-Channels","bot":{"type":"Indicator","name":"Paula","code":{"team":"AAMasters","bot":"AAPaula"},"processes":[{"type":"Process","subType":"Indicator Process","name":"Daily","code":{"process":"Multi-Period-Daily"},"id":"81f0108b-8af9-4b22-94dd-81ef4a5c8065"},{"type":"Process","subType":"Indicator Process","name":"Market","code":{"process":"Multi-Period-Market"},"id":"6ddd81e2-d6db-4814-9c6c-96538a74824c"}],"id":"27564838-24b1-4814-af8c-ec65accb05d1"},"id":"aa0f2533-460c-464f-ad77-6ae4cadd1178"}'
try {
global.TASK_NODE = JSON.parse(argument)
} catch (err) {