diff --git a/.vs/AACloud/v15/.suo b/.vs/AACloud/v15/.suo
index e9ba96e1d..3b5b7b810 100644
Binary files a/.vs/AACloud/v15/.suo and b/.vs/AACloud/v15/.suo differ
diff --git a/Debug Log.js b/Debug Log.js
index 827f6b47b..1f34c0a2e 100644
--- a/Debug Log.js
+++ b/Debug Log.js
@@ -11,6 +11,7 @@
let messageId = 0;
let firstCall = true;
let folderPath;
+ let loopCounter;
let thisObject = {
bot: undefined,
@@ -50,16 +51,30 @@
catch (err) {
console.log("Error trying to create the folders needed. Error: " + err.message);
}
+ }
+ function createLoopFolder() {
+ try {
+
+ folderPath = '../Logs/' + thisObject.bot.devTeam + "/" + thisObject.bot.type + "/" + thisObject.bot.codeName + "." + thisObject.bot.version.major + "." + thisObject.bot.version.minor + "/" + thisObject.bot.process + "/Loop." + loopCounter;
+
+ createFolderSync(folderPath);
+
+ }
+ catch (err) {
+ console.log("Error trying to create the loop folder needed. Error: " + err.message);
+ }
}
function write(Message) {
- if (firstCall === true) {
+ if (firstCall === true) { createFolders();}
- createFolders();
+ if (global.loopCointer !== loopCounter) {
+ loopCounter = global.loopCointer;
+ createLoopFolder();
}
let filePath = getCurrentLogFile(folderPath + "/" + dateString + "---" + randomId + "---", this.fileName);
diff --git a/Dependencies.js b/Dependencies.js
new file mode 100644
index 000000000..ae562375e
--- /dev/null
+++ b/Dependencies.js
@@ -0,0 +1,140 @@
+exports.newDependencies = function newDependencies(BOT, DEBUG_MODULE, STATUS_REPORT, FILE_STORAGE, UTILITIES) {
+
+ const FULL_LOG = true;
+ const LOG_FILE_CONTENT = false;
+
+ const MODULE_NAME = "Dependencies";
+
+ let thisObject = {
+ statusReports: new Map(),
+ initialize: initialize
+ };
+
+ /*
+
+ During the process we will create a new History Record. This will go to the Context History file which essentially mantains an
+ index of all the bots executions. This file will later be plotted by the bot s plotter on the timeline, allowing end users to
+ know where there is information related to the actions taken by the bot.
+
+ */
+
+ let bot = BOT;
+ let ownerBot; // This is the bot owner of the Status Report. Only owners can save the report and override the existing content.
+
+ const logger = DEBUG_MODULE.newDebugLog();
+ logger.fileName = MODULE_NAME;
+ logger.bot = bot;
+
+ return thisObject;
+
+ function initialize(pDependenciesConfig, callBackFunction) {
+
+ try {
+
+ if (FULL_LOG === true) { logger.write("[INFO] initialize -> Entering function."); }
+
+ /*
+
+ For each dependency declared at the bot config, we will initialize the status report, and load it as part of this initialization process.
+
+ */
+ let alreadyCalledBack = false;
+ let loadCount = 0;
+
+ for (let i = 0; i < pDependenciesConfig.length; i++) {
+
+ let statusReportModule = STATUS_REPORT.newStatusReport(BOT, DEBUG_MODULE, FILE_STORAGE, UTILITIES);
+
+ statusReportModule.initialize(pDependenciesConfig[i], onInitilized);
+
+ function onInitilized(err) {
+
+ if (err.result !== global.DEFAULT_OK_RESPONSE.result) {
+ logger.write("[ERROR] initialize -> onInitilized -> err = " + err.message);
+
+ if (alreadyCalledBack === false) {
+ callBackFunction(err);
+ } else {
+ alreadyCalledBack = true;
+ }
+ return;
+ }
+
+ statusReportModule.load(onLoad);
+ }
+
+ function onLoad(err) {
+
+ try {
+
+ switch (err.result) {
+ case global.DEFAULT_OK_RESPONSE.result: {
+ logger.write("[INFO] initialize -> onLoad -> Execution finished well. :-)");
+
+ addReport();
+ return;
+ }
+ case global.CUSTOM_OK_RESPONSE.result: { // We need to see if we can handle this.
+ logger.write("[ERROR] initialize -> onLoad -> err.message = " + err.message);
+
+ if (err.message === "Status Report was never created.") {
+
+ logger.write("[ERROR] initialize -> onLoad -> err.message = " + err.message);
+ logger.write("[ERROR] initialize -> onLoad -> pDependenciesConfig[i] = " + JSON.stringify(pDependenciesConfig[i]));
+ addReport();
+ return;
+ } else {
+
+ logger.write("[WARN] initialize -> onLoad -> Response not understood.");
+
+ if (alreadyCalledBack === false) {
+ callBackFunction(err);
+ } else {
+ alreadyCalledBack = true;
+ }
+ return;
+ }
+
+ }
+ default:
+ {
+ logger.write("[ERROR] initialize -> onLoad -> Operation Failed.");
+
+ if (alreadyCalledBack === false) {
+ callBackFunction(err);
+ } else {
+ alreadyCalledBack = true;
+ }
+ return;
+ }
+ }
+ }
+ catch (err) {
+ logger.write("[ERROR] initialize -> onLoad -> err = " + err.message);
+ callBackFunction(global.DEFAULT_FAIL_RESPONSE);
+ }
+ }
+
+ function addReport() {
+
+ loadCount++;
+
+ let key = pDependenciesConfig[i].devTeam + "-" + pDependenciesConfig[i].bot + "-" + pDependenciesConfig[i].process + "-" + pDependenciesConfig[i].dataSetVersion;
+
+ thisObject.statusReports.set(key, statusReportModule);
+
+ if (loadCount === pDependenciesConfig.length) {
+ if (alreadyCalledBack === false) {
+ callBackFunction(global.DEFAULT_OK_RESPONSE);
+ }
+ }
+ }
+ }
+
+ } catch (err) {
+ logger.write("[ERROR] initialize -> err = " + err.message);
+ callBackFunction(global.DEFAULT_FAIL_RESPONSE);
+ }
+ }
+
+};
\ No newline at end of file
diff --git a/Extraction Bot Main Loop.js b/Extraction Bot Main Loop.js
index 6c11cfa21..a449645d9 100644
--- a/Extraction Bot Main Loop.js
+++ b/Extraction Bot Main Loop.js
@@ -55,6 +55,8 @@
function loop() {
try {
+ global.loopCointer++;
+
if (FULL_LOG === true) { logger.write("[INFO] run -> loop -> Entering function."); }
/* We define here all the modules that the rest of the infraestructure, including the bots themselves can consume. */
@@ -64,6 +66,7 @@
const DEBUG_MODULE = require(ROOT_DIR + 'Debug Log');
const STATUS_REPORT = require(ROOT_DIR + 'Status Report');
const POLONIEX_CLIENT_MODULE = require(ROOT_DIR + 'Poloniex API Client');
+ const DEPENDENCIES = require(ROOT_DIR + 'Dependencies');
/* We define the datetime for the process that we are running now. This will be the official processing time for both the infraestructure and the bot. */
@@ -71,11 +74,43 @@
/* We will prepare first the infraestructure needed for the bot to run. There are 3 modules we need to sucessfullly initialize first. */
+ let dependencies;
let userBot;
let nextWaitTime;
- initializeUserBot();
+ initializeDependencies();
+
+ function initializeDependencies() {
+
+ if (FULL_LOG === true) { logger.write("[INFO] run -> loop -> initializeDependencies -> Entering function."); }
+
+ dependencies = DEPENDENCIES.newDependencies(bot, DEBUG_MODULE, STATUS_REPORT, FILE_STORAGE, UTILITIES);
+
+ dependencies.initialize(processConfig.dependencies, onInizialized);
+
+ function onInizialized(err) {
+
+ switch (err.result) {
+ case global.DEFAULT_OK_RESPONSE.result: {
+ logger.write("[INFO] run -> loop -> initializeDependencies -> onInizialized > Execution finished well. :-)");
+ initializeUserBot();
+ return;
+ }
+ case global.DEFAULT_RETRY_RESPONSE.result: { // Something bad happened, but if we retry in a while it might go through the next time.
+ logger.write("[ERROR] run -> loop -> initializeDependencies -> onInizialized > Retry Later. Requesting Execution Retry.");
+ nextWaitTime = 'Retry';
+ loopControl(nextWaitTime);
+ return;
+ }
+ case global.DEFAULT_FAIL_RESPONSE.result: { // This is an unexpected exception that we do not know how to handle.
+ logger.write("[ERROR] run -> loop -> initializeDependencies -> onInizialized > Operation Failed. Aborting the process.");
+ callBackFunction(err);
+ return;
+ }
+ }
+ }
+ }
function initializeUserBot() {
@@ -83,7 +118,7 @@
usertBot = USER_BOT_MODULE.newUserBot(bot, COMMONS_MODULE, UTILITIES, DEBUG_MODULE, FILE_STORAGE, STATUS_REPORT, POLONIEX_CLIENT_MODULE);
- usertBot.initialize(undefined, undefined, onInizialized);
+ usertBot.initialize(dependencies, onInizialized, undefined, undefined);
function onInizialized(err) {
@@ -93,20 +128,17 @@
startUserBot();
return;
}
- break;
case global.DEFAULT_RETRY_RESPONSE.result: { // Something bad happened, but if we retry in a while it might go through the next time.
logger.write("[ERROR] run -> loop -> initializeUserBot -> onInizialized > Retry Later. Requesting Execution Retry.");
nextWaitTime = 'Retry';
loopControl(nextWaitTime);
return;
}
- break;
case global.DEFAULT_FAIL_RESPONSE.result: { // This is an unexpected exception that we do not know how to handle.
logger.write("[ERROR] run -> loop -> initializeUserBot -> onInizialized > Operation Failed. Aborting the process.");
callBackFunction(err);
return;
}
- break;
}
}
}
diff --git a/File Storage.js b/File Storage.js
index a081f6f40..d35b1ee67 100644
--- a/File Storage.js
+++ b/File Storage.js
@@ -77,7 +77,7 @@ exports.newFileStorage = function newFileStorage(BOT) {
try {
let fs = require('fs');
- filePath = '../' + 'Connection-Strings' + '/' + global.RUNNING_MODE + '/' + dataOwner + '.azure.storage.connstring';
+ filePath = '../' + 'Connection-Strings' + '/' + global.STORAGE_CONN_STRING_FOLDER + '/' + dataOwner + '.azure.storage.connstring';
let connObj = JSON.parse(fs.readFileSync(filePath, 'utf8'));
callBack(global.DEFAULT_OK_RESPONSE, connObj);
diff --git a/Indicator Bot Main Loop.js b/Indicator Bot Main Loop.js
index a0c4ba208..282d4bdf0 100644
--- a/Indicator Bot Main Loop.js
+++ b/Indicator Bot Main Loop.js
@@ -55,6 +55,8 @@
function loop() {
try {
+ global.loopCointer++;
+
if (FULL_LOG === true) { logger.write("[INFO] run -> loop -> Entering function."); }
/* We define here all the modules that the rest of the infraestructure, including the bots themselves can consume. */
@@ -63,6 +65,7 @@
const FILE_STORAGE = require(ROOT_DIR + 'File Storage');
const DEBUG_MODULE = require(ROOT_DIR + 'Debug Log');
const STATUS_REPORT = require(ROOT_DIR + 'Status Report');
+ const DEPENDENCIES = require(ROOT_DIR + 'Dependencies');
/* We define the datetime for the process that we are running now. This will be the official processing time for both the infraestructure and the bot. */
@@ -74,15 +77,46 @@
let nextWaitTime;
- initializeUserBot();
+ initializeDependencies();
+
+ function initializeDependencies() {
+
+ if (FULL_LOG === true) { logger.write("[INFO] run -> loop -> initializeDependencies -> Entering function."); }
+
+ dependencies = DEPENDENCIES.newDependencies(bot, DEBUG_MODULE, STATUS_REPORT, FILE_STORAGE, UTILITIES);
+
+ dependencies.initialize(processConfig.dependencies, onInizialized);
+
+ function onInizialized(err) {
+
+ switch (err.result) {
+ case global.DEFAULT_OK_RESPONSE.result: {
+ logger.write("[INFO] run -> loop -> initializeDependencies -> onInizialized > Execution finished well. :-)");
+ initializeUserBot();
+ return;
+ }
+ case global.DEFAULT_RETRY_RESPONSE.result: { // Something bad happened, but if we retry in a while it might go through the next time.
+ logger.write("[ERROR] run -> loop -> initializeDependencies -> onInizialized > Retry Later. Requesting Execution Retry.");
+ nextWaitTime = 'Retry';
+ loopControl(nextWaitTime);
+ return;
+ }
+ case global.DEFAULT_FAIL_RESPONSE.result: { // This is an unexpected exception that we do not know how to handle.
+ logger.write("[ERROR] run -> loop -> initializeDependencies -> onInizialized > Operation Failed. Aborting the process.");
+ callBackFunction(err);
+ return;
+ }
+ }
+ }
+ }
function initializeUserBot() {
if (FULL_LOG === true) { logger.write("[INFO] run -> loop -> initializeUserBot -> Entering function."); }
- usertBot = USER_BOT_MODULE.newUserBot(bot, COMMONS_MODULE, UTILITIES, DEBUG_MODULE, FILE_STORAGE, STATUS_REPORT);
+ usertBot = USER_BOT_MODULE.newUserBot(bot, COMMONS_MODULE, UTILITIES, DEBUG_MODULE, FILE_STORAGE);
- usertBot.initialize(undefined, undefined, onInizialized);
+ usertBot.initialize(dependencies, onInizialized, undefined, undefined);
function onInizialized(err) {
@@ -92,20 +126,17 @@
startUserBot();
return;
}
- break;
case global.DEFAULT_RETRY_RESPONSE.result: { // Something bad happened, but if we retry in a while it might go through the next time.
logger.write("[ERROR] run -> loop -> initializeUserBot -> onInizialized > Retry Later. Requesting Execution Retry.");
nextWaitTime = 'Retry';
loopControl(nextWaitTime);
return;
}
- break;
case global.DEFAULT_FAIL_RESPONSE.result: { // This is an unexpected exception that we do not know how to handle.
logger.write("[ERROR] run -> loop -> initializeUserBot -> onInizialized > Operation Failed. Aborting the process.");
callBackFunction(err);
return;
}
- break;
}
}
}
@@ -125,20 +156,17 @@
loopControl(nextWaitTime);
return;
}
- break;
case global.DEFAULT_RETRY_RESPONSE.result: { // Something bad happened, but if we retry in a while it might go through the next time.
logger.write("[ERROR] run -> loop -> startUserBot -> onFinished > Retry Later. Requesting Execution Retry.");
nextWaitTime = 'Retry';
loopControl(nextWaitTime);
return;
}
- break;
case global.DEFAULT_FAIL_RESPONSE.result: { // This is an unexpected exception that we do not know how to handle.
logger.write("[ERROR] run -> loop -> startUserBot -> onFinished > Operation Failed. Aborting the process.");
callBackFunction(err);
return;
}
- break;
}
}
}
diff --git a/Project.njsproj b/Project.njsproj
index 1e4cc3cba..566e4c4e7 100644
--- a/Project.njsproj
+++ b/Project.njsproj
@@ -13,7 +13,7 @@
14.0
$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)
Project
- Poloniex-Live-Trades
+ Multi-Period-Market
C:\Program Files\nodejs\node.exe
False
@@ -23,6 +23,9 @@
Code
+
+ Code
+
Code
diff --git a/Run.js b/Run.js
index 616bd6b7b..210c0fb0d 100644
--- a/Run.js
+++ b/Run.js
@@ -1,14 +1,6 @@
const FULL_LOG = true;
-/* The following global variable tells the system if it is running on test mode or production. */
-
-global.RUNNING_MODE = 'Testnet'; // 'Testnet', 'Mixed' or 'Production'
-
-/* You do not have funds at the exchange and still want run your bot? No problem activate the exchange simulation mode: */
-
-global.EXCHANGE_SIMULATION_MODE = false;
-
/* First thing to do is to read the config and guess which bot we will be running. */
var fs = require('fs');
@@ -25,6 +17,14 @@ catch (err) {
return;
}
+/* You do not have funds at the exchange and still want run your bot? No problem activate the exchange simulation mode: */
+
+global.EXCHANGE_SIMULATION_MODE = JSON.parse(global.PLATFORM_CONFIG.exchangeSimulationMode);
+
+/* The following global variable tells the system if it is running on test mode or production. */
+
+global.STORAGE_CONN_STRING_FOLDER = global.PLATFORM_CONFIG.storageConnStringFolder; // 'Testnet', 'Mixed' or 'Production', or whatever folder name the conn strings files are into.
+
/* Now we will read the config of the bot from the path we obtained on the VM config. */
let botConfig;
@@ -144,6 +144,10 @@ global.dailyFilePeriods = JSON.parse(global.dailyFilePeriods);
global.FILE_PATH_ROOT = botConfig.devTeam + "/" + botConfig.codeName + "." + botConfig.version.major + "." + botConfig.version.minor + "/" + global.PLATFORM_CONFIG.codeName + "." + global.PLATFORM_CONFIG.version.major + "." + global.PLATFORM_CONFIG.version.minor + "/" + global.EXCHANGE_NAME + "/" + botConfig.dataSetVersion;
+/* Loop Counter */
+
+global.loopCointer = 0;
+
/* Some LAGACY code starts here. Pending for clean up. */
const INTERVAL_EXECUTOR_MODULE = require('./Interval Executor');
diff --git a/Status Report.js b/Status Report.js
index a813d2dc1..7868fe353 100644
--- a/Status Report.js
+++ b/Status Report.js
@@ -20,16 +20,8 @@
save: save
};
- /*
-
- During the process we will create a new History Record. This will go to the Context History file which essentially mantains an
- index of all the bots executions. This file will later be plotted by the bot s plotter on the timeline, allowing end users to
- know where there is information related to the actions taken by the bot.
-
- */
-
let bot = BOT;
- let ownerBot; // This is the bot owner of the Status Report. Only owners can save the report and override the existing content.
+ let owner; // This is the bot owner of the Status Report. Only owners can save the report and override the existing content.
const logger = DEBUG_MODULE.newDebugLog();
logger.fileName = MODULE_NAME;
@@ -45,26 +37,21 @@
return thisObject;
- function initialize(pOwnerBot, callBackFunction) {
+ function initialize(pOwner, callBackFunction) {
try {
+ logger.fileName = MODULE_NAME + "." + pOwner.bot;
+
if (FULL_LOG === true) { logger.write("[INFO] initialize -> Entering function."); }
- /*
-
- Here we get the positions the bot did and that are recorded at the bot storage account. We will use them through out the rest
- of the process.
-
- */
-
- ownerBot = pOwnerBot;
+ owner = pOwner;
initializeStorage();
function initializeStorage() {
- cloudStorage.initialize(bot.codeName, onInizialized);
+ cloudStorage.initialize(owner.bot, onInizialized);
function onInizialized(err) {
@@ -91,8 +78,9 @@
if (FULL_LOG === true) { logger.write("[INFO] initialize -> load -> Entering function."); }
+ let rootPath = owner.devTeam + "/" + owner.bot + "." + owner.botVersion.major + "." + owner.botVersion.minor + "/" + global.PLATFORM_CONFIG.codeName + "." + global.PLATFORM_CONFIG.version.major + "." + global.PLATFORM_CONFIG.version.minor + "/" + global.EXCHANGE_NAME + "/" + owner.dataSetVersion;
let fileName = "Status.Report.json"
- let filePath = global.FILE_PATH_ROOT + "/Reports/" + bot.process;
+ let filePath = rootPath + "/Reports/" + owner.process;
if (FULL_LOG === true) { logger.write("[INFO] initialize -> load -> fileName = " + fileName); }
if (FULL_LOG === true) { logger.write("[INFO] initialize -> load -> filePath = " + filePath); }
@@ -156,8 +144,8 @@
if (FULL_LOG === true) { logger.write("[INFO] save -> Entering function."); }
- let ownerId = ownerBot.devTeam + "-" + ownerBot.codeName;
- let botId = bot.devTeam + "-" + bot.codeName;
+ let ownerId = owner.devTeam + "-" + owner.bot + "-" + owner.botVersion.major + "-" + owner.botVersion.minor + "-" + owner.process + "-" + owner.dataSetVersion;
+ let botId = bot.devTeam + "-" + bot.codeName + "-" + bot.version.major + "-" + bot.version.minor + "-" + bot.process + "-" + bot.dataSetVersion;
if (ownerId !== botId) {
@@ -165,13 +153,13 @@
result: global.CUSTOM_FAIL_RESPONSE.result,
message: "Only bots owners of a Status Report can save them."
}
- logger.write("[ERROR] save -> customErr = " + err.message);
+ logger.write("[ERROR] save -> customErr = " + customErr.message);
callBackFunction(customErr);
return;
}
let fileName = "Status.Report.json"
- let filePath = global.FILE_PATH_ROOT + "/Reports/" + bot.process;
+ let filePath = global.FILE_PATH_ROOT + "/Reports/" + owner.process;
if (FULL_LOG === true) { logger.write("[INFO] save -> fileName = " + fileName); }
if (FULL_LOG === true) { logger.write("[INFO] save -> filePath = " + filePath); }
diff --git a/Trading Bot Main Loop.js b/Trading Bot Main Loop.js
index 92fa0f0e3..f737bc032 100644
--- a/Trading Bot Main Loop.js
+++ b/Trading Bot Main Loop.js
@@ -55,6 +55,8 @@
function loop() {
try {
+ global.loopCointer++;
+
if (FULL_LOG === true) { logger.write("[INFO] run -> loop -> Entering function."); }
/* We define here all the modules that the rest of the infraestructure, including the bots themselves can consume. */
diff --git a/this.config.json b/this.config.json
index 5d0bc2469..2c07461f0 100644
--- a/this.config.json
+++ b/this.config.json
@@ -6,7 +6,9 @@
"patch": 0
},
"bot": {
- "path": "../Bots/AAMasters/AACharly-Extraction-Bot"
+ "path": "../Bots/AAMasters/AAOlivia-Indicator-Bot"
},
- "stopGracefully": "false"
+ "stopGracefully": "false",
+ "exchangeSimulationMode": "false",
+ "storageConnStringFolder": "Mixed"
}
\ No newline at end of file