diff --git a/AAMasters/AAOlivia/Candlestick.js b/AAMasters/AAOlivia/Candlestick.js new file mode 100644 index 000000000..2b0383d08 --- /dev/null +++ b/AAMasters/AAOlivia/Candlestick.js @@ -0,0 +1,641 @@ + +function newAAMastersAAOliviaCandlesticks() { + + var candles = []; + let timePeriod = INITIAL_TIME_PERIOD; + + var plotArea = newPlotArea(); + + var datetime = INITIAL_DATE; + + var candlesticks = { + onLayerStatusChanged: onLayerStatusChanged, + currentCandle: undefined, + positionAtDatetime: positionAtDatetime, + setTimePeriod: setTimePeriod, + setDatetime: setDatetime, + container: undefined, + draw: draw, + getContainer: getContainer, + initialize: initialize + }; + + var container = newContainer(); + container.initialize(); + candlesticks.container = container; + + container.displacement.containerName = "AAMasters AAOlivia Candlesticks"; + container.zoom.containerName = "AAMasters AAOlivia Candlesticks"; + container.frame.containerName = "AAMasters AAOlivia Candlesticks"; + + let marketFile; + let dailyFilesCursor; + + let layerStatus = 'off'; + + let fileCache; + + return candlesticks; + + function initialize(pExchange, pMarket, pDatetime, pTimePeriod, chartLayersPanel) { + + datetime = pDatetime; + timePeriod = pTimePeriod; + + fileCache = newFileCache(); + fileCache.initialize("AAMasters", "AAOlivia", "Candles", "Candlesticks", pExchange, pMarket, pDatetime, onCacheInitialized); + + function onCacheInitialized() { + + marketFile = fileCache.getMarketFile(pTimePeriod, pDatetime); + + recalculateScale(); + + // From here old code... + + + //recalculateCandlesUsingDailyFiles(true); // We need the first day of candles so as to see which is going to be the center of the viewport. + + + // if (marketId === INITIAL_DEFAULT_MARKET) { // For now, lets position the view port at the market USDT/BTC + + // postitionViewPort(); + + // } + + recalculateCandles(); + + viewPort.eventHandler.listenToEvent("Zoom Changed", onZoomChanged); + canvas.eventHandler.listenToEvent("Drag Finished", onDragFinished); + + layerStatus = chartLayersPanel.getLayerStatus(chartLayersPanel.layerNames.OLIVIA_CANDLES); + } + } + + + + function getContainer(point) { + + if (layerStatus !== 'on') { return; } + + var container; + + /* First we check if this point is inside this space. */ + + if (this.container.frame.isThisPointHere(point) === true) { + + return this.container; + + } else { + + /* This point does not belong to this space. */ + + return undefined; + } + + } + + function onLayerStatusChanged(eventData) { + + if (eventData.layer === 'Olivia Candlesticks') { + layerStatus = eventData.status; + } + + } + + function onZoomChanged(event) { + + recalculateCandles(); + + } + + function onDragFinished() { + + if (timePeriod <= _1_HOUR_IN_MILISECONDS) { + + recalculateCandles(); + + } + } + + + function setTimePeriod(pTimePeriod) { + + timePeriod = period; + + if (timePeriod >= ONE_HOUR_IN_MILISECONDS) { + + marketFile = fileCache.getMarketFile(pTimePeriod, datetime); + + } else { + + dailyFilesCursor = fileCache.getFileCursor(pTimePeriod, datetime); + + } + + recalculateCandles(); + + } + + function setDatetime(newDatetime) { + + datetime = newDatetime; + recalculateCandles(); + } + + + function postitionViewPort() { + + try { + + let targetPoint = { + x: candles[Math.round(candles.length / 2)].begin, + y: candles[Math.round(candles.length / 2)].min + (candles[Math.round(candles.length / 2)].max - candles[Math.round(candles.length / 2)].min) + }; + + targetPoint = plotArea.inverseTransform(targetPoint, candlesticks.container.frame.height); + targetPoint = transformThisPoint(targetPoint, candlesticks.container); + + let displaceVector = { + x: (viewPort.visibleArea.bottomRight.x - viewPort.visibleArea.topLeft.x) / 2 - targetPoint.x, + y: (viewPort.visibleArea.bottomLeft.y - viewPort.visibleArea.topLeft.y) / 2 - targetPoint.y + }; + + viewPort.displace(displaceVector); + + } catch (err) { + + // if there data is missing of the days it must position in then an exception is raised. + } + + } + + + function positionAtDatetime(newDatetime) { + + value = newDatetime.valueOf(); + + /* Now we calculate which candle has this new time, because it will give us the y coordinate. */ + + for (let i = 0; i < candles.length; i++) { + + if (value >= candles[i].begin && value <= candles[i].end) { + + let targetPoint = { + x: value, + y: candles[i].open + }; + + targetPoint = plotArea.inverseTransform(targetPoint, candlesticks.container.frame.height); + targetPoint = transformThisPoint(targetPoint, candlesticks.container); + + let targetMax = { + x: value, + y: candles[i].max + }; + + targetMax = plotArea.inverseTransform(targetMax, candlesticks.container.frame.height); + targetMax = transformThisPoint(targetMax, candlesticks.container); + + let targetMin = { + x: value, + y: candles[i].min + }; + + targetMin = plotArea.inverseTransform(targetMin, candlesticks.container.frame.height); + targetMin = transformThisPoint(targetMin, candlesticks.container); + + let center = { + x: (viewPort.visibleArea.bottomRight.x - viewPort.visibleArea.bottomLeft.x) / 2, + y: (viewPort.visibleArea.bottomRight.y - viewPort.visibleArea.topRight.y) / 2 + }; + + if (targetMax.y < viewPort.visibleArea.topLeft.y || targetMin.y > viewPort.visibleArea.bottomRight.y) { + + let displaceVector = { + x: 0, + y: center.y - targetPoint.y + }; + + viewPort.displaceTarget(displaceVector); + + } + + let displaceVector = { + x: center.x - targetPoint.x, + y: 0 + }; + + viewPort.displace(displaceVector); + + return; + } + } + } + + + + + function draw() { + + if (layerStatus !== 'on') { return; } + + this.container.frame.draw(); + + if (timePeriod !== ONE_DAY_IN_MILISECONDS) { + + if (Math.random() * 100 > 98) { + recalculateCandles(); + } + + + } + + plotCandleChart(); + + } + + + + function recalculateCandles() { + + if (layerStatus === 'off') { return; } + + if (timePeriod >= ONE_HOUR_IN_MILISECONDS) { + + recalculateCandlesUsingMarketFiles(); + + } else { + + recalculateCandlesUsingDailyFiles(); + + } + + candlesticks.container.eventHandler.raiseEvent("Candles Changed", candles); + } + + + + function recalculateCandlesUsingDailyFiles(currentDateOnly) { + + let daysOnSides = getSideDays(timePeriod); + + let leftDate; + let rightDate; + + if (currentDateOnly === true) { + + leftDate = new Date(datetime.getTime()); + rightDate = new Date(datetime.getTime()); + + leftDate = removeTime(datetime); + rightDate = removeTime(datetime); + + } else { + + leftDate = getDateFromPoint(viewPort.visibleArea.topLeft, candlesticks.container, plotArea); + rightDate = getDateFromPoint(viewPort.visibleArea.topRight, candlesticks.container, plotArea); + + + + leftDate.setDate(leftDate.getDate() - daysOnSides); + rightDate.setDate(rightDate.getDate() + daysOnSides); + + } + + let currentDate = new Date(leftDate.getTime()); + + candles = []; + + while (currentDate.getTime() <= rightDate.getTime()) { + + let stringDate = currentDate.getFullYear() + '-' + pad(currentDate.getMonth() + 1, 2) + '-' + pad(currentDate.getDate(), 2); + + let dailyFile = dailyFilesCursor.dailyFiles.get(stringDate); + + if (dailyFile !== undefined) { + + const fileTimePeriod = 60 * 1000; + const totalCandles = dailyFile.length * fileTimePeriod / timePeriod; + const recordsPerCandle = timePeriod / fileTimePeriod; + + for (var i = 0; i < totalCandles; i++) { + + var candle = newCandle(); + + let min = dailyFile[i * recordsPerCandle][0]; + let max = dailyFile[i * recordsPerCandle][1]; + + for (var j = 0; j < recordsPerCandle; j++) { + + if (dailyFile[i * recordsPerCandle + j][0] < min) { + + min = dailyFile[i * recordsPerCandle + j][0]; + } + + if (dailyFile[i * recordsPerCandle + j][1] > max) { + + max = dailyFile[i * recordsPerCandle + j][1]; + } + + } + + candle.min = min; + candle.max = max; + + candle.open = dailyFile[i * recordsPerCandle][2]; + candle.close = dailyFile[i * recordsPerCandle + recordsPerCandle - 1][3]; + + candle.begin = dailyFile[i * recordsPerCandle][4]; + candle.end = dailyFile[i * recordsPerCandle + recordsPerCandle - 1][5]; + + candle.beginId = dailyFile[i * recordsPerCandle][6]; + candle.endId = dailyFile[i * recordsPerCandle + recordsPerCandle - 1][7]; + + 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); + + if (datetime.valueOf() >= candle.begin && datetime.valueOf() <= candle.end) { + + candlesticks.currentCandle = candle; + candlesticks.container.eventHandler.raiseEvent("Current Candle Changed", candlesticks.currentCandle); + + } + } + + } + + currentDate.setDate(currentDate.getDate() + 1); + } + + } + + + function recalculateCandlesUsingMarketFiles() { + + if (marketFile === undefined) { return;} // Initialization not complete yet. + + candles = []; + + for (var i = 0; i < marketFile.length; i++) { + + var candle = newCandle(); + + candle.min = marketFile[i][0]; + candle.max = marketFile[i][1]; + + candle.open = marketFile[i][2]; + candle.close = marketFile[i][3]; + + candle.begin = (new Date(marketFile[i][4])).valueOf(); + candle.end = (new Date(marketFile[i][5])).valueOf(); + + 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); + } + + } + + + + + function recalculateScale() { + + if (marketFile === undefined) { return; } // Initialization not complete yet. + + var minValue = { + x: EARLIEST_DATE.valueOf(), + y: 0 + }; + + var maxValue = { + x: MAX_PLOTABLE_DATE.valueOf(), + y: nextPorwerOf10(getMaxRate()) + }; + + + plotArea.initialize( + minValue, + maxValue, + candlesticks.container.frame.width, + candlesticks.container.frame.height + ); + + function getMaxRate() { + + let maxValue = 0; + + for (var i = 0; i < marketIndex.length; i++) { + + let currentMax = marketIndex[i][1]; // 1 = rates. + + if (maxValue < currentMax) { + maxValue = currentMax; + } + } + + return maxValue; + + } + + } + + + + + + + + function plotCandleChart() { + + if (candles.length > 0) { + + /* Now we calculate and plot the candles */ + + for (var i = 0; i < candles.length; i++) { + + candle = candles[i]; + + var candlePoint1 = { + x: candle.begin + timePeriod / 7 * 1.5, + y: candle.open + }; + + var candlePoint2 = { + x: candle.begin + timePeriod / 7 * 5.5, + y: candle.open + }; + + var candlePoint3 = { + x: candle.begin + timePeriod / 7 * 5.5, + y: candle.close + }; + + var candlePoint4 = { + x: candle.begin + timePeriod / 7 * 1.5, + y: candle.close + }; + + candlePoint1 = plotArea.inverseTransform(candlePoint1, candlesticks.container.frame.height); + candlePoint2 = plotArea.inverseTransform(candlePoint2, candlesticks.container.frame.height); + candlePoint3 = plotArea.inverseTransform(candlePoint3, candlesticks.container.frame.height); + candlePoint4 = plotArea.inverseTransform(candlePoint4, candlesticks.container.frame.height); + + candlePoint1 = transformThisPoint(candlePoint1, candlesticks.container); + candlePoint2 = transformThisPoint(candlePoint2, candlesticks.container); + candlePoint3 = transformThisPoint(candlePoint3, candlesticks.container); + candlePoint4 = transformThisPoint(candlePoint4, candlesticks.container); + + if (candlePoint2.x < viewPort.visibleArea.bottomLeft.x || candlePoint1.x > viewPort.visibleArea.bottomRight.x) { + continue; + } + + candlePoint1 = viewPort.fitIntoVisibleArea(candlePoint1); + candlePoint2 = viewPort.fitIntoVisibleArea(candlePoint2); + candlePoint3 = viewPort.fitIntoVisibleArea(candlePoint3); + candlePoint4 = viewPort.fitIntoVisibleArea(candlePoint4); + + var stickPoint1 = { + x: candle.begin + timePeriod / 7 * 3.2, + y: candle.max + }; + + var stickPoint2 = { + x: candle.begin + timePeriod / 7 * 3.8, + y: candle.max + }; + + var stickPoint3 = { + x: candle.begin + timePeriod / 7 * 3.8, + y: candle.min + }; + + var stickPoint4 = { + x: candle.begin + timePeriod / 7 * 3.2, + y: candle.min + }; + + stickPoint1 = plotArea.inverseTransform(stickPoint1, candlesticks.container.frame.height); + stickPoint2 = plotArea.inverseTransform(stickPoint2, candlesticks.container.frame.height); + stickPoint3 = plotArea.inverseTransform(stickPoint3, candlesticks.container.frame.height); + stickPoint4 = plotArea.inverseTransform(stickPoint4, candlesticks.container.frame.height); + + stickPoint1 = transformThisPoint(stickPoint1, candlesticks.container); + stickPoint2 = transformThisPoint(stickPoint2, candlesticks.container); + stickPoint3 = transformThisPoint(stickPoint3, candlesticks.container); + stickPoint4 = transformThisPoint(stickPoint4, candlesticks.container); + + stickPoint1 = viewPort.fitIntoVisibleArea(stickPoint1); + stickPoint2 = viewPort.fitIntoVisibleArea(stickPoint2); + stickPoint3 = viewPort.fitIntoVisibleArea(stickPoint3); + stickPoint4 = viewPort.fitIntoVisibleArea(stickPoint4); + + browserCanvasContext.beginPath(); + + browserCanvasContext.moveTo(stickPoint1.x, stickPoint1.y); + browserCanvasContext.lineTo(stickPoint2.x, stickPoint2.y); + browserCanvasContext.lineTo(stickPoint3.x, stickPoint3.y); + browserCanvasContext.lineTo(stickPoint4.x, stickPoint4.y); + + browserCanvasContext.closePath(); + browserCanvasContext.fillStyle = 'rgba(54, 54, 54, 1)'; + browserCanvasContext.fill(); + + if (datetime !== undefined) { + + let dateValue = datetime.valueOf(); + + if (dateValue >= candle.begin && dateValue <= candle.end) { + + browserCanvasContext.strokeStyle = 'rgba(255, 233, 31, 1)'; // Current candle accroding to time + + } else { + browserCanvasContext.strokeStyle = 'rgba(212, 206, 201, 1)'; + } + + } else { + browserCanvasContext.strokeStyle = 'rgba(212, 206, 201, 1)'; + } + + browserCanvasContext.lineWidth = 1; + browserCanvasContext.stroke(); + + browserCanvasContext.beginPath(); + + browserCanvasContext.moveTo(candlePoint1.x, candlePoint1.y); + browserCanvasContext.lineTo(candlePoint2.x, candlePoint2.y); + browserCanvasContext.lineTo(candlePoint3.x, candlePoint3.y); + browserCanvasContext.lineTo(candlePoint4.x, candlePoint4.y); + + browserCanvasContext.closePath(); + + if (candle.direction === 'up') { browserCanvasContext.strokeStyle = 'rgba(27, 105, 7, 1)'; } + if (candle.direction === 'down') { browserCanvasContext.strokeStyle = 'rgba(130, 9, 9, 1)'; } + if (candle.direction === 'side') { browserCanvasContext.strokeStyle = 'rgba(27, 7, 105, 1)'; } + + if (datetime !== undefined) { + + let dateValue = datetime.valueOf(); + + if (dateValue >= candle.begin && dateValue <= candle.end) { + + /* highlight the current candle */ + + browserCanvasContext.fillStyle = 'rgba(255, 233, 31, 1)'; // Current candle accroding to time + + let currentCandle = { + bodyWidth: candlePoint2.x - candlePoint1.x, + bodyHeight: candlePoint3.y - candlePoint2.y, + stickHeight: stickPoint4.y - stickPoint2.y, + stickWidth: stickPoint2.x - stickPoint1.x, + stickStart: candlePoint2.y - stickPoint2.y, + period: timePeriod, + innerCandle: candle + }; + + candlesticks.container.eventHandler.raiseEvent("Current Candle Info Changed", currentCandle); + + } else { + + if (candle.direction === 'up') { browserCanvasContext.fillStyle = 'rgba(64, 217, 26, 1)'; } + if (candle.direction === 'down') { browserCanvasContext.fillStyle = 'rgba(219, 18, 18, 1)'; } + if (candle.direction === 'side') { browserCanvasContext.fillStyle = 'rgba(64, 26, 217, 1)'; } + } + + } else { + + if (candle.direction === 'up') { browserCanvasContext.fillStyle = 'rgba(64, 217, 26, 1)'; } + if (candle.direction === 'down') { browserCanvasContext.fillStyle = 'rgba(219, 18, 18, 1)'; } + if (candle.direction === 'side') { browserCanvasContext.fillStyle = 'rgba(64, 26, 217, 1)'; } + + } + + + + if ( + candlePoint1.x < viewPort.visibleArea.topLeft.x + 50 + || + candlePoint1.x > viewPort.visibleArea.bottomRight.x - 50 + ) { + // we leave this candles without fill. + } else { + browserCanvasContext.fill(); + } + + browserCanvasContext.lineWidth = 1; + browserCanvasContext.stroke(); + + + } + } + } + + +} + diff --git a/AAWebPlatform.njsproj b/AAWebPlatform.njsproj index 2ce66f91d..4e3ded997 100644 --- a/AAWebPlatform.njsproj +++ b/AAWebPlatform.njsproj @@ -39,6 +39,9 @@ Code + + Code + Code @@ -69,7 +72,7 @@ Code - + Code @@ -121,7 +124,9 @@ + + diff --git a/Dashboard.js b/Dashboard.js index f7006807a..acbd2e08f 100644 --- a/Dashboard.js +++ b/Dashboard.js @@ -3,11 +3,17 @@ var canvas; var markets; +var ecosystem = newEcosystem(); var viewPort = newViewPort(); const DEBUG_START_UP_DELAY = 0 //3000; // This is a waiting time in case there is a need to debug the very first steps of initialization, to be able to hit F12 on time. const INITIAL_DEFAULT_MARKET = 2; // This is the market that will be shown when loading the site for the first time. +const DEFAULT_EXCHANGE = "Poloniex"; +const DEFAULT_MARKET = { + assetA: "USDT", + assetB: "BTC", +}; const WIDHTER_VOLUME_BAR_BASE_FACTOR = 2.5; const LESS_WIDHTER_VOLUME_BAR_TOP_FACTOR = 1 / 4; @@ -25,7 +31,7 @@ const _1_MINUTE_IN_MILISECONDS = 1 * 60 * 1000; const EARLIEST_DATE = new Date(2014, 0, 18, 4, 26, 8); const FONT_ASPECT_RATIO = 0.60; const CHART_ASPECT_RATIO = 1 / 10; -const INITIAL_TIME_PERIOD = _10_MINUTES_IN_MILISECONDS; +const INITIAL_TIME_PERIOD = ONE_DAY_IN_MILISECONDS; /* Here we list the valid Time Periods: */ diff --git a/Ecosystem.js b/Ecosystem.js index df6908bfa..1380367b0 100644 --- a/Ecosystem.js +++ b/Ecosystem.js @@ -1,640 +1,750 @@ -const ECOSYSTEM = { - consortium: { - organization: { - name: "AAConsortium", - type: "Non-For-Profit", - displayName: "Advanced Algos Consortium", - location: "Switzerland", - leader: "Luis Molina", - logo: "AAConsortium.jpg" - }, - web: "www.AdvancedAlgos.org", - github: { - org: "Advanced Algos", - repos: { - repo: { - name: "AAWebSite", - description: "AA Consortium Web Site.", - openIssues: 0, - openPullRequests: 0, - contributors: 1 - }, - repo: { - name: "AAWebPlatform", - description: "The part of the AA Platform that runs on web browsers.", - openIssues: 0, - openPullRequests: 0, - contributors: 1 - }, - repo: { - name: "AACloudPlatform", - description: "The part of the AA Platform that runs on the cloud.", - openIssues: 0, - openPullRequests: 0, - contributors: 1 - } - } - }, - members: { - member: { - organizationName: "AAMasters", - type: "devTeam", - delegate: "Luis Molina", - votes: 1 - }, - member: { - organizationName: "AAOrion LLC", - type: "cloudHosting", - delegate: "Luis Molina", - votes: 5 - }, - member: { - organizationName: "AAExchange Masters", - type: "exchangeWrapper", - delegate: "Luis Molina", - votes: 1 - } - } - }, - devTeams: { - team: { + +function newEcosystem() { + + let ecosystem = { + getTeam: getTeam, + getBot: getBot, + getProduct: getProduct, + getLayer: getLayer, + getExchange: getExchange, + initialize: initialize + } + return ecosystem; + + + const ECOSYSTEM = { + consortium: { organization: { - name: "AAMasters", - type: "Open Source Community", - displayName: "AA Masters", - location: "Global", + name: "AAConsortium", + type: "Non-For-Profit", + displayName: "Advanced Algos Consortium", + location: "Switzerland", leader: "Luis Molina", - logo: "AAMasters.jpg" - }, - teamMembers: { - member: { - displayName: "Luis Molina", - githubUsername: "Luis-Fernando-Molina", - profilePicture: "Luis.jpg", - tokens: { - percentDistribution: 100, - totalCollected: 121.45 - } - } - }, - bots: { - bot: { - codeName: "AACharly", - displayName: "Charly", - type: "Extract", - version: { - number: "1.0.0", - status: "Mantained", // Discontinued - }, - products: { - product: { - name: "Trades", - description: "Each file contains trades records of one market at one exchange in a period of time of one minute.", - storageAccount: "aacharly", - filePath: "@Exchange/Output/Trades/@Year/@Month/@Date/@Hour/@Minute", - fileName: "@AssetA_@AssetB.json", - exchangeList: { - exchange: { - name: "Poloniex", - datetimeRange: { - minDatetime: "2017-02-19 19:15:00.000 GMT+0000", - maxDatetime: "2018-02-13 10:10:00.000 GMT+0000" - } - } - }, - layers: { - layer: { - displayName: "Trades", - exchangeList: ["Poloniex"], - validPeriods: ["01-min"], - plotter: { - devTeam: "AAMasters", - repo: "AACharly-Plotter", - moduleName: "TradeList", - target: "Timeline" - } - } - } - } - }, - processes: { - process: { - name: "Poloniex-Live-Trades", - description: "Retrieves the trades done at the current minute and the previous minute and saves them at the storage account." - }, - process: { - name: "Poloniex-Historic-Trades", - description: "Retrieves and saves the historical trades in batches going backwards from the current time until reaching the begining of the market." - }, - process: { - name: "Poloniex-Hole-Fixing", - description: "Scans the trades saved by the Live Trades and Historic Trades processes searching for missing records. Once a hole is found on the data set, it patches it by retrieving the missing records from the exchange." - } - }, - directDependencies: {}, - directDependents: { - bot: { - devTeam: "AAMasters", - codeName: "AABruce" - }, - bot: { - devTeam: "AAMasters", - codeName: "AAOlivia" - } - }, - collaboratorsList: [], - github: { - org: "AAMasters", - repos: { - repo: { - name: "AACharly-Bot", - description: "Produces a data-set of all trades of every market in multiple exchanges.", - openIssues: 0, - openPullRequests: 0, - contributors: 1 - }, - repo: { - name: "AACharly-Plotter", - description: "Plotters plug-ins to browse trades at the AA Web Platform.", - openIssues: 0, - openPullRequests: 0, - contributors: 1 - } - } - } - }, - bot: { - codeName: "AACarol", - displayName: "Carol", - type: "Extract", - version: { - number: "1.0.0", - status: "Mantained", // Discontinued - }, - products: { - product: { - name: "Order Book", - description: "Each file contains the bids and asks positions at each market at a certain moment in time.", - storageAccount: "aacarol", - filePath: "@Exchange/Output/Order-Books/@Year/@Month/@Date/@Hour/@Minute", - fileName: "@AssetA_@AssetB.json", - exchangeList: { - exchange: { - name: "Poloniex", - datetimeRange: { - minDatetime: "2017-02-19 19:15:00.000 GMT+0000", - maxDatetime: "2018-02-13 10:10:00.000 GMT+0000" - } - } - }, - layers: { - layer: { - displayName: "Order Book", - exchangeList: ["Poloniex"], - validPeriods: ["06-hs", "03-hs", "01-hs", "30-min", "10-min", "05-min", "01-min"], - plotter: { - devTeam: "AAMasters", - repo: "AACarol-Plotter", - moduleName: "OrderBook", - target: "Panel" - } - } - } - }, - product: { - name: "Order Books", - description: "Each file contains the sumarized bids and asks positions at each market at a certain moment in time. Agreggation makes the dataset optimal for different time periods.", - storageAccount: "aacarol", - filePath: "@Exchange/Output/Aggregated-Order-Books/@Period/@Year/@Month/@Date/@Hour/@Minute", - fileName: "@AssetA_@AssetB.json", - exchangeList: { - exchange: { - name: "Poloniex", - datetimeRange: { - minDatetime: "2017-02-19 19:15:00.000 GMT+0000", - maxDatetime: "2018-02-13 10:10:00.000 GMT+0000" - } - } - }, - layers: { - layer: { - displayName: "Order Books", - exchangeList: ["Poloniex"], - validPeriods: ["06-hs", "03-hs", "01-hs", "30-min", "10-min", "05-min", "01-min"], - plotter: { - devTeam: "AAMasters", - repo: "AACarol-Plotter", - moduleName: "OrderBooks", - target: "Timeline" - } - } - } - } - }, - processes: { - process: { - name: "Poloniex-Order-Books", - description: "Retrieves the order books at the current minute and saves them at the storage account." - }, - process: { - name: "Aggregated-Order-Books", - description: "Aggregates the order books information to be viewed at different time periods." - }, - }, - directDependencies: {}, - directDependents: {}, - collaboratorsList: [], - github: { - org: "AAMasters", - repos: { - repo: { - name: "AACarol", - description: "Produces a data-set with a snapshot of all markets order books every minute.", - openIssues: 0, - openPullRequests: 0, - contributors: 1 - } - } - } - }, - bot: { - codeName: "AABruce", - displayName: "Bruce", - type: "Indicator", - version: { - number: "1.0.0", - status: "Mantained", // Discontinued - }, - products: { - product: { - name: "One Minute Candles in Daily Files", - description: "Each file contains the candles of one whole day on a one minute time period.", - storageAccount: "aabruce", - filePath: "@Exchange/Output/Candles/One-Min/@Year/@Month/@Date", - fileName: "@AssetA_@AssetB.json", - exchangeList: { - exchange: { - name: "Poloniex", - datetimeRange: { - minDatetime: "2017-02-19 19:15:00.000 GMT+0000", - maxDatetime: "2018-02-13 10:10:00.000 GMT+0000" - } - } - }, - layers: { - layer: { - displayName: "Candlesticks", - exchangeList: ["Poloniex"], - validPeriods: ["30-min", "10-min", "05-min", "01-min"], - plotter: { - devTeam: "AAMasters", - repo: "AABruce-Plotter", - moduleName: "Candlesticks", - target: "Timeline", - dependencies: { - dependency: { - devTeam: "AAMasters", - repo: "Plotters-Utilities", - moduleName: "Candlesticks" - } - } - } - } - } - }, - product: { - name: "One Minute Volumes in Daily Files", - description: "Each file contains the volumes of one whole day on a one minute time period.", - storageAccount: "aabruce", - filePath: "@Exchange/Output/Volumes/One-Min/@Year/@Month/@Date", - fileName: "@AssetA_@AssetB.json", - exchangeList: { - exchange: { - name: "Poloniex", - datetimeRange: { - minDatetime: "2017-02-19 19:15:00.000 GMT+0000", - maxDatetime: "2018-02-13 10:10:00.000 GMT+0000" - } - } - }, - layers: { - layer: { - displayName: "Sell and Buy Volumes", - exchangeList: ["Poloniex"], - validPeriods: ["06-hs", "03-hs", "01-hs", "30-min", "10-min", "05-min", "01-min"], - plotter: { - devTeam: "AAMasters", - repo: "AABruce-Plotter", - moduleName: "Volumes", - target: "Timeline", - dependencies: { - dependency: { - devTeam: "AAMasters", - repo: "Plotters-Utilities", - moduleName: "Volumes" - } - } - } - } - } - } - }, - processes: { - process: { - name: "One-Min-Daily-Candles-Volumes", - description: "Read trades files and generates one minute candles and volumes files for each day." - } - }, - directDependencies: {}, - directDependents: {}, - collaboratorsList: [], - github: { - org: "AAMasters", - repos: { - repo: { - name: "AABruce", - description: "Produces two data-sets with candles and volumes for all markets at all exchanges.", - openIssues: 0, - openPullRequests: 0, - contributors: 1 - } - } - } - }, - bot: { - codeName: "AAOlivia", - displayName: "Olivia", - type: "Indicator", - version: { - number: "1.0.0", - status: "Mantained", // Discontinued - }, - products: { - product: { - name: "Market Candles per Period", - description: "A set of files per period that contains all candles of one whole market.", - storageAccount: "aaolivia", - filePath: "@Exchange/Output/Candles/Multi-Period-Market/@Period", - fileName: "@AssetA_@AssetB.json", - exchangeList: { - exchange: { - name: "Poloniex", - datetimeRange: { - minDatetime: "2017-02-19 19:15:00.000 GMT+0000", - maxDatetime: "2018-02-13 10:10:00.000 GMT+0000" - } - } - }, - layers: { - layer: { - displayName: "Candlesticks", - exchangeList: ["Poloniex"], - validPeriods: ["24-hs", "12-hs", "06-hs", "03-hs", "01-hs"], - plotter: { - devTeam: "AAMasters", - repo: "AAOlivia-Plotter", - moduleName: "Candlesticks", - target: "Timeline", - dependencies: { - dependency: { - devTeam: "AAMasters", - repo: "Plotters-Utilities", - moduleName: "Candlesticks" - } - } - } - } - } - }, - product: { - name: "Market Volumes per Period", - description: "A set of files per period that contains all volumes of one whole market.", - storageAccount: "aaolivia", - filePath: "@Exchange/Output/Candles/Multi-Period-Market/@Period", - fileName: "@AssetA_@AssetB.json", - exchangeList: { - exchange: { - name: "Poloniex", - datetimeRange: { - minDatetime: "2017-02-19 19:15:00.000 GMT+0000", - maxDatetime: "2018-02-13 10:10:00.000 GMT+0000" - } - } - }, - layers: { - layer: { - displayName: "Volumes", - exchangeList: ["Poloniex"], - validPeriods: ["24-hs", "12-hs", "06-hs", "03-hs", "01-hs"], - plotter: { - devTeam: "AAMasters", - repo: "AAOlivia-Plotter", - moduleName: "Volumes", - target: "Timeline", - dependencies: { - dependency: { - devTeam: "AAMasters", - repo: "Plotters-Utilities", - moduleName: "Volumes" - } - } - } - } - } - } - }, - processes: { - process: { - name: "One-Min-Daily-Candles-Volumes", - description: "Read trades files and generates one minute candles and volumes files for each day." - } - }, - directDependencies: {}, - directDependents: {}, - collaboratorsList: [], - github: { - org: "AAMasters", - repos: { - repo: { - name: "AABruce", - description: "Produces two data-sets with candles and volumes for all markets at all exchanges.", - openIssues: 0, - openPullRequests: 0, - contributors: 1 - } - } - } - } - } - } - }, - clouds: { - cloudHosting: { - codeName: "AAOrion", - organization: { - name: "AAOrion LLC", - type: "Company", - displayName: "Orion", - location: "USA", - leader: "Luis Molina", - logo: "AAOrion.jpg" + logo: "AAConsortium.jpg" }, + web: "www.AdvancedAlgos.org", github: { - org: "AAOrion", + org: "Advanced Algos", repos: { repo: { - name: "AzureAAHosting", - description: "AA Azure Hosting Web Site", + name: "AAWebSite", + description: "AA Consortium Web Site.", + openIssues: 0, + openPullRequests: 0, + contributors: 1 + }, + repo: { + name: "AAWebPlatform", + description: "The part of the AA Platform that runs on web browsers.", + openIssues: 0, + openPullRequests: 0, + contributors: 1 + }, + repo: { + name: "AACloudPlatform", + description: "The part of the AA Platform that runs on the cloud.", openIssues: 0, openPullRequests: 0, contributors: 1 } } }, - underlayingCloud: "Azure", - botsRunning: { - bot: { - devTeam: "AAMasters", - codeName: "AACharly", - version: "1.0.0", - status: "Alive", - stats: { + members: { + member: { + organizationName: "AAMasters", + type: "devTeam", + delegate: "Luis Molina", + votes: 1 + }, + member: { + organizationName: "AAOrion LLC", + type: "cloudHosting", + delegate: "Luis Molina", + votes: 5 + }, + member: { + organizationName: "AAExchange Masters", + type: "exchangeWrapper", + delegate: "Luis Molina", + votes: 1 + } + } + }, + devTeams: { + team: { + codeName: "AAMasters", + organization: { + name: "AAMasters", + type: "Open Source Community", + displayName: "AA Masters", + location: "Global", + leader: "Luis Molina", + logo: "AAMasters.jpg" + }, + teamMembers: { + member: { + displayName: "Luis Molina", + githubUsername: "Luis-Fernando-Molina", + profilePicture: "Luis.jpg", tokens: { - totalCollected: 532.2442, - totalSpent: 323.455, - currentBalance: 142, - expensesPerHour: 1.44, - maxBalance: 177, - minBalance: 22.44 - }, - life: { - born: "2015-02-19 19:15:00.000 GMT+0000", - died: undefined, - expectedToRetire: "2019-02-19 19:15:00.000 GMT+0000", - expectedToDie: "2019-03-19 19:15:00.000 GMT+0000" + percentDistribution: 100, + totalCollected: 121.45 } } }, - bot: { - devTeam: "AAMasters", - codeName: "AACarol", - version: "1.0.0", - status: "Alive", - stats: { - tokens: { - totalCollected: 532.2442, - totalSpent: 323.455, - currentBalance: 142, - expensesPerHour: 1.44, - maxBalance: 177, - minBalance: 22.44 + bots: { + bot: { + codeName: "AACharly", + displayName: "Charly", + type: "Extract", + version: { + number: "1.0.0", + status: "Mantained", // Discontinued }, - life: { - born: "2015-02-19 19:15:00.000 GMT+0000", - died: undefined, - expectedToRetire: "2019-02-19 19:15:00.000 GMT+0000", - expectedToDie: "2019-03-19 19:15:00.000 GMT+0000" + products: { + product: { + codeName: "Trades", + displayName: "Trades", + description: "Each file contains trades records of one market at one exchange in a period of time of one minute.", + storageAccount: "aacharly", + filePath: "@Exchange/Output/Trades/@Year/@Month/@Date/@Hour/@Minute", + fileName: "@AssetA_@AssetB.json", + exchangeList: { + exchange: { + name: "Poloniex", + datetimeRange: { + minDatetime: "2017-02-19 19:15:00.000 GMT+0000", + maxDatetime: "2018-02-13 10:10:00.000 GMT+0000" + } + } + }, + layers: { + layer: { + codeName: "Trades", + displayName: "Trades", + exchangeList: ["Poloniex"], + validPeriods: ["01-min"], + plotter: { + devTeam: "AAMasters", + repo: "AACharly-Plotter", + moduleName: "TradeList", + target: "Timeline" + } + } + } + } + }, + processes: { + process: { + name: "Poloniex-Live-Trades", + description: "Retrieves the trades done at the current minute and the previous minute and saves them at the storage account." + }, + process: { + name: "Poloniex-Historic-Trades", + description: "Retrieves and saves the historical trades in batches going backwards from the current time until reaching the begining of the market." + }, + process: { + name: "Poloniex-Hole-Fixing", + description: "Scans the trades saved by the Live Trades and Historic Trades processes searching for missing records. Once a hole is found on the data set, it patches it by retrieving the missing records from the exchange." + } + }, + directDependencies: {}, + directDependents: { + bot: { + devTeam: "AAMasters", + codeName: "AABruce" + }, + bot: { + devTeam: "AAMasters", + codeName: "AAOlivia" + } + }, + collaboratorsList: [], + github: { + org: "AAMasters", + repos: { + repo: { + name: "AACharly-Bot", + description: "Produces a data-set of all trades of every market in multiple exchanges.", + openIssues: 0, + openPullRequests: 0, + contributors: 1 + }, + repo: { + name: "AACharly-Plotter", + description: "Plotters plug-ins to browse trades at the AA Web Platform.", + openIssues: 0, + openPullRequests: 0, + contributors: 1 + } + } + }, + storage: { + sas: '?sv=2017-04-17&ss=f&srt=sco&sp=rc&se=2018-12-31T02:33:36Z&st=2018-02-01T18:33:36Z&spr=https&sig=xFTcopdKq0f60wl2iuukbtIpcLwxZVKzlw5BzpJfo5g%3D', + fileUri: 'https://' + 'aacharly' + '.file.core.windows.net' + } + }, + bot: { + codeName: "AACarol", + displayName: "Carol", + type: "Extract", + version: { + number: "1.0.0", + status: "Mantained", // Discontinued + }, + products: { + product: { + codeName: "Order Book", + displayName: "Order Book", + description: "Each file contains the bids and asks positions at each market at a certain moment in time.", + storageAccount: "aacarol", + filePath: "@Exchange/Output/Order-Books/@Year/@Month/@Date/@Hour/@Minute", + fileName: "@AssetA_@AssetB.json", + exchangeList: { + exchange: { + name: "Poloniex", + datetimeRange: { + minDatetime: "2017-02-19 19:15:00.000 GMT+0000", + maxDatetime: "2018-02-13 10:10:00.000 GMT+0000" + } + } + }, + layers: { + layer: { + codeName: "Order Book", + displayName: "Order Book", + exchangeList: ["Poloniex"], + validPeriods: ["06-hs", "03-hs", "01-hs", "30-min", "10-min", "05-min", "01-min"], + plotter: { + devTeam: "AAMasters", + repo: "AACarol-Plotter", + moduleName: "OrderBook", + target: "Panel" + } + } + } + }, + product: { + codeName: "Order Books", + displayName: "Order Books", + description: "Each file contains the sumarized bids and asks positions at each market at a certain moment in time. Agreggation makes the dataset optimal for different time periods.", + storageAccount: "aacarol", + filePath: "@Exchange/Output/Aggregated-Order-Books/@Period/@Year/@Month/@Date/@Hour/@Minute", + fileName: "@AssetA_@AssetB.json", + exchangeList: { + exchange: { + name: "Poloniex", + datetimeRange: { + minDatetime: "2017-02-19 19:15:00.000 GMT+0000", + maxDatetime: "2018-02-13 10:10:00.000 GMT+0000" + } + } + }, + layers: { + layer: { + codeName: "Order Books", + displayName: "Order Books", + exchangeList: ["Poloniex"], + validPeriods: ["06-hs", "03-hs", "01-hs", "30-min", "10-min", "05-min", "01-min"], + plotter: { + devTeam: "AAMasters", + repo: "AACarol-Plotter", + moduleName: "OrderBooks", + target: "Timeline" + } + } + } + } + }, + processes: { + process: { + name: "Poloniex-Order-Books", + description: "Retrieves the order books at the current minute and saves them at the storage account." + }, + process: { + name: "Aggregated-Order-Books", + description: "Aggregates the order books information to be viewed at different time periods." + }, + }, + directDependencies: {}, + directDependents: {}, + collaboratorsList: [], + github: { + org: "AAMasters", + repos: { + repo: { + name: "AACarol", + description: "Produces a data-set with a snapshot of all markets order books every minute.", + openIssues: 0, + openPullRequests: 0, + contributors: 1 + } + } + }, + storage: { + sas: '?sv=2017-04-17&ss=f&srt=sco&sp=r&se=2018-12-01T00:09:44Z&st=2017-12-01T13:09:44Z&spr=https,http&sig=J60UlQuUqh9Hd1Pm0PqIF6yari3D3TkGEz1fSNQJWks%3D', + fileUri: 'https://' + 'aadata' + '.file.core.windows.net' + } + }, + bot: { + codeName: "AABruce", + displayName: "Bruce", + type: "Indicator", + version: { + number: "1.0.0", + status: "Mantained", // Discontinued + }, + products: { + product: { + codeName: "Candles", + displayName: "One Minute Candles in Daily Files", + description: "Each file contains the candles of one whole day on a one minute time period.", + storageAccount: "aabruce", + filePath: "@Exchange/Output/Candles/One-Min/@Year/@Month/@Date", + fileName: "@AssetA_@AssetB.json", + exchangeList: { + exchange: { + name: "Poloniex", + datetimeRange: { + minDatetime: "2017-02-19 19:15:00.000 GMT+0000", + maxDatetime: "2018-02-13 10:10:00.000 GMT+0000" + } + } + }, + layers: { + layer: { + codeName: "Candles", + displayName: "Candlesticks", + exchangeList: ["Poloniex"], + validPeriods: ["30-min", "10-min", "05-min", "01-min"], + plotter: { + devTeam: "AAMasters", + repo: "AABruce-Plotter", + moduleName: "Candlesticks", + target: "Timeline", + dependencies: { + dependency: { + devTeam: "AAMasters", + repo: "Plotters-Utilities", + moduleName: "Candlesticks" + } + } + } + } + } + }, + product: { + codeName: "Volumes", + displayName: "One Minute Volumes in Daily Files", + description: "Each file contains the volumes of one whole day on a one minute time period.", + storageAccount: "aabruce", + filePath: "@Exchange/Output/Volumes/One-Min/@Year/@Month/@Date", + fileName: "@AssetA_@AssetB.json", + exchangeList: { + exchange: { + name: "Poloniex", + datetimeRange: { + minDatetime: "2017-02-19 19:15:00.000 GMT+0000", + maxDatetime: "2018-02-13 10:10:00.000 GMT+0000" + } + } + }, + layers: { + layer: { + codeName: "Volumes", + displayName: "Sell and Buy Volumes", + exchangeList: ["Poloniex"], + validPeriods: ["06-hs", "03-hs", "01-hs", "30-min", "10-min", "05-min", "01-min"], + plotter: { + devTeam: "AAMasters", + repo: "AABruce-Plotter", + moduleName: "Volumes", + target: "Timeline", + dependencies: { + dependency: { + devTeam: "AAMasters", + repo: "Plotters-Utilities", + moduleName: "Volumes" + } + } + } + } + } + } + }, + processes: { + process: { + name: "One-Min-Daily-Candles-Volumes", + description: "Read trades files and generates one minute candles and volumes files for each day." + } + }, + directDependencies: {}, + directDependents: {}, + collaboratorsList: [], + github: { + org: "AAMasters", + repos: { + repo: { + name: "AABruce", + description: "Produces two data-sets with candles and volumes for all markets at all exchanges.", + openIssues: 0, + openPullRequests: 0, + contributors: 1 + } + } + }, + storage: { + sas: '?sv=2017-04-17&ss=f&srt=sco&sp=r&se=2018-12-31T02:32:04Z&st=2018-02-01T18:32:04Z&spr=https&sig=SbZI6bvAE1MBxna2NOvfgMroPFZNjAyaHUsAPvh11hg%3D', + fileUri: 'https://' + 'aabruce' + '.file.core.windows.net' + } + }, + bot: { + codeName: "AAOlivia", + displayName: "Olivia", + type: "Indicator", + version: { + number: "1.0.0", + status: "Mantained", // Discontinued + }, + products: { + product: { + codeName: "Candles", + displayName: "Market Candles per Period", + description: "A set of files per period that contains all candles of one whole market.", + storageAccount: "aaolivia", + filePath: "@Exchange/Output/Candles/Multi-Period-Market/@Period", + fileName: "@AssetA_@AssetB.json", + exchangeList: { + exchange: { + name: "Poloniex", + datetimeRange: { + minDatetime: "2017-02-19 19:15:00.000 GMT+0000", + maxDatetime: "2018-02-13 10:10:00.000 GMT+0000" + } + } + }, + layers: { + layer: { + codeName: "Candlesticks", + displayName: "Candlesticks", + exchangeList: ["Poloniex"], + validPeriods: ["24-hs", "12-hs", "06-hs", "03-hs", "01-hs"], + plotter: { + devTeam: "AAMasters", + repo: "AAOlivia-Plotter", + moduleName: "Candlesticks", + target: "Timeline", + dependencies: { + dependency: { + devTeam: "AAMasters", + repo: "Plotters-Utilities", + moduleName: "Candlesticks" + } + } + } + } + } + }, + product: { + codeName: "Volumes", + displayName: "Market Volumes per Period", + description: "A set of files per period that contains all volumes of one whole market.", + storageAccount: "aaolivia", + filePath: "@Exchange/Output/Candles/Multi-Period-Market/@Period", + fileName: "@AssetA_@AssetB.json", + exchangeList: { + exchange: { + name: "Poloniex", + datetimeRange: { + minDatetime: "2017-02-19 19:15:00.000 GMT+0000", + maxDatetime: "2018-02-13 10:10:00.000 GMT+0000" + } + } + }, + layers: { + layer: { + codeName: "Volumes", + displayName: "Volumes", + exchangeList: ["Poloniex"], + validPeriods: ["24-hs", "12-hs", "06-hs", "03-hs", "01-hs"], + plotter: { + devTeam: "AAMasters", + repo: "AAOlivia-Plotter", + moduleName: "Volumes", + target: "Timeline", + dependencies: { + dependency: { + devTeam: "AAMasters", + repo: "Plotters-Utilities", + moduleName: "Volumes" + } + } + } + } + } + } + }, + processes: { + process: { + name: "One-Min-Daily-Candles-Volumes", + description: "Read trades files and generates one minute candles and volumes files for each day." + } + }, + directDependencies: {}, + directDependents: {}, + collaboratorsList: [], + github: { + org: "AAMasters", + repos: { + repo: { + name: "AABruce", + description: "Produces two data-sets with candles and volumes for all markets at all exchanges.", + openIssues: 0, + openPullRequests: 0, + contributors: 1 + } + } + }, + storage: { + sas: '?sv=2017-04-17&ss=f&srt=sco&sp=rl&se=2018-12-31T02:34:32Z&st=2018-02-01T18:34:32Z&spr=https,http&sig=24UJjGDVpPrHjhBoZtt3iKj4sxgenfSV4VTJD2v0q1U%3D', + fileUri: 'https://' + 'aaolivia' + '.file.core.windows.net' } } } - }, - stats: { - extractionBots: 2, - indicatorsBots: 24, - tradingBots: 12, - suscribers: 230, - apps: 1 } - } - }, - exchanges: { - exchangeWrapper: { - codeName: "AAExchange-Masters", - organization: { - name: "AAExchange Masters", - type: "Open Source Project", - displayName: "Exchange Masters", - location: "Global", - leader: "Luis Molina", - logo: "AAExchange-Masters.jpg" - }, - exchangesServed: { - exchange: { - name: "Poloniex", - github: { - org: "AAExchange Masters", + }, + clouds: { + cloudHosting: { + codeName: "AAOrion", + organization: { + name: "AAOrion LLC", + type: "Company", + displayName: "Orion", + location: "USA", + leader: "Luis Molina", + logo: "AAOrion.jpg" + }, + github: { + org: "AAOrion", + repos: { repo: { - name: "AAPoloniexWrapper", - description: "Wrapps Poloniex Exchange to be acceced from within the Advanced Algos Ecosystem.", + name: "AzureAAHosting", + description: "AA Azure Hosting Web Site", openIssues: 0, openPullRequests: 0, contributors: 1 } } }, - exchange: { - name: "Binance", - github: { - org: "AAExchange Masters", - repo: { - name: "AABinanceWrapper", - description: "Wrapps Binance Exchange to be acceced from within the Advanced Algos Ecosystem.", - openIssues: 0, - openPullRequests: 0, - contributors: 1 + underlayingCloud: "Azure", + botsRunning: { + bot: { + devTeam: "AAMasters", + codeName: "AACharly", + version: "1.0.0", + status: "Alive", + stats: { + tokens: { + totalCollected: 532.2442, + totalSpent: 323.455, + currentBalance: 142, + expensesPerHour: 1.44, + maxBalance: 177, + minBalance: 22.44 + }, + life: { + born: "2015-02-19 19:15:00.000 GMT+0000", + died: undefined, + expectedToRetire: "2019-02-19 19:15:00.000 GMT+0000", + expectedToDie: "2019-03-19 19:15:00.000 GMT+0000" + } + } + }, + bot: { + devTeam: "AAMasters", + codeName: "AACarol", + version: "1.0.0", + status: "Alive", + stats: { + tokens: { + totalCollected: 532.2442, + totalSpent: 323.455, + currentBalance: 142, + expensesPerHour: 1.44, + maxBalance: 177, + minBalance: 22.44 + }, + life: { + born: "2015-02-19 19:15:00.000 GMT+0000", + died: undefined, + expectedToRetire: "2019-02-19 19:15:00.000 GMT+0000", + expectedToDie: "2019-03-19 19:15:00.000 GMT+0000" + } + } + } + }, + stats: { + extractionBots: 2, + indicatorsBots: 24, + tradingBots: 12, + suscribers: 230, + apps: 1 + } + } + }, + exchanges: { + exchangeWrapper: { + codeName: "AAExchange-Masters", + organization: { + name: "AAExchange Masters", + type: "Open Source Project", + displayName: "Exchange Masters", + location: "Global", + leader: "Luis Molina", + logo: "AAExchange-Masters.jpg" + }, + exchangesServed: { + exchange: { + name: "Poloniex", + github: { + org: "AAExchange Masters", + repo: { + name: "AAPoloniexWrapper", + description: "Wrapps Poloniex Exchange to be acceced from within the Advanced Algos Ecosystem.", + openIssues: 0, + openPullRequests: 0, + contributors: 1 + } + } + }, + exchange: { + name: "Binance", + github: { + org: "AAExchange Masters", + repo: { + name: "AABinanceWrapper", + description: "Wrapps Binance Exchange to be acceced from within the Advanced Algos Ecosystem.", + openIssues: 0, + openPullRequests: 0, + contributors: 1 + } + } + } + } + } + }, + apps: { + app: { + organization: { + name: "AAApps Masters", + type: "Open Source Project", + displayName: "Global Ranking", + location: "Global", + leader: "Luis Molina", + logo: "AAApps-Masters.jpg" + }, + github: { + org: "AAApps Masters", + repo: { + name: "AAGlobalRanking", + description: "Global Ranking Web Site", + openIssues: 0, + openPullRequests: 0, + contributors: 1 + } + }, + web: "www.AAGlobalRanking.org", + tradingBots: { + bot: { + devTeam: "AAMasters", + codeName: "AAMichael", + version: "1.0.0", + cloudHosting: "AAOrion", + suscribers: { + subscriber: { + userName: "Trader 007", + subscription: { + type: "Trade-For-Me", + tokensPaid: 20, + expirationDatetime: "2019-03-19 19:15:00.000 GMT+0000" + } + }, + subscriber: { + userName: "EliasYofre1", + subscription: { + type: "Buy-Sell-Signals", + tokensPaid: 1, + expirationDatetime: "2019-03-19 19:15:00.000 GMT+0000" + } + } } } } } } - }, - apps: { - app: { - organization: { - name: "AAApps Masters", - type: "Open Source Project", - displayName: "Global Ranking", - location: "Global", - leader: "Luis Molina", - logo: "AAApps-Masters.jpg" - }, - github: { - org: "AAApps Masters", - repo: { - name: "AAGlobalRanking", - description: "Global Ranking Web Site", - openIssues: 0, - openPullRequests: 0, - contributors: 1 - } - }, - web: "www.AAGlobalRanking.org", - tradingBots: { - bot: { - devTeam: "AAMasters", - codeName: "AAMichael", - version: "1.0.0", - cloudHosting: "AAOrion", - suscribers: { - subscriber: { - userName: "Trader 007", - subscription: { - type: "Trade-For-Me", - tokensPaid: 20, - expirationDatetime: "2019-03-19 19:15:00.000 GMT+0000" - } - }, - subscriber: { - userName: "EliasYofre1", - subscription: { - type: "Buy-Sell-Signals", - tokensPaid: 1, - expirationDatetime: "2019-03-19 19:15:00.000 GMT+0000" - } - } - } - } + }; + + + function initialize() { + + + } + + + function getTeam(pTeamCodeName) { + + for (var team in ECOSYSTEM.devTeams) { + + if (team.codeName === pTeamCodeName) { + + return team; } } } -}; + + function getBot(pTeam, pBotCodeName) { + + for (var bot in pTeam.bots) { + + if (bot.codeName === pBotCodeName) { + + return bot; + } + } + } + + function getProduct(pBot, pProductCodeName) { + + for (var product in pBot.products) { + + if (bot.codeName === pProductCodeName) { + + return product; + } + } + } + + function getLayer(pProduct, pLayerCodeName) { + + for (var layer in pProduct.layers) { + + if (layer.codeName === pLayerCodeName) { + + return layer; + } + } + } + + function getExchange(pProduct, pName) { + + for (var exchange in pProduct.exchangeList) { + + if (exchange.name === pName) { + + return exchange; + } + } + } + +} + diff --git a/FileCache.js b/FileCache.js index bd7d3f368..f1878004b 100644 --- a/FileCache.js +++ b/FileCache.js @@ -1,71 +1,108 @@  -/* - -This module will acts as a dinamic file cache for each market. It works like this: - -1. It is always listening to the DATETIME the user is browsing and dinamically adjusts the cache according to that, meaning that it loads more files or - unload files that at far in time and unlikely to be needed. - -2. It is always listening to the PERIOD of candles and other visual objects to dinamically adjust the cache loading or unloading files according to that. - -3. It is also listening to the Layers Panel to only keep in the cache the files of visible layers. - -*/ - function newFileCache() { - const FILE_TYPES = { - candles: { - layers: ["candles"], - periods: [PERIOD_24_HS, PERIOD_12_HS, PERIOD_06_HS, PERIOD_03_HS, PERIOD_01_HS] - }, - volumes: { - layers: ["volumes"], - periods: [PERIOD_24_HS, PERIOD_12_HS, PERIOD_06_HS, PERIOD_03_HS, PERIOD_01_HS] - } - } + let marketFilesPeriods = + '[' + + '[' + 24 * 60 * 60 * 1000 + ',' + '"24-hs"' + ']' + ',' + + '[' + 12 * 60 * 60 * 1000 + ',' + '"12-hs"' + ']' + ',' + + '[' + 8 * 60 * 60 * 1000 + ',' + '"08-hs"' + ']' + ',' + + '[' + 6 * 60 * 60 * 1000 + ',' + '"06-hs"' + ']' + ',' + + '[' + 4 * 60 * 60 * 1000 + ',' + '"04-hs"' + ']' + ',' + + '[' + 3 * 60 * 60 * 1000 + ',' + '"03-hs"' + ']' + ',' + + '[' + 2 * 60 * 60 * 1000 + ',' + '"02-hs"' + ']' + ',' + + '[' + 1 * 60 * 60 * 1000 + ',' + '"01-hs"' + ']' + ']'; + + let dailyFilePeriods = + '[' + + '[' + 45 * 60 * 1000 + ',' + '"45-min"' + ']' + ',' + + '[' + 40 * 60 * 1000 + ',' + '"40-min"' + ']' + ',' + + '[' + 30 * 60 * 1000 + ',' + '"30-min"' + ']' + ',' + + '[' + 20 * 60 * 1000 + ',' + '"20-min"' + ']' + ',' + + '[' + 15 * 60 * 1000 + ',' + '"15-min"' + ']' + ',' + + '[' + 10 * 60 * 1000 + ',' + '"10-min"' + ']' + ',' + + '[' + 05 * 60 * 1000 + ',' + '"05-min"' + ']' + ',' + + '[' + 04 * 60 * 1000 + ',' + '"04-min"' + ']' + ',' + + '[' + 03 * 60 * 1000 + ',' + '"03-min"' + ']' + ',' + + '[' + 02 * 60 * 1000 + ',' + '"02-min"' + ']' + ',' + + '[' + 01 * 60 * 1000 + ',' + '"01-min"' + ']' + ']'; let fileCache = { - getFile: getFile, + getMarketFile: getMarketFile, + getFileCursor: getFileCursor, initialize: initialize } - let exchange; - let market; + let fileCloud; - let files = new Map; + let marketFiles = new Map; return fileCache; - function initialize(pExchange, pMarket, callBackFunction) { + function initialize(pTeamCodeName, pBotCodeName, pProductCodeName, pLayerCodeName, pExchange, pMarket, pDatetime, callBackFunction) { - exchange = pExchange; - market = pMarket; - - let server; + let product = ecosystem.getProduct(ecosystem.getBot(ecosystem.getTeam(pTeamCodeName), pBotCodeName), pProductCodeName); - server = newFileServer(); - server.initialize(); + if (product === undefined) { - server.getMarketIndexCandles(exchangeId, marketId, onCandlesReady); + throw "Product not found at this bot of the ecosystem! - pTeamCodeName = " + pTeamCodeName + " pBotCodeName = " + pBotCodeName + " pProductCodeName = " + pProductCodeName; + return; + } - function onCandlesReady(data) { + let exchange = ecosystem.getExchange(product, name); - dataCache.candles = data; + if (exchange === undefined) { - server.getMarketIndexVolumes(exchangeId, marketId, onVolumesReady); + throw "Exchange not supoorted by this product of the ecosystem! - pTeamCodeName = " + pTeamCodeName + " pBotCodeName = " + pBotCodeName + " pProductCodeName = " + pProductCodeName + " pExchange = " + pExchange; + return; + } - function onVolumesReady(data) { + let layer = ecosystem.getLayer(product, pLayerCodeName); - dataCache.volumes = data; + if (layer === undefined) { - callBackFunction(); + throw "Layer not found at this product of the ecosystem! - pTeamCodeName = " + pTeamCodeName + " pBotCodeName = " + pBotCodeName + " pProductCodeName = " + pProductCodeName + " pLayerCodeName = " + pLayerCodeName; + return; + } + fileCloud = newFileCloud(); + fileCloud.initialize(pTeamCodeName, pBotCodeName); + + let filesReceived = 0; + + for (i = 0; i < marketFilesPeriods; i++) { + + let periodTime = marketFilesPeriods[i][0]; + let periodName = marketFilesPeriods[i][1]; + + if (layer.validPeriods.includes(periodName) === true) { + + fileCloud.getMarketFile(product, exchange, pMarket, periodName, onFileReceived); + + function onFileReceived(file) { + + marketFiles.set(periodTime, file); + + filesReceived++; + + if (filesReceived === layer.validPeriods.lenght + 1) { + + callBackFunction(); + + } + } } } } - function getFile(pName, pPeriod, pDatetime) { + + function getMarketFile(pPeriod) { + + marketFiles.get(pPeriod); + + } + + + function getFileCursor(pPeriod, pDatetime) { diff --git a/FileCloud.js b/FileCloud.js index 8b1350c7a..20424c1ac 100644 --- a/FileCloud.js +++ b/FileCloud.js @@ -1,96 +1,35 @@  -/* +function newFileCloud() { -This module gets the requested file from the appropiate cloud storage account. - -*/ - - -function newFileServer() { - - const EXCHANGE_NAME = "Poloniex"; - - const CANDLES_FOLDER_NAME = "Candles"; - const CANDLES_ONE_MIN = "One-Min"; - - const VOLUMES_FOLDER_NAME = "Volumes"; - const VOLUMES_ONE_MIN = "One-Min"; - - var httpServer; // This is the object that allows as to make calls to the fileServer. - - var fileServer = { - getOrderBook: getOrderBook, - getAggregattedOrderBook: getAggregattedOrderBook, - getMarkets: getMarkets, - getLastTrades: getLastTrades, - getTrades: getTrades, - getMarketIndexCandles: getMarketIndexCandles, - getMarketIndexVolumes: getMarketIndexVolumes, - getAllTimes: getAllTimes, - getDailyFile: getDailyFile, + var fileCloud = { + getMarketFile: getMarketFile, initialize: initialize }; - const account = 'aadata'; - const sas = '?sv=2017-04-17&ss=f&srt=sco&sp=r&se=2018-12-01T00:09:44Z&st=2017-12-01T13:09:44Z&spr=https,http&sig=J60UlQuUqh9Hd1Pm0PqIF6yari3D3TkGEz1fSNQJWks%3D'; - const fileUri = 'https://' + account + '.file.core.windows.net'; - let fileService; - let charlyFileService; - let carolFileService; - let bruceFileService; - let oliviaFileService; + return fileCloud; - const genericBot = { - account: 'aadata', - sas: '?sv=2017-04-17&ss=f&srt=sco&sp=r&se=2018-12-01T00:09:44Z&st=2017-12-01T13:09:44Z&spr=https,http&sig=J60UlQuUqh9Hd1Pm0PqIF6yari3D3TkGEz1fSNQJWks%3D', - fileUri: 'https://' + 'aadata' + '.file.core.windows.net' - }; + function initialize(pTeamCodeName, pBotCodeName) { - const charlyBot = { - sas: '?sv=2017-04-17&ss=f&srt=sco&sp=rc&se=2018-12-31T02:33:36Z&st=2018-02-01T18:33:36Z&spr=https&sig=xFTcopdKq0f60wl2iuukbtIpcLwxZVKzlw5BzpJfo5g%3D', - fileUri: 'https://' + 'aacharly' + '.file.core.windows.net' - }; + let bot = ecosystem.getBot(ecosystem.getTeam(pTeamCodeName), pBotCodeName); - const carolBot = { - sas: '?sv=2017-04-17&ss=f&srt=sco&sp=r&se=2018-12-01T00:09:44Z&st=2017-12-01T13:09:44Z&spr=https,http&sig=J60UlQuUqh9Hd1Pm0PqIF6yari3D3TkGEz1fSNQJWks%3D', - fileUri: 'https://' + 'aadata' + '.file.core.windows.net' - }; - - const bruceBot = { - sas: '?sv=2017-04-17&ss=f&srt=sco&sp=r&se=2018-12-31T02:32:04Z&st=2018-02-01T18:32:04Z&spr=https&sig=SbZI6bvAE1MBxna2NOvfgMroPFZNjAyaHUsAPvh11hg%3D', - fileUri: 'https://' + 'aabruce' + '.file.core.windows.net' - }; - - const oliviaBot = { - sas: '?sv=2017-04-17&ss=f&srt=sco&sp=rl&se=2018-12-31T02:34:32Z&st=2018-02-01T18:34:32Z&spr=https,http&sig=24UJjGDVpPrHjhBoZtt3iKj4sxgenfSV4VTJD2v0q1U%3D', - fileUri: 'https://' + 'aaolivia' + '.file.core.windows.net' - }; - - return fileServer; - - function initialize() { - - httpServer = new XMLHttpRequest(); - - fileService = AzureStorage.createFileServiceWithSas(fileUri, sas).withFilter(new AzureStorage.ExponentialRetryPolicyFilter()); - - charlyFileService = AzureStorage.createFileServiceWithSas(charlyBot.fileUri, charlyBot.sas).withFilter(new AzureStorage.ExponentialRetryPolicyFilter()); - carolFileService = AzureStorage.createFileServiceWithSas(carolBot.fileUri, carolBot.sas).withFilter(new AzureStorage.ExponentialRetryPolicyFilter()); - bruceFileService = AzureStorage.createFileServiceWithSas(bruceBot.fileUri, bruceBot.sas).withFilter(new AzureStorage.ExponentialRetryPolicyFilter()); - oliviaFileService = AzureStorage.createFileServiceWithSas(oliviaBot.fileUri, oliviaBot.sas).withFilter(new AzureStorage.ExponentialRetryPolicyFilter()); + fileService = AzureStorage.createFileServiceWithSas(bot.storage.fileUri, bot.storage.sas).withFilter(new AzureStorage.ExponentialRetryPolicyFilter()); } - function getMarketIndexCandles(exchangeId, marketId, callBackFunction) { + function getMarketFile(pProduct, pExchange, pMarket, pPeriodName, callBackFunction) { - //let fileName = '' + market.assetA + '_' + market.assetB + '.json'; + let fileName = pProduct.fileName; + let filePath = pProduct.filePath; - let fileName = '' + 'USDT' + '_' + 'BTC' + '.json'; - let filePath = EXCHANGE_NAME + "/Output/" + CANDLES_FOLDER_NAME + "/24-hs-Market"; + fileName.replace("@AssetA", pMarket.assetA); + fileName.replace("@AssetB", pMarket.assetB); - oliviaFileService.getFileToText('data', filePath, fileName, undefined, onFileReceived); + filePath.replace("@Exchange", pExchange.name); + filePath.replace("@Period", pPeriodName); + + fileService.getFileToText('data', filePath, fileName, undefined, onFileReceived); function onFileReceived(err, text, response) { @@ -117,273 +56,6 @@ function newFileServer() { } } - - function getMarketIndexVolumes(exchangeId, marketId, callBackFunction) { - - //let fileName = '' + market.assetA + '_' + market.assetB + '.json'; - - let fileName = '' + 'USDT' + '_' + 'BTC' + '.json'; - let filePath = EXCHANGE_NAME + "/Output/" + VOLUMES_FOLDER_NAME + "/24-hs-Market"; - - oliviaFileService.getFileToText('data', filePath, fileName, undefined, onFileReceived); - - function onFileReceived(err, text, response) { - - let data; - - if (err) { - - data = JSON.parse("[]"); - - } else { - - try { - - data = JSON.parse(text); - - } catch (err) { - - data = JSON.parse("[]"); - - } - } - - callBackFunction(data); - - } - } - - - function getAllTimes(exchangeId, marketId, callBackFunction) { - - let fileName = exchangeId + "_" + marketId + ".json"; - - fileService.getFileToText('data', 'all-times', fileName, undefined, onFileReceived); - - function onFileReceived(err, text, response) { - - if (err) { - - let data = JSON.parse("[]"); - callBackFunction(data); - - } else { - - let data = JSON.parse(text); - callBackFunction(data); - - } - } - } - - - function getDailyFile(exchangeId, marketId, date, callBackFunction) { - - let fileName = '' + 'USDT' + '_' + 'BTC' + '.json'; - - let dateForPath = date.getUTCFullYear() + '/' + pad(date.getUTCMonth() + 1, 2) + '/' + pad(date.getUTCDate(), 2); - - let filePath = EXCHANGE_NAME + "/Output/" + CANDLES_FOLDER_NAME + '/' + CANDLES_ONE_MIN + '/' + dateForPath; - - bruceFileService.getFileToText('data', filePath, fileName, undefined, onFileReceived); - - function onFileReceived(err, text, response) { - - let data; - - if (err) { - - data = JSON.parse("[]"); - - } else { - - try { - - data = JSON.parse(text); - - } catch (err) { - - data = JSON.parse("[]"); - - } - } - - callBackFunction(data); - - } - - } - - - - - function getMarkets(exchangeId, callBackFunction) { - - let fileName = "Markets_" + exchangeId + "_USDT_BTC" + ".json"; - - fileService.getFileToText('data', 'other-files', fileName, undefined, onFileReceived); - - function onFileReceived(err, text, response) { - - if (err) { - - let data = JSON.parse("[]"); - callBackFunction(data); - - } else { - - var fileString = text; - let cleanString = fileString; - - /* Dont know why but sometimes files comes with a first characater that is not supposed to be there and you can not see it at the file opened with notepad */ - - if (fileString[0] !== "[") { - - cleanString = ''; - - for (let i = 1; i < fileString.length; i++) { - cleanString = cleanString + fileString[i]; - } - } - - let data = JSON.parse(cleanString); - callBackFunction(data); - - } - } - } - - - - function getAggregattedOrderBook(exchangeId, marketId, date, callBackFunction) { - - let stringDate = date.getFullYear() + '/' + pad(date.getMonth() + 1, 2) + '/' + pad(date.getDate(), 2) + '/' + pad(date.getHours(), 2) + '/' + pad(date.getMinutes(), 2); - - let fileName = stringDate + "/" + exchangeId + "_" + marketId + ".json"; - - fileService.getFileToText('data', 'aggregatted-order-books', fileName, undefined, onFileReceived); - - function onFileReceived(err, text, response) { - - if (err) { - - let data = JSON.parse("[]"); - callBackFunction(data); - - } else { - - let data = JSON.parse(text); - callBackFunction(data); - - } - } - - } - - - - function getOrderBook(exchangeId, marketId, date, callBackFunction) { - - let stringDate = date.getFullYear() + '/' + pad(date.getMonth() + 1, 2) + '/' + pad(date.getDate(), 2) + '/' + pad(date.getHours(), 2) + '/' + pad(date.getMinutes(), 2); - - let fileName = stringDate + "/" + exchangeId + "_" + marketId + ".json"; - - fileService.getFileToText('data', 'order-books', fileName, undefined, onFileReceived); - - function onFileReceived(err, text, response) { - - if (err) { - - let data = JSON.parse("[]"); - callBackFunction(data); - - } else { - - let data = JSON.parse(text); - callBackFunction(data); - - } - } - } - - - - - function getLastTrades(marketId, exchangeId, callBackFunction) { - - requestTrades(); - - function requestTrades() { - - httpServer = new XMLHttpRequest(); - httpServer.open('GET', "lastTrades/" + marketId + "/" + exchangeId, true); - httpServer.send(); - - httpServer.onreadystatechange = onHttpServerResponded; - - function onHttpServerResponded(err) { - - checkResponse(callBackFunction); - - } - } - - } - - - - function getTrades(idBegin, idEnd, marketId, exchangeId, callBackFunction) { - - requestTrades(); - - function requestTrades() { - - httpServer = new XMLHttpRequest(); - httpServer.open('GET', "trades/" + marketId + "/" + exchangeId + "/" + idBegin + "/" + idEnd, true); - httpServer.send(); - - httpServer.onreadystatechange = onHttpServerResponded; - - function onHttpServerResponded(err) { - - checkResponse(callBackFunction); - - } - } - } - - - - - function checkResponse(callBackFunction) { - - if (httpServer.status === 404) { - - let data = JSON.parse("[]"); - - callBackFunction(data); - - } - - if (httpServer.readyState === 4 && httpServer.status === 200) { - - let data; - - try { - - data = JSON.parse(httpServer.responseText); - - } catch (err) { - - data = JSON.parse("[]"); - - } - - callBackFunction(data); - - } - } - } diff --git a/FileServer.js b/FileServer.js index 7bf35116c..e4a6a5a04 100644 --- a/FileServer.js +++ b/FileServer.js @@ -1,6 +1,6 @@  - +/* This module is about to be replaced by FileClound. */ function newFileServer() { @@ -20,7 +20,7 @@ function newFileServer() { getMarkets: getMarkets, getLastTrades: getLastTrades, getTrades: getTrades, - getMarketIndexCandles: getMarketIndexCandles, + getMarketFilesCandles: getMarketFilesCandles, getMarketIndexVolumes: getMarketIndexVolumes, getAllTimes: getAllTimes, getDailyFile: getDailyFile, @@ -79,7 +79,7 @@ function newFileServer() { } - function getMarketIndexCandles(exchangeId, marketId, callBackFunction) { + function getMarketFilesCandles(exchangeId, marketId, callBackFunction) { //let fileName = '' + market.assetA + '_' + market.assetB + '.json'; diff --git a/MarketIndex.js b/MarketIndex.js index e6f5c16e5..63942a6c3 100644 --- a/MarketIndex.js +++ b/MarketIndex.js @@ -25,7 +25,7 @@ function newMarketIndex() { server = newFileServer(); server.initialize(); - server.getMarketIndexCandles(exchangeId, marketId, onCandlesReady); + server.getMarketFilesCandles(exchangeId, marketId, onCandlesReady); function onCandlesReady(data) { diff --git a/Panels/ChartLayersPanel.js b/Panels/ChartLayersPanel.js index c730fdf15..0dec6e1f0 100644 --- a/Panels/ChartLayersPanel.js +++ b/Panels/ChartLayersPanel.js @@ -10,6 +10,7 @@ function newChartLayersPanel() { }; const LAYER_NAMES = { + OLIVIA_CANDLES: 'Olivia Candlesticks', CANDLESTICKS: 'Candlesticks', VOLUME: 'Volume', ATH: 'All-time Highs and Lows', @@ -50,7 +51,7 @@ function newChartLayersPanel() { function initialize() { this.container.frame.width = 200; - this.container.frame.height = 170; + this.container.frame.height = 200; var position = { x: viewPort.visibleArea.topRight.x - this.container.frame.width, @@ -61,7 +62,7 @@ function newChartLayersPanel() { var buttonPosition; - var buttonNames = [LAYER_NAMES.CANDLESTICKS, LAYER_NAMES.VOLUME, LAYER_NAMES.ATH, LAYER_NAMES.HIGH_LOWS, LAYER_NAMES.FORECAST, LAYER_NAMES.ORDER_BOOKS, LAYER_NAMES.CANDLE_STAIRS, LAYER_NAMES.VOLUME_STAIRS, LAYER_NAMES.BUY_SELL_BALANCE, LAYER_NAMES.LINEAR_REGRESION_CURVE]; + var buttonNames = [LAYER_NAMES.OLIVIA_CANDLES,LAYER_NAMES.CANDLESTICKS, LAYER_NAMES.VOLUME, LAYER_NAMES.ATH, LAYER_NAMES.HIGH_LOWS, LAYER_NAMES.FORECAST, LAYER_NAMES.ORDER_BOOKS, LAYER_NAMES.CANDLE_STAIRS, LAYER_NAMES.VOLUME_STAIRS, LAYER_NAMES.BUY_SELL_BALANCE, LAYER_NAMES.LINEAR_REGRESION_CURVE]; var lastY = 5; buttons = []; diff --git a/TimelineChart.js b/TimelineChart.js index 39099bafe..aa10babca 100644 --- a/TimelineChart.js +++ b/TimelineChart.js @@ -93,6 +93,23 @@ function newTimelineChart() { function initializeLayers() { + /* AAMasters AAOlivia Candlesticks */ + + var layerAAMastersAAOliviaCandlesticks = newAAMastersAAOliviaCandlesticks(); + + layerAAMastersAAOliviaCandlesticks.container.displacement.parentDisplacement = timelineChart.container.displacement; + layerAAMastersAAOliviaCandlesticks.container.zoom.parentZoom = timelineChart.container.zoom; + layerAAMastersAAOliviaCandlesticks.container.frame.parentFrame = timelineChart.container.frame; + + layerAAMastersAAOliviaCandlesticks.container.parentContainer = timelineChart.container; + + layerAAMastersAAOliviaCandlesticks.container.frame.width = timelineChart.container.frame.width * 1; + layerAAMastersAAOliviaCandlesticks.container.frame.height = timelineChart.container.frame.height * 1; + + layerAAMastersAAOliviaCandlesticks.container.frame.position.x = timelineChart.container.frame.width / 2 - layerAAMastersAAOliviaCandlesticks.container.frame.width / 2; + layerAAMastersAAOliviaCandlesticks.container.frame.position.y = timelineChart.container.frame.height / 2 - layerAAMastersAAOliviaCandlesticks.container.frame.height / 2; + + layerAAMastersAAOliviaCandlesticks.initialize(DEFAULT_EXCHANGE, DEFAULT_MARKET, INITIAL_DATE, INITIAL_TIME_PERIOD, chartLayersPanel); /* All Time Layer */ @@ -310,6 +327,8 @@ function newTimelineChart() { /* Add all layers to the internal array */ + timelineChart.layers.push(layerAAMastersAAOliviaCandlesticks); + timelineChart.layers.push(allTimeChartLayer); timelineChart.layers.push(orderBooksChartLayer); timelineChart.layers.push(forecastChartLayer); @@ -338,6 +357,8 @@ function newTimelineChart() { /* Connecting all layers to the panel that provides a user interface to turn them on - visible - off */ + chartLayersPanel.container.eventHandler.listenToEvent("Layer Status Changed", layerAAMastersAAOliviaCandlesticks.onLayerStatusChanged); + chartLayersPanel.container.eventHandler.listenToEvent("Layer Status Changed", accumulatedVolumeChartLayer.onLayerStatusChanged); chartLayersPanel.container.eventHandler.listenToEvent("Layer Status Changed", candleStickChartLayer.onLayerStatusChanged); chartLayersPanel.container.eventHandler.listenToEvent("Layer Status Changed", candleTechnicalAnalisysChartLayer.onLayerStatusChanged); diff --git a/index.html b/index.html index bf0de4ee1..ee4997093 100644 --- a/index.html +++ b/index.html @@ -5,6 +5,8 @@ Advanced Algos + + @@ -47,6 +49,8 @@ + +