From d2b72fea61cac18fa5cc298af36f0c2050040f8e Mon Sep 17 00:00:00 2001 From: Luis Fernando Molina Date: Tue, 6 Mar 2018 11:36:32 +0100 Subject: [PATCH] Datasource Implemented --- .vs/AACloudPlatform/v15/.suo | Bin 68096 -> 69120 bytes AACloudPlatform.njsproj | 3 + Context.js | 1 - Datasource.js | 362 +++++++++++++++++++++++++++++++++++ 4 files changed, 365 insertions(+), 1 deletion(-) create mode 100644 Datasource.js diff --git a/.vs/AACloudPlatform/v15/.suo b/.vs/AACloudPlatform/v15/.suo index 4703b39c6ac18d948ceec953c4e424ad6beeab44..871593d713a4f8cd5e86b0f3ff5392e3e20a58e4 100644 GIT binary patch delta 1941 zcmdUve^69a6vywmZx?o1SXp3Ui6s|ggrot+0433V=#JHl)3{_x6Jsz)1v2q#7v)E> zL}(T%%UOh+9EXR@m_v?o?Z?Da%Q#LBmQgrplcr^5KS=8j{)m~_&I>duDyP5d&V1he zb?&*}ch9-k~tCb`;dNnnrjW z6STGFM;T+&fk2>|>N|)?VjaG$O@?Q@&h$=Rp*`B4b@`93f)_m$L5AT3tqo|YUO-rg zpQ#^3bttijh$f6gEMX#a#BD?zVI~?01EGqDr#b=Mx^!&=wQ{`9g%IO)#^D#bJHxCr zvX;1qsK#XzVBe%Cji0&Np5Yry*OMo@4v zycu3Vx2YN0#iXg3Yq$Q@q`42G)Xh}NW;a%iaUdo|rw*!$#D$n7jk$$dPZO;~8$pwS zX#w|t2c1?IJSN=M=OrbP4;H#O)S)}6Ip{vJS`&d&NmGV$YEE$akn8Goks>1H8VnXC z28qP9PbDRjD-}Ulk!uy!+$QN31u1uPly}66SjSZuyq9yqw@*tZRn^?0D!dL#lSbLV zm3%%cwIHBXHEwR@Gy0%hOg>_WQZ{mI*$^XQ>I#hfBq??IPRUu`*W2O7XMxE3o0UwL;!q0e@#; zSVI}9X0ML*WAWHR4D>yqFLo8zR=R6SN-?856_0crqIl2D<)iWRQrzf0jD=%KWSfr@ zLo0>wX*kTkd@=TVlX0|r73%jsEd2Xq>EGWK1J#iB@t9`&y@t+cPU2kSt&-(W&k7z7(bzf8uXsq6z^cgbOnl8Ey-}R8oCgrERB^@pD~*l{^VV) zSb9&c$ znS7><$!6|gmN5>-%M>zsOct|?u|$-x^)tn2bKI@H%3iRqVL27_H5B23V|8{BN7gaz z%zBh$9$A#WAUn!CyXED~TA{wjE~=bOj0$hDSH_(>-6WcGg0$B-S74VbN+Xzcb&!F! z+zxtQ&gOOqZR@{n=8sU`3%qGb-!gA4A8}8>v2#8klb&)lR@zEiWn1`N%~&B~6|K~c zwu%n>L!49S!qtkaSrK+G34YjYGF?dmuhhGxJMc3Zs~yHm!dN4WX8YlqA>}`IL}#N% zdUpP#9DY~`eAgU6(?%!8qY3GZ{wgLKG5G%$=Y6~2A`8++sq`VskRv((3R8cFRJpuu9KzRr=WCKHNG?f0puAIQYX&)Q)g z@XN^MS~8BQbJESDPWi-W7a7L|?isASG3SJUZ?Xy758b!KnmcQ)UHoEPJoQDnHDU`( zBb%*?U#yW-7J_UseLRSRKNQGqV<4D)AsISrl5s{@*U1|$gcDxWp6it6FCmI0^o;Q7 zCDwVol?cL|3dos+m&hmS{FfTk^I>`MOaV=e5q)dNo|7x&H{X{E8T!#A)JzAah8^^@ zf>iUfXj0s_(ZB4@MV*D_{p<&rIsKS!-Z59iDs-I<5Nj;$y7(VLGxu=iYdp1Gm~fU! K--dHHQTr!OuI&{7 diff --git a/AACloudPlatform.njsproj b/AACloudPlatform.njsproj index 081717a47..6f6b1681b 100644 --- a/AACloudPlatform.njsproj +++ b/AACloudPlatform.njsproj @@ -25,6 +25,9 @@ Code + + Code + Code diff --git a/Context.js b/Context.js index 10833d0e8..867466340 100644 --- a/Context.js +++ b/Context.js @@ -376,7 +376,6 @@ } } - } catch (err) { logger.write("[ERROR] saveAll -> Error = " + err.message); callBackFunction("Operation Failed."); diff --git a/Datasource.js b/Datasource.js new file mode 100644 index 000000000..aadf5fd5b --- /dev/null +++ b/Datasource.js @@ -0,0 +1,362 @@ +exports.newDatasource = function newDatasource(BOT) { + + /* + + This module allows trading bots to access information stored at the cloud storage. + + */ + + const MODULE_NAME = "Datasource"; + + thisObject = { + initialize: initialize, + candlesFiles: new Map, + candlesMap: new Map, + stairsFiles: new Map, + stairsMap: new Map + }; + + let bot = BOT; + + const DEBUG_MODULE = require('./Debug Log'); + const logger = DEBUG_MODULE.newDebugLog(); + logger.fileName = MODULE_NAME; + + return thisObject; + + function initialize(callBackFunction) { + + try { + + getCandles(onCandlesReady); + + function onCandlesReady() {getPatterns(onPatternsReady); } + + function onDailyFileonPatternsReadysReady() {callBackFunction();} + + } catch (err) { + + logger.write("[ERROR] initialize -> err = " + err); + callBackFunction("Operation Failed."); + } + } + + function getCandles(callBack) { + + try { + + /* + + We will read several files with candles for the current day. We will use these files as an input + to make trading decitions later. + + */ + + getMarketFiles(); + + function getMarketFiles() { + + try { + /* Now we will get the market files */ + + for (i = 0; i < marketFilesPeriods.length; i++) { + + let periodTime = marketFilesPeriods[i][0]; + let periodName = marketFilesPeriods[i][1]; + + getFile(oliviaAzureFileStorage, "@AssetA_@AssetB.json", "@Exchange/Output/Candles/Multi-Period-Market/@Period", periodName, undefined, onFileReceived); + + function onFileReceived(file) { + + thisObject.candlesFiles.set(periodName, file); + + if (thisObject.candlesFiles.size === marketFilesPeriods.length) { + + getDailyFiles(); + + } + } + } + } catch (err) { + logger.write("[ERROR] getCandles -> getMarketFiles -> err = " + err); + callBack("Operation Failed."); + } + } + + function getDailyFiles(callBack) { + + try { + for (i = 0; i < dailyFilePeriods.length; i++) { + + let periodTime = dailyFilePeriods[i][0]; + let periodName = dailyFilePeriods[i][1]; + + getFile(oliviaAzureFileStorage, "@AssetA_@AssetB.json", "@Exchange/Output/Candles/Multi-Period-Daily/@Period/@Year/@Month/@Day", periodName, processDatetime, onFileReceived); + + function onFileReceived(file) { + + thisObject.candlesFiles.set(periodName, file); + + if (thisObject.candlesFiles.size === dailyFilePeriods.length + marketFilesPeriods.length) { + + getCandlesWeAreIn(); + + } + } + } + } catch (err) { + logger.write("[ERROR] getCandles -> getDailyFiles -> err = " + err); + callBack("Operation Failed."); + } + } + + function getCandlesWeAreIn() { + + try { + let counter = 0; + + thisObject.candlesFiles.forEach(getCurrentCandles); + + function getCurrentCandles(pCandlesFile, pPeriodName, map) { + + let candlesArray = []; + + for (i = 0; i < pCandlesFile.length; i++) { + + let candle = { + open: undefined, + close: undefined, + min: 10000000000000, + max: 0, + begin: undefined, + end: undefined, + direction: undefined + }; + + candle.min = pCandlesFile[i][0]; + candle.max = pCandlesFile[i][1]; + + candle.open = pCandlesFile[i][2]; + candle.close = pCandlesFile[i][3]; + + candle.begin = pCandlesFile[i][4]; + candle.end = pCandlesFile[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'; } + + /* We are going to store the last 10 candles per period, which will give the bot a good sense of where it is. */ + + let timePeriod = candle.end - candle.begin + 1; // In miliseconds. (remember each candle spans a period minus one milisecond) + + if (candle.begin >= processDatetime.valueOf() - timePeriod * 10 && candle.end <= processDatetime.valueOf()) { + + candlesArray.push(candle); + + } + } + + thisObject.candlesMap.set(pPeriodName, candlesArray); + + counter++; + + if (counter === thisObject.candlesFiles.size) { + + callBack(); + + } + } + } catch (err) { + logger.write("[ERROR] getCandles -> getCandlesWeAreIn -> err = " + err); + callBack("Operation Failed."); + } + } + + } catch (err) { + logger.write("[ERROR] getCandles -> err = " + err); + callBack("Operation Failed."); + } + } + + function getPatterns(callBack) { + + try { + /* + + We will read several files with pattern calculations for the current day. We will use these files as an input + to make trading decitions later. + + */ + + getMarketFiles(); + + function getMarketFiles() { + + try { + /* Now we will get the market files */ + + for (i = 0; i < marketFilesPeriods.length; i++) { + + let periodTime = marketFilesPeriods[i][0]; + let periodName = marketFilesPeriods[i][1]; + + getFile(tomAzureFileStorage, "@AssetA_@AssetB.json", "@Exchange/Tom/dataSet.V1/Output/Candle-Stairs/Multi-Period-Market/@Period", periodName, undefined, onFileReceived); + + function onFileReceived(file) { + + thisObject.stairsFiles.set(periodName, file); + + if (thisObject.stairsFiles.size === marketFilesPeriods.length) { + + getDailyFiles(); + + } + } + } + } catch (err) { + logger.write("[ERROR] getPatterns -> getMarketFiles -> err = " + err); + callBack("Operation Failed."); + } + } + + function getDailyFiles() { + + try { + for (i = 0; i < dailyFilePeriods.length; i++) { + + let periodTime = dailyFilePeriods[i][0]; + let periodName = dailyFilePeriods[i][1]; + + getFile(tomAzureFileStorage, "@AssetA_@AssetB.json", "@Exchange/Tom/dataSet.V1/Output/Candle-Stairs/Multi-Period-Daily/@Period/@Year/@Month/@Day", periodName, processDatetime, onFileReceived); + + function onFileReceived(file) { + + thisObject.stairsFiles.set(periodName, file); + + if (thisObject.stairsFiles.size === dailyFilePeriods.length + marketFilesPeriods.length) { + + getStairsWeAreIn(); + + } + } + } + } catch (err) { + logger.write("[ERROR] getPatterns -> getDailyFiles -> err = " + err); + callBack("Operation Failed."); + } + } + + function getStairsWeAreIn() { + + try { + let counter = 0; + + thisObject.stairsFiles.forEach(getCurrentStairs); + + function getCurrentStairs(pStairsFile, pPeriodName, map) { + + for (i = 0; i < pStairsFile.length; i++) { + + let 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.open = pStairsFile[i][0]; + stairs.close = pStairsFile[i][1]; + + stairs.min = pStairsFile[i][2]; + stairs.max = pStairsFile[i][3]; + + stairs.begin = pStairsFile[i][4]; + stairs.end = pStairsFile[i][5]; + + stairs.direction = pStairsFile[i][6]; + stairs.candleCount = pStairsFile[i][7]; + + stairs.firstMin = pStairsFile[i][8]; + stairs.firstMax = pStairsFile[i][9]; + + stairs.lastMin = pStairsFile[i][10]; + stairs.lastMax = pStairsFile[i][11]; + + if (processDatetime.valueOf() >= stairs.begin && processDatetime.valueOf() <= stairs.end) { + + thisObject.stairsMap.set(pPeriodName, stairs); + + } + } + + counter++; + + if (counter === thisObject.stairsFiles.size) { + + callBack(); + + } + } + } catch (err) { + logger.write("[ERROR] getPatterns -> getStairsWeAreIn -> err = " + err); + callBack("Operation Failed."); + } + } + + } catch (err) { + logger.write("[ERROR] getPatterns -> err = " + err); + callBack("Operation Failed."); + } + } + + function getFile(pFileService, pFileName, pFilePath, pPeriodName, pDatetime, callBackFunction) { + try { + pFileName = pFileName.replace("@AssetA", market.assetA); + pFileName = pFileName.replace("@AssetB", market.assetB); + + pFilePath = pFilePath.replace("@Exchange", EXCHANGE_NAME); + pFilePath = pFilePath.replace("@Period", pPeriodName); + + if (pDatetime !== undefined) { + + pFilePath = pFilePath.replace("@Year", pDatetime.getUTCFullYear()); + pFilePath = pFilePath.replace("@Month", utilities.pad(pDatetime.getUTCMonth() + 1, 2)); + pFilePath = pFilePath.replace("@Day", utilities.pad(pDatetime.getUTCDate(), 2)); + + } + + pFileService.getTextFile(pFilePath, pFileName, onFileReceived); + + function onFileReceived(text) { + + let data; + + try { + + data = JSON.parse(text); + + } catch (err) { + + data = JSON.parse("[]"); + + } + + callBackFunction(data); + + } + + } catch (err) { + logger.write("[ERROR] getPatterns -> err = " + err); + callBack("Operation Failed."); + } + } +}; \ No newline at end of file