diff --git a/Context.js b/Context.js index 6b0c32b0e..0392beed2 100644 --- a/Context.js +++ b/Context.js @@ -304,10 +304,10 @@ thisObject.executionHistory = []; - if (process.env.INITIAL_BALANCE_ASSET_A === undefined || process.env.INITIAL_BALANCE_ASSET_B === undefined) { throw new Error("Environment Variables INITIAL_BALANCE_A and INITIAL_BALANCE_B cannot be undefined.") } + if (global.INITIAL_BALANCE_ASSET_A === undefined || global.INITIAL_BALANCE_ASSET_B === undefined) { throw new Error("Global Variables INITIAL_BALANCE_A and INITIAL_BALANCE_B cannot be undefined.") } - const INITIAL_BALANCE_A = Number(process.env.INITIAL_BALANCE_ASSET_A); - const INITIAL_BALANCE_B = Number(process.env.INITIAL_BALANCE_ASSET_B); + const INITIAL_BALANCE_A = Number(global.INITIAL_BALANCE_ASSET_A); + const INITIAL_BALANCE_B = Number(global.INITIAL_BALANCE_ASSET_B); thisObject.executionContext = { diff --git a/DebugLog.js b/DebugLog.js index ac46321e3..07da825e5 100644 --- a/DebugLog.js +++ b/DebugLog.js @@ -135,9 +135,7 @@ exports.newDebugLog = function newDebugLog() { if (thisObject.bot) { key = thisObject.bot.devTeam + '-' + thisObject.bot.codeName + '-' + thisObject.bot.process } - console.log(" "); - console.log(message + ' @ ' + key) - console.log(" "); + console.log('*********** ' + message + ' @ ' + key) } accumulatedLog = accumulatedLog + logLine; diff --git a/FileStorage.js b/FileStorage.js index 66d570bb4..5f5534c3d 100644 --- a/FileStorage.js +++ b/FileStorage.js @@ -24,10 +24,12 @@ exports.newFileStorage = function newFileStorage(logger) { return thisObject - function getTextFile(container, filePath, callBackFunction) { + function getTextFile(container, filePath, callBackFunction, noRetry) { logger.write(MODULE_NAME, '[INFO] FileStorage -> getTextFile -> Entering Function.') + let fileDoesNotExist = false + container = container.toLowerCase() /* Choose path for either bots or data */ @@ -50,13 +52,21 @@ exports.newFileStorage = function newFileStorage(logger) { if (err) { - if (err.code === 'ENOENT') { - let customResponse = { - result: global.CUSTOM_FAIL_RESPONSE.result, - message: 'File does not exist.' + 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. + if (noRetry === true) { + logger.write(MODULE_NAME, '[WARN] FileStorage -> getTextFile -> onFileRead -> File does not exist. Not Retrying. ') + let customResponse = { + result: global.CUSTOM_FAIL_RESPONSE.result, + message: 'File does not exist.' + } + callBackFunction(customResponse) + return + } else { + fileDoesNotExist = true + logger.write(MODULE_NAME, '[WARN] FileStorage -> getTextFile -> onFileRead -> File does not exist. Retrying. ') + setTimeout(retry, RETRY_TIME_IN_MILISECONDS) + return } - callBackFunction(customResponse) - return } logger.write(MODULE_NAME, '[WARN] FileStorage -> getTextFile -> onFileRead -> Error reading file -> err = ' + err.stack) @@ -89,9 +99,21 @@ exports.newFileStorage = function newFileStorage(logger) { getTextFile(container, filePath, callBackFunction) } else { currentRetryGetTextFile = 0 - logger.write(MODULE_NAME, '[ERROR] FileStorage -> getTextFile -> retry -> Max retries reached reading a file. Giving up.') - logger.write(MODULE_NAME, '[ERROR] FileStorage -> getTextFile -> retry -> file = ' + fileLocation) - callBackFunction(global.DEFAULT_FAIL_RESPONSE) + + if (fileDoesNotExist === true) { + logger.write(MODULE_NAME, '[WARN] FileStorage -> getTextFile -> retry -> Max retries reached reading a file. File Not Found.') + let customResponse = { + result: global.CUSTOM_FAIL_RESPONSE.result, + message: 'File does not exist.' + } + callBackFunction(customResponse) + return + } else { + logger.write(MODULE_NAME, '[ERROR] FileStorage -> getTextFile -> retry -> Max retries reached reading a file. Giving up.') + logger.write(MODULE_NAME, '[ERROR] FileStorage -> getTextFile -> retry -> file = ' + fileLocation) + callBackFunction(global.DEFAULT_FAIL_RESPONSE) + return + } } } } diff --git a/StatusDependencies.js b/StatusDependencies.js index c2bfbba48..a0eaa4374 100644 --- a/StatusDependencies.js +++ b/StatusDependencies.js @@ -34,25 +34,33 @@ let statusReportModule = STATUS_REPORT.newStatusReport(BOT, logger, UTILITIES); + logger.write(MODULE_NAME, "[INFO] initialize -> onInitilized -> Initializing Status Report # " + (i + 1)); statusReportModule.initialize(pStatusDependenciesConfig[i], pMonth, pYear, onInitilized); function onInitilized(err) { - if (err.result !== global.DEFAULT_OK_RESPONSE.result) { - logger.write(MODULE_NAME, "[ERROR] initialize -> onInitilized -> err = "+ err.stack); + logger.write(MODULE_NAME, "[INFO] initialize -> onInitilized -> Initialized Status Report # " + (i + 1)); - alreadyCalledBack = true; - callBackFunction(err); + if (err.result !== global.DEFAULT_OK_RESPONSE.result) { + if (alreadyCalledBack === false) { + logger.write(MODULE_NAME, "[ERROR] initialize -> onInitilized -> err = " + err.stack); + logger.write(MODULE_NAME, "[ERROR] initialize -> onInitilized -> err.message = " + err.message); + alreadyCalledBack = true; + callBackFunction(err); + } else { + if (FULL_LOG === true) { logger.write(MODULE_NAME, "[WARN] initialize -> Can not call back because I already did."); } + } return; } + logger.write(MODULE_NAME, "[INFO] initialize -> onInitilized -> Loading Status Report # " + (i + 1)); statusReportModule.load(onLoad); } function onLoad(err) { try { - + logger.write(MODULE_NAME, "[INFO] initialize -> onLoad -> Loaded Status Report # " + (i + 1)); statusReportModule.status = err.message; switch (err.message) { @@ -102,8 +110,10 @@ function addReport() { if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] initialize -> addReport -> Entering function."); } + logger.write(MODULE_NAME, "[INFO] initialize -> addReport -> Adding Status Report # " + (i + 1)); loadCount++; + logger.write(MODULE_NAME, "[INFO] initialize -> addReport -> Total Added = " + loadCount); let key; @@ -123,6 +133,8 @@ alreadyCalledBack = true callBackFunction(global.DEFAULT_OK_RESPONSE); return; + } else { + if (FULL_LOG === true) { logger.write(MODULE_NAME, "[WARN] initialize -> addReport -> Can not call back because I already did."); } } } } diff --git a/StatusReport.js b/StatusReport.js index aa0d89f87..1b6eb7446 100644 --- a/StatusReport.js +++ b/StatusReport.js @@ -41,6 +41,7 @@ function initialize(pOwner, pMonth, pYear, callBackFunction) { try { + if (global.LOG_CONTROL[MODULE_NAME].logInfo === true) { logger.write(MODULE_NAME, "[INFO] initialize -> Entering function."); } logger.fileName = MODULE_NAME + "." + pOwner.bot + "." + pOwner.process; @@ -56,6 +57,9 @@ } if (owner.waitUntilNextUpdate === true) { + + if (global.LOG_CONTROL[MODULE_NAME].logInfo === true) { logger.write(MODULE_NAME, "[INFO] initialize -> waitUntilNextUpdate -> Entering Code Block."); } + /* This forces this process to wait until the process that this one depends on, updates its status report. */ let extraCallerId = '' @@ -71,6 +75,7 @@ function responseCallBack(message) { if (message.result !== global.DEFAULT_OK_RESPONSE.result) { + logger.write(MODULE_NAME, "[ERROR] initialize -> responseCallBack -> message = " + JSON.stringify(message)) callBackFunction(global.DEFAULT_FAIL_RESPONSE); } else { subscriptionIdStatusReport = message.eventSubscriptionId @@ -78,6 +83,8 @@ } function eventsCallBack() { + if (global.LOG_CONTROL[MODULE_NAME].logInfo === true) { logger.write(MODULE_NAME, "[INFO] initialize -> eventsCallBack -> Entering function."); } + /* We continue the normal flow after we learn the dependent process has updated its status report. */ global.SYSTEM_EVENT_HANDLER.stopListening(key, 'Status Report Updated', subscriptionIdStatusReport) callBackFunction(global.DEFAULT_OK_RESPONSE); diff --git a/TradingEngineProcessMainLoop.js b/TradingEngineProcessMainLoop.js index bd7f4cdaf..ae56003d5 100644 --- a/TradingEngineProcessMainLoop.js +++ b/TradingEngineProcessMainLoop.js @@ -200,6 +200,10 @@ if (tradingSystem.parameters.baseAsset !== undefined) { let code try { + /* Default Value */ + global.INITIAL_BALANCE_ASSET_B = 0.001; + global.INITIAL_BALANCE_ASSET_A = 0 + code = JSON.parse(tradingSystem.parameters.baseAsset.code); if (code.name !== undefined) { @@ -212,20 +216,20 @@ if (baseAsset === 'BTC') { // NOTE: POLONIEX, the only exchange working so far, has Asset A and B inverted. We need to fix this. if (code.initialBalance !== undefined) { - process.env.INITIAL_BALANCE_ASSET_B = code.initialBalance; - process.env.INITIAL_BALANCE_ASSET_A = 0 + global.INITIAL_BALANCE_ASSET_B = code.initialBalance; + global.INITIAL_BALANCE_ASSET_A = 0 } } else { if (code.initialBalance !== undefined) { - process.env.INITIAL_BALANCE_ASSET_A = code.initialBalance; - process.env.INITIAL_BALANCE_ASSET_B = 0 + global.INITIAL_BALANCE_ASSET_A = code.initialBalance; + global.INITIAL_BALANCE_ASSET_B = 0 } } } catch (err) { global.DEFINITION.tradingSystem.parameters.baseAsset.error = err.message - process.env.INITIAL_BALANCE_ASSET_A = 0 // default - process.env.INITIAL_BALANCE_ASSET_B = 0.001 // default + global.INITIAL_BALANCE_ASSET_A = 0 // default + global.INITIAL_BALANCE_ASSET_B = 0.001 // default } } diff --git a/server.js b/server.js index 23ba18dba..0b7f12a40 100644 --- a/server.js +++ b/server.js @@ -72,9 +72,9 @@ if (global.TASK_NODE !== undefined) { } else { // I use this section to debug in standalone mode. let argument = ' {"type":"Task","name":"Runs Backtests, Fordwardtests & Live Trades ","bot":{"type":"Trading Engine","processes":[{"type":"Process","name":"Multi Period","code":{"team":"AAMasters","bot":"AAJason","process":"Multi-Period","repo":"AAJason-Trading-Engine-Bot"},"id":"4748c8c4-4d19-4076-96b2-e9c06524fbb3"}]},"id":"561bac18-fc78-464a-90c5-79fd821fc633"}' - // charly argument = '{"type":"Task","name":"Brings Trades Records from the Exchange","bot":{"type":"Sensor","name":"Charly","processes":[{"type":"Process","name":"Live Trades","code":{"team":"AAMasters","bot":"AACharly","process":"Live-Trades"},"id":"5846ebc7-1979-4a80-9cc7-94bb4b8659dc"},{"type":"Process","name":"Hole Fixing","code":{"team":"AAMasters","bot":"AACharly","process":"Hole-Fixing"},"id":"31fc4f05-75d4-419a-9fb0-73e25e856f15"}]},"id":"5bfef4dc-54c1-44db-ace6-1ab27a86746e"}' + /* charly */ argument = '{"type":"Task","name":"Brings Trades Records from the Exchange","bot":{"type":"Sensor","name":"Charly","processes":[{"type":"Process","name":"Live Trades","code":{"team":"AAMasters","bot":"AACharly","process":"Live-Trades"},"id":"5846ebc7-1979-4a80-9cc7-94bb4b8659dc"},{"type":"Process","name":"Hole Fixing","code":{"team":"AAMasters","bot":"AACharly","process":"Hole-Fixing"},"id":"31fc4f05-75d4-419a-9fb0-73e25e856f15"}]},"id":"5bfef4dc-54c1-44db-ace6-1ab27a86746e"}' // olivia argument = '{"type":"Task","name":"Generates 1 min to 24 hs Candles & Volumes","bot":{"type":"Indicator","name":"Olivia","processes":[{"type":"Process","name":"Daily","code":{"team":"AAMasters","bot":"AAOlivia","process":"Multi-Period-Daily"},"id":"68cc8e1b-e94a-477e-82d0-15ecc9f1b9e2"},{"type":"Process","name":"Market","code":{"team":"AAMasters","bot":"AAOlivia","process":"Multi-Period-Market"},"id":"e1ac5e3d-d491-4e90-baf4-d4e5b71a8b1a"}]},"id":"efe36e05-75ea-41b5-8d92-c6b27635c834"}' - argument = ' {"type":"Task","name":"Converts Trades into 1 min Candles & Volumes","bot":{"type":"Indicator","name":"Bruce","processes":[{"type":"Process","name":"New Process","code":{"team":"AAMasters","bot":"AABruce","process":"Single-Period-Daily"},"id":"e184744f-5de0-41c1-ad4c-36960f4ced90"}]},"id":"42758590-a7bd-4712-a5c9-80a3a820c5b3"}' + // bruce argument = ' {"type":"Task","name":"Converts Trades into 1 min Candles & Volumes","bot":{"type":"Indicator","name":"Bruce","processes":[{"type":"Process","name":"New Process","code":{"team":"AAMasters","bot":"AABruce","process":"Single-Period-Daily"},"id":"e184744f-5de0-41c1-ad4c-36960f4ced90"}]},"id":"42758590-a7bd-4712-a5c9-80a3a820c5b3"}' try { global.TASK_NODE = JSON.parse(argument) } catch (err) {