Merge pull request #145 from AAMasters/develop

Release to Master Branch
This commit is contained in:
Luis Fernando Molina authored and GitHub committed 2020-03-22 14:31:38 +01:00
commit 0cf4261b9c
21 files changed
+282 -416

No files matched your search

+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);
+12 -5
View File
@@ -37,18 +37,25 @@ exports.newDebugLog = function newDebugLog() {
}
}
function newInternalLoop(pBot, pProcess, date) {
function newInternalLoop(pBot, pProcess, date, percentage) {
if (percentage === undefined) {
percentage = ""
} else {
percentage = percentage.toFixed(2) + " %"
}
if (date === undefined) { date = thisObject.bot.processDatetime }
date = date.getUTCFullYear() + '-' + strPad(date.getUTCMonth() + 1, 2, "0") + '-' + strPad(date.getUTCDate(), 2, "0");
console.log(new Date().toISOString() + " " + strPad(pBot, 20) + " " + strPad(pProcess, 30) + " " + strPad(thisObject.bot.exchange, 20) + " " + strPad(thisObject.bot.market.baseAsset + '/' + thisObject.bot.market.quotedAsset, 10)
+ " Entered into Internal Loop # " + strPad(internalLoopCounter + 1, 8) + " " + strPad(date.toISOString(), 30))
console.log(new Date().toISOString() + " " + strPad(thisObject.bot.exchange, 20) + " " + strPad(thisObject.bot.market.baseAsset + '/' + thisObject.bot.market.quotedAsset, 10) + " " + strPad(pBot, 20) + " " + strPad(pProcess, 30)
+ " Internal Loop # " + strPad(internalLoopCounter + 1, 8) + " " + strPad(date, 30) + " " + strPad(percentage, 10))
persist();
function strPad(str, max) {
function strPad(str, max, fill) {
if (fill === undefined) {fill = " "}
str = str.toString();
return str.length < max ? strPad(" " + str, max) : str;
return str.length < max ? strPad(fill + str, max) : str;
}
}
-9
View File
@@ -1,9 +0,0 @@
FROM node:8.16-alpine
RUN mkdir -p /usr/src/app
WORKDIR /usr/src/app
COPY package.json ./
RUN npm install
COPY . .
+24 -14
View File
@@ -5,9 +5,11 @@ exports.newFileStorage = function newFileStorage(logger) {
const MODULE_NAME = 'FileStorage'
const MAX_RETRY = 30
const RETRY_TIME_IN_MILISECONDS = 250
const FAST_RETRY_TIME_IN_MILISECONDS = 500
const SLOW_RETRY_TIME_IN_MILISECONDS = 5000
let currentRetryGetTextFile = 0
let currentRetryWriteTextFile = 0
let currentRetryDeleteTextFile = 0
if (logger === undefined) { // Dummy logger
logger = {}
@@ -48,7 +50,10 @@ exports.newFileStorage = function newFileStorage(logger) {
fs.readFile(fileLocation, onFileRead)
function onFileRead(err, text) {
let retryTimeToUse = FAST_RETRY_TIME_IN_MILISECONDS
if (currentRetryGetTextFile > MAX_RETRY - 2) {
retryTimeToUse = SLOW_RETRY_TIME_IN_MILISECONDS
}
if (err) {
if (err.code === 'ENOENT') { // since files are deleted before being replaced, it can happen that it does not exist and after a retry it does.
@@ -63,7 +68,7 @@ exports.newFileStorage = function newFileStorage(logger) {
} else {
fileDoesNotExist = true
logger.write(MODULE_NAME, '[WARN] FileStorage -> getTextFile -> onFileRead -> File does not exist. Retrying. ')
setTimeout(retry, RETRY_TIME_IN_MILISECONDS)
setTimeout(retry, retryTimeToUse)
return
}
}
@@ -71,13 +76,13 @@ exports.newFileStorage = function newFileStorage(logger) {
logger.write(MODULE_NAME, '[WARN] FileStorage -> getTextFile -> onFileRead -> Error reading file -> err = ' + err.stack)
logger.write(MODULE_NAME, '[WARN] FileStorage -> getTextFile -> onFileRead -> Error reading file -> filePath = ' + filePath)
logger.write(MODULE_NAME, '[WARN] FileStorage -> getTextFile -> onFileRead -> Error reading file -> err = ' + err.stack)
setTimeout(retry, RETRY_TIME_IN_MILISECONDS)
setTimeout(retry, retryTimeToUse)
return
}
if (text.toString() === "") {
logger.write(MODULE_NAME, '[WARN] FileStorage -> getTextFile -> onFileRead -> Read and Empty File -> filePath = ' + filePath)
setTimeout(retry, RETRY_TIME_IN_MILISECONDS)
setTimeout(retry, retryTimeToUse)
return
}
@@ -91,6 +96,7 @@ exports.newFileStorage = function newFileStorage(logger) {
}
function retry() {
//console.log(new Date(), ' Retry #: ' + currentRetryGetTextFile, fileLocation )
if (currentRetryGetTextFile < MAX_RETRY) {
currentRetryGetTextFile++
logger.write(MODULE_NAME, '[WARN] FileStorage -> getTextFile -> retry -> Will try to read the file again -> Retry #: ' + currentRetryGetTextFile)
@@ -144,10 +150,14 @@ exports.newFileStorage = function newFileStorage(logger) {
fs.writeFile(fileLocation + '.tmp', fileContent, onFileWritenn)
function onFileWritenn(err) {
let retryTimeToUse = FAST_RETRY_TIME_IN_MILISECONDS
if (currentRetryWriteTextFile > MAX_RETRY - 2) {
retryTimeToUse = SLOW_RETRY_TIME_IN_MILISECONDS
}
if (err) {
logger.write(MODULE_NAME, '[WARN] FileStorage -> createTextFile -> onFileWriten -> Error writing file -> file = ' + fileLocation)
logger.write(MODULE_NAME, '[WARN] FileStorage -> createTextFile -> onFileWriten -> Error writing file -> err = ' + err.stack)
setTimeout(retry, RETRY_TIME_IN_MILISECONDS)
setTimeout(retry, retryTimeToUse)
} else {
const fs = require('fs')
@@ -161,7 +171,7 @@ exports.newFileStorage = function newFileStorage(logger) {
if (code !== '' && code !== 'ENOENT') {
logger.write(MODULE_NAME, '[WARN] FileStorage -> createTextFile -> onFileWriten -> onUnlinked -> Error renaming file -> file = ' + fileLocation)
logger.write(MODULE_NAME, '[WARN] FileStorage -> createTextFile -> onFileWriten -> onUnlinked -> Error renaming file -> err = ' + err.stack)
setTimeout(retry, RETRY_TIME_IN_MILISECONDS)
setTimeout(retry, retryTimeToUse)
} else {
const fs = require('fs')
@@ -171,7 +181,7 @@ exports.newFileStorage = function newFileStorage(logger) {
if (err) {
logger.write(MODULE_NAME, '[WARN] FileStorage -> createTextFile -> onFileWriten -> onUnlinked -> onRenamed -> Error renaming file -> file = ' + fileLocation + '.tmp')
logger.write(MODULE_NAME, '[WARN] FileStorage -> createTextFile -> onFileWriten -> onUnlinked -> onRenamed -> Error renaming file -> err = ' + err.stack)
setTimeout(retry, RETRY_TIME_IN_MILISECONDS)
setTimeout(retry, retryTimeToUse)
} else {
callBackFunction(global.DEFAULT_OK_RESPONSE)
@@ -242,14 +252,14 @@ exports.newFileStorage = function newFileStorage(logger) {
}
function retry() {
if (currentRetryWriteTextFile < MAX_RETRY) {
currentRetryWriteTextFile++
logger.write(MODULE_NAME, '[WARN] FileStorage -> createTextFile -> retry -> Will try to write the file again -> Retry #: ' + currentRetryWriteTextFile)
if (currentRetryDeleteTextFile < MAX_RETRY) {
currentRetryDeleteTextFile++
logger.write(MODULE_NAME, '[WARN] FileStorage -> deleteTextFile -> retry -> Will try to delete the file again -> Retry #: ' + currentRetryDeleteTextFile)
createTextFile(filePath, fileContent, callBackFunction)
} else {
currentRetryWriteTextFile = 0
logger.write(MODULE_NAME, '[ERROR] FileStorage -> createTextFile -> retry -> Max retries reached writting a file. Giving up.')
logger.write(MODULE_NAME, '[ERROR] FileStorage -> createTextFile -> retry -> file = ' + fileLocation)
currentRetryDeleteTextFile = 0
logger.write(MODULE_NAME, '[ERROR] FileStorage -> deleteTextFile -> retry -> Max retries reached deleting a file. Giving up.')
logger.write(MODULE_NAME, '[ERROR] FileStorage -> deleteTextFile -> retry -> file = ' + fileLocation)
callBackFunction(global.DEFAULT_FAIL_RESPONSE)
}
}
+15 -84
View File
@@ -145,12 +145,11 @@
/* High level log entry */
console.log(new Date().toISOString() + " " + pad(bot.codeName, 20) + " " + pad(bot.process, 30) + " " + pad(bot.exchange, 20) + " " + pad(bot.market.baseAsset + '/' + bot.market.quotedAsset, 10)
+ " Entered into Main Loop # " + pad(Number(bot.loopCounter), 8));
console.log(new Date().toISOString() + " " + pad(bot.exchange, 20) + " " + pad(bot.market.baseAsset + '/' + bot.market.quotedAsset, 10) + " " + pad(bot.codeName, 20) + " " + pad(bot.process, 30)
+ " Main Loop # " + pad(Number(bot.loopCounter), 8))
/* We will prepare first the infraestructure needed for the bot to run. There are 3 modules we need to sucessfullly initialize first. */
let processOutput
let processExecutionEvents
let userBot;
let processFramework;
@@ -315,7 +314,7 @@
if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] run -> loop -> initializeStatusDependencies -> Entering function."); }
statusDependencies = STATUS_DEPENDENCIES.newStatusDependencies(bot, logger, STATUS_REPORT, UTILITIES);
statusDependencies = STATUS_DEPENDENCIES.newStatusDependencies(bot, logger, STATUS_REPORT, UTILITIES, PROCESS_OUTPUT);
statusDependencies.initialize(onInizialized);
@@ -494,7 +493,7 @@
if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] run -> loop -> initializeUserBot -> Entering function."); }
usertBot = USER_BOT_MODULE.newUserBot(bot, logger, COMMONS_MODULE, UTILITIES, fileStorage);
usertBot = USER_BOT_MODULE.newUserBot(bot, logger, COMMONS_MODULE, UTILITIES, FILE_STORAGE);
usertBot.initialize(statusDependencies, onInizialized);
@@ -595,7 +594,7 @@
switch (err.result) {
case global.DEFAULT_OK_RESPONSE.result: {
logger.write(MODULE_NAME, "[INFO] run -> loop -> startUserBot -> onFinished -> Execution finished well.");
raiseEventsProcessOutput()
finishProcessExecutionEvents()
return;
}
case global.DEFAULT_RETRY_RESPONSE.result: { // Something bad happened, but if we retry in a while it might go through the next time.
@@ -785,7 +784,7 @@
switch (err.result) {
case global.DEFAULT_OK_RESPONSE.result: {
logger.write(MODULE_NAME, "[INFO] run -> loop -> startProcessFramework -> onFinished -> Execution finished well.");
raiseEventsProcessOutput()
finishProcessExecutionEvents()
return;
}
case global.DEFAULT_RETRY_RESPONSE.result: { // Something bad happened, but if we retry in a while it might go through the next time.
@@ -868,81 +867,6 @@
}
}
function raiseEventsProcessOutput() {
try {
if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] run -> loop -> raiseEventsProcessOutput -> Entering function."); }
processOutput = PROCESS_OUTPUT.newProcessOutput(bot, logger)
processOutput.raiseEvents(statusDependencies, onFinished);
function onFinished(err) {
try {
if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] run -> loop -> raiseEventsProcessOutput -> onFinished -> Entering function."); }
switch (err.result) {
case global.DEFAULT_OK_RESPONSE.result: {
logger.write(MODULE_NAME, "[INFO] run -> loop -> raiseEventsProcessOutput -> onFinished -> Execution finished well.");
finishProcessExecutionEvents()
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(MODULE_NAME, "[WARN] run -> loop -> raiseEventsProcessOutput -> onFinished -> 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.
processStopped()
logger.write(MODULE_NAME, "[ERROR] run -> loop -> raiseEventsProcessOutput -> onFinished -> Operation Failed. Aborting the process.");
logger.persist();
clearInterval(fixedTimeLoopIntervalHandle);
clearTimeout(nextLoopTimeoutHandle);
clearTimeout(checkLoopHealthHandle);
bot.enableCheckLoopHealth = false;
callBackFunction(err);
return;
}
default: {
logger.write(MODULE_NAME, "[ERROR] run -> loop -> raiseEventsProcessOutput -> onFinished -> Unhandled err.result received. -> err.result = " + err.result);
logger.write(MODULE_NAME, "[ERROR] run -> loop -> raiseEventsProcessOutput -> onFinished -> Unhandled err.result received. -> err = " + err.message);
logger.persist();
clearInterval(fixedTimeLoopIntervalHandle);
clearTimeout(nextLoopTimeoutHandle);
clearTimeout(checkLoopHealthHandle);
bot.enableCheckLoopHealth = false;
callBackFunction(global.DEFAULT_FAIL_RESPONSE);
return;
}
}
} catch (err) {
logger.write(MODULE_NAME, "[ERROR] run -> loop -> raiseEventsProcessOutput -> onFinished -> err = " + err.stack);
logger.persist();
clearInterval(fixedTimeLoopIntervalHandle);
clearTimeout(nextLoopTimeoutHandle);
clearTimeout(checkLoopHealthHandle);
bot.enableCheckLoopHealth = false;
callBackFunction(err);
}
}
} catch (err) {
logger.write(MODULE_NAME, "[ERROR] run -> loop -> raiseEventsProcessOutput -> err = " + err.stack);
logger.persist();
clearInterval(fixedTimeLoopIntervalHandle);
clearTimeout(nextLoopTimeoutHandle);
clearTimeout(checkLoopHealthHandle);
bot.enableCheckLoopHealth = false;
callBackFunction(err);
}
}
function finishProcessExecutionEvents() {
try {
@@ -1040,6 +964,7 @@
logger.persist();
}
processStopped()
callBackFunction(global.DEFAULT_OK_RESPONSE);
return;
@@ -1058,6 +983,7 @@
checkLoopHealthHandle = setTimeout(checkLoopHealth, processConfig.deadWaitTime, bot.loopCounter);
}
nextLoopTimeoutHandle = setTimeout(loop, processConfig.normalWaitTime);
processHeartBeat(undefined, undefined, "Waiting " + processConfig.normalWaitTime / 1000 + " seconds for next execution.")
if(global.WRITE_LOGS_TO_FILES === 'true'){
logger.persist();
}
@@ -1069,18 +995,21 @@
checkLoopHealthHandle = setTimeout(checkLoopHealth, processConfig.deadWaitTime, bot.loopCounter);
}
nextLoopTimeoutHandle = setTimeout(loop, processConfig.retryWaitTime);
processHeartBeat(undefined, undefined, "Trying to recover from some problem. Waiting " + processConfig.retryWaitTime / 1000 + " seconds for next execution.")
logger.persist();
}
break;
case 'Sleep': {
if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] run -> loop -> loopControl -> Restarting Loop in " + (processConfig.sleepWaitTime / 60000) + " minutes."); }
nextLoopTimeoutHandle = setTimeout(loop, processConfig.sleepWaitTime);
processHeartBeat(undefined, undefined, "Waiting " + processConfig.sleepWaitTime / 60000 + " minutes for next execution.")
logger.persist();
}
break;
case 'Coma': {
if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] run -> loop -> loopControl -> Restarting Loop in " + (processConfig.comaWaitTime / 3600000) + " hours."); }
nextLoopTimeoutHandle = setTimeout(loop, processConfig.comaWaitTime);
processHeartBeat(undefined, undefined, "Waiting " + processConfig.comaWaitTime / 3600000 + " hours for next execution.")
logger.persist();
}
break;
@@ -1152,10 +1081,12 @@
}
}
function processHeartBeat(processingDate) {
function processHeartBeat(processingDate, percentage, status) {
let event = {
seconds: (new Date()).getSeconds(),
processingDate: processingDate
processingDate: processingDate,
percentage: percentage,
status: status
}
global.SYSTEM_EVENT_HANDLER.raiseEvent(bot.processKey, 'Heartbeat', event)
}
+7 -10
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") {
@@ -452,11 +452,7 @@
bot.multiPeriodProcessDatetime = new Date(bot.multiPeriodProcessDatetime.valueOf() + ONE_DAY_IN_MILISECONDS);
previousDay = new Date(bot.multiPeriodProcessDatetime.valueOf() - ONE_DAY_IN_MILISECONDS);
if (global.WRITE_LOGS_TO_FILES === 'true') {
logger.newInternalLoop(bot.codeName, bot.process);
}
if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] start -> processTimeFramesDailyFiles -> advanceTime -> bot.multiPeriodProcessDatetime = " + bot.multiPeriodProcessDatetime); }
if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] start -> processTimeFramesDailyFiles -> advanceTime -> previousDay = " + previousDay); }
@@ -636,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);
@@ -712,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);
@@ -990,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);
@@ -1009,7 +1005,7 @@
logger.write(MODULE_NAME, "[INFO] start -> writeDataRange -> onFileCreated -> Content written = " + fileContent);
}
let key = bot.dataMine + "-" + bot.codeName + "-" + productCodeName + "-" + currentOutputPeriodName
let key = bot.dataMine + "-" + bot.codeName + "-" + productCodeName + "-" + bot.exchange + "-" + bot.market.baseAsset + '/' + bot.market.quotedAsset
let event = {
dateRange: dataRange
}
@@ -1061,6 +1057,7 @@
thisReport.file.lastExecution = bot.processDatetime;
thisReport.save(callBack);
logger.newInternalLoop(bot.codeName, bot.process, bot.multiPeriodProcessDatetime);
}
catch (err) {
logger.write(MODULE_NAME, "[ERROR] start -> writeMarketStatusReport -> err = " + err.stack);
+48 -13
View File
@@ -307,6 +307,8 @@
let botNeverRan = true;
bot.multiPeriodDailyProcessDatetime = new Date(contextVariables.lastFile.valueOf() - ONE_DAY_IN_MILISECONDS); // Go back one day to start well when we advance time at the begining of the loop.
let fromDate = new Date(bot.multiPeriodDailyProcessDatetime.valueOf())
let lastDate = new Date()
advanceTime();
@@ -318,11 +320,7 @@
bot.multiPeriodDailyProcessDatetime = new Date(bot.multiPeriodDailyProcessDatetime.valueOf() + ONE_DAY_IN_MILISECONDS);
previousDay = new Date(bot.multiPeriodDailyProcessDatetime.valueOf() - ONE_DAY_IN_MILISECONDS);
if (global.WRITE_LOGS_TO_FILES === 'true') {
logger.newInternalLoop(bot.codeName, bot.process);
}
if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] start -> processTimeFrames -> advanceTime -> bot.multiPeriodDailyProcessDatetime = " + bot.multiPeriodDailyProcessDatetime); }
if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] start -> processTimeFrames -> advanceTime -> previousDay = " + previousDay); }
@@ -338,7 +336,17 @@
}
periodsLoop();
/* Telling the world we are alive and doing well */
let currentDateString = bot.multiPeriodDailyProcessDatetime.getUTCFullYear() + '-' + utilities.pad(bot.multiPeriodDailyProcessDatetime.getUTCMonth() + 1, 2) + '-' + utilities.pad(bot.multiPeriodDailyProcessDatetime.getUTCDate(), 2);
let currentDate = new Date(bot.multiPeriodDailyProcessDatetime)
let percentage = global.getPercentage(fromDate, currentDate, lastDate)
bot.processHeartBeat(currentDateString, percentage)
if (global.areEqualDates(currentDate, new Date()) === false) {
logger.newInternalLoop(bot.codeName, bot.process, currentDate, percentage);
}
checkStopTaskGracefully();
} catch (err) {
logger.write(MODULE_NAME, "[ERROR] start -> processTimeFrames -> advanceTime -> err = "+ err.stack);
@@ -346,16 +354,35 @@
}
}
function checkStopTaskGracefully() {
try {
if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] start -> processTimeFramesDailyFiles -> checkStopTaskGracefully -> Entering function."); }
/* Validation that we dont need to stop. */
if (global.STOP_TASK_GRACEFULLY === true) {
callBackFunction(global.DEFAULT_OK_RESPONSE);
return;
}
periodsLoop();
} catch (err) {
logger.write(MODULE_NAME, "[ERROR] start -> processTimeFramesDailyFiles -> checkStopTaskGracefully -> err = " + err.stack);
callBackFunction(global.DEFAULT_FAIL_RESPONSE);
}
}
function periodsLoop() {
try {
if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] start -> processTimeFrames -> periodsLoop -> Entering function."); }
/* Telling the world we are alive and doing well */
let processingDate = bot.multiPeriodDailyProcessDatetime.getUTCFullYear() + '-' + utilities.pad(bot.multiPeriodDailyProcessDatetime.getUTCMonth() + 1, 2) + '-' + utilities.pad(bot.multiPeriodDailyProcessDatetime.getUTCDate(), 2);
bot.processHeartBeat(processingDate)
/*
We will iterate through all posible periods.
@@ -432,7 +459,7 @@
} else {
filePath = dependency.product + '/' + dependency.dataSet + "/" + dateForPath;
}
let fileName = market.baseAsset + '_' + market.quotedAsset + ".json";
let fileName = "Data.json";
dataset.getTextFile(filePath, fileName, onFileReceived);
@@ -502,7 +529,7 @@
} else {
filePath = dependency.product + '/' + dependency.dataSet + "/" + dateForPath;
}
let fileName = market.baseAsset + '_' + market.quotedAsset + ".json";
let fileName = "Data.json";
dataset.getTextFile(filePath, fileName, onFileReceived);
@@ -736,7 +763,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);
@@ -755,6 +782,13 @@
logger.write(MODULE_NAME, "[INFO] start -> writeDataRange -> onFileCreated -> Content written = " + fileContent);
}
let key = bot.dataMine + "-" + bot.codeName + "-" + productCodeName + "-" + bot.exchange + "-" + bot.market.baseAsset + '/' + bot.market.quotedAsset
let event = {
dateRange: dataRange
}
global.SYSTEM_EVENT_HANDLER.raiseEvent(key, 'Data Range Updated', event)
callBack(global.DEFAULT_OK_RESPONSE);
}
}
@@ -781,6 +815,7 @@
thisReport.save(callBack);
bot.hasTheBotJustStarted = false;
}
catch (err) {
logger.write(MODULE_NAME, "[ERROR] start -> writeStatusReport -> err = "+ err.stack);
+10 -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") {
@@ -338,6 +338,15 @@
thisReport.file.lastExecution = bot.processDatetime;
thisReport.save(callBack);
if (global.areEqualDates(bot.processDatetime, new Date()) === false) {
logger.newInternalLoop(bot.codeName, bot.process, bot.processDatetime);
}
/* Telling the world we are alive and doing well */
let currentDateString = bot.processDatetime.getUTCFullYear() + '-' + utilities.pad(bot.processDatetime.getUTCMonth() + 1, 2) + '-' + utilities.pad(bot.processDatetime.getUTCDate(), 2);
let currentDate = new Date(bot.processDatetime)
let lastDate = new Date()
bot.processHeartBeat(currentDateString, global.getPercentage(currentDate, currentDate, lastDate))
}
catch (err) {
logger.write(MODULE_NAME, "[ERROR] start -> writeStatusReport -> err = "+ err.stack);
+4
View File
@@ -83,6 +83,8 @@
global.SYSTEM_EVENT_HANDLER.listenToEvent(key, 'Process Execution Finished', undefined, callerId, responseCallBack, eventsCallBack)
bot.processHeartBeat(undefined, undefined, "Waiting for " + processThisDependsOn.parentNode.parentNode.name + "->" + processThisDependsOn.parentNode.code.codeName + "->" + processThisDependsOn.code.codeName)
function responseCallBack(message) {
if (message.result !== global.DEFAULT_OK_RESPONSE.result) {
logger.write(MODULE_NAME, "[ERROR] start -> responseCallBack -> message = " + JSON.stringify(message))
@@ -110,6 +112,8 @@
global.SYSTEM_EVENT_HANDLER.createEventHandler(currentProcessKey, 'Process Execution Started')
global.SYSTEM_EVENT_HANDLER.raiseEvent(currentProcessKey, 'Process Execution Started', event)
bot.processHeartBeat(undefined, undefined,"Running...")
if (global.LOG_CONTROL[MODULE_NAME].logInfo === true) { logger.write(MODULE_NAME, "[INFO] start -> eventsCallBack -> " + currentProcessKey + " Process Execution Started because " + key + " Finished."); }
}
+3 -5
View File
@@ -14,7 +14,7 @@
return thisObject;
function raiseEvents(statusDependencies, callBackFunction) {
function raiseEvents(lastFile, callBackFunction) {
try {
if (global.LOG_CONTROL[MODULE_NAME].logInfo === true) { logger.write(MODULE_NAME, "[INFO] raiseEvents -> Entering function."); }
@@ -81,11 +81,9 @@
let product = outputDataset.referenceParent.parentNode.code.codeName
let dataset = outputDataset.referenceParent.code.codeName
let statusReport = statusDependencies.reportsByMainUtility.get("Self Reference")
key = dataMine + "-" + botName + "-" + product + "-" + dataset
key = dataMine + "-" + botName + "-" + product + "-" + dataset + "-" + bot.exchange + "-" + bot.market.baseAsset + '/' + bot.market.quotedAsset
let event = {
lastFile: statusReport.file.lastFile
lastFile: lastFile
}
global.SYSTEM_EVENT_HANDLER.createEventHandler(key, 'Dataset Updated')
global.SYSTEM_EVENT_HANDLER.raiseEvent(key, 'Dataset Updated', event)
+4 -8
View File
@@ -205,13 +205,14 @@
/* 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,
quotedAsset: global.TASK_NODE.bot.processes[processIndex].marketReference.referenceParent.quotedAsset.referenceParent.code.codeName
}
botConfig.uiStartDate = global.TASK_NODE.bot.code.startDate
botConfig.code = global.TASK_NODE.bot.code
/* This stuff is still hardcoded and unresolved. */
botConfig.version = {
@@ -224,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
@@ -386,7 +387,6 @@
logger.write(MODULE_NAME, "[INFO] start -> bootingBot -> runSensorBot -> onInitializeReady -> whenStartFinishes -> Bot execution finished sucessfully.");
logger.write(MODULE_NAME, "[INFO] start -> bootingBot -> runSensorBot -> onInitializeReady -> whenStartFinishes -> Bot Id = " + botId);
console.log(logDisplace + "Root : [INFO] start -> bootingBot -> runSensorBot -> onInitializeReady -> whenStartFinishes -> Bot execution finished sucessfully.");
logger.persist();
} else {
@@ -451,8 +451,6 @@
logger.write(MODULE_NAME, "[INFO] start -> bootingBot -> runIndicatorBot -> onInitializeReady -> whenStartFinishes -> Bot execution finished sucessfully.");
logger.write(MODULE_NAME, "[INFO] start -> bootingBot -> runIndicatorBot -> onInitializeReady -> whenStartFinishes -> Bot Id = " + botId);
console.log(logDisplace + "Root : [INFO] start -> bootingBot -> runIndicatorBot -> onInitializeReady -> whenStartFinishes -> Bot execution finished sucessfully.");
logger.persist();
} else {
@@ -517,8 +515,6 @@
logger.write(MODULE_NAME, "[INFO] start -> bootingBot -> runTradingBot -> onInitializeReady -> whenStartFinishes -> Bot execution finished sucessfully.");
logger.write(MODULE_NAME, "[INFO] start -> bootingBot -> runTradingBot -> onInitializeReady -> whenStartFinishes -> Bot Id = " + botId);
console.log(logDisplace + "Root : [INFO] start -> bootingBot -> runTradingBot -> onInitializeReady -> whenStartFinishes -> botId = " + botId);
console.log(logDisplace + "Root : [INFO] start -> bootingBot -> runTradingBot -> onInitializeReady -> whenStartFinishes -> Bot execution finished sucessfully.");
logger.persist();
} else {
@@ -557,7 +553,7 @@
function exitProcessInstance() {
global.ENDED_PROCESSES_COUNTER++
console.log("[INFO] Task Server -> " + global.TASK_NODE.name + " -> exitProcessInstance -> Process #" + global.ENDED_PROCESSES_COUNTER + " from " + global.TOTAL_PROCESS_INSTANCES_CREATED + " exiting.");
//console.log("[INFO] Task Server -> " + global.TASK_NODE.name + " -> exitProcessInstance -> Process #" + global.ENDED_PROCESSES_COUNTER + " from " + global.TOTAL_PROCESS_INSTANCES_CREATED + " exiting.");
if (global.ENDED_PROCESSES_COUNTER === global.TOTAL_PROCESS_INSTANCES_CREATED) {
global.EXIT_NODE_PROCESS()
+23 -108
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) {
@@ -115,7 +113,7 @@
function loop() {
try {
processHeartBeat(undefined, undefined, "Running...")
function pad(str, max) {
str = str.toString();
return str.length < max ? pad(" " + str, max) : str;
@@ -150,12 +148,11 @@
/* High level log entry */
console.log(new Date().toISOString() + " " + pad(bot.codeName, 20) + " " + pad(bot.process, 30) + " " + pad(bot.exchange, 20) + " " + pad(bot.market.baseAsset + '/' + bot.market.quotedAsset, 10)
+ " Entered into Main Loop # " + pad(Number(bot.loopCounter), 8) )
console.log(new Date().toISOString() + " " + pad(bot.exchange, 20) + " " + pad(bot.market.baseAsset + '/' + bot.market.quotedAsset, 10) + " " + pad(bot.codeName, 20) + " " + pad(bot.process, 30)
+ " Main Loop # " + pad(Number(bot.loopCounter), 8) )
/* We will prepare first the infraestructure needed for the bot to run. There are 4 modules we need to sucessfullly initialize first. */
let processOutput
let processExecutionEvents
let userBot;
let statusDependencies;
@@ -319,7 +316,7 @@
if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] run -> loop -> initializeStatusDependencies -> Entering function."); }
statusDependencies = STATUS_DEPENDENCIES.newStatusDependencies(bot, logger, STATUS_REPORT, UTILITIES);
statusDependencies = STATUS_DEPENDENCIES.newStatusDependencies(bot, logger, STATUS_REPORT, UTILITIES, PROCESS_OUTPUT);
statusDependencies.initialize(onInizialized);
@@ -394,7 +391,7 @@
if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] run -> loop -> initializeUserBot -> Entering function."); }
usertBot = USER_BOT_MODULE.newUserBot(bot, logger, COMMONS_MODULE, UTILITIES, fileStorage, STATUS_REPORT, exchangeAPI);
usertBot = USER_BOT_MODULE.newUserBot(bot, logger, COMMONS_MODULE, UTILITIES, FILE_STORAGE, STATUS_REPORT, exchangeAPI);
usertBot.initialize(statusDependencies, onInizialized);
@@ -495,7 +492,7 @@
switch (err.result) {
case global.DEFAULT_OK_RESPONSE.result: {
logger.write(MODULE_NAME, "[INFO] run -> loop -> startUserBot -> onFinished > Execution finished well.");
raiseEventsProcessOutput()
finishProcessExecutionEvents()
return;
}
case global.DEFAULT_RETRY_RESPONSE.result: { // Something bad happened, but if we retry in a while it might go through the next time.
@@ -578,81 +575,6 @@
}
}
function raiseEventsProcessOutput() {
try {
if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] run -> loop -> raiseEventsProcessOutput -> Entering function."); }
processOutput = PROCESS_OUTPUT.newProcessOutput(bot, logger)
processOutput.raiseEvents(statusDependencies, onFinished);
function onFinished(err) {
try {
if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] run -> loop -> raiseEventsProcessOutput -> onFinished -> Entering function."); }
switch (err.result) {
case global.DEFAULT_OK_RESPONSE.result: {
logger.write(MODULE_NAME, "[INFO] run -> loop -> raiseEventsProcessOutput -> onFinished -> Execution finished well.");
finishProcessExecutionEvents()
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(MODULE_NAME, "[WARN] run -> loop -> raiseEventsProcessOutput -> onFinished -> 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.
processStopped()
logger.write(MODULE_NAME, "[ERROR] run -> loop -> raiseEventsProcessOutput -> onFinished -> Operation Failed. Aborting the process.");
logger.persist();
clearInterval(fixedTimeLoopIntervalHandle);
clearTimeout(nextLoopTimeoutHandle);
clearTimeout(checkLoopHealthHandle);
bot.enableCheckLoopHealth = false;
callBackFunction(err);
return;
}
default: {
logger.write(MODULE_NAME, "[ERROR] run -> loop -> raiseEventsProcessOutput -> onFinished -> Unhandled err.result received. -> err.result = " + err.result);
logger.write(MODULE_NAME, "[ERROR] run -> loop -> raiseEventsProcessOutput -> onFinished -> Unhandled err.result received. -> err = " + err.message);
logger.persist();
clearInterval(fixedTimeLoopIntervalHandle);
clearTimeout(nextLoopTimeoutHandle);
clearTimeout(checkLoopHealthHandle);
bot.enableCheckLoopHealth = false;
callBackFunction(global.DEFAULT_FAIL_RESPONSE);
return;
}
}
} catch (err) {
logger.write(MODULE_NAME, "[ERROR] run -> loop -> raiseEventsProcessOutput -> onFinished -> err = " + err.stack);
logger.persist();
clearInterval(fixedTimeLoopIntervalHandle);
clearTimeout(nextLoopTimeoutHandle);
clearTimeout(checkLoopHealthHandle);
bot.enableCheckLoopHealth = false;
callBackFunction(err);
}
}
} catch (err) {
logger.write(MODULE_NAME, "[ERROR] run -> loop -> raiseEventsProcessOutput -> err = " + err.stack);
logger.persist();
clearInterval(fixedTimeLoopIntervalHandle);
clearTimeout(nextLoopTimeoutHandle);
clearTimeout(checkLoopHealthHandle);
bot.enableCheckLoopHealth = false;
callBackFunction(err);
}
}
function finishProcessExecutionEvents() {
try {
@@ -733,9 +655,6 @@
if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] run -> loop -> loopControl -> nextWaitTime = " + nextWaitTime); }
/* We show we reached the end of the loop. */
processHeartBeat()
/* Here we check if we must stop the loop gracefully. */
shallWeStop(onStop, onContinue);
@@ -754,6 +673,7 @@
clearTimeout(nextLoopTimeoutHandle);
clearTimeout(checkLoopHealthHandle);
bot.enableCheckLoopHealth = false;
processStopped()
callBackFunction(global.DEFAULT_OK_RESPONSE);
return;
@@ -767,24 +687,14 @@
switch (nextWaitTime) {
case 'Normal': {
if (bot.runAtFixedInterval === true) {
if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] run -> loop -> loopControl -> Fixed Interval Normal exit point reached."); }
if (processConfig.deadWaitTime > 0) {
checkLoopHealthHandle = setTimeout(checkLoopHealth, processConfig.deadWaitTime, bot.loopCounter);
}
if(global.WRITE_LOGS_TO_FILES === 'true'){
logger.persist();
}
return;
} else {
if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] run -> loop -> loopControl -> Restarting Loop in " + (processConfig.normalWaitTime / 1000) + " seconds."); }
if (processConfig.deadWaitTime > 0) {
checkLoopHealthHandle = setTimeout(checkLoopHealth, processConfig.deadWaitTime, bot.loopCounter);
}
nextLoopTimeoutHandle = setTimeout(loop, processConfig.normalWaitTime);
if(global.WRITE_LOGS_TO_FILES === 'true'){
logger.persist();
}
if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] run -> loop -> loopControl -> Restarting Loop in " + (processConfig.normalWaitTime / 1000) + " seconds."); }
if (processConfig.deadWaitTime > 0) {
checkLoopHealthHandle = setTimeout(checkLoopHealth, processConfig.deadWaitTime, bot.loopCounter);
}
nextLoopTimeoutHandle = setTimeout(loop, processConfig.normalWaitTime);
processHeartBeat(undefined, undefined, "Waiting " + processConfig.normalWaitTime / 1000 + " seconds for next execution.")
if(global.WRITE_LOGS_TO_FILES === 'true'){
logger.persist();
}
}
break;
@@ -794,6 +704,7 @@
checkLoopHealthHandle = setTimeout(checkLoopHealth, processConfig.retryWaitTime * 5, bot.loopCounter);
}
nextLoopTimeoutHandle = setTimeout(loop, processConfig.retryWaitTime);
processHeartBeat(undefined, undefined, "Trying to recover from some problem. Waiting " + processConfig.retryWaitTime / 1000 + " seconds for next execution.")
logger.persist();
}
break;
@@ -805,6 +716,7 @@
} else {
if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] run -> loop -> loopControl -> Restarting Loop in " + (processConfig.sleepWaitTime / 60000) + " minutes."); }
nextLoopTimeoutHandle = setTimeout(loop, processConfig.sleepWaitTime);
processHeartBeat(undefined, undefined, "Waiting " + processConfig.sleepWaitTime / 60000 + " minutes for next execution.")
logger.persist();
}
}
@@ -817,6 +729,7 @@
} else {
if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] run -> loop -> loopControl -> Restarting Loop in " + (processConfig.comaWaitTime / 3600000) + " hours."); }
nextLoopTimeoutHandle = setTimeout(loop, processConfig.comaWaitTime);
processHeartBeat(undefined, undefined, "Waiting " + processConfig.comaWaitTime / 3600000 + " hours for next execution.")
logger.persist();
}
}
@@ -890,10 +803,12 @@
}
}
function processHeartBeat(processingDate) {
function processHeartBeat(processingDate, percentage, status) {
let event = {
seconds: (new Date()).getSeconds(),
processingDate: processingDate
processingDate: processingDate,
percentage: percentage,
status: status
}
global.SYSTEM_EVENT_HANDLER.raiseEvent(bot.processKey, 'Heartbeat', event)
}
+32
View File
@@ -287,6 +287,22 @@
}
}
/* Quoted Asset */
{
if (tradingSystem.parameters.quotedAsset !== undefined) {
if (tradingSystem.parameters.quotedAsset.referenceParent !== undefined) {
if (tradingSystem.parameters.quotedAsset.referenceParent.referenceParent !== undefined) {
let code = tradingSystem.parameters.quotedAsset.referenceParent.referenceParent.code
if (code.codeName !== undefined) {
bot.VALUES_TO_USE.quotedAsset = code.codeName;
}
}
}
}
}
/* Time Frame */
if (tradingSystem.parameters.timeFrame !== undefined) {
bot.VALUES_TO_USE.timeFrame = tradingSystem.parameters.timeFrame.code.value
@@ -398,6 +414,22 @@
}
}
/* Quoted Asset. */
{
if (bot.SESSION.parameters.quotedAsset !== undefined) {
if (bot.SESSION.parameters.quotedAsset.referenceParent !== undefined) {
if (bot.SESSION.parameters.quotedAsset.referenceParent.referenceParent !== undefined) {
let code = bot.SESSION.parameters.quotedAsset.referenceParent.referenceParent.code
if (code.codeName !== undefined) {
bot.VALUES_TO_USE.quotedAsset = code.codeName;
}
}
}
}
}
/* Time Frame */
if (bot.SESSION.parameters.timeFrame !== undefined) {
bot.VALUES_TO_USE.timeFrame = bot.SESSION.parameters.timeFrame.code.value
+2 -2
View File
@@ -1,4 +1,4 @@
exports.newStatusDependencies = function newStatusDependencies(BOT, logger, STATUS_REPORT, UTILITIES) {
exports.newStatusDependencies = function newStatusDependencies(BOT, logger, STATUS_REPORT, UTILITIES, PROCESS_OUTPUT) {
const FULL_LOG = true;
const LOG_FILE_CONTENT = false;
@@ -53,7 +53,7 @@
for (let i = 0; i < dependenciesToProcess.length; i++) {
let statusReportModule = STATUS_REPORT.newStatusReport(BOT, logger, UTILITIES);
let statusReportModule = STATUS_REPORT.newStatusReport(BOT, logger, UTILITIES, PROCESS_OUTPUT);
logger.write(MODULE_NAME, "[INFO] initialize -> onInitilized -> Initializing Status Report # " + (i + 1));
let statusDependency = dependenciesToProcess[i]
+12 -5
View File
@@ -1,4 +1,4 @@
exports.newStatusReport = function newStatusReport(BOT, logger, UTILITIES) {
exports.newStatusReport = function newStatusReport(BOT, logger, UTILITIES, PROCESS_OUTPUT) {
/*
@@ -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
@@ -255,7 +257,12 @@
logger.write(MODULE_NAME, "[INFO] save -> onFileCreated -> Content written = " + fileContent);
}
callBackFunction(global.DEFAULT_OK_RESPONSE);
/* All good, lets emit the event that means data has been updated. */
let processOutput = PROCESS_OUTPUT.newProcessOutput(bot, logger)
processOutput.raiseEvents(thisObject.file.lastFile, callBackFunction);
return;
}
+22 -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);
@@ -204,6 +204,7 @@
record.minimumBalanceB + "," +
record.maximumBalanceB + "," +
record.baseAsset + "," +
record.quotedAsset + "," +
record.positionPeriods + "," +
record.positionDays + "," +
record.distanceToLastTriggerOn + "," +
@@ -219,10 +220,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 +296,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 +365,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 +437,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 +462,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);
}
@@ -555,6 +548,7 @@
record.minimumBalanceB + "," +
record.maximumBalanceB + "," +
record.baseAsset + "," +
record.quotedAsset + "," +
record.positionPeriods + "," +
record.positionDays + "]";
@@ -566,10 +560,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);
@@ -661,6 +653,7 @@
record.minimumBalanceB + "," +
record.maximumBalanceB + "," +
record.baseAsset + "," +
record.quotedAsset + "," +
record.positionPeriods + "," +
record.positionDays + "]";
@@ -673,10 +666,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 +752,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 +827,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 +905,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 +929,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);
}
+14 -84
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)
@@ -119,6 +117,7 @@
try {
processHeartBeat(undefined, undefined, "Running...")
function pad(str, max) {
str = str.toString();
return str.length < max ? pad(" " + str, max) : str;
@@ -159,8 +158,8 @@
/* High level log entry */
console.log(new Date().toISOString() + " " + pad(bot.codeName, 20) + " " + pad(bot.process, 30) + " " + pad(bot.exchange, 20) + " " + pad(bot.market.baseAsset + '/' + bot.market.quotedAsset, 10)
+ " Entered into Main Loop # " + pad(Number(bot.loopCounter), 8) + " " + bot.sessionKey )
console.log(new Date().toISOString() + " " + pad(bot.exchange, 20) + " " + pad(bot.market.baseAsset + '/' + bot.market.quotedAsset, 10) + " " + pad(bot.codeName, 20) + " " + pad(bot.process, 30)
+ " Main Loop # " + pad(Number(bot.loopCounter), 8) + " " + bot.sessionKey)
/* Checking if we need to need to emit any event */
@@ -189,7 +188,6 @@
/* We will prepare first the infraestructure needed for the bot to run. There are 3 modules we need to sucessfullly initialize first. */
let processOutput
let processExecutionEvents
let userBot;
let processFramework;
@@ -352,7 +350,7 @@
if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] run -> loop -> initializeStatusDependencies -> Entering function."); }
statusDependencies = STATUS_DEPENDENCIES.newStatusDependencies(bot, logger, STATUS_REPORT, UTILITIES);
statusDependencies = STATUS_DEPENDENCIES.newStatusDependencies(bot, logger, STATUS_REPORT, UTILITIES, PROCESS_OUTPUT);
statusDependencies.initialize(onInizialized);
@@ -701,7 +699,7 @@
case global.DEFAULT_OK_RESPONSE.result: {
logger.write(MODULE_NAME, "[INFO] run -> loop -> startProcessFramework -> onFinished -> Execution finished well.");
nextWaitTime = 'Normal';
raiseEventsProcessOutput()
finishProcessExecutionEvents()
return;
}
case global.DEFAULT_RETRY_RESPONSE.result: { // Something bad happened, but if we retry in a while it might go through the next time.
@@ -785,81 +783,6 @@
}
}
function raiseEventsProcessOutput() {
try {
if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] run -> loop -> raiseEventsProcessOutput -> Entering function."); }
processOutput = PROCESS_OUTPUT.newProcessOutput(bot, logger)
processOutput.raiseEvents(statusDependencies, onFinished);
function onFinished(err) {
try {
if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] run -> loop -> raiseEventsProcessOutput -> onFinished -> Entering function."); }
switch (err.result) {
case global.DEFAULT_OK_RESPONSE.result: {
logger.write(MODULE_NAME, "[INFO] run -> loop -> raiseEventsProcessOutput -> onFinished -> Execution finished well.");
finishProcessExecutionEvents()
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(MODULE_NAME, "[WARN] run -> loop -> raiseEventsProcessOutput -> onFinished -> 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.
processStopped()
logger.write(MODULE_NAME, "[ERROR] run -> loop -> raiseEventsProcessOutput -> onFinished -> Operation Failed. Aborting the process.");
logger.persist();
clearInterval(fixedTimeLoopIntervalHandle);
clearTimeout(nextLoopTimeoutHandle);
clearTimeout(checkLoopHealthHandle);
bot.enableCheckLoopHealth = false;
callBackFunction(err);
return;
}
default: {
logger.write(MODULE_NAME, "[ERROR] run -> loop -> raiseEventsProcessOutput -> onFinished -> Unhandled err.result received. -> err.result = " + err.result);
logger.write(MODULE_NAME, "[ERROR] run -> loop -> raiseEventsProcessOutput -> onFinished -> Unhandled err.result received. -> err = " + err.message);
logger.persist();
clearInterval(fixedTimeLoopIntervalHandle);
clearTimeout(nextLoopTimeoutHandle);
clearTimeout(checkLoopHealthHandle);
bot.enableCheckLoopHealth = false;
callBackFunction(global.DEFAULT_FAIL_RESPONSE);
return;
}
}
} catch (err) {
logger.write(MODULE_NAME, "[ERROR] run -> loop -> raiseEventsProcessOutput -> onFinished -> err = " + err.stack);
logger.persist();
clearInterval(fixedTimeLoopIntervalHandle);
clearTimeout(nextLoopTimeoutHandle);
clearTimeout(checkLoopHealthHandle);
bot.enableCheckLoopHealth = false;
callBackFunction(err);
}
}
} catch (err) {
logger.write(MODULE_NAME, "[ERROR] run -> loop -> raiseEventsProcessOutput -> err = " + err.stack);
logger.persist();
clearInterval(fixedTimeLoopIntervalHandle);
clearTimeout(nextLoopTimeoutHandle);
clearTimeout(checkLoopHealthHandle);
bot.enableCheckLoopHealth = false;
callBackFunction(err);
}
}
function finishProcessExecutionEvents() {
try {
@@ -958,6 +881,7 @@
}
global.SYSTEM_EVENT_HANDLER.raiseEvent(bot.sessionKey, 'Stopped')
processStopped()
callBackFunction(global.DEFAULT_OK_RESPONSE);
return;
@@ -983,6 +907,7 @@
checkLoopHealthHandle = setTimeout(checkLoopHealth, processConfig.deadWaitTime, bot.loopCounter);
}
nextLoopTimeoutHandle = setTimeout(loop, waitTime);
processHeartBeat(undefined, undefined, "Waiting " + waitTime / 1000 + " seconds for next execution.")
if (global.WRITE_LOGS_TO_FILES === 'true') {
logger.persist();
}
@@ -994,18 +919,21 @@
checkLoopHealthHandle = setTimeout(checkLoopHealth, processConfig.deadWaitTime, bot.loopCounter);
}
nextLoopTimeoutHandle = setTimeout(loop, processConfig.retryWaitTime);
processHeartBeat(undefined, undefined, "Trying to recover from some problem. Waiting " + processConfig.retryWaitTime / 1000 + " seconds for next execution.")
logger.persist();
}
break;
case 'Sleep': {
if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] run -> loop -> loopControl -> Restarting Loop in " + (processConfig.sleepWaitTime / 60000) + " minutes."); }
nextLoopTimeoutHandle = setTimeout(loop, processConfig.sleepWaitTime);
processHeartBeat(undefined, undefined, "Waiting " + processConfig.sleepWaitTime / 60000 + " minutes for next execution.")
logger.persist();
}
break;
case 'Coma': {
if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] run -> loop -> loopControl -> Restarting Loop in " + (processConfig.comaWaitTime / 3600000) + " hours."); }
nextLoopTimeoutHandle = setTimeout(loop, processConfig.comaWaitTime);
processHeartBeat(undefined, undefined, "Waiting " + processConfig.comaWaitTime / 3600000 + " hours for next execution.")
logger.persist();
}
break;
@@ -1078,10 +1006,12 @@
}
}
function processHeartBeat(processingDate) {
function processHeartBeat(processingDate, percentage, status) {
let event = {
seconds: (new Date()).getSeconds(),
processingDate: processingDate
processingDate: processingDate,
percentage: percentage,
status: status
}
global.SYSTEM_EVENT_HANDLER.raiseEvent(bot.processKey, 'Heartbeat', event)
}
+21 -11
View File
@@ -2,9 +2,9 @@
const FULL_LOG = true;
const LOG_FILE_CONTENT = false;
const MODULE_NAME = "Trading Simulation -> " + bot.SESSION.name;
const ONE_DAY_IN_MILISECONDS = 24 * 60 * 60 * 1000;
const MODULE_NAME = "Trading Simulation -> " + bot.SESSION.name;
const GMT_SECONDS = ':00.000 GMT+0000';
let thisObject = {
@@ -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
}
@@ -658,7 +658,7 @@
let key = j + '-' + 'triggerStage' + '-' + 'triggerOn' + '-' + k + '-' + m;
if (condition.javascriptCode !== undefined) {
newCondition(key, condition.javascriptCode);
newCondition(key, condition.javascriptCode, chart);
}
}
}
@@ -676,7 +676,7 @@
let key = j + '-' + 'triggerStage' + '-' + 'triggerOff' + '-' + k + '-' + m;
if (condition.javascriptCode !== undefined) {
newCondition(key, condition.javascriptCode);
newCondition(key, condition.javascriptCode, chart);
}
}
}
@@ -694,7 +694,7 @@
let key = j + '-' + 'triggerStage' + '-' + 'takePosition' + '-' + k + '-' + m;
if (condition.javascriptCode !== undefined) {
newCondition(key, condition.javascriptCode);
newCondition(key, condition.javascriptCode, chart);
}
}
}
@@ -825,7 +825,7 @@
let key = j + '-' + 'openStage' + '-' + 'initialDefinition' + '-' + 'stopLoss' + '-' + p + '-' + k + '-' + m;
if (condition.javascriptCode !== undefined) {
newCondition(key, condition.javascriptCode);
newCondition(key, condition.javascriptCode, chart);
}
}
}
@@ -891,7 +891,7 @@
let key = j + '-' + 'openStage' + '-' + 'initialDefinition' + '-' + 'takeProfit' + '-' + p + '-' + k + '-' + m;
if (condition.javascriptCode !== undefined) {
newCondition(key, condition.javascriptCode);
newCondition(key, condition.javascriptCode, chart);
}
}
}
@@ -967,7 +967,7 @@
let key = j + '-' + 'manageStage' + '-' + 'stopLoss' + '-' + p + '-' + k + '-' + m;
if (condition.javascriptCode !== undefined) {
newCondition(key, condition.javascriptCode);
newCondition(key, condition.javascriptCode, chart);
}
}
}
@@ -1034,7 +1034,7 @@
let key = j + '-' + 'manageStage' + '-' + 'takeProfit' + '-' + p + '-' + k + '-' + m;
if (condition.javascriptCode !== undefined) {
newCondition(key, condition.javascriptCode);
newCondition(key, condition.javascriptCode, chart);
}
}
}
@@ -1043,7 +1043,7 @@
}
}
function newCondition(key, node) {
function newCondition(key, node, chart) {
let condition;
let error = ''
@@ -1103,6 +1103,14 @@
maximumBalance = bot.VALUES_TO_USE.maximumBalanceB
}
if (minimumBalance === undefined) {
minimumBalance = 0
}
if (maximumBalance === undefined) {
maximumBalance = 10000000000000000
}
if (balance > minimumBalance && balance < maximumBalance) {
/*
@@ -2488,6 +2496,7 @@
}
let quotedBaseAsset = '"' + bot.VALUES_TO_USE.baseAsset + '"'
let quotedQuotedAsset = '"' + bot.VALUES_TO_USE.quotedAsset + '"'
simulationRecord = {
begin: candle.begin,
@@ -2524,6 +2533,7 @@
minimumBalanceB: bot.VALUES_TO_USE.minimumBalanceB,
maximumBalanceB: bot.VALUES_TO_USE.maximumBalanceB,
baseAsset: quotedBaseAsset,
quotedAsset: quotedQuotedAsset,
positionPeriods: positionPeriods,
positionDays: positionDays,
distanceToLastTriggerOn: distanceToLast.triggerOn,
-12
View File
@@ -1,12 +0,0 @@
version: '3'
services:
node:
image: superalgos/clone-executor:1.0.51
build:
context: .
dockerfile: ./Dockerfile
container_name: clone-executor
tty: true
stdin_open: true
command: node Run.js
restart: always
+25 -1
View File
@@ -25,6 +25,8 @@ global.CUSTOM_FAIL_RESPONSE = {
message: "Custom Message"
};
const ONE_DAY_IN_MILISECONDS = 24 * 60 * 60 * 1000;
/* Process Events */
process.on('uncaughtException', function (err) {
@@ -177,7 +179,7 @@ function bootLoader() {
}
if (global.TASK_NODE.bot.processes[processIndex].marketReference.referenceParent === undefined) {
console.log("[WARN] Task Server -> server -> bootLoader -> Market Reference without a Reference Parent. This process will not be executed. -> Process Instance = " + JSON.stringify(global.TASK_NODE.bot.processes[processIndex].marketReference));
console.log("[WARN] Task Server -> server -> bootLoader -> Market Reference without a Reference Parent. This process will not be executed. -> Process Instance = " + JSON.stringify(global.TASK_NODE.bot.processes[processIndex].marketReference) + ", bot = " + global.TASK_NODE.bot.name);
continue
}
@@ -260,3 +262,25 @@ function startRoot(processIndex) {
}
}
global.getPercentage = function (fromDate, currentDate, lastDate) {
let fromDays = Math.trunc(fromDate.valueOf() / ONE_DAY_IN_MILISECONDS)
let currentDays = Math.trunc(currentDate.valueOf() / ONE_DAY_IN_MILISECONDS)
let lastDays = Math.trunc(lastDate.valueOf() / ONE_DAY_IN_MILISECONDS)
let percentage = (currentDays - fromDays) * 100 / (lastDays - fromDays)
if ((lastDays - fromDays) === 0) {
percentage = 100
}
return percentage
}
global.areEqualDates = function (date1, date2) {
let day1Days = Math.trunc(date1.valueOf() / ONE_DAY_IN_MILISECONDS)
let day2Days = Math.trunc(date2.valueOf() / ONE_DAY_IN_MILISECONDS)
if (day1Days === day2Days) {
return true
} else {
return false
}
}