Old bot names refactored

This commit is contained in:
Luis Fernando Molina committed 2020-03-12 11:41:24 +01:00
1 parent ec052d2e94
commit 2b5abf1a61
65 files changed
+316 -1383

No files matched your search

+1 -1
View File
@@ -428,7 +428,7 @@ function newCircularMenuItem () {
if (thisObject.currentRadius >= thisObject.targetRadius) {
labelPoint = {
x: menuPosition.x + thisObject.currentRadius + 20,
x: menuPosition.x + thisObject.currentRadius + 25,
y: menuPosition.y + fontSize * FONT_ASPECT_RATIO
}
+7
View File
@@ -289,7 +289,11 @@ function newUiObject () {
if (nowTimestamp - lastHeartBeat.valueOf() > ONE_MIN) {
lastHeartBeat = undefined
thisObject.isRunning = false
setValue('')
}
} else {
thisObject.isRunning = false
setValue('')
}
}
@@ -313,9 +317,12 @@ function newUiObject () {
thisObject.isRunning = true
} else {
thisObject.isRunning = false
setValue('')
}
return
} else {
heartBeatPhysics()
}
}
}
+3 -3
View File
@@ -75,8 +75,8 @@ function newFileCloud () {
}
if (pMarket !== undefined) {
fileName = fileName.replace('@BaseAsset', pMarket.baseAsset)
fileName = fileName.replace('@QuotedAsset', pMarket.quotedAsset)
filePath = filePath.replace('@BaseAsset', pMarket.baseAsset)
filePath = filePath.replace('@QuotedAsset', pMarket.quotedAsset)
}
if (pDataMine !== undefined) {
@@ -99,7 +99,7 @@ function newFileCloud () {
}
if (pExchange !== undefined) {
filePath = filePath.replace('@Exchange', pExchange.code.codeName)
filePath = filePath.replace('@Exchange', pExchange.name)
}
filePath = filePath.replace('@Period', pPeriodName)
+2 -2
View File
@@ -89,10 +89,10 @@ function newFileCursor () {
beginDateRange = pBeginDateRange
endDateRange = pEndDateRange
let key = dataMine.code.codeName + '-' + bot.code.codeName + '-' + product.code.codeName + '-' + dataset.code.codeName + '-' + exchange.code.codeName + '-' + market.baseAsset + '/' + market.quotedAsset
let key = dataMine.code.codeName + '-' + bot.code.codeName + '-' + product.code.codeName + '-' + dataset.code.codeName + '-' + exchange.name + '-' + market.baseAsset + '/' + market.quotedAsset
systemEventHandler.listenToEvent(key, 'Dataset Updated', undefined, key + '-' + periodName, onResponseDataSet, updateFiles)
key = dataMine.code.codeName + '-' + bot.code.codeName + '-' + product.code.codeName + '-' + exchange.code.codeName + '-' + market.baseAsset + '/' + market.quotedAsset
key = dataMine.code.codeName + '-' + bot.code.codeName + '-' + product.code.codeName + '-' + exchange.name + '-' + market.baseAsset + '/' + market.quotedAsset
systemEventHandler.listenToEvent(key, 'Data Range Updated', undefined, key, onResponseDataRange, updateDataRange)
callBackFunction(GLOBAL.DEFAULT_OK_RESPONSE)
+1 -1
View File
@@ -74,7 +74,7 @@ function newFileSequence () {
callerId = newUniqueId()
let key = dataMine.code.codeName + '-' + bot.code.codeName + '-' + product.code.codeName + '-' + dataset.code.codeName + '-' + exchange.code.codeName + '-' + market.baseAsset + '/' + market.quotedAsset
let key = dataMine.code.codeName + '-' + bot.code.codeName + '-' + product.code.codeName + '-' + dataset.code.codeName + '-' + exchange.name + '-' + market.baseAsset + '/' + market.quotedAsset
systemEventHandler.listenToEvent(key, 'Dataset Updated', undefined, callerId, onResponse, updateFiles)
function onResponse (message) {
+1 -1
View File
@@ -106,7 +106,7 @@ function newMarketFiles () {
}
if (filesLoaded + filesNotLoaded === marketFilesPeriods.length) {
let key = dataMine.code.codeName + '-' + bot.code.codeName + '-' + product.code.codeName + '-' + dataset.code.codeName + '-' + exchange.code.codeName + '-' + market.baseAsset + '/' + market.quotedAsset
let key = dataMine.code.codeName + '-' + bot.code.codeName + '-' + product.code.codeName + '-' + dataset.code.codeName + '-' + exchange.name + '-' + market.baseAsset + '/' + market.quotedAsset
systemEventHandler.listenToEvent(key, 'Dataset Updated', undefined, key + '-' + periodName, onResponse, updateFiles)
callBackFunction(GLOBAL.DEFAULT_OK_RESPONSE, thisObject)
@@ -1,67 +0,0 @@
exports.newCommons = function newCommons(bot, logger, UTILITIES) {
const FULL_LOG = true;
const LOG_FILE_CONTENT = false;
const MODULE_NAME = "Commons";
const ONE_DAY_IN_MILISECONDS = 24 * 60 * 60 * 1000;
const GMT_SECONDS = ':00.000 GMT+0000';
let thisObject = {
initializeStorage: initializeStorage
};
let utilities = UTILITIES.newCloudUtilities(bot, logger);
return thisObject;
function initializeStorage(charlyStorage, bruceStorage, callBackFunction) {
try {
if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] initializeStorage -> Entering function."); }
initializeBruceStorage();
function initializeBruceStorage() {
bruceStorage.initialize(bot.dataMine, onBruceInizialized);
function onBruceInizialized(err) {
if (err.result === global.DEFAULT_OK_RESPONSE.result) {
initializeCharlyStorage();
} else {
logger.write(MODULE_NAME, "[ERROR] initializeStorage -> initializeBruceStorage -> onBruceInizialized -> err = " + err.stack);
callBackFunction(err);
}
}
}
function initializeCharlyStorage() {
charlyStorage.initialize(bot.dataMine, onCharlyInizialized);
function onCharlyInizialized(err) {
if (err.result === global.DEFAULT_OK_RESPONSE.result) {
callBackFunction(global.DEFAULT_OK_RESPONSE);
} else {
logger.write(MODULE_NAME, "[ERROR] initializeStorage -> initializeCharlyStorage -> onCharlyInizialized -> err = " + err.stack);
callBackFunction(err);
}
}
}
}
catch (err) {
logger.write(MODULE_NAME, "[ERROR] initializeStorage -> err = " + err.stack);
callBackFunction(global.DEFAULT_FAIL_RESPONSE);
}
}
};
@@ -1,813 +0,0 @@
exports.newUserBot = function newUserBot(bot, logger, COMMONS, UTILITIES, fileStorage) {
const FULL_LOG = true;
const LOG_FILE_CONTENT = false;
const GMT_SECONDS = ':00.000 GMT+0000';
const GMT_MILI_SECONDS = '.000 GMT+0000';
const ONE_DAY_IN_MILISECONDS = 24 * 60 * 60 * 1000;
const MODULE_NAME = "User Bot";
const TRADES_FOLDER_NAME = "Trades";
const CANDLES_FOLDER_NAME = "Candles";
const CANDLES_ONE_MIN = "One-Min";
const VOLUMES_FOLDER_NAME = "Volumes";
const VOLUMES_ONE_MIN = "One-Min";
thisObject = {
initialize: initialize,
start: start
};
let utilities = UTILITIES.newCloudUtilities(bot, logger);
let statusDependencies;
return thisObject;
function initialize(pStatusDependencies, callBackFunction) {
statusDependencies = pStatusDependencies;
logger.fileName = MODULE_NAME
logger.initialize();
callBackFunction(global.DEFAULT_OK_RESPONSE);
}
/*
This process is going to do the following:
Read the trades from Charly's Output and pack them into daily files with candles of one minute.
*/
function start(callBackFunction) {
try {
if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] start -> Entering function."); }
let processDate = new Date((new Date()).getUTCFullYear() + "-" + ((new Date()).getUTCMonth() + 1) + "-1 00:00:00.000 GMT+0000");
let thisDatetime = new Date();
let market = bot.market;
let lastTradeFileProcessed; // Datetime of the last file certified by the Hole Fixing process as without permanent holes.
let firstTradeFile; // Datetime of the first trade file in the whole market history.
let lastTradeFileSaved; // Datetime of the last verified file without holes.
let lastCandleClose; // Value of the last candle close.
let lastTradeFile; // Datetime pointing to the last Trade File sucessfuly processed and included in the last file.
let beginingOfMarket
getContextVariables();
function getContextVariables() {
try {
if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] start -> getContextVariables -> Entering function."); }
let thisReport;
let reportKey;
/* First Status Report */
reportKey = "AAMasters" + "-" + "AACharly" + "-" + "Historic-Trades" + "-" + "dataSet.V1";
if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] start -> getContextVariables -> reportKey = " + reportKey); }
if (statusDependencies.statusReports.get(reportKey).status === "Status Report is corrupt.") {
logger.write(MODULE_NAME, "[ERROR] start -> getContextVariables -> Can not continue because dependecy Status Report is corrupt. ");
callBackFunction(global.DEFAULT_RETRY_RESPONSE);
return;
}
thisReport = statusDependencies.statusReports.get(reportKey).file;
if (thisReport.beginingOfMarket === undefined) {
logger.write(MODULE_NAME, "[WARN] start -> getContextVariables -> Undefined Last File. -> reportKey = " + reportKey);
logger.write(MODULE_NAME, "[HINT] start -> getContextVariables -> It is too early too run this process since the trade history of the market is not there yet.");
let customOK = {
result: global.CUSTOM_OK_RESPONSE.result,
message: "Dependency does not exist."
}
logger.write(MODULE_NAME, "[WARN] start -> getContextVariables -> customOK = " + customOK.message);
callBackFunction(customOK);
return;
}
firstTradeFile = new Date(thisReport.beginingOfMarket.year + "-" + thisReport.beginingOfMarket.month + "-" + thisReport.beginingOfMarket.days + " " + thisReport.beginingOfMarket.hours + ":" + thisReport.beginingOfMarket.minutes + GMT_SECONDS);
lastTradeFileSaved = new Date(thisReport.lastFileSaved.year + "-" + thisReport.lastFileSaved.month + "-" + thisReport.lastFileSaved.days + " " + thisReport.lastFileSaved.hours + ":" + thisReport.lastFileSaved.minutes + GMT_SECONDS);
/* Final Status Report */
reportKey = "AAMasters" + "-" + "AABruce" + "-" + "Single-Period-Daily" + "-" + "dataSet.V1"
if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] start -> getContextVariables -> reportKey = " + reportKey); }
if (statusDependencies.statusReports.get(reportKey).status === "Status Report is corrupt.") {
logger.write(MODULE_NAME, "[ERROR] start -> getContextVariables -> Can not continue because self dependecy Status Report is corrupt. Aborting Process.");
callBackFunction(global.DEFAULT_FAIL_RESPONSE);
return;
}
thisReport = statusDependencies.statusReports.get(reportKey).file;
if (thisReport.lastFile === undefined) { // Means this is the first time ever this process runs.
logger.write(MODULE_NAME, "[INFO] start -> getContextVariables -> Process Running for the very first time. -> reportKey = " + reportKey);
lastCandleClose = 0;
lastTradeFileProcessed = new Date(firstTradeFile.valueOf() - ONE_DAY_IN_MILISECONDS)
beginingOfMarket = new Date(firstTradeFile.valueOf())
buildCandlesAndVolumes();
} else {
logger.write(MODULE_NAME, "[INFO] start -> getContextVariables -> Process Running not for the very first time. -> reportKey = " + reportKey);
lastTradeFileProcessed = new Date(thisReport.lastTradeFile.year + "-" + thisReport.lastTradeFile.month + "-" + thisReport.lastTradeFile.days + " " + "00:00" + GMT_SECONDS);
lastCandleClose = thisReport.candleClose;
beginingOfMarket = new Date(thisReport.beginingOfMarket.year + "-" + thisReport.beginingOfMarket.month + "-" + thisReport.beginingOfMarket.days + " " + thisReport.beginingOfMarket.hours + ":" + thisReport.beginingOfMarket.minutes + GMT_SECONDS);
if (beginingOfMarket.valueOf() !== firstTradeFile.valueOf()) { // Reset Mechanism for Begining of the Market
logger.write(MODULE_NAME, "[INFO] start -> getContextVariables -> Reset Mechanism for Begining of the Market Activated. -> reportKey = " + reportKey);
beginingOfMarket = new Date(firstTradeFile.valueOf())
lastTradeFileProcessed = new Date(firstTradeFile.valueOf() - ONE_DAY_IN_MILISECONDS)
lastCandleClose = 0
buildCandlesAndVolumes()
return
}
if (thisReport.fileComplete === true) {
buildCandlesAndVolumes();
} else {
lastTradeFile = new Date(thisReport.lastTradeFile.year + "-" + thisReport.lastTradeFile.month + "-" + thisReport.lastTradeFile.days + " " + thisReport.lastTradeFile.hours + ":" + thisReport.lastTradeFile.minutes + GMT_SECONDS);
findPreviousContent();
}
}
} catch (err) {
logger.write(MODULE_NAME, "[ERROR] start -> getContextVariables -> err = " + err.stack);
if (err.message === "Cannot read property 'file' of undefined") {
logger.write(MODULE_NAME, "[HINT] start -> getContextVariables -> Check the bot configuration to see if all of its statusDependencies declarations are correct. ");
logger.write(MODULE_NAME, "[HINT] start -> getContextVariables -> Dependencies loaded -> keys = " + JSON.stringify(statusDependencies.keys));
}
callBackFunction(global.DEFAULT_FAIL_RESPONSE);
}
}
function findPreviousContent() {
try {
if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] start -> findPreviousContent -> Entering function."); }
let previousCandles;
let previousVolumes;
getCandles();
function getCandles() {
try {
if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] start -> findPreviousContent -> getCandles -> Entering function."); }
let fileName = '' + market.baseAsset + '_' + market.quotedAsset + '.json';
let dateForPath = lastTradeFileProcessed.getUTCFullYear() + '/' + utilities.pad(lastTradeFileProcessed.getUTCMonth() + 1, 2) + '/' + utilities.pad(lastTradeFileProcessed.getUTCDate(), 2);
let filePath = bot.filePathRoot + "/Output/" + CANDLES_FOLDER_NAME + '/' + CANDLES_ONE_MIN + '/' + dateForPath;
filePath += '/' + fileName
fileStorage.getTextFile(filePath, onFileReceived);
logger.write(MODULE_NAME, "[INFO] start -> findPreviousContent -> getCandles -> reading file at dateForPath = " + dateForPath);
function onFileReceived(err, text) {
let candlesFile;
try {
if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] start -> findPreviousContent -> getCandles -> onFileReceived -> Entering function."); }
if (err.result !== global.DEFAULT_OK_RESPONSE.result) {
logger.write(MODULE_NAME, "[ERROR] start -> findPreviousContent -> getCandles -> onFileReceived -> err = " + err.stack);
callBackFunction(err);
return;
}
if (LOG_FILE_CONTENT === true) {
logger.write(MODULE_NAME, "[INFO] start -> findPreviousContent -> getCandles -> onFileReceived -> text = " + text);
}
candlesFile = JSON.parse(text);
previousCandles = candlesFile;
getVolumes();
} catch (err) {
logger.write(MODULE_NAME, "[ERROR] start -> findPreviousContent -> getCandles -> onFileReceived -> err = " + err.stack);
logger.write(MODULE_NAME, "[ERROR] start -> findPreviousContent -> getCandles -> onFileReceived -> filePath = " + filePath);
logger.write(MODULE_NAME, "[HINT] start -> findPreviousContent -> getCandles -> onFileReceived -> Empty or corrupt volume file found.");
callBackFunction(global.DEFAULT_FAIL_RESPONSE);
return;
}
}
} catch (err) {
logger.write(MODULE_NAME, "[ERROR] start -> findPreviousContent -> getCandles -> err = " + err.stack);
callBackFunction(global.DEFAULT_FAIL_RESPONSE);
}
}
function getVolumes() {
try {
if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] start -> findPreviousContent -> getVolumes -> Entering function."); }
let fileName = '' + market.baseAsset + '_' + market.quotedAsset + '.json';
let dateForPath = lastTradeFileProcessed.getUTCFullYear() + '/' + utilities.pad(lastTradeFileProcessed.getUTCMonth() + 1, 2) + '/' + utilities.pad(lastTradeFileProcessed.getUTCDate(), 2);
let filePath = bot.filePathRoot + "/Output/" + VOLUMES_FOLDER_NAME + '/' + VOLUMES_ONE_MIN + '/' + dateForPath;
filePath += '/' + fileName
fileStorage.getTextFile(filePath, onFileReceived);
logger.write(MODULE_NAME, "[INFO] start -> findPreviousContent -> getVolumes -> reading file at dateForPath = " + dateForPath);
function onFileReceived(err, text) {
let volumesFile;
try {
if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] start -> findPreviousContent -> getVolumes -> onFileReceived -> Entering function."); }
if (err.result !== global.DEFAULT_OK_RESPONSE.result) {
logger.write(MODULE_NAME, "[ERROR] start -> findPreviousContent -> getVolumes -> onFileReceived -> err = " + err.stack);
logger.write(MODULE_NAME, "[ERROR] start -> findPreviousContent -> getVolumes -> onFileReceived -> text = " + text);
callBackFunction(err);
return;
}
if (LOG_FILE_CONTENT === true) {
logger.write(MODULE_NAME, "[INFO] start -> findPreviousContent -> getVolumes -> onFileReceived -> text = " + text);
}
volumesFile = JSON.parse(text);
previousVolumes = volumesFile;
lastTradeFileProcessed = new Date(lastTradeFileProcessed.valueOf() - ONE_DAY_IN_MILISECONDS); // We know that after the next call a new day will be added.
buildCandlesAndVolumes(previousCandles, previousVolumes);
} catch (err) {
logger.write(MODULE_NAME, "[ERROR] start -> findPreviousContent -> getVolumes -> onFileReceived -> err = " + err.stack);
logger.write(MODULE_NAME, "[ERROR] start -> findPreviousContent -> getVolumes -> onFileReceived -> filePath = " + filePath);
logger.write(MODULE_NAME, "[ERROR] start -> findPreviousContent -> getVolumes -> onFileReceived -> text = " + text);
logger.write(MODULE_NAME, "[HINT] start -> findPreviousContent -> getVolumes -> onFileReceived -> Empty or corrupt volume file found.");
callBackFunction(global.DEFAULT_FAIL_RESPONSE);
return;
}
}
} catch (err) {
logger.write(MODULE_NAME, "[ERROR] start -> findPreviousContent -> getVolumes -> err = " + err.stack);
callBackFunction(global.DEFAULT_FAIL_RESPONSE);
}
}
} catch (err) {
logger.write(MODULE_NAME, "[ERROR] start -> findPreviousContent -> err = " + err.stack);
callBackFunction(global.DEFAULT_FAIL_RESPONSE);
}
}
function buildCandlesAndVolumes(previousCandles, previousVolumes) {
if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] start -> buildCandlesAndVolumes -> Entering function."); }
/*
Here we are going to scan the trades files packing them in candles files every one day.
We need for this the last close value, bacause all candles that are empty of trades at the begining, they need to
have a valid open and close value. This was previously calculated before arriving to this function.
*/
let canAddPrevious = true;
try {
nextFile();
function nextFile() {
try {
if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] start -> buildCandlesAndVolumes -> nextFile -> Entering function."); }
lastTradeFileProcessed = new Date(lastTradeFileProcessed.valueOf() + ONE_DAY_IN_MILISECONDS);
let date = new Date(lastTradeFileProcessed.valueOf() - 60 * 1000);
if (date.valueOf() < firstTradeFile.valueOf()) { // At the special case where we are at the begining of the market, this might be true.
date = new Date(firstTradeFile.valueOf() - 60 * 1000);
}
if (lastTradeFile !== undefined) {
date = new Date(lastTradeFile.valueOf());
}
if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] start -> buildCandlesAndVolumes -> nextFile -> date = " + date); }
let candles = [];
let volumes = [];
if (previousCandles !== undefined && canAddPrevious === true) {
if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] start -> buildCandlesAndVolumes -> nextFile -> Adding Previous Candles. "); }
for (let i = 0; i < previousCandles.length; i++) {
let candle = {
open: previousCandles[i][2],
close: previousCandles[i][3],
min: previousCandles[i][0],
max: previousCandles[i][1],
begin: previousCandles[i][4],
end: previousCandles[i][5]
};
candles.push(candle);
}
}
if (previousVolumes !== undefined && canAddPrevious === true) {
if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] start -> buildCandlesAndVolumes -> nextFile -> Adding Previous Volumes. "); }
for (let i = 0; i < previousVolumes.length; i++) {
let volume = {
begin: previousVolumes[i][2],
end: previousVolumes[i][3],
buy: previousVolumes[i][0],
sell: previousVolumes[i][1]
};
volumes.push(volume);
}
}
canAddPrevious = false; // We add them only onece.
nextDate();
function nextDate() {
try {
if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] start -> buildCandlesAndVolumes -> nextFile -> nextDate -> Entering function."); }
date = new Date(date.valueOf() + 60 * 1000);
if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] start -> buildCandlesAndVolumes -> nextFile -> nextDate -> date = " + date); }
/* Check if we are outside the current Day / File */
if (date.getUTCDate() !== lastTradeFileProcessed.getUTCDate()) {
writeFiles(lastTradeFileProcessed, candles, volumes, true, onFilesWritten);
return;
function onFilesWritten() {
nextFile();
}
}
/* Check if we have past the most recent hole fixed file */
if (date.valueOf() > lastTradeFileSaved.valueOf()) {
writeFiles(lastTradeFileProcessed, candles, volumes, false, onFilesWritten);
return;
function onFilesWritten() {
if (FULL_LOG === true) {
logger.write(MODULE_NAME, "[INFO] start -> buildCandlesAndVolumes -> nextFile -> nextDate -> Head of the market reached for market " + market.baseAsset + '_' + market.quotedAsset + ".");
}
callBackFunction(global.DEFAULT_OK_RESPONSE);
return;
}
}
readTrades();
} catch (err) {
logger.write(MODULE_NAME, "[ERROR] start -> buildCandlesAndVolumes -> nextFile -> nextDate -> err = " + err.stack);
callBackFunction(global.DEFAULT_FAIL_RESPONSE);
}
}
function readTrades() {
try {
if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] start -> buildCandlesAndVolumes -> nextFile -> nextDate -> readTrades -> Entering function."); }
lastTradeFile = new Date(date.valueOf());
let dateForPath = date.getUTCFullYear() + '/' + utilities.pad(date.getUTCMonth() + 1, 2) + '/' + utilities.pad(date.getUTCDate(), 2) + '/' + utilities.pad(date.getUTCHours(), 2) + '/' + utilities.pad(date.getUTCMinutes(), 2);
let fileName = market.baseAsset + '_' + market.quotedAsset + ".json"
let filePathRoot = bot.dataMine + "/" + "AACharly" + "/" + bot.exchange;
let filePath = filePathRoot + "/Output/" + TRADES_FOLDER_NAME + '/' + dateForPath;
filePath += '/' + fileName
fileStorage.getTextFile(filePath, onFileReceived);
logger.write(MODULE_NAME, "[INFO] start -> buildCandlesAndVolumes -> nextFile -> nextDate -> readTrades -> reading file at dateForPath = " + dateForPath);
function onFileReceived(err, text) {
let tradesFile;
try {
if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] start -> buildCandlesAndVolumes -> nextFile -> readTrades -> onFileReceived -> Entering function."); }
if (err.result !== global.DEFAULT_OK_RESPONSE.result) {
logger.write(MODULE_NAME, "[ERROR] start -> buildCandlesAndVolumes -> nextFile -> readTrades -> onFileReceived -> err = " + err.stack);
logger.write(MODULE_NAME, "[ERROR] start -> buildCandlesAndVolumes -> nextFile -> readTrades -> onFileReceived -> text = " + text);
callBackFunction(err);
return;
}
if (LOG_FILE_CONTENT === true) {
logger.write(MODULE_NAME, "[INFO] start -> buildCandlesAndVolumes -> nextFile -> readTrades -> onFileReceived -> text = " + text);
}
let candle = {
open: lastCandleClose,
close: lastCandleClose,
min: lastCandleClose,
max: lastCandleClose,
begin: date.valueOf(),
end: date.valueOf() + 60 * 1000 - 1
};
let volume = {
begin: date.valueOf(),
end: date.valueOf() + 60 * 1000 - 1,
buy: 0,
sell: 0
};
tradesFile = JSON.parse(text);
let tradesCount = utilities.pad(tradesFile.length, 5);
logger.write(MODULE_NAME, "[INFO] start -> buildCandlesAndVolumes -> nextFile -> readTrades -> onFileReceived -> " + tradesCount + " trades found at " + filePath + " for market " + market.baseAsset + '_' + market.quotedAsset + ". ");
if (tradesFile.length > 0) {
/* Candle open and close Calculations */
candle.open = tradesFile[0][2];
candle.close = tradesFile[tradesFile.length - 1][2];
lastCandleClose = candle.close;
}
for (let i = 0; i < tradesFile.length; i++) {
let record = {
side: tradesFile[i][1],
price: tradesFile[i][2],
amount: tradesFile[i][3]
};
let trade = {
type: record.side,
rate: record.price,
amountA: record.amount,
amountB: record.amount * record.price
};
/* Candle min and max Calculations */
if (trade.rate < candle.min) {
candle.min = trade.rate;
}
if (trade.rate > candle.max) {
candle.max = trade.rate;
}
/* Volume Calculations */
if (trade.type === "sell") {
volume.sell = volume.sell + trade.amountA;
} else {
volume.buy = volume.buy + trade.amountA;
}
}
candles.push(candle);
volumes.push(volume);
nextDate();
} catch (err) {
logger.write(MODULE_NAME, "[ERROR] start -> buildCandlesAndVolumes -> nextFile -> readTrades -> onFileReceived -> err = " + err.stack);
logger.write(MODULE_NAME, "[ERROR] start -> buildCandlesAndVolumes -> nextFile -> readTrades -> onFileReceived -> filePath = " + filePath);
logger.write(MODULE_NAME, "[ERROR] start -> buildCandlesAndVolumes -> nextFile -> readTrades -> onFileReceived -> text = " + text);
logger.write(MODULE_NAME, "[HINT] start -> buildCandlesAndVolumes -> nextFile -> readTrades -> onFileReceived -> Empty or corrupt volume file found.");
callBackFunction(global.DEFAULT_FAIL_RESPONSE);
return;
}
}
} catch (err) {
logger.write(MODULE_NAME, "[ERROR] start -> buildCandlesAndVolumes -> nextFile -> readTrades -> err = " + err.stack);
callBackFunction(global.DEFAULT_FAIL_RESPONSE);
}
}
} catch (err) {
logger.write(MODULE_NAME, "[ERROR] start -> buildCandlesAndVolumes -> nextFile -> err = " + err.stack);
callBackFunction(global.DEFAULT_FAIL_RESPONSE);
}
}
} catch (err) {
logger.write(MODULE_NAME, "[ERROR] start -> buildCandlesAndVolumes -> err = " + err.stack);
callBackFunction(global.DEFAULT_FAIL_RESPONSE);
}
}
function writeFiles(date, candles, volumes, isFileComplete, callBack) {
if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] start -> writeFiles -> Entering function."); }
/*
Here we will write the contents of the Candles and Volumens files. If the File is declared as complete, we will also write the status report.
*/
try {
writeCandles();
function writeCandles() {
try {
if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] start -> writeFiles -> writeCandles -> Entering function."); }
let separator = "";
let fileRecordCounter = 0;
let fileContent = "";
for (i = 0; i < candles.length; i++) {
fileContent = fileContent + separator + '[' + candles[i].min + "," + candles[i].max + "," + candles[i].open + "," + candles[i].close + "," + candles[i].begin + "," + candles[i].end + "]";
if (separator === "") { separator = ","; }
fileRecordCounter++;
}
fileContent = "[" + fileContent + "]";
let fileName = '' + market.baseAsset + '_' + market.quotedAsset + '.json';
let dateForPath = date.getUTCFullYear() + '/' + utilities.pad(date.getUTCMonth() + 1, 2) + '/' + utilities.pad(date.getUTCDate(), 2);
let filePath = bot.filePathRoot + "/Output/" + CANDLES_FOLDER_NAME + '/' + CANDLES_ONE_MIN + '/' + dateForPath;
filePath += '/' + fileName
fileStorage.createTextFile(filePath, fileContent + '\n', onFileCreated);
logger.write(MODULE_NAME, "[INFO] start -> writeFiles -> writeCandles -> writing file at dateForPath = " + dateForPath);
function onFileCreated(err) {
try {
if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] start -> writeFiles -> writeCandles -> onFileCreated -> Entering function."); }
if (err.result !== global.DEFAULT_OK_RESPONSE.result) {
logger.write(MODULE_NAME, "[ERROR] start -> writeFiles -> writeCandles -> onFileCreated -> err = " + err.stack);
callBackFunction(err);
return;
}
if (LOG_FILE_CONTENT === true) {
logger.write(MODULE_NAME, "[INFO] start -> writeFiles -> writeCandles -> onFileCreated -> fileContent = " + fileContent);
}
logger.write(MODULE_NAME, "[INFO] start -> writeFiles -> writeCandles -> onFileCreated -> Finished with File @ " + market.baseAsset + "_" + market.quotedAsset + ", " + fileRecordCounter + " records inserted into " + filePath + "/" + fileName + "");
writeVolumes();
} catch (err) {
logger.write(MODULE_NAME, "[ERROR] start -> writeFiles -> writeCandles -> onFileCreated -> err = " + err.stack);
callBackFunction(global.DEFAULT_FAIL_RESPONSE);
}
}
} catch (err) {
logger.write(MODULE_NAME, "[ERROR] start -> writeFiles -> writeCandles -> err = " + err.stack);
callBackFunction(global.DEFAULT_FAIL_RESPONSE);
}
}
function writeVolumes() {
try {
if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] start -> writeFiles -> writeVolumes -> Entering function."); }
let separator = "";
let fileRecordCounter = 0;
let fileContent = "";
for (i = 0; i < volumes.length; i++) {
/* Validation trying to find a BUG that changes the dates of rubish data. */
if (volumes[i].begin < 1262304000000 | volumes[i].end < 1262304000000) { // If it is storing a number that represents a date before the year 2010...
logger.write(MODULE_NAME, "[ERROR] start -> writeFiles -> writeVolumes -> Invalid Date trying to be recorded on output file. ");
logger.write(MODULE_NAME, "[ERROR] start -> writeFiles -> writeVolumes -> volumes[i].begin = " + volumes[i].begin);
logger.write(MODULE_NAME, "[ERROR] start -> writeFiles -> writeVolumes -> volumes[i].end = " + volumes[i].end);
logger.write(MODULE_NAME, "[ERROR] start -> writeFiles -> writeVolumes -> i = " + i);
logger.write(MODULE_NAME, "[ERROR] start -> writeFiles -> writeVolumes -> volumes = " + JSON.stringify(volumes));
callBackFunction(global.DEFAULT_FAIL_RESPONSE);
return;
}
fileContent = fileContent + separator + '[' + volumes[i].buy + "," + volumes[i].sell + "," + volumes[i].begin + "," + volumes[i].end + "]";
if (separator === "") { separator = ","; }
fileRecordCounter++;
}
fileContent = "[" + fileContent + "]";
let fileName = '' + market.baseAsset + '_' + market.quotedAsset + '.json';
let dateForPath = date.getUTCFullYear() + '/' + utilities.pad(date.getUTCMonth() + 1, 2) + '/' + utilities.pad(date.getUTCDate(), 2);
let filePath = bot.filePathRoot + "/Output/" + VOLUMES_FOLDER_NAME + '/' + VOLUMES_ONE_MIN + '/' + dateForPath;
filePath += '/' + fileName
fileStorage.createTextFile(filePath, fileContent + '\n', onFileCreated);
logger.write(MODULE_NAME, "[INFO] start -> writeFiles -> writeVolumes -> writing file at dateForPath = " + dateForPath);
function onFileCreated(err) {
try {
if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] start -> writeFiles -> writeVolumes -> onFileCreated -> Entering function."); }
if (err.result !== global.DEFAULT_OK_RESPONSE.result) {
logger.write(MODULE_NAME, "[ERROR] start -> writeFiles -> writeVolumes -> onFileCreated -> err = " + err.stack);
callBackFunction(err);
return;
}
if (LOG_FILE_CONTENT === true) {
logger.write(MODULE_NAME, "[INFO] start -> writeFiles -> writeVolumes -> onFileCreated -> fileContent = " + fileContent);
}
logger.write(MODULE_NAME, "[INFO] start -> writeFiles -> writeVolumes -> onFileCreated -> Finished with File @ " + market.baseAsset + "_" + market.quotedAsset + ", " + fileRecordCounter + " records inserted into " + filePath + "/" + fileName + "");
writeReport();
} catch (err) {
logger.write(MODULE_NAME, "[ERROR] start -> writeFiles -> writeVolumes -> onFileCreated -> err = " + err.stack);
callBackFunction(global.DEFAULT_FAIL_RESPONSE);
}
}
} catch (err) {
logger.write(MODULE_NAME, "[ERROR] start -> writeFiles -> writeVolumes -> err = " + err.stack);
callBackFunction(global.DEFAULT_FAIL_RESPONSE);
}
}
function writeReport() {
try {
if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] start -> writeFiles -> writeReport -> Entering function."); }
writeStatusReport(date, lastTradeFile, lastCandleClose, isFileComplete, false, onStatusReportWritten);
function onStatusReportWritten(err) {
try {
if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] start -> writeFiles -> writeReport -> onStatusReportWritten -> Entering function."); }
if (err.result !== global.DEFAULT_OK_RESPONSE.result) {
logger.write(MODULE_NAME, "[ERROR] start -> writeFiles -> onStatusReportWritten -> err = " + err.stack);
callBackFunction(err);
return;
}
callBack();
return;
} catch (err) {
logger.write(MODULE_NAME, "[ERROR] start -> writeFiles -> writeReport -> onStatusReportWritten -> err = " + err.stack);
callBackFunction(global.DEFAULT_FAIL_RESPONSE);
return;
}
}
} catch (err) {
logger.write(MODULE_NAME, "[ERROR] start -> writeFiles -> writeReport -> err = " + err.stack);
callBackFunction(global.DEFAULT_FAIL_RESPONSE);
}
}
} catch (err) {
logger.write(MODULE_NAME, "[ERROR] start -> writeFiles -> err = " + err.stack);
callBackFunction(global.DEFAULT_FAIL_RESPONSE);
}
}
function writeStatusReport(lastFileDate, lastTradeFile, candleClose, isFileComplete, isMonthComplete, callBack) {
if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] start -> writeStatusReport -> Entering function."); }
if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] start -> writeStatusReport -> lastFileDate = " + lastFileDate); }
if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] start -> writeStatusReport -> lastTradeFile = " + lastTradeFile); }
if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] start -> writeStatusReport -> candleClose = " + candleClose); }
if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] start -> writeStatusReport -> isFileComplete = " + isFileComplete); }
if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] start -> writeStatusReport -> isMonthComplete = " + isMonthComplete); }
try {
if (lastTradeFile === undefined) {
/* At the begining of a new month, it can happen for reasons not 100% clear that this variable gets undifined.
Probably it is because the instance that was waiting to execute in coma state, wakes up before than Charly
writting the trades of this new month. Anyway, when this happens, a different path in code is taken and this
variable gets undefined. A workaround for that without further investigation of the real cause of the problem
is to RETRY the execution until the normal conditions arise and everything continues working well. That is what
we are going to do for now. */
if (FULL_LOG === true) { logger.write(MODULE_NAME, "[WARN] start -> writeStatusReport -> Cannot write the status report."); }
if (FULL_LOG === true) { logger.write(MODULE_NAME, "[WARN] start -> writeStatusReport -> lastTradeFile = undefined."); }
callBackFunction(global.DEFAULT_RETRY_RESPONSE);
return;
}
let key = bot.dataMine + "-" + bot.codeName + "-" + bot.process + "-" + bot.dataSetVersion
let statusReport = statusDependencies.statusReports.get(key);
statusReport.file = {
lastFile: {
year: lastFileDate.getUTCFullYear(),
month: (lastFileDate.getUTCMonth() + 1),
days: lastFileDate.getUTCDate()
},
lastTradeFile: {
year: lastTradeFile.getUTCFullYear(),
month: (lastTradeFile.getUTCMonth() + 1),
days: lastTradeFile.getUTCDate(),
hours: lastTradeFile.getUTCHours(),
minutes: lastTradeFile.getUTCMinutes()
},
beginingOfMarket: {
year: beginingOfMarket.getUTCFullYear(),
month: (beginingOfMarket.getUTCMonth() + 1),
days: beginingOfMarket.getUTCDate(),
hours: beginingOfMarket.getUTCHours(),
minutes: beginingOfMarket.getUTCMinutes()
},
candleClose: candleClose,
fileComplete: isFileComplete
};
let fileContent = JSON.stringify(statusReport);
statusReport.save(onSaved);
function onSaved(err) {
if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] start -> writeStatusReport -> onSaved -> Entering function."); }
if (err.result !== global.DEFAULT_OK_RESPONSE.result) {
logger.write(MODULE_NAME, "[ERROR] start -> writeStatusReport -> onSaved -> err = " + err.stack);
callBackFunction(err);
return;
}
callBack(global.DEFAULT_OK_RESPONSE);
}
}
catch (err) {
logger.write(MODULE_NAME, "[ERROR] start -> writeStatusReport -> err = " + err.stack);
callBackFunction(global.DEFAULT_FAIL_RESPONSE);
}
}
}
catch (err) {
logger.write(MODULE_NAME, "[ERROR] start -> err = " + err.stack);
callBackFunction(global.DEFAULT_FAIL_RESPONSE);
}
}
};
@@ -1,13 +0,0 @@
{
"name": "AABruce",
"version": "1.0.0",
"description": "Processes that get the order books from Poloniex.",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "Luis-Fernando-Molina",
"license": "ISC",
"dependencies": {
}
}
@@ -1,143 +0,0 @@
{
"displayName": "Bruce",
"codeName": "AABruce",
"type": "Indicator Bot",
"version": {
"major": 1,
"minor": 0,
"patch": 0
},
"dataMine": "AAMasters",
"profilePicture": "Bruce.png",
"dataSetVersion": "dataSet.V1",
"processes": [
{
"name": "Single-Period-Daily",
"description": "Produces two data-sets with candles and volumes.",
"startMode": {
"allMonths": {
"run": "true",
"minYear": "2019",
"maxYear": "2019"
},
"oneMonth": {
"run": "false",
"year": "2018",
"month": "6"
},
"noTime": {
"run": "false"
},
"fixedInterval": {
"run": "false",
"interval": 0
}
},
"deadWaitTime": 0,
"normalWaitTime": 0,
"retryWaitTime": 10000,
"sleepWaitTime": 3600000,
"comaWaitTime": 86400000,
"statusDependencies": [
{
"dataMine": "AAMasters",
"bot": "AACharly",
"botVersion": {
"major": 1,
"minor": 0
},
"process": "Historic-Trades",
"dataSetVersion": "dataSet.V1"
},
{
"dataMine": "AAMasters",
"bot": "AACharly",
"botVersion": {
"major": 1,
"minor": 0
},
"process": "Hole-Fixing",
"dataSetVersion": "dataSet.V1",
"dataSetSection": "Month",
"waitUntilNextUpdate": true
},
{
"dataMine": "AAMasters",
"bot": "AABruce",
"botVersion": {
"major": 1,
"minor": 0
},
"process": "Single-Period-Daily",
"dataSetVersion": "dataSet.V1",
"dataSetSection": "Month"
}
]
}
],
"products": [
{
"codeName": "Candles",
"displayName": "Candles",
"description": "01 Min Candles.",
"storageAccount": "aamasters",
"dataSets": [
{
"codeName": "One-Min",
"type": "Daily Files",
"validPeriods": [ "01-min" ],
"filePath": "AAMasters/AAOlivia.1.0/AACloud.1.1/@Exchange/dataSet.V1/Output/Candles/One-Min",
"fileName": "@AssetA_@AssetB.json"
}
],
"exchangeList": [
{
"name": "Poloniex"
},
{
"name": "Coss"
}
],
"plotter": {
"dataMine": "AAMasters",
"codeName": "PlottersCandlesVolumes",
"moduleName": "Candles"
}
},
{
"codeName": "Volumes",
"displayName": "Buy and Sell Volumes",
"description": "01 Min Volumes.",
"storageAccount": "aamasters",
"dataSets": [
{
"codeName": "One-Min",
"type": "Daily Files",
"validPeriods": [ "01-min" ],
"filePath": "AAMasters/AAOlivia.1.0/AACloud.1.1/@Exchange/dataSet.V1/Output/Volumes/One-Min",
"fileName": "@AssetA_@AssetB.json"
}
],
"exchangeList": [
{
"name": "Poloniex"
},
{
"name": "Coss"
}
],
"plotter": {
"dataMine": "AAMasters",
"codeName": "PlottersCandlesVolumes",
"moduleName": "Volumes"
}
}
],
"storage": {
"sas": "?sv=2017-07-29&ss=b&srt=sco&sp=rl&se=2018-12-31T22:59:59Z&st=2018-04-01T12:59:54Z&spr=https&sig=Fre%2FUWrF9IAXNnJSOZ%2F5q5LUow9uno7dXg5pGZ3YDzo%3D",
"fileUri": "https://aamasters.blob.core.windows.net"
}
}
@@ -50,7 +50,7 @@
This process is going to do the following:
Read the candles from Olivia and produce daily files with bollinger bands.
Read the candles from Candles Volumes and produce daily files with bollinger bands.
*/
@@ -85,9 +85,9 @@
let reportKey;
let statusReport;
/* We look first for Charly in order to get when the market starts. */
/* We look first for Exchange Raw Data in order to get when the market starts. */
reportKey = "AAMasters" + "-" + "AACharly" + "-" + "Historic-Trades" + "-" + "dataSet.V1";
reportKey = "Masters" + "-" + "Exchange-Raw-Data" + "-" + "Historic-Trades" + "-" + "dataSet.V1";
if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] start -> getContextVariables -> reportKey = " + reportKey); }
statusReport = statusDependencies.statusReports.get(reportKey);
@@ -121,9 +121,9 @@
contextVariables.firstTradeFile = new Date(thisReport.beginingOfMarket.year + "-" + thisReport.beginingOfMarket.month + "-" + thisReport.beginingOfMarket.days + " " + thisReport.beginingOfMarket.hours + ":" + thisReport.beginingOfMarket.minutes + GMT_SECONDS);
/* Second, we get the report from Olivia, to know when the marted ends. */
/* Second, we get the report from Candles Volumes, to know when the marted ends. */
reportKey = "AAMasters" + "-" + "AAOlivia" + "-" + "Multi-Period-Daily" + "-" + "dataSet.V1";
reportKey = "Masters" + "-" + "Candles-Volumes" + "-" + "Multi-Period-Daily" + "-" + "dataSet.V1";
if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] start -> getContextVariables -> reportKey = " + reportKey); }
statusReport = statusDependencies.statusReports.get(reportKey);
@@ -158,7 +158,7 @@
/* Finally we get our own Status Report. */
reportKey = "AAMasters" + "-" + "AAChris" + "-" + "Multi-Period-Daily" + "-" + "dataSet.V1";
reportKey = "Masters" + "-" + "Bollinger-Bands" + "-" + "Multi-Period-Daily" + "-" + "dataSet.V1";
if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] start -> getContextVariables -> reportKey = " + reportKey); }
statusReport = statusDependencies.statusReports.get(reportKey);
@@ -328,9 +328,8 @@
if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] start -> buildBands -> loopBody -> getPreviousDayFile -> Entering function."); }
let dateForPath = previousDay.getUTCFullYear() + '/' + utilities.pad(previousDay.getUTCMonth() + 1, 2) + '/' + utilities.pad(previousDay.getUTCDate(), 2);
let fileName = market.baseAsset + '_' + market.quotedAsset + ".json"
let filePathRoot = bot.dataMine + "/" + "AAOlivia" + "/" + bot.exchange;
let fileName = "Data.json"
let filePathRoot = bot.exchange + "/" + bot.market.baseAsset + "-" + bot.market.quotedAsset + "/" + bot.dataMine + "/" + "Candles-Volumes";
let filePath = filePathRoot + "/Output/" + CANDLES_FOLDER_NAME + '/' + "Multi-Period-Daily" + "/" + timeFrame + "/" + dateForPath;
filePath += '/' + fileName
@@ -368,9 +367,8 @@
if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] start -> buildBands -> loopBody -> getProcessDayFile -> Entering function."); }
let dateForPath = processDate.getUTCFullYear() + '/' + utilities.pad(processDate.getUTCMonth() + 1, 2) + '/' + utilities.pad(processDate.getUTCDate(), 2);
let fileName = market.baseAsset + '_' + market.quotedAsset + ".json"
let filePathRoot = bot.dataMine + "/" + "AAOlivia" + "/" + bot.exchange;
let fileName = "Data.json"
let filePathRoot = bot.exchange + "/" + bot.market.baseAsset + "-" + bot.market.quotedAsset + "/" + bot.dataMine + "/" + "Candles-Volumes";
let filePath = filePathRoot + "/Output/" + CANDLES_FOLDER_NAME + '/' + "Multi-Period-Daily" + "/" + timeFrame + "/" + dateForPath;
filePath += '/' + fileName
@@ -598,10 +596,8 @@
fileContent = "[" + fileContent + "]";
let dateForPath = processDate.getUTCFullYear() + '/' + utilities.pad(processDate.getUTCMonth() + 1, 2) + '/' + utilities.pad(processDate.getUTCDate(), 2);
let fileName = '' + market.baseAsset + '_' + market.quotedAsset + '.json';
let filePathRoot = bot.dataMine + "/" + bot.codeName + "/" + bot.exchange;
let filePath = filePathRoot + "/Output/" + BOLLINGER_BANDS_FOLDER_NAME + "/" + bot.process + "/" + timeFrame + "/" + dateForPath;
let fileName = 'Data.json';
let filePath = bot.filePathRoot + "/Output/" + BOLLINGER_BANDS_FOLDER_NAME + "/" + bot.process + "/" + timeFrame + "/" + dateForPath;
filePath += '/' + fileName
fileStorage.createTextFile(filePath, fileContent + '\n', onFileCreated);
@@ -670,10 +666,8 @@
fileContent = "[" + fileContent + "]";
let dateForPath = processDate.getUTCFullYear() + '/' + utilities.pad(processDate.getUTCMonth() + 1, 2) + '/' + utilities.pad(processDate.getUTCDate(), 2);
let fileName = '' + market.baseAsset + '_' + market.quotedAsset + '.json';
let filePathRoot = bot.dataMine + "/" + bot.codeName + "/" + bot.exchange;
let filePath = filePathRoot + "/Output/" + PERCENTAGE_BANDWIDTH_FOLDER_NAME + "/" + bot.process + "/" + timeFrame + "/" + dateForPath;
let fileName = 'Data.json';
let filePath = bot.filePathRoot + "/Output/" + PERCENTAGE_BANDWIDTH_FOLDER_NAME + "/" + bot.process + "/" + timeFrame + "/" + dateForPath;
filePath += '/' + fileName
fileStorage.createTextFile(filePath, fileContent + '\n', onFileCreated);
@@ -826,7 +820,7 @@
let fileContent = JSON.stringify(dataRange);
let fileName = 'Data.Range.' + market.baseAsset + '_' + market.quotedAsset + '.json';
let fileName = 'Data.Range.json';
let filePath = bot.filePathRoot + "/Output/" + pProductFolder + "/" + bot.process;
filePath += '/' + fileName
@@ -863,7 +857,7 @@
try {
let reportKey = "AAMasters" + "-" + "AAChris" + "-" + "Multi-Period-Daily" + "-" + "dataSet.V1";
let reportKey = "Masters" + "-" + "Bollinger-Bands" + "-" + "Multi-Period-Daily" + "-" + "dataSet.V1";
let thisReport = statusDependencies.statusReports.get(reportKey);
thisReport.file.lastExecution = bot.processDatetime;
@@ -43,7 +43,7 @@
This process is going to do the following:
Read the candles from Olivia and produce the bollinger bands out of them.
Read the candles from Candles Volumes and produce the bollinger bands out of them.
*/
@@ -107,9 +107,9 @@
if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] start -> buildBands -> loopBody -> nextCandleFile -> Entering function."); }
let fileName = market.baseAsset + '_' + market.quotedAsset + ".json";
let fileName = "Data.json";
let filePathRoot = bot.dataMine + "/" + "AAOlivia" + "/" + bot.exchange;
let filePathRoot = bot.exchange + "/" + bot.market.baseAsset + "-" + bot.market.quotedAsset + "/" + bot.dataMine + "/" + "Candles-Volumes";
let filePath = filePathRoot + "/Output/" + CANDLES_FOLDER_NAME + "/" + "Multi-Period-Market" + "/" + timeFrame;
filePath += '/' + fileName
@@ -297,10 +297,8 @@
fileContent = "[" + fileContent + "]";
let fileName = '' + market.baseAsset + '_' + market.quotedAsset + '.json';
let filePathRoot = bot.dataMine + "/" + bot.codeName + "/" + bot.exchange;
let filePath = filePathRoot + "/Output/" + BOLLINGER_BANDS_FOLDER_NAME + "/" + "Multi-Period-Market" + "/" + timeFrame;
let fileName = 'Data.json';
let filePath = bot.filePathRoot + "/Output/" + BOLLINGER_BANDS_FOLDER_NAME + "/" + "Multi-Period-Market" + "/" + timeFrame;
filePath += '/' + fileName
fileStorage.createTextFile(filePath, fileContent + '\n', onFileCreated);
@@ -369,10 +367,8 @@
fileContent = "[" + fileContent + "]";
let fileName = '' + market.baseAsset + '_' + market.quotedAsset + '.json';
let filePathRoot = bot.dataMine + "/" + bot.codeName + "/" + bot.exchange;
let filePath = filePathRoot + "/Output/" + PERCENTAGE_BANDWIDTH_FOLDER_NAME + "/" + "Multi-Period-Market" + "/" + timeFrame;
let fileName = 'Data.json';
let filePath = bot.filePathRoot + "/Output/" + PERCENTAGE_BANDWIDTH_FOLDER_NAME + "/" + "Multi-Period-Market" + "/" + timeFrame;
filePath += '/' + fileName
fileStorage.createTextFile(filePath, fileContent + '\n', onFileCreated);
@@ -467,7 +463,7 @@
try {
let reportKey = "AAMasters" + "-" + "AAChris" + "-" + "Multi-Period-Market" + "-" + "dataSet.V1";
let reportKey = "Masters" + "-" + "Bollinger-Bands" + "-" + "Multi-Period-Market" + "-" + "dataSet.V1";
let thisReport = statusDependencies.statusReports.get(reportKey);
thisReport.file.lastExecution = bot.processDatetime;
@@ -1,14 +1,14 @@
{
"displayName": "Chris",
"codeName": "AAChris",
"displayName": "Bollinger Bands",
"codeName": "Bollinger-Bands",
"type": "Indicator Bot",
"version": {
"major": 1,
"minor": 0,
"patch": 0
},
"dataMine": "AAMasters",
"profilePicture": "Chris.png",
"dataMine": "Masters",
"profilePicture": "Bollinger Bands.png",
"dataSetVersion": "dataSet.V1",
"processes": [
{
@@ -50,8 +50,8 @@
],
"statusDependencies": [
{
"dataMine": "AAMasters",
"bot": "AAChris",
"dataMine": "Masters",
"bot": "Bollinger-Bands",
"botVersion": {
"major": 1,
"minor": 0
@@ -60,8 +60,8 @@
"dataSetVersion": "dataSet.V1"
},
{
"dataMine": "AAMasters",
"bot": "AAOlivia",
"dataMine": "Masters",
"bot": "Candles-Volumes",
"botVersion": {
"major": 1,
"minor": 0
@@ -111,8 +111,8 @@
],
"statusDependencies": [
{
"dataMine": "AAMasters",
"bot": "AACharly",
"dataMine": "Masters",
"bot": "Exchange-Raw-Data",
"botVersion": {
"major": 1,
"minor": 0
@@ -121,8 +121,8 @@
"dataSetVersion": "dataSet.V1"
},
{
"dataMine": "AAMasters",
"bot": "AAOlivia",
"dataMine": "Masters",
"bot": "Candles-Volumes",
"botVersion": {
"major": 1,
"minor": 0
@@ -132,8 +132,8 @@
"waitUntilNextUpdate": true
},
{
"dataMine": "AAMasters",
"bot": "AAChris",
"dataMine": "Masters",
"bot": "Bollinger-Bands",
"botVersion": {
"major": 1,
"minor": 0
@@ -149,24 +149,24 @@
"codeName": "Bollinger-Bands",
"displayName": "Bollinger Bands",
"description": "Bollinger Bands",
"storageAccount": "aachris",
"storageAccount": "Bollinger-Bands",
"shareWith": "Public",
"dataSets": [
{
"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/AAChris.1.0/AACloud.1.1/@Exchange/dataSet.V1/Output/Bollinger-Bands/Multi-Period-Market/@Period",
"filePath": "Masters/Bollinger-Bands.1.0/AACloud.1.1/@Exchange/dataSet.V1/Output/Bollinger-Bands/Multi-Period-Market/@Period",
"fileName": "@AssetA_@AssetB.json"
},
{
"codeName": "Multi-Period-Daily",
"type": "Daily Files",
"validPeriods": [ "45-min", "40-min", "30-min", "20-min", "15-min", "10-min", "05-min", "04-min", "03-min", "02-min", "01-min" ],
"filePath": "AAMasters/AAChris.1.0/AACloud.1.1/@Exchange/dataSet.V1/Output/Bollinger-Bands/Multi-Period-Daily/@Period/@Year/@Month/@Day",
"filePath": "Masters/Bollinger-Bands.1.0/AACloud.1.1/@Exchange/dataSet.V1/Output/Bollinger-Bands/Multi-Period-Daily/@Period/@Year/@Month/@Day",
"fileName": "@AssetA_@AssetB.json",
"dataRange": {
"filePath": "AAMasters/AAChris.1.0/AACloud.1.1/@Exchange/dataSet.V1/Output/Bollinger-Bands/Multi-Period-Daily",
"filePath": "Masters/Bollinger-Bands.1.0/AACloud.1.1/@Exchange/dataSet.V1/Output/Bollinger-Bands/Multi-Period-Daily",
"fileName": "Data.Range.@AssetA_@AssetB.json"
}
}
@@ -180,7 +180,7 @@
}
],
"plotter": {
"dataMine": "AAMasters",
"dataMine": "Masters",
"codeName": "PlottersBollingerBands",
"moduleName": "BollingerBands"
}
@@ -189,24 +189,24 @@
"codeName": "Percentage-Bandwidth",
"displayName": "Percentage Bandwidth",
"description": "Percentage Bandwidth",
"storageAccount": "aachris",
"storageAccount": "Bollinger-Bands",
"shareWith": "Public",
"dataSets": [
{
"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/AAChris.1.0/AACloud.1.1/@Exchange/dataSet.V1/Output/Percentage-Bandwidth/Multi-Period-Market/@Period",
"filePath": "Masters/Bollinger-Bands.1.0/AACloud.1.1/@Exchange/dataSet.V1/Output/Percentage-Bandwidth/Multi-Period-Market/@Period",
"fileName": "@AssetA_@AssetB.json"
},
{
"codeName": "Multi-Period-Daily",
"type": "Daily Files",
"validPeriods": [ "45-min", "40-min", "30-min", "20-min", "15-min", "10-min", "05-min", "04-min", "03-min", "02-min", "01-min" ],
"filePath": "AAMasters/AAChris.1.0/AACloud.1.1/@Exchange/dataSet.V1/Output/Percentage-Bandwidth/Multi-Period-Daily/@Period/@Year/@Month/@Day",
"filePath": "Masters/Bollinger-Bands.1.0/AACloud.1.1/@Exchange/dataSet.V1/Output/Percentage-Bandwidth/Multi-Period-Daily/@Period/@Year/@Month/@Day",
"fileName": "@AssetA_@AssetB.json",
"dataRange": {
"filePath": "AAMasters/AAChris.1.0/AACloud.1.1/@Exchange/dataSet.V1/Output/Percentage-Bandwidth/Multi-Period-Daily",
"filePath": "Masters/Bollinger-Bands.1.0/AACloud.1.1/@Exchange/dataSet.V1/Output/Percentage-Bandwidth/Multi-Period-Daily",
"fileName": "Data.Range.@AssetA_@AssetB.json"
}
}
@@ -220,7 +220,7 @@
}
],
"plotter": {
"dataMine": "AAMasters",
"dataMine": "Masters",
"codeName": "PlottersBollingerBands",
"moduleName": "PercentageBandwidth"
}
@@ -52,7 +52,7 @@
This process is going to do the following:
Read the candles and volumes from Charly and produce a file for each day and for each period with candles and volumes.
Read the candles and volumes from Exchange Raw Data and produce a file for each day and for each period with candles and volumes.
*/
@@ -84,9 +84,9 @@ Read the candles and volumes from Charly and produce a file for each day and for
let reportKey;
let statusReport;
/* We look first for Charly in order to get when the market starts. */
/* We look first for Exchange Raw Data in order to get when the market starts. */
reportKey = "AAMasters" + "-" + "AACharly" + "-" + "Historic-OHLCVs" + "-" + "dataSet.V1";
reportKey = "Masters" + "-" + "Exchange-Raw-Data" + "-" + "Historic-OHLCVs" + "-" + "dataSet.V1";
if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] start -> getContextVariables -> reportKey = " + reportKey); }
statusReport = statusDependencies.statusReports.get(reportKey);
@@ -120,9 +120,9 @@ Read the candles and volumes from Charly and produce a file for each day and for
contextVariables.firstTradeFile = new Date(thisReport.beginingOfMarket.year + "-" + thisReport.beginingOfMarket.month + "-" + thisReport.beginingOfMarket.days + " " + thisReport.beginingOfMarket.hours + ":" + thisReport.beginingOfMarket.minutes + GMT_SECONDS);
/* Second, we get the report from Charly, to know when the marted ends. */
/* Second, we get the report from Exchange Raw Data, to know when the marted ends. */
reportKey = "AAMasters" + "-" + "AACharly" + "-" + "Historic-OHLCVs" + "-" + "dataSet.V1"
reportKey = "Masters" + "-" + "Exchange-Raw-Data" + "-" + "Historic-OHLCVs" + "-" + "dataSet.V1"
if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] start -> getContextVariables -> reportKey = " + reportKey); }
statusReport = statusDependencies.statusReports.get(reportKey);
@@ -157,7 +157,7 @@ Read the candles and volumes from Charly and produce a file for each day and for
/* Finally we get our own Status Report. */
reportKey = "AAMasters" + "-" + "AAOlivia" + "-" + "Multi-Period-Daily" + "-" + "dataSet.V1";
reportKey = "Masters" + "-" + "Candles-Volumes" + "-" + "Multi-Period-Daily" + "-" + "dataSet.V1";
if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] start -> getContextVariables -> reportKey = " + reportKey); }
statusReport = statusDependencies.statusReports.get(reportKey);
@@ -303,8 +303,8 @@ Read the candles and volumes from Charly and produce a file for each day and for
if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] start -> buildCandles -> periodsLoop -> loopBody -> nextCandleFile -> Entering function."); }
let dateForPath = contextVariables.lastCandleFile.getUTCFullYear() + '/' + utilities.pad(contextVariables.lastCandleFile.getUTCMonth() + 1, 2) + '/' + utilities.pad(contextVariables.lastCandleFile.getUTCDate(), 2);
let fileName = market.baseAsset + '_' + market.quotedAsset + ".json"
let filePathRoot = bot.dataMine + "/" + "AACharly" + "/" + bot.exchange;
let fileName = "Data.json"
let filePathRoot = bot.exchange + "/" + bot.market.baseAsset + "-" + bot.market.quotedAsset + "/" + bot.dataMine + "/" + "Exchange-Raw-Data";
let filePath = filePathRoot + "/Output/" + CANDLES_FOLDER_NAME + '/' + CANDLES_ONE_MIN + '/' + dateForPath;
filePath += '/' + fileName
@@ -429,8 +429,8 @@ Read the candles and volumes from Charly and produce a file for each day and for
if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] start -> buildCandles -> periodsLoop -> loopBody -> nextVolumeFile -> Entering function."); }
let dateForPath = contextVariables.lastCandleFile.getUTCFullYear() + '/' + utilities.pad(contextVariables.lastCandleFile.getUTCMonth() + 1, 2) + '/' + utilities.pad(contextVariables.lastCandleFile.getUTCDate(), 2);
let fileName = market.baseAsset + '_' + market.quotedAsset + ".json"
let filePathRoot = bot.dataMine + "/" + "AACharly" + "/" + bot.exchange;
let fileName = "Data.json"
let filePathRoot = bot.exchange + "/" + bot.market.baseAsset + "-" + bot.market.quotedAsset + "/" + bot.dataMine + "/" + "Exchange-Raw-Data";
let filePath = filePathRoot + "/Output/" + VOLUMES_FOLDER_NAME + '/' + VOLUMES_ONE_MIN + '/' + dateForPath;
filePath += '/' + fileName
@@ -592,7 +592,7 @@ Read the candles and volumes from Charly and produce a file for each day and for
fileContent = "[" + fileContent + "]";
let fileName = '' + market.baseAsset + '_' + market.quotedAsset + '.json';
let fileName = 'Data.json';
let dateForPath = contextVariables.lastCandleFile.getUTCFullYear() + '/' + utilities.pad(contextVariables.lastCandleFile.getUTCMonth() + 1, 2) + '/' + utilities.pad(contextVariables.lastCandleFile.getUTCDate(), 2);
let filePath = bot.filePathRoot + "/Output/" + CANDLES_FOLDER_NAME + "/" + bot.process + "/" + timeFrame + "/" + dateForPath;
filePath += '/' + fileName
@@ -643,7 +643,7 @@ Read the candles and volumes from Charly and produce a file for each day and for
fileContent = "[" + fileContent + "]";
let fileName = '' + market.baseAsset + '_' + market.quotedAsset + '.json';
let fileName = 'Data.json';
let dateForPath = contextVariables.lastCandleFile.getUTCFullYear() + '/' + utilities.pad(contextVariables.lastCandleFile.getUTCMonth() + 1, 2) + '/' + utilities.pad(contextVariables.lastCandleFile.getUTCDate(), 2);
let filePath = bot.filePathRoot + "/Output/" + VOLUMES_FOLDER_NAME + "/" + bot.process + "/" + timeFrame + "/" + dateForPath;
filePath += '/' + fileName
@@ -732,7 +732,7 @@ Read the candles and volumes from Charly and produce a file for each day and for
let fileContent = JSON.stringify(dataRange);
let fileName = 'Data.Range.' + market.baseAsset + '_' + market.quotedAsset + '.json';
let fileName = 'Data.Range.json';
let filePath = bot.filePathRoot + "/Output/" + pProductFolder + "/" + bot.process;
filePath += '/' + fileName
@@ -775,7 +775,7 @@ Read the candles and volumes from Charly and produce a file for each day and for
try {
let reportKey = "AAMasters" + "-" + "AAOlivia" + "-" + "Multi-Period-Daily" + "-" + "dataSet.V1";
let reportKey = "Masters" + "-" + "Candles-Volumes" + "-" + "Multi-Period-Daily" + "-" + "dataSet.V1";
let thisReport = statusDependencies.statusReports.get(reportKey);
thisReport.file.lastExecution = bot.processDatetime;
@@ -50,16 +50,16 @@
This process is going to do the following:
Read the candles and volumes from Charly and produce a single Index File for Market Period. But this is the situation:
Read the candles and volumes from Exchange Raw Data and produce a single Index File for Market Period. But this is the situation:
Charly has a dataset organized with daily files with candles of 1 min. Olivia is writting in this process a single file for each timeFrame for the whole market.
Exchange Raw Data has a dataset organized with daily files with candles of 1 min. Candles Volumes is writting in this process a single file for each timeFrame for the whole market.
Everytime this process run, must be able to resume its job and process everything pending until reaching the head of the market. So the tactic to do this is the
following:
1. First we need to read the last file written by this process, and load all the information into in-memory arrays. We will then append to this arrays the new
information we will get from Charly.
information we will get from Exchange Raw Data.
2. We know from out status report which was the last DAY we processed from Charly, but we must be carefull, because that day mightn not have been complete, if the
2. We know from out status report which was the last DAY we processed from Exchange Raw Data, but we must be carefull, because that day mightn not have been complete, if the
last run found the head of the market. That means that we have to be carefull not to append candles that are already there. To simplify what we do is to discard
all candles of the last processed day, and then we can process that full day again adding all the candles.
@@ -93,9 +93,9 @@
let reportKey;
let statusReport;
/* We look first for Charly in order to get when the market starts. */
/* We look first for Exchange Raw Data in order to get when the market starts. */
reportKey = "AAMasters" + "-" + "AACharly" + "-" + "Historic-OHLCVs" + "-" + "dataSet.V1";
reportKey = "Masters" + "-" + "Exchange-Raw-Data" + "-" + "Historic-OHLCVs" + "-" + "dataSet.V1";
if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] start -> getContextVariables -> reportKey = " + reportKey); }
statusReport = statusDependencies.statusReports.get(reportKey);
@@ -129,9 +129,9 @@
contextVariables.firstTradeFile = new Date(thisReport.beginingOfMarket.year + "-" + thisReport.beginingOfMarket.month + "-" + thisReport.beginingOfMarket.days + " " + thisReport.beginingOfMarket.hours + ":" + thisReport.beginingOfMarket.minutes + GMT_SECONDS);
/* Second, we get the report from Charly, to know when the marted ends. */
/* Second, we get the report from Exchange Raw Data, to know when the marted ends. */
reportKey = "AAMasters" + "-" + "AACharly" + "-" + "Historic-OHLCVs" + "-" + "dataSet.V1"
reportKey = "Masters" + "-" + "Exchange-Raw-Data" + "-" + "Historic-OHLCVs" + "-" + "dataSet.V1"
if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] start -> getContextVariables -> reportKey = " + reportKey); }
statusReport = statusDependencies.statusReports.get(reportKey);
@@ -166,7 +166,7 @@
/* Finally we get our own Status Report. */
reportKey = "AAMasters" + "-" + "AAOlivia" + "-" + "Multi-Period-Market" + "-" + "dataSet.V1";
reportKey = "Masters" + "-" + "Candles-Volumes" + "-" + "Multi-Period-Market" + "-" + "dataSet.V1";
if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] start -> getContextVariables -> reportKey = " + reportKey); }
statusReport = statusDependencies.statusReports.get(reportKey);
@@ -269,7 +269,7 @@
if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] start -> findPreviousContent -> loopBody -> getCandles -> Entering function."); }
let fileName = '' + market.baseAsset + '_' + market.quotedAsset + '.json';
let fileName = 'Data.json';
let filePath = bot.filePathRoot + "/Output/" + CANDLES_FOLDER_NAME + "/" + bot.process + "/" + timeFrame;
filePath += '/' + fileName
@@ -308,7 +308,7 @@
if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] start -> findPreviousContent -> loopBody -> getVolumes -> Entering function."); }
let fileName = '' + market.baseAsset + '_' + market.quotedAsset + '.json';
let fileName = 'Data.json';
let filePath = bot.filePathRoot + "/Output/" + VOLUMES_FOLDER_NAME + "/" + bot.process + "/" + timeFrame;
filePath += '/' + fileName
@@ -452,12 +452,12 @@
const timeFrame = global.marketFilesPeriods[n][1];
/*
Here we are inside a Loop that is going to advance 1 day at the time, at each pass, will ready one of Charly's daily files and
Here we are inside a Loop that is going to advance 1 day at the time, at each pass, will ready one of Exchange Raw Data's daily files and
add all its candles to our in memory arrays. At the first iteration of this loop, we will add the candles that we are carrying
from our previous run, the ones we already have in-memory. You can see below how we discard from those candles the ones that
are belonging to the first day we are processing at this run, that it is exactly the same as the last day processed the privious
run. By discarding these candles, we are ready to run after that standard function that will just add ALL the candles found each
day at Charly.
day at Exchange Raw Data.
*/
if (previousCandles !== undefined) {
@@ -507,7 +507,7 @@
}
/*
From here on is where every iteration of the loop fully runs. Here is where we read Charly's files and add their content to whatever
From here on is where every iteration of the loop fully runs. Here is where we read Exchange Raw Data's files and add their content to whatever
we already have in our arrays in-memory. In this way the process will run as many days needed and it should only stop when it reaches
the head of the market.
*/
@@ -519,8 +519,8 @@
if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] start -> buildCandles -> periodsLoop -> loopBody -> nextCandleFile -> Entering function."); }
let dateForPath = contextVariables.lastCandleFile.getUTCFullYear() + '/' + utilities.pad(contextVariables.lastCandleFile.getUTCMonth() + 1, 2) + '/' + utilities.pad(contextVariables.lastCandleFile.getUTCDate(), 2);
let fileName = market.baseAsset + '_' + market.quotedAsset + ".json"
let filePathRoot = bot.dataMine + "/" + "AACharly" + "/" + bot.exchange;
let fileName = "Data.json"
let filePathRoot = bot.exchange + "/" + bot.market.baseAsset + "-" + bot.market.quotedAsset + "/" + bot.dataMine + "/" + "Exchange-Raw-Data";
let filePath = filePathRoot + "/Output/" + CANDLES_FOLDER_NAME + '/' + CANDLES_ONE_MIN + '/' + dateForPath;
filePath += '/' + fileName
@@ -570,8 +570,8 @@
let beginingOutputTime = contextVariables.lastCandleFile.valueOf();
/*
The algorithm that follows is going to agregate candles of 1 min timeFrame read from Charly, into candles of each timeFrame
that Olivia generates. For market files those timePediods goes from 1h to 24hs.
The algorithm that follows is going to agregate candles of 1 min timeFrame read from Exchange Raw Data, into candles of each timeFrame
that Candles Volumes generates. For market files those timePediods goes from 1h to 24hs.
*/
for (let i = 0; i < totalOutputCandles; i++) {
@@ -650,8 +650,8 @@
if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] start -> buildCandles -> periodsLoop -> loopBody -> nextVolumeFile -> Entering function."); }
let dateForPath = contextVariables.lastCandleFile.getUTCFullYear() + '/' + utilities.pad(contextVariables.lastCandleFile.getUTCMonth() + 1, 2) + '/' + utilities.pad(contextVariables.lastCandleFile.getUTCDate(), 2);
let fileName = market.baseAsset + '_' + market.quotedAsset + ".json"
let filePathRoot = bot.dataMine + "/" + "AACharly" + "/" + bot.exchange;
let fileName = "Data.json"
let filePathRoot = bot.exchange + "/" + bot.market.baseAsset + "-" + bot.market.quotedAsset + "/" + bot.dataMine + "/" + "Exchange-Raw-Data";
let filePath = filePathRoot + "/Output/" + VOLUMES_FOLDER_NAME + '/' + VOLUMES_ONE_MIN + '/' + dateForPath;
filePath += '/' + fileName
@@ -797,7 +797,7 @@
fileContent = "[" + fileContent + "]";
let fileName = '' + market.baseAsset + '_' + market.quotedAsset + '.json';
let fileName = 'Data.json';
let filePath = bot.filePathRoot + "/Output/" + CANDLES_FOLDER_NAME + "/" + bot.process + "/" + timeFrame;
filePath += '/' + fileName
@@ -847,7 +847,7 @@
fileContent = "[" + fileContent + "]";
let fileName = '' + market.baseAsset + '_' + market.quotedAsset + '.json';
let fileName = 'Data.json';
let filePath = bot.filePathRoot + "/Output/" + VOLUMES_FOLDER_NAME + "/" + bot.process + "/" + timeFrame;
filePath += '/' + fileName
@@ -888,7 +888,7 @@
try {
let reportKey = "AAMasters" + "-" + "AAOlivia" + "-" + "Multi-Period-Market" + "-" + "dataSet.V1";
let reportKey = "Masters" + "-" + "Candles-Volumes" + "-" + "Multi-Period-Market" + "-" + "dataSet.V1";
let thisReport = statusDependencies.statusReports.get(reportKey);
thisReport.file.lastExecution = bot.processDatetime;
@@ -1,14 +1,14 @@
{
"displayName": "Olivia",
"codeName": "AAOlivia",
"displayName": "Candles Volumes",
"codeName": "Candles-Volumes",
"type": "Indicator Bot",
"version": {
"major": 1,
"minor": 0,
"patch": 0
},
"dataMine": "AAMasters",
"profilePicture": "Olivia.png",
"dataMine": "Masters",
"profilePicture": "Candles Volumes.png",
"dataSetVersion": "dataSet.V1",
"processes": [
{
@@ -50,8 +50,8 @@
],
"statusDependencies": [
{
"dataMine": "AAMasters",
"bot": "AACharly",
"dataMine": "Masters",
"bot": "Exchange-Raw-Data",
"botVersion": {
"major": 1,
"minor": 0
@@ -60,8 +60,8 @@
"dataSetVersion": "dataSet.V1"
},
{
"dataMine": "AAMasters",
"bot": "AACharly",
"dataMine": "Masters",
"bot": "Exchange-Raw-Data",
"botVersion": {
"major": 1,
"minor": 0
@@ -72,8 +72,8 @@
"waitUntilNextUpdate": true
},
{
"dataMine": "AAMasters",
"bot": "AAOlivia",
"dataMine": "Masters",
"bot": "Candles-Volumes",
"botVersion": {
"major": 1,
"minor": 0
@@ -122,8 +122,8 @@
],
"statusDependencies": [
{
"dataMine": "AAMasters",
"bot": "AACharly",
"dataMine": "Masters",
"bot": "Exchange-Raw-Data",
"botVersion": {
"major": 1,
"minor": 0
@@ -132,8 +132,8 @@
"dataSetVersion": "dataSet.V1"
},
{
"dataMine": "AAMasters",
"bot": "AACharly",
"dataMine": "Masters",
"bot": "Exchange-Raw-Data",
"botVersion": {
"major": 1,
"minor": 0
@@ -144,8 +144,8 @@
"waitUntilNextUpdate": true
},
{
"dataMine": "AAMasters",
"bot": "AAOlivia",
"dataMine": "Masters",
"bot": "Candles-Volumes",
"botVersion": {
"major": 1,
"minor": 0
@@ -161,24 +161,24 @@
"codeName": "Candles",
"displayName": "Candles",
"description": "Two sets of files per period that contains candles.",
"storageAccount": "aaolivia",
"storageAccount": "Candles-Volumes",
"shareWith": "Public",
"dataSets": [
{
"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/AAOlivia.1.0/AACloud.1.1/@Exchange/dataSet.V1/Output/Candles/Multi-Period-Market/@Period",
"filePath": "Masters/Candles-Volumes.1.0/AACloud.1.1/@Exchange/dataSet.V1/Output/Candles/Multi-Period-Market/@Period",
"fileName": "@AssetA_@AssetB.json"
},
{
"codeName": "Multi-Period-Daily",
"type": "Daily Files",
"validPeriods": [ "45-min", "40-min", "30-min", "20-min", "15-min", "10-min", "05-min", "04-min", "03-min", "02-min", "01-min" ],
"filePath": "AAMasters/AAOlivia.1.0/AACloud.1.1/@Exchange/dataSet.V1/Output/Candles/Multi-Period-Daily/@Period/@Year/@Month/@Day",
"filePath": "Masters/Candles-Volumes.1.0/AACloud.1.1/@Exchange/dataSet.V1/Output/Candles/Multi-Period-Daily/@Period/@Year/@Month/@Day",
"fileName": "@AssetA_@AssetB.json",
"dataRange": {
"filePath": "AAMasters/AAOlivia.1.0/AACloud.1.1/@Exchange/dataSet.V1/Output/Candles/Multi-Period-Daily",
"filePath": "Masters/Candles-Volumes.1.0/AACloud.1.1/@Exchange/dataSet.V1/Output/Candles/Multi-Period-Daily",
"fileName": "Data.Range.@AssetA_@AssetB.json"
}
}
@@ -192,7 +192,7 @@
}
],
"plotter": {
"dataMine": "AAMasters",
"dataMine": "Masters",
"codeName": "PlottersCandlesVolumes",
"moduleName": "Candles"
}
@@ -201,24 +201,24 @@
"codeName": "Volumes",
"displayName": "Buy and Sell Volumes",
"description": "Two sets of files per period that contains buy and sell volumes.",
"storageAccount": "aaolivia",
"storageAccount": "Candles-Volumes",
"shareWith": "Public",
"dataSets": [
{
"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/AAOlivia.1.0/AACloud.1.1/@Exchange/dataSet.V1/Output/Volumes/Multi-Period-Market/@Period",
"filePath": "Masters/Candles-Volumes.1.0/AACloud.1.1/@Exchange/dataSet.V1/Output/Volumes/Multi-Period-Market/@Period",
"fileName": "@AssetA_@AssetB.json"
},
{
"codeName": "Multi-Period-Daily",
"type": "Daily Files",
"validPeriods": [ "45-min", "40-min", "30-min", "20-min", "15-min", "10-min", "05-min", "04-min", "03-min", "02-min", "01-min" ],
"filePath": "AAMasters/AAOlivia.1.0/AACloud.1.1/@Exchange/dataSet.V1/Output/Volumes/Multi-Period-Daily/@Period/@Year/@Month/@Day",
"filePath": "Masters/Candles-Volumes.1.0/AACloud.1.1/@Exchange/dataSet.V1/Output/Volumes/Multi-Period-Daily/@Period/@Year/@Month/@Day",
"fileName": "@AssetA_@AssetB.json",
"dataRange": {
"filePath": "AAMasters/AAOlivia.1.0/AACloud.1.1/@Exchange/dataSet.V1/Output/Volumes/Multi-Period-Daily",
"filePath": "Masters/Candles-Volumes.1.0/AACloud.1.1/@Exchange/dataSet.V1/Output/Volumes/Multi-Period-Daily",
"fileName": "Data.Range.@AssetA_@AssetB.json"
}
}
@@ -232,7 +232,7 @@
}
],
"plotter": {
"dataMine": "AAMasters",
"dataMine": "Masters",
"codeName": "PlottersCandlesVolumes",
"moduleName": "Volumes"
}
@@ -41,6 +41,7 @@ exports.newUserBot = function newUserBot(bot, logger, COMMONS, UTILITIES, fileSt
let fisrtTimeThisProcessRun = false
let limit = 1000 // This is the default value
let hostname
let lastCandleOfTheDay
return thisObject;
@@ -122,22 +123,6 @@ exports.newUserBot = function newUserBot(bot, logger, COMMONS, UTILITIES, fileSt
function start(callBackFunction) {
try {
let lastCandle = {
begin: 0,
end: 0,
open: 0,
close: 0,
min: 0,
max: 0
}
let lastVolume = {
begin: 0,
end: 0,
buy: 0,
sell: 0
}
if (global.STOP_TASK_GRACEFULLY === true) {
callBackFunction(global.DEFAULT_OK_RESPONSE);
return
@@ -165,7 +150,7 @@ exports.newUserBot = function newUserBot(bot, logger, COMMONS, UTILITIES, fileSt
try {
let reportKey;
reportKey = "AAMasters" + "-" + "AACharly" + "-" + "Historic-OHLCVs" + "-" + "dataSet.V1";
reportKey = "Masters" + "-" + "Exchange-Raw-Data" + "-" + "Historic-OHLCVs" + "-" + "dataSet.V1";
if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] start -> getContextVariables -> reportKey = " + reportKey); }
if (statusDependencies.statusReports.get(reportKey).status === "Status Report is corrupt.") {
@@ -180,6 +165,7 @@ exports.newUserBot = function newUserBot(bot, logger, COMMONS, UTILITIES, fileSt
beginingOfMarket = new Date(thisReport.file.beginingOfMarket.year + "-" + thisReport.file.beginingOfMarket.month + "-" + thisReport.file.beginingOfMarket.days + " " + thisReport.file.beginingOfMarket.hours + ":" + thisReport.file.beginingOfMarket.minutes + GMT_SECONDS);
lastFile = new Date(thisReport.file.lastFile.year + "-" + thisReport.file.lastFile.month + "-" + thisReport.file.lastFile.days + " " + thisReport.file.lastFile.hours + ":" + thisReport.file.lastFile.minutes + GMT_SECONDS);
lastId = thisReport.file.lastId
lastCandleOfTheDay = thisReport.file.lastCandleOfTheDay
} else { // This means this is the first time this process run.
fisrtTimeThisProcessRun = true
beginingOfMarket = new Date(uiStartDate.valueOf())
@@ -368,9 +354,29 @@ exports.newUserBot = function newUserBot(bot, logger, COMMONS, UTILITIES, fileSt
let heartBeatCounter = 0
let headOfTheMarketReached = false
let lastCandle = {
begin: 0,
end: 0,
open: 0,
close: 0,
min: 0,
max: 0
}
let lastVolume = {
begin: 0,
end: 0,
buy: 0,
sell: 0
}
let i = 0
lastId = undefined
if (lastCandleOfTheDay !== undefined) {
lastCandle = JSON.parse(JSON.stringify(lastCandleOfTheDay))
}
controlLoop()
function loop() {
@@ -501,10 +507,13 @@ exports.newUserBot = function newUserBot(bot, logger, COMMONS, UTILITIES, fileSt
}
/* Add the candle to the file content.*/
candlesFileContent = candlesFileContent + separator + '[' + candle.min + "," + candle.max + "," + candle.open + "," + candle.close + "," + candle.begin + "," + candle.end + "]";
volumesFileContent = volumesFileContent + separator + '[' + volume.buy + "," + volume.sell + "," + volume.begin + "," + volume.end + "]";
/* We store the last candle of the day in order to have a previous candles during next execution. */
if (j === 1440 - 1) {
lastCandleOfTheDay = JSON.parse(JSON.stringify(candle))
}
}
previousDay = currentDay
@@ -520,7 +529,7 @@ exports.newUserBot = function newUserBot(bot, logger, COMMONS, UTILITIES, fileSt
candlesFileContent = candlesFileContent + ']'
volumesFileContent = volumesFileContent + ']'
let fileName = bot.market.baseAsset + '_' + bot.market.quotedAsset + '.json'
let fileName = 'Data.json'
filesToCreate++
fileStorage.createTextFile(getFilePath(day * ONE_DAY, CANDLES_FOLDER_NAME) + '/' + fileName, candlesFileContent + '\n', onFileCreated);
@@ -602,7 +611,8 @@ exports.newUserBot = function newUserBot(bot, logger, COMMONS, UTILITIES, fileSt
hours: beginingOfMarket.getUTCHours(),
minutes: beginingOfMarket.getUTCMinutes()
},
uiStartDate: uiStartDate.toUTCString()
uiStartDate: uiStartDate.toUTCString(),
lastCandleOfTheDay: lastCandleOfTheDay
};
if (fetchType === "by Id") {
@@ -135,7 +135,7 @@ exports.newUserBot = function newUserBot(bot, logger, COMMONS, UTILITIES, fileSt
try {
let reportKey;
reportKey = "AAMasters" + "-" + "AACharly" + "-" + "Historic-Trades" + "-" + "dataSet.V1";
reportKey = "Masters" + "-" + "Exchange-Raw-Data" + "-" + "Historic-Trades" + "-" + "dataSet.V1";
if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] start -> getContextVariables -> reportKey = " + reportKey); }
if (statusDependencies.statusReports.get(reportKey).status === "Status Report is corrupt.") {
@@ -376,7 +376,7 @@ exports.newUserBot = function newUserBot(bot, logger, COMMONS, UTILITIES, fileSt
if (currentRecordMinute - previousRecordMinute > 1) {
createMissingEmptyFiles(previousRecordMinute, currentRecordMinute)
}
let fileName = bot.market.baseAsset + '_' + bot.market.quotedAsset + '.json'
let fileName = 'Data.json'
if (previousRecordMinute >= initialProcessTimestamp / ONE_MINUTE) {
filesToCreate++
fileStorage.createTextFile(getFilePath(minute * ONE_MINUTE) + '/' + fileName, fileContent + '\n', onFileCreated);
@@ -398,7 +398,7 @@ exports.newUserBot = function newUserBot(bot, logger, COMMONS, UTILITIES, fileSt
}
for (let j = begin + 1; j < end; j++) {
let fileName = bot.market.baseAsset + '_' + bot.market.quotedAsset + '.json'
let fileName = 'Data.json'
filesToCreate++
fileStorage.createTextFile(getFilePath(j * ONE_MINUTE) + '/' + fileName, "[]" + '\n', onFileCreated);
@@ -1,14 +1,14 @@
{
"displayName": "Charly",
"codeName": "AACharly",
"displayName": "Exchange Raw Data",
"codeName": "Exchange-Raw-Data",
"type": "Sensor Bot",
"version": {
"major": 1,
"minor": 0,
"patch": 0
},
"dataMine": "AAMasters",
"profilePicture": "Charly.png",
"dataMine": "Masters",
"profilePicture": "Exchange Raw Data.png",
"dataSetVersion": "dataSet.V1",
"processes": [
{
@@ -40,8 +40,8 @@
"comaWaitTime": 86400000,
"statusDependencies": [
{
"dataMine": "AAMasters",
"bot": "AACharly",
"dataMine": "Masters",
"bot": "Exchange-Raw-Data",
"botVersion": {
"major": 1,
"minor": 0
@@ -80,8 +80,8 @@
"comaWaitTime": 86400000,
"statusDependencies": [
{
"dataMine": "AAMasters",
"bot": "AACharly",
"dataMine": "Masters",
"bot": "Exchange-Raw-Data",
"botVersion": {
"major": 1,
"minor": 0
@@ -90,8 +90,8 @@
"dataSetVersion": "dataSet.V1"
},
{
"dataMine": "AAMasters",
"bot": "AACharly",
"dataMine": "Masters",
"bot": "Exchange-Raw-Data",
"botVersion": {
"major": 1,
"minor": 0
@@ -130,8 +130,8 @@
"comaWaitTime": 86400000,
"statusDependencies": [
{
"dataMine": "AAMasters",
"bot": "AACharly",
"dataMine": "Masters",
"bot": "Exchange-Raw-Data",
"botVersion": {
"major": 1,
"minor": 0
@@ -141,8 +141,8 @@
"waitUntilNextUpdate": true
},
{
"dataMine": "AAMasters",
"bot": "AACharly",
"dataMine": "Masters",
"bot": "Exchange-Raw-Data",
"botVersion": {
"major": 1,
"minor": 0
@@ -151,8 +151,8 @@
"dataSetVersion": "dataSet.V1"
},
{
"dataMine": "AAMasters",
"bot": "AACharly",
"dataMine": "Masters",
"bot": "Exchange-Raw-Data",
"botVersion": {
"major": 1,
"minor": 0
@@ -162,8 +162,8 @@
"dataSetSection": "Month"
},
{
"dataMine": "AAMasters",
"bot": "AACharly",
"dataMine": "Masters",
"bot": "Exchange-Raw-Data",
"botVersion": {
"major": 1,
"minor": 0
@@ -52,7 +52,7 @@
This process is going to do the following:
Read the candles and volumes from Olivia and produce for each market two files with candles stairs and volumes stairs respectively.
Read the candles and volumes from Candles Volumes and produce for each market two files with candles stairs and volumes stairs respectively.
*/
@@ -92,9 +92,9 @@
let reportKey;
let statusReport;
/* We look first for Charly in order to get when the market starts. */
/* We look first for Exchange Raw Data in order to get when the market starts. */
reportKey = "AAMasters" + "-" + "AACharly" + "-" + "Historic-Trades" + "-" + "dataSet.V1";
reportKey = "Masters" + "-" + "Exchange-Raw-Data" + "-" + "Historic-Trades" + "-" + "dataSet.V1";
if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] start -> getContextVariables -> reportKey = " + reportKey); }
statusReport = statusDependencies.statusReports.get(reportKey);
@@ -128,9 +128,9 @@
contextVariables.firstTradeFile = new Date(thisReport.beginingOfMarket.year + "-" + thisReport.beginingOfMarket.month + "-" + thisReport.beginingOfMarket.days + " " + thisReport.beginingOfMarket.hours + ":" + thisReport.beginingOfMarket.minutes + GMT_SECONDS);
/* Second, we get the report from Olivia, to know when the marted ends. */
/* Second, we get the report from Candles Volumes, to know when the marted ends. */
reportKey = "AAMasters" + "-" + "AAOlivia" + "-" + "Multi-Period-Daily" + "-" + "dataSet.V1";
reportKey = "Masters" + "-" + "Candles-Volumes" + "-" + "Multi-Period-Daily" + "-" + "dataSet.V1";
if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] start -> getContextVariables -> reportKey = " + reportKey); }
statusReport = statusDependencies.statusReports.get(reportKey);
@@ -165,7 +165,7 @@
/* Finally we get our own Status Report. */
reportKey = "AAMasters" + "-" + "AATom" + "-" + "Multi-Period-Daily" + "-" + "dataSet.V1";
reportKey = "Masters" + "-" + "Stairs-Patterns" + "-" + "Multi-Period-Daily" + "-" + "dataSet.V1";
if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] start -> getContextVariables -> reportKey = " + reportKey); }
statusReport = statusDependencies.statusReports.get(reportKey);
@@ -353,10 +353,8 @@
if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] start -> buildStairs -> loopBody -> getEndOfLastCandleStair -> getCandleStairsFile -> Entering function."); }
let dateForPath = fileDate.getUTCFullYear() + '/' + utilities.pad(fileDate.getUTCMonth() + 1, 2) + '/' + utilities.pad(fileDate.getUTCDate(), 2);
let fileName = market.baseAsset + '_' + market.quotedAsset + ".json"
let filePathRoot = bot.dataMine + "/" + bot.codeName + "/" + bot.exchange;
let filePath = filePathRoot + "/Output/" + CANDLE_STAIRS_FOLDER_NAME + '/' + "Multi-Period-Daily" + "/" + timeFrame + "/" + dateForPath;
let fileName = "Data.json"
let filePath = bot.filePathRoot + "/Output/" + CANDLE_STAIRS_FOLDER_NAME + '/' + "Multi-Period-Daily" + "/" + timeFrame + "/" + dateForPath;
filePath += '/' + fileName
fileStorage.getTextFile(filePath, onFileReceived);
@@ -430,10 +428,8 @@
if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] start -> buildStairs -> loopBody -> getEndOfLastVolumeStair -> getCandleStairsFile -> Entering function."); }
let dateForPath = fileDate.getUTCFullYear() + '/' + utilities.pad(fileDate.getUTCMonth() + 1, 2) + '/' + utilities.pad(fileDate.getUTCDate(), 2);
let fileName = market.baseAsset + '_' + market.quotedAsset + ".json"
let filePathRoot = bot.dataMine + "/" + bot.codeName + "/" + bot.exchange;
let filePath = filePathRoot + "/Output/" + VOLUME_STAIRS_FOLDER_NAME + '/' + "Multi-Period-Daily" + "/" + timeFrame + "/" + dateForPath;
let fileName = "Data.json"
let filePath = bot.filePathRoot + "/Output/" + VOLUME_STAIRS_FOLDER_NAME + '/' + "Multi-Period-Daily" + "/" + timeFrame + "/" + dateForPath;
filePath += '/' + fileName
fileStorage.getTextFile(filePath, onFileReceived);
@@ -533,9 +529,8 @@
if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] start -> buildStairs -> loopBody -> processCandles -> getCandleStairsFile -> Entering function."); }
let dateForPath = previousDay.getUTCFullYear() + '/' + utilities.pad(previousDay.getUTCMonth() + 1, 2) + '/' + utilities.pad(previousDay.getUTCDate(), 2);
let fileName = market.baseAsset + '_' + market.quotedAsset + ".json"
let filePathRoot = bot.dataMine + "/" + "AAOlivia" + "/" + bot.exchange;
let fileName = "Data.json"
let filePathRoot = bot.exchange + "/" + bot.market.baseAsset + "-" + bot.market.quotedAsset + "/" + bot.dataMine + "/" + "Candles-Volumes";
let filePath = filePathRoot + "/Output/" + CANDLES_FOLDER_NAME + '/' + "Multi-Period-Daily" + "/" + timeFrame + "/" + dateForPath;
filePath += '/' + fileName
@@ -573,9 +568,8 @@
if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] start -> buildStairs -> loopBody -> processCandles -> getProcessDayFile -> Entering function."); }
let dateForPath = processDate.getUTCFullYear() + '/' + utilities.pad(processDate.getUTCMonth() + 1, 2) + '/' + utilities.pad(processDate.getUTCDate(), 2);
let fileName = market.baseAsset + '_' + market.quotedAsset + ".json"
let filePathRoot = bot.dataMine + "/" + "AAOlivia" + "/" + bot.exchange;
let fileName = "Data.json"
let filePathRoot = bot.exchange + "/" + bot.market.baseAsset + "-" + bot.market.quotedAsset + "/" + bot.dataMine + "/" + "Candles-Volumes";
let filePath = filePathRoot + "/Output/" + CANDLES_FOLDER_NAME + '/' + "Multi-Period-Daily" + "/" + timeFrame + "/" + dateForPath;
filePath += '/' + fileName
@@ -871,10 +865,9 @@
fileContent = "[" + fileContent + "]";
let dateForPath = pDate.getUTCFullYear() + '/' + utilities.pad(pDate.getUTCMonth() + 1, 2) + '/' + utilities.pad(pDate.getUTCDate(), 2);
let fileName = '' + market.baseAsset + '_' + market.quotedAsset + '.json';
let fileName = 'Data.json';
let filePathRoot = bot.dataMine + "/" + bot.codeName + "/" + bot.exchange;
let filePath = filePathRoot + "/Output/" + CANDLE_STAIRS_FOLDER_NAME + "/" + bot.process + "/" + timeFrame + "/" + dateForPath;
let filePath = bot.filePathRoot + "/Output/" + CANDLE_STAIRS_FOLDER_NAME + "/" + bot.process + "/" + timeFrame + "/" + dateForPath;
filePath += '/' + fileName
fileStorage.createTextFile(filePath, fileContent + '\n', onFileCreated);
@@ -947,9 +940,8 @@
if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] start -> buildStairs -> loopBody -> processVolumes -> getCandleStairsFile -> Entering function."); }
let dateForPath = previousDay.getUTCFullYear() + '/' + utilities.pad(previousDay.getUTCMonth() + 1, 2) + '/' + utilities.pad(previousDay.getUTCDate(), 2);
let fileName = market.baseAsset + '_' + market.quotedAsset + ".json"
let filePathRoot = bot.dataMine + "/" + "AAOlivia" + "/" + bot.exchange;
let fileName = "Data.json"
let filePathRoot = bot.exchange + "/" + bot.market.baseAsset + "-" + bot.market.quotedAsset + "/" + bot.dataMine + "/" + "Candles-Volumes";
let filePath = filePathRoot + "/Output/" + VOLUMES_FOLDER_NAME + '/' + "Multi-Period-Daily" + "/" + timeFrame + "/" + dateForPath;
filePath += '/' + fileName
@@ -987,9 +979,8 @@
if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] start -> buildStairs -> loopBody -> processVolumes -> getProcessDayFile -> Entering function."); }
let dateForPath = processDate.getUTCFullYear() + '/' + utilities.pad(processDate.getUTCMonth() + 1, 2) + '/' + utilities.pad(processDate.getUTCDate(), 2);
let fileName = market.baseAsset + '_' + market.quotedAsset + ".json"
let filePathRoot = bot.dataMine + "/" + "AAOlivia" + "/" + bot.exchange;
let fileName = "Data.json"
let filePathRoot = bot.exchange + "/" + bot.market.baseAsset + "-" + bot.market.quotedAsset + "/" + bot.dataMine + "/" + "Candles-Volumes";
let filePath = filePathRoot + "/Output/" + VOLUMES_FOLDER_NAME + '/' + "Multi-Period-Daily" + "/" + timeFrame + "/" + dateForPath;
filePath += '/' + fileName
@@ -1416,10 +1407,8 @@
fileContent = "[" + fileContent + "]";
let dateForPath = pDate.getUTCFullYear() + '/' + utilities.pad(pDate.getUTCMonth() + 1, 2) + '/' + utilities.pad(pDate.getUTCDate(), 2);
let fileName = '' + market.baseAsset + '_' + market.quotedAsset + '.json';
let filePathRoot = bot.dataMine + "/" + bot.codeName + "/" + bot.exchange;
let filePath = filePathRoot + "/Output/" + VOLUME_STAIRS_FOLDER_NAME + "/" + bot.process + "/" + timeFrame + "/" + dateForPath;
let fileName = 'Data.json';
let filePath = bot.filePathRoot + "/Output/" + VOLUME_STAIRS_FOLDER_NAME + "/" + bot.process + "/" + timeFrame + "/" + dateForPath;
filePath += '/' + fileName
fileStorage.createTextFile(filePath, fileContent + '\n', onFileCreated);
@@ -1581,7 +1570,7 @@
let fileContent = JSON.stringify(dataRange);
let fileName = 'Data.Range.' + market.baseAsset + '_' + market.quotedAsset + '.json';
let fileName = 'Data.Range.json';
let filePath = bot.filePathRoot + "/Output/" + pProductFolder + "/" + bot.process;
filePath += '/' + fileName
@@ -1624,7 +1613,7 @@
try {
let reportKey = "AAMasters" + "-" + "AATom" + "-" + "Multi-Period-Daily" + "-" + "dataSet.V1";
let reportKey = "Masters" + "-" + "Stairs-Patterns" + "-" + "Multi-Period-Daily" + "-" + "dataSet.V1";
let thisReport = statusDependencies.statusReports.get(reportKey);
thisReport.file.lastExecution = bot.processDatetime;
@@ -48,7 +48,7 @@
This process is going to do the following:
Read the candles and volumes from Olivia and produce for each market two files with candles stairs and volumes stairs respectively.
Read the candles and volumes from Candles Volumes and produce for each market two files with candles stairs and volumes stairs respectively.
*/
@@ -112,9 +112,9 @@
if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] start -> buildStairs -> loopBody -> nextCandleFile -> Entering function."); }
let fileName = market.baseAsset + '_' + market.quotedAsset + ".json";
let fileName = "Data.json";
let filePathRoot = bot.dataMine + "/" + "AAOlivia" + "/" + bot.exchange;
let filePathRoot = bot.exchange + "/" + bot.market.baseAsset + "-" + bot.market.quotedAsset + "/" + bot.dataMine + "/" + "Candles-Volumes";
let filePath = filePathRoot + "/Output/" + CANDLES_FOLDER_NAME + "/" + "Multi-Period-Market" + "/" + timeFrame;
filePath += '/' + fileName
@@ -328,10 +328,8 @@
fileContent = "[" + fileContent + "]";
let fileName = '' + market.baseAsset + '_' + market.quotedAsset + '.json';
let filePathRoot = bot.dataMine + "/" + bot.codeName + "/" + bot.exchange;
let filePath = filePathRoot + "/Output/" + CANDLE_STAIRS_FOLDER_NAME + "/" + "Multi-Period-Market" + "/" + timeFrame;
let fileName = 'Data.json';
let filePath = bot.filePathRoot + "/Output/" + CANDLE_STAIRS_FOLDER_NAME + "/" + "Multi-Period-Market" + "/" + timeFrame;
filePath += '/' + fileName
fileStorage.createTextFile(filePath, fileContent + '\n', onFileCreated);
@@ -388,9 +386,9 @@
if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] start -> buildStairs -> loopBody -> nextVolumeFile -> Entering function."); }
let fileName = market.baseAsset + '_' + market.quotedAsset + ".json"
let fileName = "Data.json"
let filePathRoot = bot.dataMine + "/" + "AAOlivia" + "/" + bot.exchange;
let filePathRoot = bot.exchange + "/" + bot.market.baseAsset + "-" + bot.market.quotedAsset + "/" + bot.dataMine + "/" + "Candles-Volumes";
let filePath = filePathRoot + "/Output/" + VOLUMES_FOLDER_NAME + "/" + "Multi-Period-Market" + "/" + timeFrame;
filePath += '/' + fileName
@@ -698,10 +696,8 @@
fileContent = "[" + fileContent + "]";
let fileName = '' + market.baseAsset + '_' + market.quotedAsset + '.json';
let filePathRoot = bot.dataMine + "/" + bot.codeName + "/" + bot.exchange;
let filePath = filePathRoot + "/Output/" + VOLUME_STAIRS_FOLDER_NAME + "/" + "Multi-Period-Market" + "/" + timeFrame;
let fileName = 'Data.json';
let filePath = bot.filePathRoot + "/Output/" + VOLUME_STAIRS_FOLDER_NAME + "/" + "Multi-Period-Market" + "/" + timeFrame;
filePath += '/' + fileName
fileStorage.createTextFile(filePath, fileContent + '\n', onFileCreated);
@@ -790,7 +786,7 @@
try {
let reportKey = "AAMasters" + "-" + "AATom" + "-" + "Multi-Period-Market" + "-" + "dataSet.V1";
let reportKey = "Masters" + "-" + "Stairs-Patterns" + "-" + "Multi-Period-Market" + "-" + "dataSet.V1";
let thisReport = statusDependencies.statusReports.get(reportKey);
thisReport.file.lastExecution = bot.processDatetime;
@@ -1,5 +1,5 @@
{
"name": "AAToma",
"name": "Stairs-Patternsa",
"version": "1.0.0",
"description": "",
"main": "index.js",
@@ -1,14 +1,14 @@
{
"displayName": "Tom",
"codeName": "AATom",
"displayName": "Stairs Patterns",
"codeName": "Stairs-Patterns",
"type": "Indicator Bot",
"version": {
"major": 1,
"minor": 0,
"patch": 0
},
"dataMine": "AAMasters",
"profilePicture": "Tom.png",
"dataMine": "Masters",
"profilePicture": "Stairs Patterns.png",
"dataSetVersion": "dataSet.V1",
"processes": [
{
@@ -50,8 +50,8 @@
],
"statusDependencies": [
{
"dataMine": "AAMasters",
"bot": "AATom",
"dataMine": "Masters",
"bot": "Stairs-Patterns",
"botVersion": {
"major": 1,
"minor": 0
@@ -60,8 +60,8 @@
"dataSetVersion": "dataSet.V1"
},
{
"dataMine": "AAMasters",
"bot": "AAOlivia",
"dataMine": "Masters",
"bot": "Candles-Volumes",
"botVersion": {
"major": 1,
"minor": 0
@@ -111,8 +111,8 @@
],
"statusDependencies": [
{
"dataMine": "AAMasters",
"bot": "AACharly",
"dataMine": "Masters",
"bot": "Exchange-Raw-Data",
"botVersion": {
"major": 1,
"minor": 0
@@ -121,8 +121,8 @@
"dataSetVersion": "dataSet.V1"
},
{
"dataMine": "AAMasters",
"bot": "AAOlivia",
"dataMine": "Masters",
"bot": "Candles-Volumes",
"botVersion": {
"major": 1,
"minor": 0
@@ -132,8 +132,8 @@
"waitUntilNextUpdate": true
},
{
"dataMine": "AAMasters",
"bot": "AATom",
"dataMine": "Masters",
"bot": "Stairs-Patterns",
"botVersion": {
"major": 1,
"minor": 0
@@ -149,24 +149,24 @@
"codeName": "Candle-Stairs",
"displayName": "Candle-Stairs Patters",
"description": "Two sets of files per period that contains candle-stairs patterns.",
"storageAccount": "aatom",
"storageAccount": "Stairs-Patterns",
"shareWith": "Public",
"dataSets": [
{
"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/AATom.1.0/AACloud.1.1/@Exchange/dataSet.V1/Output/Candle-Stairs/Multi-Period-Market/@Period",
"filePath": "Masters/Stairs-Patterns.1.0/AACloud.1.1/@Exchange/dataSet.V1/Output/Candle-Stairs/Multi-Period-Market/@Period",
"fileName": "@AssetA_@AssetB.json"
},
{
"codeName": "Multi-Period-Daily",
"type": "Daily Files",
"validPeriods": [ "45-min", "40-min", "30-min", "20-min", "15-min", "10-min", "05-min", "04-min", "03-min", "02-min", "01-min" ],
"filePath": "AAMasters/AATom.1.0/AACloud.1.1/@Exchange/dataSet.V1/Output/Candle-Stairs/Multi-Period-Daily/@Period/@Year/@Month/@Day",
"filePath": "Masters/Stairs-Patterns.1.0/AACloud.1.1/@Exchange/dataSet.V1/Output/Candle-Stairs/Multi-Period-Daily/@Period/@Year/@Month/@Day",
"fileName": "@AssetA_@AssetB.json",
"dataRange": {
"filePath": "AAMasters/AATom.1.0/AACloud.1.1/@Exchange/dataSet.V1/Output/Candle-Stairs/Multi-Period-Daily",
"filePath": "Masters/Stairs-Patterns.1.0/AACloud.1.1/@Exchange/dataSet.V1/Output/Candle-Stairs/Multi-Period-Daily",
"fileName": "Data.Range.@AssetA_@AssetB.json"
}
}
@@ -180,7 +180,7 @@
}
],
"plotter": {
"dataMine": "AAMasters",
"dataMine": "Masters",
"codeName": "PlottersStairsPatterns",
"moduleName": "CandleStairs"
}
@@ -189,24 +189,24 @@
"codeName": "Volume-Stairs",
"displayName": "Volume-Stairs Patters",
"description": "Two sets of files per period that contains volume-stairs patterns.",
"storageAccount": "aatom",
"storageAccount": "Stairs-Patterns",
"shareWith": "Public",
"dataSets": [
{
"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/AATom.1.0/AACloud.1.1/@Exchange/dataSet.V1/Output/Volume-Stairs/Multi-Period-Market/@Period",
"filePath": "Masters/Stairs-Patterns.1.0/AACloud.1.1/@Exchange/dataSet.V1/Output/Volume-Stairs/Multi-Period-Market/@Period",
"fileName": "@AssetA_@AssetB.json"
},
{
"codeName": "Multi-Period-Daily",
"type": "Daily Files",
"validPeriods": [ "45-min", "40-min", "30-min", "20-min", "15-min", "10-min", "05-min", "04-min", "03-min", "02-min", "01-min" ],
"filePath": "AAMasters/AATom.1.0/AACloud.1.1/@Exchange/dataSet.V1/Output/Volume-Stairs/Multi-Period-Daily/@Period/@Year/@Month/@Day",
"filePath": "Masters/Stairs-Patterns.1.0/AACloud.1.1/@Exchange/dataSet.V1/Output/Volume-Stairs/Multi-Period-Daily/@Period/@Year/@Month/@Day",
"fileName": "@AssetA_@AssetB.json",
"dataRange": {
"filePath": "AAMasters/AATom.1.0/AACloud.1.1/@Exchange/dataSet.V1/Output/Volume-Stairs/Multi-Period-Daily",
"filePath": "Masters/Stairs-Patterns.1.0/AACloud.1.1/@Exchange/dataSet.V1/Output/Volume-Stairs/Multi-Period-Daily",
"fileName": "Data.Range.@AssetA_@AssetB.json"
}
}
@@ -220,7 +220,7 @@
}
],
"plotter": {
"dataMine": "AAMasters",
"dataMine": "Masters",
"codeName": "PlottersStairsPatterns",
"moduleName": "VolumeStairs"
}
@@ -1,4 +1,4 @@
function newAAMastersPlottersBollingerBandsBollingerBands() {
function newMastersPlottersBollingerBandsBollingerBands() {
const MODULE_NAME = "Bands Plotter";
const ERROR_LOG = true;
@@ -1,5 +1,5 @@

function newAAMastersPlottersBollingerBandsBollingerBandsBollingerBandsPanel () {
function newMastersPlottersBollingerBandsBollingerBandsBollingerBandsPanel () {
var thisObject = {
fitFunction: undefined,
@@ -1,4 +1,4 @@
function newAAMastersPlottersBollingerBandsPercentageBandwidth() {
function newMastersPlottersBollingerBandsPercentageBandwidth() {
const MODULE_NAME = "Bands Plotter";
const ERROR_LOG = true;
@@ -1,7 +1,7 @@
{
"displayName": "Plotters Bollinger Bands",
"codeName": "PlottersBollingerBands",
"dataMine": "AAMasters",
"dataMine": "Masters",
"modules": [
{
"codeName": "BollingerBands",
@@ -1,5 +1,5 @@

function newAAMastersPlottersCandlesVolumesCandlesCandlePanel() {
function newMastersPlottersCandlesVolumesCandlesCandlePanel() {
let thisObject = {
fitFunction: undefined,
@@ -1,4 +1,4 @@
function newAAMastersPlottersCandlesVolumesCandles() {
function newMastersPlottersCandlesVolumesCandles() {
const MODULE_NAME = "Candles Plotter";
const ERROR_LOG = true;
@@ -1,5 +1,5 @@

function newAAMastersPlottersCandlesVolumesVolumesVolumePanel() {
function newMastersPlottersCandlesVolumesVolumesVolumePanel() {
let thisObject = {
fitFunction: undefined,
@@ -1,4 +1,4 @@
function newAAMastersPlottersCandlesVolumesVolumes() {
function newMastersPlottersCandlesVolumesVolumes() {
const MODULE_NAME = "Volumes Plotter";
const ERROR_LOG = true;
@@ -1,7 +1,7 @@
{
"displayName": "Plotters Candles & Volumes",
"codeName": "PlottersCandlesVolumes",
"dataMine": "AAMasters",
"dataMine": "Masters",
"modules": [
{
"codeName": "Candles",
@@ -1,6 +1,6 @@
function newAAMastersPlottersStairsPatternsCandleStairs() {
function newMastersPlottersStairsPatternsCandleStairs() {
const MODULE_NAME = "AAMasters Plotters Stairs Patterns Candle Stairs";
const MODULE_NAME = "Masters Plotters Stairs Patterns Candle Stairs";
const ERROR_LOG = true;
const INTENSIVE_LOG = false;
const logger = newWebDebugLog();
@@ -1,6 +1,6 @@
function newAAMastersPlottersStairsPatternsVolumeStairs() {
function newMastersPlottersStairsPatternsVolumeStairs() {
const MODULE_NAME = "AAMasters Plotters Stairs Patterns Volume Stairs";
const MODULE_NAME = "Masters Plotters Stairs Patterns Volume Stairs";
const ERROR_LOG = true;
const INTENSIVE_LOG = false;
const logger = newWebDebugLog();
@@ -1,7 +1,7 @@
{
"displayName": "Plotters Stairs Patterns",
"codeName": "PlottersStairsPatterns",
"dataMine": "AAMasters",
"dataMine": "Masters",
"modules": [
{
"codeName": "CandleStairs",
@@ -1,4 +1,4 @@
function newAAMastersPlottersTradingSimulationConditions() {
function newMastersPlottersTradingSimulationConditions() {
const MODULE_NAME = "Conditions Plotter";
const INFO_LOG = false;
@@ -1,4 +1,4 @@
function newAAMastersPlottersTradingSimulationSimulationExecution() {
function newMastersPlottersTradingSimulationSimulationExecution() {
const MODULE_NAME = "Simulation Execution Plotter";
const INTENSIVE_LOG = false;
@@ -1,5 +1,5 @@

function newAAMastersPlottersTradingSimulationSimulationExecutionSimulationExecutionPanel() {
function newMastersPlottersTradingSimulationSimulationExecutionSimulationExecutionPanel() {
let thisObject = {
@@ -1,4 +1,4 @@
function newAAMastersPlottersTradingSimulationStrategies() {
function newMastersPlottersTradingSimulationStrategies() {
const MODULE_NAME = "Strategies Plotter";
const INFO_LOG = false;
@@ -1,4 +1,4 @@
function newAAMastersPlottersTradingSimulationTrades() {
function newMastersPlottersTradingSimulationTrades() {
const MODULE_NAME = "Trades Plotter";
const INFO_LOG = false;
@@ -1,4 +1,4 @@
function newAAMastersPlottersTradingSimulationTradingSimulation() {
function newMastersPlottersTradingSimulationTradingSimulation() {
const MODULE_NAME = "Simulation Plotter";
const ERROR_LOG = true;
@@ -1,5 +1,5 @@

function newAAMastersPlottersTradingSimulationTradingSimulationTradingSimulationPanel() {
function newMastersPlottersTradingSimulationTradingSimulationTradingSimulationPanel() {
let thisObject = {
fitFunction: undefined,
@@ -1,7 +1,7 @@
{
"displayName": "Plotters Trading Simulation",
"codeName": "PlottersTradingSimulation",
"dataMine": "AAMasters",
"dataMine": "Masters",
"modules": [
{
"codeName": "TradingSimulation",
+2 -2
View File
@@ -469,14 +469,14 @@
if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] start -> writeFile -> Entering function."); }
let market = bot.market;
let fileName = '' + market.baseAsset + '_' + market.quotedAsset + '.json';
let fileName = 'Data.json';
let dateForPath = ''
if (processingDailyFiles === true) {
dateForPath = "/" + currentDay.getUTCFullYear() + '/' + utilities.pad(currentDay.getUTCMonth() + 1, 2) + '/' + utilities.pad(currentDay.getUTCDate(), 2);
}
let filePathRoot = contextSummary.dataMine + "/" + contextSummary.bot + "/" + bot.exchange;
let filePathRoot = bot.exchange + "/" + bot.market.baseAsset + "-" + bot.market.quotedAsset + "/" + contextSummary.dataMine + "/" + contextSummary.bot;
let filePath = filePathRoot + "/Output/" + contextSummary.product + "/" + contextSummary.dataset + "/" + timeFrameLabel + dateForPath;
filePath += '/' + fileName
+2 -2
View File
@@ -104,7 +104,7 @@ exports.newDataSet = function newDataSet(BOT, logger) {
if (global.LOG_CONTROL[MODULE_NAME].logInfo === true) { logger.write(MODULE_NAME, "[INFO] getTextFile -> Entering function."); }
let filePathRoot = dataDependencyNode.dataMine + "/" + dataDependencyNode.bot + "/" + bot.exchange;
let filePathRoot = bot.exchange + "/" + bot.market.baseAsset + "-" + bot.market.quotedAsset + "/" + dataDependencyNode.dataMine + "/" + dataDependencyNode.bot;
let filePath = filePathRoot + "/Output/" + pFolderPath;
filePath += '/' + pFileName
@@ -146,7 +146,7 @@ exports.newDataSet = function newDataSet(BOT, logger) {
return;
}
let filePathRoot = dataDependencyNode.dataMine + "/" + dataDependencyNode.bot + "/" + bot.exchange;
let filePathRoot = bot.exchange + "/" + bot.market.baseAsset + "-" + bot.market.quotedAsset + "/" + dataDependencyNode.dataMine + "/" + dataDependencyNode.bot;
let filePath = filePathRoot + "/Output/" + pFolderPath + '/' + pFileName;
fileStorage.createTextFile(filePath, pFileContent, onFileCreated);
+4 -4
View File
@@ -312,7 +312,7 @@
if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] start -> processTimeFramesMarketFiles -> periodsLoopBody -> dependencyLoopBody -> getFile -> Entering function."); }
let fileName = market.baseAsset + '_' + market.quotedAsset + ".json";
let fileName = "Data.json";
if (dependency.dataSet !== "Multi-Period-Market") {
@@ -632,7 +632,7 @@
} else {
filePath = dependency.product + '/' + dependency.dataSet + "/" + dateForPath;
}
let fileName = market.baseAsset + '_' + market.quotedAsset + ".json";
let fileName = "Data.json";
dataset.getTextFile(filePath, fileName, onFileReceived);
@@ -708,7 +708,7 @@
} else {
filePath = dependency.product + '/' + dependency.dataSet + "/" + dateForPath;
}
let fileName = market.baseAsset + '_' + market.quotedAsset + ".json";
let fileName = "Data.json";
dataset.getTextFile(filePath, fileName, onFileReceived);
@@ -986,7 +986,7 @@
let fileContent = JSON.stringify(dataRange);
let fileName = '/Data.Range.' + market.baseAsset + '_' + market.quotedAsset + '.json';
let fileName = '/Data.Range.json';
let filePath = bot.filePathRoot + "/Output/" + bot.SESSION.folderName + "/" + productCodeName + "/" + 'Multi-Period-Daily' + fileName;
fileStorage.createTextFile(filePath, fileContent + '\n', onFileCreated);
+3 -3
View File
@@ -451,7 +451,7 @@
} else {
filePath = dependency.product + '/' + dependency.dataSet + "/" + dateForPath;
}
let fileName = market.baseAsset + '_' + market.quotedAsset + ".json";
let fileName = "Data.json";
dataset.getTextFile(filePath, fileName, onFileReceived);
@@ -521,7 +521,7 @@
} else {
filePath = dependency.product + '/' + dependency.dataSet + "/" + dateForPath;
}
let fileName = market.baseAsset + '_' + market.quotedAsset + ".json";
let fileName = "Data.json";
dataset.getTextFile(filePath, fileName, onFileReceived);
@@ -755,7 +755,7 @@
let fileContent = JSON.stringify(dataRange);
let fileName = '/Data.Range.' + market.baseAsset + '_' + market.quotedAsset + '.json';
let fileName = '/Data.Range.json';
let filePath = bot.filePathRoot + "/Output/" + productCodeName + "/" + bot.process + fileName;
fileStorage.createTextFile(filePath, fileContent + '\n', onFileCreated);
+1 -1
View File
@@ -173,7 +173,7 @@
if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] start -> processTimeFrames -> periodsLoopBody -> dependencyLoopBody -> getFile -> Entering function."); }
let dateForPath = bot.processDatetime.getUTCFullYear() + '/' + utilities.pad(bot.processDatetime.getUTCMonth() + 1, 2) + '/' + utilities.pad(bot.processDatetime.getUTCDate(), 2);
let fileName = market.baseAsset + '_' + market.quotedAsset + ".json";
let fileName = "Data.json";
let filePath
if (dependency.dataSet === "Multi-Period-Market") {
+2 -2
View File
@@ -205,7 +205,7 @@
/* Simplifying the access to basic info */
botConfig.dataMine = global.TASK_NODE.bot.processes[processIndex].referenceParent.parentNode.parentNode.code.codeName
botConfig.exchange = global.TASK_NODE.bot.processes[processIndex].marketReference.referenceParent.parentNode.parentNode.code.codeName
botConfig.exchange = global.TASK_NODE.bot.processes[processIndex].marketReference.referenceParent.parentNode.parentNode.name
botConfig.exchangeNode = global.TASK_NODE.bot.processes[processIndex].marketReference.referenceParent.parentNode.parentNode
botConfig.market = {
baseAsset: global.TASK_NODE.bot.processes[processIndex].marketReference.referenceParent.baseAsset.referenceParent.code.codeName,
@@ -225,7 +225,7 @@
botConfig.loopCounter = 0;
/* File Path Root */
botConfig.filePathRoot = botConfig.dataMine + "/" + botConfig.codeName + "/" + botConfig.exchange;
botConfig.filePathRoot = botConfig.exchange + "/" + botConfig.market.baseAsset + "-" + botConfig.market.quotedAsset + "/" + botConfig.dataMine + "/" + botConfig.codeName ;
/* Process Key */
botConfig.processKey = global.TASK_NODE.bot.processes[processIndex].name + '-' + global.TASK_NODE.bot.processes[processIndex].type + '-' + global.TASK_NODE.bot.processes[processIndex].id
+1 -3
View File
@@ -56,9 +56,7 @@
return;
}
USER_BOT_MODULE = {}
if (bot.process === "Hole-Fixing") {
//USER_BOT_MODULE.newUserBot = require(process.env.BOTS_PATH + '/aamasters/AAMasters/bots/AACharly-Sensor-Bot/Hole-Fixing/User.Bot').newUserBot
}
try {
USER_BOT_MODULE.newUserBot = eval(text); // TODO This needs to be changed function
} catch (err) {
+5 -3
View File
@@ -136,14 +136,16 @@
if (global.LOG_CONTROL[MODULE_NAME].logInfo === true) { logger.write(MODULE_NAME, "[INFO] load -> Entering function."); }
let fileName = "Status.Report." + bot.market.baseAsset + '_' + bot.market.quotedAsset + ".json";
let fileName = "Status.Report.json";
let filePath;
let ownerId = statusDependencyNode.dataMine + "-" + statusDependencyNode.bot + "-" + statusDependencyNode.botVersion.major + "-" + statusDependencyNode.botVersion.minor + "-" + statusDependencyNode.process + "-" + statusDependencyNode.dataSetVersion;
let botId = bot.dataMine + "-" + bot.codeName + "-" + bot.version.major + "-" + bot.version.minor + "-" + bot.process + "-" + bot.dataSetVersion;
if (ownerId !== botId) {
let rootPath = statusDependencyNode.dataMine + "/" + statusDependencyNode.bot + "/" + bot.exchange;
let rootPath = bot.exchange + "/" + bot.market.baseAsset + "-" + bot.market.quotedAsset + "/" + statusDependencyNode.dataMine + "/" + statusDependencyNode.bot
filePath = rootPath + "/Reports/" + sessionPath + statusDependencyNode.process ;
} else {
filePath = bot.filePathRoot + "/Reports/" + sessionPath + statusDependencyNode.process ;
@@ -233,7 +235,7 @@
return;
}
let fileName = "Status.Report." + bot.market.baseAsset + '_' + bot.market.quotedAsset + ".json";
let fileName = "Status.Report.json";
let filePath = bot.filePathRoot + "/Reports/" + sessionPath + statusDependencyNode.process;
filePath += '/' + fileName
+19 -40
View File
@@ -103,7 +103,7 @@
}
}
/* From here we have more or less the same we used to have at JASON */
const TRADING_SIMULATION = require('./TradingSimulation.js');
let tradingSimulation = TRADING_SIMULATION.newTradingSimulation(bot, logger, UTILITIES);
@@ -219,10 +219,8 @@
fileContent = "[" + fileContent + "]";
let fileName = '' + market.baseAsset + '_' + market.quotedAsset + '.json';
let filePathRoot = bot.dataMine + "/" + bot.codeName + "/" + bot.exchange;
let filePath = filePathRoot + "/Output/" + bot.SESSION.folderName + "/" + SIMULATED_RECORDS_FOLDER_NAME + "/" + "Multi-Period-Market" + "/" + timeFrameLabel;
let fileName = 'Data.json';
let filePath = bot.filePathRoot + "/Output/" + bot.SESSION.folderName + "/" + SIMULATED_RECORDS_FOLDER_NAME + "/" + "Multi-Period-Market" + "/" + timeFrameLabel;
filePath += '/' + fileName
fileStorage.createTextFile(filePath, fileContent + '\n', onFileCreated);
@@ -297,10 +295,9 @@
fileContent = "[" + fileContent + "]";
fileContent = "[" + JSON.stringify(tradingSystem) + "," + fileContent + "]";
let fileName = '' + market.baseAsset + '_' + market.quotedAsset + '.json';
let filePathRoot = bot.dataMine + "/" + bot.codeName + "/" + bot.exchange;
let filePath = filePathRoot + "/Output/" + bot.SESSION.folderName + "/" + CONDITIONS_FOLDER_NAME + "/" + "Multi-Period-Market" + "/" + timeFrameLabel;
let fileName = 'Data.json';
let filePath = bot.filePathRoot + "/Output/" + bot.SESSION.folderName + "/" + CONDITIONS_FOLDER_NAME + "/" + "Multi-Period-Market" + "/" + timeFrameLabel;
filePath += '/' + fileName
fileStorage.createTextFile(filePath, fileContent + '\n', onFileCreated);
@@ -367,10 +364,9 @@
}
fileContent = "[" + fileContent + "]";
let fileName = '' + market.baseAsset + '_' + market.quotedAsset + '.json';
let filePathRoot = bot.dataMine + "/" + bot.codeName + "/" + bot.exchange;
let filePath = filePathRoot + "/Output/" + bot.SESSION.folderName + "/" + STRATEGIES_FOLDER_NAME + "/" + "Multi-Period-Market" + "/" + timeFrameLabel;
let fileName = 'Data.json';
let filePath = bot.filePathRoot + "/Output/" + bot.SESSION.folderName + "/" + STRATEGIES_FOLDER_NAME + "/" + "Multi-Period-Market" + "/" + timeFrameLabel;
filePath += '/' + fileName
fileStorage.createTextFile(filePath, fileContent + '\n', onFileCreated);
@@ -440,10 +436,9 @@
}
fileContent = "[" + fileContent + "]";
let fileName = '' + market.baseAsset + '_' + market.quotedAsset + '.json';
let filePathRoot = bot.dataMine + "/" + bot.codeName + "/" + bot.exchange;
let filePath = filePathRoot + "/Output/" + bot.SESSION.folderName + "/" + TRADES_FOLDER_NAME + "/" + "Multi-Period-Market" + "/" + timeFrameLabel;
let fileName = 'Data.json';
let filePath = bot.filePathRoot + "/Output/" + bot.SESSION.folderName + "/" + TRADES_FOLDER_NAME + "/" + "Multi-Period-Market" + "/" + timeFrameLabel;
filePath += '/' + fileName
fileStorage.createTextFile(filePath, fileContent + '\n', onFileCreated);
@@ -466,9 +461,6 @@
}
/* Emit event that signals that simulation files were updated */
global.SYSTEM_EVENT_HANDLER.raiseEvent('Jason-Multi-Period', 'Simulation Files Updated')
callBackFunction(global.DEFAULT_OK_RESPONSE);
}
@@ -566,10 +558,8 @@
fileContent = "[" + fileContent + "]";
let fileName = '' + market.baseAsset + '_' + market.quotedAsset + '.json';
let filePathRoot = bot.dataMine + "/" + bot.codeName + "/" + bot.exchange;
let filePath = filePathRoot + "/Output/" + bot.SESSION.folderName + "/" + SIMULATED_RECORDS_FOLDER_NAME + "/" + "Multi-Period-Daily" + "/" + timeFrameLabel;
let fileName = 'Data.json';
let filePath = bot.filePathRoot + "/Output/" + bot.SESSION.folderName + "/" + SIMULATED_RECORDS_FOLDER_NAME + "/" + "Multi-Period-Daily" + "/" + timeFrameLabel;
filePath += '/' + fileName
fileStorage.createTextFile(filePath, fileContent + '\n', onFileCreated);
@@ -673,10 +663,8 @@
fileContent = "[" + fileContent + "]";
let dateForPath = currentDay.getUTCFullYear() + '/' + utilities.pad(currentDay.getUTCMonth() + 1, 2) + '/' + utilities.pad(currentDay.getUTCDate(), 2);
let fileName = '' + market.baseAsset + '_' + market.quotedAsset + '.json';
let filePathRoot = bot.dataMine + "/" + bot.codeName + "/" + bot.exchange;
let filePath = filePathRoot + "/Output/" + bot.SESSION.folderName + "/" + SIMULATED_RECORDS_FOLDER_NAME + "/" + "Multi-Period-Daily" + "/" + timeFrameLabel + "/" + dateForPath;
let fileName = 'Data.json';
let filePath = bot.filePathRoot + "/Output/" + bot.SESSION.folderName + "/" + SIMULATED_RECORDS_FOLDER_NAME + "/" + "Multi-Period-Daily" + "/" + timeFrameLabel + "/" + dateForPath;
filePath += '/' + fileName
fileStorage.createTextFile(filePath, fileContent + '\n', onFileCreated);
@@ -761,10 +749,8 @@
fileContent = "[" + JSON.stringify(tradingSystem) + "," + fileContent + "]";
let dateForPath = currentDay.getUTCFullYear() + '/' + utilities.pad(currentDay.getUTCMonth() + 1, 2) + '/' + utilities.pad(currentDay.getUTCDate(), 2);
let fileName = '' + market.baseAsset + '_' + market.quotedAsset + '.json';
let filePathRoot = bot.dataMine + "/" + bot.codeName + "/" + bot.exchange;
let filePath = filePathRoot + "/Output/" + bot.SESSION.folderName + "/" + CONDITIONS_FOLDER_NAME + "/" + "Multi-Period-Daily" + "/" + timeFrameLabel + "/" + dateForPath;
let fileName = 'Data.json';
let filePath = bot.filePathRoot + "/Output/" + bot.SESSION.folderName + "/" + CONDITIONS_FOLDER_NAME + "/" + "Multi-Period-Daily" + "/" + timeFrameLabel + "/" + dateForPath;
filePath += '/' + fileName
fileStorage.createTextFile(filePath, fileContent + '\n', onFileCreated);
@@ -838,10 +824,8 @@
fileContent = "[" + fileContent + "]";
let dateForPath = currentDay.getUTCFullYear() + '/' + utilities.pad(currentDay.getUTCMonth() + 1, 2) + '/' + utilities.pad(currentDay.getUTCDate(), 2);
let fileName = '' + market.baseAsset + '_' + market.quotedAsset + '.json';
let filePathRoot = bot.dataMine + "/" + bot.codeName + "/" + bot.exchange;
let filePath = filePathRoot + "/Output/" + bot.SESSION.folderName + "/" + STRATEGIES_FOLDER_NAME + "/" + "Multi-Period-Daily" + "/" + timeFrameLabel + "/" + dateForPath;
let fileName = 'Data.json';
let filePath = bot.filePathRoot + "/Output/" + bot.SESSION.folderName + "/" + STRATEGIES_FOLDER_NAME + "/" + "Multi-Period-Daily" + "/" + timeFrameLabel + "/" + dateForPath;
filePath += '/' + fileName
fileStorage.createTextFile(filePath, fileContent + '\n', onFileCreated);
@@ -918,10 +902,8 @@
fileContent = "[" + fileContent + "]";
let dateForPath = currentDay.getUTCFullYear() + '/' + utilities.pad(currentDay.getUTCMonth() + 1, 2) + '/' + utilities.pad(currentDay.getUTCDate(), 2);
let fileName = '' + market.baseAsset + '_' + market.quotedAsset + '.json';
let filePathRoot = bot.dataMine + "/" + bot.codeName + "/" + bot.exchange;
let filePath = filePathRoot + "/Output/" + bot.SESSION.folderName + "/" + TRADES_FOLDER_NAME + "/" + "Multi-Period-Daily" + "/" + timeFrameLabel + "/" + dateForPath;
let fileName = 'Data.json';
let filePath = bot.filePathRoot + "/Output/" + bot.SESSION.folderName + "/" + TRADES_FOLDER_NAME + "/" + "Multi-Period-Daily" + "/" + timeFrameLabel + "/" + dateForPath;
filePath += '/' + fileName
fileStorage.createTextFile(filePath, fileContent + '\n', onFileCreated);
@@ -944,9 +926,6 @@
}
/* Emit event that signals that simulation files were updated */
global.SYSTEM_EVENT_HANDLER.raiseEvent('Jason-Multi-Period', 'Simulation Files Updated')
callBackFunction(global.DEFAULT_OK_RESPONSE);
}
-2
View File
@@ -69,7 +69,6 @@
}
USER_BOT_MODULE = {}
//USER_BOT_MODULE.newUserBot = require(process.env.BOTS_PATH + '/aamasters/AAMasters/bots/AAJason-Trading-Engine-Bot/Multi-Period/User.Bot').newUserBot // Use this for a better debugging experience. You need to bring this js module to this folder in order to work.
USER_BOT_MODULE.newUserBot = eval(text); // Use this for production
filePath = bot.dataMine + "/" + "bots" + "/" + bot.repo;
@@ -86,7 +85,6 @@
}
USER_BOT_COMMONS = {}
//USER_BOT_COMMONS.newCommons = require(process.env.BOTS_PATH + '/aamasters/AAMasters/bots/AAJason-Trading-Engine-Bot/Commons').newCommons // Use this for a better debugging experience. You need to bring this js module to this folder in order to work.
USER_BOT_COMMONS.newCommons = eval(text); // Use this for production
session.initialize(onSessionInitialized)
+1 -1
View File
@@ -570,7 +570,7 @@
let processingDate = loopingDay.getUTCFullYear() + '-' + utilities.pad(loopingDay.getUTCMonth() + 1, 2) + '-' + utilities.pad(loopingDay.getUTCDate(), 2);
if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] runSimulation -> loop -> Simulation " + bot.sessionKey + " Loop # " + currentCandleIndex + " @ " + processingDate) }
console.log("Jason -> " + MODULE_NAME + " -> runSimulation -> loop -> Simulation " + bot.sessionKey + " Loop # " + currentCandleIndex + " @ " + processingDate)
console.log("Trading-Engine -> " + MODULE_NAME + " -> runSimulation -> loop -> Simulation " + bot.sessionKey + " Loop # " + currentCandleIndex + " @ " + processingDate)
bot.sessionHeartBeat(processingDate) // tell the world we are alive and doing well
}
+16 -16
View File
@@ -171,22 +171,22 @@ function newAppLoader() {
function defaultPlotters() {
return [
'Plotters/AAMasters/Plotters-Candles-Volumes/Candles.js',
'Plotters/AAMasters/Plotters-Candles-Volumes/CandlePanel.js',
'Plotters/AAMasters/Plotters-Candles-Volumes/Volumes.js',
'Plotters/AAMasters/Plotters-Candles-Volumes/VolumePanel.js',
'Plotters/AAMasters/Plotters-Stairs-Patterns/CandleStairs.js',
'Plotters/AAMasters/Plotters-Stairs-Patterns/VolumeStairs.js',
'Plotters/AAMasters/Plotters-Bollinger-Bands/BollingerBands.js',
'Plotters/AAMasters/Plotters-Bollinger-Bands/BollingerBandsPanel.js',
'Plotters/AAMasters/Plotters-Bollinger-Bands/PercentageBandwidth.js',
'Plotters/AAMasters/Plotters-Trading-Simulation/TradingSimulation.js',
'Plotters/AAMasters/Plotters-Trading-Simulation/TradingSimulationPanel.js',
'Plotters/AAMasters/Plotters-Trading-Simulation/Conditions.js',
'Plotters/AAMasters/Plotters-Trading-Simulation/Strategies.js',
'Plotters/AAMasters/Plotters-Trading-Simulation/Trades.js',
'Plotters/AAMasters/Plotters-Trading-Simulation/SimulationExecution.js',
'Plotters/AAMasters/Plotters-Trading-Simulation/SimulationExecutionPanel.js'
'Plotters/Masters/Plotters-Candles-Volumes/Candles.js',
'Plotters/Masters/Plotters-Candles-Volumes/CandlePanel.js',
'Plotters/Masters/Plotters-Candles-Volumes/Volumes.js',
'Plotters/Masters/Plotters-Candles-Volumes/VolumePanel.js',
'Plotters/Masters/Plotters-Stairs-Patterns/CandleStairs.js',
'Plotters/Masters/Plotters-Stairs-Patterns/VolumeStairs.js',
'Plotters/Masters/Plotters-Bollinger-Bands/BollingerBands.js',
'Plotters/Masters/Plotters-Bollinger-Bands/BollingerBandsPanel.js',
'Plotters/Masters/Plotters-Bollinger-Bands/PercentageBandwidth.js',
'Plotters/Masters/Plotters-Trading-Simulation/TradingSimulation.js',
'Plotters/Masters/Plotters-Trading-Simulation/TradingSimulationPanel.js',
'Plotters/Masters/Plotters-Trading-Simulation/Conditions.js',
'Plotters/Masters/Plotters-Trading-Simulation/Strategies.js',
'Plotters/Masters/Plotters-Trading-Simulation/Trades.js',
'Plotters/Masters/Plotters-Trading-Simulation/SimulationExecution.js',
'Plotters/Masters/Plotters-Trading-Simulation/SimulationExecutionPanel.js'
]
}
+1 -1
View File
@@ -218,7 +218,7 @@ function onBrowserRequest (request, response) {
{
try {
let rimraf = require('rimraf')
rimraf.sync(process.env.STORAGE_PATH + '/AAMasters/AAMasters/AAJason.1.0')
rimraf.sync(process.env.STORAGE_PATH + '/Masters/Masters/AAJason.1.0')
rimraf.sync(process.env.LOG_PATH)
respondWithContent(JSON.stringify(global.DEFAULT_OK_RESPONSE), response)
+1 -1
View File
@@ -1 +1 @@
{"type":"Workspace","name":"My Workspace","rootNodes":[{"type":"Network","name":"Superalgos","networkNodes":[{"type":"Network Node","name":"My Computer","dataStorage":{"type":"Data Storage","name":"New Data Storage","sessionIndependentData":{"type":"Session Independent Data","name":"New Session Independent Data","exchangeDataProducts":[{"type":"Exchange Data Products","name":"Binance","singleMarketData":[{"type":"Single Market Data","name":"Binance BTC/USDT","dataProducts":[{"type":"Data Product","name":"Candles","id":"592901f9-9d7e-4d02-9c3e-9941fd1cbc62","savedPayload":{"position":{"x":25668.591222219326,"y":29993.21611788368},"targetPosition":{"x":25557.124436708455,"y":30327.627717281495},"floatingObject":{"isPinned":false,"isFrozen":false,"isCollapsed":true,"angleToParent":2,"distanceToParent":3},"uiObject":{},"referenceParent":{"type":"Product Definition","name":"Candles","id":"fe6065ec-4d2d-47a0-bae0-8647f0e195d7"}}},{"type":"Data Product","name":"Volumes","id":"54e5d587-dae5-4901-8625-899f3b6eb361","savedPayload":{"position":{"x":25728.141198236768,"y":30019.392075018255},"targetPosition":{"x":25557.124436708455,"y":30327.627717281495},"floatingObject":{"isPinned":false,"isFrozen":false,"isCollapsed":true,"angleToParent":2,"distanceToParent":3},"uiObject":{},"referenceParent":{"type":"Product Definition","name":"Volumes","id":"1a366aef-efef-470e-88e0-2a6fbe4dd91f"}}},{"type":"Data Product","name":"Candle-Stairs","id":"7f5856c1-cf3a-4525-8036-69da93e57771","savedPayload":{"position":{"x":25781.86740324687,"y":30056.06461611922},"targetPosition":{"x":25557.124436708455,"y":30327.627717281495},"floatingObject":{"isPinned":false,"isFrozen":false,"isCollapsed":true,"angleToParent":2,"distanceToParent":3},"uiObject":{},"referenceParent":{"type":"Product Definition","name":"Candle-Stairs","id":"642474e9-da61-4168-97dc-7f7869bebc02"}}},{"type":"Data Product","name":"Volume-Stairs","id":"fad346d0-20f9-4cf4-9663-7eb54622b5f0","savedPayload":{"position":{"x":25827.940255775495,"y":30101.98490178324},"targetPosition":{"x":25557.124436708455,"y":30327.627717281495},"floatingObject":{"isPinned":false,"isFrozen":false,"isCollapsed":true,"angleToParent":2,"distanceToParent":3},"uiObject":{},"referenceParent":{"type":"Product Definition","name":"Volume-Stairs","id":"846e9572-c4d6-4c7e-942e-c82402c5ecea"}}},{"type":"Data Product","name":"Bollinger Bands","id":"2fc1f392-7d9b-409e-9cb7-85c14e1e7c07","savedPayload":{"position":{"x":25864.79080008807,"y":30155.589171757336},"targetPosition":{"x":25557.124436708455,"y":30327.627717281495},"floatingObject":{"isPinned":false,"isFrozen":false,"isCollapsed":true,"angleToParent":2,"distanceToParent":3},"uiObject":{},"referenceParent":{"type":"Product Definition","name":"Bollinger Bands","id":"29088877-8d63-4217-8d34-8742afc262f4"}}},{"type":"Data Product","name":"Percentage Bandwidth","id":"e7c4252c-3b6b-4b21-9f7a-6a6263739835","savedPayload":{"position":{"x":25891.164135095394,"y":30215.05199691878},"targetPosition":{"x":25557.124436708455,"y":30327.627717281495},"floatingObject":{"isPinned":false,"isFrozen":false,"isCollapsed":true,"angleToParent":2,"distanceToParent":3},"uiObject":{},"referenceParent":{"type":"Product Definition","name":"Percentage Bandwidth","id":"3b7885a0-cd72-4a3f-a38b-3dc8c47bd068"}}},{"type":"Data Product","name":"Bollinger Channels Objects","id":"3e9c58db-ca68-4089-9a02-d99f01428a41","savedPayload":{"position":{"x":25906.16214850512,"y":30278.3484420745},"targetPosition":{"x":25557.124436708455,"y":30327.627717281495},"floatingObject":{"isPinned":false,"isFrozen":false,"isCollapsed":true,"angleToParent":2,"distanceToParent":3},"uiObject":{},"referenceParent":{"type":"Product Definition","name":"Bollinger Channels Objects","id":"1f111f72-624f-4166-9f99-ab8d785d5267"}}},{"type":"Data Product","name":"Bollinger Sub-Channels Objects","id":"b47bf5eb-2f3e-462f-aa45-8e5c6ae784bc","savedPayload":{"position":{"x":25909.27410095871,"y":30343.323022700435},"targetPosition":{"x":25557.124436708455,"y":30327.627717281495},"floatingObject":{"isPinned":false,"isFrozen":false,"isCollapsed":true,"angleToParent":2,"distanceToParent":3},"uiObject":{},"referenceParent":{"type":"Product Definition","name":"Bollinger Sub-Channels Objects","id":"080c87fc-4546-4482-ab11-180a33f6d9ab"}}},{"type":"Data Product","name":"Popular SMAs","id":"67a989ee-e8da-4079-9b0a-8a7509db45a5","savedPayload":{"position":{"x":25900.394018647734,"y":30407.763107381787},"targetPosition":{"x":25557.124436708455,"y":30327.627717281495},"floatingObject":{"isPinned":false,"isFrozen":false,"isCollapsed":false,"angleToParent":2,"distanceToParent":3},"uiObject":{},"referenceParent":{"type":"Product Definition","name":"Popular SMAs","id":"4029d5bf-a8ad-4d80-b874-2af506e0ab34"}}},{"type":"Data Product","name":"Base7 SMAs","id":"763cde69-4a76-498f-a753-87baa3b227f3","savedPayload":{"position":{"x":25879.824302124813,"y":30469.474266322093},"targetPosition":{"x":25557.124436708455,"y":30327.627717281495},"fLine truncated
{"type":"Workspace","name":"My Workspace","rootNodes":[{"type":"Network","name":"Superalgos","networkNodes":[{"type":"Network Node","name":"My Computer","dataStorage":{"type":"Data Storage","name":"New Data Storage","sessionIndependentData":{"type":"Session Independent Data","name":"New Session Independent Data","exchangeDataProducts":[{"type":"Exchange Data Products","name":"Binance","singleMarketData":[{"type":"Single Market Data","name":"Binance BTC/USDT","dataProducts":[{"type":"Data Product","name":"Candles","id":"592901f9-9d7e-4d02-9c3e-9941fd1cbc62","savedPayload":{"position":{"x":25619.14913408399,"y":29826.271495898716},"targetPosition":{"x":25632.29444095039,"y":30178.525149848574},"floatingObject":{"isPinned":false,"isFrozen":false,"isCollapsed":true,"angleToParent":2,"distanceToParent":3},"uiObject":{},"referenceParent":{"type":"Product Definition","name":"Candles","id":"fe6065ec-4d2d-47a0-bae0-8647f0e195d7"}}},{"type":"Data Product","name":"Volumes","id":"54e5d587-dae5-4901-8625-899f3b6eb361","savedPayload":{"position":{"x":25684.099470510602,"y":29829.8539773933},"targetPosition":{"x":25632.29444095039,"y":30178.525149848574},"floatingObject":{"isPinned":false,"isFrozen":false,"isCollapsed":true,"angleToParent":2,"distanceToParent":3},"uiObject":{},"referenceParent":{"type":"Product Definition","name":"Volumes","id":"1a366aef-efef-470e-88e0-2a6fbe4dd91f"}}},{"type":"Data Product","name":"Candle-Stairs","id":"7f5856c1-cf3a-4525-8036-69da93e57771","savedPayload":{"position":{"x":25747.285624786167,"y":29845.310053333007},"targetPosition":{"x":25632.29444095039,"y":30178.525149848574},"floatingObject":{"isPinned":false,"isFrozen":false,"isCollapsed":true,"angleToParent":2,"distanceToParent":3},"uiObject":{},"referenceParent":{"type":"Product Definition","name":"Candle-Stairs","id":"642474e9-da61-4168-97dc-7f7869bebc02"}}},{"type":"Data Product","name":"Volume-Stairs","id":"fad346d0-20f9-4cf4-9663-7eb54622b5f0","savedPayload":{"position":{"x":25806.555868210267,"y":29872.11338558923},"targetPosition":{"x":25632.29444095039,"y":30178.525149848574},"floatingObject":{"isPinned":false,"isFrozen":false,"isCollapsed":true,"angleToParent":2,"distanceToParent":3},"uiObject":{},"referenceParent":{"type":"Product Definition","name":"Volume-Stairs","id":"846e9572-c4d6-4c7e-942e-c82402c5ecea"}}},{"type":"Data Product","name":"Bollinger Bands","id":"2fc1f392-7d9b-409e-9cb7-85c14e1e7c07","savedPayload":{"position":{"x":25859.891823729915,"y":29909.351218829033},"targetPosition":{"x":25632.29444095039,"y":30178.525149848574},"floatingObject":{"isPinned":false,"isFrozen":false,"isCollapsed":true,"angleToParent":2,"distanceToParent":3},"uiObject":{},"referenceParent":{"type":"Product Definition","name":"Bollinger Bands","id":"29088877-8d63-4217-8d34-8742afc262f4"}}},{"type":"Data Product","name":"Percentage Bandwidth","id":"e7c4252c-3b6b-4b21-9f7a-6a6263739835","savedPayload":{"position":{"x":25905.477199349316,"y":29955.7554633033},"targetPosition":{"x":25632.29444095039,"y":30178.525149848574},"floatingObject":{"isPinned":false,"isFrozen":false,"isCollapsed":true,"angleToParent":2,"distanceToParent":3},"uiObject":{},"referenceParent":{"type":"Product Definition","name":"Percentage Bandwidth","id":"3b7885a0-cd72-4a3f-a38b-3dc8c47bd068"}}},{"type":"Data Product","name":"Bollinger Channels Objects","id":"3e9c58db-ca68-4089-9a02-d99f01428a41","savedPayload":{"position":{"x":25941.759639775388,"y":30009.74587812221},"targetPosition":{"x":25632.29444095039,"y":30178.525149848574},"floatingObject":{"isPinned":false,"isFrozen":false,"isCollapsed":true,"angleToParent":2,"distanceToParent":3},"uiObject":{},"referenceParent":{"type":"Product Definition","name":"Bollinger Channels Objects","id":"1f111f72-624f-4166-9f99-ab8d785d5267"}}},{"type":"Data Product","name":"Bollinger Sub-Channels Objects","id":"b47bf5eb-2f3e-462f-aa45-8e5c6ae784bc","savedPayload":{"position":{"x":25967.503590015407,"y":30069.48388446347},"targetPosition":{"x":25632.29444095039,"y":30178.525149848574},"floatingObject":{"isPinned":false,"isFrozen":false,"isCollapsed":true,"angleToParent":2,"distanceToParent":3},"uiObject":{},"referenceParent":{"type":"Product Definition","name":"Bollinger Sub-Channels Objects","id":"080c87fc-4546-4482-ab11-180a33f6d9ab"}}},{"type":"Data Product","name":"Popular SMAs","id":"67a989ee-e8da-4079-9b0a-8a7509db45a5","savedPayload":{"position":{"x":25981.832370720418,"y":30132.935176168972},"targetPosition":{"x":25632.29444095039,"y":30178.525149848574},"floatingObject":{"isPinned":false,"isFrozen":false,"isCollapsed":false,"angleToParent":2,"distanceToParent":3},"uiObject":{},"referenceParent":{"type":"Product Definition","name":"Popular SMAs","id":"4029d5bf-a8ad-4d80-b874-2af506e0ab34"}}},{"type":"Data Product","name":"Base7 SMAs","id":"763cde69-4a76-498f-a753-87baa3b227f3","savedPayload":{"position":{"x":25984.25803244899,"y":30197.938995601125},"targetPosition":{"x":25632.29444095039,"y":30178.525149848574},"floatingObLine truncated