From 784e39e9717730996eaa03ff6173fe89f122385c Mon Sep 17 00:00:00 2001 From: Luis Fernando Molina Date: Wed, 20 Feb 2019 09:25:41 +0100 Subject: [PATCH 01/11] 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 02/11] 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 03/11] 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 04/11] 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 05/11] 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 06/11] 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 07/11] 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 08/11] 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 09/11] 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 10/11] 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 11/11] 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) {