Indicator Bot Market Daily and Common Implemented
This commit is contained in:
1 parent
9d16680022
commit
136be168a5
8 files changed
+1174
-11
No files matched your search
@@ -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);
|
||||
}
|
||||
}
|
||||
};
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
};
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
};
|
||||
@@ -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
@@ -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) {
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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) {
|
||||
|
||||
Reference in new issue
Block a user