diff --git a/.vs/AAOlivia-Indicator-Bot/v15/.suo b/.vs/AAOlivia-Indicator-Bot/v15/.suo
index e037f3b17..aa9d419a5 100644
Binary files a/.vs/AAOlivia-Indicator-Bot/v15/.suo and b/.vs/AAOlivia-Indicator-Bot/v15/.suo differ
diff --git a/Commons.js b/Commons.js
new file mode 100644
index 000000000..50c2c7df0
--- /dev/null
+++ b/Commons.js
@@ -0,0 +1,264 @@
+exports.newCommons = function newCommons(BOT, DEBUG_MODULE, 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,
+ getContextVariables: getContextVariables
+ };
+
+ let bot = BOT;
+
+ const logger = DEBUG_MODULE.newDebugLog();
+ logger.fileName = MODULE_NAME;
+ logger.bot = bot;
+
+ let utilities = UTILITIES.newUtilities(bot);
+
+ return thisObject;
+
+ function initializeStorage(charlyFileStorage, bruceFileStorage, oliviaFileStorage, callBackFunction) {
+
+ try {
+
+ if (FULL_LOG === true) { logger.write("[INFO] initializeStorage -> Entering function."); }
+
+ initializeCharlyStorage();
+
+ function initializeCharlyStorage() {
+
+ charlyFileStorage.initialize("AACharly", onCharlyInizialized);
+
+ function onCharlyInizialized(err) {
+
+ if (err.result === global.DEFAULT_OK_RESPONSE.result) {
+
+ initializeBruceStorage();
+
+ } else {
+ logger.write("[ERROR] initializeStorage -> initializeCharlyStorage -> onCharlyInizialized -> err = " + err.message);
+ callBackFunction(err);
+ }
+ }
+ }
+
+ function initializeBruceStorage() {
+
+ bruceFileStorage.initialize("AABruce", onBruceInizialized);
+
+ function onBruceInizialized(err) {
+
+ if (err.result === global.DEFAULT_OK_RESPONSE.result) {
+
+ initializeOliviaStorage();
+
+ } else {
+ logger.write("[ERROR] initializeStorage -> initializeBruceStorage -> onBruceInizialized -> err = " + err.message);
+ callBackFunction(err);
+ }
+ }
+ }
+
+ function initializeOliviaStorage() {
+
+ oliviaFileStorage.initialize("AAOlivia", onOliviaInizialized);
+
+ function onOliviaInizialized(err) {
+
+ if (err.result === global.DEFAULT_OK_RESPONSE.result) {
+
+ callBackFunction(global.DEFAULT_OK_RESPONSE);
+
+ } else {
+ logger.write("[ERROR] initializeStorage -> initializeOliviaStorage -> onOliviaInizialized -> err = " + err.message);
+ callBackFunction(err);
+ }
+ }
+ }
+ }
+ catch (err) {
+ logger.write("[ERROR] initializeStorage -> err = " + err.message);
+ callBackFunction(global.DEFAULT_FAIL_RESPONSE);
+ }
+ }
+
+ function getContextVariables(charlyFileStorage, bruceFileStorage, oliviaFileStorage, contextVariables, statusReportModule, callBackFunction) {
+
+ try {
+
+ if (FULL_LOG === true) { logger.write("[INFO] getContextVariables -> Entering function."); }
+
+ let reportFilePath;
+ let fileName = "Status.Report." + global.MARKET.assetA + '_' + global.MARKET.assetB + ".json"
+
+ if (FULL_LOG === true) { logger.write("[INFO] getContextVariables -> fileName = " + fileName); }
+
+ getHistoricTrades();
+
+ function getHistoricTrades() {
+
+ if (FULL_LOG === true) { logger.write("[INFO] getContextVariables -> getHistoricTrades -> Entering function."); }
+
+ /*
+
+ We need to know where is the begining of the market, since that will help us know where the Index Files should start.
+
+ */
+
+ reportFilePath = EXCHANGE_NAME + "/Processes/" + "Poloniex-Historic-Trades";
+
+ if (FULL_LOG === true) { logger.write("[INFO] getContextVariables -> getHistoricTrades -> reportFilePath = " + reportFilePath); }
+
+ charlyFileStorage.getTextFile(reportFilePath, fileName, onFileReceived);
+
+ function onFileReceived(err, text) {
+
+ if (FULL_LOG === true) { logger.write("[INFO] getContextVariables -> getHistoricTrades -> onFileReceived -> Entering function."); }
+ if (FULL_LOG === true) { logger.write("[INFO] getContextVariables -> getHistoricTrades -> onFileReceived -> text = " + text); }
+
+ let thisReport;
+
+ if (err.result === global.DEFAULT_OK_RESPONSE.result) {
+ try {
+ thisReport = JSON.parse(text);
+
+ contextVariables.firstTradeFile = new Date(thisReport.lastFile.year + "-" + thisReport.lastFile.month + "-" + thisReport.lastFile.days + " " + thisReport.lastFile.hours + ":" + thisReport.lastFile.minutes + GMT_SECONDS);
+
+ getOneMinDailyCandlesVolumes();
+
+ } catch (err) {
+ logger.write("[ERROR] getContextVariables -> getHistoricTrades -> onFileReceived -> err = " + err.message);
+ logger.write("[ERROR] getContextVariables -> getHistoricTrades -> onFileReceived -> Asuming this is a temporary situation. Requesting a Retry.");
+ callBackFunction(global.DEFAULT_RETRY_RESPONSE);
+ }
+ } else {
+ logger.write("[ERROR] getContextVariables -> getHistoricTrades -> onFileReceived -> err = " + err.message);
+ callBackFunction(err);
+ }
+ }
+ }
+
+ function getOneMinDailyCandlesVolumes() {
+
+ if (FULL_LOG === true) { logger.write("[INFO] getContextVariables -> getOneMinDailyCandlesVolumes -> Entering function."); }
+
+ /* We need to discover the maxCandle file, which is the last file with candles we can use as input. */
+
+ let date = new Date();
+ let currentYear = date.getUTCFullYear();
+ let currentMonth = utilities.pad(date.getUTCMonth() + 1, 2);
+
+ reportFilePath = EXCHANGE_NAME + "/Processes/" + "One-Min-Daily-Candles-Volumes" + "/" + currentYear + "/" + currentMonth;
+
+ if (FULL_LOG === true) { logger.write("[INFO] getContextVariables -> getOneMinDailyCandlesVolumes -> reportFilePath = " + reportFilePath); }
+
+ bruceFileStorage.getTextFile(reportFilePath, fileName, onFileReceived);
+
+ function onFileReceived(err, text) {
+
+ if (FULL_LOG === true) { logger.write("[INFO] getContextVariables -> getOneMinDailyCandlesVolumes -> onFileReceived -> Entering function."); }
+ if (FULL_LOG === true) { logger.write("[INFO] getContextVariables -> getOneMinDailyCandlesVolumes -> onFileReceived -> text = " + text); }
+
+ let thisReport;
+
+ if (err.result === global.DEFAULT_OK_RESPONSE.result) {
+ try {
+ thisReport = JSON.parse(text);
+
+ contextVariables.maxCandleFile = new Date(thisReport.lastFile.year + "-" + thisReport.lastFile.month + "-" + thisReport.lastFile.days + " " + "00:00" + GMT_SECONDS);
+
+ getThisProcessReport();
+
+ } catch (err) {
+ logger.write("[ERROR] getContextVariables -> getOneMinDailyCandlesVolumes -> onFileReceived -> err = " + err.message);
+ logger.write("[ERROR] getContextVariables -> getOneMinDailyCandlesVolumes -> onFileReceived -> Asuming this is a temporary situation. Requesting a Retry.");
+ callBackFunction(global.DEFAULT_RETRY_RESPONSE);
+ }
+ } else {
+ logger.write("[ERROR] getContextVariables -> getHistoricTrades -> onFileReceived -> err = " + err.message);
+ callBackFunction(err);
+ }
+ }
+ }
+
+ function getThisProcessReport() {
+
+ if (FULL_LOG === true) { logger.write("[INFO] getContextVariables -> getThisProcessReport -> Entering function."); }
+
+ statusReportModule.initialize(bot, onInitilized);
+
+ function onInitilized(err) {
+
+ try {
+
+ switch (err.result) {
+ case global.DEFAULT_OK_RESPONSE.result: {
+ logger.write("[INFO] getContextVariables -> getThisProcessReport -> onInitilized -> Execution finished well. :-)");
+
+ contextVariables.lastCandleFile = new Date(statusReportModule.file.lastFile);
+
+ /*
+ Here we assume that the last day written might contain incomplete information. This actually happens every time the head of the market is reached.
+ For that reason we go back one day, the partial information is discarded and added again with whatever new info is available.
+ */
+
+ contextVariables.lastCandleFile = new Date(contextVariables.lastCandleFile.valueOf() - ONE_DAY_IN_MILISECONDS);
+
+ let customOk = {
+ result: global.CUSTOM_OK_RESPONSE.result,
+ message: "Status Report did exist."
+ };
+
+ callBackFunction(customOk);
+
+ return;
+ }
+ case global.CUSTOM_FAIL_RESPONSE.result: { // We need to see if we can handle this.
+ logger.write("[ERROR] getContextVariables -> getThisProcessReport -> onInitilized -> err.message = " + err.message);
+
+ if (err.message === "Status Report was never created.") {
+
+ contextVariables.lastCandleFile = new Date(contextVariables.firstTradeFile.getUTCFullYear() + "-" + (contextVariables.firstTradeFile.getUTCMonth() + 1) + "-" + contextVariables.firstTradeFile.getUTCDate() + " " + "00:00" + GMT_SECONDS);
+
+ contextVariables.lastCandleFile = new Date(contextVariables.lastCandleFile.valueOf() - ONE_DAY_IN_MILISECONDS); // Go back one day to start well.
+
+ let customOk = {
+ result: global.CUSTOM_OK_RESPONSE.result,
+ message: "Status Report did not exist."
+ };
+
+ callBackFunction(customOk);
+ return;
+
+ } else {
+ callBackFunction(err); // we cant handle this here.
+ }
+ return;
+ }
+ default:
+ {
+ logger.write("[ERROR] getContextVariables -> getThisProcessReport -> onInitilized -> Operation Failed.");
+ callBackFunction(err);
+ return;
+ }
+ }
+ }
+ catch (err) {
+ logger.write("[ERROR] getContextVariables -> getThisProcessReport -> onInitilized -> err = " + err.message);
+ callBackFunction(global.DEFAULT_FAIL_RESPONSE);
+ }
+ }
+ }
+ }
+ catch (err) {
+ logger.write("[ERROR] getContextVariables -> err = " + err.message);
+ callBackFunction(global.DEFAULT_FAIL_RESPONSE);
+ }
+ }
+};
\ No newline at end of file
diff --git a/Multi-Period-Daily/Interval.js b/Multi-Period-Daily/User.bot.js
similarity index 74%
rename from Multi-Period-Daily/Interval.js
rename to Multi-Period-Daily/User.bot.js
index 248159bfc..8ac9e0b66 100644
--- a/Multi-Period-Daily/Interval.js
+++ b/Multi-Period-Daily/User.bot.js
@@ -1,4 +1,7 @@
-exports.newInterval = function newInterval(BOT, UTILITIES, AZURE_FILE_STORAGE, DEBUG_MODULE, MARKETS_MODULE, POLONIEX_CLIENT_MODULE) {
+exports.newUserBot = function newUserBot(BOT, COMMONS, UTILITIES, DEBUG_MODULE, FILE_STORAGE, STATUS_REPORT) {
+
+ const FULL_LOG = true;
+ const LOG_FILE_CONTENT = false;
let bot = BOT;
@@ -6,11 +9,9 @@
const GMT_MILI_SECONDS = '.000 GMT+0000';
const ONE_DAY_IN_MILISECONDS = 24 * 60 * 60 * 1000;
- const MODULE_NAME = "Interval";
- const LOG_INFO = true;
+ const MODULE_NAME = "UserBot";
const EXCHANGE_NAME = "Poloniex";
- const EXCHANGE_ID = 1;
const TRADES_FOLDER_NAME = "Trades";
@@ -20,27 +21,27 @@
const VOLUMES_FOLDER_NAME = "Volumes";
const VOLUMES_ONE_MIN = "One-Min";
- const GO_RANDOM = false;
- const FORCE_MARKET = 2; // This allows to debug the execution of an specific market. Not intended for production.
-
const logger = DEBUG_MODULE.newDebugLog();
logger.fileName = MODULE_NAME;
logger.bot = bot;
- interval = {
+ const commons = COMMONS.newCommons(bot, DEBUG_MODULE);
+
+ thisObject = {
initialize: initialize,
start: start
};
- let markets;
-
- let charlyAzureFileStorage = AZURE_FILE_STORAGE.newAzureFileStorage(bot);
- let bruceAzureFileStorage = AZURE_FILE_STORAGE.newAzureFileStorage(bot);
- let oliviaAzureFileStorage = AZURE_FILE_STORAGE.newAzureFileStorage(bot);
+ let charlyFileStorage = FILE_STORAGE.newAzureFileStorage(bot);
+ let bruceFileStorage = FILE_STORAGE.newAzureFileStorage(bot);
+ let oliviaFileStorage = FILE_STORAGE.newAzureFileStorage(bot);
let utilities = UTILITIES.newUtilities(bot);
- return interval;
+ let statusReport;
+ let statusReportModule;
+
+ return thisObject;
function initialize(yearAssigend, monthAssigned, callBackFunction) {
@@ -48,30 +49,72 @@
/* IMPORTANT NOTE:
- We are ignoring in this Interval the received Year and Month. This interval is not depending on Year Month since it procecess the whole market at once.
+ We are ignoring in this UserBot the received Year and Month. thisObject is not depending on Year Month since it procecess the whole market at once.
*/
logger.fileName = MODULE_NAME;
- const logText = "[INFO] initialize - Entering function 'initialize' ";
- console.log(logText);
- logger.write(logText);
+ if (FULL_LOG === true) { logger.write("[INFO] initialize -> Entering function."); }
+ if (FULL_LOG === true) { logger.write("[INFO] initialize -> yearAssigend = " + yearAssigend); }
+ if (FULL_LOG === true) { logger.write("[INFO] initialize -> monthAssigned = " + monthAssigned); }
- charlyAzureFileStorage.initialize("Charly");
- bruceAzureFileStorage.initialize("Bruce");
- oliviaAzureFileStorage.initialize("Olivia");
+ initializeCharlyStorage();
- markets = MARKETS_MODULE.newMarkets(bot);
- markets.initialize(callBackFunction);
+ function initializeCharlyStorage() {
+ charlyFileStorage.initialize("AACharly", onCharlyInizialized);
+
+ function onCharlyInizialized(err) {
+
+ if (err.result === global.DEFAULT_OK_RESPONSE.result) {
+
+ initializeBruceStorage();
+
+ } else {
+ logger.write("[ERROR] initialize -> initializeCharlyStorage -> onCharlyInizialized -> err = " + err.message);
+ callBackFunction(err);
+ }
+ }
+ }
+
+ function initializeBruceStorage() {
+
+ bruceFileStorage.initialize("AABruce", onBruceInizialized);
+
+ function onBruceInizialized(err) {
+
+ if (err.result === global.DEFAULT_OK_RESPONSE.result) {
+
+ initializeOliviaStorage();
+
+ } else {
+ logger.write("[ERROR] initialize -> initializeBruceStorage -> onBruceInizialized -> err = " + err.message);
+ callBackFunction(err);
+ }
+ }
+ }
+
+ function initializeOliviaStorage() {
+
+ oliviaFileStorage.initialize("AAOlivia", onOliviaInizialized);
+
+ function onOliviaInizialized(err) {
+
+ if (err.result === global.DEFAULT_OK_RESPONSE.result) {
+
+ callBackFunction(global.DEFAULT_OK_RESPONSE);
+
+ } else {
+ logger.write("[ERROR] initialize -> initializeOliviaStorage -> onOliviaInizialized -> err = " + err.message);
+ callBackFunction(err);
+ }
+ }
+ }
} catch (err) {
-
- const logText = "[ERROR] initialize - ' ERROR : " + err.message;
- console.log(logText);
- logger.write(logText);
-
+ logger.write("[ERROR] initialize -> err = " + err.message);
+ callBackFunction(global.DEFAULT_FAIL_RESPONSE);
}
}
@@ -79,7 +122,7 @@
This process is going to do the following:
-Read the candles and volumes from Bruce and produce a single Index File for each market with daily candles and volumes.
+Read the candles and volumes from Bruce and produce a file for each day and for each period with candles and volumes.
*/
@@ -87,171 +130,18 @@ Read the candles and volumes from Bruce and produce a single Index File for each
try {
- if (LOG_INFO === true) {
- logger.write("[INFO] Entering function 'start'");
- }
+ if (FULL_LOG === true) { logger.write("[INFO] start -> Entering function."); }
- let nextIntervalExecution = false; // This tell weather the Interval module will be executed again or not. By default it will not unless some hole have been found in the current execution.
- let nextIntervalLapse; // With this we can request the next execution wait time.
+ let market = global.MARKET;
- let marketQueue; // This is the queue of all markets to be procesesd at each interval.
- let market = { // This is the current market being processed after removing it from the queue.
- id: 0,
- assetA: "",
- assetB: ""
- };
+
let lastCandleFile; // Datetime of the last file included on the Index File.
let firstTradeFile; // Datetime of the first trade file in the whole market history.
let maxCandleFile; // Datetime of the last file available to be included in the Index File.
- let periods =
- '[' +
- '[' + 45 * 60 * 1000 + ',' + '"45-min"' + ']' + ',' +
- '[' + 40 * 60 * 1000 + ',' + '"40-min"' + ']' + ',' +
- '[' + 30 * 60 * 1000 + ',' + '"30-min"' + ']' + ',' +
- '[' + 20 * 60 * 1000 + ',' + '"20-min"' + ']' + ',' +
- '[' + 15 * 60 * 1000 + ',' + '"15-min"' + ']' + ',' +
- '[' + 10 * 60 * 1000 + ',' + '"10-min"' + ']' + ',' +
- '[' + 05 * 60 * 1000 + ',' + '"05-min"' + ']' + ',' +
- '[' + 04 * 60 * 1000 + ',' + '"04-min"' + ']' + ',' +
- '[' + 03 * 60 * 1000 + ',' + '"03-min"' + ']' + ',' +
- '[' + 02 * 60 * 1000 + ',' + '"02-min"' + ']' + ',' +
- '[' + 01 * 60 * 1000 + ',' + '"01-min"' + ']' + ']';
-
- const outputPeriods = JSON.parse(periods);
-
- marketsLoop();
-
- /*
-
- At every run, the process needs to loop through all the markets at this exchange.
- The following functions marketsLoop(), openMarket(), closeMarket() and closeAndOpenMarket() controls the serialization of this processing.
-
- */
-
- function marketsLoop() {
-
- try {
-
- if (LOG_INFO === true) {
- logger.write("[INFO] Entering function 'marketsLoop'");
- }
-
- markets.getMarketsByExchange(EXCHANGE_ID, onMarketsReady);
-
- function onMarketsReady(marketsArray) {
-
- marketQueue = JSON.parse(marketsArray);
-
- openMarket(); // First execution and entering into the real loop.
-
- }
- }
- catch (err) {
- const logText = "[ERROR] 'marketsLoop' - ERROR : " + err.message;
- logger.write(logText);
- }
- }
-
- function openMarket() {
-
- // To open a Market means picking a new market from the queue.
-
- try {
-
- if (LOG_INFO === true) {
- logger.write("[INFO] Entering function 'openMarket'");
- }
- if (marketQueue.length === 0) {
-
- if (LOG_INFO === true) {
- logger.write("[INFO] 'openMarket' - marketQueue.length === 0");
- }
-
- const logText = "[WARN] We processed all the markets.";
- logger.write(logText);
-
- callBackFunction(nextIntervalExecution, nextIntervalLapse);
-
- return;
- }
-
- if (GO_RANDOM === true) {
- const index = parseInt(Math.random() * (marketQueue.length - 1));
-
- market.id = marketQueue[index][0];
- market.assetA = marketQueue[index][1];
- market.assetB = marketQueue[index][2];
- market.status = marketQueue[index][3];
-
- marketQueue.splice(index, 1);
- } else {
- let marketRecord = marketQueue.shift();
-
- market.id = marketRecord[0];
- market.assetA = marketRecord[1];
- market.assetB = marketRecord[2];
- market.status = marketRecord[3];
-
- if (FORCE_MARKET > 0) {
- if (FORCE_MARKET !== market.id) {
- closeAndOpenMarket();
- return;
- }
- }
- }
-
- if (LOG_INFO === true) {
- logger.write("[INFO] 'openMarket' - marketQueue.length = " + marketQueue.length);
- logger.write("[INFO] 'openMarket' - market sucessfully opened : " + market.assetA + "_" + market.assetB);
- }
-
- if (market.status === markets.ENABLED) {
-
- getStatusReport();
-
- } else {
-
- logger.write("[INFO] 'openMarket' - market " + market.assetA + "_" + market.assetB + " skipped because its status is not valid. Status = " + market.status);
- closeAndOpenMarket();
- return;
-
- }
-
-
- }
- catch (err) {
- const logText = "[ERROR] 'openMarket' - ERROR : " + err.message;
- logger.write(logText);
- closeMarket();
- }
- }
-
- function closeMarket() {
-
- if (LOG_INFO === true) {
- logger.write("[INFO] Entering function 'closeMarket'");
- }
-
- }
-
- function closeAndOpenMarket() {
-
- if (LOG_INFO === true) {
- logger.write("[INFO] Entering function 'closeAndOpenMarket'");
- }
-
- openMarket();
- }
-
- /*
-
- The following code executes for each market.
-
- */
function getStatusReport() {
@@ -272,7 +162,7 @@ Read the candles and volumes from Bruce and produce a single Index File for each
reportFilePath = EXCHANGE_NAME + "/Processes/" + "Poloniex-Historic-Trades";
- charlyAzureFileStorage.getTextFile(reportFilePath, fileName, onStatusReportReceived, true);
+ charlyFileStorage.getTextFile(reportFilePath, fileName, onStatusReportReceived, true);
function onStatusReportReceived(text) {
@@ -306,7 +196,7 @@ Read the candles and volumes from Bruce and produce a single Index File for each
reportFilePath = EXCHANGE_NAME + "/Processes/" + "One-Min-Daily-Candles-Volumes" + "/" + currentYear + "/" + currentMonth;
- bruceAzureFileStorage.getTextFile(reportFilePath, fileName, onStatusReportReceived, true);
+ bruceFileStorage.getTextFile(reportFilePath, fileName, onStatusReportReceived, true);
function onStatusReportReceived(text) {
@@ -342,7 +232,7 @@ Read the candles and volumes from Bruce and produce a single Index File for each
reportFilePath = EXCHANGE_NAME + "/Processes/" + bot.process;
- oliviaAzureFileStorage.getTextFile(reportFilePath, fileName, onStatusReportReceived, true);
+ oliviaFileStorage.getTextFile(reportFilePath, fileName, onStatusReportReceived, true);
function onStatusReportReceived(text) {
@@ -404,7 +294,7 @@ Read the candles and volumes from Bruce and produce a single Index File for each
if (lastCandleFile.valueOf() > maxCandleFile.valueOf()) {
- nextIntervalExecution = true; // we request a new interval execution.
+ nextIntervalExecution = true; // we request a new thisObject execution.
const logText = "[INFO] 'buildCandles' - Head of the market found @ " + lastCandleFile.getUTCFullYear() + "/" + (lastCandleFile.getUTCMonth() + 1) + "/" + lastCandleFile.getUTCDate() + ".";
logger.write(logText);
@@ -463,7 +353,7 @@ Read the candles and volumes from Bruce and produce a single Index File for each
let fileName = market.assetA + '_' + market.assetB + ".json"
let filePath = EXCHANGE_NAME + "/Output/" + CANDLES_FOLDER_NAME + '/' + CANDLES_ONE_MIN + '/' + dateForPath;
- bruceAzureFileStorage.getTextFile(filePath, fileName, onFileReceived, true);
+ bruceFileStorage.getTextFile(filePath, fileName, onFileReceived, true);
function onFileReceived(text) {
@@ -480,7 +370,7 @@ Read the candles and volumes from Bruce and produce a single Index File for each
closeAndOpenMarket();
- nextIntervalExecution = true; // we request a new interval execution.
+ nextIntervalExecution = true; // we request a new thisObject execution.
nextIntervalLapse = 30000;
return;
@@ -567,7 +457,7 @@ Read the candles and volumes from Bruce and produce a single Index File for each
let fileName = market.assetA + '_' + market.assetB + ".json"
let filePath = EXCHANGE_NAME + "/Output/" + VOLUMES_FOLDER_NAME + '/' + VOLUMES_ONE_MIN + '/' + dateForPath;
- bruceAzureFileStorage.getTextFile(filePath, fileName, onFileReceived, true);
+ bruceFileStorage.getTextFile(filePath, fileName, onFileReceived, true);
function onFileReceived(text) {
@@ -705,11 +595,11 @@ Read the candles and volumes from Bruce and produce a single Index File for each
let filePath = EXCHANGE_NAME + "/Output/" + CANDLES_FOLDER_NAME + "/" + bot.process + "/" + folderName + "/" + dateForPath;
- utilities.createFolderIfNeeded(filePath, oliviaAzureFileStorage, onFolderCreated);
+ utilities.createFolderIfNeeded(filePath, oliviaFileStorage, onFolderCreated);
function onFolderCreated() {
- oliviaAzureFileStorage.createTextFile(filePath, fileName, fileContent + '\n', onFileCreated);
+ oliviaFileStorage.createTextFile(filePath, fileName, fileContent + '\n', onFileCreated);
function onFileCreated() {
@@ -750,11 +640,11 @@ Read the candles and volumes from Bruce and produce a single Index File for each
let filePath = EXCHANGE_NAME + "/Output/" + VOLUMES_FOLDER_NAME + "/" + bot.process + "/" + folderName + "/" + dateForPath;
- utilities.createFolderIfNeeded(filePath, oliviaAzureFileStorage, onFolderCreated);
+ utilities.createFolderIfNeeded(filePath, oliviaFileStorage, onFolderCreated);
function onFolderCreated() {
- oliviaAzureFileStorage.createTextFile(filePath, fileName, fileContent + '\n', onFileCreated);
+ oliviaFileStorage.createTextFile(filePath, fileName, fileContent + '\n', onFileCreated);
function onFileCreated() {
@@ -785,7 +675,7 @@ Read the candles and volumes from Bruce and produce a single Index File for each
let reportFilePath = EXCHANGE_NAME + "/Processes/" + bot.process;
- utilities.createFolderIfNeeded(reportFilePath, oliviaAzureFileStorage, onFolderCreated);
+ utilities.createFolderIfNeeded(reportFilePath, oliviaFileStorage, onFolderCreated);
function onFolderCreated() {
@@ -803,7 +693,7 @@ Read the candles and volumes from Bruce and produce a single Index File for each
let fileContent = JSON.stringify(report);
- oliviaAzureFileStorage.createTextFile(reportFilePath, fileName, fileContent + '\n', onFileCreated);
+ oliviaFileStorage.createTextFile(reportFilePath, fileName, fileContent + '\n', onFileCreated);
function onFileCreated() {
diff --git a/Multi-Period-Market/User.bot.js b/Multi-Period-Market/User.bot.js
index 7011deaf0..948e8a192 100644
--- a/Multi-Period-Market/User.bot.js
+++ b/Multi-Period-Market/User.bot.js
@@ -1,4 +1,4 @@
-exports.newUserBot = function newUserBot(BOT, UTILITIES, DEBUG_MODULE, FILE_STORAGE, STATUS_REPORT) {
+exports.newUserBot = function newUserBot(BOT, COMMONS, UTILITIES, DEBUG_MODULE, FILE_STORAGE, STATUS_REPORT) {
const FULL_LOG = true;
const LOG_FILE_CONTENT = false;
@@ -12,7 +12,6 @@
const MODULE_NAME = "UserBot";
const EXCHANGE_NAME = "Poloniex";
- const EXCHANGE_ID = 1;
const TRADES_FOLDER_NAME = "Trades";
@@ -26,7 +25,9 @@
logger.fileName = MODULE_NAME;
logger.bot = bot;
- interval = {
+ const commons = COMMONS.newCommons(bot, DEBUG_MODULE, UTILITIES);
+
+ thisObject = {
initialize: initialize,
start: start
};
@@ -37,10 +38,9 @@
let utilities = UTILITIES.newUtilities(bot);
- let statusReport;
- let statusReportModule;
+ let statusReportModule = STATUS_REPORT.newStatusReport(BOT, DEBUG_MODULE, FILE_STORAGE, UTILITIES);
- return interval;
+ return thisObject;
function initialize(yearAssigend, monthAssigned, callBackFunction) {
@@ -48,7 +48,7 @@
/* IMPORTANT NOTE:
- We are ignoring in this UserBot the received Year and Month. This interval is not depending on Year Month since it procecess the whole market at once.
+ We are ignoring in this UserBot the received Year and Month. thisObject is not depending on Year Month since it procecess the whole market at once.
*/
@@ -58,58 +58,7 @@
if (FULL_LOG === true) { logger.write("[INFO] initialize -> yearAssigend = " + yearAssigend); }
if (FULL_LOG === true) { logger.write("[INFO] initialize -> monthAssigned = " + monthAssigned); }
- initializeCharlyStorage();
-
- function initializeCharlyStorage() {
-
- charlyFileStorage.initialize("AACharly", onCharlyInizialized);
-
- function onCharlyInizialized(err) {
-
- if (err.result === global.DEFAULT_OK_RESPONSE.result) {
-
- initializeBruceStorage();
-
- } else {
- logger.write("[ERROR] initialize -> initializeCharlyStorage -> onCharlyInizialized -> err = " + err.message);
- callBackFunction(err);
- }
- }
- }
-
- function initializeBruceStorage() {
-
- bruceFileStorage.initialize("AABruce", onBruceInizialized);
-
- function onBruceInizialized(err) {
-
- if (err.result === global.DEFAULT_OK_RESPONSE.result) {
-
- initializeOliviaStorage();
-
- } else {
- logger.write("[ERROR] initialize -> initializeBruceStorage -> onBruceInizialized -> err = " + err.message);
- callBackFunction(err);
- }
- }
- }
-
- function initializeOliviaStorage() {
-
- oliviaFileStorage.initialize("AAOlivia", onOliviaInizialized);
-
- function onOliviaInizialized(err) {
-
- if (err.result === global.DEFAULT_OK_RESPONSE.result) {
-
- callBackFunction(global.DEFAULT_OK_RESPONSE);
-
- } else {
- logger.write("[ERROR] initialize -> initializeOliviaStorage -> onOliviaInizialized -> err = " + err.message);
- callBackFunction(err);
- }
- }
- }
+ commons.initializeStorage(charlyFileStorage, bruceFileStorage, oliviaFileStorage, callBackFunction);
} catch (err) {
logger.write("[ERROR] initialize -> err = " + err.message);
@@ -135,176 +84,52 @@ Read the candles and volumes from Bruce and produce a single Index File for Mark
/* Context Variables */
- let lastCandleFile; // Datetime of the last file included on the Index Files.
- let firstTradeFile; // Datetime of the first trade file in the whole market history.
- let maxCandleFile; // Datetime of the last file available to be included in the Index File.
+ contextVariables = {
+ lastCandleFile: undefined, // Datetime of the last file included on the Index Files.
+ firstTradeFile: undefined, // Datetime of the first trade file in the whole market history.
+ maxCandleFile: undefined // Datetime of the last file available to be included in the Index File.
+ };
- getContextVariables();
+ commons.getContextVariables(charlyFileStorage, bruceFileStorage, oliviaFileStorage, contextVariables, statusReportModule, onVariablesReady);
- function getContextVariables() {
+ function onVariablesReady(err) {
try {
- if (FULL_LOG === true) { logger.write("[INFO] start -> getContextVariables -> Entering function."); }
+ if (FULL_LOG === true) { logger.write("[INFO] start -> onVariablesReady -> Entering function."); }
- let reportFilePath;
- let fileName = "Status.Report." + market.assetA + '_' + market.assetB + ".json"
+ if (err.result === global.CUSTOM_OK_RESPONSE.result) {
- if (FULL_LOG === true) { logger.write("[INFO] start -> getContextVariables -> fileName = " + fileName); }
+ switch (err.message) {
+ case 'Status Report did exist.': {
+ logger.write("[INFO] start -> onVariablesReady -> Status Report did exist.");
- getHistoricTrades();
-
- function getHistoricTrades() {
-
- if (FULL_LOG === true) { logger.write("[INFO] start -> getContextVariables -> getHistoricTrades -> Entering function."); }
-
- /*
-
- We need to know where is the begining of the market, since that will help us know where the Index Files should start.
-
- */
-
- reportFilePath = EXCHANGE_NAME + "/Processes/" + "Poloniex-Historic-Trades";
-
- if (FULL_LOG === true) { logger.write("[INFO] start -> getContextVariables -> getHistoricTrades -> reportFilePath = " + reportFilePath); }
-
- charlyFileStorage.getTextFile(reportFilePath, fileName, onFileReceived);
-
- function onFileReceived(err, text) {
-
- if (FULL_LOG === true) { logger.write("[INFO] start -> getContextVariables -> getHistoricTrades -> onFileReceived -> Entering function."); }
- if (FULL_LOG === true) { logger.write("[INFO] start -> getContextVariables -> getHistoricTrades -> onFileReceived -> text = " + text); }
-
- let thisReport;
-
- if (err.result === global.DEFAULT_OK_RESPONSE.result) {
- try {
- thisReport = JSON.parse(text);
-
- firstTradeFile = new Date(thisReport.lastFile.year + "-" + thisReport.lastFile.month + "-" + thisReport.lastFile.days + " " + thisReport.lastFile.hours + ":" + thisReport.lastFile.minutes + GMT_SECONDS);
-
- getOneMinDailyCandlesVolumes();
-
- } catch (err) {
- logger.write("[ERROR] start -> getContextVariables -> getHistoricTrades -> onFileReceived -> err = " + err.message);
- logger.write("[ERROR] start -> getContextVariables -> getHistoricTrades -> onFileReceived -> Asuming this is a temporary situation. Requesting a Retry.");
- callBackFunction(global.DEFAULT_RETRY_RESPONSE);
- }
- } else {
- logger.write("[ERROR] start -> getContextVariables -> getHistoricTrades -> onFileReceived -> err = " + err.message);
- callBackFunction(err);
+ findPreviousContent();
+ return;
}
+ case 'Status Report did not exist.': {
+ logger.write("[ERROR] start -> onVariablesReady -> Status Report did not exist.");
+
+ buildCandles();
+ return;
+ }
+ default:
+ {
+ logger.write("[ERROR] start -> onVariablesReady -> Operation Failed.");
+ callBackFunction(err);
+ return;
+ }
}
+
+ } else {
+ logger.write("[ERROR] start -> onVariablesReady -> Operation Failed.");
+ callBackFunction(err);
+ return;
}
- function getOneMinDailyCandlesVolumes() {
-
- if (FULL_LOG === true) { logger.write("[INFO] start -> getContextVariables -> getOneMinDailyCandlesVolumes -> Entering function."); }
-
- /* We need to discover the maxCandle file, which is the last file with candles we can use as input. */
-
- let date = new Date();
- let currentYear = date.getUTCFullYear();
- let currentMonth = utilities.pad(date.getUTCMonth() + 1,2);
-
- reportFilePath = EXCHANGE_NAME + "/Processes/" + "One-Min-Daily-Candles-Volumes" + "/" + currentYear + "/" + currentMonth;
-
- if (FULL_LOG === true) { logger.write("[INFO] start -> getContextVariables -> getOneMinDailyCandlesVolumes -> reportFilePath = " + reportFilePath); }
-
- bruceFileStorage.getTextFile(reportFilePath, fileName, onFileReceived);
-
- function onFileReceived(err, text) {
-
- if (FULL_LOG === true) { logger.write("[INFO] start -> getContextVariables -> getOneMinDailyCandlesVolumes -> onFileReceived -> Entering function."); }
- if (FULL_LOG === true) { logger.write("[INFO] start -> getContextVariables -> getOneMinDailyCandlesVolumes -> onFileReceived -> text = " + text); }
-
- let thisReport;
-
- if (err.result === global.DEFAULT_OK_RESPONSE.result) {
- try {
- thisReport = JSON.parse(text);
-
- maxCandleFile = new Date(thisReport.lastFile.year + "-" + thisReport.lastFile.month + "-" + thisReport.lastFile.days + " " + "00:00" + GMT_SECONDS);
-
- getThisProcessReport();
-
- } catch (err) {
- logger.write("[ERROR] start -> getContextVariables -> getOneMinDailyCandlesVolumes -> onFileReceived -> err = " + err.message);
- logger.write("[ERROR] start -> getContextVariables -> getOneMinDailyCandlesVolumes -> onFileReceived -> Asuming this is a temporary situation. Requesting a Retry.");
- callBackFunction(global.DEFAULT_RETRY_RESPONSE);
- }
- } else {
- logger.write("[ERROR] start -> getContextVariables -> getHistoricTrades -> onFileReceived -> err = " + err.message);
- callBackFunction(err);
- }
- }
- }
-
- function getThisProcessReport() {
-
- if (FULL_LOG === true) { logger.write("[INFO] start -> getContextVariables -> getThisProcessReport -> Entering function."); }
-
- statusReportModule = STATUS_REPORT.newStatusReport(BOT, DEBUG_MODULE, FILE_STORAGE, UTILITIES);
- statusReportModule.initialize(bot, onInitilized);
-
- function onInitilized(err) {
-
- try {
-
- switch (err.result) {
- case global.DEFAULT_OK_RESPONSE.result: {
- logger.write("[INFO] start -> getContextVariables -> getThisProcessReport -> onInitilized -> Execution finished well. :-)");
-
- statusReport = statusReportModule.file;
-
- lastCandleFile = new Date(statusReport.lastFile);
-
- /*
- Here we assume that the last day written might contain incomplete information. This actually happens every time the head of the market is reached.
- For that reason we go back one day, the partial information is discarded and added again with whatever new info is available.
- */
-
- lastCandleFile = new Date(lastCandleFile.valueOf() - ONE_DAY_IN_MILISECONDS);
-
- findPreviousContent();
- return;
- }
- case global.CUSTOM_FAIL_RESPONSE.result: { // We need to see if we can handle this.
- logger.write("[ERROR] start -> getContextVariables -> getThisProcessReport -> onInitilized -> err.message = " + err.message);
-
- if (err.message === "Status Report was never created.") {
-
- statusReport = statusReportModule.file;
-
- lastCandleFile = new Date(firstTradeFile.getUTCFullYear() + "-" + (firstTradeFile.getUTCMonth() + 1) + "-" + firstTradeFile.getUTCDate() + " " + "00:00" + GMT_SECONDS);
-
- lastCandleFile = new Date(lastCandleFile.valueOf() - ONE_DAY_IN_MILISECONDS); // Go back one day to start well.
-
- buildCandles();
-
- } else {
- callBackFunction(err); // we cant handle this here.
- }
- return;
- }
- default:
- {
- logger.write("[ERROR] start -> getContextVariables -> getThisProcessReport -> onInitilized -> Operation Failed.");
- callBackFunction(err);
- return;
- }
- }
- }
- catch (err) {
- logger.write("[ERROR] start -> getContextVariables -> getThisProcessReport -> onInitilized -> err = " + err.message);
- callBackFunction(global.DEFAULT_FAIL_RESPONSE);
- }
- }
- }
- }
- catch (err) {
- logger.write("[ERROR] start -> getContextVariables -> err = " + err.message);
- callBackFunction(global.DEFAULT_FAIL_RESPONSE);
+ } catch (err) {
+ logger.write("[ERROR] start -> onVariablesReady -> err = " + err.message);
+ callBack(global.DEFAULT_FAIL_RESPONSE);
}
}
@@ -471,15 +296,15 @@ Read the candles and volumes from Bruce and produce a single Index File for Mark
if (FULL_LOG === true) { logger.write("[INFO] start -> buildCandles -> advanceTime -> Entering function."); }
- lastCandleFile = new Date(lastCandleFile.valueOf() + ONE_DAY_IN_MILISECONDS);
+ contextVariables.lastCandleFile = new Date(contextVariables.lastCandleFile.valueOf() + ONE_DAY_IN_MILISECONDS);
- if (FULL_LOG === true) { logger.write("[INFO] start -> buildCandles -> advanceTime -> New processing time @ " + lastCandleFile.getUTCFullYear() + "/" + (lastCandleFile.getUTCMonth() + 1) + "/" + lastCandleFile.getUTCDate() + "."); }
+ if (FULL_LOG === true) { logger.write("[INFO] start -> buildCandles -> advanceTime -> New processing time @ " + contextVariables.lastCandleFile.getUTCFullYear() + "/" + (contextVariables.lastCandleFile.getUTCMonth() + 1) + "/" + contextVariables.lastCandleFile.getUTCDate() + "."); }
/* Validation that we are not going past the head of the market. */
- if (lastCandleFile.valueOf() > maxCandleFile.valueOf()) {
+ if (contextVariables.lastCandleFile.valueOf() > contextVariables.maxCandleFile.valueOf()) {
- if (FULL_LOG === true) { logger.write("[INFO] start -> buildCandles -> advanceTime -> Head of the market found @ " + lastCandleFile.getUTCFullYear() + "/" + (lastCandleFile.getUTCMonth() + 1) + "/" + lastCandleFile.getUTCDate() + "."); }
+ if (FULL_LOG === true) { logger.write("[INFO] start -> buildCandles -> advanceTime -> Head of the market found @ " + contextVariables.lastCandleFile.getUTCFullYear() + "/" + (contextVariables.lastCandleFile.getUTCMonth() + 1) + "/" + contextVariables.lastCandleFile.getUTCDate() + "."); }
callBackFunction(global.DEFAULT_OK_RESPONSE); // Here is where we finish processing and wait for the platform to run this module again.
return;
@@ -535,7 +360,7 @@ Read the candles and volumes from Bruce and produce a single Index File for Mark
end: previousCandles[i][5]
};
- if (candle.end < lastCandleFile.valueOf()) {
+ if (candle.end < contextVariables.lastCandleFile.valueOf()) {
outputCandles[n].push(candle);
@@ -557,7 +382,7 @@ Read the candles and volumes from Bruce and produce a single Index File for Mark
sell: previousVolumes[i][1]
};
- if (volume.end < lastCandleFile.valueOf()) {
+ if (volume.end < contextVariables.lastCandleFile.valueOf()) {
outputVolumes[n].push(volume);
@@ -574,7 +399,7 @@ Read the candles and volumes from Bruce and produce a single Index File for Mark
if (FULL_LOG === true) { logger.write("[INFO] start -> buildCandles -> periodsLoop -> loopBody -> nextCandleFile -> Entering function."); }
- let dateForPath = lastCandleFile.getUTCFullYear() + '/' + utilities.pad(lastCandleFile.getUTCMonth() + 1, 2) + '/' + utilities.pad(lastCandleFile.getUTCDate(), 2);
+ let dateForPath = contextVariables.lastCandleFile.getUTCFullYear() + '/' + utilities.pad(contextVariables.lastCandleFile.getUTCMonth() + 1, 2) + '/' + utilities.pad(contextVariables.lastCandleFile.getUTCDate(), 2);
let fileName = market.assetA + '_' + market.assetB + ".json"
let filePath = EXCHANGE_NAME + "/Output/" + CANDLES_FOLDER_NAME + '/' + CANDLES_ONE_MIN + '/' + dateForPath;
@@ -610,7 +435,7 @@ Read the candles and volumes from Bruce and produce a single Index File for Mark
const inputFilePeriod = 24 * 60 * 60 * 1000; // 24 hs
let totalOutputCandles = inputFilePeriod / outputPeriod; // this should be 2 in this case.
- let beginingOutputTime = lastCandleFile.valueOf();
+ let beginingOutputTime = contextVariables.lastCandleFile.valueOf();
for (let i = 0; i < totalOutputCandles; i++) {
@@ -690,7 +515,7 @@ Read the candles and volumes from Bruce and produce a single Index File for Mark
if (FULL_LOG === true) { logger.write("[INFO] start -> buildCandles -> periodsLoop -> loopBody -> nextVolumeFile -> Entering function."); }
- let dateForPath = lastCandleFile.getUTCFullYear() + '/' + utilities.pad(lastCandleFile.getUTCMonth() + 1, 2) + '/' + utilities.pad(lastCandleFile.getUTCDate(), 2);
+ let dateForPath = contextVariables.lastCandleFile.getUTCFullYear() + '/' + utilities.pad(contextVariables.lastCandleFile.getUTCMonth() + 1, 2) + '/' + utilities.pad(contextVariables.lastCandleFile.getUTCDate(), 2);
let fileName = market.assetA + '_' + market.assetB + ".json"
let filePath = EXCHANGE_NAME + "/Output/" + VOLUMES_FOLDER_NAME + '/' + VOLUMES_ONE_MIN + '/' + dateForPath;
@@ -724,7 +549,7 @@ Read the candles and volumes from Bruce and produce a single Index File for Mark
const inputFilePeriod = 24 * 60 * 60 * 1000; // 24 hs
let totalOutputVolumes = inputFilePeriod / outputPeriod; // this should be 2 in this case.
- let beginingOutputTime = lastCandleFile.valueOf();
+ let beginingOutputTime = contextVariables.lastCandleFile.valueOf();
for (let i = 0; i < totalOutputVolumes; i++) {
@@ -788,7 +613,7 @@ Read the candles and volumes from Bruce and produce a single Index File for Mark
} else {
- writeStatusReport(lastCandleFile, advanceTime);
+ writeStatusReport(contextVariables.lastCandleFile, advanceTime);
}
}
@@ -954,8 +779,8 @@ Read the candles and volumes from Bruce and produce a single Index File for Mark
try {
- statusReport.lastExecution = global.processDatetime;
- statusReport.lastFile = lastFileDate;
+ statusReportModule.file.lastExecution = global.processDatetime;
+ statusReportModule.file.lastFile = lastFileDate;
statusReportModule.save(callBack);
}
diff --git a/Project.njsproj b/Project.njsproj
index 88157af1a..9651242ae 100644
--- a/Project.njsproj
+++ b/Project.njsproj
@@ -21,7 +21,10 @@
-
+
+ Code
+
+
diff --git a/this.bot.config.json b/this.bot.config.json
index 91ee9168e..ac5dc1c9f 100644
--- a/this.bot.config.json
+++ b/this.bot.config.json
@@ -28,8 +28,8 @@
"run": "true"
}
},
- "intervalLapse": 3600000,
- "intervalMaxLoops": -1
+ "executionWaitTime": 3600000,
+ "retryWaitTime": 10000
},
{
"name": "Multi-Period-Daily",
@@ -49,8 +49,8 @@
"run": "true"
}
},
- "intervalLapse": 60000,
- "intervalMaxLoops": -1
+ "executionWaitTime": 60000,
+ "retryWaitTime": 10000
}
],
"products": [