Cleaning Learning
This commit is contained in:
1 parent
0bb9208d66
commit
dc8ef4d010
3 files changed
+2
-1288
No files matched your search
@@ -25,641 +25,10 @@ exports.newLearningBot = function (processIndex, bot, parentLogger) {
|
||||
return thisObject;
|
||||
|
||||
function initialize(pProcessConfig, callBackFunction) {
|
||||
/* This function is exactly the same in the 3 modules representing the 2 different bot types loops. */
|
||||
try {
|
||||
processConfig = pProcessConfig;
|
||||
if (bot.repo === undefined) {
|
||||
/* The code of the bot is defined at the UI. No need to load a file with the code. */
|
||||
session.initialize(processConfig, callBackFunction)
|
||||
}
|
||||
|
||||
} catch (err) {
|
||||
parentLogger.write(MODULE_NAME, "[ERROR] initialize -> err = " + err.stack);
|
||||
callBackFunction(TS.projects.superalgos.globals.standardResponses.DEFAULT_FAIL_RESPONSE);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
function run(callBackFunction) {
|
||||
try {
|
||||
/* Some initial values*/
|
||||
TS.projects.superalgos.globals.processVariables.VARIABLES_BY_PROCESS_INDEX_MAP.get(processIndex).IS_SESSION_STOPPING = true;
|
||||
if (FULL_LOG === true) { parentLogger.write(MODULE_NAME, '[IMPORTANT] run -> Stopping the Session now. ') }
|
||||
|
||||
loop();
|
||||
|
||||
function loop() {
|
||||
try {
|
||||
TS.projects.superalgos.functionLibraries.processFunctions.processHeartBeat(processIndex, undefined, undefined, "Running...")
|
||||
function pad(str, max) {
|
||||
str = str.toString();
|
||||
return str.length < max ? pad(" " + str, max) : str;
|
||||
}
|
||||
|
||||
/* For each loop we want to create a new log file. */
|
||||
if (logger !== undefined) {
|
||||
logger.finalize()
|
||||
}
|
||||
logger = DEBUG_MODULE.newDebugLog(processIndex);
|
||||
TS.projects.superalgos.globals.taskVariables.LOGGER_MAP.set(MODULE_NAME + TS.projects.superalgos.globals.taskConstants.TASK_NODE.bot.processes[processIndex].id, logger)
|
||||
logger.bot = bot;
|
||||
logger.initialize();
|
||||
|
||||
TS.projects.superalgos.globals.processVariables.VARIABLES_BY_PROCESS_INDEX_MAP.get(processIndex).MAIN_LOOP_COUNTER++;
|
||||
bot.loopStartTime = new Date().valueOf();
|
||||
|
||||
let nextWaitTime;
|
||||
|
||||
/* We tell the UI that we are running. */
|
||||
TS.projects.superalgos.functionLibraries.processFunctions.processHeartBeat(processIndex, undefined, undefined, "Running...")
|
||||
|
||||
/* We define here all the modules that the rest of the infraestructure, including the bots themselves can consume. */
|
||||
const UTILITIES = require(TS.projects.superalgos.globals.nodeJSConstants.REQUIRE_ROOT_DIR + 'CloudUtilities');
|
||||
const STATUS_REPORT = require(TS.projects.superalgos.globals.nodeJSConstants.REQUIRE_ROOT_DIR + 'StatusReport');
|
||||
const STATUS_DEPENDENCIES = require(TS.projects.superalgos.globals.nodeJSConstants.REQUIRE_ROOT_DIR + 'StatusDependencies');
|
||||
const DATA_DEPENDENCIES = require(TS.projects.superalgos.globals.nodeJSConstants.REQUIRE_ROOT_DIR + 'DataDependencies');
|
||||
const DATA_SET = require(TS.projects.superalgos.globals.nodeJSConstants.REQUIRE_ROOT_DIR + 'DataSet');
|
||||
const PROCESS_EXECUTION_EVENTS = require(TS.projects.superalgos.globals.nodeJSConstants.REQUIRE_ROOT_DIR + 'ProcessExecutionEvents');
|
||||
const PROCESS_OUTPUT = require(TS.projects.superalgos.globals.nodeJSConstants.REQUIRE_ROOT_DIR + 'ProcessOutput');
|
||||
|
||||
/* We define the datetime for the process that we are running now. This will be the official processing time for both the infraestructure and the bot. */
|
||||
bot.processDatetime = new Date(); // This will be considered the process date and time, so as to have it consistenly all over the execution.
|
||||
|
||||
/* Main Loop Console Logging */
|
||||
logger.newMainLoop()
|
||||
|
||||
/* Checking if we need to need to emit any event */
|
||||
if (bot.SESSION_STATUS === 'Idle' && TS.projects.superalgos.globals.processVariables.VARIABLES_BY_PROCESS_INDEX_MAP.get(processIndex).IS_SESSION_STOPPING === false) {
|
||||
bot.SESSION_STATUS = 'Running'
|
||||
}
|
||||
|
||||
if (bot.SESSION_STATUS === 'Running' && TS.projects.superalgos.globals.processVariables.VARIABLES_BY_PROCESS_INDEX_MAP.get(processIndex).IS_SESSION_STOPPING === true) {
|
||||
bot.SESSION_STATUS = 'Stopped'
|
||||
}
|
||||
|
||||
TS.projects.superalgos.functionLibraries.sessionFunctions.emitSessionStatus(bot.SESSION_STATUS, TS.projects.superalgos.globals.processVariables.VARIABLES_BY_PROCESS_INDEX_MAP.get(processIndex).SESSION_KEY)
|
||||
|
||||
/* Checking if we should process this loop or not.*/
|
||||
if (TS.projects.superalgos.globals.processVariables.VARIABLES_BY_PROCESS_INDEX_MAP.get(processIndex).IS_SESSION_STOPPING === true) {
|
||||
|
||||
if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] run -> loop -> Waiting for " + TS.projects.superalgos.globals.taskConstants.TASK_NODE.bot.processes[processIndex].session.type + " " + TS.projects.superalgos.globals.taskConstants.TASK_NODE.bot.processes[processIndex].session.name + " to be run."); }
|
||||
|
||||
console.log(new Date().toISOString() + " " + pad(TS.projects.superalgos.globals.taskConstants.TASK_NODE.bot.processes[processIndex].referenceParent.parentNode.config.codeName, 20) + " " + pad(TS.projects.superalgos.globals.taskConstants.TASK_NODE.bot.processes[processIndex].referenceParent.config.codeName, 30)
|
||||
+ " Waiting for " + TS.projects.superalgos.globals.taskConstants.TASK_NODE.bot.processes[processIndex].session.type + " " + TS.projects.superalgos.globals.taskConstants.TASK_NODE.bot.processes[processIndex].session.name + " to be run. ");
|
||||
|
||||
nextWaitTime = 'Waiting for Session';
|
||||
loopControl(nextWaitTime);
|
||||
return
|
||||
}
|
||||
|
||||
/* We will prepare first the infraestructure needed for the bot to run. There are 3 modules we need to sucessfullly initialize first. */
|
||||
|
||||
let processExecutionEvents
|
||||
let userBot;
|
||||
let processFramework;
|
||||
let statusDependencies;
|
||||
let dataDependencies;
|
||||
|
||||
initializeProcessExecutionEvents();
|
||||
|
||||
function initializeProcessExecutionEvents() {
|
||||
try {
|
||||
processExecutionEvents = PROCESS_EXECUTION_EVENTS.newProcessExecutionEvents(processIndex, bot, logger)
|
||||
processExecutionEvents.initialize(processConfig, onInizialized);
|
||||
|
||||
function onInizialized(err) {
|
||||
try {
|
||||
switch (err.result) {
|
||||
case TS.projects.superalgos.globals.standardResponses.DEFAULT_OK_RESPONSE.result: {
|
||||
logger.write(MODULE_NAME, "[INFO] run -> loop -> initializeProcessExecutionEvents -> onInizialized -> Execution finished well.");
|
||||
startProcessExecutionEvents()
|
||||
return;
|
||||
}
|
||||
case TS.projects.superalgos.globals.standardResponses.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 -> initializeProcessExecutionEvents -> onInizialized -> Retry Later. Requesting Execution Retry.");
|
||||
nextWaitTime = 'Retry';
|
||||
loopControl(nextWaitTime);
|
||||
return;
|
||||
}
|
||||
case TS.projects.superalgos.globals.standardResponses.DEFAULT_FAIL_RESPONSE.result: { // This is an unexpected exception that we do not know how to handle.
|
||||
logger.write(MODULE_NAME, "[ERROR] run -> loop -> initializeProcessExecutionEvents -> onInizialized -> Operation Failed. Aborting the process.");
|
||||
global.unexpectedError = err.message
|
||||
processStopped()
|
||||
return
|
||||
}
|
||||
default: {
|
||||
logger.write(MODULE_NAME, "[ERROR] run -> loop -> initializeProcessExecutionEvents -> onInizialized -> Unhandled err.result received. -> err.result = " + err.result);
|
||||
logger.write(MODULE_NAME, "[ERROR] run -> loop -> initializeProcessExecutionEvents -> onInizialized -> Unhandled err.result received. -> err = " + err.message);
|
||||
global.unexpectedError = err.message
|
||||
processStopped()
|
||||
return
|
||||
}
|
||||
}
|
||||
} catch (err) {
|
||||
logger.write(MODULE_NAME, "[ERROR] run -> loop -> initializeProcessExecutionEvents -> onInizialized -> err = " + err.stack);
|
||||
global.unexpectedError = err.message
|
||||
processStopped()
|
||||
return
|
||||
}
|
||||
}
|
||||
} catch (err) {
|
||||
logger.write(MODULE_NAME, "[ERROR] run -> loop -> initializeProcessExecutionEvents -> err = " + err.stack);
|
||||
global.unexpectedError = err.message
|
||||
processStopped()
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
function startProcessExecutionEvents() {
|
||||
try {
|
||||
processExecutionEvents.start(onStarted);
|
||||
|
||||
function onStarted(err) {
|
||||
try {
|
||||
switch (err.result) {
|
||||
case TS.projects.superalgos.globals.standardResponses.DEFAULT_OK_RESPONSE.result: {
|
||||
logger.write(MODULE_NAME, "[INFO] run -> loop -> startProcessExecutionEvents -> onStarted -> Execution finished well.");
|
||||
|
||||
if (TS.projects.superalgos.globals.taskVariables.IS_TASK_STOPPING === true) {
|
||||
loopControl()
|
||||
return
|
||||
}
|
||||
|
||||
initializeStatusDependencies();
|
||||
return;
|
||||
}
|
||||
case TS.projects.superalgos.globals.standardResponses.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 -> startProcessExecutionEvents -> onStarted -> Retry Later. Requesting Execution Retry.");
|
||||
nextWaitTime = 'Retry';
|
||||
loopControl(nextWaitTime);
|
||||
return;
|
||||
}
|
||||
case TS.projects.superalgos.globals.standardResponses.DEFAULT_FAIL_RESPONSE.result: { // This is an unexpected exception that we do not know how to handle.
|
||||
logger.write(MODULE_NAME, "[ERROR] run -> loop -> startProcessExecutionEvents -> onStarted -> Operation Failed. Aborting the process.");
|
||||
global.unexpectedError = err.message
|
||||
processStopped()
|
||||
return
|
||||
}
|
||||
default: {
|
||||
logger.write(MODULE_NAME, "[ERROR] run -> loop -> startProcessExecutionEvents -> onStarted -> Unhandled err.result received. -> err.result = " + err.result);
|
||||
logger.write(MODULE_NAME, "[ERROR] run -> loop -> startProcessExecutionEvents -> onStarted -> Unhandled err.result received. -> err = " + err.message);
|
||||
global.unexpectedError = err.message
|
||||
processStopped()
|
||||
return
|
||||
}
|
||||
}
|
||||
} catch (err) {
|
||||
logger.write(MODULE_NAME, "[ERROR] run -> loop -> startProcessExecutionEvents -> onStarted -> err = " + err.stack);
|
||||
global.unexpectedError = err.message
|
||||
processStopped()
|
||||
return
|
||||
}
|
||||
}
|
||||
} catch (err) {
|
||||
logger.write(MODULE_NAME, "[ERROR] run -> loop -> startProcessExecutionEvents -> err = " + err.stack);
|
||||
global.unexpectedError = err.message
|
||||
processStopped()
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
function initializeStatusDependencies() {
|
||||
try {
|
||||
statusDependencies = STATUS_DEPENDENCIES.newStatusDependencies(processIndex, bot, logger, STATUS_REPORT, UTILITIES, PROCESS_OUTPUT);
|
||||
statusDependencies.initialize(onInizialized);
|
||||
|
||||
function onInizialized(err) {
|
||||
try {
|
||||
switch (err.result) {
|
||||
case TS.projects.superalgos.globals.standardResponses.DEFAULT_OK_RESPONSE.result: {
|
||||
logger.write(MODULE_NAME, "[INFO] run -> loop -> initializeStatusDependencies -> onInizialized -> Execution finished well.");
|
||||
initializeDataDependencies();
|
||||
return;
|
||||
}
|
||||
case TS.projects.superalgos.globals.standardResponses.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 -> initializeStatusDependencies -> onInizialized -> Retry Later. Requesting Execution Retry.");
|
||||
nextWaitTime = 'Retry';
|
||||
loopControl(nextWaitTime);
|
||||
return;
|
||||
}
|
||||
case TS.projects.superalgos.globals.standardResponses.DEFAULT_FAIL_RESPONSE.result: { // This is an unexpected exception that we do not know how to handle.
|
||||
logger.write(MODULE_NAME, "[ERROR] run -> loop -> initializeStatusDependencies -> onInizialized -> Operation Failed. Aborting the process.");
|
||||
global.unexpectedError = err.message
|
||||
processStopped()
|
||||
return
|
||||
}
|
||||
default: {
|
||||
logger.write(MODULE_NAME, "[ERROR] run -> loop -> initializeStatusDependencies -> onInizialized -> Unhandled err.result received. -> err.result = " + err.result);
|
||||
logger.write(MODULE_NAME, "[ERROR] run -> loop -> initializeStatusDependencies -> onInizialized -> Unhandled err.result received. -> err = " + err.message);
|
||||
global.unexpectedError = err.message
|
||||
processStopped()
|
||||
return
|
||||
}
|
||||
}
|
||||
} catch (err) {
|
||||
logger.write(MODULE_NAME, "[ERROR] run -> loop -> initializeStatusDependencies -> onInizialized -> err = " + err.stack);
|
||||
global.unexpectedError = err.message
|
||||
processStopped()
|
||||
return
|
||||
}
|
||||
}
|
||||
} catch (err) {
|
||||
logger.write(MODULE_NAME, "[ERROR] run -> loop -> initializeStatusDependencies -> err = " + err.stack);
|
||||
global.unexpectedError = err.message
|
||||
processStopped()
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
function initializeDataDependencies() {
|
||||
try {
|
||||
dataDependencies = DATA_DEPENDENCIES.newDataDependencies(processIndex, bot, logger, DATA_SET);
|
||||
dataDependencies.initialize(onInizialized);
|
||||
|
||||
function onInizialized(err) {
|
||||
try {
|
||||
switch (err.result) {
|
||||
case TS.projects.superalgos.globals.standardResponses.DEFAULT_OK_RESPONSE.result: {
|
||||
if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] run -> loop -> initializeDataDependencies -> onInizialized -> Execution finished well."); }
|
||||
switch (processConfig.framework.name) {
|
||||
case 'Low-Frequency-Trading-Process': {
|
||||
processFramework = TRADING_PROCESS_MODULE.newMachineLearningProcess(bot, logger, UTILITIES);
|
||||
intitializeProcessFramework();
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
logger.write(MODULE_NAME, "[ERROR] run -> loop -> initializeDataDependencies -> onInizialized -> Process Framework not Supported.");
|
||||
logger.write(MODULE_NAME, "[ERROR] run -> loop -> initializeDataDependencies -> onInizialized -> Process Framework Name = " + processConfig.framework.name);
|
||||
global.unexpectedError = err.message
|
||||
processStopped()
|
||||
return
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
case TS.projects.superalgos.globals.standardResponses.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 -> initializeDataDependencies -> onInizialized -> Retry Later. Requesting Execution Retry.");
|
||||
nextWaitTime = 'Retry';
|
||||
loopControl(nextWaitTime);
|
||||
return;
|
||||
}
|
||||
case TS.projects.superalgos.globals.standardResponses.DEFAULT_FAIL_RESPONSE.result: { // This is an unexpected exception that we do not know how to handle.
|
||||
logger.write(MODULE_NAME, "[ERROR] run -> loop -> initializeDataDependencies -> onInizialized -> Operation Failed. Aborting the process.");
|
||||
global.unexpectedError = err.message
|
||||
processStopped()
|
||||
return
|
||||
}
|
||||
default: {
|
||||
logger.write(MODULE_NAME, "[ERROR] run -> loop -> initializeDataDependencies -> onInizialized -> Unhandled err.result received. -> err.result = " + err.result);
|
||||
logger.write(MODULE_NAME, "[ERROR] run -> loop -> initializeDataDependencies -> onInizialized -> Unhandled err.result received. -> err = " + err.message);
|
||||
global.unexpectedError = err.message
|
||||
processStopped()
|
||||
return
|
||||
}
|
||||
}
|
||||
} catch (err) {
|
||||
logger.write(MODULE_NAME, "[ERROR] run -> loop -> initializeDataDependencies -> onInizialized -> err = " + err.stack);
|
||||
global.unexpectedError = err.message
|
||||
processStopped()
|
||||
return
|
||||
}
|
||||
}
|
||||
} catch (err) {
|
||||
logger.write(MODULE_NAME, "[ERROR] run -> loop -> initializeDataDependencies -> err = " + err.stack);
|
||||
global.unexpectedError = err.message
|
||||
processStopped()
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
function intitializeProcessFramework() {
|
||||
try {
|
||||
processFramework.initialize(processConfig, statusDependencies, dataDependencies, onInizialized);
|
||||
|
||||
function onInizialized(err) {
|
||||
try {
|
||||
switch (err.result) {
|
||||
case TS.projects.superalgos.globals.standardResponses.DEFAULT_OK_RESPONSE.result: {
|
||||
logger.write(MODULE_NAME, "[INFO] run -> loop -> intitializeProcessFramework -> onInizialized -> Execution finished well.");
|
||||
startProcessFramework();
|
||||
return;
|
||||
}
|
||||
case TS.projects.superalgos.globals.standardResponses.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 -> intitializeProcessFramework -> onInizialized -> Retry Later. Requesting Execution Retry.");
|
||||
nextWaitTime = 'Retry';
|
||||
loopControl(nextWaitTime);
|
||||
return;
|
||||
}
|
||||
case TS.projects.superalgos.globals.standardResponses.DEFAULT_FAIL_RESPONSE.result: { // This is an unexpected exception that we do not know how to handle.
|
||||
logger.write(MODULE_NAME, "[ERROR] run -> loop -> intitializeProcessFramework -> onInizialized -> Operation Failed. Aborting the process.");
|
||||
global.unexpectedError = err.message
|
||||
processStopped()
|
||||
return
|
||||
}
|
||||
case TS.projects.superalgos.globals.standardResponses.CUSTOM_OK_RESPONSE.result: {
|
||||
logger.write(MODULE_NAME, "[ERROR] run -> loop -> intitializeProcessFramework -> onInizialized > Unhandled custom response received. -> err = " + err.message);
|
||||
global.unexpectedError = err.message
|
||||
processStopped()
|
||||
return
|
||||
}
|
||||
default: {
|
||||
logger.write(MODULE_NAME, "[ERROR] run -> loop -> intitializeProcessFramework -> onInizialized -> Unhandled err.result received. -> err.result = " + err.result);
|
||||
logger.write(MODULE_NAME, "[ERROR] run -> loop -> intitializeProcessFramework -> onInizialized -> Unhandled err.result received. -> err = " + err.message);
|
||||
global.unexpectedError = err.message
|
||||
processStopped()
|
||||
return
|
||||
}
|
||||
}
|
||||
} catch (err) {
|
||||
logger.write(MODULE_NAME, "[ERROR] run -> loop -> intitializeProcessFramework -> onInizialized -> err = " + err.stack);
|
||||
global.unexpectedError = err.message
|
||||
processStopped()
|
||||
return
|
||||
}
|
||||
}
|
||||
} catch (err) {
|
||||
logger.write(MODULE_NAME, "[ERROR] run -> loop -> intitializeProcessFramework -> err = " + err.stack);
|
||||
global.unexpectedError = err.message
|
||||
processStopped()
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
function startProcessFramework() {
|
||||
try {
|
||||
processFramework.start(onFinished);
|
||||
|
||||
function onFinished(err) {
|
||||
try {
|
||||
processFramework.finalize()
|
||||
processFramework = undefined
|
||||
dataDependencies.finalize()
|
||||
dataDependencies = undefined
|
||||
statusDependencies.finalize()
|
||||
statusDependencies = undefined
|
||||
|
||||
switch (err.result) {
|
||||
case TS.projects.superalgos.globals.standardResponses.DEFAULT_OK_RESPONSE.result: {
|
||||
logger.write(MODULE_NAME, "[INFO] run -> loop -> startProcessFramework -> onFinished -> Execution finished well.");
|
||||
nextWaitTime = 'Normal';
|
||||
finishProcessExecutionEvents()
|
||||
return;
|
||||
}
|
||||
case TS.projects.superalgos.globals.standardResponses.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 -> startProcessFramework -> onFinished -> Retry Later. Requesting Execution Retry.");
|
||||
nextWaitTime = 'Retry';
|
||||
loopControl(nextWaitTime);
|
||||
return;
|
||||
}
|
||||
case TS.projects.superalgos.globals.standardResponses.DEFAULT_FAIL_RESPONSE.result: { // This is an unexpected exception that we do not know how to handle.
|
||||
logger.write(MODULE_NAME, "[ERROR] run -> loop -> startProcessFramework -> onFinished -> Operation Failed. Aborting the process.");
|
||||
global.unexpectedError = err.message
|
||||
processStopped()
|
||||
return
|
||||
}
|
||||
case TS.projects.superalgos.globals.standardResponses.CUSTOM_OK_RESPONSE.result: {
|
||||
|
||||
switch (err.message) {
|
||||
case "Dependency does not exist.": {
|
||||
logger.write(MODULE_NAME, "[WARN] run -> loop -> startProcessFramework -> onFinished -> Dependency does not exist. This Loop will go to sleep.");
|
||||
nextWaitTime = 'Sleep';
|
||||
loopControl(nextWaitTime);
|
||||
return;
|
||||
}
|
||||
case "Dependency not ready.": {
|
||||
logger.write(MODULE_NAME, "[WARN] run -> loop -> startProcessFramework -> onFinished -> Dependency not ready. This Loop will go to sleep.");
|
||||
nextWaitTime = 'Sleep';
|
||||
loopControl(nextWaitTime);
|
||||
return;
|
||||
}
|
||||
default: {
|
||||
logger.write(MODULE_NAME, "[ERROR] run -> loop -> startProcessFramework -> onFinished -> Unhandled custom response received. -> err = " + err.message);
|
||||
global.unexpectedError = err.message
|
||||
processStopped()
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
default: {
|
||||
logger.write(MODULE_NAME, "[ERROR] run -> loop -> startProcessFramework -> onFinished -> Unhandled err.result received. -> err.result = " + err.result);
|
||||
logger.write(MODULE_NAME, "[ERROR] run -> loop -> startProcessFramework -> onFinished -> Unhandled err.result received. -> err = " + err.message);
|
||||
global.unexpectedError = err.message
|
||||
processStopped()
|
||||
return
|
||||
}
|
||||
}
|
||||
} catch (err) {
|
||||
logger.write(MODULE_NAME, "[ERROR] run -> loop -> startProcessFramework -> onFinished -> err = " + err.stack);
|
||||
global.unexpectedError = err.message
|
||||
processStopped()
|
||||
return
|
||||
}
|
||||
}
|
||||
} catch (err) {
|
||||
logger.write(MODULE_NAME, "[ERROR] run -> loop -> startProcessFramework -> err = " + err.stack);
|
||||
global.unexpectedError = err.message
|
||||
processStopped()
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
function finishProcessExecutionEvents() {
|
||||
try {
|
||||
processExecutionEvents.finish(onFinished);
|
||||
|
||||
function onFinished(err) {
|
||||
try {
|
||||
processExecutionEvents.finalize()
|
||||
processExecutionEvents = undefined
|
||||
|
||||
switch (err.result) {
|
||||
case TS.projects.superalgos.globals.standardResponses.DEFAULT_OK_RESPONSE.result: {
|
||||
logger.write(MODULE_NAME, "[INFO] run -> loop -> finishProcessExecutionEvents -> onFinished -> Execution finished well.");
|
||||
nextWaitTime = 'Normal';
|
||||
loopControl(nextWaitTime);
|
||||
return;
|
||||
}
|
||||
case TS.projects.superalgos.globals.standardResponses.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 -> finishProcessExecutionEvents -> onFinished -> Retry Later. Requesting Execution Retry.");
|
||||
nextWaitTime = 'Retry';
|
||||
loopControl(nextWaitTime);
|
||||
return;
|
||||
}
|
||||
case TS.projects.superalgos.globals.standardResponses.DEFAULT_FAIL_RESPONSE.result: { // This is an unexpected exception that we do not know how to handle.
|
||||
logger.write(MODULE_NAME, "[ERROR] run -> loop -> finishProcessExecutionEvents -> onFinished -> Operation Failed. Aborting the process.");
|
||||
global.unexpectedError = err.message
|
||||
processStopped()
|
||||
return
|
||||
}
|
||||
default: {
|
||||
logger.write(MODULE_NAME, "[ERROR] run -> loop -> finishProcessExecutionEvents -> onFinished -> Unhandled err.result received. -> err.result = " + err.result);
|
||||
logger.write(MODULE_NAME, "[ERROR] run -> loop -> finishProcessExecutionEvents -> onFinished -> Unhandled err.result received. -> err = " + err.message);
|
||||
global.unexpectedError = err.message
|
||||
processStopped()
|
||||
return
|
||||
}
|
||||
}
|
||||
} catch (err) {
|
||||
logger.write(MODULE_NAME, "[ERROR] run -> loop -> finishProcessExecutionEvents -> onFinished -> err = " + err.stack);
|
||||
global.unexpectedError = err.message
|
||||
processStopped()
|
||||
return
|
||||
}
|
||||
}
|
||||
} catch (err) {
|
||||
logger.write(MODULE_NAME, "[ERROR] run -> loop -> finishProcessExecutionEvents -> err = " + err.stack);
|
||||
global.unexpectedError = err.message
|
||||
processStopped()
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
function loopControl(nextWaitTime) {
|
||||
if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] run -> loop -> loopControl -> nextWaitTime = " + nextWaitTime); }
|
||||
|
||||
/* We show we reached the end of the loop. */
|
||||
TS.projects.superalgos.functionLibraries.processFunctions.processHeartBeat(processIndex, undefined, undefined, "Running...")
|
||||
|
||||
/* Here we check if we must stop the loop gracefully. */
|
||||
shallWeStop(onStop, onContinue);
|
||||
|
||||
function onStop() {
|
||||
if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] run -> loop -> loopControl -> onStop -> Stopping the Loop Gracefully. See you next time!"); }
|
||||
logger.persist();
|
||||
|
||||
global.EVENT_SERVER_CLIENT_MODULE.raiseEvent(TS.projects.superalgos.globals.processVariables.VARIABLES_BY_PROCESS_INDEX_MAP.get(processIndex).SESSION_KEY, 'Stopped')
|
||||
processStopped()
|
||||
return;
|
||||
}
|
||||
|
||||
function onContinue() {
|
||||
/* Indicator bots are going to be executed after a configured period of time after the last execution ended. This is to avoid overlapping executions. */
|
||||
switch (nextWaitTime) {
|
||||
case 'Waiting for Session': {
|
||||
let waitTime = processConfig.sessionRunWaitTime
|
||||
nextLoopTimeoutHandle = setTimeout(loop, waitTime);
|
||||
let waitingTime = waitTime / 1000 / 60
|
||||
let label = 'minute/s'
|
||||
if (waitingTime < 1) {
|
||||
waitingTime = waitTime / 1000
|
||||
label = 'seconds'
|
||||
}
|
||||
TS.projects.superalgos.functionLibraries.processFunctions.processHeartBeat(processIndex, undefined, undefined, "Waiting " + waitingTime + " " + label + " for " + TS.projects.superalgos.globals.taskConstants.TASK_NODE.bot.processes[processIndex].session.type + " " + TS.projects.superalgos.globals.taskConstants.TASK_NODE.bot.processes[processIndex].session.name + " to be run. ")
|
||||
logger.persist();
|
||||
}
|
||||
break
|
||||
case 'Normal': {
|
||||
let waitTime
|
||||
if (processConfig.waitsForExecutionFinishedEvent === true) {
|
||||
waitTime = 0
|
||||
} else {
|
||||
switch (bot.LEARNING_SESSION.type) {
|
||||
case 'Live Trading Session': {
|
||||
waitTime = bot.LEARNING_SESSION.learningParameters.timeFrame.config.value
|
||||
break
|
||||
}
|
||||
case 'Fordward Tessting Session': {
|
||||
waitTime = bot.LEARNING_SESSION.learningParameters.timeFrame.config.value
|
||||
break
|
||||
}
|
||||
case 'Paper Trading Session': {
|
||||
waitTime = bot.LEARNING_SESSION.learningParameters.timeFrame.config.value
|
||||
break
|
||||
}
|
||||
case 'Backtesting Session': {
|
||||
waitTime = 0
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] run -> loop -> loopControl -> Restarting Loop in " + (waitTime / 1000 / 60) + " minute/s."); }
|
||||
nextLoopTimeoutHandle = setTimeout(loop, waitTime);
|
||||
let waitingTime = waitTime / 1000 / 60
|
||||
let label = 'minute/s'
|
||||
if (waitingTime < 1) {
|
||||
waitingTime = waitTime / 1000
|
||||
label = 'seconds'
|
||||
}
|
||||
TS.projects.superalgos.functionLibraries.processFunctions.processHeartBeat(processIndex, undefined, undefined, "Waiting " + waitingTime + " " + label + " for next execution.")
|
||||
logger.persist();
|
||||
}
|
||||
break;
|
||||
case 'Retry': {
|
||||
if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] run -> loop -> loopControl -> Restarting Loop in " + (processConfig.retryWaitTime / 1000) + " seconds."); }
|
||||
nextLoopTimeoutHandle = setTimeout(loop, processConfig.retryWaitTime);
|
||||
TS.projects.superalgos.functionLibraries.processFunctions.processHeartBeat(processIndex, 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);
|
||||
TS.projects.superalgos.functionLibraries.processFunctions.processHeartBeat(processIndex, 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);
|
||||
TS.projects.superalgos.functionLibraries.processFunctions.processHeartBeat(processIndex, undefined, undefined, "Waiting " + processConfig.comaWaitTime / 3600000 + " hours for next execution.")
|
||||
logger.persist();
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function shallWeStop(stopCallBack, continueCallBack) {
|
||||
try {
|
||||
/* IMPORTANT: This function is exactly the same on the 3 modules. */
|
||||
if (!TS.projects.superalgos.globals.taskVariables.IS_TASK_STOPPING) {
|
||||
continueCallBack();
|
||||
} else {
|
||||
stopCallBack();
|
||||
}
|
||||
} catch (err) {
|
||||
logger.write(MODULE_NAME, "[ERROR] run -> loop -> shallWeStop -> err = " + err.stack);
|
||||
global.unexpectedError = err.message
|
||||
processStopped()
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
} catch (err) {
|
||||
parentLogger.write(MODULE_NAME, "[ERROR] run -> loop -> err = " + err.stack);
|
||||
global.unexpectedError = err.message
|
||||
processStopped()
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
function processStopped() {
|
||||
if (global.unexpectedError !== undefined) {
|
||||
TS.projects.superalgos.functionLibraries.processFunctions.processError(TS.projects.superalgos.globals.processVariables.VARIABLES_BY_PROCESS_INDEX_MAP.get(processIndex).PROCESS_KEY, undefined, "An unexpected error caused the Process to stop.")
|
||||
} else {
|
||||
global.EVENT_SERVER_CLIENT_MODULE.raiseEvent(TS.projects.superalgos.globals.processVariables.VARIABLES_BY_PROCESS_INDEX_MAP.get(processIndex).PROCESS_KEY, 'Stopped')
|
||||
}
|
||||
sessionStopped()
|
||||
logger.persist();
|
||||
clearTimeout(nextLoopTimeoutHandle);
|
||||
if (global.unexpectedError !== undefined) {
|
||||
callBackFunction(TS.projects.superalgos.globals.standardResponses.DEFAULT_FAIL_RESPONSE)
|
||||
} else {
|
||||
callBackFunction(TS.projects.superalgos.globals.standardResponses.DEFAULT_OK_RESPONSE)
|
||||
}
|
||||
}
|
||||
|
||||
function sessionStopped() {
|
||||
if (bot.SESSION_STATUS === 'Running') {
|
||||
global.EVENT_SERVER_CLIENT_MODULE.raiseEvent(TS.projects.superalgos.globals.processVariables.VARIABLES_BY_PROCESS_INDEX_MAP.get(processIndex).SESSION_KEY, 'Stopped')
|
||||
bot.SESSION_STATUS = 'Stopped'
|
||||
}
|
||||
}
|
||||
|
||||
} catch (err) {
|
||||
parentLogger.write(MODULE_NAME, "[ERROR] run -> err = " + err.stack);
|
||||
clearTimeout(nextLoopTimeoutHandle);
|
||||
callBackFunction(TS.projects.superalgos.globals.standardResponses.DEFAULT_FAIL_RESPONSE);
|
||||
}
|
||||
}
|
||||
};
|
||||
@@ -1,218 +1,22 @@
|
||||
exports.newMarkovDecisionProcess = function newMarkovDecisionProcess(bot, logger) {
|
||||
/*
|
||||
We call the Trading Engine to the data structure that is needed in order to exevute the
|
||||
trading protocol with the specific rules defined at the Trading System.
|
||||
*/
|
||||
|
||||
const MODULE_NAME = 'Markov Decision Process'
|
||||
let thisObject = {
|
||||
mantain: mantain,
|
||||
reset: reset,
|
||||
getNodeById: getNodeById,
|
||||
cloneValues: cloneValues,
|
||||
setCurrentCandle: setCurrentCandle,
|
||||
setCurrentCycle: setCurrentCycle,
|
||||
initializeNode: initializeNode,
|
||||
initialize: initialize,
|
||||
finalize: finalize
|
||||
}
|
||||
|
||||
let tradingEngine
|
||||
let sessionParameters
|
||||
let nodesMap = new Map()
|
||||
|
||||
return thisObject
|
||||
|
||||
function initialize() {
|
||||
|
||||
tradingEngine = TS.projects.superalgos.globals.processVariables.VARIABLES_BY_PROCESS_INDEX_MAP.get(processIndex).SIMULATION_STATE.tradingEngine
|
||||
sessionParameters = bot.LEARNING_SESSION.learningParameters
|
||||
|
||||
initializeNodeMap(tradingEngine)
|
||||
|
||||
if (TS.projects.superalgos.globals.processVariables.VARIABLES_BY_PROCESS_INDEX_MAP.get(processIndex).IS_SESSION_FIRST_LOOP === true) {
|
||||
/*
|
||||
Here we will go through all the nodes in the Trading Engine hiriarchy and
|
||||
apply the initial value to the value property when needed
|
||||
*/
|
||||
initializeNode(tradingEngine)
|
||||
}
|
||||
}
|
||||
|
||||
function finalize() {
|
||||
tradingEngine = undefined
|
||||
sessionParameters = undefined
|
||||
nodesMap = undefined
|
||||
}
|
||||
|
||||
function mantain() {
|
||||
}
|
||||
|
||||
function reset() {
|
||||
|
||||
}
|
||||
|
||||
function getNodeById(NodeId) {
|
||||
return nodesMap.get(NodeId)
|
||||
}
|
||||
|
||||
function setCurrentCandle(candle) {
|
||||
tradingEngine.current.episode.candle.begin.value = candle.begin
|
||||
tradingEngine.current.episode.candle.end.value = candle.end
|
||||
tradingEngine.current.episode.candle.open.value = candle.open
|
||||
tradingEngine.current.episode.candle.close.value = candle.close
|
||||
tradingEngine.current.episode.candle.min.value = candle.min
|
||||
tradingEngine.current.episode.candle.max.value = candle.max
|
||||
}
|
||||
|
||||
function setCurrentCycle(cycle) {
|
||||
tradingEngine.current.episode.cycle.value = cycle
|
||||
tradingEngine.current.episode.cycle.lastBegin.value = tradingEngine.current.episode.cycle.begin.value
|
||||
tradingEngine.current.episode.cycle.lastEnd.value = tradingEngine.current.episode.cycle.end.value
|
||||
switch (cycle) {
|
||||
case 'First': {
|
||||
tradingEngine.current.episode.cycle.begin.value =
|
||||
tradingEngine.current.episode.candle.begin.value +
|
||||
sessionParameters.timeFrame.config.value
|
||||
tradingEngine.current.episode.cycle.end.value =
|
||||
tradingEngine.current.episode.candle.begin.value +
|
||||
sessionParameters.timeFrame.config.value +
|
||||
sessionParameters.timeFrame.config.value / 2 - 1
|
||||
break
|
||||
}
|
||||
case 'Second': {
|
||||
tradingEngine.current.episode.cycle.begin.value =
|
||||
tradingEngine.current.episode.candle.begin.value +
|
||||
sessionParameters.timeFrame.config.value +
|
||||
sessionParameters.timeFrame.config.value / 2
|
||||
tradingEngine.current.episode.cycle.end.value =
|
||||
tradingEngine.current.episode.candle.begin.value +
|
||||
sessionParameters.timeFrame.config.value +
|
||||
sessionParameters.timeFrame.config.value * 4 / 4 - 1
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function cloneValues(originNode, destinationNode) {
|
||||
if (originNode === undefined) { return }
|
||||
if (destinationNode === undefined) { return }
|
||||
|
||||
/* Here copy the node value */
|
||||
destinationNode.value = originNode.value
|
||||
|
||||
/* Now we go down through all the children of the origin node, assuming the destination node has the same children structure*/
|
||||
let nodeDefinition = TS.projects.superalgos.globals.taskConstants.APP_SCHEMA_MAP.get(originNode.project + '-' + originNode.type)
|
||||
if (nodeDefinition === undefined) { return }
|
||||
|
||||
if (nodeDefinition.properties !== undefined) {
|
||||
let previousPropertyName // Since there are cases where there are many properties with the same name,because they can hold nodes of different types but only one at the time, we have to avoind counting each property of those as individual children.
|
||||
for (let i = 0; i < nodeDefinition.properties.length; i++) {
|
||||
let property = nodeDefinition.properties[i]
|
||||
|
||||
switch (property.type) {
|
||||
case 'node': {
|
||||
if (property.name !== previousPropertyName) {
|
||||
if (originNode[property.name] !== undefined && destinationNode[property.name] !== undefined) {
|
||||
cloneValues(originNode[property.name], destinationNode[property.name])
|
||||
}
|
||||
previousPropertyName = property.name
|
||||
}
|
||||
break
|
||||
}
|
||||
case 'array': {
|
||||
if (originNode[property.name] !== undefined && destinationNode[property.name] !== undefined) {
|
||||
let originNodePropertyArray = originNode[property.name]
|
||||
let destinationNodePropertyArray = destinationNode[property.name]
|
||||
for (let m = 0; m < originNodePropertyArray.length; m++) {
|
||||
cloneValues(originNodePropertyArray[m], destinationNodePropertyArray[m])
|
||||
}
|
||||
}
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function initializeNodeMap(node) {
|
||||
if (node === undefined) { return }
|
||||
/* Add to Node Map */
|
||||
nodesMap.set(node.id, node)
|
||||
|
||||
/* Now we go down through all this node children */
|
||||
let nodeDefinition = TS.projects.superalgos.globals.taskConstants.APP_SCHEMA_MAP.get(node.project + '-' + node.type)
|
||||
if (nodeDefinition === undefined) { return }
|
||||
|
||||
if (nodeDefinition.properties !== undefined) {
|
||||
let previousPropertyName // Since there are cases where there are many properties with the same name,because they can hold nodes of different types but only one at the time, we have to avoind counting each property of those as individual children.
|
||||
for (let i = 0; i < nodeDefinition.properties.length; i++) {
|
||||
let property = nodeDefinition.properties[i]
|
||||
|
||||
switch (property.type) {
|
||||
case 'node': {
|
||||
if (property.name !== previousPropertyName) {
|
||||
if (node[property.name] !== undefined) {
|
||||
initializeNodeMap(node[property.name])
|
||||
}
|
||||
previousPropertyName = property.name
|
||||
}
|
||||
break
|
||||
}
|
||||
case 'array': {
|
||||
if (node[property.name] !== undefined) {
|
||||
let nodePropertyArray = node[property.name]
|
||||
for (let m = 0; m < nodePropertyArray.length; m++) {
|
||||
initializeNodeMap(nodePropertyArray[m])
|
||||
}
|
||||
}
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function initializeNode(node) {
|
||||
if (node === undefined) { return }
|
||||
|
||||
/* Here we initialize the node value */
|
||||
if (node.config !== undefined) {
|
||||
if (node.config.initialValue !== undefined) {
|
||||
node.value = node.config.initialValue
|
||||
}
|
||||
}
|
||||
|
||||
/* Now we go down through all this node children */
|
||||
let nodeDefinition = TS.projects.superalgos.globals.taskConstants.APP_SCHEMA_MAP.get(node.project + '-' + node.type)
|
||||
if (nodeDefinition === undefined) { return }
|
||||
|
||||
if (nodeDefinition.properties !== undefined) {
|
||||
let previousPropertyName // Since there are cases where there are many properties with the same name,because they can hold nodes of different types but only one at the time, we have to avoind counting each property of those as individual children.
|
||||
for (let i = 0; i < nodeDefinition.properties.length; i++) {
|
||||
let property = nodeDefinition.properties[i]
|
||||
|
||||
switch (property.type) {
|
||||
case 'node': {
|
||||
if (property.name !== previousPropertyName) {
|
||||
if (node[property.name] !== undefined) {
|
||||
initializeNode(node[property.name])
|
||||
}
|
||||
previousPropertyName = property.name
|
||||
}
|
||||
break
|
||||
}
|
||||
case 'array': {
|
||||
if (node[property.name] !== undefined) {
|
||||
let nodePropertyArray = node[property.name]
|
||||
for (let m = 0; m < nodePropertyArray.length; m++) {
|
||||
initializeNode(nodePropertyArray[m])
|
||||
}
|
||||
}
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user