From 30abba7acd881b818c97981997d98b6574c11e05 Mon Sep 17 00:00:00 2001 From: Luis Fernando Molina Date: Mon, 18 Feb 2019 14:51:50 +0100 Subject: [PATCH 01/40] Initial commit --- .gitattributes | 2 + .gitignore | 11 + AAChris-Indicator-Bot.sln | 25 + Commons.js | 66 ++ LICENSE | 24 + Multi-Period-Daily/User.Bot.js | 1637 +++++++++++++++++++++++++++++++ Multi-Period-Market/User.Bot.js | 460 +++++++++ Project.njsproj | 91 ++ README.md | 7 + Tom.png | Bin 0 -> 16438 bytes package.json | 13 + this.bot.config.json | 154 +++ 12 files changed, 2490 insertions(+) create mode 100644 .gitattributes create mode 100644 .gitignore create mode 100644 AAChris-Indicator-Bot.sln create mode 100644 Commons.js create mode 100644 LICENSE create mode 100644 Multi-Period-Daily/User.Bot.js create mode 100644 Multi-Period-Market/User.Bot.js create mode 100644 Project.njsproj create mode 100644 README.md create mode 100644 Tom.png create mode 100644 package.json create mode 100644 this.bot.config.json diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 000000000..dfe077042 --- /dev/null +++ b/.gitattributes @@ -0,0 +1,2 @@ +# Auto detect text files and perform LF normalization +* text=auto diff --git a/.gitignore b/.gitignore new file mode 100644 index 000000000..82c487bdd --- /dev/null +++ b/.gitignore @@ -0,0 +1,11 @@ + +.vs/* +obj/* + +bin/* + +*.config +*.log +*.cache +node_modules/* + diff --git a/AAChris-Indicator-Bot.sln b/AAChris-Indicator-Bot.sln new file mode 100644 index 000000000..da30e179e --- /dev/null +++ b/AAChris-Indicator-Bot.sln @@ -0,0 +1,25 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio 15 +VisualStudioVersion = 15.0.27130.2027 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{9092AA53-FB77-4645-B42D-1CCCA6BD08BD}") = "Project", "Project.njsproj", "{AA2901BC-8F81-40F0-A402-5CA79A3F22AD}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {AA2901BC-8F81-40F0-A402-5CA79A3F22AD}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {AA2901BC-8F81-40F0-A402-5CA79A3F22AD}.Debug|Any CPU.Build.0 = Debug|Any CPU + {AA2901BC-8F81-40F0-A402-5CA79A3F22AD}.Release|Any CPU.ActiveCfg = Release|Any CPU + {AA2901BC-8F81-40F0-A402-5CA79A3F22AD}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {B4BDAEAF-E863-458A-87C1-CC6D8C490784} + EndGlobalSection +EndGlobal diff --git a/Commons.js b/Commons.js new file mode 100644 index 000000000..6f4edfe55 --- /dev/null +++ b/Commons.js @@ -0,0 +1,66 @@ +exports.newCommons = function newCommons(bot, logger, UTILITIES) { + + const FULL_LOG = true; + const LOG_FILE_CONTENT = false; + + const MODULE_NAME = "Commons"; + + const GMT_SECONDS = ':00.000 GMT+0000'; + + let thisObject = { + initializeStorage: initializeStorage + }; + + let utilities = UTILITIES.newCloudUtilities(bot, logger); + + return thisObject; + + function initializeStorage(oliviaStorage, chrisStorage, callBackFunction) { + + try { + + if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] initializeStorage -> Entering function."); } + + initializetomStorage(); + + function initializetomStorage() { + + chrisStorage.initialize(bot.devTeam, onBruceInizialized); + + function onBruceInizialized(err) { + + if (err.result === global.DEFAULT_OK_RESPONSE.result) { + + initializeOliviaStorage(); + + } else { + logger.write(MODULE_NAME, "[ERROR] initializeStorage -> initializetomStorage -> onBruceInizialized -> err = " + err.message); + callBackFunction(err); + } + } + } + + function initializeOliviaStorage() { + + oliviaStorage.initialize(bot.devTeam, onOliviaInizialized); + + function onOliviaInizialized(err) { + + if (err.result === global.DEFAULT_OK_RESPONSE.result) { + + callBackFunction(global.DEFAULT_OK_RESPONSE); + + } else { + logger.write(MODULE_NAME, "[ERROR] initializeStorage -> initializeOliviaStorage -> onOliviaInizialized -> err = " + err.message); + callBackFunction(err); + } + } + } + } + catch (err) { + logger.write(MODULE_NAME, "[ERROR] initializeStorage -> err = " + err.message); + callBackFunction(global.DEFAULT_FAIL_RESPONSE); + } + } + +}; \ No newline at end of file diff --git a/LICENSE b/LICENSE new file mode 100644 index 000000000..10e295746 --- /dev/null +++ b/LICENSE @@ -0,0 +1,24 @@ +Financial Beings License + +Collective Copyright by the Advanced Algos Community + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software including without limitation the rights to use, copy, modify, +merge, publish, distribute and sublicense copies of the Software, and to permit +persons to whom the Software is furnished to do so, subject to the following +conditions: + + 1. Using, copying, modifying, publishing, distributing and sublicensing rights + are restricted to the Advanced Algos Platform, meaning the rights granted can + only be exercised through the Advanced Algos Service. + + 2. The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, +INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT +HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/Multi-Period-Daily/User.Bot.js b/Multi-Period-Daily/User.Bot.js new file mode 100644 index 000000000..4a84367a2 --- /dev/null +++ b/Multi-Period-Daily/User.Bot.js @@ -0,0 +1,1637 @@ +exports.newUserBot = function newUserBot(bot, logger, COMMONS, UTILITIES, BLOB_STORAGE, FILE_STORAGE) { + + const FULL_LOG = true; + const INTENSIVE_LOG = false; + const LOG_FILE_CONTENT = false; + + const GMT_SECONDS = ':00.000 GMT+0000'; + const GMT_MILI_SECONDS = '.000 GMT+0000'; + const ONE_DAY_IN_MILISECONDS = 24 * 60 * 60 * 1000; + + const MODULE_NAME = "User Bot"; + + const EXCHANGE_NAME = "Poloniex"; + + const TRADES_FOLDER_NAME = "Trades"; + + const CANDLES_FOLDER_NAME = "Candles"; + const CANDLE_STAIRS_FOLDER_NAME = "Candle-Stairs"; + + const VOLUMES_FOLDER_NAME = "Volumes"; + const VOLUME_STAIRS_FOLDER_NAME = "Volume-Stairs"; + + const commons = COMMONS.newCommons(bot, logger, UTILITIES); + + thisObject = { + initialize: initialize, + start: start + }; + + let oliviaStorage = BLOB_STORAGE.newBlobStorage(bot, logger); + let tomStorage = BLOB_STORAGE.newBlobStorage(bot, logger); + + let utilities = UTILITIES.newCloudUtilities(bot, logger); + + let statusDependencies; + + return thisObject; + + function initialize(pStatusDependencies, pMonth, pYear, callBackFunction) { + + try { + + logger.fileName = MODULE_NAME; + logger.initialize(); + + if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] initialize -> Entering function."); } + + statusDependencies = pStatusDependencies; + + commons.initializeStorage(oliviaStorage, tomStorage, onInizialized); + + function onInizialized(err) { + + if (err.result === global.DEFAULT_OK_RESPONSE.result) { + + if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] initialize -> onInizialized -> Initialization Succeed."); } + callBackFunction(global.DEFAULT_OK_RESPONSE); + + } else { + logger.write(MODULE_NAME, "[ERROR] initialize -> onInizialized -> err = " + err.message); + callBackFunction(err); + } + } + + } catch (err) { + logger.write(MODULE_NAME, "[ERROR] initialize -> err = " + err.message); + callBackFunction(global.DEFAULT_FAIL_RESPONSE); + } + } + + /* + + This process is going to do the following: + + Read the candles and volumes from Olivia and produce for each market two files with candles stairs and volumes stairs respectively. + + */ + + function start(callBackFunction) { + + try { + + if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] start -> Entering function."); } + + /* One of the challenges of this process is that each imput file contains one day of candles. So if a stair spans more than one day + then we dont want to break the stais in two pieces. What we do is that we read to candles files at the time and record at the current + date all stairs of the day plus the ones thas spans to the second day without bigining at the second day. Then when we process the next + day, we must remember where the last stairs of each type endded, so as not to create overlapping stairs in the current day. */ + + let market = global.MARKET; + + /* Context Variables */ + + let contextVariables = { + lastCandleFile: undefined, // Datetime of the last file files sucessfully produced by this process. + firstTradeFile: undefined, // Datetime of the first trade file in the whole market history. + maxCandleFile: undefined // Datetime of the last file available to be used as an input of this process. + }; + + let previousDay; // Holds the date of the previous day relative to the processing date. + let processDate; // Holds the processing date. + + getContextVariables(); + + function getContextVariables() { + + try { + + if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] start -> getContextVariables -> Entering function."); } + + let thisReport; + let reportKey; + let statusReport; + + /* We look first for Charly in order to get when the market starts. */ + + reportKey = "AAMasters" + "-" + "AACharly" + "-" + "Poloniex-Historic-Trades" + "-" + "dataSet.V1"; + if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] start -> getContextVariables -> reportKey = " + reportKey); } + + statusReport = statusDependencies.statusReports.get(reportKey); + + if (statusReport === undefined) { // This means the status report does not exist, that could happen for instance at the begining of a month. + logger.write(MODULE_NAME, "[WARN] start -> getContextVariables -> Status Report does not exist. Retrying Later. "); + callBackFunction(global.DEFAULT_RETRY_RESPONSE); + return; + } + + if (statusReport.status === "Status Report is corrupt.") { + logger.write(MODULE_NAME, "[ERROR] start -> getContextVariables -> Can not continue because dependecy Status Report is corrupt. "); + callBackFunction(global.DEFAULT_RETRY_RESPONSE); + return; + } + + thisReport = statusDependencies.statusReports.get(reportKey).file; + + if (thisReport.lastFile === undefined) { + logger.write(MODULE_NAME, "[WARN] start -> getContextVariables -> Undefined Last File. -> reportKey = " + reportKey); + logger.write(MODULE_NAME, "[HINT] start -> getContextVariables -> It is too early too run this process since the trade history of the market is not there yet."); + + let customOK = { + result: global.CUSTOM_OK_RESPONSE.result, + message: "Dependency does not exist." + } + logger.write(MODULE_NAME, "[WARN] start -> getContextVariables -> customOK = " + customOK.message); + callBackFunction(customOK); + return; + } + + contextVariables.firstTradeFile = new Date(thisReport.lastFile.year + "-" + thisReport.lastFile.month + "-" + thisReport.lastFile.days + " " + thisReport.lastFile.hours + ":" + thisReport.lastFile.minutes + GMT_SECONDS); + + /* Second, we get the report from Olivia, to know when the marted ends. */ + + reportKey = "AAMasters" + "-" + "AAOlivia" + "-" + "Multi-Period-Daily" + "-" + "dataSet.V1"; + if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] start -> getContextVariables -> reportKey = " + reportKey); } + + statusReport = statusDependencies.statusReports.get(reportKey); + + if (statusReport === undefined) { // This means the status report does not exist, that could happen for instance at the begining of a month. + logger.write(MODULE_NAME, "[WARN] start -> getContextVariables -> Status Report does not exist. Retrying Later. "); + callBackFunction(global.DEFAULT_RETRY_RESPONSE); + return; + } + + if (statusReport.status === "Status Report is corrupt.") { + logger.write(MODULE_NAME, "[ERROR] start -> getContextVariables -> Can not continue because dependecy Status Report is corrupt. "); + callBackFunction(global.DEFAULT_RETRY_RESPONSE); + return; + } + + thisReport = statusDependencies.statusReports.get(reportKey).file; + + if (thisReport.lastFile === undefined) { + logger.write(MODULE_NAME, "[WARN] start -> getContextVariables -> Undefined Last File. -> reportKey = " + reportKey); + + let customOK = { + result: global.CUSTOM_OK_RESPONSE.result, + message: "Dependency not ready." + } + logger.write(MODULE_NAME, "[WARN] start -> getContextVariables -> customOK = " + customOK.message); + callBackFunction(customOK); + return; + } + + contextVariables.maxCandleFile = new Date(thisReport.lastFile.valueOf()); + + /* Finally we get our own Status Report. */ + + reportKey = "AAMasters" + "-" + "AATom" + "-" + "Multi-Period-Daily" + "-" + "dataSet.V1"; + if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] start -> getContextVariables -> reportKey = " + reportKey); } + + statusReport = statusDependencies.statusReports.get(reportKey); + + if (statusReport === undefined) { // This means the status report does not exist, that could happen for instance at the begining of a month. + logger.write(MODULE_NAME, "[WARN] start -> getContextVariables -> Status Report does not exist. Retrying Later. "); + callBackFunction(global.DEFAULT_RETRY_RESPONSE); + return; + } + + if (statusReport.status === "Status Report is corrupt.") { + logger.write(MODULE_NAME, "[ERROR] start -> getContextVariables -> Can not continue because self dependecy Status Report is corrupt. Aborting Process."); + callBackFunction(global.DEFAULT_FAIL_RESPONSE); + return; + } + + thisReport = statusDependencies.statusReports.get(reportKey).file; + + if (thisReport.lastFile !== undefined) { + + contextVariables.lastCandleFile = new Date(thisReport.lastFile); + + /* + The stairs objects can span more than one day. In order not to cut these objects into two when this happens, this process will alsways read + 3 files. + + 1. The first file is a stairs file corresponding to processDay -2. From there we will know where the last staris ended. + 2. The second is a candle or volume file corresponding to processDay -1. + 3. The third is a candle of volume file at processDay. + + We will recalculate 2 and 3 considering the objects already in 1, so as to make the transition between 2 and 3 smooth. + */ + + if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] start -> getContextVariables -> thisReport.lastFile !== undefined"); } + + buildStairs(); + return; + + } else { + + /* + In the case when there is no status report, we take the date of the file with the first trades as the begining of the market. Then we will + go one day back in time, so that when we enter the loop, one day will be added and we will be exactly at the date where the first trades occured. + */ + + contextVariables.lastCandleFile = new Date(contextVariables.firstTradeFile.getUTCFullYear() + "-" + (contextVariables.firstTradeFile.getUTCMonth() + 1) + "-" + contextVariables.firstTradeFile.getUTCDate() + " " + "00:00" + GMT_SECONDS); + + if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] start -> getContextVariables -> thisReport.lastFile === undefined"); } + if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] start -> getContextVariables -> contextVariables.lastCandleFile = " + contextVariables.lastCandleFile); } + + buildStairs(); + return; + } + + } catch (err) { + logger.write(MODULE_NAME, "[ERROR] start -> getContextVariables -> err = " + err.message); + if (err.message === "Cannot read property 'file' of undefined") { + logger.write(MODULE_NAME, "[HINT] start -> getContextVariables -> Check the bot configuration to see if all of its statusDependencies declarations are correct. "); + logger.write(MODULE_NAME, "[HINT] start -> getContextVariables -> Dependencies loaded -> keys = " + JSON.stringify(statusDependencies.keys)); + } + callBackFunction(global.DEFAULT_FAIL_RESPONSE); + } + } + + function buildStairs() { + + try { + + if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] start -> buildStairs -> Entering function."); } + + let n; + processDate = new Date(contextVariables.lastCandleFile.valueOf() - ONE_DAY_IN_MILISECONDS); // Go back one day to start well when we advance time at the begining of the loop. + if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] start -> buildStairs -> processDate = " + processDate); } + + advanceTime(); + + function advanceTime() { + + try { + + logger.newInternalLoop(bot.codeName, bot.process); + + if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] start -> buildStairs -> advanceTime -> Entering function."); } + + processDate = new Date(processDate.valueOf() + ONE_DAY_IN_MILISECONDS); + previousDay = new Date(processDate.valueOf() - ONE_DAY_IN_MILISECONDS); + + if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] start -> buildStairs -> advanceTime -> processDate = " + processDate); } + if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] start -> buildStairs -> advanceTime -> previousDay = " + previousDay); } + + /* Validation that we are not going past the head of the market. */ + + if (processDate.valueOf() > contextVariables.maxCandleFile.valueOf()) { + + const logText = "Head of the market found @ " + previousDay.getUTCFullYear() + "/" + (previousDay.getUTCMonth() + 1) + "/" + previousDay.getUTCDate() + "."; + if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] start -> buildStairs -> advanceTime -> " + logText); } + + callBackFunction(global.DEFAULT_OK_RESPONSE); + return; + + } + + periodsLoop(); + + } catch (err) { + logger.write(MODULE_NAME, "[ERROR] start -> buildStairs -> advanceTime -> err = " + err.message); + callBackFunction(global.DEFAULT_FAIL_RESPONSE); + } + } + + function periodsLoop() { + + try { + + if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] start -> buildStairs -> periodsLoop -> Entering function."); } + + /* + + We will iterate through all posible timePeriods. + + */ + + n = 0 // loop Variable representing each possible period as defined at the periods array. + + loopBody(); + + } catch (err) { + logger.write(MODULE_NAME, "[ERROR] start -> buildStairs -> periodsLoop -> err = " + err.message); + callBackFunction(global.DEFAULT_FAIL_RESPONSE); + } + } + + function loopBody() { + + try { + + if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] start -> buildStairs -> loopBody -> Entering function."); } + + const timePeriod = global.dailyFilePeriods[n][1]; + + let endOfLastCandleStair = new Date(previousDay.valueOf() - ONE_DAY_IN_MILISECONDS); + let endOfLastBuyVolumeStair = new Date(previousDay.valueOf() - ONE_DAY_IN_MILISECONDS); + let endOfLastSellVolumeStair = new Date(previousDay.valueOf() - ONE_DAY_IN_MILISECONDS); + + /* + By default we set the starting date of the processDay - 2 file. If we find the file this value shoulld be overwritten by the value of the end property + of the last object on the file. + */ + + endOfLastCandleStair = endOfLastCandleStair.valueOf(); + endOfLastBuyVolumeStair = endOfLastBuyVolumeStair.valueOf(); + endOfLastSellVolumeStair = endOfLastSellVolumeStair.valueOf(); + + getEndOfLastCandleStair(); + + function getEndOfLastCandleStair() { + + try { + + if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] start -> buildStairs -> loopBody -> getEndOfLastCandleStair -> Entering function."); } + + let fileDate = new Date(previousDay.valueOf() - ONE_DAY_IN_MILISECONDS); + getCandleStairsFile(); + + function getCandleStairsFile() { + + try { + + if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] start -> buildStairs -> loopBody -> getEndOfLastCandleStair -> getCandleStairsFile -> Entering function."); } + + let dateForPath = fileDate.getUTCFullYear() + '/' + utilities.pad(fileDate.getUTCMonth() + 1, 2) + '/' + utilities.pad(fileDate.getUTCDate(), 2); + let fileName = market.assetA + '_' + market.assetB + ".json" + + let filePathRoot = bot.devTeam + "/" + bot.codeName + "." + bot.version.major + "." + bot.version.minor + "/" + global.PLATFORM_CONFIG.codeName + "." + global.PLATFORM_CONFIG.version.major + "." + global.PLATFORM_CONFIG.version.minor + "/" + global.EXCHANGE_NAME + "/" + bot.dataSetVersion; + let filePath = filePathRoot + "/Output/" + CANDLE_STAIRS_FOLDER_NAME + '/' + "Multi-Period-Daily" + "/" + timePeriod + "/" + dateForPath; + + tomStorage.getTextFile(filePath, fileName, onFileReceived, true); + + function onFileReceived(err, text) { + + try { + + if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] start -> buildStairs -> loopBody -> getEndOfLastCandleStair -> getCandleStairsFile -> onFileReceived -> Entering function."); } + + if (LOG_FILE_CONTENT === true) { logger.write(MODULE_NAME, "[INFO] start -> buildStairs -> loopBody -> getEndOfLastCandleStair -> getCandleStairsFile -> onFileReceived -> text = " + text); } + + if ( + err.result === global.CUSTOM_FAIL_RESPONSE.result && + (err.message === 'Folder does not exist.' || err.message === 'File does not exist.') + ) { + + getEndOfLastVolumeStair(); + return; + } + + let stairsFile = JSON.parse(text); + + if (stairsFile.length > 0) { + + endOfLastCandleStair = stairsFile[stairsFile.length - 1][5]; // We get from the last regord the end value. Position 5 = Stairs.end + getEndOfLastVolumeStair(); + + } else { + + getEndOfLastVolumeStair(); + return; + + } + + } catch (err) { + logger.write(MODULE_NAME, "[ERROR] start -> buildStairs -> periodsLoop -> loopBody -> getEndOfLastCandleStair -> getCandleStairsFile -> onFileReceived -> err = " + err.message); + logger.write(MODULE_NAME, "[ERROR] start -> buildStairs -> periodsLoop -> loopBody -> getEndOfLastCandleStair -> getCandleStairsFile -> onFileReceived -> filePath = " + filePath); + logger.write(MODULE_NAME, "[ERROR] start -> buildStairs -> periodsLoop -> loopBody -> getEndOfLastCandleStair -> getCandleStairsFile -> onFileReceived -> market = " + market.assetA + '_' + market.assetB); + + callBackFunction(global.DEFAULT_RETRY_RESPONSE); + } + } + + } catch (err) { + logger.write(MODULE_NAME, "[ERROR] start -> buildStairs -> periodsLoop -> loopBody -> getEndOfLastCandleStair -> getCandleStairsFile -> err = " + err.message); + callBackFunction(global.DEFAULT_FAIL_RESPONSE); + } + } + + } catch (err) { + logger.write(MODULE_NAME, "[ERROR] start -> buildStairs -> periodsLoop -> loopBody -> getEndOfLastCandleStair -> err = " + err.message); + callBackFunction(global.DEFAULT_FAIL_RESPONSE); + } + } + + function getEndOfLastVolumeStair() { + + try { + + + if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] start -> buildStairs -> loopBody -> getEndOfLastVolumeStair -> Entering function."); } + + let fileDate = new Date(previousDay.valueOf() - ONE_DAY_IN_MILISECONDS); + getCandleStairsFile(); + + function getCandleStairsFile() { + + try { + + if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] start -> buildStairs -> loopBody -> getEndOfLastVolumeStair -> getCandleStairsFile -> Entering function."); } + + let dateForPath = fileDate.getUTCFullYear() + '/' + utilities.pad(fileDate.getUTCMonth() + 1, 2) + '/' + utilities.pad(fileDate.getUTCDate(), 2); + let fileName = market.assetA + '_' + market.assetB + ".json" + + let filePathRoot = bot.devTeam + "/" + bot.codeName + "." + bot.version.major + "." + bot.version.minor + "/" + global.PLATFORM_CONFIG.codeName + "." + global.PLATFORM_CONFIG.version.major + "." + global.PLATFORM_CONFIG.version.minor + "/" + global.EXCHANGE_NAME + "/" + bot.dataSetVersion; + let filePath = filePathRoot + "/Output/" + VOLUME_STAIRS_FOLDER_NAME + '/' + "Multi-Period-Daily" + "/" + timePeriod + "/" + dateForPath; + + tomStorage.getTextFile(filePath, fileName, onFileReceived, true); + + function onFileReceived(err, text) { + + try { + + if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] start -> buildStairs -> loopBody -> getEndOfLastVolumeStair -> getCandleStairsFile -> onFileReceived -> Entering function."); } + if (LOG_FILE_CONTENT === true) { logger.write(MODULE_NAME, "[INFO] start -> buildStairs -> loopBody -> getEndOfLastVolumeStair -> getCandleStairsFile -> onFileReceived -> text = " + text); } + + if ( + err.result === global.CUSTOM_FAIL_RESPONSE.result && + (err.message === 'Folder does not exist.' || err.message === 'File does not exist.') + ) { + + processCandles(); + return; + } + + let stairsFile = JSON.parse(text); + + if (stairsFile.length > 0) { + + for (let i = 0; i < stairsFile.length; i++) { + + let stairs = { + type: stairsFile[i][0], + begin: stairsFile[i][1], + end: stairsFile[i][2], + direction: stairsFile[i][3], + barsCount: stairsFile[i][4], + firstAmount: stairsFile[i][5], + lastAmount: stairsFile[i][6] + }; + + if (stairs.type === 'buy') { + + endOfLastBuyVolumeStair = stairs.end; + + } else { + + endOfLastSellVolumeStair = stairs.end; + + } + } + + processCandles(); + + } else { + + processCandles(); + return; + + } + + } catch (err) { + logger.write(MODULE_NAME, "[ERROR] start -> buildStairs -> periodsLoop -> loopBody -> getEndOfLastVolumeStair -> getCandleStairsFile -> onFileReceived -> err = " + err.message); + logger.write(MODULE_NAME, "[ERROR] start -> buildStairs -> periodsLoop -> loopBody -> getEndOfLastVolumeStair -> getCandleStairsFile -> onFileReceived -> filePath = " + filePath); + logger.write(MODULE_NAME, "[ERROR] start -> buildStairs -> periodsLoop -> loopBody -> getEndOfLastVolumeStair -> getCandleStairsFile -> onFileReceived -> market = " + market.assetA + '_' + market.assetB); + + callBackFunction(global.DEFAULT_RETRY_RESPONSE); + } + } + } catch (err) { + logger.write(MODULE_NAME, "[ERROR] start -> buildStairs -> periodsLoop -> loopBody -> getEndOfLastVolumeStair -> getCandleStairsFile -> err = " + err.message); + callBackFunction(global.DEFAULT_FAIL_RESPONSE); + } + } + + } catch (err) { + logger.write(MODULE_NAME, "[ERROR] start -> buildStairs -> periodsLoop -> loopBody -> getEndOfLastVolumeStair -> err = " + err.message); + callBackFunction(global.DEFAULT_FAIL_RESPONSE); + } + } + + function processCandles() { + + try { + + if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] start -> buildStairs -> loopBody -> processCandles -> Entering function."); } + + let candles = []; // Here we will put all the candles of the 2 files read. + + let previousDayStairsArray = []; // Here All the stairs of the previous day. + let processDayStairsArray = []; // Here All the stairs of the process day. + + let previousDayFile; + let processDayFile; + + getCandleStairsFile(); + + function getCandleStairsFile() { + + try { + + if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] start -> buildStairs -> loopBody -> processCandles -> getCandleStairsFile -> Entering function."); } + + let dateForPath = previousDay.getUTCFullYear() + '/' + utilities.pad(previousDay.getUTCMonth() + 1, 2) + '/' + utilities.pad(previousDay.getUTCDate(), 2); + let fileName = market.assetA + '_' + market.assetB + ".json" + + let filePathRoot = bot.devTeam + "/" + "AAOlivia" + "." + bot.version.major + "." + bot.version.minor + "/" + global.PLATFORM_CONFIG.codeName + "." + global.PLATFORM_CONFIG.version.major + "." + global.PLATFORM_CONFIG.version.minor + "/" + global.EXCHANGE_NAME + "/" + bot.dataSetVersion; + let filePath = filePathRoot + "/Output/" + CANDLES_FOLDER_NAME + '/' + "Multi-Period-Daily" + "/" + timePeriod + "/" + dateForPath; + + oliviaStorage.getTextFile(filePath, fileName, onCurrentDayFileReceived, true); + + function onCurrentDayFileReceived(err, text) { + + try { + + if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] start -> buildStairs -> loopBody -> processCandles -> getCandleStairsFile -> onCurrentDayFileReceived -> Entering function."); } + if (LOG_FILE_CONTENT === true) { logger.write(MODULE_NAME, "[INFO] start -> buildStairs -> loopBody -> processCandles -> getCandleStairsFile -> onCurrentDayFileReceived -> text = " + text); } + + previousDayFile = JSON.parse(text); + getProcessDayFile() + + } catch (err) { + logger.write(MODULE_NAME, "[ERROR] start -> buildStairs -> periodsLoop -> loopBody -> processCandles -> getCandleStairsFile -> onCurrentDayFileReceived -> err = " + err.message); + logger.write(MODULE_NAME, "[ERROR] start -> buildStairs -> periodsLoop -> loopBody -> processCandles -> getCandleStairsFile -> onCurrentDayFileReceived -> filePath = " + filePath); + logger.write(MODULE_NAME, "[ERROR] start -> buildStairs -> periodsLoop -> loopBody -> processCandles -> getCandleStairsFile -> onCurrentDayFileReceived -> market = " + market.assetA + '_' + market.assetB); + + callBackFunction(global.DEFAULT_RETRY_RESPONSE); + } + } + + } catch (err) { + logger.write(MODULE_NAME, "[ERROR] start -> buildStairs -> periodsLoop -> loopBody -> processCandles -> getCandleStairsFile -> err = " + err.message); + callBackFunction(global.DEFAULT_FAIL_RESPONSE); + } + } + + function getProcessDayFile() { + + try { + + if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] start -> buildStairs -> loopBody -> processCandles -> getProcessDayFile -> Entering function."); } + + let dateForPath = processDate.getUTCFullYear() + '/' + utilities.pad(processDate.getUTCMonth() + 1, 2) + '/' + utilities.pad(processDate.getUTCDate(), 2); + let fileName = market.assetA + '_' + market.assetB + ".json" + + let filePathRoot = bot.devTeam + "/" + "AAOlivia" + "." + bot.version.major + "." + bot.version.minor + "/" + global.PLATFORM_CONFIG.codeName + "." + global.PLATFORM_CONFIG.version.major + "." + global.PLATFORM_CONFIG.version.minor + "/" + global.EXCHANGE_NAME + "/" + bot.dataSetVersion; + let filePath = filePathRoot + "/Output/" + CANDLES_FOLDER_NAME + '/' + "Multi-Period-Daily" + "/" + timePeriod + "/" + dateForPath; + + oliviaStorage.getTextFile(filePath, fileName, onCurrentDayFileReceived, true); + + function onCurrentDayFileReceived(err, text) { + + try { + + if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] start -> buildStairs -> loopBody -> processCandles -> getProcessDayFile -> onCurrentDayFileReceived -> Entering function."); } + if (LOG_FILE_CONTENT === true) { logger.write(MODULE_NAME, "[INFO] start -> buildStairs -> loopBody -> processCandles -> getProcessDayFile -> onCurrentDayFileReceived -> text = " + text); } + + processDayFile = JSON.parse(text); + buildCandles(); + + } catch (err) { + + if (processDate.valueOf() > contextVariables.maxCandleFile.valueOf()) { + + processDayFile = []; // we are past the head of the market, then no worries if this file is non existent. + buildCandles(); + + } else { + + logger.write(MODULE_NAME, "[ERROR] start -> buildStairs -> periodsLoop -> loopBody -> processCandles -> getProcessDayFile -> onCurrentDayFileReceived -> err = " + err.message); + logger.write(MODULE_NAME, "[ERROR] start -> buildStairs -> periodsLoop -> loopBody -> processCandles -> getProcessDayFile -> onCurrentDayFileReceived -> filePath = " + filePath); + logger.write(MODULE_NAME, "[ERROR] start -> buildStairs -> periodsLoop -> loopBody -> processCandles -> getProcessDayFile -> onCurrentDayFileReceived -> market = " + market.assetA + '_' + market.assetB); + + callBackFunction(global.DEFAULT_RETRY_RESPONSE); + return; + } + } + } + + } catch (err) { + logger.write(MODULE_NAME, "[ERROR] start -> buildStairs -> periodsLoop -> loopBody -> processCandles -> getProcessDayFile -> err = " + err.message); + callBackFunction(global.DEFAULT_FAIL_RESPONSE); + } + } + + function buildCandles() { + + try { + + if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] start -> buildStairs -> loopBody -> processCandles -> buildCandles -> Entering function."); } + + pushCandles(previousDayFile); + pushCandles(processDayFile); + findCandleStairs(); + + function pushCandles(candlesFile) { + + try { + + if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] start -> buildStairs -> loopBody -> processCandles -> buildCandles -> pushCandles -> Entering function."); } + + for (let i = 0; i < candlesFile.length; i++) { + + let candle = { + open: undefined, + close: undefined, + min: 10000000000000, + max: 0, + begin: undefined, + end: undefined, + direction: undefined + }; + + candle.min = candlesFile[i][0]; + candle.max = candlesFile[i][1]; + + candle.open = candlesFile[i][2]; + candle.close = candlesFile[i][3]; + + candle.begin = candlesFile[i][4]; + candle.end = candlesFile[i][5]; + + if (candle.open > candle.close) { candle.direction = 'down'; } + if (candle.open < candle.close) { candle.direction = 'up'; } + if (candle.open === candle.close) { candle.direction = 'side'; } + + candles.push(candle); + } + + } catch (err) { + logger.write(MODULE_NAME, "[ERROR] start -> buildStairs -> periodsLoop -> loopBody -> processCandles -> buildCandles -> pushCandles -> err = " + err.message); + callBackFunction(global.DEFAULT_FAIL_RESPONSE); + return; + } + } + + } catch (err) { + logger.write(MODULE_NAME, "[ERROR] start -> buildStairs -> periodsLoop -> loopBody -> processCandles -> buildCandles -> err = " + err.message); + callBackFunction(global.DEFAULT_FAIL_RESPONSE); + return; + } + } + + function findCandleStairs() { + + try { + + if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] start -> buildStairs -> loopBody -> processCandles -> findCandleStairs -> Entering function."); } + + /* Finding stairs */ + + let stairs; + + for (let i = 0; i < candles.length - 1; i++) { + + let currentCandle = candles[i]; + let nextCandle = candles[i + 1]; + + if (currentCandle.direction === nextCandle.direction && currentCandle.direction !== 'side') { + + if (stairs === undefined) { + + stairs = { + open: undefined, + close: undefined, + min: 10000000000000, + max: 0, + begin: undefined, + end: undefined, + direction: undefined, + candleCount: 0, + firstMin: 0, + firstMax: 0, + lastMin: 0, + lastMax: 0 + }; + + stairs.direction = currentCandle.direction; + stairs.candleCount = 2; + + stairs.begin = currentCandle.begin; + stairs.end = nextCandle.end; + + stairs.open = currentCandle.open; + stairs.close = nextCandle.close; + + if (currentCandle.min < nextCandle.min) { stairs.min = currentCandle.min; } else { stairs.min = nextCandle.min; } + if (currentCandle.max > nextCandle.max) { stairs.max = currentCandle.max; } else { stairs.max = nextCandle.max; } + + if (stairs.direction === 'up') { + + stairs.firstMin = currentCandle.open; + stairs.firstMax = currentCandle.close; + + stairs.lastMin = nextCandle.open; + stairs.lastMax = nextCandle.close; + + } else { + + stairs.firstMin = currentCandle.close; + stairs.firstMax = currentCandle.open; + + stairs.lastMin = nextCandle.close; + stairs.lastMax = nextCandle.open; + + } + + + } else { + + stairs.candleCount++; + stairs.end = nextCandle.end; + stairs.close = nextCandle.close; + + if (stairs.min < nextCandle.min) { stairs.min = currentCandle.min; } + if (stairs.max > nextCandle.max) { stairs.max = currentCandle.max; } + + if (stairs.direction === 'up') { + + stairs.lastMin = nextCandle.open; + stairs.lastMax = nextCandle.close; + + } else { + + stairs.lastMin = nextCandle.close; + stairs.lastMax = nextCandle.open; + + } + + } + + } else { + + if (stairs !== undefined) { + + /* + Here we detect stairs that started at process day - 2. + */ + + if (stairs.begin > endOfLastCandleStair) { + + if (stairs.begin >= processDate.valueOf()) { + + processDayStairsArray.push(stairs); + + } else { + + previousDayStairsArray.push(stairs); + + } + } + + stairs = undefined; + } + } + } + + writeCandleStairsFile(); + + } catch (err) { + logger.write(MODULE_NAME, "[ERROR] start -> buildStairs -> periodsLoop -> loopBody -> processCandles -> findCandleStairs -> err = " + err.message); + callBackFunction(global.DEFAULT_FAIL_RESPONSE); + return; + } + } + + function writeCandleStairsFile() { + + try { + + if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] start -> buildStairs -> loopBody -> processCandles -> writeCandleStairsFile -> Entering function."); } + + writeFile(previousDayStairsArray, previousDay, onPreviousFileWritten); + + function onPreviousFileWritten() { + + try { + + if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] start -> buildStairs -> loopBody -> processCandles -> writeCandleStairsFile -> onPreviousFileWritten -> Entering function."); } + + writeFile(processDayStairsArray, processDate, onProcessFileWritten); + + function onProcessFileWritten() { + + try { + + if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] start -> buildStairs -> loopBody -> processCandles -> writeCandleStairsFile -> onPreviousFileWritten -> onProcessFileWritten -> Entering function."); } + + processVolumes(); + + } catch (err) { + logger.write(MODULE_NAME, "[ERROR] start -> buildStairs -> periodsLoop -> loopBody -> processCandles -> writeCandleStairsFile -> onPreviousFileWritten -> onProcessFileWritten -> err = " + err.message); + callBackFunction(global.DEFAULT_FAIL_RESPONSE); + } + } + + } catch (err) { + logger.write(MODULE_NAME, "[ERROR] start -> buildStairs -> periodsLoop -> loopBody -> processCandles -> writeCandleStairsFile -> onPreviousFileWritten -> err = " + err.message); + callBackFunction(global.DEFAULT_FAIL_RESPONSE); + } + } + + function writeFile(pStairs, pDate, callback) { + + try { + + if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] start -> buildStairs -> loopBody -> processCandles -> writeCandleStairsFile -> writeFile -> Entering function."); } + + let separator = ""; + let fileRecordCounter = 0; + + let fileContent = ""; + + for (i = 0; i < pStairs.length; i++) { + + let stairs = pStairs[i]; + + fileContent = fileContent + separator + '[' + + stairs.open + "," + + stairs.close + "," + + stairs.min + "," + + stairs.max + "," + + stairs.begin + "," + + stairs.end + "," + + '"' + stairs.direction + '"' + "," + + stairs.candleCount + "," + + stairs.firstMin + "," + + stairs.firstMax + "," + + stairs.lastMin + "," + + stairs.lastMax + "]"; + + if (separator === "") { separator = ","; } + + fileRecordCounter++; + + } + + fileContent = "[" + fileContent + "]"; + + let dateForPath = pDate.getUTCFullYear() + '/' + utilities.pad(pDate.getUTCMonth() + 1, 2) + '/' + utilities.pad(pDate.getUTCDate(), 2); + let fileName = '' + market.assetA + '_' + market.assetB + '.json'; + + let filePathRoot = bot.devTeam + "/" + bot.codeName + "." + bot.version.major + "." + bot.version.minor + "/" + global.PLATFORM_CONFIG.codeName + "." + global.PLATFORM_CONFIG.version.major + "." + global.PLATFORM_CONFIG.version.minor + "/" + global.EXCHANGE_NAME + "/" + bot.dataSetVersion; + let filePath = filePathRoot + "/Output/" + CANDLE_STAIRS_FOLDER_NAME + "/" + bot.process + "/" + timePeriod + "/" + dateForPath; + + tomStorage.createTextFile(filePath, fileName, fileContent + '\n', onFileCreated); + + function onFileCreated(err) { + + try { + + if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] start -> buildStairs -> loopBody -> processCandles -> writeCandleStairsFile -> writeFile -> onFileCreated -> Entering function."); } + + if (LOG_FILE_CONTENT === true) { + logger.write(MODULE_NAME, "[INFO] start -> buildStairs -> loopBody -> processCandles -> writeCandleStairsFile -> writeFile -> onFileCreated -> Content written = " + fileContent); + } + + if (err.result !== global.DEFAULT_OK_RESPONSE.result) { + logger.write(MODULE_NAME, "[ERROR] start -> buildStairs -> loopBody -> processCandles -> writeCandleStairsFile -> writeFile -> onFileCreated -> err = " + err.message); + callBack(err); + return; + } + + const logText = "[WARN] Finished with File @ " + market.assetA + "_" + market.assetB + ", " + fileRecordCounter + " records inserted into " + filePath + "/" + fileName + ""; + if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] start -> buildStairs -> loopBody -> processCandles -> writeCandleStairsFile -> writeFile -> onFileCreated -> " + logText); } + + callback(); + + } catch (err) { + logger.write(MODULE_NAME, "[ERROR] start -> buildStairs -> periodsLoop -> loopBody -> processCandles -> writeCandleStairsFile -> writeFile -> onFileCreated -> err = " + err.message); + callBackFunction(global.DEFAULT_RETRY_RESPONSE); + } + } + + } catch (err) { + logger.write(MODULE_NAME, "[ERROR] start -> buildStairs -> periodsLoop -> loopBody -> processCandles -> writeCandleStairsFile -> writeFile -> err = " + err.message); + callBackFunction(global.DEFAULT_FAIL_RESPONSE); + } + } + + } catch (err) { + logger.write(MODULE_NAME, "[ERROR] start -> buildStairs -> periodsLoop -> loopBody -> processCandles -> writeCandleStairsFile -> err = " + err.message); + callBackFunction(global.DEFAULT_FAIL_RESPONSE); + } + } + + } catch (err) { + logger.write(MODULE_NAME, "[ERROR] start -> buildStairs -> periodsLoop -> loopBody -> processCandles -> err = " + err.message); + callBackFunction(global.DEFAULT_FAIL_RESPONSE); + } + } + + function processVolumes() { + + try { + + if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] start -> buildStairs -> loopBody -> processVolumes -> Entering function."); } + + let volumes = []; + + let previousDayStairsArray = []; // Here All the stairs of the previous day. + let processDayStairsArray = []; // Here All the stairs of the process day. + + let previousDayFile; + let processDayFile; + + getCandleStairsFile(); + + function getCandleStairsFile() { + + try { + + if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] start -> buildStairs -> loopBody -> processVolumes -> getCandleStairsFile -> Entering function."); } + + let dateForPath = previousDay.getUTCFullYear() + '/' + utilities.pad(previousDay.getUTCMonth() + 1, 2) + '/' + utilities.pad(previousDay.getUTCDate(), 2); + let fileName = market.assetA + '_' + market.assetB + ".json" + + let filePathRoot = bot.devTeam + "/" + "AAOlivia" + "." + bot.version.major + "." + bot.version.minor + "/" + global.PLATFORM_CONFIG.codeName + "." + global.PLATFORM_CONFIG.version.major + "." + global.PLATFORM_CONFIG.version.minor + "/" + global.EXCHANGE_NAME + "/" + bot.dataSetVersion; + let filePath = filePathRoot + "/Output/" + VOLUMES_FOLDER_NAME + '/' + "Multi-Period-Daily" + "/" + timePeriod + "/" + dateForPath; + + oliviaStorage.getTextFile(filePath, fileName, onCurrentDayFileReceived, true); + + function onCurrentDayFileReceived(err, text) { + + try { + + if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] start -> buildStairs -> loopBody -> processVolumes -> getCandleStairsFile -> onCurrentDayFileReceived -> Entering function."); } + if (LOG_FILE_CONTENT === true) { logger.write(MODULE_NAME, "[INFO] start -> buildStairs -> loopBody -> processVolumes -> getCandleStairsFile -> onCurrentDayFileReceived -> text = " + text); } + + previousDayFile = JSON.parse(text); + getProcessDayFile() + + } catch (err) { + logger.write(MODULE_NAME, "[ERROR] start -> buildStairs -> periodsLoop -> loopBody -> processVolumes -> getCandleStairsFile -> onCurrentDayFileReceived -> err = " + err.message); + logger.write(MODULE_NAME, "[ERROR] start -> buildStairs -> periodsLoop -> loopBody -> processVolumes -> getCandleStairsFile -> onCurrentDayFileReceived -> filePath = " + filePath); + logger.write(MODULE_NAME, "[ERROR] start -> buildStairs -> periodsLoop -> loopBody -> processVolumes -> getCandleStairsFile -> onCurrentDayFileReceived -> market = " + market.assetA + '_' + market.assetB); + + callBackFunction(global.DEFAULT_RETRY_RESPONSE); + } + } + + } catch (err) { + logger.write(MODULE_NAME, "[ERROR] start -> buildStairs -> periodsLoop -> loopBody -> processVolumes -> getCandleStairsFile -> err = " + err.message); + callBackFunction(global.DEFAULT_FAIL_RESPONSE); + } + } + + function getProcessDayFile() { + + try { + + if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] start -> buildStairs -> loopBody -> processVolumes -> getProcessDayFile -> Entering function."); } + + let dateForPath = processDate.getUTCFullYear() + '/' + utilities.pad(processDate.getUTCMonth() + 1, 2) + '/' + utilities.pad(processDate.getUTCDate(), 2); + let fileName = market.assetA + '_' + market.assetB + ".json" + + let filePathRoot = bot.devTeam + "/" + "AAOlivia" + "." + bot.version.major + "." + bot.version.minor + "/" + global.PLATFORM_CONFIG.codeName + "." + global.PLATFORM_CONFIG.version.major + "." + global.PLATFORM_CONFIG.version.minor + "/" + global.EXCHANGE_NAME + "/" + bot.dataSetVersion; + let filePath = filePathRoot + "/Output/" + VOLUMES_FOLDER_NAME + '/' + "Multi-Period-Daily" + "/" + timePeriod + "/" + dateForPath; + + oliviaStorage.getTextFile(filePath, fileName, onCurrentDayFileReceived, true); + + function onCurrentDayFileReceived(err, text) { + + try { + + if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] start -> buildStairs -> loopBody -> processVolumes -> getProcessDayFile -> onCurrentDayFileReceived -> Entering function."); } + if (LOG_FILE_CONTENT === true) { logger.write(MODULE_NAME, "[INFO] start -> buildStairs -> loopBody -> processVolumes -> getProcessDayFile -> onCurrentDayFileReceived -> text = " + text); } + + processDayFile = JSON.parse(text); + buildVolumes(); + + } catch (err) { + + if (processDate.valueOf() > contextVariables.maxCandleFile.valueOf()) { + + processDayFile = []; // we are past the head of the market, then no worries if this file is non existent. + buildVolumes(); + + } else { + + logger.write(MODULE_NAME, "[ERROR] start -> buildStairs -> periodsLoop -> loopBody -> processVolumes -> getProcessDayFile -> onCurrentDayFileReceived -> err = " + err.message); + logger.write(MODULE_NAME, "[ERROR] start -> buildStairs -> periodsLoop -> loopBody -> processVolumes -> getProcessDayFile -> onCurrentDayFileReceived -> filePath = " + filePath); + logger.write(MODULE_NAME, "[ERROR] start -> buildStairs -> periodsLoop -> loopBody -> processVolumes -> getProcessDayFile -> onCurrentDayFileReceived -> market = " + market.assetA + '_' + market.assetB); + + callBackFunction(global.DEFAULT_RETRY_RESPONSE); + return; + } + } + } + + } catch (err) { + logger.write(MODULE_NAME, "[ERROR] start -> buildStairs -> periodsLoop -> loopBody -> processVolumes -> getProcessDayFile -> err = " + err.message); + callBackFunction(global.DEFAULT_FAIL_RESPONSE); + } + } + + function buildVolumes() { + + try { + + if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] start -> buildStairs -> loopBody -> processVolumes -> buildVolumes -> Entering function."); } + + pushVolumes(previousDayFile); + pushVolumes(processDayFile); + findVolumesStairs(); + + function pushVolumes(volumesFile) { + + try { + + if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] start -> buildStairs -> loopBody -> processVolumes -> buildVolumes -> pushVolumes -> Entering function."); } + + for (let i = 0; i < volumesFile.length; i++) { + + let volume = { + amountBuy: 0, + amountSell: 0, + begin: undefined, + end: undefined + }; + + volume.amountBuy = volumesFile[i][0]; + volume.amountSell = volumesFile[i][1]; + + volume.begin = volumesFile[i][2]; + volume.end = volumesFile[i][3]; + + volumes.push(volume); + + } + + } catch (err) { + logger.write(MODULE_NAME, "[ERROR] start -> buildStairs -> periodsLoop -> loopBody -> processVolumes -> buildVolumes -> pushVolumes -> err = " + err.message); + callBackFunction(global.DEFAULT_FAIL_RESPONSE); + } + } + + } catch (err) { + logger.write(MODULE_NAME, "[ERROR] start -> buildStairs -> periodsLoop -> loopBody -> processVolumes -> buildVolumes -> err = " + err.message); + callBackFunction(global.DEFAULT_FAIL_RESPONSE); + } + } + + function findVolumesStairs() { + + try { + + if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] start -> buildStairs -> loopBody -> processVolumes -> findVolumesStairs -> Entering function."); } + + /* Finding stairs */ + + let buyUpStairs; + let buyDownStairs; + + let sellUpStairs; + let sellDownStairs; + + for (let i = 0; i < volumes.length - 1; i++) { + + let currentVolume = volumes[i]; + let nextVolume = volumes[i + 1]; + + + /* buy volume going up */ + + if (currentVolume.amountBuy < nextVolume.amountBuy) { + + if (buyUpStairs === undefined) { + + buyUpStairs = { + type: undefined, + begin: undefined, + end: undefined, + direction: undefined, + barsCount: 0, + firstAmount: 0, + lastAmount: 0 + }; + + buyUpStairs.type = 'buy'; + buyUpStairs.direction = 'up'; + buyUpStairs.barsCount = 2; + + buyUpStairs.begin = currentVolume.begin; + buyUpStairs.end = nextVolume.end; + + buyUpStairs.firstAmount = currentVolume.amountBuy; + buyUpStairs.lastAmount = nextVolume.amountBuy; + + } else { + + buyUpStairs.barsCount++; + buyUpStairs.end = nextVolume.end; + buyUpStairs.lastAmount = nextVolume.amountBuy; + + } + + } else { + + if (buyUpStairs !== undefined) { + + if (buyUpStairs.barsCount > 2) { + + pushToArray(buyUpStairs); + } + + buyUpStairs = undefined; + } + } + + /* buy volume going down */ + + if (currentVolume.amountBuy > nextVolume.amountBuy) { + + if (buyDownStairs === undefined) { + + buyDownStairs = { + type: undefined, + begin: undefined, + end: undefined, + direction: undefined, + barsCount: 0, + firstAmount: 0, + lastAmount: 0 + }; + + buyDownStairs.type = 'buy'; + buyDownStairs.direction = 'down'; + buyDownStairs.barsCount = 2; + + buyDownStairs.begin = currentVolume.begin; + buyDownStairs.end = nextVolume.end; + + buyDownStairs.firstAmount = currentVolume.amountBuy; + buyDownStairs.lastAmount = nextVolume.amountBuy; + + } else { + + buyDownStairs.barsCount++; + buyDownStairs.end = nextVolume.end; + buyDownStairs.lastAmount = nextVolume.amountBuy; + + } + + } else { + + if (buyDownStairs !== undefined) { + + if (buyDownStairs.barsCount > 2) { + + pushToArray(buyDownStairs); + } + + buyDownStairs = undefined; + } + } + + /* sell volume going up */ + + if (currentVolume.amountSell < nextVolume.amountSell) { + + if (sellUpStairs === undefined) { + + sellUpStairs = { + type: undefined, + begin: undefined, + end: undefined, + direction: undefined, + barsCount: 0, + firstAmount: 0, + lastAmount: 0 + }; + + sellUpStairs.type = 'sell'; + sellUpStairs.direction = 'up'; + sellUpStairs.barsCount = 2; + + sellUpStairs.begin = currentVolume.begin; + sellUpStairs.end = nextVolume.end; + + sellUpStairs.firstAmount = currentVolume.amountSell; + sellUpStairs.lastAmount = nextVolume.amountSell; + + } else { + + sellUpStairs.barsCount++; + sellUpStairs.end = nextVolume.end; + sellUpStairs.lastAmount = nextVolume.amountSell; + + } + + } else { + + if (sellUpStairs !== undefined) { + + if (sellUpStairs.barsCount > 2) { + + pushToArray(sellUpStairs); + } + + sellUpStairs = undefined; + } + } + + /* sell volume going down */ + + if (currentVolume.amountSell > nextVolume.amountSell) { + + if (sellDownStairs === undefined) { + + sellDownStairs = { + type: undefined, + begin: undefined, + end: undefined, + direction: undefined, + barsCount: 0, + firstAmount: 0, + lastAmount: 0 + }; + + sellDownStairs.type = 'sell'; + sellDownStairs.direction = 'down'; + sellDownStairs.barsCount = 2; + + sellDownStairs.begin = currentVolume.begin; + sellDownStairs.end = nextVolume.end; + + sellDownStairs.firstAmount = currentVolume.amountSell; + sellDownStairs.lastAmount = nextVolume.amountSell; + + } else { + + sellDownStairs.barsCount++; + sellDownStairs.end = nextVolume.end; + sellDownStairs.lastAmount = nextVolume.amountSell; + + } + + } else { + + if (sellDownStairs !== undefined) { + + if (sellDownStairs.barsCount > 2) { + + pushToArray(sellDownStairs); + } + + sellDownStairs = undefined; + } + } + + function pushToArray(stairs) { + + if (INTENSIVE_LOG === true) { logger.write(MODULE_NAME, "[INFO] start -> buildStairs -> loopBody -> processVolumes -> findVolumesStairs -> pushToArray -> Entering function."); } + + try { + + if (stairs !== undefined) { + + /* + Here we detect stairs that started at process day - 2. + */ + + if (stairs.type === 'sell') { + + if (stairs.begin > endOfLastSellVolumeStair) { + + if (stairs.begin >= processDate.valueOf()) { + + processDayStairsArray.push(stairs); + + } else { + + previousDayStairsArray.push(stairs); + + } + } + } + else { + + if (stairs.begin > endOfLastBuyVolumeStair) { + + if (stairs.begin >= processDate.valueOf()) { + + processDayStairsArray.push(stairs); + + } else { + + previousDayStairsArray.push(stairs); + + } + } + + } + + stairs = undefined; + } + + } catch (err) { + logger.write(MODULE_NAME, "[ERROR] start -> buildStairs -> periodsLoop -> loopBody -> processVolumes -> findVolumesStairs -> pushToArray -> err = " + err.message); + callBackFunction(global.DEFAULT_FAIL_RESPONSE); + } + } + } + + writeVolumeStairsFile(); + + } catch (err) { + logger.write(MODULE_NAME, "[ERROR] start -> buildStairs -> periodsLoop -> loopBody -> processVolumes -> findVolumesStairs -> err = " + err.message); + callBackFunction(global.DEFAULT_FAIL_RESPONSE); + } + } + + function writeVolumeStairsFile() { + + try { + + if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] start -> buildStairs -> loopBody -> processVolumes -> writeVolumeStairsFile -> Entering function."); } + + writeFile(previousDayStairsArray, previousDay, onPreviousFileWritten); + + function onPreviousFileWritten() { + + try { + + if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] start -> buildStairs -> loopBody -> processVolumes -> writeVolumeStairsFile -> onPreviousFileWritten -> Entering function."); } + + writeFile(processDayStairsArray, processDate, onProcessFileWritten); + + function onProcessFileWritten() { + + try { + + if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] start -> buildStairs -> loopBody -> processVolumes -> writeVolumeStairsFile -> onPreviousFileWritten -> onProcessFileWritten -> Entering function."); } + + controlLoop(); + + } catch (err) { + logger.write(MODULE_NAME, "[ERROR] start -> buildStairs -> periodsLoop -> loopBody -> processVolumes -> writeVolumeStairsFile -> onPreviousFileWritten -> onProcessFileWritten -> err = " + err.message); + callBackFunction(global.DEFAULT_FAIL_RESPONSE); + } + } + + } catch (err) { + logger.write(MODULE_NAME, "[ERROR] start -> buildStairs -> periodsLoop -> loopBody -> processVolumes -> writeVolumeStairsFile -> onPreviousFileWritten -> err = " + err.message); + callBackFunction(global.DEFAULT_FAIL_RESPONSE); + } + } + + function writeFile(pStairs, pDate, callback) { + + try { + + if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] start -> buildStairs -> loopBody -> processVolumes -> writeVolumeStairsFile -> writeFile -> Entering function."); } + + let separator = ""; + let fileRecordCounter = 0; + + let fileContent = ""; + + for (i = 0; i < pStairs.length; i++) { + + let stairs = pStairs[i]; + + fileContent = fileContent + separator + '[' + + '"' + stairs.type + '"' + "," + + stairs.begin + "," + + stairs.end + "," + + '"' + stairs.direction + '"' + "," + + stairs.barsCount + "," + + stairs.firstAmount + "," + + stairs.lastAmount + "]"; + + if (separator === "") { separator = ","; } + + fileRecordCounter++; + + } + + fileContent = "[" + fileContent + "]"; + + let dateForPath = pDate.getUTCFullYear() + '/' + utilities.pad(pDate.getUTCMonth() + 1, 2) + '/' + utilities.pad(pDate.getUTCDate(), 2); + let fileName = '' + market.assetA + '_' + market.assetB + '.json'; + + let filePathRoot = bot.devTeam + "/" + bot.codeName + "." + bot.version.major + "." + bot.version.minor + "/" + global.PLATFORM_CONFIG.codeName + "." + global.PLATFORM_CONFIG.version.major + "." + global.PLATFORM_CONFIG.version.minor + "/" + global.EXCHANGE_NAME + "/" + bot.dataSetVersion; + let filePath = filePathRoot + "/Output/" + VOLUME_STAIRS_FOLDER_NAME + "/" + bot.process + "/" + timePeriod + "/" + dateForPath; + + tomStorage.createTextFile(filePath, fileName, fileContent + '\n', onFileCreated); + + function onFileCreated(err) { + + try { + + if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] start -> buildStairs -> loopBody -> processVolumes -> writeVolumeStairsFile -> writeFile -> onFileCreated -> Entering function."); } + + if (LOG_FILE_CONTENT === true) { + logger.write(MODULE_NAME, "[INFO] start -> buildStairs -> loopBody -> processVolumes -> writeVolumeStairsFile -> writeFile -> onFileCreated -> Content written = " + fileContent); + } + + if (err.result !== global.DEFAULT_OK_RESPONSE.result) { + logger.write(MODULE_NAME, "[ERROR] start -> buildStairs -> loopBody -> processVolumes -> writeVolumeStairsFile -> writeFile -> onFileCreated -> err = " + err.message); + callBack(err); + return; + } + + const logText = "[WARN] Finished with File @ " + market.assetA + "_" + market.assetB + ", " + fileRecordCounter + " records inserted into " + filePath + "/" + fileName + ""; + if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] start -> buildStairs -> loopBody -> processVolumes -> writeVolumeStairsFile -> writeFile -> onFileCreated -> " + logText); } + + callback(); + + } catch (err) { + logger.write(MODULE_NAME, "[ERROR] start -> buildStairs -> periodsLoop -> loopBody -> processVolumes -> writeVolumeStairsFile -> onPreviousFileWritten -> writeFile -> onFileCreated -> err = " + err.message); + callBackFunction(global.DEFAULT_FAIL_RESPONSE); + } + } + + } catch (err) { + logger.write(MODULE_NAME, "[ERROR] start -> buildStairs -> periodsLoop -> loopBody -> processVolumes -> writeVolumeStairsFile -> onPreviousFileWritten -> writeFile -> err = " + err.message); + callBackFunction(global.DEFAULT_FAIL_RESPONSE); + } + } + + } catch (err) { + logger.write(MODULE_NAME, "[ERROR] start -> buildStairs -> periodsLoop -> loopBody -> processVolumes -> writeVolumeStairsFile -> err = " + err.message); + callBackFunction(global.DEFAULT_FAIL_RESPONSE); + } + } + + } catch (err) { + logger.write(MODULE_NAME, "[ERROR] start -> buildStairs -> periodsLoop -> loopBody -> processVolumes -> err = " + err.message); + callBackFunction(global.DEFAULT_FAIL_RESPONSE); + } + } + + } catch (err) { + logger.write(MODULE_NAME, "[ERROR] start -> buildStairs -> periodsLoop -> loopBody -> err = " + err.message); + callBackFunction(global.DEFAULT_FAIL_RESPONSE); + } + } + + function controlLoop() { + + try { + + if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] start -> buildStairs -> controlLoop -> Entering function."); } + + n++; + + if (n < global.dailyFilePeriods.length) { + + loopBody(); + + } else { + + n = 0; + + writeDataRanges(onWritten); + + function onWritten(err) { + + try { + + if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] start -> buildStairs -> controlLoop -> onWritten -> Entering function."); } + + if (err.result !== global.DEFAULT_OK_RESPONSE.result) { + logger.write(MODULE_NAME, "[ERROR] start -> buildStairs -> controlLoop -> onWritten -> err = " + err.message); + callBack(err); + return; + } + + writeStatusReport(processDate, advanceTime); + + } catch (err) { + logger.write(MODULE_NAME, "[ERROR] start -> buildStairs -> periodsLoop -> controlLoop -> onWritten -> err = " + err.message); + callBackFunction(global.DEFAULT_FAIL_RESPONSE); + } + } + } + + } catch (err) { + logger.write(MODULE_NAME, "[ERROR] start -> buildStairs -> periodsLoop -> controlLoop -> err = " + err.message); + callBackFunction(global.DEFAULT_FAIL_RESPONSE); + } + } + } + + catch (err) { + logger.write(MODULE_NAME, "[ERROR] start -> buildStairs -> err.message = " + err.message); + callBackFunction(global.DEFAULT_FAIL_RESPONSE); + } + } + + function writeDataRanges(callBack) { + + try { + + if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] start -> writeDataRanges -> Entering function."); } + + writeDataRange(contextVariables.firstTradeFile, processDate, CANDLE_STAIRS_FOLDER_NAME, onCandlesStairsDataRangeWritten); + + function onCandlesStairsDataRangeWritten(err) { + + if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] start -> writeDataRanges -> Entering function."); } + + if (err.result !== global.DEFAULT_OK_RESPONSE.result) { + logger.write(MODULE_NAME, "[ERROR] writeDataRanges -> writeDataRanges -> onCandlesStairsDataRangeWritten -> err = " + err.message); + callBack(err); + return; + } + + writeDataRange(contextVariables.firstTradeFile, processDate, VOLUME_STAIRS_FOLDER_NAME, onVolumeStairsDataRangeWritten); + + function onVolumeStairsDataRangeWritten(err) { + + if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] writeDataRanges -> writeDataRanges -> onVolumeStairsDataRangeWritten -> Entering function."); } + + if (err.result !== global.DEFAULT_OK_RESPONSE.result) { + logger.write(MODULE_NAME, "[ERROR] writeDataRanges -> writeDataRanges -> onVolumeStairsDataRangeWritten -> err = " + err.message); + callBack(err); + return; + } + + callBack(global.DEFAULT_OK_RESPONSE); + } + } + } + catch (err) { + logger.write(MODULE_NAME, "[ERROR] start -> writeDataRanges -> err = " + err.message); + callBack(global.DEFAULT_FAIL_RESPONSE); + } + + } + + function writeDataRange(pBegin, pEnd, pProductFolder, callBack) { + + try { + + if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] start -> writeDataRange -> Entering function."); } + + let dataRange = { + begin: pBegin.valueOf(), + end: pEnd.valueOf() + }; + + let fileContent = JSON.stringify(dataRange); + + let fileName = 'Data.Range.' + market.assetA + '_' + market.assetB + '.json'; + let filePath = bot.filePathRoot + "/Output/" + pProductFolder + "/" + bot.process; + + if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] start -> writeDataRange -> fileName = " + fileName); } + if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] start -> writeDataRange -> filePath = " + filePath); } + + tomStorage.createTextFile(filePath, fileName, fileContent + '\n', onFileCreated); + + function onFileCreated(err) { + + if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] start -> writeDataRange -> onFileCreated -> Entering function."); } + + if (err.result !== global.DEFAULT_OK_RESPONSE.result) { + logger.write(MODULE_NAME, "[ERROR] start -> writeDataRange -> onFileCreated -> err = " + err.message); + callBack(err); + return; + } + + if (LOG_FILE_CONTENT === true) { + logger.write(MODULE_NAME, "[INFO] start -> writeDataRange -> onFileCreated -> Content written = " + fileContent); + } + + callBack(global.DEFAULT_OK_RESPONSE); + } + } + catch (err) { + logger.write(MODULE_NAME, "[ERROR] start -> writeDataRange -> err = " + err.message); + callBack(global.DEFAULT_FAIL_RESPONSE); + } + } + + function writeStatusReport(lastFileDate, callBack) { + + if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] start -> writeStatusReport -> Entering function."); } + if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] start -> writeStatusReport -> lastFileDate = " + lastFileDate); } + + try { + + let reportKey = "AAMasters" + "-" + "AATom" + "-" + "Multi-Period-Daily" + "-" + "dataSet.V1"; + let thisReport = statusDependencies.statusReports.get(reportKey); + + thisReport.file.lastExecution = bot.processDatetime; + thisReport.file.lastFile = lastFileDate; + thisReport.save(callBack); + + } + catch (err) { + logger.write(MODULE_NAME, "[ERROR] start -> writeStatusReport -> err = " + err.message); + callBackFunction(global.DEFAULT_FAIL_RESPONSE); + } + } + } + catch (err) { + logger.write(MODULE_NAME, "[ERROR] start -> err.message = " + err.message); + callBackFunction(global.DEFAULT_FAIL_RESPONSE); + } + } +}; diff --git a/Multi-Period-Market/User.Bot.js b/Multi-Period-Market/User.Bot.js new file mode 100644 index 000000000..547e93984 --- /dev/null +++ b/Multi-Period-Market/User.Bot.js @@ -0,0 +1,460 @@ +exports.newUserBot = function newUserBot(bot, logger, COMMONS, UTILITIES, BLOB_STORAGE, FILE_STORAGE) { + + const FULL_LOG = true; + const LOG_FILE_CONTENT = false; + + const MODULE_NAME = "User Bot"; + + const EXCHANGE_NAME = "Poloniex"; + + const TRADES_FOLDER_NAME = "Trades"; + + const CANDLES_FOLDER_NAME = "Candles"; + const BOLINGER_BANDS_FOLDER_NAME = "Boliniger-Bands"; + + const commons = COMMONS.newCommons(bot, logger, UTILITIES); + + thisObject = { + initialize: initialize, + start: start + }; + + let oliviaStorage = BLOB_STORAGE.newBlobStorage(bot, logger); + let chrisStorage = BLOB_STORAGE.newBlobStorage(bot, logger); + + let utilities = UTILITIES.newCloudUtilities(bot, logger); + + let statusDependencies; + + return thisObject; + + function initialize(pStatusDependencies, pMonth, pYear, callBackFunction) { + + try { + + logger.fileName = MODULE_NAME; + logger.initialize(); + + if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] initialize -> Entering function."); } + + statusDependencies = pStatusDependencies; + + commons.initializeStorage(oliviaStorage, chrisStorage, onInizialized); + + function onInizialized(err) { + + if (err.result === global.DEFAULT_OK_RESPONSE.result) { + + if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] initialize -> onInizialized -> Initialization Succeed."); } + callBackFunction(global.DEFAULT_OK_RESPONSE); + + } else { + logger.write(MODULE_NAME, "[ERROR] initialize -> onInizialized -> err = " + err.message); + callBackFunction(err); + } + } + + } catch (err) { + logger.write(MODULE_NAME, "[ERROR] initialize -> err = " + err.message); + callBackFunction(global.DEFAULT_FAIL_RESPONSE); + } + } + + /* + + This process is going to do the following: + + Read the candles and volumes from Olivia and produce the bollinger bands out of them. + + */ + + function start(callBackFunction) { + + try { + + if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] start -> Entering function."); } + + let market = global.MARKET; + + buildStairs(); + + function buildStairs() { + + if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] start -> buildStairs -> Entering function."); } + + try { + + let n; + + periodsLoop(); + + function periodsLoop() { + + try { + + if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] start -> buildStairs -> periodsLoop -> Entering function."); } + + /* + + We will iterate through all posible periods. + + */ + + n = 0 // loop Variable representing each possible period as defined at the periods array. + + loopBody(); + + } + catch (err) { + logger.write(MODULE_NAME, "[ERROR] start -> buildStairs -> periodsLoop -> err = " + err.message); + callBackFunction(global.DEFAULT_FAIL_RESPONSE); + } + } + + function loopBody() { + + try { + + if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] start -> buildStairs -> loopBody -> Entering function."); } + + const outputPeriod = global.marketFilesPeriods[n][0]; + const timePeriod = global.marketFilesPeriods[n][1]; + + nextCandleFile(); + + function nextCandleFile() { + + try { + + if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] start -> buildStairs -> loopBody -> nextCandleFile -> Entering function."); } + + let fileName = market.assetA + '_' + market.assetB + ".json"; + + let filePathRoot = bot.devTeam + "/" + "AAOlivia" + "." + bot.version.major + "." + bot.version.minor + "/" + global.PLATFORM_CONFIG.codeName + "." + global.PLATFORM_CONFIG.version.major + "." + global.PLATFORM_CONFIG.version.minor + "/" + global.EXCHANGE_NAME + "/" + bot.dataSetVersion; + let filePath = filePathRoot + "/Output/" + CANDLES_FOLDER_NAME + "/" + "Multi-Period-Market" + "/" + timePeriod; + + oliviaStorage.getTextFile(filePath, fileName, onFileReceived, true); + + function onFileReceived(err, text) { + + try { + + if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] start -> buildStairs -> loopBody -> nextCandleFile -> onFileReceived -> Entering function."); } + if (LOG_FILE_CONTENT === true) { logger.write(MODULE_NAME, "[INFO] start -> buildStairs -> loopBody -> nextCandleFile -> onFileReceived -> text = " + text); } + + if (err.result !== global.DEFAULT_OK_RESPONSE.result) { + + logger.write(MODULE_NAME, "[ERROR] start -> buildStairs -> loopBody -> nextCandleFile -> onFileReceived -> err = " + err.message); + callBackFunction(err); + return; + + } + + let marketFile = JSON.parse(text); + + let candles = []; + let stairsArray = []; + + buildCandles(); + + function buildCandles() { + + if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] start -> buildStairs -> loopBody -> nextCandleFile -> onFileReceived -> buildCandles -> Entering function."); } + + try { + + for (let i = 0; i < marketFile.length; i++) { + + let candle = { + open: undefined, + close: undefined, + min: 10000000000000, + max: 0, + begin: undefined, + end: undefined, + direction: undefined + }; + + candle.min = marketFile[i][0]; + candle.max = marketFile[i][1]; + + candle.open = marketFile[i][2]; + candle.close = marketFile[i][3]; + + candle.begin = marketFile[i][4]; + candle.end = marketFile[i][5]; + + if (candle.open > candle.close) { candle.direction = 'down'; } + if (candle.open < candle.close) { candle.direction = 'up'; } + if (candle.open === candle.close) { candle.direction = 'side'; } + + candles.push(candle); + + } + + findCandleStairs(); + + } + catch (err) { + logger.write(MODULE_NAME, "[ERROR] start -> buildStairs -> loopBody -> nextCandleFile -> onFileReceived -> buildCandles -> err = " + err.message); + callBackFunction(global.DEFAULT_FAIL_RESPONSE); + } + } + + function findCandleStairs() { + + try { + + if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] start -> buildStairs -> loopBody -> nextCandleFile -> onFileReceived -> findCandleStairs -> Entering function."); } + + /* Finding stairs */ + + let stairs; + + for (let i = 0; i < candles.length - 1; i++) { + + let currentCandle = candles[i]; + let nextCandle = candles[i + 1]; + + if (currentCandle.direction === nextCandle.direction && currentCandle.direction !== 'side') { + + if (stairs === undefined) { + + stairs = { + open: undefined, + close: undefined, + min: 10000000000000, + max: 0, + begin: undefined, + end: undefined, + direction: undefined, + candleCount: 0, + firstMin: 0, + firstMax: 0, + lastMin: 0, + lastMax: 0 + }; + + stairs.direction = currentCandle.direction; + stairs.candleCount = 2; + + stairs.begin = currentCandle.begin; + stairs.end = nextCandle.end; + + stairs.open = currentCandle.open; + stairs.close = nextCandle.close; + + if (currentCandle.min < nextCandle.min) { stairs.min = currentCandle.min; } else { stairs.min = nextCandle.min; } + if (currentCandle.max > nextCandle.max) { stairs.max = currentCandle.max; } else { stairs.max = nextCandle.max; } + + if (stairs.direction === 'up') { + + stairs.firstMin = currentCandle.open; + stairs.firstMax = currentCandle.close; + + stairs.lastMin = nextCandle.open; + stairs.lastMax = nextCandle.close; + + } else { + + stairs.firstMin = currentCandle.close; + stairs.firstMax = currentCandle.open; + + stairs.lastMin = nextCandle.close; + stairs.lastMax = nextCandle.open; + + } + + + } else { + + stairs.candleCount++; + stairs.end = nextCandle.end; + stairs.close = nextCandle.close; + + if (stairs.min < nextCandle.min) { stairs.min = currentCandle.min; } + if (stairs.max > nextCandle.max) { stairs.max = currentCandle.max; } + + if (stairs.direction === 'up') { + + stairs.lastMin = nextCandle.open; + stairs.lastMax = nextCandle.close; + + } else { + + stairs.lastMin = nextCandle.close; + stairs.lastMax = nextCandle.open; + + } + + } + + } else { + + if (stairs !== undefined) { + stairsArray.push(stairs); + stairs = undefined; + } + } + } + + writeCandleStairsFile(); + } + catch (err) { + logger.write(MODULE_NAME, "[ERROR] start -> buildStairs -> loopBody -> nextCandleFile -> onFileReceived -> findCandleStairs -> err = " + err.message); + callBackFunction(global.DEFAULT_FAIL_RESPONSE); + } + } + + function writeCandleStairsFile() { + + try { + + if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] start -> buildStairs -> loopBody -> nextCandleFile -> onFileReceived -> writeCandleStairsFile -> Entering function."); } + + let separator = ""; + let fileRecordCounter = 0; + + let fileContent = ""; + + for (i = 0; i < stairsArray.length; i++) { + + let stairs = stairsArray[i]; + + fileContent = fileContent + separator + '[' + + stairs.open + "," + + stairs.close + "," + + stairs.min + "," + + stairs.max + "," + + stairs.begin + "," + + stairs.end + "," + + '"' + stairs.direction + '"' + "," + + stairs.candleCount + "," + + stairs.firstMin + "," + + stairs.firstMax + "," + + stairs.lastMin + "," + + stairs.lastMax + "]"; + + if (separator === "") { separator = ","; } + + fileRecordCounter++; + + } + + fileContent = "[" + fileContent + "]"; + + let fileName = '' + market.assetA + '_' + market.assetB + '.json'; + + let filePathRoot = bot.devTeam + "/" + bot.codeName + "." + bot.version.major + "." + bot.version.minor + "/" + global.PLATFORM_CONFIG.codeName + "." + global.PLATFORM_CONFIG.version.major + "." + global.PLATFORM_CONFIG.version.minor + "/" + global.EXCHANGE_NAME + "/" + bot.dataSetVersion; + let filePath = filePathRoot + "/Output/" + BOLINGER_BANDS_FOLDER_NAME + "/" + "Multi-Period-Market" + "/" + timePeriod; + + chrisStorage.createTextFile(filePath, fileName, fileContent + '\n', onFileCreated); + + function onFileCreated(err) { + + try { + + if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] start -> buildStairs -> loopBody -> nextCandleFile -> onFileReceived -> writeCandleStairsFile -> onFileCreated -> Entering function."); } + if (LOG_FILE_CONTENT === true) { logger.write(MODULE_NAME, "[INFO] start -> buildStairs -> loopBody -> nextCandleFile -> onFileReceived -> writeCandleStairsFile -> onFileCreated -> fileContent = " + fileContent); } + + if (err.result !== global.DEFAULT_OK_RESPONSE.result) { + + logger.write(MODULE_NAME, "[ERROR] start -> buildStairs -> loopBody -> nextCandleFile -> onFileReceived -> writeCandleStairsFile -> onFileCreated -> err = " + err.message); + logger.write(MODULE_NAME, "[ERROR] start -> buildStairs -> loopBody -> nextCandleFile -> onFileReceived -> writeCandleStairsFile -> onFileCreated -> filePath = " + filePath); + logger.write(MODULE_NAME, "[ERROR] start -> buildStairs -> loopBody -> nextCandleFile -> onFileReceived -> writeCandleStairsFile -> onFileCreated -> market = " + market.assetA + "_" + market.assetB); + + callBackFunction(err); + return; + + } + + controlLoop(); + + } + catch (err) { + logger.write(MODULE_NAME, "[ERROR] start -> buildStairs -> loopBody -> nextCandleFile -> onFileReceived -> writeCandleStairsFile -> onFileCreated -> err = " + err.message); + callBackFunction(global.DEFAULT_FAIL_RESPONSE); + } + } + } + catch (err) { + logger.write(MODULE_NAME, "[ERROR] start -> buildStairs -> loopBody -> nextCandleFile -> onFileReceived -> writeCandleStairsFile -> err = " + err.message); + callBackFunction(global.DEFAULT_FAIL_RESPONSE); + } + } + } + catch (err) { + logger.write(MODULE_NAME, "[ERROR] start -> buildStairs -> loopBody -> nextCandleFile -> onFileReceived -> err = " + err.message); + callBackFunction(global.DEFAULT_FAIL_RESPONSE); + } + } + } + catch (err) { + logger.write(MODULE_NAME, "[ERROR] start -> buildStairs -> loopBody -> nextCandleFile -> err = " + err.message); + callBackFunction(global.DEFAULT_FAIL_RESPONSE); + } + } + + } + catch (err) { + logger.write(MODULE_NAME, "[ERROR] start -> buildStairs -> loopBody -> err = " + err.message); + callBackFunction(global.DEFAULT_FAIL_RESPONSE); + } + } + + function controlLoop() { + + try { + + if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] start -> buildStairs -> controlLoop -> Entering function."); } + + n++; + + if (n < global.marketFilesPeriods.length) { + + loopBody(); + + } else { + + writeStatusReport(callBackFunction); + + } + } + catch (err) { + logger.write(MODULE_NAME, "[ERROR] start -> buildStairs -> controlLoop -> err = " + err.message); + callBackFunction(global.DEFAULT_FAIL_RESPONSE); + } + } + + } + catch (err) { + logger.write(MODULE_NAME, "[ERROR] start -> buildStairs -> err = " + err.message); + callBackFunction(global.DEFAULT_FAIL_RESPONSE); + } + } + + function writeStatusReport(callBack) { + + if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] start -> writeStatusReport -> Entering function."); } + + try { + + let reportKey = "AAMasters" + "-" + "AAChris" + "-" + "Multi-Period-Market" + "-" + "dataSet.V1"; + let thisReport = statusDependencies.statusReports.get(reportKey); + + thisReport.file.lastExecution = bot.processDatetime; + thisReport.save(callBack); + + } + catch (err) { + logger.write(MODULE_NAME, "[ERROR] start -> writeStatusReport -> err = " + err.message); + callBackFunction(global.DEFAULT_FAIL_RESPONSE); + } + } + } + catch (err) { + logger.write(MODULE_NAME, "[ERROR] start -> err = " + err.message); + callBackFunction(global.DEFAULT_FAIL_RESPONSE); + } + } +}; diff --git a/Project.njsproj b/Project.njsproj new file mode 100644 index 000000000..4cab6c556 --- /dev/null +++ b/Project.njsproj @@ -0,0 +1,91 @@ + + + + Debug + 2.0 + {aa2901bc-8f81-40f0-a402-5ca79a3f22ad} + + ShowAllFiles + + + c:\users\luis\source\repos\AAOlivia\Multi-Period-Market + . + {3AF33F2E-1136-4D97-BBB7-1795711AC8B8};{349c5851-65df-11da-9384-00065b846f21};{9092AA53-FB77-4645-B42D-1CCCA6BD08BD} + 14.0 + $(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion) + Project + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + False + True + 0 + / + http://localhost:48022/ + False + True + http://localhost:1337 + False + + + + + + + CurrentPage + True + False + False + False + + + + + + + + + False + False + + + + + \ No newline at end of file diff --git a/README.md b/README.md new file mode 100644 index 000000000..b2e66cfb1 --- /dev/null +++ b/README.md @@ -0,0 +1,7 @@ +# I'm Chris, an AA i-Bot! + +# Disclaimer + +THE AA MASTERS BOTS AND THEIR ASSOCIATED PRODUCTS AND SERVICES ARE PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, SUITABILITY FOR A PARTICULAR PURPOSE, OR NON-INFRINGEMENT. + +IN NO EVENT WILL ADVANCED ALGOS BE LIABLE TO ANY PARTY FOR ANY DIRECT, INDIRECT, SPECIAL OR OTHER CONSEQUENTIAL DAMAGES FOR ANY USE OF THE AACLOUD, THE AA ARENA COMPETITION, THE AA MASTERS BOTS, OR ANY OTHER ASSOCIATED SERVICE OR WEB SITE, INCLUDING, WITHOUT LIMITATION, ANY LOST PROFITS, BUSINESS INTERRUPTION, LOSS OF FUNDS, PROGRAMS OR OTHER DATA OR OTHERWISE, EVEN IF WE ARE EXPRESSLY ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. diff --git a/Tom.png b/Tom.png new file mode 100644 index 0000000000000000000000000000000000000000..dfd3561738ce327a580b093e53e93a9ccc0f38c8 GIT binary patch literal 16438 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 a*uvEPKMRCZ$^iZe07;6 Date: Wed, 20 Feb 2019 09:25:41 +0100 Subject: [PATCH 02/40] Market Files generated successfully --- Multi-Period-Market/User.Bot.js | 203 +++++++++++--------------------- Tom.png | Bin 16438 -> 0 bytes this.bot.config.json | 16 +-- 3 files changed, 74 insertions(+), 145 deletions(-) delete mode 100644 Tom.png diff --git a/Multi-Period-Market/User.Bot.js b/Multi-Period-Market/User.Bot.js index 547e93984..8725317f9 100644 --- a/Multi-Period-Market/User.Bot.js +++ b/Multi-Period-Market/User.Bot.js @@ -10,7 +10,7 @@ const TRADES_FOLDER_NAME = "Trades"; const CANDLES_FOLDER_NAME = "Candles"; - const BOLINGER_BANDS_FOLDER_NAME = "Boliniger-Bands"; + const BOLINGER_BANDS_FOLDER_NAME = "Bollinger-Bands"; const commons = COMMONS.newCommons(bot, logger, UTILITIES); @@ -64,7 +64,7 @@ This process is going to do the following: - Read the candles and volumes from Olivia and produce the bollinger bands out of them. + Read the candles from Olivia and produce the bollinger bands out of them. */ @@ -76,11 +76,11 @@ let market = global.MARKET; - buildStairs(); + buildBands(); - function buildStairs() { + function buildBands() { - if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] start -> buildStairs -> Entering function."); } + if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] start -> buildBands -> Entering function."); } try { @@ -92,7 +92,7 @@ try { - if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] start -> buildStairs -> periodsLoop -> Entering function."); } + if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] start -> buildBands -> periodsLoop -> Entering function."); } /* @@ -106,7 +106,7 @@ } catch (err) { - logger.write(MODULE_NAME, "[ERROR] start -> buildStairs -> periodsLoop -> err = " + err.message); + logger.write(MODULE_NAME, "[ERROR] start -> buildBands -> periodsLoop -> err = " + err.message); callBackFunction(global.DEFAULT_FAIL_RESPONSE); } } @@ -115,7 +115,7 @@ try { - if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] start -> buildStairs -> loopBody -> Entering function."); } + if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] start -> buildBands -> loopBody -> Entering function."); } const outputPeriod = global.marketFilesPeriods[n][0]; const timePeriod = global.marketFilesPeriods[n][1]; @@ -126,7 +126,7 @@ try { - if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] start -> buildStairs -> loopBody -> nextCandleFile -> Entering function."); } + if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] start -> buildBands -> loopBody -> nextCandleFile -> Entering function."); } let fileName = market.assetA + '_' + market.assetB + ".json"; @@ -139,12 +139,12 @@ try { - if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] start -> buildStairs -> loopBody -> nextCandleFile -> onFileReceived -> Entering function."); } - if (LOG_FILE_CONTENT === true) { logger.write(MODULE_NAME, "[INFO] start -> buildStairs -> loopBody -> nextCandleFile -> onFileReceived -> text = " + text); } + if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] start -> buildBands -> loopBody -> nextCandleFile -> onFileReceived -> Entering function."); } + if (LOG_FILE_CONTENT === true) { logger.write(MODULE_NAME, "[INFO] start -> buildBands -> loopBody -> nextCandleFile -> onFileReceived -> text = " + text); } if (err.result !== global.DEFAULT_OK_RESPONSE.result) { - logger.write(MODULE_NAME, "[ERROR] start -> buildStairs -> loopBody -> nextCandleFile -> onFileReceived -> err = " + err.message); + logger.write(MODULE_NAME, "[ERROR] start -> buildBands -> loopBody -> nextCandleFile -> onFileReceived -> err = " + err.message); callBackFunction(err); return; @@ -153,13 +153,13 @@ let marketFile = JSON.parse(text); let candles = []; - let stairsArray = []; + let bandsArray = []; buildCandles(); function buildCandles() { - if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] start -> buildStairs -> loopBody -> nextCandleFile -> onFileReceived -> buildCandles -> Entering function."); } + if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] start -> buildBands -> loopBody -> nextCandleFile -> onFileReceived -> buildCandles -> Entering function."); } try { @@ -184,156 +184,85 @@ candle.begin = marketFile[i][4]; candle.end = marketFile[i][5]; - if (candle.open > candle.close) { candle.direction = 'down'; } - if (candle.open < candle.close) { candle.direction = 'up'; } - if (candle.open === candle.close) { candle.direction = 'side'; } - candles.push(candle); } - findCandleStairs(); + buildBands(); } catch (err) { - logger.write(MODULE_NAME, "[ERROR] start -> buildStairs -> loopBody -> nextCandleFile -> onFileReceived -> buildCandles -> err = " + err.message); + logger.write(MODULE_NAME, "[ERROR] start -> buildBands -> loopBody -> nextCandleFile -> onFileReceived -> buildCandles -> err = " + err.message); callBackFunction(global.DEFAULT_FAIL_RESPONSE); } } - function findCandleStairs() { + function buildBands() { try { - if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] start -> buildStairs -> loopBody -> nextCandleFile -> onFileReceived -> findCandleStairs -> Entering function."); } + if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] start -> buildBands -> loopBody -> nextCandleFile -> onFileReceived -> buildBands -> Entering function."); } - /* Finding stairs */ + let n = 20; - let stairs; + /* Building bands */ - for (let i = 0; i < candles.length - 1; i++) { + let band; - let currentCandle = candles[i]; - let nextCandle = candles[i + 1]; + for (let i = n - 1; i < candles.length - 1; i++) { // Go through all the candles to generate a band segment for each of them. - if (currentCandle.direction === nextCandle.direction && currentCandle.direction !== 'side') { - - if (stairs === undefined) { - - stairs = { - open: undefined, - close: undefined, - min: 10000000000000, - max: 0, - begin: undefined, - end: undefined, - direction: undefined, - candleCount: 0, - firstMin: 0, - firstMax: 0, - lastMin: 0, - lastMax: 0 - }; - - stairs.direction = currentCandle.direction; - stairs.candleCount = 2; - - stairs.begin = currentCandle.begin; - stairs.end = nextCandle.end; - - stairs.open = currentCandle.open; - stairs.close = nextCandle.close; - - if (currentCandle.min < nextCandle.min) { stairs.min = currentCandle.min; } else { stairs.min = nextCandle.min; } - if (currentCandle.max > nextCandle.max) { stairs.max = currentCandle.max; } else { stairs.max = nextCandle.max; } - - if (stairs.direction === 'up') { - - stairs.firstMin = currentCandle.open; - stairs.firstMax = currentCandle.close; - - stairs.lastMin = nextCandle.open; - stairs.lastMax = nextCandle.close; - - } else { - - stairs.firstMin = currentCandle.close; - stairs.firstMax = currentCandle.open; - - stairs.lastMin = nextCandle.close; - stairs.lastMax = nextCandle.open; - - } - - - } else { - - stairs.candleCount++; - stairs.end = nextCandle.end; - stairs.close = nextCandle.close; - - if (stairs.min < nextCandle.min) { stairs.min = currentCandle.min; } - if (stairs.max > nextCandle.max) { stairs.max = currentCandle.max; } - - if (stairs.direction === 'up') { - - stairs.lastMin = nextCandle.open; - stairs.lastMax = nextCandle.close; - - } else { - - stairs.lastMin = nextCandle.close; - stairs.lastMax = nextCandle.open; - - } - - } - - } else { - - if (stairs !== undefined) { - stairsArray.push(stairs); - stairs = undefined; - } + let movingAverage = 0; + for (let j = i - n + 1; j < i + 1; j++) { // go through the last n candles to calculate the moving average. + movingAverage = movingAverage + candles[j].close; } + movingAverage = movingAverage / n; + + let standardDeviation = 0; + for (let j = i - n + 1; j < i + 1; j++) { // go through the last n candles to calculate the standard deviation. + standardDeviation = standardDeviation + Math.pow (candles[j].close - movingAverage, 2); + } + standardDeviation = standardDeviation / n; + standardDeviation = Math.sqrt(standardDeviation); + + band = { + begin: candles[i].begin, + end: candles[i].end, + movingAverage: movingAverage, + standardDeviation: standardDeviation + }; + + bandsArray.push(band); + } - writeCandleStairsFile(); + writeBandsFile(); } catch (err) { - logger.write(MODULE_NAME, "[ERROR] start -> buildStairs -> loopBody -> nextCandleFile -> onFileReceived -> findCandleStairs -> err = " + err.message); + logger.write(MODULE_NAME, "[ERROR] start -> buildBands -> loopBody -> nextCandleFile -> onFileReceived -> buildBands -> err = " + err.message); callBackFunction(global.DEFAULT_FAIL_RESPONSE); } } - function writeCandleStairsFile() { + function writeBandsFile() { try { - if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] start -> buildStairs -> loopBody -> nextCandleFile -> onFileReceived -> writeCandleStairsFile -> Entering function."); } + if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] start -> buildBands -> loopBody -> nextCandleFile -> onFileReceived -> writeBandsFile -> Entering function."); } let separator = ""; let fileRecordCounter = 0; let fileContent = ""; - for (i = 0; i < stairsArray.length; i++) { + for (i = 0; i < bandsArray.length; i++) { - let stairs = stairsArray[i]; + let band = bandsArray[i]; fileContent = fileContent + separator + '[' + - stairs.open + "," + - stairs.close + "," + - stairs.min + "," + - stairs.max + "," + - stairs.begin + "," + - stairs.end + "," + - '"' + stairs.direction + '"' + "," + - stairs.candleCount + "," + - stairs.firstMin + "," + - stairs.firstMax + "," + - stairs.lastMin + "," + - stairs.lastMax + "]"; + band.begin + "," + + band.end + "," + + band.movingAverage + "," + + band.standardDeviation + "]"; if (separator === "") { separator = ","; } @@ -354,14 +283,14 @@ try { - if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] start -> buildStairs -> loopBody -> nextCandleFile -> onFileReceived -> writeCandleStairsFile -> onFileCreated -> Entering function."); } - if (LOG_FILE_CONTENT === true) { logger.write(MODULE_NAME, "[INFO] start -> buildStairs -> loopBody -> nextCandleFile -> onFileReceived -> writeCandleStairsFile -> onFileCreated -> fileContent = " + fileContent); } + if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] start -> buildBands -> loopBody -> nextCandleFile -> onFileReceived -> writeBandsFile -> onFileCreated -> Entering function."); } + if (LOG_FILE_CONTENT === true) { logger.write(MODULE_NAME, "[INFO] start -> buildBands -> loopBody -> nextCandleFile -> onFileReceived -> writeBandsFile -> onFileCreated -> fileContent = " + fileContent); } if (err.result !== global.DEFAULT_OK_RESPONSE.result) { - logger.write(MODULE_NAME, "[ERROR] start -> buildStairs -> loopBody -> nextCandleFile -> onFileReceived -> writeCandleStairsFile -> onFileCreated -> err = " + err.message); - logger.write(MODULE_NAME, "[ERROR] start -> buildStairs -> loopBody -> nextCandleFile -> onFileReceived -> writeCandleStairsFile -> onFileCreated -> filePath = " + filePath); - logger.write(MODULE_NAME, "[ERROR] start -> buildStairs -> loopBody -> nextCandleFile -> onFileReceived -> writeCandleStairsFile -> onFileCreated -> market = " + market.assetA + "_" + market.assetB); + logger.write(MODULE_NAME, "[ERROR] start -> buildBands -> loopBody -> nextCandleFile -> onFileReceived -> writeBandsFile -> onFileCreated -> err = " + err.message); + logger.write(MODULE_NAME, "[ERROR] start -> buildBands -> loopBody -> nextCandleFile -> onFileReceived -> writeBandsFile -> onFileCreated -> filePath = " + filePath); + logger.write(MODULE_NAME, "[ERROR] start -> buildBands -> loopBody -> nextCandleFile -> onFileReceived -> writeBandsFile -> onFileCreated -> market = " + market.assetA + "_" + market.assetB); callBackFunction(err); return; @@ -372,32 +301,32 @@ } catch (err) { - logger.write(MODULE_NAME, "[ERROR] start -> buildStairs -> loopBody -> nextCandleFile -> onFileReceived -> writeCandleStairsFile -> onFileCreated -> err = " + err.message); + logger.write(MODULE_NAME, "[ERROR] start -> buildBands -> loopBody -> nextCandleFile -> onFileReceived -> writeBandsFile -> onFileCreated -> err = " + err.message); callBackFunction(global.DEFAULT_FAIL_RESPONSE); } } } catch (err) { - logger.write(MODULE_NAME, "[ERROR] start -> buildStairs -> loopBody -> nextCandleFile -> onFileReceived -> writeCandleStairsFile -> err = " + err.message); + logger.write(MODULE_NAME, "[ERROR] start -> buildBands -> loopBody -> nextCandleFile -> onFileReceived -> writeBandsFile -> err = " + err.message); callBackFunction(global.DEFAULT_FAIL_RESPONSE); } } } catch (err) { - logger.write(MODULE_NAME, "[ERROR] start -> buildStairs -> loopBody -> nextCandleFile -> onFileReceived -> err = " + err.message); + logger.write(MODULE_NAME, "[ERROR] start -> buildBands -> loopBody -> nextCandleFile -> onFileReceived -> err = " + err.message); callBackFunction(global.DEFAULT_FAIL_RESPONSE); } } } catch (err) { - logger.write(MODULE_NAME, "[ERROR] start -> buildStairs -> loopBody -> nextCandleFile -> err = " + err.message); + logger.write(MODULE_NAME, "[ERROR] start -> buildBands -> loopBody -> nextCandleFile -> err = " + err.message); callBackFunction(global.DEFAULT_FAIL_RESPONSE); } } } catch (err) { - logger.write(MODULE_NAME, "[ERROR] start -> buildStairs -> loopBody -> err = " + err.message); + logger.write(MODULE_NAME, "[ERROR] start -> buildBands -> loopBody -> err = " + err.message); callBackFunction(global.DEFAULT_FAIL_RESPONSE); } } @@ -406,7 +335,7 @@ try { - if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] start -> buildStairs -> controlLoop -> Entering function."); } + if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] start -> buildBands -> controlLoop -> Entering function."); } n++; @@ -421,14 +350,14 @@ } } catch (err) { - logger.write(MODULE_NAME, "[ERROR] start -> buildStairs -> controlLoop -> err = " + err.message); + logger.write(MODULE_NAME, "[ERROR] start -> buildBands -> controlLoop -> err = " + err.message); callBackFunction(global.DEFAULT_FAIL_RESPONSE); } } } catch (err) { - logger.write(MODULE_NAME, "[ERROR] start -> buildStairs -> err = " + err.message); + logger.write(MODULE_NAME, "[ERROR] start -> buildBands -> err = " + err.message); callBackFunction(global.DEFAULT_FAIL_RESPONSE); } } diff --git a/Tom.png b/Tom.png deleted file mode 100644 index dfd3561738ce327a580b093e53e93a9ccc0f38c8..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 16438 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 a*uvEPKMRCZ$^iZe07;6 Date: Wed, 20 Feb 2019 21:13:14 +0100 Subject: [PATCH 03/40] Market Working with added .close, pending on Daily --- Multi-Period-Daily/User.Bot.js | 1312 +++++-------------------------- Multi-Period-Market/User.Bot.js | 10 +- 2 files changed, 221 insertions(+), 1101 deletions(-) diff --git a/Multi-Period-Daily/User.Bot.js b/Multi-Period-Daily/User.Bot.js index 4a84367a2..d7d878654 100644 --- a/Multi-Period-Daily/User.Bot.js +++ b/Multi-Period-Daily/User.Bot.js @@ -5,7 +5,6 @@ const LOG_FILE_CONTENT = false; const GMT_SECONDS = ':00.000 GMT+0000'; - const GMT_MILI_SECONDS = '.000 GMT+0000'; const ONE_DAY_IN_MILISECONDS = 24 * 60 * 60 * 1000; const MODULE_NAME = "User Bot"; @@ -15,10 +14,7 @@ const TRADES_FOLDER_NAME = "Trades"; const CANDLES_FOLDER_NAME = "Candles"; - const CANDLE_STAIRS_FOLDER_NAME = "Candle-Stairs"; - - const VOLUMES_FOLDER_NAME = "Volumes"; - const VOLUME_STAIRS_FOLDER_NAME = "Volume-Stairs"; + const BOLLINGER_BANDS_FOLDER_NAME = "Bollinger-Bands"; const commons = COMMONS.newCommons(bot, logger, UTILITIES); @@ -28,7 +24,7 @@ }; let oliviaStorage = BLOB_STORAGE.newBlobStorage(bot, logger); - let tomStorage = BLOB_STORAGE.newBlobStorage(bot, logger); + let chrisStorage = BLOB_STORAGE.newBlobStorage(bot, logger); let utilities = UTILITIES.newCloudUtilities(bot, logger); @@ -47,7 +43,7 @@ statusDependencies = pStatusDependencies; - commons.initializeStorage(oliviaStorage, tomStorage, onInizialized); + commons.initializeStorage(oliviaStorage, chrisStorage, onInizialized); function onInizialized(err) { @@ -72,7 +68,7 @@ This process is going to do the following: - Read the candles and volumes from Olivia and produce for each market two files with candles stairs and volumes stairs respectively. + Read the candles from Olivia and produce daily files with bollinger bands. */ @@ -82,19 +78,14 @@ if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] start -> Entering function."); } - /* One of the challenges of this process is that each imput file contains one day of candles. So if a stair spans more than one day - then we dont want to break the stais in two pieces. What we do is that we read to candles files at the time and record at the current - date all stairs of the day plus the ones thas spans to the second day without bigining at the second day. Then when we process the next - day, we must remember where the last stairs of each type endded, so as not to create overlapping stairs in the current day. */ - let market = global.MARKET; /* Context Variables */ let contextVariables = { - lastCandleFile: undefined, // Datetime of the last file files sucessfully produced by this process. + lastBandFile: undefined, // Datetime of the last file files sucessfully produced by this process. firstTradeFile: undefined, // Datetime of the first trade file in the whole market history. - maxCandleFile: undefined // Datetime of the last file available to be used as an input of this process. + maxBandFile: undefined // Datetime of the last file available to be used as an input of this process. }; let previousDay; // Holds the date of the previous day relative to the processing date. @@ -181,11 +172,11 @@ return; } - contextVariables.maxCandleFile = new Date(thisReport.lastFile.valueOf()); + contextVariables.maxBandFile = new Date(thisReport.lastFile.valueOf()); /* Finally we get our own Status Report. */ - reportKey = "AAMasters" + "-" + "AATom" + "-" + "Multi-Period-Daily" + "-" + "dataSet.V1"; + reportKey = "AAMasters" + "-" + "AAChris" + "-" + "Multi-Period-Daily" + "-" + "dataSet.V1"; if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] start -> getContextVariables -> reportKey = " + reportKey); } statusReport = statusDependencies.statusReports.get(reportKey); @@ -206,37 +197,37 @@ if (thisReport.lastFile !== undefined) { - contextVariables.lastCandleFile = new Date(thisReport.lastFile); + contextVariables.lastBandFile = new Date(thisReport.lastFile); /* - The stairs objects can span more than one day. In order not to cut these objects into two when this happens, this process will alsways read - 3 files. + The bands objects needs to be calculated over more than one day in some situations. In order to simplify the calculations we will + always load the last 2 days of candles, and run the calculations on that array. - 1. The first file is a stairs file corresponding to processDay -2. From there we will know where the last staris ended. - 2. The second is a candle or volume file corresponding to processDay -1. - 3. The third is a candle of volume file at processDay. + 1. So first we will load the candles file of processDay -1. + 2. Secondly we will load the candles file of processDay. - We will recalculate 2 and 3 considering the objects already in 1, so as to make the transition between 2 and 3 smooth. + After reading these two files we will add all candles to a unique array. */ if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] start -> getContextVariables -> thisReport.lastFile !== undefined"); } - buildStairs(); + buildBands(); return; } else { /* In the case when there is no status report, we take the date of the file with the first trades as the begining of the market. Then we will - go one day back in time, so that when we enter the loop, one day will be added and we will be exactly at the date where the first trades occured. + go one day further in time, so that the previous day does fine a file at the begining of the market. */ - contextVariables.lastCandleFile = new Date(contextVariables.firstTradeFile.getUTCFullYear() + "-" + (contextVariables.firstTradeFile.getUTCMonth() + 1) + "-" + contextVariables.firstTradeFile.getUTCDate() + " " + "00:00" + GMT_SECONDS); + contextVariables.lastBandFile = new Date(contextVariables.firstTradeFile.getUTCFullYear() + "-" + (contextVariables.firstTradeFile.getUTCMonth() + 1) + "-" + contextVariables.firstTradeFile.getUTCDate() + " " + "00:00" + GMT_SECONDS); + contextVariables.lastBandFile = new Date(contextVariables.lastBandFile.valueOf() + ONE_DAY_IN_MILISECONDS); if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] start -> getContextVariables -> thisReport.lastFile === undefined"); } - if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] start -> getContextVariables -> contextVariables.lastCandleFile = " + contextVariables.lastCandleFile); } + if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] start -> getContextVariables -> contextVariables.lastBandFile = " + contextVariables.lastBandFile); } - buildStairs(); + buildBands(); return; } @@ -250,15 +241,15 @@ } } - function buildStairs() { + function buildBands() { try { - if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] start -> buildStairs -> Entering function."); } + if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] start -> buildBands -> Entering function."); } let n; - processDate = new Date(contextVariables.lastCandleFile.valueOf() - ONE_DAY_IN_MILISECONDS); // Go back one day to start well when we advance time at the begining of the loop. - if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] start -> buildStairs -> processDate = " + processDate); } + processDate = new Date(contextVariables.lastBandFile.valueOf() - ONE_DAY_IN_MILISECONDS); // Go back one day to start well when we advance time at the begining of the loop. + if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] start -> buildBands -> processDate = " + processDate); } advanceTime(); @@ -268,20 +259,20 @@ logger.newInternalLoop(bot.codeName, bot.process); - if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] start -> buildStairs -> advanceTime -> Entering function."); } + if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] start -> buildBands -> advanceTime -> Entering function."); } processDate = new Date(processDate.valueOf() + ONE_DAY_IN_MILISECONDS); previousDay = new Date(processDate.valueOf() - ONE_DAY_IN_MILISECONDS); - if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] start -> buildStairs -> advanceTime -> processDate = " + processDate); } - if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] start -> buildStairs -> advanceTime -> previousDay = " + previousDay); } + if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] start -> buildBands -> advanceTime -> processDate = " + processDate); } + if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] start -> buildBands -> advanceTime -> previousDay = " + previousDay); } /* Validation that we are not going past the head of the market. */ - if (processDate.valueOf() > contextVariables.maxCandleFile.valueOf()) { + if (processDate.valueOf() > contextVariables.maxBandFile.valueOf()) { const logText = "Head of the market found @ " + previousDay.getUTCFullYear() + "/" + (previousDay.getUTCMonth() + 1) + "/" + previousDay.getUTCDate() + "."; - if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] start -> buildStairs -> advanceTime -> " + logText); } + if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] start -> buildBands -> advanceTime -> " + logText); } callBackFunction(global.DEFAULT_OK_RESPONSE); return; @@ -291,7 +282,7 @@ periodsLoop(); } catch (err) { - logger.write(MODULE_NAME, "[ERROR] start -> buildStairs -> advanceTime -> err = " + err.message); + logger.write(MODULE_NAME, "[ERROR] start -> buildBands -> advanceTime -> err = " + err.message); callBackFunction(global.DEFAULT_FAIL_RESPONSE); } } @@ -300,7 +291,7 @@ try { - if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] start -> buildStairs -> periodsLoop -> Entering function."); } + if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] start -> buildBands -> periodsLoop -> Entering function."); } /* @@ -313,7 +304,7 @@ loopBody(); } catch (err) { - logger.write(MODULE_NAME, "[ERROR] start -> buildStairs -> periodsLoop -> err = " + err.message); + logger.write(MODULE_NAME, "[ERROR] start -> buildBands -> periodsLoop -> err = " + err.message); callBackFunction(global.DEFAULT_FAIL_RESPONSE); } } @@ -322,1151 +313,290 @@ try { - if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] start -> buildStairs -> loopBody -> Entering function."); } + if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] start -> buildBands -> loopBody -> Entering function."); } const timePeriod = global.dailyFilePeriods[n][1]; - let endOfLastCandleStair = new Date(previousDay.valueOf() - ONE_DAY_IN_MILISECONDS); - let endOfLastBuyVolumeStair = new Date(previousDay.valueOf() - ONE_DAY_IN_MILISECONDS); - let endOfLastSellVolumeStair = new Date(previousDay.valueOf() - ONE_DAY_IN_MILISECONDS); + let candles = []; // Here we will put all the candles of the 2 files read. - /* - By default we set the starting date of the processDay - 2 file. If we find the file this value shoulld be overwritten by the value of the end property - of the last object on the file. - */ + let previousDayFile; + let processDayFile; - endOfLastCandleStair = endOfLastCandleStair.valueOf(); - endOfLastBuyVolumeStair = endOfLastBuyVolumeStair.valueOf(); - endOfLastSellVolumeStair = endOfLastSellVolumeStair.valueOf(); + getPreviousDayFile(); - getEndOfLastCandleStair(); - - function getEndOfLastCandleStair() { + function getPreviousDayFile() { try { - if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] start -> buildStairs -> loopBody -> getEndOfLastCandleStair -> Entering function."); } + if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] start -> buildBands -> loopBody -> getPreviousDayFile -> Entering function."); } - let fileDate = new Date(previousDay.valueOf() - ONE_DAY_IN_MILISECONDS); - getCandleStairsFile(); + let dateForPath = previousDay.getUTCFullYear() + '/' + utilities.pad(previousDay.getUTCMonth() + 1, 2) + '/' + utilities.pad(previousDay.getUTCDate(), 2); + let fileName = market.assetA + '_' + market.assetB + ".json" - function getCandleStairsFile() { + let filePathRoot = bot.devTeam + "/" + "AAOlivia" + "." + bot.version.major + "." + bot.version.minor + "/" + global.PLATFORM_CONFIG.codeName + "." + global.PLATFORM_CONFIG.version.major + "." + global.PLATFORM_CONFIG.version.minor + "/" + global.EXCHANGE_NAME + "/" + bot.dataSetVersion; + let filePath = filePathRoot + "/Output/" + CANDLES_FOLDER_NAME + '/' + "Multi-Period-Daily" + "/" + timePeriod + "/" + dateForPath; + + oliviaStorage.getTextFile(filePath, fileName, onCurrentDayFileReceived, true); + + function onCurrentDayFileReceived(err, text) { try { - if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] start -> buildStairs -> loopBody -> getEndOfLastCandleStair -> getCandleStairsFile -> Entering function."); } + if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] start -> buildBands -> loopBody -> getPreviousDayFile -> onCurrentDayFileReceived -> Entering function."); } + if (LOG_FILE_CONTENT === true) { logger.write(MODULE_NAME, "[INFO] start -> buildBands -> loopBody -> getPreviousDayFile -> onCurrentDayFileReceived -> text = " + text); } - let dateForPath = fileDate.getUTCFullYear() + '/' + utilities.pad(fileDate.getUTCMonth() + 1, 2) + '/' + utilities.pad(fileDate.getUTCDate(), 2); - let fileName = market.assetA + '_' + market.assetB + ".json" - - let filePathRoot = bot.devTeam + "/" + bot.codeName + "." + bot.version.major + "." + bot.version.minor + "/" + global.PLATFORM_CONFIG.codeName + "." + global.PLATFORM_CONFIG.version.major + "." + global.PLATFORM_CONFIG.version.minor + "/" + global.EXCHANGE_NAME + "/" + bot.dataSetVersion; - let filePath = filePathRoot + "/Output/" + CANDLE_STAIRS_FOLDER_NAME + '/' + "Multi-Period-Daily" + "/" + timePeriod + "/" + dateForPath; - - tomStorage.getTextFile(filePath, fileName, onFileReceived, true); - - function onFileReceived(err, text) { - - try { - - if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] start -> buildStairs -> loopBody -> getEndOfLastCandleStair -> getCandleStairsFile -> onFileReceived -> Entering function."); } - - if (LOG_FILE_CONTENT === true) { logger.write(MODULE_NAME, "[INFO] start -> buildStairs -> loopBody -> getEndOfLastCandleStair -> getCandleStairsFile -> onFileReceived -> text = " + text); } - - if ( - err.result === global.CUSTOM_FAIL_RESPONSE.result && - (err.message === 'Folder does not exist.' || err.message === 'File does not exist.') - ) { - - getEndOfLastVolumeStair(); - return; - } - - let stairsFile = JSON.parse(text); - - if (stairsFile.length > 0) { - - endOfLastCandleStair = stairsFile[stairsFile.length - 1][5]; // We get from the last regord the end value. Position 5 = Stairs.end - getEndOfLastVolumeStair(); - - } else { - - getEndOfLastVolumeStair(); - return; - - } - - } catch (err) { - logger.write(MODULE_NAME, "[ERROR] start -> buildStairs -> periodsLoop -> loopBody -> getEndOfLastCandleStair -> getCandleStairsFile -> onFileReceived -> err = " + err.message); - logger.write(MODULE_NAME, "[ERROR] start -> buildStairs -> periodsLoop -> loopBody -> getEndOfLastCandleStair -> getCandleStairsFile -> onFileReceived -> filePath = " + filePath); - logger.write(MODULE_NAME, "[ERROR] start -> buildStairs -> periodsLoop -> loopBody -> getEndOfLastCandleStair -> getCandleStairsFile -> onFileReceived -> market = " + market.assetA + '_' + market.assetB); - - callBackFunction(global.DEFAULT_RETRY_RESPONSE); - } - } + previousDayFile = JSON.parse(text); + getProcessDayFile() } catch (err) { - logger.write(MODULE_NAME, "[ERROR] start -> buildStairs -> periodsLoop -> loopBody -> getEndOfLastCandleStair -> getCandleStairsFile -> err = " + err.message); - callBackFunction(global.DEFAULT_FAIL_RESPONSE); + logger.write(MODULE_NAME, "[ERROR] start -> buildBands -> periodsLoop -> loopBody -> getPreviousDayFile -> onCurrentDayFileReceived -> err = " + err.message); + logger.write(MODULE_NAME, "[ERROR] start -> buildBands -> periodsLoop -> loopBody -> getPreviousDayFile -> onCurrentDayFileReceived -> filePath = " + filePath); + logger.write(MODULE_NAME, "[ERROR] start -> buildBands -> periodsLoop -> loopBody -> getPreviousDayFile -> onCurrentDayFileReceived -> market = " + market.assetA + '_' + market.assetB); + + callBackFunction(global.DEFAULT_RETRY_RESPONSE); } } } catch (err) { - logger.write(MODULE_NAME, "[ERROR] start -> buildStairs -> periodsLoop -> loopBody -> getEndOfLastCandleStair -> err = " + err.message); + logger.write(MODULE_NAME, "[ERROR] start -> buildBands -> periodsLoop -> loopBody -> getPreviousDayFile -> err = " + err.message); callBackFunction(global.DEFAULT_FAIL_RESPONSE); } } - function getEndOfLastVolumeStair() { + function getProcessDayFile() { try { + if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] start -> buildBands -> loopBody -> getProcessDayFile -> Entering function."); } - if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] start -> buildStairs -> loopBody -> getEndOfLastVolumeStair -> Entering function."); } + let dateForPath = processDate.getUTCFullYear() + '/' + utilities.pad(processDate.getUTCMonth() + 1, 2) + '/' + utilities.pad(processDate.getUTCDate(), 2); + let fileName = market.assetA + '_' + market.assetB + ".json" - let fileDate = new Date(previousDay.valueOf() - ONE_DAY_IN_MILISECONDS); - getCandleStairsFile(); + let filePathRoot = bot.devTeam + "/" + "AAOlivia" + "." + bot.version.major + "." + bot.version.minor + "/" + global.PLATFORM_CONFIG.codeName + "." + global.PLATFORM_CONFIG.version.major + "." + global.PLATFORM_CONFIG.version.minor + "/" + global.EXCHANGE_NAME + "/" + bot.dataSetVersion; + let filePath = filePathRoot + "/Output/" + CANDLES_FOLDER_NAME + '/' + "Multi-Period-Daily" + "/" + timePeriod + "/" + dateForPath; - function getCandleStairsFile() { + oliviaStorage.getTextFile(filePath, fileName, onCurrentDayFileReceived, true); + + function onCurrentDayFileReceived(err, text) { try { - if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] start -> buildStairs -> loopBody -> getEndOfLastVolumeStair -> getCandleStairsFile -> Entering function."); } + if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] start -> buildBands -> loopBody -> getProcessDayFile -> onCurrentDayFileReceived -> Entering function."); } + if (LOG_FILE_CONTENT === true) { logger.write(MODULE_NAME, "[INFO] start -> buildBands -> loopBody -> getProcessDayFile -> onCurrentDayFileReceived -> text = " + text); } - let dateForPath = fileDate.getUTCFullYear() + '/' + utilities.pad(fileDate.getUTCMonth() + 1, 2) + '/' + utilities.pad(fileDate.getUTCDate(), 2); - let fileName = market.assetA + '_' + market.assetB + ".json" + processDayFile = JSON.parse(text); + buildBands(); - let filePathRoot = bot.devTeam + "/" + bot.codeName + "." + bot.version.major + "." + bot.version.minor + "/" + global.PLATFORM_CONFIG.codeName + "." + global.PLATFORM_CONFIG.version.major + "." + global.PLATFORM_CONFIG.version.minor + "/" + global.EXCHANGE_NAME + "/" + bot.dataSetVersion; - let filePath = filePathRoot + "/Output/" + VOLUME_STAIRS_FOLDER_NAME + '/' + "Multi-Period-Daily" + "/" + timePeriod + "/" + dateForPath; - - tomStorage.getTextFile(filePath, fileName, onFileReceived, true); - - function onFileReceived(err, text) { - - try { - - if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] start -> buildStairs -> loopBody -> getEndOfLastVolumeStair -> getCandleStairsFile -> onFileReceived -> Entering function."); } - if (LOG_FILE_CONTENT === true) { logger.write(MODULE_NAME, "[INFO] start -> buildStairs -> loopBody -> getEndOfLastVolumeStair -> getCandleStairsFile -> onFileReceived -> text = " + text); } - - if ( - err.result === global.CUSTOM_FAIL_RESPONSE.result && - (err.message === 'Folder does not exist.' || err.message === 'File does not exist.') - ) { - - processCandles(); - return; - } - - let stairsFile = JSON.parse(text); - - if (stairsFile.length > 0) { - - for (let i = 0; i < stairsFile.length; i++) { - - let stairs = { - type: stairsFile[i][0], - begin: stairsFile[i][1], - end: stairsFile[i][2], - direction: stairsFile[i][3], - barsCount: stairsFile[i][4], - firstAmount: stairsFile[i][5], - lastAmount: stairsFile[i][6] - }; - - if (stairs.type === 'buy') { - - endOfLastBuyVolumeStair = stairs.end; - - } else { - - endOfLastSellVolumeStair = stairs.end; - - } - } - - processCandles(); - - } else { - - processCandles(); - return; - - } - - } catch (err) { - logger.write(MODULE_NAME, "[ERROR] start -> buildStairs -> periodsLoop -> loopBody -> getEndOfLastVolumeStair -> getCandleStairsFile -> onFileReceived -> err = " + err.message); - logger.write(MODULE_NAME, "[ERROR] start -> buildStairs -> periodsLoop -> loopBody -> getEndOfLastVolumeStair -> getCandleStairsFile -> onFileReceived -> filePath = " + filePath); - logger.write(MODULE_NAME, "[ERROR] start -> buildStairs -> periodsLoop -> loopBody -> getEndOfLastVolumeStair -> getCandleStairsFile -> onFileReceived -> market = " + market.assetA + '_' + market.assetB); - - callBackFunction(global.DEFAULT_RETRY_RESPONSE); - } - } } catch (err) { - logger.write(MODULE_NAME, "[ERROR] start -> buildStairs -> periodsLoop -> loopBody -> getEndOfLastVolumeStair -> getCandleStairsFile -> err = " + err.message); - callBackFunction(global.DEFAULT_FAIL_RESPONSE); + + if (processDate.valueOf() > contextVariables.maxBandFile.valueOf()) { + + processDayFile = []; // we are past the head of the market, then no worries if this file is non existent. + buildBands(); + + } else { + + logger.write(MODULE_NAME, "[ERROR] start -> buildBands -> periodsLoop -> loopBody -> getProcessDayFile -> onCurrentDayFileReceived -> err = " + err.message); + logger.write(MODULE_NAME, "[ERROR] start -> buildBands -> periodsLoop -> loopBody -> getProcessDayFile -> onCurrentDayFileReceived -> filePath = " + filePath); + logger.write(MODULE_NAME, "[ERROR] start -> buildBands -> periodsLoop -> loopBody -> getProcessDayFile -> onCurrentDayFileReceived -> market = " + market.assetA + '_' + market.assetB); + + callBackFunction(global.DEFAULT_RETRY_RESPONSE); + return; + } } } } catch (err) { - logger.write(MODULE_NAME, "[ERROR] start -> buildStairs -> periodsLoop -> loopBody -> getEndOfLastVolumeStair -> err = " + err.message); + logger.write(MODULE_NAME, "[ERROR] start -> buildBands -> periodsLoop -> loopBody -> getProcessDayFile -> err = " + err.message); callBackFunction(global.DEFAULT_FAIL_RESPONSE); } } - function processCandles() { + function buildBands() { try { - if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] start -> buildStairs -> loopBody -> processCandles -> Entering function."); } + if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] start -> buildBands -> loopBody -> buildBands -> Entering function."); } - let candles = []; // Here we will put all the candles of the 2 files read. + addCandlesToSingleArray(previousDayFile); + addCandlesToSingleArray(processDayFile); + calculateBands(); - let previousDayStairsArray = []; // Here All the stairs of the previous day. - let processDayStairsArray = []; // Here All the stairs of the process day. - - let previousDayFile; - let processDayFile; - - getCandleStairsFile(); - - function getCandleStairsFile() { + function addCandlesToSingleArray(candlesFile) { try { - if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] start -> buildStairs -> loopBody -> processCandles -> getCandleStairsFile -> Entering function."); } + if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] start -> buildBands -> loopBody -> buildBands -> addCandlesToSingleArray -> Entering function."); } - let dateForPath = previousDay.getUTCFullYear() + '/' + utilities.pad(previousDay.getUTCMonth() + 1, 2) + '/' + utilities.pad(previousDay.getUTCDate(), 2); - let fileName = market.assetA + '_' + market.assetB + ".json" + for (let i = 0; i < candlesFile.length; i++) { - let filePathRoot = bot.devTeam + "/" + "AAOlivia" + "." + bot.version.major + "." + bot.version.minor + "/" + global.PLATFORM_CONFIG.codeName + "." + global.PLATFORM_CONFIG.version.major + "." + global.PLATFORM_CONFIG.version.minor + "/" + global.EXCHANGE_NAME + "/" + bot.dataSetVersion; - let filePath = filePathRoot + "/Output/" + CANDLES_FOLDER_NAME + '/' + "Multi-Period-Daily" + "/" + timePeriod + "/" + dateForPath; + let candle = { + open: undefined, + close: undefined, + min: 10000000000000, + max: 0, + begin: undefined, + end: undefined, + direction: undefined + }; - oliviaStorage.getTextFile(filePath, fileName, onCurrentDayFileReceived, true); + candle.min = candlesFile[i][0]; + candle.max = candlesFile[i][1]; - function onCurrentDayFileReceived(err, text) { + candle.open = candlesFile[i][2]; + candle.close = candlesFile[i][3]; - try { + candle.begin = candlesFile[i][4]; + candle.end = candlesFile[i][5]; - if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] start -> buildStairs -> loopBody -> processCandles -> getCandleStairsFile -> onCurrentDayFileReceived -> Entering function."); } - if (LOG_FILE_CONTENT === true) { logger.write(MODULE_NAME, "[INFO] start -> buildStairs -> loopBody -> processCandles -> getCandleStairsFile -> onCurrentDayFileReceived -> text = " + text); } + if (candle.open > candle.close) { candle.direction = 'down'; } + if (candle.open < candle.close) { candle.direction = 'up'; } + if (candle.open === candle.close) { candle.direction = 'side'; } - previousDayFile = JSON.parse(text); - getProcessDayFile() - - } catch (err) { - logger.write(MODULE_NAME, "[ERROR] start -> buildStairs -> periodsLoop -> loopBody -> processCandles -> getCandleStairsFile -> onCurrentDayFileReceived -> err = " + err.message); - logger.write(MODULE_NAME, "[ERROR] start -> buildStairs -> periodsLoop -> loopBody -> processCandles -> getCandleStairsFile -> onCurrentDayFileReceived -> filePath = " + filePath); - logger.write(MODULE_NAME, "[ERROR] start -> buildStairs -> periodsLoop -> loopBody -> processCandles -> getCandleStairsFile -> onCurrentDayFileReceived -> market = " + market.assetA + '_' + market.assetB); - - callBackFunction(global.DEFAULT_RETRY_RESPONSE); - } + candles.push(candle); } } catch (err) { - logger.write(MODULE_NAME, "[ERROR] start -> buildStairs -> periodsLoop -> loopBody -> processCandles -> getCandleStairsFile -> err = " + err.message); - callBackFunction(global.DEFAULT_FAIL_RESPONSE); - } - } - - function getProcessDayFile() { - - try { - - if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] start -> buildStairs -> loopBody -> processCandles -> getProcessDayFile -> Entering function."); } - - let dateForPath = processDate.getUTCFullYear() + '/' + utilities.pad(processDate.getUTCMonth() + 1, 2) + '/' + utilities.pad(processDate.getUTCDate(), 2); - let fileName = market.assetA + '_' + market.assetB + ".json" - - let filePathRoot = bot.devTeam + "/" + "AAOlivia" + "." + bot.version.major + "." + bot.version.minor + "/" + global.PLATFORM_CONFIG.codeName + "." + global.PLATFORM_CONFIG.version.major + "." + global.PLATFORM_CONFIG.version.minor + "/" + global.EXCHANGE_NAME + "/" + bot.dataSetVersion; - let filePath = filePathRoot + "/Output/" + CANDLES_FOLDER_NAME + '/' + "Multi-Period-Daily" + "/" + timePeriod + "/" + dateForPath; - - oliviaStorage.getTextFile(filePath, fileName, onCurrentDayFileReceived, true); - - function onCurrentDayFileReceived(err, text) { - - try { - - if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] start -> buildStairs -> loopBody -> processCandles -> getProcessDayFile -> onCurrentDayFileReceived -> Entering function."); } - if (LOG_FILE_CONTENT === true) { logger.write(MODULE_NAME, "[INFO] start -> buildStairs -> loopBody -> processCandles -> getProcessDayFile -> onCurrentDayFileReceived -> text = " + text); } - - processDayFile = JSON.parse(text); - buildCandles(); - - } catch (err) { - - if (processDate.valueOf() > contextVariables.maxCandleFile.valueOf()) { - - processDayFile = []; // we are past the head of the market, then no worries if this file is non existent. - buildCandles(); - - } else { - - logger.write(MODULE_NAME, "[ERROR] start -> buildStairs -> periodsLoop -> loopBody -> processCandles -> getProcessDayFile -> onCurrentDayFileReceived -> err = " + err.message); - logger.write(MODULE_NAME, "[ERROR] start -> buildStairs -> periodsLoop -> loopBody -> processCandles -> getProcessDayFile -> onCurrentDayFileReceived -> filePath = " + filePath); - logger.write(MODULE_NAME, "[ERROR] start -> buildStairs -> periodsLoop -> loopBody -> processCandles -> getProcessDayFile -> onCurrentDayFileReceived -> market = " + market.assetA + '_' + market.assetB); - - callBackFunction(global.DEFAULT_RETRY_RESPONSE); - return; - } - } - } - - } catch (err) { - logger.write(MODULE_NAME, "[ERROR] start -> buildStairs -> periodsLoop -> loopBody -> processCandles -> getProcessDayFile -> err = " + err.message); - callBackFunction(global.DEFAULT_FAIL_RESPONSE); - } - } - - function buildCandles() { - - try { - - if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] start -> buildStairs -> loopBody -> processCandles -> buildCandles -> Entering function."); } - - pushCandles(previousDayFile); - pushCandles(processDayFile); - findCandleStairs(); - - function pushCandles(candlesFile) { - - try { - - if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] start -> buildStairs -> loopBody -> processCandles -> buildCandles -> pushCandles -> Entering function."); } - - for (let i = 0; i < candlesFile.length; i++) { - - let candle = { - open: undefined, - close: undefined, - min: 10000000000000, - max: 0, - begin: undefined, - end: undefined, - direction: undefined - }; - - candle.min = candlesFile[i][0]; - candle.max = candlesFile[i][1]; - - candle.open = candlesFile[i][2]; - candle.close = candlesFile[i][3]; - - candle.begin = candlesFile[i][4]; - candle.end = candlesFile[i][5]; - - if (candle.open > candle.close) { candle.direction = 'down'; } - if (candle.open < candle.close) { candle.direction = 'up'; } - if (candle.open === candle.close) { candle.direction = 'side'; } - - candles.push(candle); - } - - } catch (err) { - logger.write(MODULE_NAME, "[ERROR] start -> buildStairs -> periodsLoop -> loopBody -> processCandles -> buildCandles -> pushCandles -> err = " + err.message); - callBackFunction(global.DEFAULT_FAIL_RESPONSE); - return; - } - } - - } catch (err) { - logger.write(MODULE_NAME, "[ERROR] start -> buildStairs -> periodsLoop -> loopBody -> processCandles -> buildCandles -> err = " + err.message); + logger.write(MODULE_NAME, "[ERROR] start -> buildBands -> periodsLoop -> loopBody -> buildBands -> addCandlesToSingleArray -> err = " + err.message); callBackFunction(global.DEFAULT_FAIL_RESPONSE); return; } } - function findCandleStairs() { - - try { - - if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] start -> buildStairs -> loopBody -> processCandles -> findCandleStairs -> Entering function."); } - - /* Finding stairs */ - - let stairs; - - for (let i = 0; i < candles.length - 1; i++) { - - let currentCandle = candles[i]; - let nextCandle = candles[i + 1]; - - if (currentCandle.direction === nextCandle.direction && currentCandle.direction !== 'side') { - - if (stairs === undefined) { - - stairs = { - open: undefined, - close: undefined, - min: 10000000000000, - max: 0, - begin: undefined, - end: undefined, - direction: undefined, - candleCount: 0, - firstMin: 0, - firstMax: 0, - lastMin: 0, - lastMax: 0 - }; - - stairs.direction = currentCandle.direction; - stairs.candleCount = 2; - - stairs.begin = currentCandle.begin; - stairs.end = nextCandle.end; - - stairs.open = currentCandle.open; - stairs.close = nextCandle.close; - - if (currentCandle.min < nextCandle.min) { stairs.min = currentCandle.min; } else { stairs.min = nextCandle.min; } - if (currentCandle.max > nextCandle.max) { stairs.max = currentCandle.max; } else { stairs.max = nextCandle.max; } - - if (stairs.direction === 'up') { - - stairs.firstMin = currentCandle.open; - stairs.firstMax = currentCandle.close; - - stairs.lastMin = nextCandle.open; - stairs.lastMax = nextCandle.close; - - } else { - - stairs.firstMin = currentCandle.close; - stairs.firstMax = currentCandle.open; - - stairs.lastMin = nextCandle.close; - stairs.lastMax = nextCandle.open; - - } - - - } else { - - stairs.candleCount++; - stairs.end = nextCandle.end; - stairs.close = nextCandle.close; - - if (stairs.min < nextCandle.min) { stairs.min = currentCandle.min; } - if (stairs.max > nextCandle.max) { stairs.max = currentCandle.max; } - - if (stairs.direction === 'up') { - - stairs.lastMin = nextCandle.open; - stairs.lastMax = nextCandle.close; - - } else { - - stairs.lastMin = nextCandle.close; - stairs.lastMax = nextCandle.open; - - } - - } - - } else { - - if (stairs !== undefined) { - - /* - Here we detect stairs that started at process day - 2. - */ - - if (stairs.begin > endOfLastCandleStair) { - - if (stairs.begin >= processDate.valueOf()) { - - processDayStairsArray.push(stairs); - - } else { - - previousDayStairsArray.push(stairs); - - } - } - - stairs = undefined; - } - } - } - - writeCandleStairsFile(); - - } catch (err) { - logger.write(MODULE_NAME, "[ERROR] start -> buildStairs -> periodsLoop -> loopBody -> processCandles -> findCandleStairs -> err = " + err.message); - callBackFunction(global.DEFAULT_FAIL_RESPONSE); - return; - } - } - - function writeCandleStairsFile() { - - try { - - if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] start -> buildStairs -> loopBody -> processCandles -> writeCandleStairsFile -> Entering function."); } - - writeFile(previousDayStairsArray, previousDay, onPreviousFileWritten); - - function onPreviousFileWritten() { - - try { - - if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] start -> buildStairs -> loopBody -> processCandles -> writeCandleStairsFile -> onPreviousFileWritten -> Entering function."); } - - writeFile(processDayStairsArray, processDate, onProcessFileWritten); - - function onProcessFileWritten() { - - try { - - if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] start -> buildStairs -> loopBody -> processCandles -> writeCandleStairsFile -> onPreviousFileWritten -> onProcessFileWritten -> Entering function."); } - - processVolumes(); - - } catch (err) { - logger.write(MODULE_NAME, "[ERROR] start -> buildStairs -> periodsLoop -> loopBody -> processCandles -> writeCandleStairsFile -> onPreviousFileWritten -> onProcessFileWritten -> err = " + err.message); - callBackFunction(global.DEFAULT_FAIL_RESPONSE); - } - } - - } catch (err) { - logger.write(MODULE_NAME, "[ERROR] start -> buildStairs -> periodsLoop -> loopBody -> processCandles -> writeCandleStairsFile -> onPreviousFileWritten -> err = " + err.message); - callBackFunction(global.DEFAULT_FAIL_RESPONSE); - } - } - - function writeFile(pStairs, pDate, callback) { - - try { - - if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] start -> buildStairs -> loopBody -> processCandles -> writeCandleStairsFile -> writeFile -> Entering function."); } - - let separator = ""; - let fileRecordCounter = 0; - - let fileContent = ""; - - for (i = 0; i < pStairs.length; i++) { - - let stairs = pStairs[i]; - - fileContent = fileContent + separator + '[' + - stairs.open + "," + - stairs.close + "," + - stairs.min + "," + - stairs.max + "," + - stairs.begin + "," + - stairs.end + "," + - '"' + stairs.direction + '"' + "," + - stairs.candleCount + "," + - stairs.firstMin + "," + - stairs.firstMax + "," + - stairs.lastMin + "," + - stairs.lastMax + "]"; - - if (separator === "") { separator = ","; } - - fileRecordCounter++; - - } - - fileContent = "[" + fileContent + "]"; - - let dateForPath = pDate.getUTCFullYear() + '/' + utilities.pad(pDate.getUTCMonth() + 1, 2) + '/' + utilities.pad(pDate.getUTCDate(), 2); - let fileName = '' + market.assetA + '_' + market.assetB + '.json'; - - let filePathRoot = bot.devTeam + "/" + bot.codeName + "." + bot.version.major + "." + bot.version.minor + "/" + global.PLATFORM_CONFIG.codeName + "." + global.PLATFORM_CONFIG.version.major + "." + global.PLATFORM_CONFIG.version.minor + "/" + global.EXCHANGE_NAME + "/" + bot.dataSetVersion; - let filePath = filePathRoot + "/Output/" + CANDLE_STAIRS_FOLDER_NAME + "/" + bot.process + "/" + timePeriod + "/" + dateForPath; - - tomStorage.createTextFile(filePath, fileName, fileContent + '\n', onFileCreated); - - function onFileCreated(err) { - - try { - - if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] start -> buildStairs -> loopBody -> processCandles -> writeCandleStairsFile -> writeFile -> onFileCreated -> Entering function."); } - - if (LOG_FILE_CONTENT === true) { - logger.write(MODULE_NAME, "[INFO] start -> buildStairs -> loopBody -> processCandles -> writeCandleStairsFile -> writeFile -> onFileCreated -> Content written = " + fileContent); - } - - if (err.result !== global.DEFAULT_OK_RESPONSE.result) { - logger.write(MODULE_NAME, "[ERROR] start -> buildStairs -> loopBody -> processCandles -> writeCandleStairsFile -> writeFile -> onFileCreated -> err = " + err.message); - callBack(err); - return; - } - - const logText = "[WARN] Finished with File @ " + market.assetA + "_" + market.assetB + ", " + fileRecordCounter + " records inserted into " + filePath + "/" + fileName + ""; - if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] start -> buildStairs -> loopBody -> processCandles -> writeCandleStairsFile -> writeFile -> onFileCreated -> " + logText); } - - callback(); - - } catch (err) { - logger.write(MODULE_NAME, "[ERROR] start -> buildStairs -> periodsLoop -> loopBody -> processCandles -> writeCandleStairsFile -> writeFile -> onFileCreated -> err = " + err.message); - callBackFunction(global.DEFAULT_RETRY_RESPONSE); - } - } - - } catch (err) { - logger.write(MODULE_NAME, "[ERROR] start -> buildStairs -> periodsLoop -> loopBody -> processCandles -> writeCandleStairsFile -> writeFile -> err = " + err.message); - callBackFunction(global.DEFAULT_FAIL_RESPONSE); - } - } - - } catch (err) { - logger.write(MODULE_NAME, "[ERROR] start -> buildStairs -> periodsLoop -> loopBody -> processCandles -> writeCandleStairsFile -> err = " + err.message); - callBackFunction(global.DEFAULT_FAIL_RESPONSE); - } - } - } catch (err) { - logger.write(MODULE_NAME, "[ERROR] start -> buildStairs -> periodsLoop -> loopBody -> processCandles -> err = " + err.message); + logger.write(MODULE_NAME, "[ERROR] start -> buildBands -> periodsLoop -> loopBody -> buildBands -> err = " + err.message); callBackFunction(global.DEFAULT_FAIL_RESPONSE); + return; } } - function processVolumes() { + function calculateBands() { try { - if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] start -> buildStairs -> loopBody -> processVolumes -> Entering function."); } + if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] start -> buildBands -> loopBody -> calculateBands -> Entering function."); } - let volumes = []; + let bandsArray = []; + let numberOfPeriods = 20; - let previousDayStairsArray = []; // Here All the stairs of the previous day. - let processDayStairsArray = []; // Here All the stairs of the process day. + /* Building bands */ - let previousDayFile; - let processDayFile; + let band; - getCandleStairsFile(); + for (let i = numberOfPeriods - 1; i < candles.length; i++) { // Go through all the candles to generate a band segment for each of them. - function getCandleStairsFile() { - - try { - - if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] start -> buildStairs -> loopBody -> processVolumes -> getCandleStairsFile -> Entering function."); } - - let dateForPath = previousDay.getUTCFullYear() + '/' + utilities.pad(previousDay.getUTCMonth() + 1, 2) + '/' + utilities.pad(previousDay.getUTCDate(), 2); - let fileName = market.assetA + '_' + market.assetB + ".json" - - let filePathRoot = bot.devTeam + "/" + "AAOlivia" + "." + bot.version.major + "." + bot.version.minor + "/" + global.PLATFORM_CONFIG.codeName + "." + global.PLATFORM_CONFIG.version.major + "." + global.PLATFORM_CONFIG.version.minor + "/" + global.EXCHANGE_NAME + "/" + bot.dataSetVersion; - let filePath = filePathRoot + "/Output/" + VOLUMES_FOLDER_NAME + '/' + "Multi-Period-Daily" + "/" + timePeriod + "/" + dateForPath; - - oliviaStorage.getTextFile(filePath, fileName, onCurrentDayFileReceived, true); - - function onCurrentDayFileReceived(err, text) { - - try { - - if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] start -> buildStairs -> loopBody -> processVolumes -> getCandleStairsFile -> onCurrentDayFileReceived -> Entering function."); } - if (LOG_FILE_CONTENT === true) { logger.write(MODULE_NAME, "[INFO] start -> buildStairs -> loopBody -> processVolumes -> getCandleStairsFile -> onCurrentDayFileReceived -> text = " + text); } - - previousDayFile = JSON.parse(text); - getProcessDayFile() - - } catch (err) { - logger.write(MODULE_NAME, "[ERROR] start -> buildStairs -> periodsLoop -> loopBody -> processVolumes -> getCandleStairsFile -> onCurrentDayFileReceived -> err = " + err.message); - logger.write(MODULE_NAME, "[ERROR] start -> buildStairs -> periodsLoop -> loopBody -> processVolumes -> getCandleStairsFile -> onCurrentDayFileReceived -> filePath = " + filePath); - logger.write(MODULE_NAME, "[ERROR] start -> buildStairs -> periodsLoop -> loopBody -> processVolumes -> getCandleStairsFile -> onCurrentDayFileReceived -> market = " + market.assetA + '_' + market.assetB); - - callBackFunction(global.DEFAULT_RETRY_RESPONSE); - } - } - - } catch (err) { - logger.write(MODULE_NAME, "[ERROR] start -> buildStairs -> periodsLoop -> loopBody -> processVolumes -> getCandleStairsFile -> err = " + err.message); - callBackFunction(global.DEFAULT_FAIL_RESPONSE); + let movingAverage = 0; + for (let j = i - numberOfPeriods + 1; j < i + 1; j++) { // go through the last n candles to calculate the moving average. + movingAverage = movingAverage + candles[j].close; } + movingAverage = movingAverage / numberOfPeriods; + + let standardDeviation = 0; + for (let j = i - numberOfPeriods + 1; j < i + 1; j++) { // go through the last n candles to calculate the standard deviation. + standardDeviation = standardDeviation + Math.pow(candles[j].close - movingAverage, 2); + } + standardDeviation = standardDeviation / numberOfPeriods; + standardDeviation = Math.sqrt(standardDeviation); + + + + band = { + begin: candles[i].begin, + end: candles[i].end, + movingAverage: movingAverage, + standardDeviation: standardDeviation + }; + + /* Will only add to the array the bands of the current day */ + + if (band.begin >= processDate.valueOf()) { bandsArray.push(band); } + } - function getProcessDayFile() { + writeFile(bandsArray); - try { + } catch (err) { + logger.write(MODULE_NAME, "[ERROR] start -> buildBands -> periodsLoop -> loopBody -> calculateBands -> err = " + err.message); + callBackFunction(global.DEFAULT_FAIL_RESPONSE); + return; + } + } - if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] start -> buildStairs -> loopBody -> processVolumes -> getProcessDayFile -> Entering function."); } + function writeFile(pBands, callback) { - let dateForPath = processDate.getUTCFullYear() + '/' + utilities.pad(processDate.getUTCMonth() + 1, 2) + '/' + utilities.pad(processDate.getUTCDate(), 2); - let fileName = market.assetA + '_' + market.assetB + ".json" + try { - let filePathRoot = bot.devTeam + "/" + "AAOlivia" + "." + bot.version.major + "." + bot.version.minor + "/" + global.PLATFORM_CONFIG.codeName + "." + global.PLATFORM_CONFIG.version.major + "." + global.PLATFORM_CONFIG.version.minor + "/" + global.EXCHANGE_NAME + "/" + bot.dataSetVersion; - let filePath = filePathRoot + "/Output/" + VOLUMES_FOLDER_NAME + '/' + "Multi-Period-Daily" + "/" + timePeriod + "/" + dateForPath; + if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] start -> buildBands -> loopBody -> writeBandBandsFile -> writeFile -> Entering function."); } - oliviaStorage.getTextFile(filePath, fileName, onCurrentDayFileReceived, true); + let separator = ""; + let fileRecordCounter = 0; - function onCurrentDayFileReceived(err, text) { + let fileContent = ""; - try { + for (i = 0; i < pBands.length; i++) { - if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] start -> buildStairs -> loopBody -> processVolumes -> getProcessDayFile -> onCurrentDayFileReceived -> Entering function."); } - if (LOG_FILE_CONTENT === true) { logger.write(MODULE_NAME, "[INFO] start -> buildStairs -> loopBody -> processVolumes -> getProcessDayFile -> onCurrentDayFileReceived -> text = " + text); } + let band = pBands[i]; - processDayFile = JSON.parse(text); - buildVolumes(); + fileContent = fileContent + separator + '[' + + band.begin + "," + + band.end + "," + + band.movingAverage + "," + + band.standardDeviation + "]"; - } catch (err) { + if (separator === "") { separator = ","; } - if (processDate.valueOf() > contextVariables.maxCandleFile.valueOf()) { + fileRecordCounter++; - processDayFile = []; // we are past the head of the market, then no worries if this file is non existent. - buildVolumes(); - - } else { - - logger.write(MODULE_NAME, "[ERROR] start -> buildStairs -> periodsLoop -> loopBody -> processVolumes -> getProcessDayFile -> onCurrentDayFileReceived -> err = " + err.message); - logger.write(MODULE_NAME, "[ERROR] start -> buildStairs -> periodsLoop -> loopBody -> processVolumes -> getProcessDayFile -> onCurrentDayFileReceived -> filePath = " + filePath); - logger.write(MODULE_NAME, "[ERROR] start -> buildStairs -> periodsLoop -> loopBody -> processVolumes -> getProcessDayFile -> onCurrentDayFileReceived -> market = " + market.assetA + '_' + market.assetB); - - callBackFunction(global.DEFAULT_RETRY_RESPONSE); - return; - } - } - } - - } catch (err) { - logger.write(MODULE_NAME, "[ERROR] start -> buildStairs -> periodsLoop -> loopBody -> processVolumes -> getProcessDayFile -> err = " + err.message); - callBackFunction(global.DEFAULT_FAIL_RESPONSE); - } } - function buildVolumes() { + fileContent = "[" + fileContent + "]"; + + let dateForPath = processDate.getUTCFullYear() + '/' + utilities.pad(processDate.getUTCMonth() + 1, 2) + '/' + utilities.pad(processDate.getUTCDate(), 2); + let fileName = '' + market.assetA + '_' + market.assetB + '.json'; + + let filePathRoot = bot.devTeam + "/" + bot.codeName + "." + bot.version.major + "." + bot.version.minor + "/" + global.PLATFORM_CONFIG.codeName + "." + global.PLATFORM_CONFIG.version.major + "." + global.PLATFORM_CONFIG.version.minor + "/" + global.EXCHANGE_NAME + "/" + bot.dataSetVersion; + let filePath = filePathRoot + "/Output/" + BOLLINGER_BANDS_FOLDER_NAME + "/" + bot.process + "/" + timePeriod + "/" + dateForPath; + + chrisStorage.createTextFile(filePath, fileName, fileContent + '\n', onFileCreated); + + function onFileCreated(err) { try { - if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] start -> buildStairs -> loopBody -> processVolumes -> buildVolumes -> Entering function."); } + if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] start -> buildBands -> loopBody -> writeBandBandsFile -> writeFile -> onFileCreated -> Entering function."); } - pushVolumes(previousDayFile); - pushVolumes(processDayFile); - findVolumesStairs(); - - function pushVolumes(volumesFile) { - - try { - - if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] start -> buildStairs -> loopBody -> processVolumes -> buildVolumes -> pushVolumes -> Entering function."); } - - for (let i = 0; i < volumesFile.length; i++) { - - let volume = { - amountBuy: 0, - amountSell: 0, - begin: undefined, - end: undefined - }; - - volume.amountBuy = volumesFile[i][0]; - volume.amountSell = volumesFile[i][1]; - - volume.begin = volumesFile[i][2]; - volume.end = volumesFile[i][3]; - - volumes.push(volume); - - } - - } catch (err) { - logger.write(MODULE_NAME, "[ERROR] start -> buildStairs -> periodsLoop -> loopBody -> processVolumes -> buildVolumes -> pushVolumes -> err = " + err.message); - callBackFunction(global.DEFAULT_FAIL_RESPONSE); - } + if (LOG_FILE_CONTENT === true) { + logger.write(MODULE_NAME, "[INFO] start -> buildBands -> loopBody -> writeBandBandsFile -> writeFile -> onFileCreated -> Content written = " + fileContent); } + if (err.result !== global.DEFAULT_OK_RESPONSE.result) { + logger.write(MODULE_NAME, "[ERROR] start -> buildBands -> loopBody -> writeBandBandsFile -> writeFile -> onFileCreated -> err = " + err.message); + callBackFunction(err); + return; + } + + const logText = "[WARN] Finished with File @ " + market.assetA + "_" + market.assetB + ", " + fileRecordCounter + " records inserted into " + filePath + "/" + fileName + ""; + if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] start -> buildBands -> loopBody -> writeBandBandsFile -> writeFile -> onFileCreated -> " + logText); } + + controlLoop(); + } catch (err) { - logger.write(MODULE_NAME, "[ERROR] start -> buildStairs -> periodsLoop -> loopBody -> processVolumes -> buildVolumes -> err = " + err.message); - callBackFunction(global.DEFAULT_FAIL_RESPONSE); - } - } - - function findVolumesStairs() { - - try { - - if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] start -> buildStairs -> loopBody -> processVolumes -> findVolumesStairs -> Entering function."); } - - /* Finding stairs */ - - let buyUpStairs; - let buyDownStairs; - - let sellUpStairs; - let sellDownStairs; - - for (let i = 0; i < volumes.length - 1; i++) { - - let currentVolume = volumes[i]; - let nextVolume = volumes[i + 1]; - - - /* buy volume going up */ - - if (currentVolume.amountBuy < nextVolume.amountBuy) { - - if (buyUpStairs === undefined) { - - buyUpStairs = { - type: undefined, - begin: undefined, - end: undefined, - direction: undefined, - barsCount: 0, - firstAmount: 0, - lastAmount: 0 - }; - - buyUpStairs.type = 'buy'; - buyUpStairs.direction = 'up'; - buyUpStairs.barsCount = 2; - - buyUpStairs.begin = currentVolume.begin; - buyUpStairs.end = nextVolume.end; - - buyUpStairs.firstAmount = currentVolume.amountBuy; - buyUpStairs.lastAmount = nextVolume.amountBuy; - - } else { - - buyUpStairs.barsCount++; - buyUpStairs.end = nextVolume.end; - buyUpStairs.lastAmount = nextVolume.amountBuy; - - } - - } else { - - if (buyUpStairs !== undefined) { - - if (buyUpStairs.barsCount > 2) { - - pushToArray(buyUpStairs); - } - - buyUpStairs = undefined; - } - } - - /* buy volume going down */ - - if (currentVolume.amountBuy > nextVolume.amountBuy) { - - if (buyDownStairs === undefined) { - - buyDownStairs = { - type: undefined, - begin: undefined, - end: undefined, - direction: undefined, - barsCount: 0, - firstAmount: 0, - lastAmount: 0 - }; - - buyDownStairs.type = 'buy'; - buyDownStairs.direction = 'down'; - buyDownStairs.barsCount = 2; - - buyDownStairs.begin = currentVolume.begin; - buyDownStairs.end = nextVolume.end; - - buyDownStairs.firstAmount = currentVolume.amountBuy; - buyDownStairs.lastAmount = nextVolume.amountBuy; - - } else { - - buyDownStairs.barsCount++; - buyDownStairs.end = nextVolume.end; - buyDownStairs.lastAmount = nextVolume.amountBuy; - - } - - } else { - - if (buyDownStairs !== undefined) { - - if (buyDownStairs.barsCount > 2) { - - pushToArray(buyDownStairs); - } - - buyDownStairs = undefined; - } - } - - /* sell volume going up */ - - if (currentVolume.amountSell < nextVolume.amountSell) { - - if (sellUpStairs === undefined) { - - sellUpStairs = { - type: undefined, - begin: undefined, - end: undefined, - direction: undefined, - barsCount: 0, - firstAmount: 0, - lastAmount: 0 - }; - - sellUpStairs.type = 'sell'; - sellUpStairs.direction = 'up'; - sellUpStairs.barsCount = 2; - - sellUpStairs.begin = currentVolume.begin; - sellUpStairs.end = nextVolume.end; - - sellUpStairs.firstAmount = currentVolume.amountSell; - sellUpStairs.lastAmount = nextVolume.amountSell; - - } else { - - sellUpStairs.barsCount++; - sellUpStairs.end = nextVolume.end; - sellUpStairs.lastAmount = nextVolume.amountSell; - - } - - } else { - - if (sellUpStairs !== undefined) { - - if (sellUpStairs.barsCount > 2) { - - pushToArray(sellUpStairs); - } - - sellUpStairs = undefined; - } - } - - /* sell volume going down */ - - if (currentVolume.amountSell > nextVolume.amountSell) { - - if (sellDownStairs === undefined) { - - sellDownStairs = { - type: undefined, - begin: undefined, - end: undefined, - direction: undefined, - barsCount: 0, - firstAmount: 0, - lastAmount: 0 - }; - - sellDownStairs.type = 'sell'; - sellDownStairs.direction = 'down'; - sellDownStairs.barsCount = 2; - - sellDownStairs.begin = currentVolume.begin; - sellDownStairs.end = nextVolume.end; - - sellDownStairs.firstAmount = currentVolume.amountSell; - sellDownStairs.lastAmount = nextVolume.amountSell; - - } else { - - sellDownStairs.barsCount++; - sellDownStairs.end = nextVolume.end; - sellDownStairs.lastAmount = nextVolume.amountSell; - - } - - } else { - - if (sellDownStairs !== undefined) { - - if (sellDownStairs.barsCount > 2) { - - pushToArray(sellDownStairs); - } - - sellDownStairs = undefined; - } - } - - function pushToArray(stairs) { - - if (INTENSIVE_LOG === true) { logger.write(MODULE_NAME, "[INFO] start -> buildStairs -> loopBody -> processVolumes -> findVolumesStairs -> pushToArray -> Entering function."); } - - try { - - if (stairs !== undefined) { - - /* - Here we detect stairs that started at process day - 2. - */ - - if (stairs.type === 'sell') { - - if (stairs.begin > endOfLastSellVolumeStair) { - - if (stairs.begin >= processDate.valueOf()) { - - processDayStairsArray.push(stairs); - - } else { - - previousDayStairsArray.push(stairs); - - } - } - } - else { - - if (stairs.begin > endOfLastBuyVolumeStair) { - - if (stairs.begin >= processDate.valueOf()) { - - processDayStairsArray.push(stairs); - - } else { - - previousDayStairsArray.push(stairs); - - } - } - - } - - stairs = undefined; - } - - } catch (err) { - logger.write(MODULE_NAME, "[ERROR] start -> buildStairs -> periodsLoop -> loopBody -> processVolumes -> findVolumesStairs -> pushToArray -> err = " + err.message); - callBackFunction(global.DEFAULT_FAIL_RESPONSE); - } - } - } - - writeVolumeStairsFile(); - - } catch (err) { - logger.write(MODULE_NAME, "[ERROR] start -> buildStairs -> periodsLoop -> loopBody -> processVolumes -> findVolumesStairs -> err = " + err.message); - callBackFunction(global.DEFAULT_FAIL_RESPONSE); - } - } - - function writeVolumeStairsFile() { - - try { - - if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] start -> buildStairs -> loopBody -> processVolumes -> writeVolumeStairsFile -> Entering function."); } - - writeFile(previousDayStairsArray, previousDay, onPreviousFileWritten); - - function onPreviousFileWritten() { - - try { - - if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] start -> buildStairs -> loopBody -> processVolumes -> writeVolumeStairsFile -> onPreviousFileWritten -> Entering function."); } - - writeFile(processDayStairsArray, processDate, onProcessFileWritten); - - function onProcessFileWritten() { - - try { - - if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] start -> buildStairs -> loopBody -> processVolumes -> writeVolumeStairsFile -> onPreviousFileWritten -> onProcessFileWritten -> Entering function."); } - - controlLoop(); - - } catch (err) { - logger.write(MODULE_NAME, "[ERROR] start -> buildStairs -> periodsLoop -> loopBody -> processVolumes -> writeVolumeStairsFile -> onPreviousFileWritten -> onProcessFileWritten -> err = " + err.message); - callBackFunction(global.DEFAULT_FAIL_RESPONSE); - } - } - - } catch (err) { - logger.write(MODULE_NAME, "[ERROR] start -> buildStairs -> periodsLoop -> loopBody -> processVolumes -> writeVolumeStairsFile -> onPreviousFileWritten -> err = " + err.message); - callBackFunction(global.DEFAULT_FAIL_RESPONSE); - } - } - - function writeFile(pStairs, pDate, callback) { - - try { - - if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] start -> buildStairs -> loopBody -> processVolumes -> writeVolumeStairsFile -> writeFile -> Entering function."); } - - let separator = ""; - let fileRecordCounter = 0; - - let fileContent = ""; - - for (i = 0; i < pStairs.length; i++) { - - let stairs = pStairs[i]; - - fileContent = fileContent + separator + '[' + - '"' + stairs.type + '"' + "," + - stairs.begin + "," + - stairs.end + "," + - '"' + stairs.direction + '"' + "," + - stairs.barsCount + "," + - stairs.firstAmount + "," + - stairs.lastAmount + "]"; - - if (separator === "") { separator = ","; } - - fileRecordCounter++; - - } - - fileContent = "[" + fileContent + "]"; - - let dateForPath = pDate.getUTCFullYear() + '/' + utilities.pad(pDate.getUTCMonth() + 1, 2) + '/' + utilities.pad(pDate.getUTCDate(), 2); - let fileName = '' + market.assetA + '_' + market.assetB + '.json'; - - let filePathRoot = bot.devTeam + "/" + bot.codeName + "." + bot.version.major + "." + bot.version.minor + "/" + global.PLATFORM_CONFIG.codeName + "." + global.PLATFORM_CONFIG.version.major + "." + global.PLATFORM_CONFIG.version.minor + "/" + global.EXCHANGE_NAME + "/" + bot.dataSetVersion; - let filePath = filePathRoot + "/Output/" + VOLUME_STAIRS_FOLDER_NAME + "/" + bot.process + "/" + timePeriod + "/" + dateForPath; - - tomStorage.createTextFile(filePath, fileName, fileContent + '\n', onFileCreated); - - function onFileCreated(err) { - - try { - - if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] start -> buildStairs -> loopBody -> processVolumes -> writeVolumeStairsFile -> writeFile -> onFileCreated -> Entering function."); } - - if (LOG_FILE_CONTENT === true) { - logger.write(MODULE_NAME, "[INFO] start -> buildStairs -> loopBody -> processVolumes -> writeVolumeStairsFile -> writeFile -> onFileCreated -> Content written = " + fileContent); - } - - if (err.result !== global.DEFAULT_OK_RESPONSE.result) { - logger.write(MODULE_NAME, "[ERROR] start -> buildStairs -> loopBody -> processVolumes -> writeVolumeStairsFile -> writeFile -> onFileCreated -> err = " + err.message); - callBack(err); - return; - } - - const logText = "[WARN] Finished with File @ " + market.assetA + "_" + market.assetB + ", " + fileRecordCounter + " records inserted into " + filePath + "/" + fileName + ""; - if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] start -> buildStairs -> loopBody -> processVolumes -> writeVolumeStairsFile -> writeFile -> onFileCreated -> " + logText); } - - callback(); - - } catch (err) { - logger.write(MODULE_NAME, "[ERROR] start -> buildStairs -> periodsLoop -> loopBody -> processVolumes -> writeVolumeStairsFile -> onPreviousFileWritten -> writeFile -> onFileCreated -> err = " + err.message); - callBackFunction(global.DEFAULT_FAIL_RESPONSE); - } - } - - } catch (err) { - logger.write(MODULE_NAME, "[ERROR] start -> buildStairs -> periodsLoop -> loopBody -> processVolumes -> writeVolumeStairsFile -> onPreviousFileWritten -> writeFile -> err = " + err.message); - callBackFunction(global.DEFAULT_FAIL_RESPONSE); - } - } - - } catch (err) { - logger.write(MODULE_NAME, "[ERROR] start -> buildStairs -> periodsLoop -> loopBody -> processVolumes -> writeVolumeStairsFile -> err = " + err.message); - callBackFunction(global.DEFAULT_FAIL_RESPONSE); + logger.write(MODULE_NAME, "[ERROR] start -> buildBands -> periodsLoop -> loopBody -> writeBandBandsFile -> writeFile -> onFileCreated -> err = " + err.message); + callBackFunction(global.DEFAULT_RETRY_RESPONSE); } } } catch (err) { - logger.write(MODULE_NAME, "[ERROR] start -> buildStairs -> periodsLoop -> loopBody -> processVolumes -> err = " + err.message); + logger.write(MODULE_NAME, "[ERROR] start -> buildBands -> periodsLoop -> loopBody -> writeBandBandsFile -> writeFile -> err = " + err.message); callBackFunction(global.DEFAULT_FAIL_RESPONSE); } } + + + } catch (err) { - logger.write(MODULE_NAME, "[ERROR] start -> buildStairs -> periodsLoop -> loopBody -> err = " + err.message); + logger.write(MODULE_NAME, "[ERROR] start -> buildBands -> periodsLoop -> loopBody -> err = " + err.message); callBackFunction(global.DEFAULT_FAIL_RESPONSE); } } @@ -1475,7 +605,7 @@ try { - if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] start -> buildStairs -> controlLoop -> Entering function."); } + if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] start -> buildBands -> controlLoop -> Entering function."); } n++; @@ -1493,32 +623,32 @@ try { - if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] start -> buildStairs -> controlLoop -> onWritten -> Entering function."); } + if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] start -> buildBands -> controlLoop -> onWritten -> Entering function."); } if (err.result !== global.DEFAULT_OK_RESPONSE.result) { - logger.write(MODULE_NAME, "[ERROR] start -> buildStairs -> controlLoop -> onWritten -> err = " + err.message); - callBack(err); + logger.write(MODULE_NAME, "[ERROR] start -> buildBands -> controlLoop -> onWritten -> err = " + err.message); + callBackFunction(err); return; } writeStatusReport(processDate, advanceTime); } catch (err) { - logger.write(MODULE_NAME, "[ERROR] start -> buildStairs -> periodsLoop -> controlLoop -> onWritten -> err = " + err.message); + logger.write(MODULE_NAME, "[ERROR] start -> buildBands -> periodsLoop -> controlLoop -> onWritten -> err = " + err.message); callBackFunction(global.DEFAULT_FAIL_RESPONSE); } } } } catch (err) { - logger.write(MODULE_NAME, "[ERROR] start -> buildStairs -> periodsLoop -> controlLoop -> err = " + err.message); + logger.write(MODULE_NAME, "[ERROR] start -> buildBands -> periodsLoop -> controlLoop -> err = " + err.message); callBackFunction(global.DEFAULT_FAIL_RESPONSE); } } } catch (err) { - logger.write(MODULE_NAME, "[ERROR] start -> buildStairs -> err.message = " + err.message); + logger.write(MODULE_NAME, "[ERROR] start -> buildBands -> err.message = " + err.message); callBackFunction(global.DEFAULT_FAIL_RESPONSE); } } @@ -1529,32 +659,20 @@ if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] start -> writeDataRanges -> Entering function."); } - writeDataRange(contextVariables.firstTradeFile, processDate, CANDLE_STAIRS_FOLDER_NAME, onCandlesStairsDataRangeWritten); + writeDataRange(contextVariables.firstTradeFile, processDate, BOLLINGER_BANDS_FOLDER_NAME, onBandsBandsDataRangeWritten); - function onCandlesStairsDataRangeWritten(err) { + function onBandsBandsDataRangeWritten(err) { if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] start -> writeDataRanges -> Entering function."); } if (err.result !== global.DEFAULT_OK_RESPONSE.result) { - logger.write(MODULE_NAME, "[ERROR] writeDataRanges -> writeDataRanges -> onCandlesStairsDataRangeWritten -> err = " + err.message); + logger.write(MODULE_NAME, "[ERROR] writeDataRanges -> writeDataRanges -> onBandsBandsDataRangeWritten -> err = " + err.message); callBack(err); return; } - writeDataRange(contextVariables.firstTradeFile, processDate, VOLUME_STAIRS_FOLDER_NAME, onVolumeStairsDataRangeWritten); + callBack(global.DEFAULT_OK_RESPONSE); - function onVolumeStairsDataRangeWritten(err) { - - if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] writeDataRanges -> writeDataRanges -> onVolumeStairsDataRangeWritten -> Entering function."); } - - if (err.result !== global.DEFAULT_OK_RESPONSE.result) { - logger.write(MODULE_NAME, "[ERROR] writeDataRanges -> writeDataRanges -> onVolumeStairsDataRangeWritten -> err = " + err.message); - callBack(err); - return; - } - - callBack(global.DEFAULT_OK_RESPONSE); - } } } catch (err) { @@ -1583,7 +701,7 @@ if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] start -> writeDataRange -> fileName = " + fileName); } if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] start -> writeDataRange -> filePath = " + filePath); } - tomStorage.createTextFile(filePath, fileName, fileContent + '\n', onFileCreated); + chrisStorage.createTextFile(filePath, fileName, fileContent + '\n', onFileCreated); function onFileCreated(err) { @@ -1615,7 +733,7 @@ try { - let reportKey = "AAMasters" + "-" + "AATom" + "-" + "Multi-Period-Daily" + "-" + "dataSet.V1"; + let reportKey = "AAMasters" + "-" + "AAChris" + "-" + "Multi-Period-Daily" + "-" + "dataSet.V1"; let thisReport = statusDependencies.statusReports.get(reportKey); thisReport.file.lastExecution = bot.processDatetime; diff --git a/Multi-Period-Market/User.Bot.js b/Multi-Period-Market/User.Bot.js index 8725317f9..7a91ac933 100644 --- a/Multi-Period-Market/User.Bot.js +++ b/Multi-Period-Market/User.Bot.js @@ -10,7 +10,7 @@ const TRADES_FOLDER_NAME = "Trades"; const CANDLES_FOLDER_NAME = "Candles"; - const BOLINGER_BANDS_FOLDER_NAME = "Bollinger-Bands"; + const BOLLINGER_BANDS_FOLDER_NAME = "Bollinger-Bands"; const commons = COMMONS.newCommons(bot, logger, UTILITIES); @@ -209,7 +209,7 @@ let band; - for (let i = n - 1; i < candles.length - 1; i++) { // Go through all the candles to generate a band segment for each of them. + for (let i = n - 1; i < candles.length; i++) { // Go through all the candles to generate a band segment for each of them. let movingAverage = 0; for (let j = i - n + 1; j < i + 1; j++) { // go through the last n candles to calculate the moving average. @@ -223,10 +223,11 @@ } standardDeviation = standardDeviation / n; standardDeviation = Math.sqrt(standardDeviation); - + band = { begin: candles[i].begin, end: candles[i].end, + close: candles[i].close, movingAverage: movingAverage, standardDeviation: standardDeviation }; @@ -261,6 +262,7 @@ fileContent = fileContent + separator + '[' + band.begin + "," + band.end + "," + + band.close + "," + band.movingAverage + "," + band.standardDeviation + "]"; @@ -275,7 +277,7 @@ let fileName = '' + market.assetA + '_' + market.assetB + '.json'; let filePathRoot = bot.devTeam + "/" + bot.codeName + "." + bot.version.major + "." + bot.version.minor + "/" + global.PLATFORM_CONFIG.codeName + "." + global.PLATFORM_CONFIG.version.major + "." + global.PLATFORM_CONFIG.version.minor + "/" + global.EXCHANGE_NAME + "/" + bot.dataSetVersion; - let filePath = filePathRoot + "/Output/" + BOLINGER_BANDS_FOLDER_NAME + "/" + "Multi-Period-Market" + "/" + timePeriod; + let filePath = filePathRoot + "/Output/" + BOLLINGER_BANDS_FOLDER_NAME + "/" + "Multi-Period-Market" + "/" + timePeriod; chrisStorage.createTextFile(filePath, fileName, fileContent + '\n', onFileCreated); From 8ec74219faeb57c9ad4e433dbf9dffeecce3a7cd Mon Sep 17 00:00:00 2001 From: Luis Fernando Molina Date: Thu, 21 Feb 2019 12:21:58 +0100 Subject: [PATCH 04/40] New Product: Percentage Bandwitdth --- Multi-Period-Daily/User.Bot.js | 2 ++ this.bot.config.json | 36 ++++++++++++++++++++++++++++++++++ 2 files changed, 38 insertions(+) diff --git a/Multi-Period-Daily/User.Bot.js b/Multi-Period-Daily/User.Bot.js index d7d878654..92747b740 100644 --- a/Multi-Period-Daily/User.Bot.js +++ b/Multi-Period-Daily/User.Bot.js @@ -503,6 +503,7 @@ band = { begin: candles[i].begin, end: candles[i].end, + close: candles[i].close, movingAverage: movingAverage, standardDeviation: standardDeviation }; @@ -540,6 +541,7 @@ fileContent = fileContent + separator + '[' + band.begin + "," + band.end + "," + + band.close + "," + band.movingAverage + "," + band.standardDeviation + "]"; diff --git a/this.bot.config.json b/this.bot.config.json index 17acbe4ba..d9f1eef3c 100644 --- a/this.bot.config.json +++ b/this.bot.config.json @@ -146,6 +146,42 @@ "codeName": "PlottersBollingerBands", "moduleName": "BollingerBands" } + }, + { + "codeName": "Percentage-Bandwidth", + "displayName": "Percentage Bandwidth", + "description": "Percentage Bandwidth", + "storageAccount": "aachris", + "dataSets": [ + { + "codeName": "Multi-Period-Market", + "type": "Market Files", + "validPeriods": [ "24-hs", "12-hs", "08-hs", "06-hs", "04-hs", "03-hs", "02-hs", "01-hs" ], + "filePath": "AAMasters/AAChris.1.0/AACloud.1.1/@Exchange/dataSet.V1/Output/Bollinger-Bands/Multi-Period-Market/@Period", + "fileName": "@AssetA_@AssetB.json" + }, + { + "codeName": "Multi-Period-Daily", + "type": "Daily Files", + "validPeriods": [ "45-min", "40-min", "30-min", "20-min", "15-min", "10-min", "05-min", "04-min", "03-min", "02-min", "01-min" ], + "filePath": "AAMasters/AAChris.1.0/AACloud.1.1/@Exchange/dataSet.V1/Output/Bollinger-Bands/Multi-Period-Daily/@Period/@Year/@Month/@Day", + "fileName": "@AssetA_@AssetB.json", + "dataRange": { + "filePath": "AAMasters/AAChris.1.0/AACloud.1.1/@Exchange/dataSet.V1/Output/Bollinger-Bands/Multi-Period-Daily", + "fileName": "Data.Range.@AssetA_@AssetB.json" + } + } + ], + "exchangeList": [ + { + "name": "Poloniex" + } + ], + "plotter": { + "devTeam": "AAMasters", + "codeName": "PlottersBollingerBands", + "moduleName": "PercentageBandwidth" + } } ] } From 8d3304f283d878171dcdb194bdd3577418cea856 Mon Sep 17 00:00:00 2001 From: Luis Fernando Molina Date: Sun, 24 Feb 2019 11:19:21 +0100 Subject: [PATCH 05/40] Market Files Running with version 2 --- Multi-Period-Daily/User.Bot.js | 173 +++++++++++++++++++++++++++----- Multi-Period-Market/User.Bot.js | 165 ++++++++++++++++++++++++++---- this.bot.config.json | 6 +- 3 files changed, 301 insertions(+), 43 deletions(-) diff --git a/Multi-Period-Daily/User.Bot.js b/Multi-Period-Daily/User.Bot.js index 92747b740..e0711c260 100644 --- a/Multi-Period-Daily/User.Bot.js +++ b/Multi-Period-Daily/User.Bot.js @@ -15,6 +15,7 @@ const CANDLES_FOLDER_NAME = "Candles"; const BOLLINGER_BANDS_FOLDER_NAME = "Bollinger-Bands"; + const PERCENTAGE_BANDWIDTH_FOLDER_NAME = "Percentage-Bandwidth"; const commons = COMMONS.newCommons(bot, logger, UTILITIES); @@ -477,44 +478,101 @@ if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] start -> buildBands -> loopBody -> calculateBands -> Entering function."); } let bandsArray = []; - let numberOfPeriods = 20; + let pBArray = []; + let numberOfPeriodsBB = 20; + let numberOfStandardDeviations = 2; /* Building bands */ let band; + let previousBand; - for (let i = numberOfPeriods - 1; i < candles.length; i++) { // Go through all the candles to generate a band segment for each of them. + for (let i = numberOfPeriodsBB - 1; i < candles.length; i++) { // Go through all the candles to generate a band segment for each of them. + + /* Calculating the bollinger bands. */ let movingAverage = 0; - for (let j = i - numberOfPeriods + 1; j < i + 1; j++) { // go through the last n candles to calculate the moving average. + for (let j = i - numberOfPeriodsBB + 1; j < i + 1; j++) { // go through the last n candles to calculate the moving average. movingAverage = movingAverage + candles[j].close; } - movingAverage = movingAverage / numberOfPeriods; + movingAverage = movingAverage / numberOfPeriodsBB; let standardDeviation = 0; - for (let j = i - numberOfPeriods + 1; j < i + 1; j++) { // go through the last n candles to calculate the standard deviation. + for (let j = i - numberOfPeriodsBB + 1; j < i + 1; j++) { // go through the last n candles to calculate the standard deviation. standardDeviation = standardDeviation + Math.pow(candles[j].close - movingAverage, 2); } - standardDeviation = standardDeviation / numberOfPeriods; + standardDeviation = standardDeviation / numberOfPeriodsBB; standardDeviation = Math.sqrt(standardDeviation); - - band = { begin: candles[i].begin, end: candles[i].end, - close: candles[i].close, movingAverage: movingAverage, - standardDeviation: standardDeviation + standardDeviation: standardDeviation, + deviation: standardDeviation * numberOfStandardDeviations }; /* Will only add to the array the bands of the current day */ if (band.begin >= processDate.valueOf()) { bandsArray.push(band); } + + /* Calculating %B */ + + let lowerBB; + let upperBB; + + lowerBB = band.movingAverage - band.deviation; + upperBB = band.movingAverage + band.deviation; + + let currentPercentBandwidth = (candles[i].close - lowerBB) / (upperBB - lowerBB) * 100; + + let previousPercentBandwidth; + + if (previousBand !== undefined) { + + lowerBB = previousBand.movingAverage - previousBand.deviation; + upperBB = previousBand.movingAverage + previousBand.deviation; + + previousPercentBandwidth = (candles[i - 1].close - lowerBB) / (upperBB - lowerBB) * 100; + + } else { + previousPercentBandwidth = currentPercentBandwidth; + } + previousBand = band; + + /* Moving Average Calculation */ + + let numberOfPreviousPeriods; + let currentPosition = pBArray.length; + + if (currentPosition < numberOfPeriodsPB) { // Avoinding to get into negative array indexes + numberOfPreviousPeriods = currentPosition; + } else { + numberOfPreviousPeriods = numberOfPeriodsPB; + } + + movingAverage = 0; + for (let j = currentPosition - numberOfPreviousPeriods; j < currentPosition; j++) { // go through the last numberOfPeriodsPBs to calculate the moving average. + movingAverage = movingAverage + pBArray[j].currentPercentBandwidth; + } + movingAverage = movingAverage + currentPercentBandwidth; + movingAverage = movingAverage / (numberOfPreviousPeriods + 1); + + let percentageBandwidth = { + begin: candles[i].begin, + end: candles[i].end, + previousPercentBandwidth: previousPercentBandwidth, + currentPercentBandwidth: currentPercentBandwidth, + movingAverage: movingAverage + }; + + /* Will only add to the array the pBs of the current day */ + + if (pB.begin >= processDate.valueOf()) { pBArray.push(percentageBandwidth); } } - writeFile(bandsArray); + writeBandsFile(bandsArray, pBArray); } catch (err) { logger.write(MODULE_NAME, "[ERROR] start -> buildBands -> periodsLoop -> loopBody -> calculateBands -> err = " + err.message); @@ -523,11 +581,11 @@ } } - function writeFile(pBands, callback) { + function writeBandsFile(pBands, pPB) { try { - if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] start -> buildBands -> loopBody -> writeBandBandsFile -> writeFile -> Entering function."); } + if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] start -> buildBands -> loopBody -> writeBandBandsFile -> writeBandsFile -> Entering function."); } let separator = ""; let fileRecordCounter = 0; @@ -541,9 +599,9 @@ fileContent = fileContent + separator + '[' + band.begin + "," + band.end + "," + - band.close + "," + band.movingAverage + "," + - band.standardDeviation + "]"; + band.standardDeviation + "," + + band.deviation + "]"; if (separator === "") { separator = ","; } @@ -565,36 +623,105 @@ try { - if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] start -> buildBands -> loopBody -> writeBandBandsFile -> writeFile -> onFileCreated -> Entering function."); } + if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] start -> buildBands -> loopBody -> writeBandBandsFile -> writeBandsFile -> onFileCreated -> Entering function."); } if (LOG_FILE_CONTENT === true) { - logger.write(MODULE_NAME, "[INFO] start -> buildBands -> loopBody -> writeBandBandsFile -> writeFile -> onFileCreated -> Content written = " + fileContent); + logger.write(MODULE_NAME, "[INFO] start -> buildBands -> loopBody -> writeBandBandsFile -> writeBandsFile -> onFileCreated -> Content written = " + fileContent); } if (err.result !== global.DEFAULT_OK_RESPONSE.result) { - logger.write(MODULE_NAME, "[ERROR] start -> buildBands -> loopBody -> writeBandBandsFile -> writeFile -> onFileCreated -> err = " + err.message); + logger.write(MODULE_NAME, "[ERROR] start -> buildBands -> loopBody -> writeBandBandsFile -> writeBandsFile -> onFileCreated -> err = " + err.message); callBackFunction(err); return; } const logText = "[WARN] Finished with File @ " + market.assetA + "_" + market.assetB + ", " + fileRecordCounter + " records inserted into " + filePath + "/" + fileName + ""; - if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] start -> buildBands -> loopBody -> writeBandBandsFile -> writeFile -> onFileCreated -> " + logText); } + if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] start -> buildBands -> loopBody -> writeBandBandsFile -> writeBandsFile -> onFileCreated -> " + logText); } - controlLoop(); + writePBFile(pPB); } catch (err) { - logger.write(MODULE_NAME, "[ERROR] start -> buildBands -> periodsLoop -> loopBody -> writeBandBandsFile -> writeFile -> onFileCreated -> err = " + err.message); + logger.write(MODULE_NAME, "[ERROR] start -> buildBands -> periodsLoop -> loopBody -> writeBandBandsFile -> writeBandsFile -> onFileCreated -> err = " + err.message); callBackFunction(global.DEFAULT_RETRY_RESPONSE); } } } catch (err) { - logger.write(MODULE_NAME, "[ERROR] start -> buildBands -> periodsLoop -> loopBody -> writeBandBandsFile -> writeFile -> err = " + err.message); + logger.write(MODULE_NAME, "[ERROR] start -> buildBands -> periodsLoop -> loopBody -> writeBandBandsFile -> writeBandsFile -> err = " + err.message); callBackFunction(global.DEFAULT_FAIL_RESPONSE); } } - + function writePBFile(pPercentageBandwidths) { + + try { + + if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] start -> buildBands -> loopBody -> writeBandBandsFile -> writePBFile -> Entering function."); } + + let separator = ""; + let fileRecordCounter = 0; + + let fileContent = ""; + + for (i = 0; i < pPercentageBandwidths.length; i++) { + + let pB = pPercentageBandwidths[i]; + + fileContent = fileContent + separator + '[' + + pB.begin + "," + + pB.end + "," + + pB.previousPercentBandwidth + "," + + pB.currentPercentBandwidth + "," + + pB.movingAverage + "]"; + + if (separator === "") { separator = ","; } + + fileRecordCounter++; + + } + + fileContent = "[" + fileContent + "]"; + + let dateForPath = processDate.getUTCFullYear() + '/' + utilities.pad(processDate.getUTCMonth() + 1, 2) + '/' + utilities.pad(processDate.getUTCDate(), 2); + let fileName = '' + market.assetA + '_' + market.assetB + '.json'; + + let filePathRoot = bot.devTeam + "/" + bot.codeName + "." + bot.version.major + "." + bot.version.minor + "/" + global.PLATFORM_CONFIG.codeName + "." + global.PLATFORM_CONFIG.version.major + "." + global.PLATFORM_CONFIG.version.minor + "/" + global.EXCHANGE_NAME + "/" + bot.dataSetVersion; + let filePath = filePathRoot + "/Output/" + PERCENTAGE_BANDWIDTH_FOLDER_NAME + "/" + bot.process + "/" + timePeriod + "/" + dateForPath; + + chrisStorage.createTextFile(filePath, fileName, fileContent + '\n', onFileCreated); + + function onFileCreated(err) { + + try { + + if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] start -> buildBands -> loopBody -> writeBandBandsFile -> writePBFile -> onFileCreated -> Entering function."); } + + if (LOG_FILE_CONTENT === true) { + logger.write(MODULE_NAME, "[INFO] start -> buildBands -> loopBody -> writeBandBandsFile -> writePBFile -> onFileCreated -> Content written = " + fileContent); + } + + if (err.result !== global.DEFAULT_OK_RESPONSE.result) { + logger.write(MODULE_NAME, "[ERROR] start -> buildBands -> loopBody -> writeBandBandsFile -> writePBFile -> onFileCreated -> err = " + err.message); + callBackFunction(err); + return; + } + + const logText = "[WARN] Finished with File @ " + market.assetA + "_" + market.assetB + ", " + fileRecordCounter + " records inserted into " + filePath + "/" + fileName + ""; + if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] start -> buildBands -> loopBody -> writeBandBandsFile -> writePBFile -> onFileCreated -> " + logText); } + + controlLoop(); + + } catch (err) { + logger.write(MODULE_NAME, "[ERROR] start -> buildBands -> periodsLoop -> loopBody -> writeBandBandsFile -> writePBFile -> onFileCreated -> err = " + err.message); + callBackFunction(global.DEFAULT_RETRY_RESPONSE); + } + } + + } catch (err) { + logger.write(MODULE_NAME, "[ERROR] start -> buildBands -> periodsLoop -> loopBody -> writeBandBandsFile -> writePBFile -> err = " + err.message); + callBackFunction(global.DEFAULT_FAIL_RESPONSE); + } + } } catch (err) { diff --git a/Multi-Period-Market/User.Bot.js b/Multi-Period-Market/User.Bot.js index 7a91ac933..752687c86 100644 --- a/Multi-Period-Market/User.Bot.js +++ b/Multi-Period-Market/User.Bot.js @@ -11,6 +11,7 @@ const CANDLES_FOLDER_NAME = "Candles"; const BOLLINGER_BANDS_FOLDER_NAME = "Bollinger-Bands"; + const PERCENTAGE_BANDWIDTH_FOLDER_NAME = "Percentage-Bandwidth"; const commons = COMMONS.newCommons(bot, logger, UTILITIES); @@ -153,7 +154,6 @@ let marketFile = JSON.parse(text); let candles = []; - let bandsArray = []; buildCandles(); @@ -203,40 +203,99 @@ if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] start -> buildBands -> loopBody -> nextCandleFile -> onFileReceived -> buildBands -> Entering function."); } - let n = 20; + let bandsArray = []; + let pBArray = []; + let numberOfPeriodsBB = 20; + let numberOfStandardDeviations = 2; + let numberOfPeriodsPB = 10; /* Building bands */ let band; + let previousBand; - for (let i = n - 1; i < candles.length; i++) { // Go through all the candles to generate a band segment for each of them. + for (let i = numberOfPeriodsBB - 1; i < candles.length; i++) { // Go through all the candles to generate a band segment for each of them. let movingAverage = 0; - for (let j = i - n + 1; j < i + 1; j++) { // go through the last n candles to calculate the moving average. + for (let j = i - numberOfPeriodsBB + 1; j < i + 1; j++) { // go through the last numberOfPeriodsBB candles to calculate the moving average. movingAverage = movingAverage + candles[j].close; } - movingAverage = movingAverage / n; + movingAverage = movingAverage / numberOfPeriodsBB; let standardDeviation = 0; - for (let j = i - n + 1; j < i + 1; j++) { // go through the last n candles to calculate the standard deviation. + for (let j = i - numberOfPeriodsBB + 1; j < i + 1; j++) { // go through the last numberOfPeriodsBB candles to calculate the standard deviation. standardDeviation = standardDeviation + Math.pow (candles[j].close - movingAverage, 2); } - standardDeviation = standardDeviation / n; + standardDeviation = standardDeviation / numberOfPeriodsBB; standardDeviation = Math.sqrt(standardDeviation); band = { begin: candles[i].begin, end: candles[i].end, - close: candles[i].close, movingAverage: movingAverage, - standardDeviation: standardDeviation + standardDeviation: standardDeviation, + deviation: standardDeviation * numberOfStandardDeviations }; bandsArray.push(band); - + + /* Calculating %B */ + + let lowerBB; + let upperBB; + + lowerBB = band.movingAverage - band.deviation; + upperBB = band.movingAverage + band.deviation; + + let currentPercentBandwidth = (candles[i].close - lowerBB) / (upperBB - lowerBB) * 100; + + let previousPercentBandwidth; + + if (previousBand !== undefined) { + + lowerBB = previousBand.movingAverage - previousBand.deviation; + upperBB = previousBand.movingAverage + previousBand.deviation; + + previousPercentBandwidth = (candles[i-1].close - lowerBB) / (upperBB - lowerBB) * 100; + + } else { + previousPercentBandwidth = currentPercentBandwidth; + } + + previousBand = band; + + /* Moving Average Calculation */ + + let numberOfPreviousPeriods; + let currentPosition = pBArray.length; + + if (currentPosition < numberOfPeriodsPB) { // Avoinding to get into negative array indexes + numberOfPreviousPeriods = currentPosition; + } else { + numberOfPreviousPeriods = numberOfPeriodsPB; + } + + movingAverage = 0; + for (let j = currentPosition - numberOfPreviousPeriods; j < currentPosition; j++) { // go through the last numberOfPeriodsPBs to calculate the moving average. + movingAverage = movingAverage + pBArray[j].currentPercentBandwidth; + } + movingAverage = movingAverage + currentPercentBandwidth; + movingAverage = movingAverage / (numberOfPreviousPeriods + 1); + + let percentageBandwidth = { + begin: candles[i].begin, + end: candles[i].end, + previousPercentBandwidth: previousPercentBandwidth, + currentPercentBandwidth: currentPercentBandwidth, + movingAverage: movingAverage + }; + + /* Will only add to the array the pBs of the current day */ + + pBArray.push(percentageBandwidth); } - writeBandsFile(); + writeBandsFile(bandsArray, pBArray); } catch (err) { logger.write(MODULE_NAME, "[ERROR] start -> buildBands -> loopBody -> nextCandleFile -> onFileReceived -> buildBands -> err = " + err.message); @@ -244,7 +303,7 @@ } } - function writeBandsFile() { + function writeBandsFile(pBands, pPB) { try { @@ -255,16 +314,16 @@ let fileContent = ""; - for (i = 0; i < bandsArray.length; i++) { + for (i = 0; i < pBands.length; i++) { - let band = bandsArray[i]; + let band = pBands[i]; fileContent = fileContent + separator + '[' + band.begin + "," + band.end + "," + - band.close + "," + band.movingAverage + "," + - band.standardDeviation + "]"; + band.standardDeviation + "," + + band.deviation + "]"; if (separator === "") { separator = ","; } @@ -299,7 +358,7 @@ } - controlLoop(); + writePBFile(pPB); } catch (err) { @@ -313,6 +372,78 @@ callBackFunction(global.DEFAULT_FAIL_RESPONSE); } } + + + function writePBFile(pPercentageBandwidths) { + + try { + + if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] start -> buildBands -> loopBody -> nextCandleFile -> onFileReceived -> writePBFile -> Entering function."); } + + let separator = ""; + let fileRecordCounter = 0; + + let fileContent = ""; + + for (i = 0; i < pPercentageBandwidths.length; i++) { + + let pB = pPercentageBandwidths[i]; + + fileContent = fileContent + separator + '[' + + pB.begin + "," + + pB.end + "," + + pB.previousPercentBandwidth + "," + + pB.currentPercentBandwidth + "," + + pB.movingAverage + "]"; + + if (separator === "") { separator = ","; } + + fileRecordCounter++; + + } + + fileContent = "[" + fileContent + "]"; + + let fileName = '' + market.assetA + '_' + market.assetB + '.json'; + + let filePathRoot = bot.devTeam + "/" + bot.codeName + "." + bot.version.major + "." + bot.version.minor + "/" + global.PLATFORM_CONFIG.codeName + "." + global.PLATFORM_CONFIG.version.major + "." + global.PLATFORM_CONFIG.version.minor + "/" + global.EXCHANGE_NAME + "/" + bot.dataSetVersion; + let filePath = filePathRoot + "/Output/" + PERCENTAGE_BANDWIDTH_FOLDER_NAME + "/" + "Multi-Period-Market" + "/" + timePeriod; + + chrisStorage.createTextFile(filePath, fileName, fileContent + '\n', onFileCreated); + + function onFileCreated(err) { + + try { + + if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] start -> buildBands -> loopBody -> nextCandleFile -> onFileReceived -> writePBFile -> onFileCreated -> Entering function."); } + if (LOG_FILE_CONTENT === true) { logger.write(MODULE_NAME, "[INFO] start -> buildBands -> loopBody -> nextCandleFile -> onFileReceived -> writePBFile -> onFileCreated -> fileContent = " + fileContent); } + + if (err.result !== global.DEFAULT_OK_RESPONSE.result) { + + logger.write(MODULE_NAME, "[ERROR] start -> buildBands -> loopBody -> nextCandleFile -> onFileReceived -> writePBFile -> onFileCreated -> err = " + err.message); + logger.write(MODULE_NAME, "[ERROR] start -> buildBands -> loopBody -> nextCandleFile -> onFileReceived -> writePBFile -> onFileCreated -> filePath = " + filePath); + logger.write(MODULE_NAME, "[ERROR] start -> buildBands -> loopBody -> nextCandleFile -> onFileReceived -> writePBFile -> onFileCreated -> market = " + market.assetA + "_" + market.assetB); + + callBackFunction(err); + return; + + } + + controlLoop(); + + } + catch (err) { + logger.write(MODULE_NAME, "[ERROR] start -> buildBands -> loopBody -> nextCandleFile -> onFileReceived -> writePBFile -> onFileCreated -> err = " + err.message); + callBackFunction(global.DEFAULT_FAIL_RESPONSE); + } + } + } + catch (err) { + logger.write(MODULE_NAME, "[ERROR] start -> buildBands -> loopBody -> nextCandleFile -> onFileReceived -> writePBFile -> err = " + err.message); + callBackFunction(global.DEFAULT_FAIL_RESPONSE); + } + } + } catch (err) { logger.write(MODULE_NAME, "[ERROR] start -> buildBands -> loopBody -> nextCandleFile -> onFileReceived -> err = " + err.message); diff --git a/this.bot.config.json b/this.bot.config.json index d9f1eef3c..df4e2643b 100644 --- a/this.bot.config.json +++ b/this.bot.config.json @@ -157,17 +157,17 @@ "codeName": "Multi-Period-Market", "type": "Market Files", "validPeriods": [ "24-hs", "12-hs", "08-hs", "06-hs", "04-hs", "03-hs", "02-hs", "01-hs" ], - "filePath": "AAMasters/AAChris.1.0/AACloud.1.1/@Exchange/dataSet.V1/Output/Bollinger-Bands/Multi-Period-Market/@Period", + "filePath": "AAMasters/AAChris.1.0/AACloud.1.1/@Exchange/dataSet.V1/Output/Percentage-Bandwidth/Multi-Period-Market/@Period", "fileName": "@AssetA_@AssetB.json" }, { "codeName": "Multi-Period-Daily", "type": "Daily Files", "validPeriods": [ "45-min", "40-min", "30-min", "20-min", "15-min", "10-min", "05-min", "04-min", "03-min", "02-min", "01-min" ], - "filePath": "AAMasters/AAChris.1.0/AACloud.1.1/@Exchange/dataSet.V1/Output/Bollinger-Bands/Multi-Period-Daily/@Period/@Year/@Month/@Day", + "filePath": "AAMasters/AAChris.1.0/AACloud.1.1/@Exchange/dataSet.V1/Output/Percentage-Bandwidth/Multi-Period-Daily/@Period/@Year/@Month/@Day", "fileName": "@AssetA_@AssetB.json", "dataRange": { - "filePath": "AAMasters/AAChris.1.0/AACloud.1.1/@Exchange/dataSet.V1/Output/Bollinger-Bands/Multi-Period-Daily", + "filePath": "AAMasters/AAChris.1.0/AACloud.1.1/@Exchange/dataSet.V1/Output/Percentage-Bandwidth/Multi-Period-Daily", "fileName": "Data.Range.@AssetA_@AssetB.json" } } From 8202cd73c1fa11c43df0b8663fc7b162bac0ee9c Mon Sep 17 00:00:00 2001 From: Luis Fernando Molina Date: Sun, 24 Feb 2019 16:55:06 +0100 Subject: [PATCH 06/40] Working version --- Multi-Period-Daily/User.Bot.js | 32 ++++++++------------------------ Multi-Period-Market/User.Bot.js | 31 +++++++------------------------ 2 files changed, 15 insertions(+), 48 deletions(-) diff --git a/Multi-Period-Daily/User.Bot.js b/Multi-Period-Daily/User.Bot.js index e0711c260..f092a78bc 100644 --- a/Multi-Period-Daily/User.Bot.js +++ b/Multi-Period-Daily/User.Bot.js @@ -481,11 +481,11 @@ let pBArray = []; let numberOfPeriodsBB = 20; let numberOfStandardDeviations = 2; + let numberOfPeriodsPB = 10; /* Building bands */ let band; - let previousBand; for (let i = numberOfPeriodsBB - 1; i < candles.length; i++) { // Go through all the candles to generate a band segment for each of them. @@ -503,6 +503,7 @@ } standardDeviation = standardDeviation / numberOfPeriodsBB; standardDeviation = Math.sqrt(standardDeviation); + if (standardDeviation === 0) { standardDeviation = 0.000000001; } // This is to prevent a division by zero later. band = { begin: candles[i].begin, @@ -524,22 +525,7 @@ lowerBB = band.movingAverage - band.deviation; upperBB = band.movingAverage + band.deviation; - let currentPercentBandwidth = (candles[i].close - lowerBB) / (upperBB - lowerBB) * 100; - - let previousPercentBandwidth; - - if (previousBand !== undefined) { - - lowerBB = previousBand.movingAverage - previousBand.deviation; - upperBB = previousBand.movingAverage + previousBand.deviation; - - previousPercentBandwidth = (candles[i - 1].close - lowerBB) / (upperBB - lowerBB) * 100; - - } else { - previousPercentBandwidth = currentPercentBandwidth; - } - - previousBand = band; + let value = (candles[i].close - lowerBB) / (upperBB - lowerBB) * 100; /* Moving Average Calculation */ @@ -554,22 +540,21 @@ movingAverage = 0; for (let j = currentPosition - numberOfPreviousPeriods; j < currentPosition; j++) { // go through the last numberOfPeriodsPBs to calculate the moving average. - movingAverage = movingAverage + pBArray[j].currentPercentBandwidth; + movingAverage = movingAverage + pBArray[j].value; } - movingAverage = movingAverage + currentPercentBandwidth; + movingAverage = movingAverage + value; movingAverage = movingAverage / (numberOfPreviousPeriods + 1); let percentageBandwidth = { begin: candles[i].begin, end: candles[i].end, - previousPercentBandwidth: previousPercentBandwidth, - currentPercentBandwidth: currentPercentBandwidth, + value: value, movingAverage: movingAverage }; /* Will only add to the array the pBs of the current day */ - if (pB.begin >= processDate.valueOf()) { pBArray.push(percentageBandwidth); } + if (percentageBandwidth.begin >= processDate.valueOf()) { pBArray.push(percentageBandwidth); } } writeBandsFile(bandsArray, pBArray); @@ -670,8 +655,7 @@ fileContent = fileContent + separator + '[' + pB.begin + "," + pB.end + "," + - pB.previousPercentBandwidth + "," + - pB.currentPercentBandwidth + "," + + pB.value + "," + pB.movingAverage + "]"; if (separator === "") { separator = ","; } diff --git a/Multi-Period-Market/User.Bot.js b/Multi-Period-Market/User.Bot.js index 752687c86..d24062f7e 100644 --- a/Multi-Period-Market/User.Bot.js +++ b/Multi-Period-Market/User.Bot.js @@ -207,12 +207,11 @@ let pBArray = []; let numberOfPeriodsBB = 20; let numberOfStandardDeviations = 2; - let numberOfPeriodsPB = 10; + let numberOfPeriodsPB = 5; /* Building bands */ let band; - let previousBand; for (let i = numberOfPeriodsBB - 1; i < candles.length; i++) { // Go through all the candles to generate a band segment for each of them. @@ -228,6 +227,7 @@ } standardDeviation = standardDeviation / numberOfPeriodsBB; standardDeviation = Math.sqrt(standardDeviation); + if (standardDeviation === 0) { standardDeviation = 0.000000001; } // This is to prevent a division by zero later. band = { begin: candles[i].begin, @@ -247,22 +247,7 @@ lowerBB = band.movingAverage - band.deviation; upperBB = band.movingAverage + band.deviation; - let currentPercentBandwidth = (candles[i].close - lowerBB) / (upperBB - lowerBB) * 100; - - let previousPercentBandwidth; - - if (previousBand !== undefined) { - - lowerBB = previousBand.movingAverage - previousBand.deviation; - upperBB = previousBand.movingAverage + previousBand.deviation; - - previousPercentBandwidth = (candles[i-1].close - lowerBB) / (upperBB - lowerBB) * 100; - - } else { - previousPercentBandwidth = currentPercentBandwidth; - } - - previousBand = band; + let value = (candles[i].close - lowerBB) / (upperBB - lowerBB) * 100; /* Moving Average Calculation */ @@ -277,16 +262,15 @@ movingAverage = 0; for (let j = currentPosition - numberOfPreviousPeriods; j < currentPosition; j++) { // go through the last numberOfPeriodsPBs to calculate the moving average. - movingAverage = movingAverage + pBArray[j].currentPercentBandwidth; + movingAverage = movingAverage + pBArray[j].value; } - movingAverage = movingAverage + currentPercentBandwidth; + movingAverage = movingAverage + value; movingAverage = movingAverage / (numberOfPreviousPeriods + 1); let percentageBandwidth = { begin: candles[i].begin, end: candles[i].end, - previousPercentBandwidth: previousPercentBandwidth, - currentPercentBandwidth: currentPercentBandwidth, + value: value, movingAverage: movingAverage }; @@ -392,8 +376,7 @@ fileContent = fileContent + separator + '[' + pB.begin + "," + pB.end + "," + - pB.previousPercentBandwidth + "," + - pB.currentPercentBandwidth + "," + + pB.value + "," + pB.movingAverage + "]"; if (separator === "") { separator = ","; } From 3d75eb249a1ae4a90d0cfd6b2506442f01034f31 Mon Sep 17 00:00:00 2001 From: Luis Fernando Molina Date: Wed, 6 Mar 2019 00:48:52 +0100 Subject: [PATCH 07/40] Bandwidth --- Multi-Period-Market/User.Bot.js | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/Multi-Period-Market/User.Bot.js b/Multi-Period-Market/User.Bot.js index d24062f7e..922a2b8f2 100644 --- a/Multi-Period-Market/User.Bot.js +++ b/Multi-Period-Market/User.Bot.js @@ -267,15 +267,16 @@ movingAverage = movingAverage + value; movingAverage = movingAverage / (numberOfPreviousPeriods + 1); + let bandwidth = (upperBB- lowerBB) / band.movingAverage; + let percentageBandwidth = { begin: candles[i].begin, end: candles[i].end, value: value, - movingAverage: movingAverage + movingAverage: movingAverage, + bandwidth: bandwidth }; - /* Will only add to the array the pBs of the current day */ - pBArray.push(percentageBandwidth); } @@ -377,7 +378,8 @@ pB.begin + "," + pB.end + "," + pB.value + "," + - pB.movingAverage + "]"; + pB.movingAverage + "," + + pB.bandwidth + "]"; if (separator === "") { separator = ","; } From 5d75b31c97c3746af82727283377ecf4728a0d77 Mon Sep 17 00:00:00 2001 From: Luis Fernando Molina Date: Sat, 9 Mar 2019 19:53:26 +0100 Subject: [PATCH 08/40] Bandwidth Implemented --- Multi-Period-Daily/User.Bot.js | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/Multi-Period-Daily/User.Bot.js b/Multi-Period-Daily/User.Bot.js index f092a78bc..3d6381ccf 100644 --- a/Multi-Period-Daily/User.Bot.js +++ b/Multi-Period-Daily/User.Bot.js @@ -545,11 +545,14 @@ movingAverage = movingAverage + value; movingAverage = movingAverage / (numberOfPreviousPeriods + 1); + let bandwidth = (upperBB - lowerBB) / band.movingAverage; + let percentageBandwidth = { begin: candles[i].begin, end: candles[i].end, value: value, - movingAverage: movingAverage + movingAverage: movingAverage, + bandwidth: bandwidth }; /* Will only add to the array the pBs of the current day */ @@ -656,7 +659,8 @@ pB.begin + "," + pB.end + "," + pB.value + "," + - pB.movingAverage + "]"; + pB.movingAverage + "," + + pB.bandwidth + "]"; if (separator === "") { separator = ","; } From 5c53adce83be6fe0f0662befb72eba221bc62326 Mon Sep 17 00:00:00 2001 From: Luis Fernando Molina Date: Sun, 10 Mar 2019 08:51:50 +0100 Subject: [PATCH 09/40] Data range file not being updated for %B --- Multi-Period-Daily/User.Bot.js | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/Multi-Period-Daily/User.Bot.js b/Multi-Period-Daily/User.Bot.js index 3d6381ccf..2ee2b5210 100644 --- a/Multi-Period-Daily/User.Bot.js +++ b/Multi-Period-Daily/User.Bot.js @@ -788,7 +788,21 @@ return; } - callBack(global.DEFAULT_OK_RESPONSE); + writeDataRange(contextVariables.firstTradeFile, processDate, PERCENTAGE_BANDWIDTH_FOLDER_NAME, onPercentageBandwidthDataRangeWritten); + + function onPercentageBandwidthDataRangeWritten(err) { + + if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] start -> writeDataRanges -> Entering function."); } + + if (err.result !== global.DEFAULT_OK_RESPONSE.result) { + logger.write(MODULE_NAME, "[ERROR] writeDataRanges -> writeDataRanges -> onBandsBandsDataRangeWritten -> onPercentageBandwidthDataRangeWritten -> err = " + err.message); + callBack(err); + return; + } + + callBack(global.DEFAULT_OK_RESPONSE); + + } } } From a83bf98dadf6fac9000550faa31e4de416b424ba Mon Sep 17 00:00:00 2001 From: Luis Fernando Molina Date: Mon, 1 Apr 2019 14:21:46 +0200 Subject: [PATCH 10/40] Removing Poloniex from Code, adding Coss to config --- Multi-Period-Daily/User.Bot.js | 4 +--- Multi-Period-Market/User.Bot.js | 2 -- this.bot.config.json | 8 +++++++- 3 files changed, 8 insertions(+), 6 deletions(-) diff --git a/Multi-Period-Daily/User.Bot.js b/Multi-Period-Daily/User.Bot.js index 2ee2b5210..3ac7ea05f 100644 --- a/Multi-Period-Daily/User.Bot.js +++ b/Multi-Period-Daily/User.Bot.js @@ -9,8 +9,6 @@ const MODULE_NAME = "User Bot"; - const EXCHANGE_NAME = "Poloniex"; - const TRADES_FOLDER_NAME = "Trades"; const CANDLES_FOLDER_NAME = "Candles"; @@ -106,7 +104,7 @@ /* We look first for Charly in order to get when the market starts. */ - reportKey = "AAMasters" + "-" + "AACharly" + "-" + "Poloniex-Historic-Trades" + "-" + "dataSet.V1"; + reportKey = "AAMasters" + "-" + "AACharly" + "-" + "Historic-Trades" + "-" + "dataSet.V1"; if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] start -> getContextVariables -> reportKey = " + reportKey); } statusReport = statusDependencies.statusReports.get(reportKey); diff --git a/Multi-Period-Market/User.Bot.js b/Multi-Period-Market/User.Bot.js index 922a2b8f2..1ac0d72ec 100644 --- a/Multi-Period-Market/User.Bot.js +++ b/Multi-Period-Market/User.Bot.js @@ -5,8 +5,6 @@ const MODULE_NAME = "User Bot"; - const EXCHANGE_NAME = "Poloniex"; - const TRADES_FOLDER_NAME = "Trades"; const CANDLES_FOLDER_NAME = "Candles"; diff --git a/this.bot.config.json b/this.bot.config.json index df4e2643b..80ccc06af 100644 --- a/this.bot.config.json +++ b/this.bot.config.json @@ -84,7 +84,7 @@ "major": 1, "minor": 0 }, - "process": "Poloniex-Historic-Trades", + "process": "Historic-Trades", "dataSetVersion": "dataSet.V1" }, { @@ -139,6 +139,9 @@ "exchangeList": [ { "name": "Poloniex" + }, + { + "name": "Coss" } ], "plotter": { @@ -175,6 +178,9 @@ "exchangeList": [ { "name": "Poloniex" + }, + { + "name": "Coss" } ], "plotter": { From e9642d89e1bcc3ebe5188f911bb93a23539056fa Mon Sep 17 00:00:00 2001 From: Luis Fernando Molina Date: Wed, 24 Apr 2019 20:36:11 +0200 Subject: [PATCH 11/40] Public Indicator declaration --- this.bot.config.json | 2 ++ 1 file changed, 2 insertions(+) diff --git a/this.bot.config.json b/this.bot.config.json index 80ccc06af..a1e6bc2f3 100644 --- a/this.bot.config.json +++ b/this.bot.config.json @@ -116,6 +116,7 @@ "displayName": "Bollinger Bands", "description": "Bollinger Bands", "storageAccount": "aachris", + "shareWith": "Public", "dataSets": [ { "codeName": "Multi-Period-Market", @@ -155,6 +156,7 @@ "displayName": "Percentage Bandwidth", "description": "Percentage Bandwidth", "storageAccount": "aachris", + "shareWith": "Public", "dataSets": [ { "codeName": "Multi-Period-Market", From 5d0693113f79cae9109a3565c0394946aaf68647 Mon Sep 17 00:00:00 2001 From: Matias Date: Sat, 22 Jun 2019 12:45:29 -0300 Subject: [PATCH 12/40] File storage dependency --- Commons.js | 66 --------------------------------- Multi-Period-Daily/User.Bot.js | 65 +++++++++++++------------------- Multi-Period-Market/User.Bot.js | 59 +++++++++++------------------ 3 files changed, 46 insertions(+), 144 deletions(-) delete mode 100644 Commons.js diff --git a/Commons.js b/Commons.js deleted file mode 100644 index 6f4edfe55..000000000 --- a/Commons.js +++ /dev/null @@ -1,66 +0,0 @@ -exports.newCommons = function newCommons(bot, logger, UTILITIES) { - - const FULL_LOG = true; - const LOG_FILE_CONTENT = false; - - const MODULE_NAME = "Commons"; - - const GMT_SECONDS = ':00.000 GMT+0000'; - - let thisObject = { - initializeStorage: initializeStorage - }; - - let utilities = UTILITIES.newCloudUtilities(bot, logger); - - return thisObject; - - function initializeStorage(oliviaStorage, chrisStorage, callBackFunction) { - - try { - - if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] initializeStorage -> Entering function."); } - - initializetomStorage(); - - function initializetomStorage() { - - chrisStorage.initialize(bot.devTeam, onBruceInizialized); - - function onBruceInizialized(err) { - - if (err.result === global.DEFAULT_OK_RESPONSE.result) { - - initializeOliviaStorage(); - - } else { - logger.write(MODULE_NAME, "[ERROR] initializeStorage -> initializetomStorage -> onBruceInizialized -> err = " + err.message); - callBackFunction(err); - } - } - } - - function initializeOliviaStorage() { - - oliviaStorage.initialize(bot.devTeam, onOliviaInizialized); - - function onOliviaInizialized(err) { - - if (err.result === global.DEFAULT_OK_RESPONSE.result) { - - callBackFunction(global.DEFAULT_OK_RESPONSE); - - } else { - logger.write(MODULE_NAME, "[ERROR] initializeStorage -> initializeOliviaStorage -> onOliviaInizialized -> err = " + err.message); - callBackFunction(err); - } - } - } - } - catch (err) { - logger.write(MODULE_NAME, "[ERROR] initializeStorage -> err = " + err.message); - callBackFunction(global.DEFAULT_FAIL_RESPONSE); - } - } - -}; \ No newline at end of file diff --git a/Multi-Period-Daily/User.Bot.js b/Multi-Period-Daily/User.Bot.js index 3ac7ea05f..1d321dc3a 100644 --- a/Multi-Period-Daily/User.Bot.js +++ b/Multi-Period-Daily/User.Bot.js @@ -1,4 +1,4 @@ -exports.newUserBot = function newUserBot(bot, logger, COMMONS, UTILITIES, BLOB_STORAGE, FILE_STORAGE) { +exports.newUserBot = function newUserBot(bot, logger, COMMONS, UTILITIES, fileStorage) { const FULL_LOG = true; const INTENSIVE_LOG = false; @@ -15,16 +15,11 @@ const BOLLINGER_BANDS_FOLDER_NAME = "Bollinger-Bands"; const PERCENTAGE_BANDWIDTH_FOLDER_NAME = "Percentage-Bandwidth"; - const commons = COMMONS.newCommons(bot, logger, UTILITIES); - thisObject = { initialize: initialize, start: start }; - let oliviaStorage = BLOB_STORAGE.newBlobStorage(bot, logger); - let chrisStorage = BLOB_STORAGE.newBlobStorage(bot, logger); - let utilities = UTILITIES.newCloudUtilities(bot, logger); let statusDependencies; @@ -42,20 +37,7 @@ statusDependencies = pStatusDependencies; - commons.initializeStorage(oliviaStorage, chrisStorage, onInizialized); - - function onInizialized(err) { - - if (err.result === global.DEFAULT_OK_RESPONSE.result) { - - if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] initialize -> onInizialized -> Initialization Succeed."); } - callBackFunction(global.DEFAULT_OK_RESPONSE); - - } else { - logger.write(MODULE_NAME, "[ERROR] initialize -> onInizialized -> err = " + err.message); - callBackFunction(err); - } - } + callBackFunction(global.DEFAULT_OK_RESPONSE); } catch (err) { logger.write(MODULE_NAME, "[ERROR] initialize -> err = " + err.message); @@ -64,11 +46,11 @@ } /* - + This process is going to do the following: - + Read the candles from Olivia and produce daily files with bollinger bands. - + */ function start(callBackFunction) { @@ -221,7 +203,7 @@ */ contextVariables.lastBandFile = new Date(contextVariables.firstTradeFile.getUTCFullYear() + "-" + (contextVariables.firstTradeFile.getUTCMonth() + 1) + "-" + contextVariables.firstTradeFile.getUTCDate() + " " + "00:00" + GMT_SECONDS); - contextVariables.lastBandFile = new Date(contextVariables.lastBandFile.valueOf() + ONE_DAY_IN_MILISECONDS); + contextVariables.lastBandFile = new Date(contextVariables.lastBandFile.valueOf() + ONE_DAY_IN_MILISECONDS); if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] start -> getContextVariables -> thisReport.lastFile === undefined"); } if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] start -> getContextVariables -> contextVariables.lastBandFile = " + contextVariables.lastBandFile); } @@ -293,9 +275,9 @@ if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] start -> buildBands -> periodsLoop -> Entering function."); } /* - + We will iterate through all posible timePeriods. - + */ n = 0 // loop Variable representing each possible period as defined at the periods array. @@ -332,10 +314,11 @@ let dateForPath = previousDay.getUTCFullYear() + '/' + utilities.pad(previousDay.getUTCMonth() + 1, 2) + '/' + utilities.pad(previousDay.getUTCDate(), 2); let fileName = market.assetA + '_' + market.assetB + ".json" - let filePathRoot = bot.devTeam + "/" + "AAOlivia" + "." + bot.version.major + "." + bot.version.minor + "/" + global.PLATFORM_CONFIG.codeName + "." + global.PLATFORM_CONFIG.version.major + "." + global.PLATFORM_CONFIG.version.minor + "/" + global.EXCHANGE_NAME + "/" + bot.dataSetVersion; + let filePathRoot = bot.devTeam + "/" + "AAOlivia" + "." + bot.version.major + "." + bot.version.minor + "/" + global.CLONE_EXECUTOR.codeName + "." + global.CLONE_EXECUTOR.version + "/" + global.EXCHANGE_NAME + "/" + bot.dataSetVersion; let filePath = filePathRoot + "/Output/" + CANDLES_FOLDER_NAME + '/' + "Multi-Period-Daily" + "/" + timePeriod + "/" + dateForPath; + filePath += '/' + fileName - oliviaStorage.getTextFile(filePath, fileName, onCurrentDayFileReceived, true); + fileStorage.getTextFile(bot.devTeam, filePath, onCurrentDayFileReceived, true); function onCurrentDayFileReceived(err, text) { @@ -371,10 +354,11 @@ let dateForPath = processDate.getUTCFullYear() + '/' + utilities.pad(processDate.getUTCMonth() + 1, 2) + '/' + utilities.pad(processDate.getUTCDate(), 2); let fileName = market.assetA + '_' + market.assetB + ".json" - let filePathRoot = bot.devTeam + "/" + "AAOlivia" + "." + bot.version.major + "." + bot.version.minor + "/" + global.PLATFORM_CONFIG.codeName + "." + global.PLATFORM_CONFIG.version.major + "." + global.PLATFORM_CONFIG.version.minor + "/" + global.EXCHANGE_NAME + "/" + bot.dataSetVersion; + let filePathRoot = bot.devTeam + "/" + "AAOlivia" + "." + bot.version.major + "." + bot.version.minor + "/" + global.CLONE_EXECUTOR.codeName + "." + global.CLONE_EXECUTOR.version + "/" + global.EXCHANGE_NAME + "/" + bot.dataSetVersion; let filePath = filePathRoot + "/Output/" + CANDLES_FOLDER_NAME + '/' + "Multi-Period-Daily" + "/" + timePeriod + "/" + dateForPath; + filePath += '/' + fileName - oliviaStorage.getTextFile(filePath, fileName, onCurrentDayFileReceived, true); + fileStorage.getTextFile(bot.devTeam, filePath, onCurrentDayFileReceived, true); function onCurrentDayFileReceived(err, text) { @@ -501,7 +485,7 @@ } standardDeviation = standardDeviation / numberOfPeriodsBB; standardDeviation = Math.sqrt(standardDeviation); - if (standardDeviation === 0) { standardDeviation = 0.000000001; } // This is to prevent a division by zero later. + if (standardDeviation === 0) { standardDeviation = 0.000000001; } // This is to prevent a division by zero later. band = { begin: candles[i].begin, @@ -524,7 +508,7 @@ upperBB = band.movingAverage + band.deviation; let value = (candles[i].close - lowerBB) / (upperBB - lowerBB) * 100; - + /* Moving Average Calculation */ let numberOfPreviousPeriods; @@ -600,10 +584,11 @@ let dateForPath = processDate.getUTCFullYear() + '/' + utilities.pad(processDate.getUTCMonth() + 1, 2) + '/' + utilities.pad(processDate.getUTCDate(), 2); let fileName = '' + market.assetA + '_' + market.assetB + '.json'; - let filePathRoot = bot.devTeam + "/" + bot.codeName + "." + bot.version.major + "." + bot.version.minor + "/" + global.PLATFORM_CONFIG.codeName + "." + global.PLATFORM_CONFIG.version.major + "." + global.PLATFORM_CONFIG.version.minor + "/" + global.EXCHANGE_NAME + "/" + bot.dataSetVersion; + let filePathRoot = bot.devTeam + "/" + bot.codeName + "." + bot.version.major + "." + bot.version.minor + "/" + global.CLONE_EXECUTOR.codeName + "." + global.CLONE_EXECUTOR.version + "/" + global.EXCHANGE_NAME + "/" + bot.dataSetVersion; let filePath = filePathRoot + "/Output/" + BOLLINGER_BANDS_FOLDER_NAME + "/" + bot.process + "/" + timePeriod + "/" + dateForPath; + filePath += '/' + fileName - chrisStorage.createTextFile(filePath, fileName, fileContent + '\n', onFileCreated); + fileStorage.createTextFile(bot.devTeam, filePath, fileContent + '\n', onFileCreated); function onFileCreated(err) { @@ -658,7 +643,7 @@ pB.end + "," + pB.value + "," + pB.movingAverage + "," + - pB.bandwidth + "]"; + pB.bandwidth + "]"; if (separator === "") { separator = ","; } @@ -671,10 +656,11 @@ let dateForPath = processDate.getUTCFullYear() + '/' + utilities.pad(processDate.getUTCMonth() + 1, 2) + '/' + utilities.pad(processDate.getUTCDate(), 2); let fileName = '' + market.assetA + '_' + market.assetB + '.json'; - let filePathRoot = bot.devTeam + "/" + bot.codeName + "." + bot.version.major + "." + bot.version.minor + "/" + global.PLATFORM_CONFIG.codeName + "." + global.PLATFORM_CONFIG.version.major + "." + global.PLATFORM_CONFIG.version.minor + "/" + global.EXCHANGE_NAME + "/" + bot.dataSetVersion; + let filePathRoot = bot.devTeam + "/" + bot.codeName + "." + bot.version.major + "." + bot.version.minor + "/" + global.CLONE_EXECUTOR.codeName + "." + global.CLONE_EXECUTOR.version + "/" + global.EXCHANGE_NAME + "/" + bot.dataSetVersion; let filePath = filePathRoot + "/Output/" + PERCENTAGE_BANDWIDTH_FOLDER_NAME + "/" + bot.process + "/" + timePeriod + "/" + dateForPath; + filePath += '/' + fileName - chrisStorage.createTextFile(filePath, fileName, fileContent + '\n', onFileCreated); + fileStorage.createTextFile(bot.devTeam, filePath, fileContent + '\n', onFileCreated); function onFileCreated(err) { @@ -827,10 +813,9 @@ let fileName = 'Data.Range.' + market.assetA + '_' + market.assetB + '.json'; let filePath = bot.filePathRoot + "/Output/" + pProductFolder + "/" + bot.process; - if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] start -> writeDataRange -> fileName = " + fileName); } - if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] start -> writeDataRange -> filePath = " + filePath); } + filePath += '/' + fileName - chrisStorage.createTextFile(filePath, fileName, fileContent + '\n', onFileCreated); + fileStorage.createTextFile(bot.devTeam, filePath, fileContent + '\n', onFileCreated); function onFileCreated(err) { diff --git a/Multi-Period-Market/User.Bot.js b/Multi-Period-Market/User.Bot.js index 1ac0d72ec..5221335cd 100644 --- a/Multi-Period-Market/User.Bot.js +++ b/Multi-Period-Market/User.Bot.js @@ -1,4 +1,4 @@ -exports.newUserBot = function newUserBot(bot, logger, COMMONS, UTILITIES, BLOB_STORAGE, FILE_STORAGE) { +exports.newUserBot = function newUserBot(bot, logger, COMMONS, UTILITIES, fileStorage) { const FULL_LOG = true; const LOG_FILE_CONTENT = false; @@ -11,18 +11,11 @@ const BOLLINGER_BANDS_FOLDER_NAME = "Bollinger-Bands"; const PERCENTAGE_BANDWIDTH_FOLDER_NAME = "Percentage-Bandwidth"; - const commons = COMMONS.newCommons(bot, logger, UTILITIES); - thisObject = { initialize: initialize, start: start }; - let oliviaStorage = BLOB_STORAGE.newBlobStorage(bot, logger); - let chrisStorage = BLOB_STORAGE.newBlobStorage(bot, logger); - - let utilities = UTILITIES.newCloudUtilities(bot, logger); - let statusDependencies; return thisObject; @@ -38,20 +31,7 @@ statusDependencies = pStatusDependencies; - commons.initializeStorage(oliviaStorage, chrisStorage, onInizialized); - - function onInizialized(err) { - - if (err.result === global.DEFAULT_OK_RESPONSE.result) { - - if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] initialize -> onInizialized -> Initialization Succeed."); } - callBackFunction(global.DEFAULT_OK_RESPONSE); - - } else { - logger.write(MODULE_NAME, "[ERROR] initialize -> onInizialized -> err = " + err.message); - callBackFunction(err); - } - } + callBackFunction(global.DEFAULT_OK_RESPONSE); } catch (err) { logger.write(MODULE_NAME, "[ERROR] initialize -> err = " + err.message); @@ -60,11 +40,11 @@ } /* - + This process is going to do the following: - + Read the candles from Olivia and produce the bollinger bands out of them. - + */ function start(callBackFunction) { @@ -94,9 +74,9 @@ if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] start -> buildBands -> periodsLoop -> Entering function."); } /* - + We will iterate through all posible periods. - + */ n = 0 // loop Variable representing each possible period as defined at the periods array. @@ -129,10 +109,11 @@ let fileName = market.assetA + '_' + market.assetB + ".json"; - let filePathRoot = bot.devTeam + "/" + "AAOlivia" + "." + bot.version.major + "." + bot.version.minor + "/" + global.PLATFORM_CONFIG.codeName + "." + global.PLATFORM_CONFIG.version.major + "." + global.PLATFORM_CONFIG.version.minor + "/" + global.EXCHANGE_NAME + "/" + bot.dataSetVersion; + let filePathRoot = bot.devTeam + "/" + "AAOlivia" + "." + bot.version.major + "." + bot.version.minor + "/" + global.CLONE_EXECUTOR.codeName + "." + global.CLONE_EXECUTOR.version + "/" + global.EXCHANGE_NAME + "/" + bot.dataSetVersion; let filePath = filePathRoot + "/Output/" + CANDLES_FOLDER_NAME + "/" + "Multi-Period-Market" + "/" + timePeriod; + filePath += '/' + fileName - oliviaStorage.getTextFile(filePath, fileName, onFileReceived, true); + fileStorage.getTextFile(bot.devTeam, filePath, onFileReceived, true); function onFileReceived(err, text) { @@ -215,7 +196,7 @@ let movingAverage = 0; for (let j = i - numberOfPeriodsBB + 1; j < i + 1; j++) { // go through the last numberOfPeriodsBB candles to calculate the moving average. - movingAverage = movingAverage + candles[j].close; + movingAverage = movingAverage + candles[j].close; } movingAverage = movingAverage / numberOfPeriodsBB; @@ -225,8 +206,8 @@ } standardDeviation = standardDeviation / numberOfPeriodsBB; standardDeviation = Math.sqrt(standardDeviation); - if (standardDeviation === 0) { standardDeviation = 0.000000001; } // This is to prevent a division by zero later. - + if (standardDeviation === 0) { standardDeviation = 0.000000001; } // This is to prevent a division by zero later. + band = { begin: candles[i].begin, end: candles[i].end, @@ -248,7 +229,7 @@ let value = (candles[i].close - lowerBB) / (upperBB - lowerBB) * 100; /* Moving Average Calculation */ - + let numberOfPreviousPeriods; let currentPosition = pBArray.length; @@ -318,10 +299,11 @@ let fileName = '' + market.assetA + '_' + market.assetB + '.json'; - let filePathRoot = bot.devTeam + "/" + bot.codeName + "." + bot.version.major + "." + bot.version.minor + "/" + global.PLATFORM_CONFIG.codeName + "." + global.PLATFORM_CONFIG.version.major + "." + global.PLATFORM_CONFIG.version.minor + "/" + global.EXCHANGE_NAME + "/" + bot.dataSetVersion; + let filePathRoot = bot.devTeam + "/" + bot.codeName + "." + bot.version.major + "." + bot.version.minor + "/" + global.CLONE_EXECUTOR.codeName + "." + global.CLONE_EXECUTOR.version + "/" + global.EXCHANGE_NAME + "/" + bot.dataSetVersion; let filePath = filePathRoot + "/Output/" + BOLLINGER_BANDS_FOLDER_NAME + "/" + "Multi-Period-Market" + "/" + timePeriod; + filePath += '/' + fileName - chrisStorage.createTextFile(filePath, fileName, fileContent + '\n', onFileCreated); + fileStorage.createTextFile(bot.devTeam, filePath, fileContent + '\n', onFileCreated); function onFileCreated(err) { @@ -377,7 +359,7 @@ pB.end + "," + pB.value + "," + pB.movingAverage + "," + - pB.bandwidth + "]"; + pB.bandwidth + "]"; if (separator === "") { separator = ","; } @@ -389,10 +371,11 @@ let fileName = '' + market.assetA + '_' + market.assetB + '.json'; - let filePathRoot = bot.devTeam + "/" + bot.codeName + "." + bot.version.major + "." + bot.version.minor + "/" + global.PLATFORM_CONFIG.codeName + "." + global.PLATFORM_CONFIG.version.major + "." + global.PLATFORM_CONFIG.version.minor + "/" + global.EXCHANGE_NAME + "/" + bot.dataSetVersion; + let filePathRoot = bot.devTeam + "/" + bot.codeName + "." + bot.version.major + "." + bot.version.minor + "/" + global.CLONE_EXECUTOR.codeName + "." + global.CLONE_EXECUTOR.version + "/" + global.EXCHANGE_NAME + "/" + bot.dataSetVersion; let filePath = filePathRoot + "/Output/" + PERCENTAGE_BANDWIDTH_FOLDER_NAME + "/" + "Multi-Period-Market" + "/" + timePeriod; + filePath += '/' + fileName - chrisStorage.createTextFile(filePath, fileName, fileContent + '\n', onFileCreated); + fileStorage.createTextFile(bot.devTeam, filePath, fileContent + '\n', onFileCreated); function onFileCreated(err) { From 7f8dc0db38265300464672e7cfce32018be1be49 Mon Sep 17 00:00:00 2001 From: Luis Fernando Molina Date: Tue, 10 Sep 2019 11:26:23 +0200 Subject: [PATCH 13/40] Connected via Events --- this.bot.config.json | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/this.bot.config.json b/this.bot.config.json index a1e6bc2f3..4ca5cb231 100644 --- a/this.bot.config.json +++ b/this.bot.config.json @@ -47,6 +47,17 @@ }, "process": "Multi-Period-Market", "dataSetVersion": "dataSet.V1" + }, + { + "devTeam": "AAMasters", + "bot": "AAOlivia", + "botVersion": { + "major": 1, + "minor": 0 + }, + "process": "Multi-Period-Market", + "dataSetVersion": "dataSet.V1", + "waitUntilNextUpdate": true } ] }, @@ -95,7 +106,8 @@ "minor": 0 }, "process": "Multi-Period-Daily", - "dataSetVersion": "dataSet.V1" + "dataSetVersion": "dataSet.V1", + "waitUntilNextUpdate": true }, { "devTeam": "AAMasters", From 63a92ba90d2f8cafccf3079cfed4c478740cacf0 Mon Sep 17 00:00:00 2001 From: Luis Fernando Molina Date: Wed, 11 Sep 2019 09:35:33 +0200 Subject: [PATCH 14/40] Logging Improved --- Multi-Period-Daily/User.Bot.js | 58 ++++++++++++++++----------------- Multi-Period-Market/User.Bot.js | 36 ++++++++++---------- this.bot.config.json | 6 ++-- 3 files changed, 51 insertions(+), 49 deletions(-) diff --git a/Multi-Period-Daily/User.Bot.js b/Multi-Period-Daily/User.Bot.js index 1d321dc3a..53e58a91e 100644 --- a/Multi-Period-Daily/User.Bot.js +++ b/Multi-Period-Daily/User.Bot.js @@ -40,7 +40,7 @@ callBackFunction(global.DEFAULT_OK_RESPONSE); } catch (err) { - logger.write(MODULE_NAME, "[ERROR] initialize -> err = " + err.message); + logger.write(MODULE_NAME, "[ERROR] initialize -> err = " + err.stack); callBackFunction(global.DEFAULT_FAIL_RESPONSE); } } @@ -213,7 +213,7 @@ } } catch (err) { - logger.write(MODULE_NAME, "[ERROR] start -> getContextVariables -> err = " + err.message); + logger.write(MODULE_NAME, "[ERROR] start -> getContextVariables -> err = " + err.stack); if (err.message === "Cannot read property 'file' of undefined") { logger.write(MODULE_NAME, "[HINT] start -> getContextVariables -> Check the bot configuration to see if all of its statusDependencies declarations are correct. "); logger.write(MODULE_NAME, "[HINT] start -> getContextVariables -> Dependencies loaded -> keys = " + JSON.stringify(statusDependencies.keys)); @@ -263,7 +263,7 @@ periodsLoop(); } catch (err) { - logger.write(MODULE_NAME, "[ERROR] start -> buildBands -> advanceTime -> err = " + err.message); + logger.write(MODULE_NAME, "[ERROR] start -> buildBands -> advanceTime -> err = " + err.stack); callBackFunction(global.DEFAULT_FAIL_RESPONSE); } } @@ -285,7 +285,7 @@ loopBody(); } catch (err) { - logger.write(MODULE_NAME, "[ERROR] start -> buildBands -> periodsLoop -> err = " + err.message); + logger.write(MODULE_NAME, "[ERROR] start -> buildBands -> periodsLoop -> err = " + err.stack); callBackFunction(global.DEFAULT_FAIL_RESPONSE); } } @@ -331,7 +331,7 @@ getProcessDayFile() } catch (err) { - logger.write(MODULE_NAME, "[ERROR] start -> buildBands -> periodsLoop -> loopBody -> getPreviousDayFile -> onCurrentDayFileReceived -> err = " + err.message); + logger.write(MODULE_NAME, "[ERROR] start -> buildBands -> periodsLoop -> loopBody -> getPreviousDayFile -> onCurrentDayFileReceived -> err = " + err.stack); logger.write(MODULE_NAME, "[ERROR] start -> buildBands -> periodsLoop -> loopBody -> getPreviousDayFile -> onCurrentDayFileReceived -> filePath = " + filePath); logger.write(MODULE_NAME, "[ERROR] start -> buildBands -> periodsLoop -> loopBody -> getPreviousDayFile -> onCurrentDayFileReceived -> market = " + market.assetA + '_' + market.assetB); @@ -340,7 +340,7 @@ } } catch (err) { - logger.write(MODULE_NAME, "[ERROR] start -> buildBands -> periodsLoop -> loopBody -> getPreviousDayFile -> err = " + err.message); + logger.write(MODULE_NAME, "[ERROR] start -> buildBands -> periodsLoop -> loopBody -> getPreviousDayFile -> err = " + err.stack); callBackFunction(global.DEFAULT_FAIL_RESPONSE); } } @@ -379,7 +379,7 @@ } else { - logger.write(MODULE_NAME, "[ERROR] start -> buildBands -> periodsLoop -> loopBody -> getProcessDayFile -> onCurrentDayFileReceived -> err = " + err.message); + logger.write(MODULE_NAME, "[ERROR] start -> buildBands -> periodsLoop -> loopBody -> getProcessDayFile -> onCurrentDayFileReceived -> err = " + err.stack); logger.write(MODULE_NAME, "[ERROR] start -> buildBands -> periodsLoop -> loopBody -> getProcessDayFile -> onCurrentDayFileReceived -> filePath = " + filePath); logger.write(MODULE_NAME, "[ERROR] start -> buildBands -> periodsLoop -> loopBody -> getProcessDayFile -> onCurrentDayFileReceived -> market = " + market.assetA + '_' + market.assetB); @@ -390,7 +390,7 @@ } } catch (err) { - logger.write(MODULE_NAME, "[ERROR] start -> buildBands -> periodsLoop -> loopBody -> getProcessDayFile -> err = " + err.message); + logger.write(MODULE_NAME, "[ERROR] start -> buildBands -> periodsLoop -> loopBody -> getProcessDayFile -> err = " + err.stack); callBackFunction(global.DEFAULT_FAIL_RESPONSE); } } @@ -440,14 +440,14 @@ } } catch (err) { - logger.write(MODULE_NAME, "[ERROR] start -> buildBands -> periodsLoop -> loopBody -> buildBands -> addCandlesToSingleArray -> err = " + err.message); + logger.write(MODULE_NAME, "[ERROR] start -> buildBands -> periodsLoop -> loopBody -> buildBands -> addCandlesToSingleArray -> err = " + err.stack); callBackFunction(global.DEFAULT_FAIL_RESPONSE); return; } } } catch (err) { - logger.write(MODULE_NAME, "[ERROR] start -> buildBands -> periodsLoop -> loopBody -> buildBands -> err = " + err.message); + logger.write(MODULE_NAME, "[ERROR] start -> buildBands -> periodsLoop -> loopBody -> buildBands -> err = " + err.stack); callBackFunction(global.DEFAULT_FAIL_RESPONSE); return; } @@ -545,7 +545,7 @@ writeBandsFile(bandsArray, pBArray); } catch (err) { - logger.write(MODULE_NAME, "[ERROR] start -> buildBands -> periodsLoop -> loopBody -> calculateBands -> err = " + err.message); + logger.write(MODULE_NAME, "[ERROR] start -> buildBands -> periodsLoop -> loopBody -> calculateBands -> err = " + err.stack); callBackFunction(global.DEFAULT_FAIL_RESPONSE); return; } @@ -601,7 +601,7 @@ } if (err.result !== global.DEFAULT_OK_RESPONSE.result) { - logger.write(MODULE_NAME, "[ERROR] start -> buildBands -> loopBody -> writeBandBandsFile -> writeBandsFile -> onFileCreated -> err = " + err.message); + logger.write(MODULE_NAME, "[ERROR] start -> buildBands -> loopBody -> writeBandBandsFile -> writeBandsFile -> onFileCreated -> err = " + err.stack); callBackFunction(err); return; } @@ -612,13 +612,13 @@ writePBFile(pPB); } catch (err) { - logger.write(MODULE_NAME, "[ERROR] start -> buildBands -> periodsLoop -> loopBody -> writeBandBandsFile -> writeBandsFile -> onFileCreated -> err = " + err.message); + logger.write(MODULE_NAME, "[ERROR] start -> buildBands -> periodsLoop -> loopBody -> writeBandBandsFile -> writeBandsFile -> onFileCreated -> err = " + err.stack); callBackFunction(global.DEFAULT_RETRY_RESPONSE); } } } catch (err) { - logger.write(MODULE_NAME, "[ERROR] start -> buildBands -> periodsLoop -> loopBody -> writeBandBandsFile -> writeBandsFile -> err = " + err.message); + logger.write(MODULE_NAME, "[ERROR] start -> buildBands -> periodsLoop -> loopBody -> writeBandBandsFile -> writeBandsFile -> err = " + err.stack); callBackFunction(global.DEFAULT_FAIL_RESPONSE); } } @@ -673,7 +673,7 @@ } if (err.result !== global.DEFAULT_OK_RESPONSE.result) { - logger.write(MODULE_NAME, "[ERROR] start -> buildBands -> loopBody -> writeBandBandsFile -> writePBFile -> onFileCreated -> err = " + err.message); + logger.write(MODULE_NAME, "[ERROR] start -> buildBands -> loopBody -> writeBandBandsFile -> writePBFile -> onFileCreated -> err = " + err.stack); callBackFunction(err); return; } @@ -684,20 +684,20 @@ controlLoop(); } catch (err) { - logger.write(MODULE_NAME, "[ERROR] start -> buildBands -> periodsLoop -> loopBody -> writeBandBandsFile -> writePBFile -> onFileCreated -> err = " + err.message); + logger.write(MODULE_NAME, "[ERROR] start -> buildBands -> periodsLoop -> loopBody -> writeBandBandsFile -> writePBFile -> onFileCreated -> err = " + err.stack); callBackFunction(global.DEFAULT_RETRY_RESPONSE); } } } catch (err) { - logger.write(MODULE_NAME, "[ERROR] start -> buildBands -> periodsLoop -> loopBody -> writeBandBandsFile -> writePBFile -> err = " + err.message); + logger.write(MODULE_NAME, "[ERROR] start -> buildBands -> periodsLoop -> loopBody -> writeBandBandsFile -> writePBFile -> err = " + err.stack); callBackFunction(global.DEFAULT_FAIL_RESPONSE); } } } catch (err) { - logger.write(MODULE_NAME, "[ERROR] start -> buildBands -> periodsLoop -> loopBody -> err = " + err.message); + logger.write(MODULE_NAME, "[ERROR] start -> buildBands -> periodsLoop -> loopBody -> err = " + err.stack); callBackFunction(global.DEFAULT_FAIL_RESPONSE); } } @@ -727,7 +727,7 @@ if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] start -> buildBands -> controlLoop -> onWritten -> Entering function."); } if (err.result !== global.DEFAULT_OK_RESPONSE.result) { - logger.write(MODULE_NAME, "[ERROR] start -> buildBands -> controlLoop -> onWritten -> err = " + err.message); + logger.write(MODULE_NAME, "[ERROR] start -> buildBands -> controlLoop -> onWritten -> err = " + err.stack); callBackFunction(err); return; } @@ -735,21 +735,21 @@ writeStatusReport(processDate, advanceTime); } catch (err) { - logger.write(MODULE_NAME, "[ERROR] start -> buildBands -> periodsLoop -> controlLoop -> onWritten -> err = " + err.message); + logger.write(MODULE_NAME, "[ERROR] start -> buildBands -> periodsLoop -> controlLoop -> onWritten -> err = " + err.stack); callBackFunction(global.DEFAULT_FAIL_RESPONSE); } } } } catch (err) { - logger.write(MODULE_NAME, "[ERROR] start -> buildBands -> periodsLoop -> controlLoop -> err = " + err.message); + logger.write(MODULE_NAME, "[ERROR] start -> buildBands -> periodsLoop -> controlLoop -> err = " + err.stack); callBackFunction(global.DEFAULT_FAIL_RESPONSE); } } } catch (err) { - logger.write(MODULE_NAME, "[ERROR] start -> buildBands -> err.message = " + err.message); + logger.write(MODULE_NAME, "[ERROR] start -> buildBands -> err.message = " + err.stack); callBackFunction(global.DEFAULT_FAIL_RESPONSE); } } @@ -767,7 +767,7 @@ if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] start -> writeDataRanges -> Entering function."); } if (err.result !== global.DEFAULT_OK_RESPONSE.result) { - logger.write(MODULE_NAME, "[ERROR] writeDataRanges -> writeDataRanges -> onBandsBandsDataRangeWritten -> err = " + err.message); + logger.write(MODULE_NAME, "[ERROR] writeDataRanges -> writeDataRanges -> onBandsBandsDataRangeWritten -> err = " + err.stack); callBack(err); return; } @@ -779,7 +779,7 @@ if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] start -> writeDataRanges -> Entering function."); } if (err.result !== global.DEFAULT_OK_RESPONSE.result) { - logger.write(MODULE_NAME, "[ERROR] writeDataRanges -> writeDataRanges -> onBandsBandsDataRangeWritten -> onPercentageBandwidthDataRangeWritten -> err = " + err.message); + logger.write(MODULE_NAME, "[ERROR] writeDataRanges -> writeDataRanges -> onBandsBandsDataRangeWritten -> onPercentageBandwidthDataRangeWritten -> err = " + err.stack); callBack(err); return; } @@ -791,7 +791,7 @@ } } catch (err) { - logger.write(MODULE_NAME, "[ERROR] start -> writeDataRanges -> err = " + err.message); + logger.write(MODULE_NAME, "[ERROR] start -> writeDataRanges -> err = " + err.stack); callBack(global.DEFAULT_FAIL_RESPONSE); } @@ -822,7 +822,7 @@ if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] start -> writeDataRange -> onFileCreated -> Entering function."); } if (err.result !== global.DEFAULT_OK_RESPONSE.result) { - logger.write(MODULE_NAME, "[ERROR] start -> writeDataRange -> onFileCreated -> err = " + err.message); + logger.write(MODULE_NAME, "[ERROR] start -> writeDataRange -> onFileCreated -> err = " + err.stack); callBack(err); return; } @@ -835,7 +835,7 @@ } } catch (err) { - logger.write(MODULE_NAME, "[ERROR] start -> writeDataRange -> err = " + err.message); + logger.write(MODULE_NAME, "[ERROR] start -> writeDataRange -> err = " + err.stack); callBack(global.DEFAULT_FAIL_RESPONSE); } } @@ -856,13 +856,13 @@ } catch (err) { - logger.write(MODULE_NAME, "[ERROR] start -> writeStatusReport -> err = " + err.message); + logger.write(MODULE_NAME, "[ERROR] start -> writeStatusReport -> err = " + err.stack); callBackFunction(global.DEFAULT_FAIL_RESPONSE); } } } catch (err) { - logger.write(MODULE_NAME, "[ERROR] start -> err.message = " + err.message); + logger.write(MODULE_NAME, "[ERROR] start -> err.message = " + err.stack); callBackFunction(global.DEFAULT_FAIL_RESPONSE); } } diff --git a/Multi-Period-Market/User.Bot.js b/Multi-Period-Market/User.Bot.js index 5221335cd..8ac5ff9ae 100644 --- a/Multi-Period-Market/User.Bot.js +++ b/Multi-Period-Market/User.Bot.js @@ -34,7 +34,7 @@ callBackFunction(global.DEFAULT_OK_RESPONSE); } catch (err) { - logger.write(MODULE_NAME, "[ERROR] initialize -> err = " + err.message); + logger.write(MODULE_NAME, "[ERROR] initialize -> err = " + err.stack); callBackFunction(global.DEFAULT_FAIL_RESPONSE); } } @@ -85,7 +85,7 @@ } catch (err) { - logger.write(MODULE_NAME, "[ERROR] start -> buildBands -> periodsLoop -> err = " + err.message); + logger.write(MODULE_NAME, "[ERROR] start -> buildBands -> periodsLoop -> err = " + err.stack); callBackFunction(global.DEFAULT_FAIL_RESPONSE); } } @@ -124,7 +124,7 @@ if (err.result !== global.DEFAULT_OK_RESPONSE.result) { - logger.write(MODULE_NAME, "[ERROR] start -> buildBands -> loopBody -> nextCandleFile -> onFileReceived -> err = " + err.message); + logger.write(MODULE_NAME, "[ERROR] start -> buildBands -> loopBody -> nextCandleFile -> onFileReceived -> err = " + err.stack); callBackFunction(err); return; @@ -171,7 +171,7 @@ } catch (err) { - logger.write(MODULE_NAME, "[ERROR] start -> buildBands -> loopBody -> nextCandleFile -> onFileReceived -> buildCandles -> err = " + err.message); + logger.write(MODULE_NAME, "[ERROR] start -> buildBands -> loopBody -> nextCandleFile -> onFileReceived -> buildCandles -> err = " + err.stack); callBackFunction(global.DEFAULT_FAIL_RESPONSE); } } @@ -262,7 +262,7 @@ writeBandsFile(bandsArray, pBArray); } catch (err) { - logger.write(MODULE_NAME, "[ERROR] start -> buildBands -> loopBody -> nextCandleFile -> onFileReceived -> buildBands -> err = " + err.message); + logger.write(MODULE_NAME, "[ERROR] start -> buildBands -> loopBody -> nextCandleFile -> onFileReceived -> buildBands -> err = " + err.stack); callBackFunction(global.DEFAULT_FAIL_RESPONSE); } } @@ -314,7 +314,7 @@ if (err.result !== global.DEFAULT_OK_RESPONSE.result) { - logger.write(MODULE_NAME, "[ERROR] start -> buildBands -> loopBody -> nextCandleFile -> onFileReceived -> writeBandsFile -> onFileCreated -> err = " + err.message); + logger.write(MODULE_NAME, "[ERROR] start -> buildBands -> loopBody -> nextCandleFile -> onFileReceived -> writeBandsFile -> onFileCreated -> err = " + err.stack); logger.write(MODULE_NAME, "[ERROR] start -> buildBands -> loopBody -> nextCandleFile -> onFileReceived -> writeBandsFile -> onFileCreated -> filePath = " + filePath); logger.write(MODULE_NAME, "[ERROR] start -> buildBands -> loopBody -> nextCandleFile -> onFileReceived -> writeBandsFile -> onFileCreated -> market = " + market.assetA + "_" + market.assetB); @@ -327,13 +327,13 @@ } catch (err) { - logger.write(MODULE_NAME, "[ERROR] start -> buildBands -> loopBody -> nextCandleFile -> onFileReceived -> writeBandsFile -> onFileCreated -> err = " + err.message); + logger.write(MODULE_NAME, "[ERROR] start -> buildBands -> loopBody -> nextCandleFile -> onFileReceived -> writeBandsFile -> onFileCreated -> err = " + err.stack); callBackFunction(global.DEFAULT_FAIL_RESPONSE); } } } catch (err) { - logger.write(MODULE_NAME, "[ERROR] start -> buildBands -> loopBody -> nextCandleFile -> onFileReceived -> writeBandsFile -> err = " + err.message); + logger.write(MODULE_NAME, "[ERROR] start -> buildBands -> loopBody -> nextCandleFile -> onFileReceived -> writeBandsFile -> err = " + err.stack); callBackFunction(global.DEFAULT_FAIL_RESPONSE); } } @@ -386,7 +386,7 @@ if (err.result !== global.DEFAULT_OK_RESPONSE.result) { - logger.write(MODULE_NAME, "[ERROR] start -> buildBands -> loopBody -> nextCandleFile -> onFileReceived -> writePBFile -> onFileCreated -> err = " + err.message); + logger.write(MODULE_NAME, "[ERROR] start -> buildBands -> loopBody -> nextCandleFile -> onFileReceived -> writePBFile -> onFileCreated -> err = " + err.stack); logger.write(MODULE_NAME, "[ERROR] start -> buildBands -> loopBody -> nextCandleFile -> onFileReceived -> writePBFile -> onFileCreated -> filePath = " + filePath); logger.write(MODULE_NAME, "[ERROR] start -> buildBands -> loopBody -> nextCandleFile -> onFileReceived -> writePBFile -> onFileCreated -> market = " + market.assetA + "_" + market.assetB); @@ -399,33 +399,33 @@ } catch (err) { - logger.write(MODULE_NAME, "[ERROR] start -> buildBands -> loopBody -> nextCandleFile -> onFileReceived -> writePBFile -> onFileCreated -> err = " + err.message); + logger.write(MODULE_NAME, "[ERROR] start -> buildBands -> loopBody -> nextCandleFile -> onFileReceived -> writePBFile -> onFileCreated -> err = " + err.stack); callBackFunction(global.DEFAULT_FAIL_RESPONSE); } } } catch (err) { - logger.write(MODULE_NAME, "[ERROR] start -> buildBands -> loopBody -> nextCandleFile -> onFileReceived -> writePBFile -> err = " + err.message); + logger.write(MODULE_NAME, "[ERROR] start -> buildBands -> loopBody -> nextCandleFile -> onFileReceived -> writePBFile -> err = " + err.stack); callBackFunction(global.DEFAULT_FAIL_RESPONSE); } } } catch (err) { - logger.write(MODULE_NAME, "[ERROR] start -> buildBands -> loopBody -> nextCandleFile -> onFileReceived -> err = " + err.message); + logger.write(MODULE_NAME, "[ERROR] start -> buildBands -> loopBody -> nextCandleFile -> onFileReceived -> err = " + err.stack); callBackFunction(global.DEFAULT_FAIL_RESPONSE); } } } catch (err) { - logger.write(MODULE_NAME, "[ERROR] start -> buildBands -> loopBody -> nextCandleFile -> err = " + err.message); + logger.write(MODULE_NAME, "[ERROR] start -> buildBands -> loopBody -> nextCandleFile -> err = " + err.stack); callBackFunction(global.DEFAULT_FAIL_RESPONSE); } } } catch (err) { - logger.write(MODULE_NAME, "[ERROR] start -> buildBands -> loopBody -> err = " + err.message); + logger.write(MODULE_NAME, "[ERROR] start -> buildBands -> loopBody -> err = " + err.stack); callBackFunction(global.DEFAULT_FAIL_RESPONSE); } } @@ -449,14 +449,14 @@ } } catch (err) { - logger.write(MODULE_NAME, "[ERROR] start -> buildBands -> controlLoop -> err = " + err.message); + logger.write(MODULE_NAME, "[ERROR] start -> buildBands -> controlLoop -> err = " + err.stack); callBackFunction(global.DEFAULT_FAIL_RESPONSE); } } } catch (err) { - logger.write(MODULE_NAME, "[ERROR] start -> buildBands -> err = " + err.message); + logger.write(MODULE_NAME, "[ERROR] start -> buildBands -> err = " + err.stack); callBackFunction(global.DEFAULT_FAIL_RESPONSE); } } @@ -475,13 +475,13 @@ } catch (err) { - logger.write(MODULE_NAME, "[ERROR] start -> writeStatusReport -> err = " + err.message); + logger.write(MODULE_NAME, "[ERROR] start -> writeStatusReport -> err = " + err.stack); callBackFunction(global.DEFAULT_FAIL_RESPONSE); } } } catch (err) { - logger.write(MODULE_NAME, "[ERROR] start -> err = " + err.message); + logger.write(MODULE_NAME, "[ERROR] start -> err = " + err.stack); callBackFunction(global.DEFAULT_FAIL_RESPONSE); } } diff --git a/this.bot.config.json b/this.bot.config.json index 4ca5cb231..9b9fde17a 100644 --- a/this.bot.config.json +++ b/this.bot.config.json @@ -33,7 +33,8 @@ "interval": 0 } }, - "normalWaitTime": 60000, + "deadWaitTime": 90000, + "normalWaitTime": 0, "retryWaitTime": 10000, "sleepWaitTime": 3600000, "comaWaitTime": 86400000, @@ -83,7 +84,8 @@ "interval": 0 } }, - "normalWaitTime": 60000, + "deadWaitTime": 90000, + "normalWaitTime": 0, "retryWaitTime": 10000, "sleepWaitTime": 3600000, "comaWaitTime": 86400000, From 7dc63e0e3d9f9263b1a1d53381261f45d3e25f47 Mon Sep 17 00:00:00 2001 From: Luis Fernando Molina Date: Sun, 22 Sep 2019 18:12:49 +0200 Subject: [PATCH 15/40] Config to raise events when updating Datasets --- this.bot.config.json | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/this.bot.config.json b/this.bot.config.json index 9b9fde17a..948d47e83 100644 --- a/this.bot.config.json +++ b/this.bot.config.json @@ -38,6 +38,16 @@ "retryWaitTime": 10000, "sleepWaitTime": 3600000, "comaWaitTime": 86400000, + "updatesDatasets": [ + { + "product": "Bollinger-Bands", + "dataSet": "Multi-Period-Market" + }, + { + "product": "Percentage-Bandwidth", + "dataSet": "Multi-Period-Market" + } + ], "statusDependencies": [ { "devTeam": "AAMasters", @@ -89,6 +99,16 @@ "retryWaitTime": 10000, "sleepWaitTime": 3600000, "comaWaitTime": 86400000, + "updatesDatasets": [ + { + "product": "Bollinger-Bands", + "dataSet": "Multi-Period-Daily" + }, + { + "product": "Percentage-Bandwidth", + "dataSet": "Multi-Period-Daily" + } + ], "statusDependencies": [ { "devTeam": "AAMasters", From 014d1a0b3a7e28332fc8fd5662beb09443a05145 Mon Sep 17 00:00:00 2001 From: Luis Fernando Molina Date: Mon, 23 Sep 2019 17:22:13 +0200 Subject: [PATCH 16/40] No process helth check for now --- this.bot.config.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/this.bot.config.json b/this.bot.config.json index 948d47e83..649446319 100644 --- a/this.bot.config.json +++ b/this.bot.config.json @@ -33,7 +33,7 @@ "interval": 0 } }, - "deadWaitTime": 90000, + "deadWaitTime": 0, "normalWaitTime": 0, "retryWaitTime": 10000, "sleepWaitTime": 3600000, @@ -94,7 +94,7 @@ "interval": 0 } }, - "deadWaitTime": 90000, + "deadWaitTime": 0, "normalWaitTime": 0, "retryWaitTime": 10000, "sleepWaitTime": 3600000, From ab1780915985b44104dc50655bf91c5920e184e3 Mon Sep 17 00:00:00 2001 From: Luis Fernando Molina Date: Tue, 1 Oct 2019 22:01:16 +0200 Subject: [PATCH 17/40] adjusting if forces retry while reading files or not --- Multi-Period-Daily/User.Bot.js | 4 ++-- Multi-Period-Market/User.Bot.js | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Multi-Period-Daily/User.Bot.js b/Multi-Period-Daily/User.Bot.js index 53e58a91e..d48e58b53 100644 --- a/Multi-Period-Daily/User.Bot.js +++ b/Multi-Period-Daily/User.Bot.js @@ -318,7 +318,7 @@ let filePath = filePathRoot + "/Output/" + CANDLES_FOLDER_NAME + '/' + "Multi-Period-Daily" + "/" + timePeriod + "/" + dateForPath; filePath += '/' + fileName - fileStorage.getTextFile(bot.devTeam, filePath, onCurrentDayFileReceived, true); + fileStorage.getTextFile(bot.devTeam, filePath, onCurrentDayFileReceived); function onCurrentDayFileReceived(err, text) { @@ -358,7 +358,7 @@ let filePath = filePathRoot + "/Output/" + CANDLES_FOLDER_NAME + '/' + "Multi-Period-Daily" + "/" + timePeriod + "/" + dateForPath; filePath += '/' + fileName - fileStorage.getTextFile(bot.devTeam, filePath, onCurrentDayFileReceived, true); + fileStorage.getTextFile(bot.devTeam, filePath, onCurrentDayFileReceived); function onCurrentDayFileReceived(err, text) { diff --git a/Multi-Period-Market/User.Bot.js b/Multi-Period-Market/User.Bot.js index 8ac5ff9ae..e13a6976a 100644 --- a/Multi-Period-Market/User.Bot.js +++ b/Multi-Period-Market/User.Bot.js @@ -113,7 +113,7 @@ let filePath = filePathRoot + "/Output/" + CANDLES_FOLDER_NAME + "/" + "Multi-Period-Market" + "/" + timePeriod; filePath += '/' + fileName - fileStorage.getTextFile(bot.devTeam, filePath, onFileReceived, true); + fileStorage.getTextFile(bot.devTeam, filePath, onFileReceived); function onFileReceived(err, text) { From 964cfd43b3c475abd1a03b21ff1b47ed5d16e81d Mon Sep 17 00:00:00 2001 From: Luis Fernando Molina Date: Sun, 27 Oct 2019 11:32:47 +0100 Subject: [PATCH 18/40] Refactoring --- this.bot.config.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/this.bot.config.json b/this.bot.config.json index 649446319..fdfb04681 100644 --- a/this.bot.config.json +++ b/this.bot.config.json @@ -1,7 +1,7 @@ { "displayName": "Chris", "codeName": "AAChris", - "type": "Indicator", + "type": "Indicator Bot", "version": { "major": 1, "minor": 0, From bc3fd52b259be3d697b87b9ea4bc70a2f65d09e3 Mon Sep 17 00:00:00 2001 From: Luis Fernando Molina Date: Thu, 26 Dec 2019 10:46:23 +0100 Subject: [PATCH 19/40] Data Mine Refactoring --- Multi-Period-Daily/User.Bot.js | 18 +++++++++--------- Multi-Period-Market/User.Bot.js | 12 ++++++------ this.bot.config.json | 16 ++++++++-------- 3 files changed, 23 insertions(+), 23 deletions(-) diff --git a/Multi-Period-Daily/User.Bot.js b/Multi-Period-Daily/User.Bot.js index d48e58b53..7228c4a13 100644 --- a/Multi-Period-Daily/User.Bot.js +++ b/Multi-Period-Daily/User.Bot.js @@ -314,11 +314,11 @@ let dateForPath = previousDay.getUTCFullYear() + '/' + utilities.pad(previousDay.getUTCMonth() + 1, 2) + '/' + utilities.pad(previousDay.getUTCDate(), 2); let fileName = market.assetA + '_' + market.assetB + ".json" - let filePathRoot = bot.devTeam + "/" + "AAOlivia" + "." + bot.version.major + "." + bot.version.minor + "/" + global.CLONE_EXECUTOR.codeName + "." + global.CLONE_EXECUTOR.version + "/" + global.EXCHANGE_NAME + "/" + bot.dataSetVersion; + let filePathRoot = bot.dataMine + "/" + "AAOlivia" + "." + bot.version.major + "." + bot.version.minor + "/" + global.CLONE_EXECUTOR.codeName + "." + global.CLONE_EXECUTOR.version + "/" + global.EXCHANGE_NAME + "/" + bot.dataSetVersion; let filePath = filePathRoot + "/Output/" + CANDLES_FOLDER_NAME + '/' + "Multi-Period-Daily" + "/" + timePeriod + "/" + dateForPath; filePath += '/' + fileName - fileStorage.getTextFile(bot.devTeam, filePath, onCurrentDayFileReceived); + fileStorage.getTextFile(bot.dataMine, filePath, onCurrentDayFileReceived); function onCurrentDayFileReceived(err, text) { @@ -354,11 +354,11 @@ let dateForPath = processDate.getUTCFullYear() + '/' + utilities.pad(processDate.getUTCMonth() + 1, 2) + '/' + utilities.pad(processDate.getUTCDate(), 2); let fileName = market.assetA + '_' + market.assetB + ".json" - let filePathRoot = bot.devTeam + "/" + "AAOlivia" + "." + bot.version.major + "." + bot.version.minor + "/" + global.CLONE_EXECUTOR.codeName + "." + global.CLONE_EXECUTOR.version + "/" + global.EXCHANGE_NAME + "/" + bot.dataSetVersion; + let filePathRoot = bot.dataMine + "/" + "AAOlivia" + "." + bot.version.major + "." + bot.version.minor + "/" + global.CLONE_EXECUTOR.codeName + "." + global.CLONE_EXECUTOR.version + "/" + global.EXCHANGE_NAME + "/" + bot.dataSetVersion; let filePath = filePathRoot + "/Output/" + CANDLES_FOLDER_NAME + '/' + "Multi-Period-Daily" + "/" + timePeriod + "/" + dateForPath; filePath += '/' + fileName - fileStorage.getTextFile(bot.devTeam, filePath, onCurrentDayFileReceived); + fileStorage.getTextFile(bot.dataMine, filePath, onCurrentDayFileReceived); function onCurrentDayFileReceived(err, text) { @@ -584,11 +584,11 @@ let dateForPath = processDate.getUTCFullYear() + '/' + utilities.pad(processDate.getUTCMonth() + 1, 2) + '/' + utilities.pad(processDate.getUTCDate(), 2); let fileName = '' + market.assetA + '_' + market.assetB + '.json'; - let filePathRoot = bot.devTeam + "/" + bot.codeName + "." + bot.version.major + "." + bot.version.minor + "/" + global.CLONE_EXECUTOR.codeName + "." + global.CLONE_EXECUTOR.version + "/" + global.EXCHANGE_NAME + "/" + bot.dataSetVersion; + let filePathRoot = bot.dataMine + "/" + bot.codeName + "." + bot.version.major + "." + bot.version.minor + "/" + global.CLONE_EXECUTOR.codeName + "." + global.CLONE_EXECUTOR.version + "/" + global.EXCHANGE_NAME + "/" + bot.dataSetVersion; let filePath = filePathRoot + "/Output/" + BOLLINGER_BANDS_FOLDER_NAME + "/" + bot.process + "/" + timePeriod + "/" + dateForPath; filePath += '/' + fileName - fileStorage.createTextFile(bot.devTeam, filePath, fileContent + '\n', onFileCreated); + fileStorage.createTextFile(bot.dataMine, filePath, fileContent + '\n', onFileCreated); function onFileCreated(err) { @@ -656,11 +656,11 @@ let dateForPath = processDate.getUTCFullYear() + '/' + utilities.pad(processDate.getUTCMonth() + 1, 2) + '/' + utilities.pad(processDate.getUTCDate(), 2); let fileName = '' + market.assetA + '_' + market.assetB + '.json'; - let filePathRoot = bot.devTeam + "/" + bot.codeName + "." + bot.version.major + "." + bot.version.minor + "/" + global.CLONE_EXECUTOR.codeName + "." + global.CLONE_EXECUTOR.version + "/" + global.EXCHANGE_NAME + "/" + bot.dataSetVersion; + let filePathRoot = bot.dataMine + "/" + bot.codeName + "." + bot.version.major + "." + bot.version.minor + "/" + global.CLONE_EXECUTOR.codeName + "." + global.CLONE_EXECUTOR.version + "/" + global.EXCHANGE_NAME + "/" + bot.dataSetVersion; let filePath = filePathRoot + "/Output/" + PERCENTAGE_BANDWIDTH_FOLDER_NAME + "/" + bot.process + "/" + timePeriod + "/" + dateForPath; filePath += '/' + fileName - fileStorage.createTextFile(bot.devTeam, filePath, fileContent + '\n', onFileCreated); + fileStorage.createTextFile(bot.dataMine, filePath, fileContent + '\n', onFileCreated); function onFileCreated(err) { @@ -815,7 +815,7 @@ filePath += '/' + fileName - fileStorage.createTextFile(bot.devTeam, filePath, fileContent + '\n', onFileCreated); + fileStorage.createTextFile(bot.dataMine, filePath, fileContent + '\n', onFileCreated); function onFileCreated(err) { diff --git a/Multi-Period-Market/User.Bot.js b/Multi-Period-Market/User.Bot.js index e13a6976a..bd9a0612f 100644 --- a/Multi-Period-Market/User.Bot.js +++ b/Multi-Period-Market/User.Bot.js @@ -109,11 +109,11 @@ let fileName = market.assetA + '_' + market.assetB + ".json"; - let filePathRoot = bot.devTeam + "/" + "AAOlivia" + "." + bot.version.major + "." + bot.version.minor + "/" + global.CLONE_EXECUTOR.codeName + "." + global.CLONE_EXECUTOR.version + "/" + global.EXCHANGE_NAME + "/" + bot.dataSetVersion; + let filePathRoot = bot.dataMine + "/" + "AAOlivia" + "." + bot.version.major + "." + bot.version.minor + "/" + global.CLONE_EXECUTOR.codeName + "." + global.CLONE_EXECUTOR.version + "/" + global.EXCHANGE_NAME + "/" + bot.dataSetVersion; let filePath = filePathRoot + "/Output/" + CANDLES_FOLDER_NAME + "/" + "Multi-Period-Market" + "/" + timePeriod; filePath += '/' + fileName - fileStorage.getTextFile(bot.devTeam, filePath, onFileReceived); + fileStorage.getTextFile(bot.dataMine, filePath, onFileReceived); function onFileReceived(err, text) { @@ -299,11 +299,11 @@ let fileName = '' + market.assetA + '_' + market.assetB + '.json'; - let filePathRoot = bot.devTeam + "/" + bot.codeName + "." + bot.version.major + "." + bot.version.minor + "/" + global.CLONE_EXECUTOR.codeName + "." + global.CLONE_EXECUTOR.version + "/" + global.EXCHANGE_NAME + "/" + bot.dataSetVersion; + let filePathRoot = bot.dataMine + "/" + bot.codeName + "." + bot.version.major + "." + bot.version.minor + "/" + global.CLONE_EXECUTOR.codeName + "." + global.CLONE_EXECUTOR.version + "/" + global.EXCHANGE_NAME + "/" + bot.dataSetVersion; let filePath = filePathRoot + "/Output/" + BOLLINGER_BANDS_FOLDER_NAME + "/" + "Multi-Period-Market" + "/" + timePeriod; filePath += '/' + fileName - fileStorage.createTextFile(bot.devTeam, filePath, fileContent + '\n', onFileCreated); + fileStorage.createTextFile(bot.dataMine, filePath, fileContent + '\n', onFileCreated); function onFileCreated(err) { @@ -371,11 +371,11 @@ let fileName = '' + market.assetA + '_' + market.assetB + '.json'; - let filePathRoot = bot.devTeam + "/" + bot.codeName + "." + bot.version.major + "." + bot.version.minor + "/" + global.CLONE_EXECUTOR.codeName + "." + global.CLONE_EXECUTOR.version + "/" + global.EXCHANGE_NAME + "/" + bot.dataSetVersion; + let filePathRoot = bot.dataMine + "/" + bot.codeName + "." + bot.version.major + "." + bot.version.minor + "/" + global.CLONE_EXECUTOR.codeName + "." + global.CLONE_EXECUTOR.version + "/" + global.EXCHANGE_NAME + "/" + bot.dataSetVersion; let filePath = filePathRoot + "/Output/" + PERCENTAGE_BANDWIDTH_FOLDER_NAME + "/" + "Multi-Period-Market" + "/" + timePeriod; filePath += '/' + fileName - fileStorage.createTextFile(bot.devTeam, filePath, fileContent + '\n', onFileCreated); + fileStorage.createTextFile(bot.dataMine, filePath, fileContent + '\n', onFileCreated); function onFileCreated(err) { diff --git a/this.bot.config.json b/this.bot.config.json index fdfb04681..0a61ab01a 100644 --- a/this.bot.config.json +++ b/this.bot.config.json @@ -7,7 +7,7 @@ "minor": 0, "patch": 0 }, - "devTeam": "AAMasters", + "dataMine": "AAMasters", "profilePicture": "Chris.png", "dataSetVersion": "dataSet.V1", "processes": [ @@ -50,7 +50,7 @@ ], "statusDependencies": [ { - "devTeam": "AAMasters", + "dataMine": "AAMasters", "bot": "AAChris", "botVersion": { "major": 1, @@ -60,7 +60,7 @@ "dataSetVersion": "dataSet.V1" }, { - "devTeam": "AAMasters", + "dataMine": "AAMasters", "bot": "AAOlivia", "botVersion": { "major": 1, @@ -111,7 +111,7 @@ ], "statusDependencies": [ { - "devTeam": "AAMasters", + "dataMine": "AAMasters", "bot": "AACharly", "botVersion": { "major": 1, @@ -121,7 +121,7 @@ "dataSetVersion": "dataSet.V1" }, { - "devTeam": "AAMasters", + "dataMine": "AAMasters", "bot": "AAOlivia", "botVersion": { "major": 1, @@ -132,7 +132,7 @@ "waitUntilNextUpdate": true }, { - "devTeam": "AAMasters", + "dataMine": "AAMasters", "bot": "AAChris", "botVersion": { "major": 1, @@ -180,7 +180,7 @@ } ], "plotter": { - "devTeam": "AAMasters", + "dataMine": "AAMasters", "codeName": "PlottersBollingerBands", "moduleName": "BollingerBands" } @@ -220,7 +220,7 @@ } ], "plotter": { - "devTeam": "AAMasters", + "dataMine": "AAMasters", "codeName": "PlottersBollingerBands", "moduleName": "PercentageBandwidth" } From 7af1169182f3ff8d990ad21d1697409caab64af8 Mon Sep 17 00:00:00 2001 From: Luis Fernando Molina Date: Fri, 27 Dec 2019 13:26:54 +0100 Subject: [PATCH 20/40] Time Frame Refectoring --- Multi-Period-Daily/User.Bot.js | 12 ++++++------ Multi-Period-Market/User.Bot.js | 8 ++++---- this.bot.config.json | 4 ++-- 3 files changed, 12 insertions(+), 12 deletions(-) diff --git a/Multi-Period-Daily/User.Bot.js b/Multi-Period-Daily/User.Bot.js index 7228c4a13..256cd3aba 100644 --- a/Multi-Period-Daily/User.Bot.js +++ b/Multi-Period-Daily/User.Bot.js @@ -276,7 +276,7 @@ /* - We will iterate through all posible timePeriods. + We will iterate through all posible timeFrames. */ @@ -296,7 +296,7 @@ if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] start -> buildBands -> loopBody -> Entering function."); } - const timePeriod = global.dailyFilePeriods[n][1]; + const timeFrame = global.dailyFilePeriods[n][1]; let candles = []; // Here we will put all the candles of the 2 files read. @@ -315,7 +315,7 @@ let fileName = market.assetA + '_' + market.assetB + ".json" let filePathRoot = bot.dataMine + "/" + "AAOlivia" + "." + bot.version.major + "." + bot.version.minor + "/" + global.CLONE_EXECUTOR.codeName + "." + global.CLONE_EXECUTOR.version + "/" + global.EXCHANGE_NAME + "/" + bot.dataSetVersion; - let filePath = filePathRoot + "/Output/" + CANDLES_FOLDER_NAME + '/' + "Multi-Period-Daily" + "/" + timePeriod + "/" + dateForPath; + let filePath = filePathRoot + "/Output/" + CANDLES_FOLDER_NAME + '/' + "Multi-Period-Daily" + "/" + timeFrame + "/" + dateForPath; filePath += '/' + fileName fileStorage.getTextFile(bot.dataMine, filePath, onCurrentDayFileReceived); @@ -355,7 +355,7 @@ let fileName = market.assetA + '_' + market.assetB + ".json" let filePathRoot = bot.dataMine + "/" + "AAOlivia" + "." + bot.version.major + "." + bot.version.minor + "/" + global.CLONE_EXECUTOR.codeName + "." + global.CLONE_EXECUTOR.version + "/" + global.EXCHANGE_NAME + "/" + bot.dataSetVersion; - let filePath = filePathRoot + "/Output/" + CANDLES_FOLDER_NAME + '/' + "Multi-Period-Daily" + "/" + timePeriod + "/" + dateForPath; + let filePath = filePathRoot + "/Output/" + CANDLES_FOLDER_NAME + '/' + "Multi-Period-Daily" + "/" + timeFrame + "/" + dateForPath; filePath += '/' + fileName fileStorage.getTextFile(bot.dataMine, filePath, onCurrentDayFileReceived); @@ -585,7 +585,7 @@ let fileName = '' + market.assetA + '_' + market.assetB + '.json'; let filePathRoot = bot.dataMine + "/" + bot.codeName + "." + bot.version.major + "." + bot.version.minor + "/" + global.CLONE_EXECUTOR.codeName + "." + global.CLONE_EXECUTOR.version + "/" + global.EXCHANGE_NAME + "/" + bot.dataSetVersion; - let filePath = filePathRoot + "/Output/" + BOLLINGER_BANDS_FOLDER_NAME + "/" + bot.process + "/" + timePeriod + "/" + dateForPath; + let filePath = filePathRoot + "/Output/" + BOLLINGER_BANDS_FOLDER_NAME + "/" + bot.process + "/" + timeFrame + "/" + dateForPath; filePath += '/' + fileName fileStorage.createTextFile(bot.dataMine, filePath, fileContent + '\n', onFileCreated); @@ -657,7 +657,7 @@ let fileName = '' + market.assetA + '_' + market.assetB + '.json'; let filePathRoot = bot.dataMine + "/" + bot.codeName + "." + bot.version.major + "." + bot.version.minor + "/" + global.CLONE_EXECUTOR.codeName + "." + global.CLONE_EXECUTOR.version + "/" + global.EXCHANGE_NAME + "/" + bot.dataSetVersion; - let filePath = filePathRoot + "/Output/" + PERCENTAGE_BANDWIDTH_FOLDER_NAME + "/" + bot.process + "/" + timePeriod + "/" + dateForPath; + let filePath = filePathRoot + "/Output/" + PERCENTAGE_BANDWIDTH_FOLDER_NAME + "/" + bot.process + "/" + timeFrame + "/" + dateForPath; filePath += '/' + fileName fileStorage.createTextFile(bot.dataMine, filePath, fileContent + '\n', onFileCreated); diff --git a/Multi-Period-Market/User.Bot.js b/Multi-Period-Market/User.Bot.js index bd9a0612f..23fab93d7 100644 --- a/Multi-Period-Market/User.Bot.js +++ b/Multi-Period-Market/User.Bot.js @@ -97,7 +97,7 @@ if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] start -> buildBands -> loopBody -> Entering function."); } const outputPeriod = global.marketFilesPeriods[n][0]; - const timePeriod = global.marketFilesPeriods[n][1]; + const timeFrame = global.marketFilesPeriods[n][1]; nextCandleFile(); @@ -110,7 +110,7 @@ let fileName = market.assetA + '_' + market.assetB + ".json"; let filePathRoot = bot.dataMine + "/" + "AAOlivia" + "." + bot.version.major + "." + bot.version.minor + "/" + global.CLONE_EXECUTOR.codeName + "." + global.CLONE_EXECUTOR.version + "/" + global.EXCHANGE_NAME + "/" + bot.dataSetVersion; - let filePath = filePathRoot + "/Output/" + CANDLES_FOLDER_NAME + "/" + "Multi-Period-Market" + "/" + timePeriod; + let filePath = filePathRoot + "/Output/" + CANDLES_FOLDER_NAME + "/" + "Multi-Period-Market" + "/" + timeFrame; filePath += '/' + fileName fileStorage.getTextFile(bot.dataMine, filePath, onFileReceived); @@ -300,7 +300,7 @@ let fileName = '' + market.assetA + '_' + market.assetB + '.json'; let filePathRoot = bot.dataMine + "/" + bot.codeName + "." + bot.version.major + "." + bot.version.minor + "/" + global.CLONE_EXECUTOR.codeName + "." + global.CLONE_EXECUTOR.version + "/" + global.EXCHANGE_NAME + "/" + bot.dataSetVersion; - let filePath = filePathRoot + "/Output/" + BOLLINGER_BANDS_FOLDER_NAME + "/" + "Multi-Period-Market" + "/" + timePeriod; + let filePath = filePathRoot + "/Output/" + BOLLINGER_BANDS_FOLDER_NAME + "/" + "Multi-Period-Market" + "/" + timeFrame; filePath += '/' + fileName fileStorage.createTextFile(bot.dataMine, filePath, fileContent + '\n', onFileCreated); @@ -372,7 +372,7 @@ let fileName = '' + market.assetA + '_' + market.assetB + '.json'; let filePathRoot = bot.dataMine + "/" + bot.codeName + "." + bot.version.major + "." + bot.version.minor + "/" + global.CLONE_EXECUTOR.codeName + "." + global.CLONE_EXECUTOR.version + "/" + global.EXCHANGE_NAME + "/" + bot.dataSetVersion; - let filePath = filePathRoot + "/Output/" + PERCENTAGE_BANDWIDTH_FOLDER_NAME + "/" + "Multi-Period-Market" + "/" + timePeriod; + let filePath = filePathRoot + "/Output/" + PERCENTAGE_BANDWIDTH_FOLDER_NAME + "/" + "Multi-Period-Market" + "/" + timeFrame; filePath += '/' + fileName fileStorage.createTextFile(bot.dataMine, filePath, fileContent + '\n', onFileCreated); diff --git a/this.bot.config.json b/this.bot.config.json index 0a61ab01a..4252b243a 100644 --- a/this.bot.config.json +++ b/this.bot.config.json @@ -13,7 +13,7 @@ "processes": [ { "name": "Multi-Period-Market", - "description": "Produces a single file for each time period covering all the market.", + "description": "Produces a single file for each Time Frame covering all the market.", "startMode": { "allMonths": { "run": "false", @@ -74,7 +74,7 @@ }, { "name": "Multi-Period-Daily", - "description": "Produces a Daily File at each time period.", + "description": "Produces a Daily File at each Time Frame.", "startMode": { "allMonths": { "run": "false", From 6fe37b82e8a152848d50c5a96603e8ef29e3ad77 Mon Sep 17 00:00:00 2001 From: Luis Fernando Molina Date: Sun, 5 Jan 2020 11:25:52 +0100 Subject: [PATCH 21/40] Exchange taken from UI --- Multi-Period-Daily/User.Bot.js | 8 ++++---- Multi-Period-Market/User.Bot.js | 6 +++--- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/Multi-Period-Daily/User.Bot.js b/Multi-Period-Daily/User.Bot.js index 256cd3aba..6af11122d 100644 --- a/Multi-Period-Daily/User.Bot.js +++ b/Multi-Period-Daily/User.Bot.js @@ -314,7 +314,7 @@ let dateForPath = previousDay.getUTCFullYear() + '/' + utilities.pad(previousDay.getUTCMonth() + 1, 2) + '/' + utilities.pad(previousDay.getUTCDate(), 2); let fileName = market.assetA + '_' + market.assetB + ".json" - let filePathRoot = bot.dataMine + "/" + "AAOlivia" + "." + bot.version.major + "." + bot.version.minor + "/" + global.CLONE_EXECUTOR.codeName + "." + global.CLONE_EXECUTOR.version + "/" + global.EXCHANGE_NAME + "/" + bot.dataSetVersion; + let filePathRoot = bot.dataMine + "/" + "AAOlivia" + "." + bot.version.major + "." + bot.version.minor + "/" + global.CLONE_EXECUTOR.codeName + "." + global.CLONE_EXECUTOR.version + "/" + bot.exchange + "/" + bot.dataSetVersion; let filePath = filePathRoot + "/Output/" + CANDLES_FOLDER_NAME + '/' + "Multi-Period-Daily" + "/" + timeFrame + "/" + dateForPath; filePath += '/' + fileName @@ -354,7 +354,7 @@ let dateForPath = processDate.getUTCFullYear() + '/' + utilities.pad(processDate.getUTCMonth() + 1, 2) + '/' + utilities.pad(processDate.getUTCDate(), 2); let fileName = market.assetA + '_' + market.assetB + ".json" - let filePathRoot = bot.dataMine + "/" + "AAOlivia" + "." + bot.version.major + "." + bot.version.minor + "/" + global.CLONE_EXECUTOR.codeName + "." + global.CLONE_EXECUTOR.version + "/" + global.EXCHANGE_NAME + "/" + bot.dataSetVersion; + let filePathRoot = bot.dataMine + "/" + "AAOlivia" + "." + bot.version.major + "." + bot.version.minor + "/" + global.CLONE_EXECUTOR.codeName + "." + global.CLONE_EXECUTOR.version + "/" + bot.exchange + "/" + bot.dataSetVersion; let filePath = filePathRoot + "/Output/" + CANDLES_FOLDER_NAME + '/' + "Multi-Period-Daily" + "/" + timeFrame + "/" + dateForPath; filePath += '/' + fileName @@ -584,7 +584,7 @@ let dateForPath = processDate.getUTCFullYear() + '/' + utilities.pad(processDate.getUTCMonth() + 1, 2) + '/' + utilities.pad(processDate.getUTCDate(), 2); let fileName = '' + market.assetA + '_' + market.assetB + '.json'; - let filePathRoot = bot.dataMine + "/" + bot.codeName + "." + bot.version.major + "." + bot.version.minor + "/" + global.CLONE_EXECUTOR.codeName + "." + global.CLONE_EXECUTOR.version + "/" + global.EXCHANGE_NAME + "/" + bot.dataSetVersion; + let filePathRoot = bot.dataMine + "/" + bot.codeName + "." + bot.version.major + "." + bot.version.minor + "/" + global.CLONE_EXECUTOR.codeName + "." + global.CLONE_EXECUTOR.version + "/" + bot.exchange + "/" + bot.dataSetVersion; let filePath = filePathRoot + "/Output/" + BOLLINGER_BANDS_FOLDER_NAME + "/" + bot.process + "/" + timeFrame + "/" + dateForPath; filePath += '/' + fileName @@ -656,7 +656,7 @@ let dateForPath = processDate.getUTCFullYear() + '/' + utilities.pad(processDate.getUTCMonth() + 1, 2) + '/' + utilities.pad(processDate.getUTCDate(), 2); let fileName = '' + market.assetA + '_' + market.assetB + '.json'; - let filePathRoot = bot.dataMine + "/" + bot.codeName + "." + bot.version.major + "." + bot.version.minor + "/" + global.CLONE_EXECUTOR.codeName + "." + global.CLONE_EXECUTOR.version + "/" + global.EXCHANGE_NAME + "/" + bot.dataSetVersion; + let filePathRoot = bot.dataMine + "/" + bot.codeName + "." + bot.version.major + "." + bot.version.minor + "/" + global.CLONE_EXECUTOR.codeName + "." + global.CLONE_EXECUTOR.version + "/" + bot.exchange + "/" + bot.dataSetVersion; let filePath = filePathRoot + "/Output/" + PERCENTAGE_BANDWIDTH_FOLDER_NAME + "/" + bot.process + "/" + timeFrame + "/" + dateForPath; filePath += '/' + fileName diff --git a/Multi-Period-Market/User.Bot.js b/Multi-Period-Market/User.Bot.js index 23fab93d7..df1d7a08b 100644 --- a/Multi-Period-Market/User.Bot.js +++ b/Multi-Period-Market/User.Bot.js @@ -109,7 +109,7 @@ let fileName = market.assetA + '_' + market.assetB + ".json"; - let filePathRoot = bot.dataMine + "/" + "AAOlivia" + "." + bot.version.major + "." + bot.version.minor + "/" + global.CLONE_EXECUTOR.codeName + "." + global.CLONE_EXECUTOR.version + "/" + global.EXCHANGE_NAME + "/" + bot.dataSetVersion; + let filePathRoot = bot.dataMine + "/" + "AAOlivia" + "." + bot.version.major + "." + bot.version.minor + "/" + global.CLONE_EXECUTOR.codeName + "." + global.CLONE_EXECUTOR.version + "/" + bot.exchange + "/" + bot.dataSetVersion; let filePath = filePathRoot + "/Output/" + CANDLES_FOLDER_NAME + "/" + "Multi-Period-Market" + "/" + timeFrame; filePath += '/' + fileName @@ -299,7 +299,7 @@ let fileName = '' + market.assetA + '_' + market.assetB + '.json'; - let filePathRoot = bot.dataMine + "/" + bot.codeName + "." + bot.version.major + "." + bot.version.minor + "/" + global.CLONE_EXECUTOR.codeName + "." + global.CLONE_EXECUTOR.version + "/" + global.EXCHANGE_NAME + "/" + bot.dataSetVersion; + let filePathRoot = bot.dataMine + "/" + bot.codeName + "." + bot.version.major + "." + bot.version.minor + "/" + global.CLONE_EXECUTOR.codeName + "." + global.CLONE_EXECUTOR.version + "/" + bot.exchange + "/" + bot.dataSetVersion; let filePath = filePathRoot + "/Output/" + BOLLINGER_BANDS_FOLDER_NAME + "/" + "Multi-Period-Market" + "/" + timeFrame; filePath += '/' + fileName @@ -371,7 +371,7 @@ let fileName = '' + market.assetA + '_' + market.assetB + '.json'; - let filePathRoot = bot.dataMine + "/" + bot.codeName + "." + bot.version.major + "." + bot.version.minor + "/" + global.CLONE_EXECUTOR.codeName + "." + global.CLONE_EXECUTOR.version + "/" + global.EXCHANGE_NAME + "/" + bot.dataSetVersion; + let filePathRoot = bot.dataMine + "/" + bot.codeName + "." + bot.version.major + "." + bot.version.minor + "/" + global.CLONE_EXECUTOR.codeName + "." + global.CLONE_EXECUTOR.version + "/" + bot.exchange + "/" + bot.dataSetVersion; let filePath = filePathRoot + "/Output/" + PERCENTAGE_BANDWIDTH_FOLDER_NAME + "/" + "Multi-Period-Market" + "/" + timeFrame; filePath += '/' + fileName From b4bd792c5bda30196836bd953c8b4608bc11250b Mon Sep 17 00:00:00 2001 From: Luis Fernando Molina Date: Sun, 5 Jan 2020 14:27:44 +0100 Subject: [PATCH 22/40] market from UI --- Multi-Period-Daily/User.Bot.js | 2 +- Multi-Period-Market/User.Bot.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Multi-Period-Daily/User.Bot.js b/Multi-Period-Daily/User.Bot.js index 6af11122d..90645277a 100644 --- a/Multi-Period-Daily/User.Bot.js +++ b/Multi-Period-Daily/User.Bot.js @@ -59,7 +59,7 @@ if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] start -> Entering function."); } - let market = global.MARKET; + let market = bot.market; /* Context Variables */ diff --git a/Multi-Period-Market/User.Bot.js b/Multi-Period-Market/User.Bot.js index df1d7a08b..6ce11525d 100644 --- a/Multi-Period-Market/User.Bot.js +++ b/Multi-Period-Market/User.Bot.js @@ -53,7 +53,7 @@ if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] start -> Entering function."); } - let market = global.MARKET; + let market = bot.market; buildBands(); From 9a9a46435a42990ed02eaa29130d07d0ffa596a4 Mon Sep 17 00:00:00 2001 From: Luis Fernando Molina Date: Sun, 5 Jan 2020 15:14:33 +0100 Subject: [PATCH 23/40] baseAsset and quotedAsset refactoring --- Multi-Period-Daily/User.Bot.js | 18 +++++++++--------- Multi-Period-Market/User.Bot.js | 10 +++++----- 2 files changed, 14 insertions(+), 14 deletions(-) diff --git a/Multi-Period-Daily/User.Bot.js b/Multi-Period-Daily/User.Bot.js index 90645277a..334a6ce1d 100644 --- a/Multi-Period-Daily/User.Bot.js +++ b/Multi-Period-Daily/User.Bot.js @@ -312,7 +312,7 @@ if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] start -> buildBands -> loopBody -> getPreviousDayFile -> Entering function."); } let dateForPath = previousDay.getUTCFullYear() + '/' + utilities.pad(previousDay.getUTCMonth() + 1, 2) + '/' + utilities.pad(previousDay.getUTCDate(), 2); - let fileName = market.assetA + '_' + market.assetB + ".json" + let fileName = market.baseAsset + '_' + market.quotedAsset + ".json" let filePathRoot = bot.dataMine + "/" + "AAOlivia" + "." + bot.version.major + "." + bot.version.minor + "/" + global.CLONE_EXECUTOR.codeName + "." + global.CLONE_EXECUTOR.version + "/" + bot.exchange + "/" + bot.dataSetVersion; let filePath = filePathRoot + "/Output/" + CANDLES_FOLDER_NAME + '/' + "Multi-Period-Daily" + "/" + timeFrame + "/" + dateForPath; @@ -333,7 +333,7 @@ } catch (err) { logger.write(MODULE_NAME, "[ERROR] start -> buildBands -> periodsLoop -> loopBody -> getPreviousDayFile -> onCurrentDayFileReceived -> err = " + err.stack); logger.write(MODULE_NAME, "[ERROR] start -> buildBands -> periodsLoop -> loopBody -> getPreviousDayFile -> onCurrentDayFileReceived -> filePath = " + filePath); - logger.write(MODULE_NAME, "[ERROR] start -> buildBands -> periodsLoop -> loopBody -> getPreviousDayFile -> onCurrentDayFileReceived -> market = " + market.assetA + '_' + market.assetB); + logger.write(MODULE_NAME, "[ERROR] start -> buildBands -> periodsLoop -> loopBody -> getPreviousDayFile -> onCurrentDayFileReceived -> market = " + market.baseAsset + '_' + market.quotedAsset); callBackFunction(global.DEFAULT_RETRY_RESPONSE); } @@ -352,7 +352,7 @@ if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] start -> buildBands -> loopBody -> getProcessDayFile -> Entering function."); } let dateForPath = processDate.getUTCFullYear() + '/' + utilities.pad(processDate.getUTCMonth() + 1, 2) + '/' + utilities.pad(processDate.getUTCDate(), 2); - let fileName = market.assetA + '_' + market.assetB + ".json" + let fileName = market.baseAsset + '_' + market.quotedAsset + ".json" let filePathRoot = bot.dataMine + "/" + "AAOlivia" + "." + bot.version.major + "." + bot.version.minor + "/" + global.CLONE_EXECUTOR.codeName + "." + global.CLONE_EXECUTOR.version + "/" + bot.exchange + "/" + bot.dataSetVersion; let filePath = filePathRoot + "/Output/" + CANDLES_FOLDER_NAME + '/' + "Multi-Period-Daily" + "/" + timeFrame + "/" + dateForPath; @@ -381,7 +381,7 @@ logger.write(MODULE_NAME, "[ERROR] start -> buildBands -> periodsLoop -> loopBody -> getProcessDayFile -> onCurrentDayFileReceived -> err = " + err.stack); logger.write(MODULE_NAME, "[ERROR] start -> buildBands -> periodsLoop -> loopBody -> getProcessDayFile -> onCurrentDayFileReceived -> filePath = " + filePath); - logger.write(MODULE_NAME, "[ERROR] start -> buildBands -> periodsLoop -> loopBody -> getProcessDayFile -> onCurrentDayFileReceived -> market = " + market.assetA + '_' + market.assetB); + logger.write(MODULE_NAME, "[ERROR] start -> buildBands -> periodsLoop -> loopBody -> getProcessDayFile -> onCurrentDayFileReceived -> market = " + market.baseAsset + '_' + market.quotedAsset); callBackFunction(global.DEFAULT_RETRY_RESPONSE); return; @@ -582,7 +582,7 @@ fileContent = "[" + fileContent + "]"; let dateForPath = processDate.getUTCFullYear() + '/' + utilities.pad(processDate.getUTCMonth() + 1, 2) + '/' + utilities.pad(processDate.getUTCDate(), 2); - let fileName = '' + market.assetA + '_' + market.assetB + '.json'; + let fileName = '' + market.baseAsset + '_' + market.quotedAsset + '.json'; let filePathRoot = bot.dataMine + "/" + bot.codeName + "." + bot.version.major + "." + bot.version.minor + "/" + global.CLONE_EXECUTOR.codeName + "." + global.CLONE_EXECUTOR.version + "/" + bot.exchange + "/" + bot.dataSetVersion; let filePath = filePathRoot + "/Output/" + BOLLINGER_BANDS_FOLDER_NAME + "/" + bot.process + "/" + timeFrame + "/" + dateForPath; @@ -606,7 +606,7 @@ return; } - const logText = "[WARN] Finished with File @ " + market.assetA + "_" + market.assetB + ", " + fileRecordCounter + " records inserted into " + filePath + "/" + fileName + ""; + const logText = "[WARN] Finished with File @ " + market.baseAsset + "_" + market.quotedAsset + ", " + fileRecordCounter + " records inserted into " + filePath + "/" + fileName + ""; if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] start -> buildBands -> loopBody -> writeBandBandsFile -> writeBandsFile -> onFileCreated -> " + logText); } writePBFile(pPB); @@ -654,7 +654,7 @@ fileContent = "[" + fileContent + "]"; let dateForPath = processDate.getUTCFullYear() + '/' + utilities.pad(processDate.getUTCMonth() + 1, 2) + '/' + utilities.pad(processDate.getUTCDate(), 2); - let fileName = '' + market.assetA + '_' + market.assetB + '.json'; + let fileName = '' + market.baseAsset + '_' + market.quotedAsset + '.json'; let filePathRoot = bot.dataMine + "/" + bot.codeName + "." + bot.version.major + "." + bot.version.minor + "/" + global.CLONE_EXECUTOR.codeName + "." + global.CLONE_EXECUTOR.version + "/" + bot.exchange + "/" + bot.dataSetVersion; let filePath = filePathRoot + "/Output/" + PERCENTAGE_BANDWIDTH_FOLDER_NAME + "/" + bot.process + "/" + timeFrame + "/" + dateForPath; @@ -678,7 +678,7 @@ return; } - const logText = "[WARN] Finished with File @ " + market.assetA + "_" + market.assetB + ", " + fileRecordCounter + " records inserted into " + filePath + "/" + fileName + ""; + const logText = "[WARN] Finished with File @ " + market.baseAsset + "_" + market.quotedAsset + ", " + fileRecordCounter + " records inserted into " + filePath + "/" + fileName + ""; if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] start -> buildBands -> loopBody -> writeBandBandsFile -> writePBFile -> onFileCreated -> " + logText); } controlLoop(); @@ -810,7 +810,7 @@ let fileContent = JSON.stringify(dataRange); - let fileName = 'Data.Range.' + market.assetA + '_' + market.assetB + '.json'; + let fileName = 'Data.Range.' + market.baseAsset + '_' + market.quotedAsset + '.json'; let filePath = bot.filePathRoot + "/Output/" + pProductFolder + "/" + bot.process; filePath += '/' + fileName diff --git a/Multi-Period-Market/User.Bot.js b/Multi-Period-Market/User.Bot.js index 6ce11525d..f71a69279 100644 --- a/Multi-Period-Market/User.Bot.js +++ b/Multi-Period-Market/User.Bot.js @@ -107,7 +107,7 @@ if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] start -> buildBands -> loopBody -> nextCandleFile -> Entering function."); } - let fileName = market.assetA + '_' + market.assetB + ".json"; + let fileName = market.baseAsset + '_' + market.quotedAsset + ".json"; let filePathRoot = bot.dataMine + "/" + "AAOlivia" + "." + bot.version.major + "." + bot.version.minor + "/" + global.CLONE_EXECUTOR.codeName + "." + global.CLONE_EXECUTOR.version + "/" + bot.exchange + "/" + bot.dataSetVersion; let filePath = filePathRoot + "/Output/" + CANDLES_FOLDER_NAME + "/" + "Multi-Period-Market" + "/" + timeFrame; @@ -297,7 +297,7 @@ fileContent = "[" + fileContent + "]"; - let fileName = '' + market.assetA + '_' + market.assetB + '.json'; + let fileName = '' + market.baseAsset + '_' + market.quotedAsset + '.json'; let filePathRoot = bot.dataMine + "/" + bot.codeName + "." + bot.version.major + "." + bot.version.minor + "/" + global.CLONE_EXECUTOR.codeName + "." + global.CLONE_EXECUTOR.version + "/" + bot.exchange + "/" + bot.dataSetVersion; let filePath = filePathRoot + "/Output/" + BOLLINGER_BANDS_FOLDER_NAME + "/" + "Multi-Period-Market" + "/" + timeFrame; @@ -316,7 +316,7 @@ logger.write(MODULE_NAME, "[ERROR] start -> buildBands -> loopBody -> nextCandleFile -> onFileReceived -> writeBandsFile -> onFileCreated -> err = " + err.stack); logger.write(MODULE_NAME, "[ERROR] start -> buildBands -> loopBody -> nextCandleFile -> onFileReceived -> writeBandsFile -> onFileCreated -> filePath = " + filePath); - logger.write(MODULE_NAME, "[ERROR] start -> buildBands -> loopBody -> nextCandleFile -> onFileReceived -> writeBandsFile -> onFileCreated -> market = " + market.assetA + "_" + market.assetB); + logger.write(MODULE_NAME, "[ERROR] start -> buildBands -> loopBody -> nextCandleFile -> onFileReceived -> writeBandsFile -> onFileCreated -> market = " + market.baseAsset + "_" + market.quotedAsset); callBackFunction(err); return; @@ -369,7 +369,7 @@ fileContent = "[" + fileContent + "]"; - let fileName = '' + market.assetA + '_' + market.assetB + '.json'; + let fileName = '' + market.baseAsset + '_' + market.quotedAsset + '.json'; let filePathRoot = bot.dataMine + "/" + bot.codeName + "." + bot.version.major + "." + bot.version.minor + "/" + global.CLONE_EXECUTOR.codeName + "." + global.CLONE_EXECUTOR.version + "/" + bot.exchange + "/" + bot.dataSetVersion; let filePath = filePathRoot + "/Output/" + PERCENTAGE_BANDWIDTH_FOLDER_NAME + "/" + "Multi-Period-Market" + "/" + timeFrame; @@ -388,7 +388,7 @@ logger.write(MODULE_NAME, "[ERROR] start -> buildBands -> loopBody -> nextCandleFile -> onFileReceived -> writePBFile -> onFileCreated -> err = " + err.stack); logger.write(MODULE_NAME, "[ERROR] start -> buildBands -> loopBody -> nextCandleFile -> onFileReceived -> writePBFile -> onFileCreated -> filePath = " + filePath); - logger.write(MODULE_NAME, "[ERROR] start -> buildBands -> loopBody -> nextCandleFile -> onFileReceived -> writePBFile -> onFileCreated -> market = " + market.assetA + "_" + market.assetB); + logger.write(MODULE_NAME, "[ERROR] start -> buildBands -> loopBody -> nextCandleFile -> onFileReceived -> writePBFile -> onFileCreated -> market = " + market.baseAsset + "_" + market.quotedAsset); callBackFunction(err); return; From 3edfeded553a0ae9e84a61b1aee0435092dc49e9 Mon Sep 17 00:00:00 2001 From: Luis Fernando Molina Date: Fri, 24 Jan 2020 12:52:24 +0100 Subject: [PATCH 24/40] adapting to charly historic trades --- Multi-Period-Daily/User.Bot.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Multi-Period-Daily/User.Bot.js b/Multi-Period-Daily/User.Bot.js index 334a6ce1d..557de4aec 100644 --- a/Multi-Period-Daily/User.Bot.js +++ b/Multi-Period-Daily/User.Bot.js @@ -105,7 +105,7 @@ thisReport = statusDependencies.statusReports.get(reportKey).file; - if (thisReport.lastFile === undefined) { + if (thisReport.beginingOfMarket === undefined) { logger.write(MODULE_NAME, "[WARN] start -> getContextVariables -> Undefined Last File. -> reportKey = " + reportKey); logger.write(MODULE_NAME, "[HINT] start -> getContextVariables -> It is too early too run this process since the trade history of the market is not there yet."); @@ -118,7 +118,7 @@ return; } - contextVariables.firstTradeFile = new Date(thisReport.lastFile.year + "-" + thisReport.lastFile.month + "-" + thisReport.lastFile.days + " " + thisReport.lastFile.hours + ":" + thisReport.lastFile.minutes + GMT_SECONDS); + contextVariables.firstTradeFile = new Date(thisReport.beginingOfMarket.year + "-" + thisReport.beginingOfMarket.month + "-" + thisReport.beginingOfMarket.days + " " + thisReport.beginingOfMarket.hours + ":" + thisReport.beginingOfMarket.minutes + GMT_SECONDS); /* Second, we get the report from Olivia, to know when the marted ends. */ From 63b6bc1f6eaa3fa2acdc51166775c4ab5e3527be Mon Sep 17 00:00:00 2001 From: Luis Fernando Molina Date: Tue, 28 Jan 2020 12:40:33 +0100 Subject: [PATCH 25/40] Cleaning File Paths --- Multi-Period-Daily/User.Bot.js | 8 ++++---- Multi-Period-Market/User.Bot.js | 6 +++--- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/Multi-Period-Daily/User.Bot.js b/Multi-Period-Daily/User.Bot.js index 557de4aec..348c252f0 100644 --- a/Multi-Period-Daily/User.Bot.js +++ b/Multi-Period-Daily/User.Bot.js @@ -314,7 +314,7 @@ let dateForPath = previousDay.getUTCFullYear() + '/' + utilities.pad(previousDay.getUTCMonth() + 1, 2) + '/' + utilities.pad(previousDay.getUTCDate(), 2); let fileName = market.baseAsset + '_' + market.quotedAsset + ".json" - let filePathRoot = bot.dataMine + "/" + "AAOlivia" + "." + bot.version.major + "." + bot.version.minor + "/" + global.CLONE_EXECUTOR.codeName + "." + global.CLONE_EXECUTOR.version + "/" + bot.exchange + "/" + bot.dataSetVersion; + let filePathRoot = bot.dataMine + "/" + "AAOlivia" + "/" + bot.exchange; let filePath = filePathRoot + "/Output/" + CANDLES_FOLDER_NAME + '/' + "Multi-Period-Daily" + "/" + timeFrame + "/" + dateForPath; filePath += '/' + fileName @@ -354,7 +354,7 @@ let dateForPath = processDate.getUTCFullYear() + '/' + utilities.pad(processDate.getUTCMonth() + 1, 2) + '/' + utilities.pad(processDate.getUTCDate(), 2); let fileName = market.baseAsset + '_' + market.quotedAsset + ".json" - let filePathRoot = bot.dataMine + "/" + "AAOlivia" + "." + bot.version.major + "." + bot.version.minor + "/" + global.CLONE_EXECUTOR.codeName + "." + global.CLONE_EXECUTOR.version + "/" + bot.exchange + "/" + bot.dataSetVersion; + let filePathRoot = bot.dataMine + "/" + "AAOlivia" + "/" + bot.exchange; let filePath = filePathRoot + "/Output/" + CANDLES_FOLDER_NAME + '/' + "Multi-Period-Daily" + "/" + timeFrame + "/" + dateForPath; filePath += '/' + fileName @@ -584,7 +584,7 @@ let dateForPath = processDate.getUTCFullYear() + '/' + utilities.pad(processDate.getUTCMonth() + 1, 2) + '/' + utilities.pad(processDate.getUTCDate(), 2); let fileName = '' + market.baseAsset + '_' + market.quotedAsset + '.json'; - let filePathRoot = bot.dataMine + "/" + bot.codeName + "." + bot.version.major + "." + bot.version.minor + "/" + global.CLONE_EXECUTOR.codeName + "." + global.CLONE_EXECUTOR.version + "/" + bot.exchange + "/" + bot.dataSetVersion; + let filePathRoot = bot.dataMine + "/" + bot.codeName + "/" + bot.exchange; let filePath = filePathRoot + "/Output/" + BOLLINGER_BANDS_FOLDER_NAME + "/" + bot.process + "/" + timeFrame + "/" + dateForPath; filePath += '/' + fileName @@ -656,7 +656,7 @@ let dateForPath = processDate.getUTCFullYear() + '/' + utilities.pad(processDate.getUTCMonth() + 1, 2) + '/' + utilities.pad(processDate.getUTCDate(), 2); let fileName = '' + market.baseAsset + '_' + market.quotedAsset + '.json'; - let filePathRoot = bot.dataMine + "/" + bot.codeName + "." + bot.version.major + "." + bot.version.minor + "/" + global.CLONE_EXECUTOR.codeName + "." + global.CLONE_EXECUTOR.version + "/" + bot.exchange + "/" + bot.dataSetVersion; + let filePathRoot = bot.dataMine + "/" + bot.codeName + "/" + bot.exchange; let filePath = filePathRoot + "/Output/" + PERCENTAGE_BANDWIDTH_FOLDER_NAME + "/" + bot.process + "/" + timeFrame + "/" + dateForPath; filePath += '/' + fileName diff --git a/Multi-Period-Market/User.Bot.js b/Multi-Period-Market/User.Bot.js index f71a69279..54d520c57 100644 --- a/Multi-Period-Market/User.Bot.js +++ b/Multi-Period-Market/User.Bot.js @@ -109,7 +109,7 @@ let fileName = market.baseAsset + '_' + market.quotedAsset + ".json"; - let filePathRoot = bot.dataMine + "/" + "AAOlivia" + "." + bot.version.major + "." + bot.version.minor + "/" + global.CLONE_EXECUTOR.codeName + "." + global.CLONE_EXECUTOR.version + "/" + bot.exchange + "/" + bot.dataSetVersion; + let filePathRoot = bot.dataMine + "/" + "AAOlivia" + "/" + bot.exchange; let filePath = filePathRoot + "/Output/" + CANDLES_FOLDER_NAME + "/" + "Multi-Period-Market" + "/" + timeFrame; filePath += '/' + fileName @@ -299,7 +299,7 @@ let fileName = '' + market.baseAsset + '_' + market.quotedAsset + '.json'; - let filePathRoot = bot.dataMine + "/" + bot.codeName + "." + bot.version.major + "." + bot.version.minor + "/" + global.CLONE_EXECUTOR.codeName + "." + global.CLONE_EXECUTOR.version + "/" + bot.exchange + "/" + bot.dataSetVersion; + let filePathRoot = bot.dataMine + "/" + bot.codeName + "/" + bot.exchange; let filePath = filePathRoot + "/Output/" + BOLLINGER_BANDS_FOLDER_NAME + "/" + "Multi-Period-Market" + "/" + timeFrame; filePath += '/' + fileName @@ -371,7 +371,7 @@ let fileName = '' + market.baseAsset + '_' + market.quotedAsset + '.json'; - let filePathRoot = bot.dataMine + "/" + bot.codeName + "." + bot.version.major + "." + bot.version.minor + "/" + global.CLONE_EXECUTOR.codeName + "." + global.CLONE_EXECUTOR.version + "/" + bot.exchange + "/" + bot.dataSetVersion; + let filePathRoot = bot.dataMine + "/" + bot.codeName + "/" + bot.exchange; let filePath = filePathRoot + "/Output/" + PERCENTAGE_BANDWIDTH_FOLDER_NAME + "/" + "Multi-Period-Market" + "/" + timeFrame; filePath += '/' + fileName From 7b23ba46a5f904a73866c795f56a356f957da8ce Mon Sep 17 00:00:00 2001 From: Luis Fernando Molina Date: Tue, 28 Jan 2020 13:29:00 +0100 Subject: [PATCH 26/40] Removing Container Name from Paths --- Multi-Period-Daily/User.Bot.js | 10 +++++----- Multi-Period-Market/User.Bot.js | 6 +++--- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/Multi-Period-Daily/User.Bot.js b/Multi-Period-Daily/User.Bot.js index 348c252f0..0b652ef60 100644 --- a/Multi-Period-Daily/User.Bot.js +++ b/Multi-Period-Daily/User.Bot.js @@ -318,7 +318,7 @@ let filePath = filePathRoot + "/Output/" + CANDLES_FOLDER_NAME + '/' + "Multi-Period-Daily" + "/" + timeFrame + "/" + dateForPath; filePath += '/' + fileName - fileStorage.getTextFile(bot.dataMine, filePath, onCurrentDayFileReceived); + fileStorage.getTextFile(filePath, onCurrentDayFileReceived); function onCurrentDayFileReceived(err, text) { @@ -358,7 +358,7 @@ let filePath = filePathRoot + "/Output/" + CANDLES_FOLDER_NAME + '/' + "Multi-Period-Daily" + "/" + timeFrame + "/" + dateForPath; filePath += '/' + fileName - fileStorage.getTextFile(bot.dataMine, filePath, onCurrentDayFileReceived); + fileStorage.getTextFile(filePath, onCurrentDayFileReceived); function onCurrentDayFileReceived(err, text) { @@ -588,7 +588,7 @@ let filePath = filePathRoot + "/Output/" + BOLLINGER_BANDS_FOLDER_NAME + "/" + bot.process + "/" + timeFrame + "/" + dateForPath; filePath += '/' + fileName - fileStorage.createTextFile(bot.dataMine, filePath, fileContent + '\n', onFileCreated); + fileStorage.createTextFile(filePath, fileContent + '\n', onFileCreated); function onFileCreated(err) { @@ -660,7 +660,7 @@ let filePath = filePathRoot + "/Output/" + PERCENTAGE_BANDWIDTH_FOLDER_NAME + "/" + bot.process + "/" + timeFrame + "/" + dateForPath; filePath += '/' + fileName - fileStorage.createTextFile(bot.dataMine, filePath, fileContent + '\n', onFileCreated); + fileStorage.createTextFile(filePath, fileContent + '\n', onFileCreated); function onFileCreated(err) { @@ -815,7 +815,7 @@ filePath += '/' + fileName - fileStorage.createTextFile(bot.dataMine, filePath, fileContent + '\n', onFileCreated); + fileStorage.createTextFile(filePath, fileContent + '\n', onFileCreated); function onFileCreated(err) { diff --git a/Multi-Period-Market/User.Bot.js b/Multi-Period-Market/User.Bot.js index 54d520c57..c9bf74b81 100644 --- a/Multi-Period-Market/User.Bot.js +++ b/Multi-Period-Market/User.Bot.js @@ -113,7 +113,7 @@ let filePath = filePathRoot + "/Output/" + CANDLES_FOLDER_NAME + "/" + "Multi-Period-Market" + "/" + timeFrame; filePath += '/' + fileName - fileStorage.getTextFile(bot.dataMine, filePath, onFileReceived); + fileStorage.getTextFile(filePath, onFileReceived); function onFileReceived(err, text) { @@ -303,7 +303,7 @@ let filePath = filePathRoot + "/Output/" + BOLLINGER_BANDS_FOLDER_NAME + "/" + "Multi-Period-Market" + "/" + timeFrame; filePath += '/' + fileName - fileStorage.createTextFile(bot.dataMine, filePath, fileContent + '\n', onFileCreated); + fileStorage.createTextFile(filePath, fileContent + '\n', onFileCreated); function onFileCreated(err) { @@ -375,7 +375,7 @@ let filePath = filePathRoot + "/Output/" + PERCENTAGE_BANDWIDTH_FOLDER_NAME + "/" + "Multi-Period-Market" + "/" + timeFrame; filePath += '/' + fileName - fileStorage.createTextFile(bot.dataMine, filePath, fileContent + '\n', onFileCreated); + fileStorage.createTextFile(filePath, fileContent + '\n', onFileCreated); function onFileCreated(err) { From 9e6d1d7e477a7687b001c50d19e240ed660660be Mon Sep 17 00:00:00 2001 From: Luis Fernando Molina Date: Mon, 3 Feb 2020 17:59:03 +0100 Subject: [PATCH 27/40] Concept of Multiple Instances of a Process Removed --- Multi-Period-Daily/User.Bot.js | 2 +- Multi-Period-Market/User.Bot.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Multi-Period-Daily/User.Bot.js b/Multi-Period-Daily/User.Bot.js index 0b652ef60..ddaf95527 100644 --- a/Multi-Period-Daily/User.Bot.js +++ b/Multi-Period-Daily/User.Bot.js @@ -26,7 +26,7 @@ return thisObject; - function initialize(pStatusDependencies, pMonth, pYear, callBackFunction) { + function initialize(pStatusDependencies, callBackFunction) { try { diff --git a/Multi-Period-Market/User.Bot.js b/Multi-Period-Market/User.Bot.js index c9bf74b81..3f0742040 100644 --- a/Multi-Period-Market/User.Bot.js +++ b/Multi-Period-Market/User.Bot.js @@ -20,7 +20,7 @@ return thisObject; - function initialize(pStatusDependencies, pMonth, pYear, callBackFunction) { + function initialize(pStatusDependencies, callBackFunction) { try { From 856f3d4db1e23fb81b4ebca5fef7748c74022ab1 Mon Sep 17 00:00:00 2001 From: Luis Fernando Molina Date: Sat, 8 Feb 2020 18:54:52 +0100 Subject: [PATCH 28/40] Reset Begining of Market Mechanism Implemented --- Multi-Period-Daily/User.Bot.js | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/Multi-Period-Daily/User.Bot.js b/Multi-Period-Daily/User.Bot.js index ddaf95527..b773a7052 100644 --- a/Multi-Period-Daily/User.Bot.js +++ b/Multi-Period-Daily/User.Bot.js @@ -23,6 +23,7 @@ let utilities = UTILITIES.newCloudUtilities(bot, logger); let statusDependencies; + let beginingOfMarket return thisObject; @@ -178,6 +179,19 @@ if (thisReport.lastFile !== undefined) { + beginingOfMarket = new Date(thisReport.beginingOfMarket); + + if (beginingOfMarket.valueOf() !== contextVariables.firstTradeFile.valueOf()) { // Reset Mechanism for Begining of the Market + logger.write(MODULE_NAME, "[INFO] start -> getContextVariables -> Reset Mechanism for Begining of the Market Activated. -> reportKey = " + reportKey); + + beginingOfMarket = new Date(contextVariables.firstTradeFile.getUTCFullYear() + "-" + (contextVariables.firstTradeFile.getUTCMonth() + 1) + "-" + contextVariables.firstTradeFile.getUTCDate() + " " + "00:00" + GMT_SECONDS); + contextVariables.lastBandFile = new Date(contextVariables.firstTradeFile.getUTCFullYear() + "-" + (contextVariables.firstTradeFile.getUTCMonth() + 1) + "-" + contextVariables.firstTradeFile.getUTCDate() + " " + "00:00" + GMT_SECONDS); + contextVariables.lastBandFile = new Date(contextVariables.lastBandFile.valueOf() + ONE_DAY_IN_MILISECONDS); + + buildBands(); + return; + } + contextVariables.lastBandFile = new Date(thisReport.lastFile); /* @@ -205,6 +219,8 @@ contextVariables.lastBandFile = new Date(contextVariables.firstTradeFile.getUTCFullYear() + "-" + (contextVariables.firstTradeFile.getUTCMonth() + 1) + "-" + contextVariables.firstTradeFile.getUTCDate() + " " + "00:00" + GMT_SECONDS); contextVariables.lastBandFile = new Date(contextVariables.lastBandFile.valueOf() + ONE_DAY_IN_MILISECONDS); + beginingOfMarket = new Date(contextVariables.firstTradeFile.getUTCFullYear() + "-" + (contextVariables.firstTradeFile.getUTCMonth() + 1) + "-" + contextVariables.firstTradeFile.getUTCDate() + " " + "00:00" + GMT_SECONDS); + if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] start -> getContextVariables -> thisReport.lastFile === undefined"); } if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] start -> getContextVariables -> contextVariables.lastBandFile = " + contextVariables.lastBandFile); } @@ -852,6 +868,7 @@ thisReport.file.lastExecution = bot.processDatetime; thisReport.file.lastFile = lastFileDate; + thisReport.file.beginingOfMarket = beginingOfMarket.toUTCString() thisReport.save(callBack); } From 3881f9b242fae956c68cf4d3523bcde877cc56a0 Mon Sep 17 00:00:00 2001 From: Luis Fernando Molina Date: Wed, 11 Mar 2020 12:00:16 +0100 Subject: [PATCH 29/40] Change Folder Structure --- Multi-Period-Daily/User.Bot.js | 24 +++++++++--------------- Multi-Period-Market/User.Bot.js | 16 ++++++---------- 2 files changed, 15 insertions(+), 25 deletions(-) diff --git a/Multi-Period-Daily/User.Bot.js b/Multi-Period-Daily/User.Bot.js index b773a7052..836ec9ac2 100644 --- a/Multi-Period-Daily/User.Bot.js +++ b/Multi-Period-Daily/User.Bot.js @@ -328,9 +328,8 @@ if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] start -> buildBands -> loopBody -> getPreviousDayFile -> Entering function."); } let dateForPath = previousDay.getUTCFullYear() + '/' + utilities.pad(previousDay.getUTCMonth() + 1, 2) + '/' + utilities.pad(previousDay.getUTCDate(), 2); - let fileName = market.baseAsset + '_' + market.quotedAsset + ".json" - - let filePathRoot = bot.dataMine + "/" + "AAOlivia" + "/" + bot.exchange; + let fileName = "Data.json" + let filePathRoot = bot.exchange + "/" + bot.market.baseAsset + "-" + bot.market.quotedAsset + "/" + bot.dataMine + "/" + "AAOlivia"; let filePath = filePathRoot + "/Output/" + CANDLES_FOLDER_NAME + '/' + "Multi-Period-Daily" + "/" + timeFrame + "/" + dateForPath; filePath += '/' + fileName @@ -368,9 +367,8 @@ if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] start -> buildBands -> loopBody -> getProcessDayFile -> Entering function."); } let dateForPath = processDate.getUTCFullYear() + '/' + utilities.pad(processDate.getUTCMonth() + 1, 2) + '/' + utilities.pad(processDate.getUTCDate(), 2); - let fileName = market.baseAsset + '_' + market.quotedAsset + ".json" - - let filePathRoot = bot.dataMine + "/" + "AAOlivia" + "/" + bot.exchange; + let fileName = "Data.json" + let filePathRoot = bot.exchange + "/" + bot.market.baseAsset + "-" + bot.market.quotedAsset + "/" + bot.dataMine + "/" + "AAOlivia"; let filePath = filePathRoot + "/Output/" + CANDLES_FOLDER_NAME + '/' + "Multi-Period-Daily" + "/" + timeFrame + "/" + dateForPath; filePath += '/' + fileName @@ -598,10 +596,8 @@ fileContent = "[" + fileContent + "]"; let dateForPath = processDate.getUTCFullYear() + '/' + utilities.pad(processDate.getUTCMonth() + 1, 2) + '/' + utilities.pad(processDate.getUTCDate(), 2); - let fileName = '' + market.baseAsset + '_' + market.quotedAsset + '.json'; - - let filePathRoot = bot.dataMine + "/" + bot.codeName + "/" + bot.exchange; - let filePath = filePathRoot + "/Output/" + BOLLINGER_BANDS_FOLDER_NAME + "/" + bot.process + "/" + timeFrame + "/" + dateForPath; + let fileName = 'Data.json'; + let filePath = bot.filePathRoot + "/Output/" + BOLLINGER_BANDS_FOLDER_NAME + "/" + bot.process + "/" + timeFrame + "/" + dateForPath; filePath += '/' + fileName fileStorage.createTextFile(filePath, fileContent + '\n', onFileCreated); @@ -670,10 +666,8 @@ fileContent = "[" + fileContent + "]"; let dateForPath = processDate.getUTCFullYear() + '/' + utilities.pad(processDate.getUTCMonth() + 1, 2) + '/' + utilities.pad(processDate.getUTCDate(), 2); - let fileName = '' + market.baseAsset + '_' + market.quotedAsset + '.json'; - - let filePathRoot = bot.dataMine + "/" + bot.codeName + "/" + bot.exchange; - let filePath = filePathRoot + "/Output/" + PERCENTAGE_BANDWIDTH_FOLDER_NAME + "/" + bot.process + "/" + timeFrame + "/" + dateForPath; + let fileName = 'Data.json'; + let filePath = bot.filePathRoot + "/Output/" + PERCENTAGE_BANDWIDTH_FOLDER_NAME + "/" + bot.process + "/" + timeFrame + "/" + dateForPath; filePath += '/' + fileName fileStorage.createTextFile(filePath, fileContent + '\n', onFileCreated); @@ -826,7 +820,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/" + pProductFolder + "/" + bot.process; filePath += '/' + fileName diff --git a/Multi-Period-Market/User.Bot.js b/Multi-Period-Market/User.Bot.js index 3f0742040..52e09e3c8 100644 --- a/Multi-Period-Market/User.Bot.js +++ b/Multi-Period-Market/User.Bot.js @@ -107,9 +107,9 @@ if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] start -> buildBands -> loopBody -> nextCandleFile -> Entering function."); } - let fileName = market.baseAsset + '_' + market.quotedAsset + ".json"; + let fileName = "Data.json"; - let filePathRoot = bot.dataMine + "/" + "AAOlivia" + "/" + bot.exchange; + let filePathRoot = bot.exchange + "/" + bot.market.baseAsset + "-" + bot.market.quotedAsset + "/" + bot.dataMine + "/" + "AAOlivia"; let filePath = filePathRoot + "/Output/" + CANDLES_FOLDER_NAME + "/" + "Multi-Period-Market" + "/" + timeFrame; filePath += '/' + fileName @@ -297,10 +297,8 @@ fileContent = "[" + fileContent + "]"; - let fileName = '' + market.baseAsset + '_' + market.quotedAsset + '.json'; - - let filePathRoot = bot.dataMine + "/" + bot.codeName + "/" + bot.exchange; - let filePath = filePathRoot + "/Output/" + BOLLINGER_BANDS_FOLDER_NAME + "/" + "Multi-Period-Market" + "/" + timeFrame; + let fileName = 'Data.json'; + let filePath = bot.filePathRoot + "/Output/" + BOLLINGER_BANDS_FOLDER_NAME + "/" + "Multi-Period-Market" + "/" + timeFrame; filePath += '/' + fileName fileStorage.createTextFile(filePath, fileContent + '\n', onFileCreated); @@ -369,10 +367,8 @@ fileContent = "[" + fileContent + "]"; - let fileName = '' + market.baseAsset + '_' + market.quotedAsset + '.json'; - - let filePathRoot = bot.dataMine + "/" + bot.codeName + "/" + bot.exchange; - let filePath = filePathRoot + "/Output/" + PERCENTAGE_BANDWIDTH_FOLDER_NAME + "/" + "Multi-Period-Market" + "/" + timeFrame; + let fileName = 'Data.json'; + let filePath = bot.filePathRoot + "/Output/" + PERCENTAGE_BANDWIDTH_FOLDER_NAME + "/" + "Multi-Period-Market" + "/" + timeFrame; filePath += '/' + fileName fileStorage.createTextFile(filePath, fileContent + '\n', onFileCreated); From 2e9aa2b964af3373baeb8ce1f403de0ecaf1cdf3 Mon Sep 17 00:00:00 2001 From: Luis Fernando Molina Date: Wed, 11 Mar 2020 20:06:12 +0100 Subject: [PATCH 30/40] Refactored --- ...t.sln => Bollinger-Bands-Indicator-Bot.sln | 0 Multi-Period-Daily/User.Bot.js | 18 +++++------ Multi-Period-Market/User.Bot.js | 6 ++-- README.md | 2 +- this.bot.config.json | 32 +++++++++---------- 5 files changed, 29 insertions(+), 29 deletions(-) rename AAChris-Indicator-Bot.sln => Bollinger-Bands-Indicator-Bot.sln (100%) diff --git a/AAChris-Indicator-Bot.sln b/Bollinger-Bands-Indicator-Bot.sln similarity index 100% rename from AAChris-Indicator-Bot.sln rename to Bollinger-Bands-Indicator-Bot.sln diff --git a/Multi-Period-Daily/User.Bot.js b/Multi-Period-Daily/User.Bot.js index 836ec9ac2..b0a8cf0e0 100644 --- a/Multi-Period-Daily/User.Bot.js +++ b/Multi-Period-Daily/User.Bot.js @@ -50,7 +50,7 @@ This process is going to do the following: - Read the candles from Olivia and produce daily files with bollinger bands. + Read the candles from Candles Volumes and produce daily files with bollinger bands. */ @@ -85,9 +85,9 @@ let reportKey; let statusReport; - /* We look first for Charly in order to get when the market starts. */ + /* We look first for Exchange Raw Data in order to get when the market starts. */ - reportKey = "AAMasters" + "-" + "AACharly" + "-" + "Historic-Trades" + "-" + "dataSet.V1"; + reportKey = "AAMasters" + "-" + "Exchange-Raw-Data" + "-" + "Historic-Trades" + "-" + "dataSet.V1"; if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] start -> getContextVariables -> reportKey = " + reportKey); } statusReport = statusDependencies.statusReports.get(reportKey); @@ -121,9 +121,9 @@ contextVariables.firstTradeFile = new Date(thisReport.beginingOfMarket.year + "-" + thisReport.beginingOfMarket.month + "-" + thisReport.beginingOfMarket.days + " " + thisReport.beginingOfMarket.hours + ":" + thisReport.beginingOfMarket.minutes + GMT_SECONDS); - /* Second, we get the report from Olivia, to know when the marted ends. */ + /* Second, we get the report from Candles Volumes, to know when the marted ends. */ - reportKey = "AAMasters" + "-" + "AAOlivia" + "-" + "Multi-Period-Daily" + "-" + "dataSet.V1"; + reportKey = "AAMasters" + "-" + "Candles-Volumes" + "-" + "Multi-Period-Daily" + "-" + "dataSet.V1"; if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] start -> getContextVariables -> reportKey = " + reportKey); } statusReport = statusDependencies.statusReports.get(reportKey); @@ -158,7 +158,7 @@ /* Finally we get our own Status Report. */ - reportKey = "AAMasters" + "-" + "AAChris" + "-" + "Multi-Period-Daily" + "-" + "dataSet.V1"; + reportKey = "AAMasters" + "-" + "Bollinger-Bands" + "-" + "Multi-Period-Daily" + "-" + "dataSet.V1"; if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] start -> getContextVariables -> reportKey = " + reportKey); } statusReport = statusDependencies.statusReports.get(reportKey); @@ -329,7 +329,7 @@ let dateForPath = previousDay.getUTCFullYear() + '/' + utilities.pad(previousDay.getUTCMonth() + 1, 2) + '/' + utilities.pad(previousDay.getUTCDate(), 2); let fileName = "Data.json" - let filePathRoot = bot.exchange + "/" + bot.market.baseAsset + "-" + bot.market.quotedAsset + "/" + bot.dataMine + "/" + "AAOlivia"; + let filePathRoot = bot.exchange + "/" + bot.market.baseAsset + "-" + bot.market.quotedAsset + "/" + bot.dataMine + "/" + "Candles-Volumes"; let filePath = filePathRoot + "/Output/" + CANDLES_FOLDER_NAME + '/' + "Multi-Period-Daily" + "/" + timeFrame + "/" + dateForPath; filePath += '/' + fileName @@ -368,7 +368,7 @@ let dateForPath = processDate.getUTCFullYear() + '/' + utilities.pad(processDate.getUTCMonth() + 1, 2) + '/' + utilities.pad(processDate.getUTCDate(), 2); let fileName = "Data.json" - let filePathRoot = bot.exchange + "/" + bot.market.baseAsset + "-" + bot.market.quotedAsset + "/" + bot.dataMine + "/" + "AAOlivia"; + let filePathRoot = bot.exchange + "/" + bot.market.baseAsset + "-" + bot.market.quotedAsset + "/" + bot.dataMine + "/" + "Candles-Volumes"; let filePath = filePathRoot + "/Output/" + CANDLES_FOLDER_NAME + '/' + "Multi-Period-Daily" + "/" + timeFrame + "/" + dateForPath; filePath += '/' + fileName @@ -857,7 +857,7 @@ try { - let reportKey = "AAMasters" + "-" + "AAChris" + "-" + "Multi-Period-Daily" + "-" + "dataSet.V1"; + let reportKey = "AAMasters" + "-" + "Bollinger-Bands" + "-" + "Multi-Period-Daily" + "-" + "dataSet.V1"; let thisReport = statusDependencies.statusReports.get(reportKey); thisReport.file.lastExecution = bot.processDatetime; diff --git a/Multi-Period-Market/User.Bot.js b/Multi-Period-Market/User.Bot.js index 52e09e3c8..1cbd697da 100644 --- a/Multi-Period-Market/User.Bot.js +++ b/Multi-Period-Market/User.Bot.js @@ -43,7 +43,7 @@ This process is going to do the following: - Read the candles from Olivia and produce the bollinger bands out of them. + Read the candles from Candles Volumes and produce the bollinger bands out of them. */ @@ -109,7 +109,7 @@ let fileName = "Data.json"; - let filePathRoot = bot.exchange + "/" + bot.market.baseAsset + "-" + bot.market.quotedAsset + "/" + bot.dataMine + "/" + "AAOlivia"; + let filePathRoot = bot.exchange + "/" + bot.market.baseAsset + "-" + bot.market.quotedAsset + "/" + bot.dataMine + "/" + "Candles-Volumes"; let filePath = filePathRoot + "/Output/" + CANDLES_FOLDER_NAME + "/" + "Multi-Period-Market" + "/" + timeFrame; filePath += '/' + fileName @@ -463,7 +463,7 @@ try { - let reportKey = "AAMasters" + "-" + "AAChris" + "-" + "Multi-Period-Market" + "-" + "dataSet.V1"; + let reportKey = "AAMasters" + "-" + "Bollinger-Bands" + "-" + "Multi-Period-Market" + "-" + "dataSet.V1"; let thisReport = statusDependencies.statusReports.get(reportKey); thisReport.file.lastExecution = bot.processDatetime; diff --git a/README.md b/README.md index b2e66cfb1..9c6c59fe1 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -# I'm Chris, an AA i-Bot! +# I'm Bollinger Bands, an AA i-Bot! # Disclaimer diff --git a/this.bot.config.json b/this.bot.config.json index 4252b243a..41c09ff2e 100644 --- a/this.bot.config.json +++ b/this.bot.config.json @@ -1,6 +1,6 @@ { - "displayName": "Chris", - "codeName": "AAChris", + "displayName": "Bollinger Bands", + "codeName": "Bollinger-Bands", "type": "Indicator Bot", "version": { "major": 1, @@ -8,7 +8,7 @@ "patch": 0 }, "dataMine": "AAMasters", - "profilePicture": "Chris.png", + "profilePicture": "Bollinger Bands.png", "dataSetVersion": "dataSet.V1", "processes": [ { @@ -51,7 +51,7 @@ "statusDependencies": [ { "dataMine": "AAMasters", - "bot": "AAChris", + "bot": "Bollinger-Bands", "botVersion": { "major": 1, "minor": 0 @@ -61,7 +61,7 @@ }, { "dataMine": "AAMasters", - "bot": "AAOlivia", + "bot": "Candles-Volumes", "botVersion": { "major": 1, "minor": 0 @@ -112,7 +112,7 @@ "statusDependencies": [ { "dataMine": "AAMasters", - "bot": "AACharly", + "bot": "Exchange-Raw-Data", "botVersion": { "major": 1, "minor": 0 @@ -122,7 +122,7 @@ }, { "dataMine": "AAMasters", - "bot": "AAOlivia", + "bot": "Candles-Volumes", "botVersion": { "major": 1, "minor": 0 @@ -133,7 +133,7 @@ }, { "dataMine": "AAMasters", - "bot": "AAChris", + "bot": "Bollinger-Bands", "botVersion": { "major": 1, "minor": 0 @@ -149,24 +149,24 @@ "codeName": "Bollinger-Bands", "displayName": "Bollinger Bands", "description": "Bollinger Bands", - "storageAccount": "aachris", + "storageAccount": "Bollinger-Bands", "shareWith": "Public", "dataSets": [ { "codeName": "Multi-Period-Market", "type": "Market Files", "validPeriods": [ "24-hs", "12-hs", "08-hs", "06-hs", "04-hs", "03-hs", "02-hs", "01-hs" ], - "filePath": "AAMasters/AAChris.1.0/AACloud.1.1/@Exchange/dataSet.V1/Output/Bollinger-Bands/Multi-Period-Market/@Period", + "filePath": "AAMasters/Bollinger-Bands.1.0/AACloud.1.1/@Exchange/dataSet.V1/Output/Bollinger-Bands/Multi-Period-Market/@Period", "fileName": "@AssetA_@AssetB.json" }, { "codeName": "Multi-Period-Daily", "type": "Daily Files", "validPeriods": [ "45-min", "40-min", "30-min", "20-min", "15-min", "10-min", "05-min", "04-min", "03-min", "02-min", "01-min" ], - "filePath": "AAMasters/AAChris.1.0/AACloud.1.1/@Exchange/dataSet.V1/Output/Bollinger-Bands/Multi-Period-Daily/@Period/@Year/@Month/@Day", + "filePath": "AAMasters/Bollinger-Bands.1.0/AACloud.1.1/@Exchange/dataSet.V1/Output/Bollinger-Bands/Multi-Period-Daily/@Period/@Year/@Month/@Day", "fileName": "@AssetA_@AssetB.json", "dataRange": { - "filePath": "AAMasters/AAChris.1.0/AACloud.1.1/@Exchange/dataSet.V1/Output/Bollinger-Bands/Multi-Period-Daily", + "filePath": "AAMasters/Bollinger-Bands.1.0/AACloud.1.1/@Exchange/dataSet.V1/Output/Bollinger-Bands/Multi-Period-Daily", "fileName": "Data.Range.@AssetA_@AssetB.json" } } @@ -189,24 +189,24 @@ "codeName": "Percentage-Bandwidth", "displayName": "Percentage Bandwidth", "description": "Percentage Bandwidth", - "storageAccount": "aachris", + "storageAccount": "Bollinger-Bands", "shareWith": "Public", "dataSets": [ { "codeName": "Multi-Period-Market", "type": "Market Files", "validPeriods": [ "24-hs", "12-hs", "08-hs", "06-hs", "04-hs", "03-hs", "02-hs", "01-hs" ], - "filePath": "AAMasters/AAChris.1.0/AACloud.1.1/@Exchange/dataSet.V1/Output/Percentage-Bandwidth/Multi-Period-Market/@Period", + "filePath": "AAMasters/Bollinger-Bands.1.0/AACloud.1.1/@Exchange/dataSet.V1/Output/Percentage-Bandwidth/Multi-Period-Market/@Period", "fileName": "@AssetA_@AssetB.json" }, { "codeName": "Multi-Period-Daily", "type": "Daily Files", "validPeriods": [ "45-min", "40-min", "30-min", "20-min", "15-min", "10-min", "05-min", "04-min", "03-min", "02-min", "01-min" ], - "filePath": "AAMasters/AAChris.1.0/AACloud.1.1/@Exchange/dataSet.V1/Output/Percentage-Bandwidth/Multi-Period-Daily/@Period/@Year/@Month/@Day", + "filePath": "AAMasters/Bollinger-Bands.1.0/AACloud.1.1/@Exchange/dataSet.V1/Output/Percentage-Bandwidth/Multi-Period-Daily/@Period/@Year/@Month/@Day", "fileName": "@AssetA_@AssetB.json", "dataRange": { - "filePath": "AAMasters/AAChris.1.0/AACloud.1.1/@Exchange/dataSet.V1/Output/Percentage-Bandwidth/Multi-Period-Daily", + "filePath": "AAMasters/Bollinger-Bands.1.0/AACloud.1.1/@Exchange/dataSet.V1/Output/Percentage-Bandwidth/Multi-Period-Daily", "fileName": "Data.Range.@AssetA_@AssetB.json" } } From d5944f36cedd5a5df2be39320675150941455a86 Mon Sep 17 00:00:00 2001 From: Luis Fernando Molina Date: Wed, 11 Mar 2020 20:59:46 +0100 Subject: [PATCH 31/40] Rafactoring --- Multi-Period-Daily/User.Bot.js | 8 ++++---- Multi-Period-Market/User.Bot.js | 2 +- this.bot.config.json | 28 ++++++++++++++-------------- 3 files changed, 19 insertions(+), 19 deletions(-) diff --git a/Multi-Period-Daily/User.Bot.js b/Multi-Period-Daily/User.Bot.js index b0a8cf0e0..002e336b7 100644 --- a/Multi-Period-Daily/User.Bot.js +++ b/Multi-Period-Daily/User.Bot.js @@ -87,7 +87,7 @@ /* We look first for Exchange Raw Data in order to get when the market starts. */ - reportKey = "AAMasters" + "-" + "Exchange-Raw-Data" + "-" + "Historic-Trades" + "-" + "dataSet.V1"; + reportKey = "Masters" + "-" + "Exchange-Raw-Data" + "-" + "Historic-Trades" + "-" + "dataSet.V1"; if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] start -> getContextVariables -> reportKey = " + reportKey); } statusReport = statusDependencies.statusReports.get(reportKey); @@ -123,7 +123,7 @@ /* Second, we get the report from Candles Volumes, to know when the marted ends. */ - reportKey = "AAMasters" + "-" + "Candles-Volumes" + "-" + "Multi-Period-Daily" + "-" + "dataSet.V1"; + reportKey = "Masters" + "-" + "Candles-Volumes" + "-" + "Multi-Period-Daily" + "-" + "dataSet.V1"; if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] start -> getContextVariables -> reportKey = " + reportKey); } statusReport = statusDependencies.statusReports.get(reportKey); @@ -158,7 +158,7 @@ /* Finally we get our own Status Report. */ - reportKey = "AAMasters" + "-" + "Bollinger-Bands" + "-" + "Multi-Period-Daily" + "-" + "dataSet.V1"; + reportKey = "Masters" + "-" + "Bollinger-Bands" + "-" + "Multi-Period-Daily" + "-" + "dataSet.V1"; if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] start -> getContextVariables -> reportKey = " + reportKey); } statusReport = statusDependencies.statusReports.get(reportKey); @@ -857,7 +857,7 @@ try { - let reportKey = "AAMasters" + "-" + "Bollinger-Bands" + "-" + "Multi-Period-Daily" + "-" + "dataSet.V1"; + let reportKey = "Masters" + "-" + "Bollinger-Bands" + "-" + "Multi-Period-Daily" + "-" + "dataSet.V1"; let thisReport = statusDependencies.statusReports.get(reportKey); thisReport.file.lastExecution = bot.processDatetime; diff --git a/Multi-Period-Market/User.Bot.js b/Multi-Period-Market/User.Bot.js index 1cbd697da..be189f43e 100644 --- a/Multi-Period-Market/User.Bot.js +++ b/Multi-Period-Market/User.Bot.js @@ -463,7 +463,7 @@ try { - let reportKey = "AAMasters" + "-" + "Bollinger-Bands" + "-" + "Multi-Period-Market" + "-" + "dataSet.V1"; + let reportKey = "Masters" + "-" + "Bollinger-Bands" + "-" + "Multi-Period-Market" + "-" + "dataSet.V1"; let thisReport = statusDependencies.statusReports.get(reportKey); thisReport.file.lastExecution = bot.processDatetime; diff --git a/this.bot.config.json b/this.bot.config.json index 41c09ff2e..3b08b5895 100644 --- a/this.bot.config.json +++ b/this.bot.config.json @@ -7,7 +7,7 @@ "minor": 0, "patch": 0 }, - "dataMine": "AAMasters", + "dataMine": "Masters", "profilePicture": "Bollinger Bands.png", "dataSetVersion": "dataSet.V1", "processes": [ @@ -50,7 +50,7 @@ ], "statusDependencies": [ { - "dataMine": "AAMasters", + "dataMine": "Masters", "bot": "Bollinger-Bands", "botVersion": { "major": 1, @@ -60,7 +60,7 @@ "dataSetVersion": "dataSet.V1" }, { - "dataMine": "AAMasters", + "dataMine": "Masters", "bot": "Candles-Volumes", "botVersion": { "major": 1, @@ -111,7 +111,7 @@ ], "statusDependencies": [ { - "dataMine": "AAMasters", + "dataMine": "Masters", "bot": "Exchange-Raw-Data", "botVersion": { "major": 1, @@ -121,7 +121,7 @@ "dataSetVersion": "dataSet.V1" }, { - "dataMine": "AAMasters", + "dataMine": "Masters", "bot": "Candles-Volumes", "botVersion": { "major": 1, @@ -132,7 +132,7 @@ "waitUntilNextUpdate": true }, { - "dataMine": "AAMasters", + "dataMine": "Masters", "bot": "Bollinger-Bands", "botVersion": { "major": 1, @@ -156,17 +156,17 @@ "codeName": "Multi-Period-Market", "type": "Market Files", "validPeriods": [ "24-hs", "12-hs", "08-hs", "06-hs", "04-hs", "03-hs", "02-hs", "01-hs" ], - "filePath": "AAMasters/Bollinger-Bands.1.0/AACloud.1.1/@Exchange/dataSet.V1/Output/Bollinger-Bands/Multi-Period-Market/@Period", + "filePath": "Masters/Bollinger-Bands.1.0/AACloud.1.1/@Exchange/dataSet.V1/Output/Bollinger-Bands/Multi-Period-Market/@Period", "fileName": "@AssetA_@AssetB.json" }, { "codeName": "Multi-Period-Daily", "type": "Daily Files", "validPeriods": [ "45-min", "40-min", "30-min", "20-min", "15-min", "10-min", "05-min", "04-min", "03-min", "02-min", "01-min" ], - "filePath": "AAMasters/Bollinger-Bands.1.0/AACloud.1.1/@Exchange/dataSet.V1/Output/Bollinger-Bands/Multi-Period-Daily/@Period/@Year/@Month/@Day", + "filePath": "Masters/Bollinger-Bands.1.0/AACloud.1.1/@Exchange/dataSet.V1/Output/Bollinger-Bands/Multi-Period-Daily/@Period/@Year/@Month/@Day", "fileName": "@AssetA_@AssetB.json", "dataRange": { - "filePath": "AAMasters/Bollinger-Bands.1.0/AACloud.1.1/@Exchange/dataSet.V1/Output/Bollinger-Bands/Multi-Period-Daily", + "filePath": "Masters/Bollinger-Bands.1.0/AACloud.1.1/@Exchange/dataSet.V1/Output/Bollinger-Bands/Multi-Period-Daily", "fileName": "Data.Range.@AssetA_@AssetB.json" } } @@ -180,7 +180,7 @@ } ], "plotter": { - "dataMine": "AAMasters", + "dataMine": "Masters", "codeName": "PlottersBollingerBands", "moduleName": "BollingerBands" } @@ -196,17 +196,17 @@ "codeName": "Multi-Period-Market", "type": "Market Files", "validPeriods": [ "24-hs", "12-hs", "08-hs", "06-hs", "04-hs", "03-hs", "02-hs", "01-hs" ], - "filePath": "AAMasters/Bollinger-Bands.1.0/AACloud.1.1/@Exchange/dataSet.V1/Output/Percentage-Bandwidth/Multi-Period-Market/@Period", + "filePath": "Masters/Bollinger-Bands.1.0/AACloud.1.1/@Exchange/dataSet.V1/Output/Percentage-Bandwidth/Multi-Period-Market/@Period", "fileName": "@AssetA_@AssetB.json" }, { "codeName": "Multi-Period-Daily", "type": "Daily Files", "validPeriods": [ "45-min", "40-min", "30-min", "20-min", "15-min", "10-min", "05-min", "04-min", "03-min", "02-min", "01-min" ], - "filePath": "AAMasters/Bollinger-Bands.1.0/AACloud.1.1/@Exchange/dataSet.V1/Output/Percentage-Bandwidth/Multi-Period-Daily/@Period/@Year/@Month/@Day", + "filePath": "Masters/Bollinger-Bands.1.0/AACloud.1.1/@Exchange/dataSet.V1/Output/Percentage-Bandwidth/Multi-Period-Daily/@Period/@Year/@Month/@Day", "fileName": "@AssetA_@AssetB.json", "dataRange": { - "filePath": "AAMasters/Bollinger-Bands.1.0/AACloud.1.1/@Exchange/dataSet.V1/Output/Percentage-Bandwidth/Multi-Period-Daily", + "filePath": "Masters/Bollinger-Bands.1.0/AACloud.1.1/@Exchange/dataSet.V1/Output/Percentage-Bandwidth/Multi-Period-Daily", "fileName": "Data.Range.@AssetA_@AssetB.json" } } @@ -220,7 +220,7 @@ } ], "plotter": { - "dataMine": "AAMasters", + "dataMine": "Masters", "codeName": "PlottersBollingerBands", "moduleName": "PercentageBandwidth" } From edd3133f1ea0aa0c84e4a1a29cbe67416ca1a707 Mon Sep 17 00:00:00 2001 From: Luis Fernando Molina Date: Sat, 14 Mar 2020 11:28:30 +0100 Subject: [PATCH 32/40] Logging Improved --- Multi-Period-Daily/User.Bot.js | 3 ++- Multi-Period-Market/User.Bot.js | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/Multi-Period-Daily/User.Bot.js b/Multi-Period-Daily/User.Bot.js index 002e336b7..5b9af5b85 100644 --- a/Multi-Period-Daily/User.Bot.js +++ b/Multi-Period-Daily/User.Bot.js @@ -1,4 +1,4 @@ -exports.newUserBot = function newUserBot(bot, logger, COMMONS, UTILITIES, fileStorage) { +exports.newUserBot = function newUserBot(bot, logger, COMMONS, UTILITIES, FILE_STORAGE) { const FULL_LOG = true; const INTENSIVE_LOG = false; @@ -21,6 +21,7 @@ }; let utilities = UTILITIES.newCloudUtilities(bot, logger); + let fileStorage = FILE_STORAGE.newFileStorage(logger); let statusDependencies; let beginingOfMarket diff --git a/Multi-Period-Market/User.Bot.js b/Multi-Period-Market/User.Bot.js index be189f43e..e85e3a4b1 100644 --- a/Multi-Period-Market/User.Bot.js +++ b/Multi-Period-Market/User.Bot.js @@ -1,4 +1,4 @@ -exports.newUserBot = function newUserBot(bot, logger, COMMONS, UTILITIES, fileStorage) { +exports.newUserBot = function newUserBot(bot, logger, COMMONS, UTILITIES, FILE_STORAGE) { const FULL_LOG = true; const LOG_FILE_CONTENT = false; @@ -17,6 +17,7 @@ }; let statusDependencies; + let fileStorage = FILE_STORAGE.newFileStorage(logger); return thisObject; From 9c2df64aae1afb45e9fb901fc539c703f48a3481 Mon Sep 17 00:00:00 2001 From: Luis Fernando Molina Date: Sat, 14 Mar 2020 17:21:57 +0100 Subject: [PATCH 33/40] Bug Fixed --- Multi-Period-Daily/User.Bot.js | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/Multi-Period-Daily/User.Bot.js b/Multi-Period-Daily/User.Bot.js index 5b9af5b85..a8e65157a 100644 --- a/Multi-Period-Daily/User.Bot.js +++ b/Multi-Period-Daily/User.Bot.js @@ -88,7 +88,7 @@ /* We look first for Exchange Raw Data in order to get when the market starts. */ - reportKey = "Masters" + "-" + "Exchange-Raw-Data" + "-" + "Historic-Trades" + "-" + "dataSet.V1"; + reportKey = "Masters" + "-" + "Exchange-Raw-Data" + "-" + "Historic-OHLCVs" + "-" + "dataSet.V1"; if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] start -> getContextVariables -> reportKey = " + reportKey); } statusReport = statusDependencies.statusReports.get(reportKey); @@ -255,8 +255,6 @@ try { - logger.newInternalLoop(bot.codeName, bot.process); - if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] start -> buildBands -> advanceTime -> Entering function."); } processDate = new Date(processDate.valueOf() + ONE_DAY_IN_MILISECONDS); @@ -866,6 +864,7 @@ thisReport.file.beginingOfMarket = beginingOfMarket.toUTCString() thisReport.save(callBack); + logger.newInternalLoop(bot.codeName, bot.process, lastFileDate); } catch (err) { logger.write(MODULE_NAME, "[ERROR] start -> writeStatusReport -> err = " + err.stack); From d395753e35b4025fbdaddc4bd70dde36dbf17449 Mon Sep 17 00:00:00 2001 From: Luis Fernando Molina Date: Thu, 19 Mar 2020 22:16:52 +0100 Subject: [PATCH 34/40] percentage implemented --- Multi-Period-Daily/User.Bot.js | 12 +++++++++++- Multi-Period-Market/User.Bot.js | 10 ++++++++++ 2 files changed, 21 insertions(+), 1 deletion(-) diff --git a/Multi-Period-Daily/User.Bot.js b/Multi-Period-Daily/User.Bot.js index a8e65157a..3ad65642f 100644 --- a/Multi-Period-Daily/User.Bot.js +++ b/Multi-Period-Daily/User.Bot.js @@ -247,6 +247,9 @@ let n; processDate = new Date(contextVariables.lastBandFile.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(processDate.valueOf()) + let lastDate = new Date() + if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] start -> buildBands -> processDate = " + processDate); } advanceTime(); @@ -275,6 +278,11 @@ } + /* Telling the world we are alive and doing well */ + let currentDateString = processDate.getUTCFullYear() + '-' + utilities.pad(processDate.getUTCMonth() + 1, 2) + '-' + utilities.pad(processDate.getUTCDate(), 2); + let currentDate = new Date(processDate) + bot.processHeartBeat(currentDateString, global.getPercentage(fromDate, currentDate, lastDate)) + periodsLoop(); } catch (err) { @@ -864,7 +872,9 @@ thisReport.file.beginingOfMarket = beginingOfMarket.toUTCString() thisReport.save(callBack); - logger.newInternalLoop(bot.codeName, bot.process, lastFileDate); + if (global.areEqualDates(lastFileDate, new Date()) === false) { + logger.newInternalLoop(bot.codeName, bot.process, lastFileDate); + } } catch (err) { logger.write(MODULE_NAME, "[ERROR] start -> writeStatusReport -> err = " + err.stack); diff --git a/Multi-Period-Market/User.Bot.js b/Multi-Period-Market/User.Bot.js index e85e3a4b1..f5bd3cb5f 100644 --- a/Multi-Period-Market/User.Bot.js +++ b/Multi-Period-Market/User.Bot.js @@ -17,6 +17,7 @@ }; let statusDependencies; + let utilities = UTILITIES.newCloudUtilities(bot, logger); let fileStorage = FILE_STORAGE.newFileStorage(logger); return thisObject; @@ -470,6 +471,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); From 4bda68fd2bc54ec0a8831370f190f32dd4e866a4 Mon Sep 17 00:00:00 2001 From: Luis Fernando Molina Date: Fri, 20 Mar 2020 11:02:27 +0100 Subject: [PATCH 35/40] logging improved --- Multi-Period-Daily/User.Bot.js | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/Multi-Period-Daily/User.Bot.js b/Multi-Period-Daily/User.Bot.js index 3ad65642f..8c27945fd 100644 --- a/Multi-Period-Daily/User.Bot.js +++ b/Multi-Period-Daily/User.Bot.js @@ -281,8 +281,12 @@ /* Telling the world we are alive and doing well */ let currentDateString = processDate.getUTCFullYear() + '-' + utilities.pad(processDate.getUTCMonth() + 1, 2) + '-' + utilities.pad(processDate.getUTCDate(), 2); let currentDate = new Date(processDate) - bot.processHeartBeat(currentDateString, global.getPercentage(fromDate, currentDate, lastDate)) + 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); + } periodsLoop(); } catch (err) { @@ -872,9 +876,6 @@ thisReport.file.beginingOfMarket = beginingOfMarket.toUTCString() thisReport.save(callBack); - if (global.areEqualDates(lastFileDate, new Date()) === false) { - logger.newInternalLoop(bot.codeName, bot.process, lastFileDate); - } } catch (err) { logger.write(MODULE_NAME, "[ERROR] start -> writeStatusReport -> err = " + err.stack); From 11645a9bdcd6a7ad9d256b2d1b94c2c372765752 Mon Sep 17 00:00:00 2001 From: Luis Fernando Molina Date: Fri, 12 Jun 2020 12:45:51 +0200 Subject: [PATCH 36/40] Coda Mantainance --- Multi-Period-Daily/User.Bot.js | 8 ++++---- Multi-Period-Market/User.Bot.js | 2 +- Project.njsproj.user | 6 ++++++ this.bot.config.json | 32 +++----------------------------- 4 files changed, 14 insertions(+), 34 deletions(-) create mode 100644 Project.njsproj.user diff --git a/Multi-Period-Daily/User.Bot.js b/Multi-Period-Daily/User.Bot.js index 8c27945fd..08dc3de97 100644 --- a/Multi-Period-Daily/User.Bot.js +++ b/Multi-Period-Daily/User.Bot.js @@ -88,7 +88,7 @@ /* We look first for Exchange Raw Data in order to get when the market starts. */ - reportKey = "Masters" + "-" + "Exchange-Raw-Data" + "-" + "Historic-OHLCVs" + "-" + "dataSet.V1"; + reportKey = "Masters" + "-" + "Exchange-Raw-Data" + "-" + "Historic-OHLCVs" if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] start -> getContextVariables -> reportKey = " + reportKey); } statusReport = statusDependencies.statusReports.get(reportKey); @@ -124,7 +124,7 @@ /* Second, we get the report from Candles Volumes, to know when the marted ends. */ - reportKey = "Masters" + "-" + "Candles-Volumes" + "-" + "Multi-Period-Daily" + "-" + "dataSet.V1"; + reportKey = "Masters" + "-" + "Candles-Volumes" + "-" + "Multi-Period-Daily" if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] start -> getContextVariables -> reportKey = " + reportKey); } statusReport = statusDependencies.statusReports.get(reportKey); @@ -159,7 +159,7 @@ /* Finally we get our own Status Report. */ - reportKey = "Masters" + "-" + "Bollinger-Bands" + "-" + "Multi-Period-Daily" + "-" + "dataSet.V1"; + reportKey = "Masters" + "-" + "Bollinger-Bands" + "-" + "Multi-Period-Daily" if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] start -> getContextVariables -> reportKey = " + reportKey); } statusReport = statusDependencies.statusReports.get(reportKey); @@ -868,7 +868,7 @@ try { - let reportKey = "Masters" + "-" + "Bollinger-Bands" + "-" + "Multi-Period-Daily" + "-" + "dataSet.V1"; + let reportKey = "Masters" + "-" + "Bollinger-Bands" + "-" + "Multi-Period-Daily" let thisReport = statusDependencies.statusReports.get(reportKey); thisReport.file.lastExecution = bot.processDatetime; diff --git a/Multi-Period-Market/User.Bot.js b/Multi-Period-Market/User.Bot.js index f5bd3cb5f..820424630 100644 --- a/Multi-Period-Market/User.Bot.js +++ b/Multi-Period-Market/User.Bot.js @@ -465,7 +465,7 @@ try { - let reportKey = "Masters" + "-" + "Bollinger-Bands" + "-" + "Multi-Period-Market" + "-" + "dataSet.V1"; + let reportKey = "Masters" + "-" + "Bollinger-Bands" + "-" + "Multi-Period-Market" let thisReport = statusDependencies.statusReports.get(reportKey); thisReport.file.lastExecution = bot.processDatetime; diff --git a/Project.njsproj.user b/Project.njsproj.user new file mode 100644 index 000000000..db8622989 --- /dev/null +++ b/Project.njsproj.user @@ -0,0 +1,6 @@ + + + + Debug|Any CPU + + \ No newline at end of file diff --git a/this.bot.config.json b/this.bot.config.json index 3b08b5895..547ac0a0e 100644 --- a/this.bot.config.json +++ b/this.bot.config.json @@ -9,7 +9,6 @@ }, "dataMine": "Masters", "profilePicture": "Bollinger Bands.png", - "dataSetVersion": "dataSet.V1", "processes": [ { "name": "Multi-Period-Market", @@ -52,22 +51,12 @@ { "dataMine": "Masters", "bot": "Bollinger-Bands", - "botVersion": { - "major": 1, - "minor": 0 - }, - "process": "Multi-Period-Market", - "dataSetVersion": "dataSet.V1" + "process": "Multi-Period-Market" }, { "dataMine": "Masters", "bot": "Candles-Volumes", - "botVersion": { - "major": 1, - "minor": 0 - }, "process": "Multi-Period-Market", - "dataSetVersion": "dataSet.V1", "waitUntilNextUpdate": true } ] @@ -113,33 +102,18 @@ { "dataMine": "Masters", "bot": "Exchange-Raw-Data", - "botVersion": { - "major": 1, - "minor": 0 - }, - "process": "Historic-Trades", - "dataSetVersion": "dataSet.V1" + "process": "Historic-Trades" }, { "dataMine": "Masters", "bot": "Candles-Volumes", - "botVersion": { - "major": 1, - "minor": 0 - }, "process": "Multi-Period-Daily", - "dataSetVersion": "dataSet.V1", "waitUntilNextUpdate": true }, { "dataMine": "Masters", "bot": "Bollinger-Bands", - "botVersion": { - "major": 1, - "minor": 0 - }, - "process": "Multi-Period-Daily", - "dataSetVersion": "dataSet.V1" + "process": "Multi-Period-Daily" } ] } From 0b03d82de8eaf2aa8d6283e54b3911395216b7ef Mon Sep 17 00:00:00 2001 From: Luis Fernando Molina Date: Sat, 25 Jul 2020 20:04:41 +0200 Subject: [PATCH 37/40] Create Commons.js --- Commons.js | 1 + 1 file changed, 1 insertion(+) create mode 100644 Commons.js diff --git a/Commons.js b/Commons.js new file mode 100644 index 000000000..f34bae6c7 --- /dev/null +++ b/Commons.js @@ -0,0 +1 @@ +// Nothing here to run \ No newline at end of file From beae4ebff15a40c372f4d1c4d454218b4e660909 Mon Sep 17 00:00:00 2001 From: Luis Fernando Molina Date: Tue, 18 Aug 2020 14:12:21 +0200 Subject: [PATCH 38/40] Update User.Bot.js --- Multi-Period-Daily/User.Bot.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Multi-Period-Daily/User.Bot.js b/Multi-Period-Daily/User.Bot.js index 08dc3de97..64b32dfc0 100644 --- a/Multi-Period-Daily/User.Bot.js +++ b/Multi-Period-Daily/User.Bot.js @@ -826,7 +826,7 @@ let dataRange = { begin: pBegin.valueOf(), - end: pEnd.valueOf() + end: pEnd.valueOf() + ONE_DAY_IN_MILISECONDS }; let fileContent = JSON.stringify(dataRange); From 2fdf0bae97b4373927836e3a94793ef95f60a8f1 Mon Sep 17 00:00:00 2001 From: Luis Fernando Molina Date: Wed, 7 Oct 2020 23:41:15 +0200 Subject: [PATCH 39/40] Deep Scan Medium Severity --- Multi-Period-Daily/User.Bot.js | 4 ++-- Multi-Period-Market/User.Bot.js | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/Multi-Period-Daily/User.Bot.js b/Multi-Period-Daily/User.Bot.js index 64b32dfc0..c9918783d 100644 --- a/Multi-Period-Daily/User.Bot.js +++ b/Multi-Period-Daily/User.Bot.js @@ -587,7 +587,7 @@ let fileContent = ""; - for (i = 0; i < pBands.length; i++) { + for (let i = 0; i < pBands.length; i++) { let band = pBands[i]; @@ -657,7 +657,7 @@ let fileContent = ""; - for (i = 0; i < pPercentageBandwidths.length; i++) { + for (let i = 0; i < pPercentageBandwidths.length; i++) { let pB = pPercentageBandwidths[i]; diff --git a/Multi-Period-Market/User.Bot.js b/Multi-Period-Market/User.Bot.js index 820424630..061e3e56f 100644 --- a/Multi-Period-Market/User.Bot.js +++ b/Multi-Period-Market/User.Bot.js @@ -280,7 +280,7 @@ let fileContent = ""; - for (i = 0; i < pBands.length; i++) { + for (let i = 0; i < pBands.length; i++) { let band = pBands[i]; @@ -350,7 +350,7 @@ let fileContent = ""; - for (i = 0; i < pPercentageBandwidths.length; i++) { + for (let i = 0; i < pPercentageBandwidths.length; i++) { let pB = pPercentageBandwidths[i]; From a3134d9b14133637597930b2d11a587fdd447764 Mon Sep 17 00:00:00 2001 From: Luis Fernando Molina Date: Fri, 20 Nov 2020 12:51:03 +0100 Subject: [PATCH 40/40] Data-Storage Structure Multi Project --- Multi-Period-Daily/User.Bot.js | 4 ++-- Multi-Period-Market/User.Bot.js | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Multi-Period-Daily/User.Bot.js b/Multi-Period-Daily/User.Bot.js index c9918783d..3b9e1564d 100644 --- a/Multi-Period-Daily/User.Bot.js +++ b/Multi-Period-Daily/User.Bot.js @@ -340,7 +340,7 @@ let dateForPath = previousDay.getUTCFullYear() + '/' + utilities.pad(previousDay.getUTCMonth() + 1, 2) + '/' + utilities.pad(previousDay.getUTCDate(), 2); let fileName = "Data.json" - let filePathRoot = bot.exchange + "/" + bot.market.baseAsset + "-" + bot.market.quotedAsset + "/" + bot.dataMine + "/" + "Candles-Volumes"; + let filePathRoot = 'Project/' + bot.project + "/" + bot.mineType + "/" + bot.dataMine + "/" + "Candles-Volumes" + '/' + bot.exchange + "/" + bot.market.baseAsset + "-" + bot.market.quotedAsset let filePath = filePathRoot + "/Output/" + CANDLES_FOLDER_NAME + '/' + "Multi-Period-Daily" + "/" + timeFrame + "/" + dateForPath; filePath += '/' + fileName @@ -379,7 +379,7 @@ let dateForPath = processDate.getUTCFullYear() + '/' + utilities.pad(processDate.getUTCMonth() + 1, 2) + '/' + utilities.pad(processDate.getUTCDate(), 2); let fileName = "Data.json" - let filePathRoot = bot.exchange + "/" + bot.market.baseAsset + "-" + bot.market.quotedAsset + "/" + bot.dataMine + "/" + "Candles-Volumes"; + let filePathRoot = 'Project/' + bot.project + "/" + bot.mineType + "/" + bot.dataMine + "/" + "Candles-Volumes" + '/' + bot.exchange + "/" + bot.market.baseAsset + "-" + bot.market.quotedAsset let filePath = filePathRoot + "/Output/" + CANDLES_FOLDER_NAME + '/' + "Multi-Period-Daily" + "/" + timeFrame + "/" + dateForPath; filePath += '/' + fileName diff --git a/Multi-Period-Market/User.Bot.js b/Multi-Period-Market/User.Bot.js index 061e3e56f..0de295c7a 100644 --- a/Multi-Period-Market/User.Bot.js +++ b/Multi-Period-Market/User.Bot.js @@ -111,7 +111,7 @@ let fileName = "Data.json"; - let filePathRoot = bot.exchange + "/" + bot.market.baseAsset + "-" + bot.market.quotedAsset + "/" + bot.dataMine + "/" + "Candles-Volumes"; + let filePathRoot = 'Project/' + bot.project + "/" + bot.mineType + "/" + bot.dataMine + "/" + "Candles-Volumes" + '/' + bot.exchange + "/" + bot.market.baseAsset + "-" + bot.market.quotedAsset let filePath = filePathRoot + "/Output/" + CANDLES_FOLDER_NAME + "/" + "Multi-Period-Market" + "/" + timeFrame; filePath += '/' + fileName