From 75a53352d312700dec07b94b8d9f2f80e0ed4f9e Mon Sep 17 00:00:00 2001 From: Luis Fernando Molina Date: Mon, 16 Apr 2018 17:15:37 +0200 Subject: [PATCH] datasource Module DISCONTINUED, implemented not debugged yet --- .vs/AACloud/v15/.suo | Bin 77312 -> 96768 bytes Assistant.js | 178 ++++++++++++++++++++++--------- Context.js | 9 +- Data Dependencies.js | 86 +++------------ Data Set.js | 128 ++++++++++++++++++++++ Project.njsproj | 3 + Trading Bot Process Main Loop.js | 47 ++------ this.config.json | 13 ++- 8 files changed, 298 insertions(+), 166 deletions(-) create mode 100644 Data Set.js diff --git a/.vs/AACloud/v15/.suo b/.vs/AACloud/v15/.suo index c4e15f92b9d76e07f0c8245860ff17dd66ad8f59..a77a0e353942f2b02b3382e54fee69aa0b8c7df9 100644 GIT binary patch delta 7359 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 diff --git a/Assistant.js b/Assistant.js index 1bb495387..bc57fa469 100644 --- a/Assistant.js +++ b/Assistant.js @@ -1,6 +1,7 @@ exports.newAssistant = function newAssistant(BOT, DEBUG_MODULE) { const FULL_LOG = true; + const LOG_FILE_CONTENT = false; /* @@ -11,6 +12,7 @@ const MODULE_NAME = "Assistant"; let thisObject = { + dataDependencies: undefined, initialize: initialize, putPosition: putPosition, movePosition: movePosition, @@ -33,13 +35,12 @@ let context; let exchangeAPI; - let datasource; let marketRate; return thisObject; - function initialize(pContext, pExchangeAPI, pDatasource, callBackFunction) { + function initialize(pContext, pExchangeAPI, pDataDependencies, callBackFunction) { try { @@ -49,62 +50,139 @@ context = pContext; exchangeAPI = pExchangeAPI; - datasource = pDatasource; + thisObject.dataDependencies = pDataDependencies; - /* Procedure to get the current market rate. */ + getMarketRate(); - let candleArray = datasource.candlesMap.get("01-min"); // In this version of the platform, this array will contain the las 10 candles. - let candle = candleArray[candleArray.length - 1]; // The last candle of the 10 candles array for the 1 min Time Period. + function getMarketRate() { - marketRate = candle.close; - - /* - Now we verify that this candle is not too old. Lets say no more than 2 minutes old. This could happen if the datasets for - any reason stops being updated. - */ - - if (candle.begin < bot.processDatetime.valueOf() - 2 * 60 * 1000) { - - logger.write("[ERROR] initialize -> Candles more than two minutes old. Retrying later."); - callBack(global.DEFAULT_RETRY_RESPONSE); - return; - } - - /* If we are in Exchange Simulation Mode then there is not much to do here. */ - - if (global.EXCHANGE_SIMULATION_MODE === true) { - - logger.write("[WARN] initialize -> Exchange Simulation Mode detected. -> Skipping all validations."); - callBackFunction(global.DEFAULT_OK_RESPONSE); - return; - } - - /* Procedure to validate we are in sync with the exchange. */ - - getPositionsAtExchange(onDone); - - function onDone(err) { try { - switch (err.result) { - case global.DEFAULT_OK_RESPONSE.result: { - logger.write("[INFO] initialize -> onDone -> Execution finished well. :-)"); - callBackFunction(global.DEFAULT_OK_RESPONSE); - return; - } - break; - case global.DEFAULT_RETRY_RESPONSE.result: { // Something bad happened, but if we retry in a while it might go through the next time. - logger.write("[ERROR] initialize -> onDone -> Retry Later. Requesting Execution Retry."); + if (FULL_LOG === true) { logger.write("[INFO] initialize -> getMarketRate -> Entering function."); } + + /* Procedure to get the current market rate. */ + + let key = + global.PLATFORM_CONFIG.marketRateProvider.devTeam + "-" + + global.PLATFORM_CONFIG.marketRateProvider.bot + "-" + + global.PLATFORM_CONFIG.marketRateProvider.product + "-" + + global.PLATFORM_CONFIG.marketRateProvider.dataSet + "-" + + global.PLATFORM_CONFIG.marketRateProvider.dataSetVersion; + + let dataSet = thisObject.dataDependencies.dataSets.get(key); + + let timePeriod = "01-min"; + let fileName = '' + global.MARKET.assetA + '_' + global.MARKET.assetB + '.json'; + let filePath = bot.filePathRoot + "/Output/" + global.PLATFORM_CONFIG.marketRateProvider.product + "/" + global.PLATFORM_CONFIG.marketRateProvider.dataSet + "/" + timePeriod; + + dataSet.getTextFile(filePath, fileName, onFileReceived, true); + + function onFileReceived(err, text) { + + if (FULL_LOG === true) { logger.write("[INFO] initialize -> getMarketRate -> onFileReceived -> Entering function."); } + if (LOG_FILE_CONTENT === true) { logger.write("[INFO] initialize -> getMarketRate -> onFileReceived -> text = " + text); } + + let candleArray; + + if (err.result === global.DEFAULT_OK_RESPONSE.result) { + try { + candleArray = JSON.parse(text); + + let lastCandleRecord = candleArray[candleArray.length - 1]; // The last candle contains at its close value the market rate. + + let candle = { + open: lastCandleRecord[2], + close: lastCandleRecord[3], + min: lastCandleRecord[0], + max: lastCandleRecord[1], + begin: lastCandleRecord[4], + end: lastCandleRecord[5] + }; + + marketRate = candle.close; + + /* + Now we verify that this candle is not too old. Lets say no more than 2 minutes old. This could happen if the datasets for + any reason stops being updated. + */ + + if (candle.begin < bot.processDatetime.valueOf() - 2 * 60 * 1000) { + + logger.write("[ERROR] initialize -> Candles more than two minutes old. Retrying later."); + callBack(global.DEFAULT_RETRY_RESPONSE); + return; + } + + /* If we are in Exchange Simulation Mode then there is not much to do here. */ + + if (global.EXCHANGE_SIMULATION_MODE === true) { + + logger.write("[WARN] initialize -> Exchange Simulation Mode detected. -> Skipping all validations."); + callBackFunction(global.DEFAULT_OK_RESPONSE); + return; + + } else { + + validateExchangeSyncronicity(); + return; + } + + + } catch (err) { + logger.write("[ERROR] initialize -> getMarketRate -> onFileReceived -> err = " + err.message); + logger.write("[ERROR] initialize -> getMarketRate -> onFileReceived -> Asuming this is a temporary situation. Requesting a Retry."); + callBackFunction(global.DEFAULT_RETRY_RESPONSE); + } + } else { + logger.write("[ERROR] initialize -> getMarketRate -> onFileReceived -> err = " + err.message); callBackFunction(err); - return; } - break; - case global.DEFAULT_FAIL_RESPONSE.result: { // This is an unexpected exception that we do not know how to handle. - logger.write("[ERROR] initialize -> onDone -> Operation Failed. Aborting the process."); - callBackFunction(err); - return; + } + + } catch (err) { + logger.write("[ERROR] initialize -> getMarketRate -> err = " + err.message); + callBackFunction(global.DEFAULT_FAIL_RESPONSE); + } + } + + function validateExchangeSyncronicity() { + + try { + + if (FULL_LOG === true) { logger.write("[INFO] initialize -> validateExchangeSyncronicity -> Entering function."); } + + /* Procedure to validate we are in sync with the exchange. */ + + getPositionsAtExchange(onDone); + + function onDone(err) { + try { + + switch (err.result) { + case global.DEFAULT_OK_RESPONSE.result: { + logger.write("[INFO] initialize -> validateExchangeSyncronicity -> onDone -> Execution finished well. :-)"); + callBackFunction(global.DEFAULT_OK_RESPONSE); + return; + } + break; + case global.DEFAULT_RETRY_RESPONSE.result: { // Something bad happened, but if we retry in a while it might go through the next time. + logger.write("[ERROR] initialize -> validateExchangeSyncronicity -> onDone -> Retry Later. Requesting Execution Retry."); + callBackFunction(err); + return; + } + break; + case global.DEFAULT_FAIL_RESPONSE.result: { // This is an unexpected exception that we do not know how to handle. + logger.write("[ERROR] initialize -> validateExchangeSyncronicity -> onDone -> Operation Failed. Aborting the process."); + callBackFunction(err); + return; + } + break; + } + + } catch (err) { + logger.write("[ERROR] initialize -> validateExchangeSyncronicity -> onDone -> err = " + err.message); + callBackFunction(global.DEFAULT_FAIL_RESPONSE); } - break; } } catch (err) { diff --git a/Context.js b/Context.js index 242eca792..fc42f878b 100644 --- a/Context.js +++ b/Context.js @@ -76,17 +76,18 @@ let cloudStorage = BLOB_STORAGE.newBlobStorage(bot); - let dependencies; + let statusDependencies; return thisObject; - function initialize(pDependencies, callBackFunction) { + function initialize(pStatusDependencies, callBackFunction) { try { if (FULL_LOG === true) { logger.write("[INFO] initialize -> Entering function."); } - dependencies = pDependencies; + statusDependencies = pStatusDependencies; + /* Here we get the positions the bot did and that are recorded at the bot storage account. We will use them through out the rest @@ -153,7 +154,7 @@ let key = bot.devTeam + "-" + bot.codeName + "-" + bot.process + "-" + bot.dataSetVersion; - statusReportModule = dependencies.statusReports.get(key); + statusReportModule = statusDependencies.statusReports.get(key); thisObject.statusReport = statusReportModule.file; if (thisObject.statusReport.lastExecution !== undefined) { diff --git a/Data Dependencies.js b/Data Dependencies.js index 8de8f4b7b..2a7435b99 100644 --- a/Data Dependencies.js +++ b/Data Dependencies.js @@ -1,4 +1,4 @@ -exports.newDataDependencies = function newDataDependencies(BOT, DEBUG_MODULE, STATUS_REPORT, BLOB_STORAGE, UTILITIES) { +exports.newDataDependencies = function newDataDependencies(BOT, DEBUG_MODULE, DATA_SET, BLOB_STORAGE, UTILITIES) { const FULL_LOG = true; const LOG_FILE_CONTENT = false; @@ -6,13 +6,13 @@ const MODULE_NAME = "Data Dependencies"; let thisObject = { - statusReports: new Map(), + dataSets: new Map(), initialize: initialize, keys: [] }; let bot = BOT; - let ownerBot; // This is the bot owner of the Status Report. Only owners can save the report and override the existing content. + let ownerBot; // This is the bot owner of the Data Set. const logger = DEBUG_MODULE.newDebugLog(); logger.fileName = MODULE_NAME; @@ -20,7 +20,7 @@ return thisObject; - function initialize(pDataDependenciesConfig, pMonth, pYear, callBackFunction) { + function initialize(pDataDependenciesConfig, callBackFunction) { try { @@ -28,17 +28,17 @@ /* - For each dependency declared at the bot config, we will initialize the status report, and load it as part of this initialization process. + For each dependency declared at the bot config, we will initialize a DataSet as part of this initialization process. */ let alreadyCalledBack = false; - let loadCount = 0; + let addCount = 0; for (let i = 0; i < pDataDependenciesConfig.length; i++) { - let statusReportModule = STATUS_REPORT.newStatusReport(BOT, DEBUG_MODULE, BLOB_STORAGE, UTILITIES); + let dataSetModule = DATA_SET.newDataSet(BOT, DEBUG_MODULE, BLOB_STORAGE, UTILITIES); - statusReportModule.initialize(pDataDependenciesConfig[i], pMonth, pYear, onInitilized); + dataSetModule.initialize(pDataDependenciesConfig[i], onInitilized); function onInitilized(err) { @@ -50,78 +50,25 @@ return; } - statusReportModule.load(onLoad); + addDataSet(); } - function onLoad(err) { + function addDataSet() { - try { + if (FULL_LOG === true) { logger.write("[INFO] initialize -> addDataSet -> Entering function."); } - statusReportModule.status = err.message; - - switch (err.message) { - case global.DEFAULT_OK_RESPONSE.message: { - logger.write("[INFO] initialize -> onLoad -> Execution finished well. -> bot = " + pDataDependenciesConfig[i].bot); - logger.write("[INFO] initialize -> onLoad -> Execution finished well. -> process = " + pDataDependenciesConfig[i].process); - - addReport(); - return; - } - case "Status Report was never created.": { - - logger.write("[WARN] initialize -> onLoad -> err.message = " + err.message); - logger.write("[WARN] initialize -> onLoad -> Report Not Found. -> bot = " + pDataDependenciesConfig[i].bot); - logger.write("[WARN] initialize -> onLoad -> Report Not Found. -> process = " + pDataDependenciesConfig[i].process); - addReport(); - return; - } - - case "Status Report is corrupt.": { - - logger.write("[WARN] initialize -> onLoad -> err.message = " + err.message); - logger.write("[WARN] initialize -> onLoad -> Report Not Found. -> bot = " + pDataDependenciesConfig[i].bot); - logger.write("[WARN] initialize -> onLoad -> Report Not Found. -> process = " + pDataDependenciesConfig[i].process); - addReport(); - return; - } - default: - { - logger.write("[ERROR] initialize -> onLoad -> Operation Failed."); - - if (alreadyCalledBack === false) { - alreadyCalledBack = true; - callBackFunction(err); - } - return; - } - } - } - catch (err) { - logger.write("[ERROR] initialize -> onLoad -> err = " + err.message); - callBackFunction(global.DEFAULT_FAIL_RESPONSE); - } - } - - function addReport() { - - if (FULL_LOG === true) { logger.write("[INFO] initialize -> addReport -> Entering function."); } - - loadCount++; + addCount++; let key; - if (pDataDependenciesConfig[i].dataSetSection === "Month") { - key = pDataDependenciesConfig[i].devTeam + "-" + pDataDependenciesConfig[i].bot + "-" + pDataDependenciesConfig[i].process + "-" + pDataDependenciesConfig[i].dataSetVersion + "-" + pYear + "-" + pMonth; - } else { - key = pDataDependenciesConfig[i].devTeam + "-" + pDataDependenciesConfig[i].bot + "-" + pDataDependenciesConfig[i].process + "-" + pDataDependenciesConfig[i].dataSetVersion; - } + key = pDataDependenciesConfig[i].devTeam + "-" + pDataDependenciesConfig[i].bot + "-" + pDataDependenciesConfig[i].product + "-" + pDataDependenciesConfig[i].dataSet + "-" + pDataDependenciesConfig[i].dataSetVersion; thisObject.keys.push(key); - thisObject.statusReports.set(key, statusReportModule); + thisObject.dataSets.set(key, dataSetModule); - if (FULL_LOG === true) { logger.write("[INFO] initialize -> addReport -> Report added to Map. -> key = " + key); } + if (FULL_LOG === true) { logger.write("[INFO] initialize -> addDataSet -> DataSet added to Map. -> key = " + key); } - if (loadCount === pDataDependenciesConfig.length) { + if (addCount === pDataDependenciesConfig.length) { if (alreadyCalledBack === false) { callBackFunction(global.DEFAULT_OK_RESPONSE); return; @@ -135,5 +82,4 @@ callBackFunction(global.DEFAULT_FAIL_RESPONSE); } } - }; \ No newline at end of file diff --git a/Data Set.js b/Data Set.js new file mode 100644 index 000000000..00de4af72 --- /dev/null +++ b/Data Set.js @@ -0,0 +1,128 @@ +exports.newDataSet = function newDataSet(BOT, DEBUG_MODULE, BLOB_STORAGE, UTILITIES) { + + const FULL_LOG = true; + const LOG_FILE_CONTENT = false; + + const MODULE_NAME = "Data Set"; + + let thisObject = { + file: undefined, // Here we have the JSON object representing the file content. + initialize: initialize, + getTextFile: getTextFile, + createTextFile: createTextFile + }; + + let bot = BOT; + let dependencyConfig; + + const logger = DEBUG_MODULE.newDebugLog(); + logger.bot = bot; + + /* Utilities needed. */ + + let utilities = UTILITIES.newUtilities(bot); + + /* Storage account to be used here. */ + + let cloudStorage = BLOB_STORAGE.newBlobStorage(bot); + + return thisObject; + + function initialize(pDependencyConfig, callBackFunction) { + + try { + + logger.fileName = MODULE_NAME + "." + pDependencyConfig.bot + "." + pDependencyConfig.product + "." + pDependencyConfig.dataSet; + + dependencyConfig = pDependencyConfig; + + if (FULL_LOG === true) { logger.write("[INFO] initialize -> Entering function."); } + + initializeStorage(); + + function initializeStorage() { + + cloudStorage.initialize(dependencyConfig, onInizialized); + + function onInizialized(err) { + + if (err.result === global.DEFAULT_OK_RESPONSE.result) { + + if (FULL_LOG === true) { logger.write("[INFO] initialize -> initializeStorage -> onInizialized -> Entering function."); } + callBackFunction(global.DEFAULT_OK_RESPONSE); + + } else { + logger.write("[ERROR] initialize -> initializeStorage -> onInizialized -> err = " + err.message); + callBackFunction(err); + } + } + } + } catch (err) { + logger.write("[ERROR] initialize -> err = " + err.message); + callBackFunction(global.DEFAULT_FAIL_RESPONSE); + } + } + + function getTextFile(pFolderPath, pFileName, callBackFunction) { + + try { + + if (FULL_LOG === true) { logger.write("[INFO] getTextFile -> Entering function."); } + if (FULL_LOG === true) { logger.write("[INFO] getTextFile -> pFolderPath = " + pFolderPath); } + if (FULL_LOG === true) { logger.write("[INFO] getTextFile -> pFileName = " + pFileName); } + + cloudStorage.getTextFile(pFolderPath, pFileName, onFileReceived); + + function onFileReceived(err, text) { + + if (FULL_LOG === true) { logger.write("[INFO] getTextFile -> onFileReceived -> Entering function."); } + + callBackFunction(err, text); + + } + } + catch (err) { + logger.write("[ERROR] 'getTextFile' -> err = " + err.message); + callBackFunction(global.DEFAULT_FAIL_RESPONSE); + } + } + + function createTextFile(pFolderPath, pFileName, pFileContent, callBackFunction) { + + try { + + if (FULL_LOG === true) { logger.write("[INFO] createTextFile -> Entering function."); } + if (FULL_LOG === true) { logger.write("[INFO] createTextFile -> pFolderPath = " + pFolderPath); } + if (FULL_LOG === true) { logger.write("[INFO] createTextFile -> pFileName = " + pFileName); } + + let ownerId = dependencyConfig.devTeam + "-" + dependencyConfig.bot + "-" + dependencyConfig.botVersion.major + "-" + dependencyConfig.botVersion.minor + "-" + dependencyConfig.dataSetVersion; + let botId = bot.devTeam + "-" + bot.codeName + "-" + bot.version.major + "-" + bot.version.minor + "-" + bot.dataSetVersion; + + if (ownerId !== botId) { + + let customErr = { + result: global.CUSTOM_FAIL_RESPONSE.result, + message: "Only bots owners of a Data Set can create text files on them." + }; + logger.write("[ERROR] save -> customErr = " + customErr.message); + callBackFunction(customErr); + return; + } + + cloudStorage.createTextFile(pFolderPath, pFileName, pFileContent, onFileCreated); + + function onFileCreated(err) { + + if (FULL_LOG === true) { logger.write("[INFO] createTextFile -> onFileCreated -> Entering function."); } + + callBackFunction(err); + + } + } + catch (err) { + logger.write("[ERROR] 'createTextFile' -> err = " + err.message); + callBackFunction(global.DEFAULT_FAIL_RESPONSE); + } + } + +}; \ No newline at end of file diff --git a/Project.njsproj b/Project.njsproj index 96598de65..a798d6c02 100644 --- a/Project.njsproj +++ b/Project.njsproj @@ -29,6 +29,9 @@ Code + + Code + Code diff --git a/Trading Bot Process Main Loop.js b/Trading Bot Process Main Loop.js index a4b9de001..8ebfba91f 100644 --- a/Trading Bot Process Main Loop.js +++ b/Trading Bot Process Main Loop.js @@ -71,6 +71,7 @@ const DATASOURCE = require(ROOT_DIR + 'Datasource'); const ASSISTANT = require(ROOT_DIR + 'Assistant'); const STATUS_REPORT = require(ROOT_DIR + 'Status Report'); + const DATA_SET = require(ROOT_DIR + 'Data Set'); const STATUS_DEPENDENCIES = require(ROOT_DIR + 'Status Dependencies'); const DATA_DEPENDENCIES = require(ROOT_DIR + 'Data Dependencies'); @@ -81,7 +82,6 @@ /* We will prepare first the infraestructure needed for the bot to run. There are 3 modules we need to sucessfullly initialize first. */ let context; - let datasource; let exchangeAPI; let assistant; let userBot; @@ -127,9 +127,9 @@ if (FULL_LOG === true) { logger.write("[INFO] run -> loop -> initializeDataDependencies -> Entering function."); } - dataDependencies = DATA_DEPENDENCIES.newDataDependencies(bot, DEBUG_MODULE, STATUS_REPORT, BLOB_STORAGE, UTILITIES); + dataDependencies = DATA_DEPENDENCIES.newDataDependencies(bot, DEBUG_MODULE, DATA_SET, BLOB_STORAGE, UTILITIES); - dataDependencies.initialize(processConfig.dataDependencies, undefined, undefined, onInizialized); + dataDependencies.initialize(processConfig.dataDependencies, onInizialized); function onInizialized(err) { @@ -166,7 +166,7 @@ switch (err.result) { case global.DEFAULT_OK_RESPONSE.result: { logger.write("[INFO] run -> loop -> initializeContext -> onInizialized > Execution finished well. :-)"); - initializeDatasource(); + initializeExchangeAPI(); return; } case global.DEFAULT_RETRY_RESPONSE.result: { // Something bad happened, but if we retry in a while it might go through the next time. @@ -184,36 +184,6 @@ } } - function initializeDatasource() { - - if (FULL_LOG === true) { logger.write("[INFO] run -> loop -> initializeDatasource -> Entering function."); } - - datasource = DATASOURCE.newDatasource(bot, DEBUG_MODULE, BLOB_STORAGE, UTILITIES); - datasource.initialize(onInizialized); - - function onInizialized(err) { - - switch (err.result) { - case global.DEFAULT_OK_RESPONSE.result: { - logger.write("[INFO] run -> loop -> initializeDatasource -> onInizialized > Execution finished well. :-)"); - initializeExchangeAPI(); - 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("[ERROR] run -> loop -> initializeDatasource -> onInizialized > 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. - logger.write("[ERROR] run -> loop -> initializeDatasource -> onInizialized > Operation Failed. Aborting the process."); - callBackFunction(err); - return; - } - } - } - } - function initializeExchangeAPI() { if (FULL_LOG === true) { logger.write("[INFO] run -> loop -> initializeExchangeAPI -> Entering function."); } @@ -249,7 +219,7 @@ if (FULL_LOG === true) { logger.write("[INFO] run -> loop -> initializeAssistant -> Entering function."); } assistant = ASSISTANT.newAssistant(bot, DEBUG_MODULE); - assistant.initialize(context, exchangeAPI, datasource, onInizialized); + assistant.initialize(context, exchangeAPI, dataDependencies, onInizialized); function onInizialized(err) { @@ -280,12 +250,7 @@ usertBot = USER_BOT_MODULE.newUserBot(bot, DEBUG_MODULE, COMMONS_MODULE); - let platform = { - datasource: datasource, - assistant: assistant - }; - - usertBot.initialize(platform, onInizialized); + usertBot.initialize(assistant, onInizialized); function onInizialized(err) { diff --git a/this.config.json b/this.config.json index 91b0f2026..c96f6c4ec 100644 --- a/this.config.json +++ b/this.config.json @@ -45,5 +45,16 @@ "stopGracefully": "false", "exchangeSimulationMode": "false", "storageConnStringFolder": "Production", - "maxLogLoops": 5 + "maxLogLoops": 5, + "marketRateProvider": { + "devTeam": "AAMasters", + "bot": "AAOlivia", + "botVersion": { + "major": 1, + "minor": 0 + }, + "product": "Candles", + "dataSet": "Multi-Period-Daily", + "dataSetVersion": "dataSet.V1" + } } \ No newline at end of file