Merge pull request #145 from AAMasters/develop
Release to Master Branch
This commit is contained in:
21 files changed
+282
-416
No files matched your search
+2
-2
@@ -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
@@ -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
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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
@@ -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)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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
@@ -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
@@ -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
@@ -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);
|
||||
|
||||
@@ -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
@@ -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)
|
||||
|
||||
@@ -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
@@ -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
@@ -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
|
||||
|
||||
@@ -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
@@ -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
@@ -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);
|
||||
|
||||
}
|
||||
|
||||
@@ -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
@@ -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,
|
||||
|
||||
@@ -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,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
|
||||
}
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user