diff --git a/.vs/AACloud/v15/.suo b/.vs/AACloud/v15/.suo
index 7b1ba2e91..e9ba96e1d 100644
Binary files a/.vs/AACloud/v15/.suo and b/.vs/AACloud/v15/.suo differ
diff --git a/Extraction Bot Main Loop.js b/Extraction Bot Main Loop.js
new file mode 100644
index 000000000..6c11cfa21
--- /dev/null
+++ b/Extraction Bot Main Loop.js
@@ -0,0 +1,205 @@
+exports.newExtractionBotMainLoop = function newExtractionBotMainLoop(BOT) {
+
+ let bot = BOT;
+ const ROOT_DIR = './';
+
+ const MODULE_NAME = "Extraction Bot Main Loop";
+ const FULL_LOG = true;
+
+ let USER_BOT_MODULE;
+ let COMMONS_MODULE;
+
+ const DEBUG_MODULE = require(ROOT_DIR + 'Debug Log');
+ const logger = DEBUG_MODULE.newDebugLog();
+ logger.fileName = MODULE_NAME;
+ logger.bot = bot;
+
+ let thisObject = {
+ initialize: initialize,
+ run: run
+ };
+
+ let processConfig;
+
+ return thisObject;
+
+ function initialize(pBotPath, pProcessConfig, callBackFunction) {
+
+ try {
+ if (FULL_LOG === true) { logger.write("[INFO] initialize -> Entering function."); }
+ processConfig = pProcessConfig;
+
+ USER_BOT_MODULE = require(pBotPath + "/" + pProcessConfig.name + "/" + 'User.Bot');
+
+ try {
+ COMMONS_MODULE = require(pBotPath + "/" + 'Commons');
+ } catch (err) {
+ // Nothing happens since COMMONS modules are optional.
+ }
+
+ callBackFunction(global.DEFAULT_OK_RESPONSE);
+
+ } catch (err) {
+ logger.write("[ERROR] initialize -> err = " + err.message);
+ callBackFunction(global.DEFAULT_FAIL_RESPONSE);
+ }
+ }
+
+ function run(callBackFunction) {
+
+ try {
+ if (FULL_LOG === true) { logger.write("[INFO] run -> Entering function."); }
+
+ loop();
+
+ function loop() {
+
+ try {
+ 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. */
+
+ const UTILITIES = require(ROOT_DIR + 'Utilities');
+ 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 POLONIEX_CLIENT_MODULE = require(ROOT_DIR + 'Poloniex API Client');
+
+ /* 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. */
+
+ global.processDatetime = new Date(); // This will be considered the process date and time, so as to have it consistenly all over the execution.
+
+ /* We will prepare first the infraestructure needed for the bot to run. There are 3 modules we need to sucessfullly initialize first. */
+
+ let userBot;
+
+ let nextWaitTime;
+
+ initializeUserBot();
+
+ 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, POLONIEX_CLIENT_MODULE);
+
+ usertBot.initialize(undefined, undefined, onInizialized);
+
+ function onInizialized(err) {
+
+ switch (err.result) {
+ case global.DEFAULT_OK_RESPONSE.result: {
+ logger.write("[INFO] run -> loop -> initializeUserBot -> onInizialized > Execution finished well. :-)");
+ 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;
+ }
+ }
+ }
+
+ function startUserBot() {
+
+ if (FULL_LOG === true) { logger.write("[INFO] run -> loop -> startUserBot -> Entering function."); }
+
+ usertBot.start(onFinished);
+
+ function onFinished(err) {
+
+ switch (err.result) {
+ case global.DEFAULT_OK_RESPONSE.result: {
+ logger.write("[INFO] run -> loop -> startUserBot -> onFinished > Execution finished well. :-)");
+ nextWaitTime = 'Normal';
+ 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;
+ }
+ }
+ }
+
+ } catch (err) {
+ logger.write("[ERROR] run -> loop -> err = " + err.message);
+ callBackFunction(err);
+ }
+ }
+
+ function loopControl(nextWaitTime) {
+
+ if (FULL_LOG === true) { logger.write("[INFO] run -> loopControl -> nextWaitTime = " + nextWaitTime); }
+
+ /* Here we check if we must stop the loop gracefully. */
+
+ if (shallWeStop() === true) {
+
+ if (FULL_LOG === true) { logger.write("[INFO] run -> loopControl -> Stopping the Loop Gracefully. See you next time! :-)"); }
+ callBackFunction(global.DEFAULT_OK_RESPONSE);
+ return;
+
+ }
+
+ /* Extraction bots are going to be executed after a configured period of time after the last execution ended. This is to avoid overlapping executions. */
+
+ switch (nextWaitTime) {
+ case 'Normal': {
+ if (FULL_LOG === true) { logger.write("[INFO] run -> loopControl -> Restarting Loop in " + (processConfig.executionWaitTime / 1000) + " seconds."); }
+ setTimeout(loop, processConfig.executionWaitTime);
+ }
+ break;
+ case 'Retry': {
+ if (FULL_LOG === true) { logger.write("[INFO] run -> loopControl -> Restarting Loop in " + (processConfig.retryWaitTime / 1000) + " seconds."); }
+ setTimeout(loop, processConfig.retryWaitTime);
+ }
+ break;
+ }
+ }
+
+ function shallWeStop() {
+
+ var fs = require('fs');
+
+ try {
+
+ global.PLATFORM_CONFIG = JSON.parse(fs.readFileSync('this.config.json', 'utf8'));
+ return JSON.parse(global.PLATFORM_CONFIG.stopGracefully);
+ }
+ catch (err) {
+ const logText = "[ERROR] 'readConfig' - ERROR : " + err.message;
+ console.log(logText);
+
+ return;
+ }
+ }
+ }
+
+ catch (err) {
+ logger.write("[ERROR] run -> err = " + err.message);
+ }
+ }
+};
diff --git a/Project.njsproj b/Project.njsproj
index 6af1a8042..1e4cc3cba 100644
--- a/Project.njsproj
+++ b/Project.njsproj
@@ -13,7 +13,7 @@
14.0
$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)
Project
- Trading-Process
+ Poloniex-Live-Trades
C:\Program Files\nodejs\node.exe
False
@@ -23,6 +23,9 @@
Code
+
+ Code
+
diff --git a/Run.js b/Run.js
index c5238708c..616bd6b7b 100644
--- a/Run.js
+++ b/Run.js
@@ -3,7 +3,7 @@ const FULL_LOG = true;
/* The following global variable tells the system if it is running on test mode or production. */
-global.RUNNING_MODE = 'Production'; // 'Testnet', 'Mixed' 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: */
@@ -149,6 +149,7 @@ global.FILE_PATH_ROOT = botConfig.devTeam + "/" + botConfig.codeName + "." + bot
const INTERVAL_EXECUTOR_MODULE = require('./Interval Executor');
const TRADING_BOT_MAIN_LOOP_MODULE = require('./Trading Bot Main Loop');
const INDICATOR_BOT_MAIN_LOOP_MODULE = require('./Indicator Bot Main Loop');
+const EXTRACTION_BOT_MAIN_LOOP_MODULE = require('./Extraction Bot Main Loop');
/* Now we will see which are the script Arguments. We expect the name of the process to run, since that is what it should be defined at the Task Scheduller. */
@@ -214,14 +215,18 @@ for (let i = 0; i < botConfig.processes.length; i++) {
function startProcess() {
switch (bot.type) {
- case 'Trading': {
- runTradingBot(processConfig);
+ case 'Extraction': {
+ runExtractionBot(processConfig);
return;
}
case 'Indicator': {
runIndicatorBot(processConfig);
return;
}
+ case 'Trading': {
+ runTradingBot(processConfig);
+ return;
+ }
}
}
}
@@ -233,7 +238,45 @@ for (let i = 0; i < botConfig.processes.length; i++) {
}
}
+function runExtractionBot(pProcessConfig) {
+ try {
+ if (FULL_LOG === true) { logger.write("[INFO] runExtractionBot -> Entering function."); }
+
+ let extractionBotMainLoop = EXTRACTION_BOT_MAIN_LOOP_MODULE.newExtractionBotMainLoop(botConfig);
+ extractionBotMainLoop.initialize(global.PLATFORM_CONFIG.bot.path, pProcessConfig, onInitializeReady);
+
+ function onInitializeReady(err) {
+
+ if (err.result === global.DEFAULT_OK_RESPONSE.result) {
+
+ extractionBotMainLoop.run(whenRunFinishes);
+
+ function whenRunFinishes(err) {
+
+ if (err.result === global.DEFAULT_OK_RESPONSE.result) {
+
+ logger.write("[INFO] runExtractionBot -> onInitializeReady -> whenStartFinishes -> Bot execution finished sucessfully. :-)");
+ console.log("Bot execution finished sucessfully. :-)");
+
+ } else {
+
+ logger.write("[ERROR] runExtractionBot -> onInitializeReady -> whenStartFinishes -> err = " + err.message);
+ logger.write("[ERROR] runExtractionBot -> onInitializeReady -> whenStartFinishes -> Execution will be stopped. ");
+ logger.write("[ERROR] runExtractionBot -> onInitializeReady -> whenStartFinishes -> Bye. :-(");
+ }
+ }
+
+ } else {
+ logger.write("[ERROR] runExtractionBot -> onInitializeReady -> err = " + err.message);
+ logger.write("[ERROR] runExtractionBot -> onInitializeReady -> Bot will not be started. ");
+ }
+ }
+ }
+ catch (err) {
+ logger.write("[ERROR] runExtractionBot -> err = " + err.message);
+ }
+}
function runIndicatorBot(pProcessConfig) {
@@ -275,7 +318,6 @@ function runIndicatorBot(pProcessConfig) {
}
}
-
function runTradingBot(pProcessConfig) {
try {
diff --git a/this.config.json b/this.config.json
index 53b059787..5d0bc2469 100644
--- a/this.config.json
+++ b/this.config.json
@@ -6,7 +6,7 @@
"patch": 0
},
"bot": {
- "path": "../Bots/AAMasters/AAMariam-Trading-Bot"
+ "path": "../Bots/AAMasters/AACharly-Extraction-Bot"
},
"stopGracefully": "false"
}
\ No newline at end of file