From e393232c7a115bea290f26b95d257342ae0ed9fd Mon Sep 17 00:00:00 2001 From: Luis Fernando Molina Date: Tue, 27 Feb 2018 15:50:04 +0100 Subject: [PATCH 01/54] Initial commit --- .gitattributes | 2 + .vs/AAMariam-Plotter/v15/.suo | Bin 0 -> 16896 bytes .vs/AAOlivia-Plotter/v15/.suo | Bin 0 -> 17920 bytes AAMariam-Plotter.njsproj | 67 ++ AAMariam-Plotter.sln | 25 + Details.js | 762 ++++++++++++++++++ History.js | 694 ++++++++++++++++ README.md | 1 + bin/Microsoft.NodejsTools.WebRole.dll | Bin 0 -> 32992 bytes ...ia-Plotter.njsproj.CoreCompileInputs.cache | 1 + ...livia-Plotter.njsproj.FileListAbsolute.txt | 3 + ...tter.njsprojResolveAssemblyReference.cache | Bin 0 -> 2216 bytes 12 files changed, 1555 insertions(+) create mode 100644 .gitattributes create mode 100644 .vs/AAMariam-Plotter/v15/.suo create mode 100644 .vs/AAOlivia-Plotter/v15/.suo create mode 100644 AAMariam-Plotter.njsproj create mode 100644 AAMariam-Plotter.sln create mode 100644 Details.js create mode 100644 History.js create mode 100644 README.md create mode 100644 bin/Microsoft.NodejsTools.WebRole.dll create mode 100644 obj/Debug/AAOlivia-Plotter.njsproj.CoreCompileInputs.cache create mode 100644 obj/Debug/AAOlivia-Plotter.njsproj.FileListAbsolute.txt create mode 100644 obj/Debug/AAOlivia-Plotter.njsprojResolveAssemblyReference.cache diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 000000000..dfe077042 --- /dev/null +++ b/.gitattributes @@ -0,0 +1,2 @@ +# Auto detect text files and perform LF normalization +* text=auto diff --git a/.vs/AAMariam-Plotter/v15/.suo b/.vs/AAMariam-Plotter/v15/.suo new file mode 100644 index 0000000000000000000000000000000000000000..d1501bee538092438849e0f631d8a14e119713c7 GIT binary patch literal 16896 zcmeHOOKcle6n*Z8e)zQ%N@)vCODUmrj9oiUCKVqiZYUyAqb6w)vMM?8ICbjSk;h3} zn(PolY(Zj)kXXP1Ay$Y55^FZC)D^ozSKT0%Y-l)VCNCaOGM6d9zoxbpMFU`96MTW979|B^)qPyYZV|soBqEK?|ByZ z9B@DI0Fc*d69<8ZfQNxE0(rdy{|^m>>HoCrX0Ydr%lGO3PoUGUJOHHsJxu>U4Z0!v zzwh`%J>3e?|2YqD2hyT&a)lUre6-R_S|Oij9H4J9H17cJ1nvehRy+>my(e)d|4##{ z!~;(vDTr-Y!t@MMwH3pk+ZGNQh$R2~B#u3n=i6Y*9&5@FP zqVXIg|FzPefIQ5)b0QDwd7IRAIUA|gzd`>E^H2SbbIT8XxAn*g=%4Fe=C@wQ-w*u^ zw6Y-LBIzK`sTSowhf&WPx-Y}>OBjtIj7G`0QiWBx0qvhTKl6hi@(*C-r{Mq7@PGv$%zsTU*H>j{K5XZW+|d86kb?YNS216s4y^Z_+8iqxe;VnJV-)5w>b2GNc-5F0 zq;}T6F&04oR{N)YPlDz&K8%8wj4_|WEWjA(4qXBC&zx53-%fu3JZRwIDs)|eO)%y* z-fvup6|#&O3t*iph;OT88YW_^%`um z0@;gAJ%HoS9C4oy`bW|CJ|}HJGx`&tPMc^J2jG7Z=Az6&y~=O3Kf8~a^K1c9PeUtJ z!y3)VKyKFp;;#{ZIHq3dGgnzyk^elbe@2WL@y|ZTUle_73EHkO{*o@&XkO`ae`bX| zbld2EG9O_a=6vjCkBmR0%Y7ZM^vSEtzwGpx|ByDvh5C2P!DRgB8pA7nu63RKzfS)K ze1aKa3B8?x{ztkJoO{;qSnba){|K}`3##0Qwfdq{45IyUJQ>r-L!F9qi}}j<%56LS z_2ZwFlg9TZAwPA=wVqe{v^}TsHz{!jGIwIrh=gPTYw|3x9*eW^17;`846-7P551;}o;k!V z1wO;oTn!)2+*wz)S{?tpe|d{}PK+>jAQFP`0z2C+zVErZtMbp!?|%2yw%-b}i0X)&E1$yJNF zS!J|TsnxV9-Yw_ z7jMRs`FO9IiYo=JC$1z@$-JV*<8fswnJdKO`QE&$=9U=y==Fr+JDY{)OxqacT0|mq z3E7rsuk|0h{fwZ(V3K^Hp6 z^=BCMANmc~QC{gEL0_4-%l(#C>OYLX(o)cL1^S)r)NKFF>;9kId-Ezk>s7255}MJM zs}Z;TKh9)+_8+YBhp_)={N9NtbDnI6{LI2!>VJm*Nt*yRT*0dUPW_KNyqmlJ$Gvy?8vxhAM~ATMf1FEMgA8JS z^;O2^uK)R||5INDAi*xbTfN16s(xhsgY^vlCeN$>8|#0K^`9X7|D-FS&Y5$IbC1lw z?DBW^|DE;bbVur*XQw_+*X{b3`KX`zAM+VMzdz{I|LWsp*METepW*k?2Asy(dfi(8 z>(qa&ntAx`PW`7fopbHbQ5GhQ?+@qj!7a)W9FC*P)%XtrU3B5M8MG?$Pls+_ z{_NhLe}D4+mm~K|cRp@Lt8;Iy20|^a?XK73Qo+i20UtY+(@yv1Qj;-7OC)=g>s>$6Lj6bo&g|~Y z{{Q^1`De!Y;q2CPAAE7=&!P$Ti>t)>3!BA8?RiM6i<^YlihDjgf8oLfzG5BKKKzFy za72{xR~3Wepjbdz5vQn1->_Y5sOkLb7QIFvIPm)9=Rbz7L%UHL4`31$%VJ(U4eGO~ z9TX?+7e24s#Xv|Gx1VlVG=lj`Q1nT6QIx&kVPJ7I_=zwU1Fd%e)8egPJey_ zZq7Q+G$EEir6h_NKXFc@oW+xh-f@jO=!fW|w*mdqH_-Mk=UX?U{6`m{Q{Uu#ZyQQ} z|5o4@;PpWAe123$nLx+61F?f?7NGvJMjMY7Hux>)qm1033Su{Z-E{? z;hRLw|6g+)Q2F0_`hOZscG3Ssv|*(W&+$7iFDL(3d~X16j04J->Hn-#r}Y18fNuV; zzQIz(0M^-G#UxC{6Ia5wNl;6uQNfsX(m1?~Zcff3+iz$h>V+zX5Y z6Tl&$qOZykJlh9+Tzhu_^-=A9{Um;QQ5r+WQx?a?31mAJlz#Ibh)%-Y$bUkpDZh6f zdltiZOWhKtK-U7@L&$Y3WI{*9%Q6S6iW!+1S#~qmEAyWLyrmsdvaSua7b(;k-w4y7 zIwfUL5-*`V2@aV5ErXw#mf4>WJ3*g05p!C<^pj|-a%JY7%rYy;{qo2I$3eG*d#jci zo8Y4=GT@E*xhb!8sf>U=eQz)TefkBOOUQs4HDEy!MST4gS4yf!W7$srtJ6P*@i6Po zivp+@nnqn8XCu}69pqn|d;Q8k2>n*;k=>9#V;tjIFX(3>m1RUZ#2~NJ zg>}t1Qm4&R3l&7zqtHo7dSFpnUIZR$Yl)V)B(0GA>~BNJM;LHC)obweAe(3A|HwMq2 zLHwVC)!BAcs99PT@3;#00{Wk#?RWf)*UTFT&33NhEV(I(3G4|}AtA=zwPg`$!~Qu} zFjpd|^^YCpt=ibR9%|-|+)z(CBr$&GSYj-PY2nt!qw8)w=R^2=56EJnM4C{V^s zFo~;$doKw@L7(}b(gCV1VFy}lMgJJ6Ga7l>0pu_B&v@c@{JQ-$%h=ZcEJi&C zsZ^u|+WMF5UUWhHmGqep`=!q{(K3@3zyz|6d2v|Uzp_0w$4?7pO5VWygKOEVfPU$7 zPsSk+*_z;B3H0Zrtj92B6Qe#3TPsUjs6q?6RW$OGXv6+VTgCro`ZgtIg7!{a8hk85 zKJ-9ZBA@C2`>)xa-|;hFRrars>@dd7EXElYdP!p(Xoo)eXAB@r zfyN>z(az~>969yR+>^55+#i*zAG>|?^%3Zw`sDh`@A!55ZZf7 zqt2p89P5;b)Nt=F2|7(?ltN70~reFFDJu3b-kH1d;6tvA1K?$wh0rUggpO^d( zL)Isxm7i+xx<;$3^P}=V?#=ieKV!v|^9kA^{oztUH)yL^rjMbMXZm+~T@Q6AeHF*r z<&*M%0hkdZA}7?0YoUG!{>ONf1J->p2cKj#U}lgLY5YyVLyB^}oX76WB<^^gWUpy+ zE!pZ+|L1-Wp7ZKVao#2p+TjIuwncn4bbNF9?=w$+^8VG|ziX_1tUkm**8=F*Hhpvo ziD)Z{Mi3q6A^Sz>f#+szbh$=SvWNRts8@;)J`f>Fy<#RKXZ8YYlk;~(O7IvYPenZy z#RRMWg==@-HN6k(gnB7&{ap^j(@OA|B4$0VcPh9p$*jQEu@Fzl{EoYr+y^)fGKNTs zG3Z}UL-61%{B|6uRgX;dD{mb8>Q9h7bD^bEQnUbJu_3RfWiV!%m*QzNkq>G z&akta!$8E#S zfcP+!9f{)abksfaVWd|Xp&6S9#nE2!%v@9;f z&ocI|%d@rFvw5dQaokuAwz2-^%;&cLUwi+nk*0q4P#g5Q_c7~yq5epKo3T)PJ-5yyULl(O1;`(>(w6&wtkU{AU+-DH?wPW{E-k7Kj^JG3;mX>IFPYSjOt9 zH@nA;`*zGi`C9>d|IXgMTj&|>X~>1YfU(c~6iwQ$4vZxP6+i4d|JRo%|hT|NO_lu6oh3fBw^%RQu;Yfsc&(=RcR(`A;Vv&_DliKbz{G z|9G86{U6SMf}gDP@+_r$r&P!)*XjJnjpyK!9T3?|A>81MZmD-k203i(xZ9q*xi^(h zz7!3c@x)L#v3GblY$OY_;UP0W8#fZB8BZFKXf&2gBv+azh1&)H&*g2k-oR`A%!J|p zl88O{$?KMSmq23gxLX&*{=BA*BI>(=Tsd*|OZXhBm`15TlP`LHdG0LZc>Cby|8=SR vJz4Mj|JuJ%sE3U%7^1G|4`FoA;6dO2y?+|g1+k~Ku=})A*M0rJ>;L}(48i4e literal 0 HcmV?d00001 diff --git a/AAMariam-Plotter.njsproj b/AAMariam-Plotter.njsproj new file mode 100644 index 000000000..762c10990 --- /dev/null +++ b/AAMariam-Plotter.njsproj @@ -0,0 +1,67 @@ + + + + Debug + 2.0 + {096b35ad-f86f-47b9-a99f-04ca93397da8} + + ShowAllFiles + History.js + . + . + {3AF33F2E-1136-4D97-BBB7-1795711AC8B8};{349c5851-65df-11da-9384-00065b846f21};{9092AA53-FB77-4645-B42D-1CCCA6BD08BD} + 14.0 + $(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion) + AAMariam-Plotter + + + + + + + Code + + + + + + + + + + + False + True + 0 + / + http://localhost:48022/ + False + True + http://localhost:1337 + False + + + + + + + CurrentPage + True + False + False + False + + + + + + + + + False + False + + + + + \ No newline at end of file diff --git a/AAMariam-Plotter.sln b/AAMariam-Plotter.sln new file mode 100644 index 000000000..83a9e865a --- /dev/null +++ b/AAMariam-Plotter.sln @@ -0,0 +1,25 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio 15 +VisualStudioVersion = 15.0.27130.2027 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{9092AA53-FB77-4645-B42D-1CCCA6BD08BD}") = "AAMariam-Plotter", "AAMariam-Plotter.njsproj", "{096B35AD-F86F-47B9-A99F-04CA93397DA8}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {096B35AD-F86F-47B9-A99F-04CA93397DA8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {096B35AD-F86F-47B9-A99F-04CA93397DA8}.Debug|Any CPU.Build.0 = Debug|Any CPU + {096B35AD-F86F-47B9-A99F-04CA93397DA8}.Release|Any CPU.ActiveCfg = Release|Any CPU + {096B35AD-F86F-47B9-A99F-04CA93397DA8}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {E75EDC9D-66A7-4C54-8EA1-5ADC148CACA8} + EndGlobalSection +EndGlobal diff --git a/Details.js b/Details.js new file mode 100644 index 000000000..ae1961bf6 --- /dev/null +++ b/Details.js @@ -0,0 +1,762 @@ +function newAAMastersAAOliviaVolumes() { + + let thisObject = { + + // Main functions and properties. + + initialize: initialize, + container: undefined, + getContainer: getContainer, + setTimePeriod: setTimePeriod, + setDatetime: setDatetime, + draw: draw, + + // Secondary functions and properties. + + onLayerStatusChanged: onLayerStatusChanged + }; + + /* this is part of the module template */ + + let container = newContainer(); // Do not touch this 3 lines, they are just needed. + container.initialize(); + thisObject.container = container; + + let layerStatus = 'off'; // Since the moduleis a layer, it must handle the different possible layer status. + + let plotArea = newPlotArea(); // Needed to be able to plot on the timeline, otherwise not. + let plotAreaFrame = newPlotArea(); // This chart uses this extra object. + + let timePeriod; // This will hold the current Time Period the user is at. + let datetime; // This will hold the current Datetime the user is at. + + let marketFile; // This is the current Market File being plotted. + let fileCursor; // This is the current File Cursor being used to retrieve Daily Files. + + let fileCache; // This object will provide the different Market Files at different Time Periods. + let fileCursorCache; // This object will provide the different File Cursors at different Time Periods. + + /* these are module specific variables: */ + + let volumes = []; // Here we keep the volumes to be ploted every time the Draw() function is called by the AAWebPlatform. + + return thisObject; + + function initialize(pExchange, pMarket, pDatetime, pTimePeriod, pLayerStatus, callBackFunction) { + + let cursorCacheInProgress = false; + let finaleStepsInProgress = false; + + datetime = pDatetime; + timePeriod = pTimePeriod; + + fileCache = newFileCache(); + fileCache.initialize("AAMasters", "AAOlivia", "Market Volumes", "Market Volumes", pExchange, pMarket, onFileReady); + + function onFileReady() { + + let newMarketFile = fileCache.getFile(ONE_DAY_IN_MILISECONDS); + + if (newMarketFile !== undefined) { + + marketFile = newMarketFile; + + initializeFileCursorCache(); + + } + } + + function initializeFileCursorCache() { + + if (cursorCacheInProgress === false) { + + cursorCacheInProgress = true; + + fileCursorCache = newFileCursorCache(); + fileCursorCache.initialize("AAMasters", "AAOlivia", "Daily Volumes", "Daily Volumes", pExchange, pMarket, pDatetime, pTimePeriod, onFileCursorReady); + + } + } + + function onFileCursorReady() { + + recalculate(); + + let newFileCursor = fileCursorCache.getFileCursor(pTimePeriod); + + if (newFileCursor !== undefined) { // if the file ready is the one we need then it and we dont have it yet, then we will continue here. + + let stringDate = datetime.getUTCFullYear() + '-' + pad(datetime.getUTCMonth() + 1, 2) + '-' + pad(datetime.getUTCDate(), 2); + + let dailyFile = newFileCursor.files.get(stringDate); + + if (dailyFile !== undefined) { + + if (finaleStepsInProgress === false) { + + finaleStepsInProgress = true; + + fileCursor = newFileCursor; + + layerStatus = pLayerStatus; + + recalculateScaleX(); + recalculate(); + recalculateScaleY(); + + viewPort.eventHandler.listenToEvent("Zoom Changed", onZoomChanged); + canvas.eventHandler.listenToEvent("Drag Finished", onDragFinished); + + callBackFunction(); + + } + } + } + + } + + } + + function getContainer(point) { + + if (layerStatus !== 'on') { return; } + + let 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 setTimePeriod(pTimePeriod) { + + timePeriod = pTimePeriod; + + if (timePeriod >= _1_HOUR_IN_MILISECONDS) { + + let newMarketFile = fileCache.getFile(pTimePeriod); + + if (newMarketFile !== undefined) { + + marketFile = newMarketFile; + + recalculate(); + + } + + } else { + + fileCursorCache.setTimePeriod(pTimePeriod); + + fileCursorCache.setDatetime(datetime); + + let newFileCursor = fileCursorCache.getFileCursor(pTimePeriod); + + if (newFileCursor !== undefined) { + + fileCursor = newFileCursor; + + recalculate(); + + } + } + + if (timePeriod === _1_HOUR_IN_MILISECONDS) { + + fileCursorCache.setTimePeriod(pTimePeriod); + + fileCursorCache.setDatetime(datetime); + + } + + } + + function setDatetime(newDatetime) { + + /* If there is a change in the day, then we take some actions, otherwise, we dont. */ + + let currentDate = Math.trunc(datetime.valueOf() / ONE_DAY_IN_MILISECONDS); + let newDate = Math.trunc(newDatetime.valueOf() / ONE_DAY_IN_MILISECONDS); + + datetime = newDatetime; + + if (currentDate !== newDate) { + + if (timePeriod <= _1_HOUR_IN_MILISECONDS) { + + fileCursorCache.setDatetime(newDatetime); + + } + } + } + + function draw() { + + if (layerStatus !== 'on') { return; } + + this.container.frame.draw(); + + if (timePeriod < _1_HOUR_IN_MILISECONDS) { + + if (Math.random() * 1000 > 995) { + + recalculateScaleX(); + recalculate(); + recalculateScaleY(); + + } + } + + plotChart(); + + } + + function recalculate() { + + if (layerStatus === 'off') { return; } + + if (timePeriod >= _1_HOUR_IN_MILISECONDS) { + + recalculateUsingMarketFiles(); + + } else { + + recalculateUsingDailyFiles(); + + } + + thisObject.container.eventHandler.raiseEvent("Volumes Changed", volumes); + } + + function recalculateUsingDailyFiles() { + + if (fileCursor.files.size === 0) { return; } // We need to wait until there are files in the cursor + + let daysOnSides = getSideDays(timePeriod); + + let leftDate = getDateFromPoint(viewPort.visibleArea.topLeft, thisObject.container, plotArea); + let rightDate = getDateFromPoint(viewPort.visibleArea.topRight, thisObject.container, plotArea); + + let dateDiff = rightDate.valueOf() - leftDate.valueOf(); + + let farLeftDate = new Date(leftDate.valueOf() - dateDiff * 1.5); + let farRightDate = new Date(rightDate.valueOf() + dateDiff * 1.5); + + let currentDate = new Date(farLeftDate.valueOf()); + + volumes = []; + + while (currentDate.valueOf() <= farRightDate.valueOf() + ONE_DAY_IN_MILISECONDS) { + + let stringDate = currentDate.getFullYear() + '-' + pad(currentDate.getMonth() + 1, 2) + '-' + pad(currentDate.getDate(), 2); + + let dailyFile = fileCursor.files.get(stringDate); + + if (dailyFile !== undefined) { + + for (let i = 0; i < dailyFile.length; i++) { + + let volume = { + amountBuy: 0, + amountSell: 0, + begin: undefined, + end: undefined + }; + + volume.amountBuy = dailyFile[i][0]; + volume.amountSell = dailyFile[i][1]; + + volume.begin = dailyFile[i][2]; + volume.end = dailyFile[i][3]; + + if (volume.begin >= farLeftDate.valueOf() && volume.end <= farRightDate.valueOf()) { + + volumes.push(volume); + + if (datetime.valueOf() >= volume.begin && datetime.valueOf() <= volume.end) { + + thisObject.container.eventHandler.raiseEvent("Current Candle Changed", thisObject.currentCandle); + + } + } + } + } + + currentDate = new Date(currentDate.valueOf() + ONE_DAY_IN_MILISECONDS); + } + + /* Lests check if all the visible screen is going to be covered by volumes. */ + + let lowerEnd = leftDate.valueOf(); + let upperEnd = rightDate.valueOf(); + + if (volumes.length > 0) { + + if (volumes[0].begin > lowerEnd || volumes[volumes.length - 1].end < upperEnd) { + + setTimeout(recalculate, 2000); + + //console.log("File missing while calculating volumes, scheduling a recalculation in 2 seconds."); + + } + } + + //console.log("Olivia > recalculateUsingDailyFiles > total volumes generated : " + volumes.length); + + } + + function recalculateUsingMarketFiles() { + + if (marketFile === undefined) { return; } // Initialization not complete yet. + + let daysOnSides = getSideDays(timePeriod); + + let leftDate = getDateFromPoint(viewPort.visibleArea.topLeft, thisObject.container, plotArea); + let rightDate = getDateFromPoint(viewPort.visibleArea.topRight, thisObject.container, plotArea); + + let dateDiff = rightDate.valueOf() - leftDate.valueOf(); + + leftDate = new Date(leftDate.valueOf() - dateDiff * 1.5); + rightDate = new Date(rightDate.valueOf() + dateDiff * 1.5); + + volumes = []; + + for (let i = 0; i < marketFile.length; i++) { + + let volume = { + amountBuy: 0, + amountSell: 0, + begin: undefined, + end: undefined + }; + + volume.amountBuy = marketFile[i][0]; + volume.amountSell = marketFile[i][1]; + + volume.begin = marketFile[i][2]; + volume.end = marketFile[i][3]; + + if (volume.begin >= leftDate.valueOf() && volume.end <= rightDate.valueOf()) { + + volumes.push(volume); + + if (datetime.valueOf() >= volume.begin && datetime.valueOf() <= volume.end) { + + thisObject.container.eventHandler.raiseEvent("Current Volume Changed", thisObject.currentCandle); + + } + } + } + + //console.log("Olivia > recalculateUsingMarketFiles > total volumes generated : " + volumes.length); + } + + function recalculateScaleX() { + + + var minValue = { + x: EARLIEST_DATE.valueOf() + }; + + var maxValue = { + x: MAX_PLOTABLE_DATE.valueOf() + }; + + plotArea.initializeX( + minValue, + maxValue, + thisObject.container.frame.width + ); + + plotAreaFrame.initializeX( + minValue, + maxValue, + thisObject.container.frame.width + ); + + } + + function recalculateScaleY() { + + var minValue = { + y: 0 + }; + + var maxValue = { + y: 0 + }; + + let timePeriodRatio = ONE_DAY_IN_MILISECONDS / timePeriod; + + maxValue.y = getMaxVolume() / (timePeriodRatio / 10); + + plotArea.initializeY( + minValue, + maxValue, + viewPort.visibleArea.bottomRight.y - viewPort.visibleArea.topLeft.y + ); + + plotAreaFrame.initializeY( + minValue, + maxValue, + thisObject.container.frame.height + ); + + function getMaxVolume() { + + let maxValue = 0; + + for (var i = 0; i < marketFile.length; i++) { + + let currentMax = (marketFile[i][0] + marketFile[i][1]) * 4; + + if (maxValue < currentMax) { + maxValue = currentMax; + } + } + + return maxValue; + + } + + } + + function plotChart() { + + if (volumes.length > 0) { + + /* Now we calculate and plot the volumes */ + + let visibleHeight = viewPort.visibleArea.bottomRight.y - viewPort.visibleArea.topLeft.y; + + let frameCorner1 = { + x: 0, + y: 0 + }; + + let frameCorner2 = { + x: thisObject.container.frame.width, + y: thisObject.container.frame.height + }; + + + /* Now the transformations. */ + + frameCorner1 = transformThisPoint(frameCorner1, thisObject.container.frame.container); + frameCorner2 = transformThisPoint(frameCorner2, thisObject.container.frame.container); + + let frameHeightInViewPort = frameCorner2.y - frameCorner1.y; + + if (volumes.length > 0) { + + for (var i = 0; i < volumes.length; i++) { + + volume = volumes[i]; + + let volumePointA1; + let volumePointA2; + let volumePointA3; + let volumePointA4; + + function calculateBuys(plot, height) { + + volumePointA1 = { + x: volume.begin + timePeriod / 7 * 2, + y: 0 + }; + + volumePointA2 = { + x: volume.begin + timePeriod / 7 * 2, + y: volume.amountBuy + }; + + volumePointA3 = { + x: volume.begin + timePeriod / 7 * 5, + y: volume.amountBuy + }; + + volumePointA4 = { + x: volume.begin + timePeriod / 7 * 5, + y: 0 + }; + + volumePointA1 = plot.inverseTransform(volumePointA1, height); + volumePointA2 = plot.inverseTransform(volumePointA2, height); + volumePointA3 = plot.inverseTransform(volumePointA3, height); + volumePointA4 = plot.inverseTransform(volumePointA4, height); + + volumePointA1 = transformThisPoint(volumePointA1, thisObject.container); + volumePointA2 = transformThisPoint(volumePointA2, thisObject.container); + volumePointA3 = transformThisPoint(volumePointA3, thisObject.container); + volumePointA4 = transformThisPoint(volumePointA4, thisObject.container); + + let baseIncrement = (volumePointA3.x - volumePointA1.x) * WIDHTER_VOLUME_BAR_BASE_FACTOR; + + volumePointA1.x = volumePointA1.x - baseIncrement; + volumePointA4.x = volumePointA4.x + baseIncrement; + + if (volumePointA4.x < viewPort.visibleArea.bottomLeft.x || volumePointA1.x > viewPort.visibleArea.bottomRight.x) { + return false; + } + + return true; + + } + + if (calculateBuys(plotAreaFrame, thisObject.container.frame.height) === false) { continue; } // We try to see if it fits in the visible area. + + if (volumePointA1.y > viewPort.visibleArea.bottomLeft.y && frameHeightInViewPort > visibleHeight * 2 / 3) { + + if (calculateBuys(plotArea, visibleHeight) === false) { continue; } // We snap t to the view port. + + /* Now we set the real value of y. */ + + volumePointA1.y = viewPort.visibleArea.bottomRight.y; + volumePointA2.y = viewPort.visibleArea.bottomRight.y - volume.amountBuy * plotArea.scale.y; + volumePointA3.y = viewPort.visibleArea.bottomRight.y - volume.amountBuy * plotArea.scale.y; + volumePointA4.y = viewPort.visibleArea.bottomRight.y; + + } + + let volumePointB1; + let volumePointB2; + let volumePointB3; + let volumePointB4; + + function calculateSells(plot, height) { + + volumePointB1 = { + x: volume.begin + timePeriod / 7 * 2, + y: height + }; + + volumePointB2 = { + x: volume.begin + timePeriod / 7 * 2, + y: height - volume.amountSell + }; + + volumePointB3 = { + x: volume.begin + timePeriod / 7 * 5, + y: height - volume.amountSell + }; + + volumePointB4 = { + x: volume.begin + timePeriod / 7 * 5, + y: height + }; + + volumePointB1 = plot.inverseTransform2(volumePointB1, height); + volumePointB2 = plot.inverseTransform2(volumePointB2, height); + volumePointB3 = plot.inverseTransform2(volumePointB3, height); + volumePointB4 = plot.inverseTransform2(volumePointB4, height); + + volumePointB1 = transformThisPoint(volumePointB1, thisObject.container); + volumePointB2 = transformThisPoint(volumePointB2, thisObject.container); + volumePointB3 = transformThisPoint(volumePointB3, thisObject.container); + volumePointB4 = transformThisPoint(volumePointB4, thisObject.container); + + } + + calculateSells(plotAreaFrame, thisObject.container.frame.height); // We try to see if it fits in the visible area. + + if (volumePointB1.y < viewPort.visibleArea.topLeft.y && frameHeightInViewPort > visibleHeight * 2 / 3) { + + calculateSells(plotArea, visibleHeight); // We snap it to the view port. + + /* Now we set the real value of y. */ + + volumePointB1.y = viewPort.visibleArea.topLeft.y; + volumePointB2.y = viewPort.visibleArea.topLeft.y + volume.amountSell * plotArea.scale.y; + volumePointB3.y = viewPort.visibleArea.topLeft.y + volume.amountSell * plotArea.scale.y; + volumePointB4.y = viewPort.visibleArea.topLeft.y; + + } + + /* We put a wider base */ + + let baseIncrement = (volumePointB3.x - volumePointB1.x) * WIDHTER_VOLUME_BAR_BASE_FACTOR; + + volumePointB1.x = volumePointB1.x - baseIncrement; + volumePointB4.x = volumePointB4.x + baseIncrement; + + /* We put a less wider top */ + + let baseDencrement = (volumePointA3.x - volumePointA2.x) * LESS_WIDHTER_VOLUME_BAR_TOP_FACTOR; + + volumePointA2.x = volumePointA2.x + baseDencrement; + volumePointA3.x = volumePointA3.x - baseDencrement; + + volumePointB2.x = volumePointB2.x + baseDencrement; + volumePointB3.x = volumePointB3.x - baseDencrement; + + + /* Everything must fit within the visible area */ + + volumePointA1 = viewPort.fitIntoVisibleArea(volumePointA1); + volumePointA2 = viewPort.fitIntoVisibleArea(volumePointA2); + volumePointA3 = viewPort.fitIntoVisibleArea(volumePointA3); + volumePointA4 = viewPort.fitIntoVisibleArea(volumePointA4); + + volumePointB1 = viewPort.fitIntoVisibleArea(volumePointB1); + volumePointB2 = viewPort.fitIntoVisibleArea(volumePointB2); + volumePointB3 = viewPort.fitIntoVisibleArea(volumePointB3); + volumePointB4 = viewPort.fitIntoVisibleArea(volumePointB4); + + /* Everything must fit within the Frame. We know that that is equivalent to say that each bar con not be higher than the base of the opposite . */ + + if (volumePointA2.y < volumePointB1.y) { + + volumePointA2.y = volumePointB1.y; + volumePointA3.y = volumePointB1.y; + + } + + if (volumePointB2.y > volumePointA1.y) { + + volumePointB2.y = volumePointA1.y; + volumePointB3.y = volumePointA1.y; + + } + + /* Now the drawing of the volume bars*/ + + browserCanvasContext.beginPath(); + + browserCanvasContext.moveTo(volumePointA1.x, volumePointA1.y); + browserCanvasContext.lineTo(volumePointA2.x, volumePointA2.y); + browserCanvasContext.lineTo(volumePointA3.x, volumePointA3.y); + browserCanvasContext.lineTo(volumePointA4.x, volumePointA4.y); + + browserCanvasContext.closePath(); + + + if (datetime !== undefined) { + + let dateValue = datetime.valueOf(); + + if (dateValue >= volume.begin && dateValue <= volume.end) { + + browserCanvasContext.fillStyle = 'rgba(255, 233, 31, 0.40)'; // Current bar accroding to time + + } else { + + browserCanvasContext.fillStyle = 'rgba(64, 217, 26, 0.40)'; + } + + } else { + + browserCanvasContext.fillStyle = 'rgba(64, 217, 26, 0.40)'; + + } + + browserCanvasContext.fill(); + browserCanvasContext.strokeStyle = 'rgba(27, 105, 7, 0.40)'; + browserCanvasContext.lineWidth = 1; + browserCanvasContext.stroke(); + + + browserCanvasContext.beginPath(); + + browserCanvasContext.moveTo(volumePointB1.x, volumePointB1.y); + browserCanvasContext.lineTo(volumePointB2.x, volumePointB2.y); + browserCanvasContext.lineTo(volumePointB3.x, volumePointB3.y); + browserCanvasContext.lineTo(volumePointB4.x, volumePointB4.y); + + browserCanvasContext.closePath(); + + if (datetime !== undefined) { + + let dateValue = datetime.valueOf(); + + if (dateValue >= volume.begin && dateValue <= volume.end) { + + browserCanvasContext.fillStyle = 'rgba(255, 233, 31, 0.40)'; // Current candle accroding to time + + } else { + + browserCanvasContext.fillStyle = 'rgba(219, 18, 18, 0.40)'; + } + + } else { + + browserCanvasContext.fillStyle = 'rgba(219, 18, 18, 0.40)'; + + } + + browserCanvasContext.strokeStyle = 'rgba(130, 9, 9, 0.40)'; + + browserCanvasContext.fill(); + browserCanvasContext.lineWidth = 1; + browserCanvasContext.stroke(); + + + + if (datetime !== undefined) { + + let dateValue = datetime.valueOf(); + + if (dateValue >= volume.begin && dateValue <= volume.end) { + + let buyInfo = { + baseWidth: volumePointA4.x - volumePointA1.x, + topWidth: volumePointA3.x - volumePointA2.x, + height: volumePointA2.y - volumePointA1.y + }; + + let sellInfo = { + baseWidth: volumePointB4.x - volumePointB1.x, + topWidth: volumePointB3.x - volumePointB2.x, + height: volumePointB2.y - volumePointB1.y + }; + + let currentVolume = { + buyInfo: buyInfo, + sellInfo: sellInfo, + period: timePeriod, + innerVolumeBar: volume + }; + + thisObject.container.eventHandler.raiseEvent("Current Volume Info Changed", currentVolume); + + } + } + } + } + } + } + + function onLayerStatusChanged(eventData) { + + if (eventData.layer === 'Olivia Volumes') { + layerStatus = eventData.status; + } + + } + + function onZoomChanged(event) { + + recalculateScaleX(); + recalculate(); + recalculateScaleY(); + + } + + function onDragFinished() { + + recalculateScaleX(); + recalculate(); + recalculateScaleY(); + + } +} + diff --git a/History.js b/History.js new file mode 100644 index 000000000..e2b70b21f --- /dev/null +++ b/History.js @@ -0,0 +1,694 @@ +function newAAMastersAAOliviaCandles() { + + let thisObject = { + + // Main functions and properties. + + initialize: initialize, + container: undefined, + getContainer: getContainer, + setTimePeriod: setTimePeriod, + setDatetime: setDatetime, + draw: draw, + + // Secondary functions and properties. + + currentCandle: undefined, + positionAtDatetime: positionAtDatetime, + onLayerStatusChanged: onLayerStatusChanged + }; + + /* this is part of the module template */ + + let container = newContainer(); // Do not touch this 3 lines, they are just needed. + container.initialize(); + thisObject.container = container; + + let layerStatus = 'off'; // Since the moduleis a layer, it must handle the different possible layer status. + + let plotArea = newPlotArea(); // Needed to be able to plot on the timeline, otherwise not. + + let timePeriod; // This will hold the current Time Period the user is at. + let datetime; // This will hold the current Datetime the user is at. + + let marketFile; // This is the current Market File being plotted. + let fileCursor; // This is the current File Cursor being used to retrieve Daily Files. + + let fileCache; // This object will provide the different Market Files at different Time Periods. + let fileCursorCache; // This object will provide the different File Cursors at different Time Periods. + + /* these are module specific variables: */ + + let candles = []; // Here we keep the candles to be ploted every time the Draw() function is called by the AAWebPlatform. + + return thisObject; + + function initialize(pExchange, pMarket, pDatetime, pTimePeriod, pLayerStatus, callBackFunction) { + + let cursorCacheInProgress = false; + let finaleStepsInProgress = false; + + datetime = pDatetime; + timePeriod = pTimePeriod; + + fileCache = newFileCache(); + fileCache.initialize("AAMasters", "AAOlivia", "Market Candles", "Market Candlesticks", pExchange, pMarket, onFileReady); + + function onFileReady() { + + let newMarketFile = fileCache.getFile(ONE_DAY_IN_MILISECONDS); + + if (newMarketFile !== undefined) { + + marketFile = newMarketFile; + + initializeFileCursorCache(); + + } + } + + function initializeFileCursorCache() { + + if (cursorCacheInProgress === false) { + + cursorCacheInProgress = true; + + fileCursorCache = newFileCursorCache(); + fileCursorCache.initialize("AAMasters", "AAOlivia", "Daily Candles", "Daily Candlesticks", pExchange, pMarket, pDatetime, pTimePeriod, onFileCursorReady); + + } + } + + function onFileCursorReady() { + + recalculate(); + + let newFileCursor = fileCursorCache.getFileCursor(pTimePeriod); + + if (newFileCursor !== undefined) { // if the file ready is the one we need then it and we dont have it yet, then we will continue here. + + let stringDate = datetime.getUTCFullYear() + '-' + pad(datetime.getUTCMonth() + 1, 2) + '-' + pad(datetime.getUTCDate(), 2); + + let dailyFile = newFileCursor.files.get(stringDate); + + if (dailyFile !== undefined) { + + if (finaleStepsInProgress === false) { + + finaleStepsInProgress = true; + + fileCursor = newFileCursor; + + recalculateScale(); // With any of the market files we can calculate the scale. + + layerStatus = pLayerStatus; + + recalculate(); + + viewPort.eventHandler.listenToEvent("Zoom Changed", onZoomChanged); + canvas.eventHandler.listenToEvent("Drag Finished", onDragFinished); + + callBackFunction(); + + } + } + } + + } + + } + + function getContainer(point) { + + if (layerStatus !== 'on') { return; } + + let 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 setTimePeriod(pTimePeriod) { + + timePeriod = pTimePeriod; + + if (timePeriod >= _1_HOUR_IN_MILISECONDS) { + + let newMarketFile = fileCache.getFile(pTimePeriod); + + if (newMarketFile !== undefined) { + + marketFile = newMarketFile; + + recalculate(); + + } + + } else { + + fileCursorCache.setTimePeriod(pTimePeriod); + + fileCursorCache.setDatetime(datetime); + + let newFileCursor = fileCursorCache.getFileCursor(pTimePeriod); + + if (newFileCursor !== undefined) { + + fileCursor = newFileCursor; + + recalculate(); + + } + } + + if (timePeriod === _1_HOUR_IN_MILISECONDS) { + + fileCursorCache.setTimePeriod(pTimePeriod); + + fileCursorCache.setDatetime(datetime); + + } + + } + + function setDatetime(newDatetime) { + + /* If there is a change in the day, then we take some actions, otherwise, we dont. */ + + let currentDate = Math.trunc(datetime.valueOf() / ONE_DAY_IN_MILISECONDS); + let newDate = Math.trunc(newDatetime.valueOf() / ONE_DAY_IN_MILISECONDS); + + datetime = newDatetime; + + if (currentDate !== newDate) { + + if (timePeriod <= _1_HOUR_IN_MILISECONDS) { + + fileCursorCache.setDatetime(newDatetime); + + } + } + } + + 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, thisObject.container.frame.height); + targetPoint = transformThisPoint(targetPoint, thisObject.container); + + let targetMax = { + x: value, + y: candles[i].max + }; + + targetMax = plotArea.inverseTransform(targetMax, thisObject.container.frame.height); + targetMax = transformThisPoint(targetMax, thisObject.container); + + let targetMin = { + x: value, + y: candles[i].min + }; + + targetMin = plotArea.inverseTransform(targetMin, thisObject.container.frame.height); + targetMin = transformThisPoint(targetMin, thisObject.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 < _1_HOUR_IN_MILISECONDS) { + + if (Math.random() * 1000 > 995) { + + recalculate(); + + } + } + + plotChart(); + + } + + function recalculate() { + + if (layerStatus === 'off') { return; } + + if (timePeriod >= _1_HOUR_IN_MILISECONDS) { + + recalculateUsingMarketFiles(); + + } else { + + recalculateUsingDailyFiles(); + + } + + thisObject.container.eventHandler.raiseEvent("Candles Changed", candles); + } + + function recalculateUsingDailyFiles() { + + if (fileCursor.files.size === 0) { return;} // We need to wait until there are files in the cursor + + let daysOnSides = getSideDays(timePeriod); + + let leftDate = getDateFromPoint(viewPort.visibleArea.topLeft, thisObject.container, plotArea); + let rightDate = getDateFromPoint(viewPort.visibleArea.topRight, thisObject.container, plotArea); + + let dateDiff = rightDate.valueOf() - leftDate.valueOf(); + + let farLeftDate = new Date(leftDate.valueOf() - dateDiff * 1.5); + let farRightDate = new Date(rightDate.valueOf() + dateDiff * 1.5); + + let currentDate = new Date(farLeftDate.valueOf()); + + candles = []; + + while (currentDate.valueOf() <= farRightDate.valueOf() + ONE_DAY_IN_MILISECONDS) { + + let stringDate = currentDate.getFullYear() + '-' + pad(currentDate.getMonth() + 1, 2) + '-' + pad(currentDate.getDate(), 2); + + let dailyFile = fileCursor.files.get(stringDate); + + if (dailyFile !== undefined) { + + for (let i = 0; i < dailyFile.length; i++) { + + let candle = { + open: undefined, + close: undefined, + min: 10000000000000, + max: 0, + begin: undefined, + end: undefined, + direction: undefined + }; + + candle.min = dailyFile[i][0]; + candle.max = dailyFile[i][1]; + + candle.open = dailyFile[i][2]; + candle.close = dailyFile[i][3]; + + candle.begin = dailyFile[i][4]; + candle.end = dailyFile[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'; } + + if (candle.begin >= farLeftDate.valueOf() && candle.end <= farRightDate.valueOf()) { + + candles.push(candle); + + if (datetime.valueOf() >= candle.begin && datetime.valueOf() <= candle.end) { + + thisObject.currentCandle = candle; + thisObject.container.eventHandler.raiseEvent("Current Candle Changed", thisObject.currentCandle); + + } + } + } + } + + currentDate = new Date(currentDate.valueOf() + ONE_DAY_IN_MILISECONDS); + } + + /* Lests check if all the visible screen is going to be covered by candles. */ + + let lowerEnd = leftDate.valueOf(); + let upperEnd = rightDate.valueOf(); + + if (candles.length > 0) { + + if (candles[0].begin > lowerEnd || candles[candles.length - 1].end < upperEnd) { + + setTimeout(recalculate, 2000); + + //console.log("File missing while calculating candles, scheduling a recalculation in 2 seconds."); + + } + } + + //console.log("Olivia > recalculateUsingDailyFiles > total candles generated : " + candles.length); + + } + + function recalculateUsingMarketFiles() { + + if (marketFile === undefined) { return; } // Initialization not complete yet. + + let daysOnSides = getSideDays(timePeriod); + + let leftDate = getDateFromPoint(viewPort.visibleArea.topLeft, thisObject.container, plotArea); + let rightDate = getDateFromPoint(viewPort.visibleArea.topRight, thisObject.container, plotArea); + + let dateDiff = rightDate.valueOf() - leftDate.valueOf(); + + leftDate = new Date(leftDate.valueOf() - dateDiff * 1.5); + rightDate = new Date(rightDate.valueOf() + dateDiff * 1.5); + + candles = []; + + for (let i = 0; i < marketFile.length; i++) { + + let candle = { + open: undefined, + close: undefined, + min: 10000000000000, + max: 0, + begin: undefined, + end: undefined, + direction: undefined + }; + + candle.min = marketFile[i][0]; + candle.max = marketFile[i][1]; + + candle.open = marketFile[i][2]; + candle.close = marketFile[i][3]; + + candle.begin = marketFile[i][4]; + candle.end = marketFile[i][5]; + + if (candle.open > candle.close) { candle.direction = 'down'; } + if (candle.open < candle.close) { candle.direction = 'up'; } + if (candle.open === candle.close) { candle.direction = 'side'; } + + if (candle.begin >= leftDate.valueOf() && candle.end <= rightDate.valueOf()) { + + candles.push(candle); + + if (datetime.valueOf() >= candle.begin && datetime.valueOf() <= candle.end) { + + thisObject.currentCandle = candle; + thisObject.container.eventHandler.raiseEvent("Current Candle Changed", thisObject.currentCandle); + + } + } + } + + //console.log("Olivia > recalculateUsingMarketFiles > total candles generated : " + candles.length); + } + + function recalculateScale() { + + if (marketFile === undefined) { return; } // We need the market file to be loaded to make the calculation. + + if (plotArea.maxValue > 0) { return; } // Already calculated. + + let minValue = { + x: EARLIEST_DATE.valueOf(), + y: 0 + }; + + let maxValue = { + x: MAX_PLOTABLE_DATE.valueOf(), + y: nextPorwerOf10(getMaxRate()) + }; + + + plotArea.initialize( + minValue, + maxValue, + thisObject.container.frame.width, + thisObject.container.frame.height + ); + + function getMaxRate() { + + let maxValue = 0; + + for (let i = 0; i < marketFile.length; i++) { + + let currentMax = marketFile[i][1]; // 1 = rates. + + if (maxValue < currentMax) { + maxValue = currentMax; + } + } + + return maxValue; + + } + + } + + function plotChart() { + + if (candles.length > 0) { + + /* Now we calculate and plot the candles */ + + for (let i = 0; i < candles.length; i++) { + + candle = candles[i]; + + let candlePoint1 = { + x: candle.begin + timePeriod / 7 * 1.5, + y: candle.open + }; + + let candlePoint2 = { + x: candle.begin + timePeriod / 7 * 5.5, + y: candle.open + }; + + let candlePoint3 = { + x: candle.begin + timePeriod / 7 * 5.5, + y: candle.close + }; + + let candlePoint4 = { + x: candle.begin + timePeriod / 7 * 1.5, + y: candle.close + }; + + candlePoint1 = plotArea.inverseTransform(candlePoint1, thisObject.container.frame.height); + candlePoint2 = plotArea.inverseTransform(candlePoint2, thisObject.container.frame.height); + candlePoint3 = plotArea.inverseTransform(candlePoint3, thisObject.container.frame.height); + candlePoint4 = plotArea.inverseTransform(candlePoint4, thisObject.container.frame.height); + + candlePoint1 = transformThisPoint(candlePoint1, thisObject.container); + candlePoint2 = transformThisPoint(candlePoint2, thisObject.container); + candlePoint3 = transformThisPoint(candlePoint3, thisObject.container); + candlePoint4 = transformThisPoint(candlePoint4, thisObject.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); + + let stickPoint1 = { + x: candle.begin + timePeriod / 7 * 3.2, + y: candle.max + }; + + let stickPoint2 = { + x: candle.begin + timePeriod / 7 * 3.8, + y: candle.max + }; + + let stickPoint3 = { + x: candle.begin + timePeriod / 7 * 3.8, + y: candle.min + }; + + let stickPoint4 = { + x: candle.begin + timePeriod / 7 * 3.2, + y: candle.min + }; + + stickPoint1 = plotArea.inverseTransform(stickPoint1, thisObject.container.frame.height); + stickPoint2 = plotArea.inverseTransform(stickPoint2, thisObject.container.frame.height); + stickPoint3 = plotArea.inverseTransform(stickPoint3, thisObject.container.frame.height); + stickPoint4 = plotArea.inverseTransform(stickPoint4, thisObject.container.frame.height); + + stickPoint1 = transformThisPoint(stickPoint1, thisObject.container); + stickPoint2 = transformThisPoint(stickPoint2, thisObject.container); + stickPoint3 = transformThisPoint(stickPoint3, thisObject.container); + stickPoint4 = transformThisPoint(stickPoint4, thisObject.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 + }; + + thisObject.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(); + + + } + } + } + + function onLayerStatusChanged(eventData) { + + if (eventData.layer === 'Olivia Candlesticks') { + layerStatus = eventData.status; + } + + } + + function onZoomChanged(event) { + + recalculate(); + + } + + function onDragFinished() { + + recalculate(); + + } +} + diff --git a/README.md b/README.md new file mode 100644 index 000000000..1fec2f25c --- /dev/null +++ b/README.md @@ -0,0 +1 @@ +# AAMariam-Plotter diff --git a/bin/Microsoft.NodejsTools.WebRole.dll b/bin/Microsoft.NodejsTools.WebRole.dll new file mode 100644 index 0000000000000000000000000000000000000000..03b93f4a1c5dfb1659630bf8ea0ad76d2a599ed4 GIT binary patch literal 32992 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 literal 0 HcmV?d00001 diff --git a/obj/Debug/AAOlivia-Plotter.njsproj.CoreCompileInputs.cache b/obj/Debug/AAOlivia-Plotter.njsproj.CoreCompileInputs.cache new file mode 100644 index 000000000..78474ee71 --- /dev/null +++ b/obj/Debug/AAOlivia-Plotter.njsproj.CoreCompileInputs.cache @@ -0,0 +1 @@ +573924208ee1de43c28a684e3ad9af2dcef5974d diff --git a/obj/Debug/AAOlivia-Plotter.njsproj.FileListAbsolute.txt b/obj/Debug/AAOlivia-Plotter.njsproj.FileListAbsolute.txt new file mode 100644 index 000000000..4c3907976 --- /dev/null +++ b/obj/Debug/AAOlivia-Plotter.njsproj.FileListAbsolute.txt @@ -0,0 +1,3 @@ +C:\Users\Luis\source\repos\AAOlivia-Plotter\obj\Debug\AAOlivia-Plotter.njsprojResolveAssemblyReference.cache +C:\Users\Luis\source\repos\AAOlivia-Plotter\obj\Debug\AAOlivia-Plotter.njsproj.CoreCompileInputs.cache +C:\Users\Luis\source\repos\AAOlivia-Plotter\bin\Microsoft.NodejsTools.WebRole.dll diff --git a/obj/Debug/AAOlivia-Plotter.njsprojResolveAssemblyReference.cache b/obj/Debug/AAOlivia-Plotter.njsprojResolveAssemblyReference.cache new file mode 100644 index 0000000000000000000000000000000000000000..67d5be9b7a12b38e6fe524eedeba2ea6a1a31246 GIT binary patch literal 2216 zcmb_d+iu%N5T)*RdTpA)&tW2&Cd7K4^8EmeX{a^_^}K>O{gp42hO3tnZvAqmX;w!0b$% zLwqo5wu4Tv8?;(}r^(u^M8-b7-o{|2G(-cA|0w}SaS=4l}-Sv+P}L{la~Zj;ik@ZnU73+{t7>BoTo2t|xY zl^?M%0c9A4f>A1MnAh3r&vo6t#^?SO{ja{i_ay~et&;Orkwgi_HqB_ETt;!w-5);g zpM3S*tN7z& z1%zec5=J+x+udE(@j9Qk_S$!$d2g>ow%*8Fg005XY9uC811)(xwz(ScXc_`RaeKlP z)|&@P33({J3D;QT*i`+vmr&fa$>LFzq~&f)h}d)reou<1Kxr+0lEwNEf~-B(0L2ySaRO}Wl?GcxSQfv{Ynk^4-6>1GX3bE*3e!?BQDPoj_3KYK!UMXaR= zKXkE3L_8*Q$U3Kt%Ug3DDYmgjSoijga%qms{?wJh_Q7o9~R z!~q{Ck`bHE%LQ9_KAo*O`*x>3yIPl5Li^&T{$&2IA#ja>)qYFi$(J`Vdm9Tg6092K z{U;RVEfhy|&+IoEjqZLUBiY8XvXNvP3zBUtS*Ed~kVw|rMpebX@H%}vtf-MI7j(b4 zu3;8`M#g@P%19xuV441jvv&e(-9kznuTbYrFkC Date: Tue, 27 Feb 2018 18:00:23 +0100 Subject: [PATCH 02/54] History implemented --- .vs/AAMariam-Plotter/v15/.suo | Bin 16896 -> 18944 bytes Details.js | 2 +- History.js | 533 +++------------------------------- 3 files changed, 46 insertions(+), 489 deletions(-) diff --git a/.vs/AAMariam-Plotter/v15/.suo b/.vs/AAMariam-Plotter/v15/.suo index d1501bee538092438849e0f631d8a14e119713c7..7c0634ec7435ac7b75424dfa4edacd3fc226c588 100644 GIT binary patch delta 1505 zcmd5*O-~b16rDFMZ7Gj3wI6(=EhLsm=?t{RLMa;y%#$$D2c(1-sE&{@16I~yXU;A+-H?XY%MRc z76^&QJ*yMK#HVNPS*IWfl{P4gWp)N?j!o{sLNnq!2F!L2G^Oy*XZU6-dV`qx5dlO8 z!Uq@a-QE+J(aRJe%)|N(`x2{)c_#g2dYvi|6UW{z(>a*7Da0n;gImr#Y}jOz#M#|L z{7!@mLFZ^e)NyM!K0$Wnz5ST%k~Mzn&u14{)x8#qVq+K)L&yjPF@hLH#1RPyxqZ#! zm`xzk`YX4ORr!pI#-Y7vT6P*1`Gr=2PSI|yk3o$WIUR=P*n2$*izhd^DU4ZmkPeO} zDEr^>ZcMFuf)<#Aw}V40sMiLI4Ag)OTH6+EIAvXvN{o}TeHIQdymKy6#M~XUW7{s0 zW4{n9aW59SEJfXjl|>vJLtq3;oV@o~nz}Z+V%NX+7VK_E6WWU{QGj|_ z8=0A3(5~IQJ$z+hd3i~RtIAj^sYG*U6G}9mjH}UaC!0?Bef(;X3Ozqzx*$czUsJSyX)%t3`tZM&#QK|X^f73ms+A#EL^c=Vv+ zx;Bi){Hib*z7nVrdEf2x9A(@6MD}=$NCh1)aXU6_mQlb6^yrct|MwPE5=VDe6jZtw z<40fVZY+U^8QFPQ{w9+PTt}hIc#H|%Ya)CCh0IIO4%y#`k0P{B&ckX~e>I(jtC^1f pZy5TX%^1KWg81_=6=nmLy#ycn{7|2~3sM({_4GPq)7is2KLDX%#4G>+ delta 1013 zcmZ`&O-~bH5Z>8-E#+;yr7ise+9FX5F?Be61eG3!^yji z*U*&95VWePM_V1PCMcjKtZGZxlfPhTtl%jS*}%RpJuyOGK7vB<6TE~`!pUGTz=Bfd zvis2VALEQ)h0DfIe*_Ne^G&g?s1!y~1Kfzuz#{I7I{}c1i#z!|_RjCY0`3MXV(Rq5 zPBP33RS+&>(~cC>!e0fC#%&BkwJ{2vAcmW@Su`UxY|kyD9&KY=o<}WK2}ogzU=9C9 zEmQ^1$-3F3H%Et#jE&%DEQJfGg=z}VZr`K1IDu;7ieO^Wd7&k0O3F!?i7I|lS5Qx0 z3jq7UIu7d;*W6IUe(bhj%My;OX4-8$8Gi-uQ$@w!A?3I~kc{riEZ}l+$pumgyVILZ z|9X<`VAz(k##}3j_uUb)CTeuap2Pa1Gsfip7{jx%Fm_*%#h$1LH&MJHLpnoF(T?N` zUUo~BNT6GS2Xc0fW?qLV?uPatV)Q~45Ue*#Y}Y|;?z?i(DgdXL#e>P|(H&`9dTepl*<+otKXnh|sk=ri zqsxMKnr+}ze34$oZ0ahuuIs3$idekS!um}e)zvil^UL~Atyp?-yZo@2E)1u(IEx&{ O4{Og)6W`!LJo_5~8aZhI diff --git a/Details.js b/Details.js index ae1961bf6..c0dcd6005 100644 --- a/Details.js +++ b/Details.js @@ -737,7 +737,7 @@ function onLayerStatusChanged(eventData) { - if (eventData.layer === 'Olivia Volumes') { + if (eventData.layer === 'Mariam Trades Details') { layerStatus = eventData.status; } diff --git a/History.js b/History.js index e2b70b21f..6381212cc 100644 --- a/History.js +++ b/History.js @@ -1,4 +1,4 @@ -function newAAMastersAAOliviaCandles() { +function newAAMastersAAMariamTradingHistory() { let thisObject = { @@ -31,91 +31,26 @@ let timePeriod; // This will hold the current Time Period the user is at. let datetime; // This will hold the current Datetime the user is at. - let marketFile; // This is the current Market File being plotted. - let fileCursor; // This is the current File Cursor being used to retrieve Daily Files. - - let fileCache; // This object will provide the different Market Files at different Time Periods. - let fileCursorCache; // This object will provide the different File Cursors at different Time Periods. - /* these are module specific variables: */ - let candles = []; // Here we keep the candles to be ploted every time the Draw() function is called by the AAWebPlatform. + let file; // Here we keep the history records to be ploted every time the Draw() function is called by the AAWebPlatform. + let history = []; // This is where the history records are stored before plotting. return thisObject; function initialize(pExchange, pMarket, pDatetime, pTimePeriod, pLayerStatus, callBackFunction) { - let cursorCacheInProgress = false; - let finaleStepsInProgress = false; - datetime = pDatetime; timePeriod = pTimePeriod; - fileCache = newFileCache(); - fileCache.initialize("AAMasters", "AAOlivia", "Market Candles", "Market Candlesticks", pExchange, pMarket, onFileReady); + let File = newFile(); + File.initialize("AAMasters", "AAMariam", "Trading History", "Trading History", pExchange, pMarket, onFileReady) function onFileReady() { - let newMarketFile = fileCache.getFile(ONE_DAY_IN_MILISECONDS); - - if (newMarketFile !== undefined) { - - marketFile = newMarketFile; - - initializeFileCursorCache(); - - } - } - - function initializeFileCursorCache() { - - if (cursorCacheInProgress === false) { - - cursorCacheInProgress = true; - - fileCursorCache = newFileCursorCache(); - fileCursorCache.initialize("AAMasters", "AAOlivia", "Daily Candles", "Daily Candlesticks", pExchange, pMarket, pDatetime, pTimePeriod, onFileCursorReady); - - } - } - - function onFileCursorReady() { - - recalculate(); - - let newFileCursor = fileCursorCache.getFileCursor(pTimePeriod); - - if (newFileCursor !== undefined) { // if the file ready is the one we need then it and we dont have it yet, then we will continue here. - - let stringDate = datetime.getUTCFullYear() + '-' + pad(datetime.getUTCMonth() + 1, 2) + '-' + pad(datetime.getUTCDate(), 2); - - let dailyFile = newFileCursor.files.get(stringDate); - - if (dailyFile !== undefined) { - - if (finaleStepsInProgress === false) { - - finaleStepsInProgress = true; - - fileCursor = newFileCursor; - - recalculateScale(); // With any of the market files we can calculate the scale. - - layerStatus = pLayerStatus; - - recalculate(); - - viewPort.eventHandler.listenToEvent("Zoom Changed", onZoomChanged); - canvas.eventHandler.listenToEvent("Drag Finished", onDragFinished); - - callBackFunction(); - - } - } - } + file = File.getFile(); } - } function getContainer(point) { @@ -143,141 +78,18 @@ timePeriod = pTimePeriod; - if (timePeriod >= _1_HOUR_IN_MILISECONDS) { - - let newMarketFile = fileCache.getFile(pTimePeriod); - - if (newMarketFile !== undefined) { - - marketFile = newMarketFile; - - recalculate(); - - } - - } else { - - fileCursorCache.setTimePeriod(pTimePeriod); - - fileCursorCache.setDatetime(datetime); - - let newFileCursor = fileCursorCache.getFileCursor(pTimePeriod); - - if (newFileCursor !== undefined) { - - fileCursor = newFileCursor; - - recalculate(); - - } - } - - if (timePeriod === _1_HOUR_IN_MILISECONDS) { - - fileCursorCache.setTimePeriod(pTimePeriod); - - fileCursorCache.setDatetime(datetime); - - } - } function setDatetime(newDatetime) { - /* If there is a change in the day, then we take some actions, otherwise, we dont. */ - - let currentDate = Math.trunc(datetime.valueOf() / ONE_DAY_IN_MILISECONDS); - let newDate = Math.trunc(newDatetime.valueOf() / ONE_DAY_IN_MILISECONDS); - datetime = newDatetime; - if (currentDate !== newDate) { - - if (timePeriod <= _1_HOUR_IN_MILISECONDS) { - - fileCursorCache.setDatetime(newDatetime); - - } - } - } - - 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, thisObject.container.frame.height); - targetPoint = transformThisPoint(targetPoint, thisObject.container); - - let targetMax = { - x: value, - y: candles[i].max - }; - - targetMax = plotArea.inverseTransform(targetMax, thisObject.container.frame.height); - targetMax = transformThisPoint(targetMax, thisObject.container); - - let targetMin = { - x: value, - y: candles[i].min - }; - - targetMin = plotArea.inverseTransform(targetMin, thisObject.container.frame.height); - targetMin = transformThisPoint(targetMin, thisObject.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 < _1_HOUR_IN_MILISECONDS) { - - if (Math.random() * 1000 > 995) { - - recalculate(); - - } - } - plotChart(); } @@ -286,167 +98,26 @@ if (layerStatus === 'off') { return; } - if (timePeriod >= _1_HOUR_IN_MILISECONDS) { + for (let i = 0; i < file.length; i++) { - recalculateUsingMarketFiles(); + let newHistoryRecord = { - } else { - - recalculateUsingDailyFiles(); - - } - - thisObject.container.eventHandler.raiseEvent("Candles Changed", candles); - } - - function recalculateUsingDailyFiles() { - - if (fileCursor.files.size === 0) { return;} // We need to wait until there are files in the cursor - - let daysOnSides = getSideDays(timePeriod); - - let leftDate = getDateFromPoint(viewPort.visibleArea.topLeft, thisObject.container, plotArea); - let rightDate = getDateFromPoint(viewPort.visibleArea.topRight, thisObject.container, plotArea); - - let dateDiff = rightDate.valueOf() - leftDate.valueOf(); - - let farLeftDate = new Date(leftDate.valueOf() - dateDiff * 1.5); - let farRightDate = new Date(rightDate.valueOf() + dateDiff * 1.5); - - let currentDate = new Date(farLeftDate.valueOf()); - - candles = []; - - while (currentDate.valueOf() <= farRightDate.valueOf() + ONE_DAY_IN_MILISECONDS) { - - let stringDate = currentDate.getFullYear() + '-' + pad(currentDate.getMonth() + 1, 2) + '-' + pad(currentDate.getDate(), 2); - - let dailyFile = fileCursor.files.get(stringDate); - - if (dailyFile !== undefined) { - - for (let i = 0; i < dailyFile.length; i++) { - - let candle = { - open: undefined, - close: undefined, - min: 10000000000000, - max: 0, - begin: undefined, - end: undefined, - direction: undefined - }; - - candle.min = dailyFile[i][0]; - candle.max = dailyFile[i][1]; - - candle.open = dailyFile[i][2]; - candle.close = dailyFile[i][3]; - - candle.begin = dailyFile[i][4]; - candle.end = dailyFile[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'; } - - if (candle.begin >= farLeftDate.valueOf() && candle.end <= farRightDate.valueOf()) { - - candles.push(candle); - - if (datetime.valueOf() >= candle.begin && datetime.valueOf() <= candle.end) { - - thisObject.currentCandle = candle; - thisObject.container.eventHandler.raiseEvent("Current Candle Changed", thisObject.currentCandle); - - } - } - } - } - - currentDate = new Date(currentDate.valueOf() + ONE_DAY_IN_MILISECONDS); - } - - /* Lests check if all the visible screen is going to be covered by candles. */ - - let lowerEnd = leftDate.valueOf(); - let upperEnd = rightDate.valueOf(); - - if (candles.length > 0) { - - if (candles[0].begin > lowerEnd || candles[candles.length - 1].end < upperEnd) { - - setTimeout(recalculate, 2000); - - //console.log("File missing while calculating candles, scheduling a recalculation in 2 seconds."); - - } - } - - //console.log("Olivia > recalculateUsingDailyFiles > total candles generated : " + candles.length); - - } - - function recalculateUsingMarketFiles() { - - if (marketFile === undefined) { return; } // Initialization not complete yet. - - let daysOnSides = getSideDays(timePeriod); - - let leftDate = getDateFromPoint(viewPort.visibleArea.topLeft, thisObject.container, plotArea); - let rightDate = getDateFromPoint(viewPort.visibleArea.topRight, thisObject.container, plotArea); - - let dateDiff = rightDate.valueOf() - leftDate.valueOf(); - - leftDate = new Date(leftDate.valueOf() - dateDiff * 1.5); - rightDate = new Date(rightDate.valueOf() + dateDiff * 1.5); - - candles = []; - - for (let i = 0; i < marketFile.length; i++) { - - let candle = { - open: undefined, - close: undefined, - min: 10000000000000, - max: 0, - begin: undefined, - end: undefined, - direction: undefined + date: Math.trunc(file[i][0] / 60000) * 60000 + 30000, + rate: file[i][1], + newPositions: file[i][2], + newTrades: file[i][3], + movedPositions: file[i][4] }; - candle.min = marketFile[i][0]; - candle.max = marketFile[i][1]; - - candle.open = marketFile[i][2]; - candle.close = marketFile[i][3]; - - candle.begin = marketFile[i][4]; - candle.end = marketFile[i][5]; - - if (candle.open > candle.close) { candle.direction = 'down'; } - if (candle.open < candle.close) { candle.direction = 'up'; } - if (candle.open === candle.close) { candle.direction = 'side'; } - - if (candle.begin >= leftDate.valueOf() && candle.end <= rightDate.valueOf()) { - - candles.push(candle); - - if (datetime.valueOf() >= candle.begin && datetime.valueOf() <= candle.end) { - - thisObject.currentCandle = candle; - thisObject.container.eventHandler.raiseEvent("Current Candle Changed", thisObject.currentCandle); - - } - } + history.push(newHistoryRecord); } - //console.log("Olivia > recalculateUsingMarketFiles > total candles generated : " + candles.length); + thisObject.container.eventHandler.raiseEvent("History Changed", history); } function recalculateScale() { - if (marketFile === undefined) { return; } // We need the market file to be loaded to make the calculation. + if (file === undefined) { return; } // We need the market file to be loaded to make the calculation. if (plotArea.maxValue > 0) { return; } // Already calculated. @@ -472,7 +143,7 @@ let maxValue = 0; - for (let i = 0; i < marketFile.length; i++) { + for (let i = 0; i < file.length; i++) { let currentMax = marketFile[i][1]; // 1 = rates. @@ -489,176 +160,66 @@ function plotChart() { - if (candles.length > 0) { + for (let i = 0; i < history.length; i++) { - /* Now we calculate and plot the candles */ + record = history[i]; - for (let i = 0; i < candles.length; i++) { - - candle = candles[i]; - - let candlePoint1 = { - x: candle.begin + timePeriod / 7 * 1.5, - y: candle.open + let point = { + x: record.begin + timePeriod / 7 * 1.5, + y: record.open }; - let candlePoint2 = { - x: candle.begin + timePeriod / 7 * 5.5, - y: candle.open - }; + point = plotArea.inverseTransform(point, thisObject.container.frame.height); - let candlePoint3 = { - x: candle.begin + timePeriod / 7 * 5.5, - y: candle.close - }; + point = transformThisPoint(point, thisObject.container); - let candlePoint4 = { - x: candle.begin + timePeriod / 7 * 1.5, - y: candle.close - }; - - candlePoint1 = plotArea.inverseTransform(candlePoint1, thisObject.container.frame.height); - candlePoint2 = plotArea.inverseTransform(candlePoint2, thisObject.container.frame.height); - candlePoint3 = plotArea.inverseTransform(candlePoint3, thisObject.container.frame.height); - candlePoint4 = plotArea.inverseTransform(candlePoint4, thisObject.container.frame.height); - - candlePoint1 = transformThisPoint(candlePoint1, thisObject.container); - candlePoint2 = transformThisPoint(candlePoint2, thisObject.container); - candlePoint3 = transformThisPoint(candlePoint3, thisObject.container); - candlePoint4 = transformThisPoint(candlePoint4, thisObject.container); - - if (candlePoint2.x < viewPort.visibleArea.bottomLeft.x || candlePoint1.x > viewPort.visibleArea.bottomRight.x) { + if (point.x < viewPort.visibleArea.bottomLeft.x || point.x > viewPort.visibleArea.bottomRight.x) { continue; } - candlePoint1 = viewPort.fitIntoVisibleArea(candlePoint1); - candlePoint2 = viewPort.fitIntoVisibleArea(candlePoint2); - candlePoint3 = viewPort.fitIntoVisibleArea(candlePoint3); - candlePoint4 = viewPort.fitIntoVisibleArea(candlePoint4); - - let stickPoint1 = { - x: candle.begin + timePeriod / 7 * 3.2, - y: candle.max - }; - - let stickPoint2 = { - x: candle.begin + timePeriod / 7 * 3.8, - y: candle.max - }; - - let stickPoint3 = { - x: candle.begin + timePeriod / 7 * 3.8, - y: candle.min - }; - - let stickPoint4 = { - x: candle.begin + timePeriod / 7 * 3.2, - y: candle.min - }; - - stickPoint1 = plotArea.inverseTransform(stickPoint1, thisObject.container.frame.height); - stickPoint2 = plotArea.inverseTransform(stickPoint2, thisObject.container.frame.height); - stickPoint3 = plotArea.inverseTransform(stickPoint3, thisObject.container.frame.height); - stickPoint4 = plotArea.inverseTransform(stickPoint4, thisObject.container.frame.height); - - stickPoint1 = transformThisPoint(stickPoint1, thisObject.container); - stickPoint2 = transformThisPoint(stickPoint2, thisObject.container); - stickPoint3 = transformThisPoint(stickPoint3, thisObject.container); - stickPoint4 = transformThisPoint(stickPoint4, thisObject.container); - - stickPoint1 = viewPort.fitIntoVisibleArea(stickPoint1); - stickPoint2 = viewPort.fitIntoVisibleArea(stickPoint2); - stickPoint3 = viewPort.fitIntoVisibleArea(stickPoint3); - stickPoint4 = viewPort.fitIntoVisibleArea(stickPoint4); + point = viewPort.fitIntoVisibleArea(point); 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.moveTo(point.x, point.y); browserCanvasContext.closePath(); - browserCanvasContext.fillStyle = 'rgba(54, 54, 54, 1)'; - browserCanvasContext.fill(); + + if (record.direction === 'up') { browserCanvasContext.strokeStyle = 'rgba(27, 105, 7, 1)'; } + if (record.direction === 'down') { browserCanvasContext.strokeStyle = 'rgba(130, 9, 9, 1)'; } + if (record.direction === 'side') { browserCanvasContext.strokeStyle = 'rgba(27, 7, 105, 1)'; } if (datetime !== undefined) { let dateValue = datetime.valueOf(); - if (dateValue >= candle.begin && dateValue <= candle.end) { + if (dateValue >= record.begin && dateValue <= record.end) { - browserCanvasContext.strokeStyle = 'rgba(255, 233, 31, 1)'; // Current candle accroding to time + /* highlight the current record */ - } 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 - }; - - thisObject.container.eventHandler.raiseEvent("Current Candle Info Changed", currentCandle); + browserCanvasContext.fillStyle = 'rgba(255, 233, 31, 1)'; // Current record accroding to time } 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 (record.direction === 'up') { browserCanvasContext.fillStyle = 'rgba(64, 217, 26, 1)'; } + if (record.direction === 'down') { browserCanvasContext.fillStyle = 'rgba(219, 18, 18, 1)'; } + if (record.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 (record.direction === 'up') { browserCanvasContext.fillStyle = 'rgba(64, 217, 26, 1)'; } + if (record.direction === 'down') { browserCanvasContext.fillStyle = 'rgba(219, 18, 18, 1)'; } + if (record.direction === 'side') { browserCanvasContext.fillStyle = 'rgba(64, 26, 217, 1)'; } } - - if ( - candlePoint1.x < viewPort.visibleArea.topLeft.x + 50 + point.x < viewPort.visibleArea.topLeft.x + 50 || - candlePoint1.x > viewPort.visibleArea.bottomRight.x - 50 + point.x > viewPort.visibleArea.bottomRight.x - 50 ) { - // we leave this candles without fill. + // we leave this history without fill. } else { browserCanvasContext.fill(); } @@ -668,12 +229,12 @@ } - } + } function onLayerStatusChanged(eventData) { - if (eventData.layer === 'Olivia Candlesticks') { + if (eventData.layer === 'Mariam Trades History') { layerStatus = eventData.status; } @@ -681,14 +242,10 @@ function onZoomChanged(event) { - recalculate(); - } function onDragFinished() { - recalculate(); - } } From 8a49f6918c9883fef6e8895ae4bb7850beafe8e9 Mon Sep 17 00:00:00 2001 From: Luis Fernando Molina Date: Wed, 28 Feb 2018 08:05:18 +0100 Subject: [PATCH 03/54] Implementation completed --- .vs/AAMariam-Plotter/v15/.suo | Bin 18944 -> 18944 bytes History.js | 117 ++++++++++++++++++++-------------- 2 files changed, 68 insertions(+), 49 deletions(-) diff --git a/.vs/AAMariam-Plotter/v15/.suo b/.vs/AAMariam-Plotter/v15/.suo index 7c0634ec7435ac7b75424dfa4edacd3fc226c588..d07e77737a3d482dd6edf78db5b53281cb4072d9 100644 GIT binary patch delta 472 zcmZpe!q_l{aYGIho5AeKxk(!~7cu=}W;^h!tO&$r3uNPE!S{TVkO7HVah?4euD%OD7pN49427u^sJtl@wfgnF3au(?D( hgc*kmjrDm1Gl5n?fYyQMAjakc_V1ao2|GKm0RUWDsNw(s delta 490 zcmaKoO-e&C5XX}|j8T%7C$0T(Tcj305LfaR3a+IopiM@L;lWV3^@I!+iXgYrb6b*9Re26|25p;7R-xa`kq7pK`g7hDpZQ0R0y& zEC!PhwNsh`Z?^gnK`(IB|q4o(0 zzVFnS0Eqosgb#5V;?U|5RywrmM{{GCKtz9pcx*+pp3Vk;GUwr4UP7E%uG3|^*{q)9 z+3pa}oJvn5YqawyKzbmPDxTX$za&@N3I4(r|D1hQ>GBc#TYJW244a$pq8zpi;{<&Q Io4Z^22R{k48~^|S diff --git a/History.js b/History.js index 6381212cc..f7290d2e4 100644 --- a/History.js +++ b/History.js @@ -160,76 +160,95 @@ function plotChart() { - for (let i = 0; i < history.length; i++) { + for (let i = 0; i < history.length; i++) { - record = history[i]; + record = history[i]; - let point = { - x: record.begin + timePeriod / 7 * 1.5, - y: record.open - }; + let point = { + x: record.begin + timePeriod / 7 * 1.5, + y: record.open + }; - point = plotArea.inverseTransform(point, thisObject.container.frame.height); + point = plotArea.inverseTransform(point, thisObject.container.frame.height); - point = transformThisPoint(point, thisObject.container); + point = transformThisPoint(point, thisObject.container); - if (point.x < viewPort.visibleArea.bottomLeft.x || point.x > viewPort.visibleArea.bottomRight.x) { - continue; - } + if (point.x < viewPort.visibleArea.bottomLeft.x || point.x > viewPort.visibleArea.bottomRight.x) { + continue; + } - point = viewPort.fitIntoVisibleArea(point); + point = viewPort.fitIntoVisibleArea(point); - browserCanvasContext.beginPath(); + let isCurrentRecord = false; - browserCanvasContext.moveTo(point.x, point.y); + if (datetime !== undefined) { - browserCanvasContext.closePath(); + let dateValue = datetime.valueOf(); - if (record.direction === 'up') { browserCanvasContext.strokeStyle = 'rgba(27, 105, 7, 1)'; } - if (record.direction === 'down') { browserCanvasContext.strokeStyle = 'rgba(130, 9, 9, 1)'; } - if (record.direction === 'side') { browserCanvasContext.strokeStyle = 'rgba(27, 7, 105, 1)'; } + if (dateValue >= record.date - 30000 && dateValue + 30000 - 1 <= record.date) { - if (datetime !== undefined) { + /* highlight the current record */ - let dateValue = datetime.valueOf(); + browserCanvasContext.fillStyle = 'rgba(255, 233, 31, 1)'; // Current record accroding to time + isCurrentRecord = true; - if (dateValue >= record.begin && dateValue <= record.end) { + } + } - /* highlight the current record */ + let radiusFactor = 3; - browserCanvasContext.fillStyle = 'rgba(255, 233, 31, 1)'; // Current record accroding to time + let radius1 = record.newPositions * radiusFactor; + let radius2 = radius1 + record.movedPositions * radiusFactor; + let radius3 = radius2 + record.newTrades * radiusFactor; - } else { + browserCanvasContext.beginPath(); - if (record.direction === 'up') { browserCanvasContext.fillStyle = 'rgba(64, 217, 26, 1)'; } - if (record.direction === 'down') { browserCanvasContext.fillStyle = 'rgba(219, 18, 18, 1)'; } - if (record.direction === 'side') { browserCanvasContext.fillStyle = 'rgba(64, 26, 217, 1)'; } - } - - } else { - - if (record.direction === 'up') { browserCanvasContext.fillStyle = 'rgba(64, 217, 26, 1)'; } - if (record.direction === 'down') { browserCanvasContext.fillStyle = 'rgba(219, 18, 18, 1)'; } - if (record.direction === 'side') { browserCanvasContext.fillStyle = 'rgba(64, 26, 217, 1)'; } - - } - - if ( - point.x < viewPort.visibleArea.topLeft.x + 50 - || - point.x > viewPort.visibleArea.bottomRight.x - 50 - ) { - // we leave this history without fill. - } else { - browserCanvasContext.fill(); - } - - browserCanvasContext.lineWidth = 1; - browserCanvasContext.stroke(); + if (isCurrentRecord === false) { + browserCanvasContext.strokeStyle = 'rgba(27, 105, 7, 1)'; + browserCanvasContext.fillStyle = 'rgba(64, 217, 26, 1)'; } + browserCanvasContext.arc(point.x, point.y, radius1, 0, Math.PI * 2, true); + + if (isCurrentRecord === false) { + + browserCanvasContext.strokeStyle = 'rgba(105, 27, 7, 1)'; + browserCanvasContext.fillStyle = 'rgba(217, 64, 26, 1)'; + + } + + browserCanvasContext.arc(point.x, point.y, radius2, 0, Math.PI * 2, true); + + if (isCurrentRecord === false) { + + browserCanvasContext.strokeStyle = 'rgba(27, 7, 105, 1)'; + browserCanvasContext.fillStyle = 'rgba(64, 26, 217, 1)'; + + } + + browserCanvasContext.arc(point.x, point.y, radius3, 0, Math.PI * 2, true); + + browserCanvasContext.closePath(); + + + if ( + point.x < viewPort.visibleArea.topLeft.x + 50 + || + point.x > viewPort.visibleArea.bottomRight.x - 50 + ) { + // we leave this history without fill. + } else { + browserCanvasContext.fill(); + } + + browserCanvasContext.lineWidth = 1; + browserCanvasContext.stroke(); + + + } + } function onLayerStatusChanged(eventData) { From b6ccb9b7dc64cff31d6ae094fc17d111ef5f732a Mon Sep 17 00:00:00 2001 From: Luis Fernando Molina Date: Wed, 28 Feb 2018 09:11:23 +0100 Subject: [PATCH 04/54] Plotting working --- .vs/AAMariam-Plotter/v15/.suo | Bin 18944 -> 18944 bytes History.js | 25 +++++++++++++++---------- 2 files changed, 15 insertions(+), 10 deletions(-) diff --git a/.vs/AAMariam-Plotter/v15/.suo b/.vs/AAMariam-Plotter/v15/.suo index d07e77737a3d482dd6edf78db5b53281cb4072d9..e587ee6e315034abbaf24886f6bb6b951b52db16 100644 GIT binary patch delta 339 zcmZpe!q_l{aYGIh>jcv$TA7;*nZg-4_!t-%{sY0}Kyj7LUzjVHSQ&mET$#1GkS&Of zmw^W;%Y~wXCxCIXi(Uf{NDl{!44*$EFC$2p8CkeQ04B_dEc`{#pJ}tRP6OlS!=kOi z9MVW~lS?#1I8YU9`ZG>G%w)K^MEeTkAqj5&!spM(3pSe>S-3>NpKgv$Jpm)8xat4U?Vu8o^c~yKXYjN?ry&pk{s~ s12&iF2e52DB5A|5$! Date: Wed, 28 Feb 2018 10:58:51 +0100 Subject: [PATCH 05/54] History being plotted well --- .vs/AAMariam-Plotter/v15/.suo | Bin 18944 -> 18432 bytes History.js | 71 ++++++++++++++---- ...am-Plotter.njsproj.CoreCompileInputs.cache | 1 + ...ariam-Plotter.njsproj.FileListAbsolute.txt | 3 + ...tter.njsprojResolveAssemblyReference.cache | Bin 0 -> 2216 bytes 5 files changed, 60 insertions(+), 15 deletions(-) create mode 100644 obj/Debug/AAMariam-Plotter.njsproj.CoreCompileInputs.cache create mode 100644 obj/Debug/AAMariam-Plotter.njsproj.FileListAbsolute.txt create mode 100644 obj/Debug/AAMariam-Plotter.njsprojResolveAssemblyReference.cache diff --git a/.vs/AAMariam-Plotter/v15/.suo b/.vs/AAMariam-Plotter/v15/.suo index e587ee6e315034abbaf24886f6bb6b951b52db16..c558203f3923cbf335a6466f815322f523b8867d 100644 GIT binary patch delta 486 zcmZpe!q_l@ae{#?0}Kc-FbD$Kj6nSF|Ns9WVaCah9OfGnY8WRm<*+6MH?6MPT*ws8 z$RQ4t11kAHIZ#|>^B3j{Ce{M+TiHNKws1ByNgjX3&CYs_jGK?}H!$)@0yWAbYc3Hy z&$!rGn`!c4Hp9s!q9Gi7$g*EVdl=P27%~|O7y=kl8HyN+f$U<25+FN|AsI-z0C5?E zA%g*f_GCpSNdYYeCPp!!3DQWWOfC_T*(@NjgOP&^S=7OeW%Cco3p^YkPa`~|7Qh5{ zC9(;dOEk{|eId-s#DVPi$tAi0Jgh+7$ZnqeMc03`Gan=4W*2=MCQ=;Fs5RM9(jVy3 t&5XQYPhdLNcssY?F`$Joa0$pz*nGhLJ+t6bm>7`$1jP264>&up0075cj${A; delta 417 zcmZpez}PT_ae{#?69W_oFfgzHnT$aE@Bjb*AW`PYjvVG26KWVIG3BsMFnywxxw()j zoRNbMC%H}W36-=xQKM$_V+FZyM&c?xoBFW>=xY=2ck&y?ahaXw0g#Q8~ zk2p|73`JD%JWzu+D-(w_lJMjb(GU(vB!SIeM0*$~OGvr!fZPEClLe&=Hc6adoP2^! zXR?DE%jO@F7kD^8c7RksT&otq#KQ^{K{kGKiRO96#m>S^lMgc)PA<_6;1L9>K(=r4 z7hV6&&U}rGn~&)4!DaCgMjnt~kOKhX3ghkEg4cjDFz_D4*nGhLJ+t5`m>7^=0mO2f M4>&upEOKK40GK$G;Q#;t diff --git a/History.js b/History.js index 9d4ed88fb..1fa7fb78c 100644 --- a/History.js +++ b/History.js @@ -80,6 +80,8 @@ timePeriod = pTimePeriod; + recalculate(); + } function setDatetime(newDatetime) { @@ -98,7 +100,21 @@ function recalculate() { - for (let i = 0; i < file.length; i++) { + if (file === undefined) { return; } + + /* + + We are going to filter the records depending on the Time Period. We want that for a 1 min time peroid all the records appears on screen, + but for higher periods, we will filter out some records, so that they do not overlap ever. + + */ + + history = []; + + let oneMin = 60000; + let step = timePeriod / oneMin; + + for (let i = 0; i < file.length; i = i + step) { let newHistoryRecord = { @@ -185,58 +201,83 @@ let dateValue = datetime.valueOf(); - if (dateValue >= record.date - 30000 && dateValue + 30000 - 1 <= record.date) { + if (dateValue >= record.date - timePeriod / 2 && dateValue <= record.date + timePeriod / 2 - 1) { - /* highlight the current record */ - - browserCanvasContext.fillStyle = 'rgba(255, 233, 31, 1)'; // Current record accroding to time isCurrentRecord = true; } } let radiusFactor = 3; + let opacity = '0.2'; let radius1 = record.newPositions * radiusFactor; let radius2 = radius1 + record.movedPositions * radiusFactor; let radius3 = radius2 + record.newTrades * radiusFactor; + /* Outer Circle */ + browserCanvasContext.beginPath(); + browserCanvasContext.strokeStyle = 'rgba(27, 105, 7, ' + opacity + ')'; + if (isCurrentRecord === false) { - browserCanvasContext.strokeStyle = 'rgba(27, 105, 7, 1)'; - browserCanvasContext.fillStyle = 'rgba(64, 217, 26, 1)'; + browserCanvasContext.fillStyle = 'rgba(64, 217, 26, ' + opacity + ')'; + + } else { + + browserCanvasContext.fillStyle = 'rgba(255, 233, 31, ' + opacity + ')'; /* highlight the current record */ } browserCanvasContext.arc(point.x, point.y, radius3, 0, Math.PI * 2, true); - //browserCanvasContext.closePath(); - //browserCanvasContext.beginPath(); + browserCanvasContext.closePath(); + browserCanvasContext.fill(); + + /* Middle Circle */ + + browserCanvasContext.beginPath(); + + browserCanvasContext.strokeStyle = 'rgba(44, 61, 89, ' + opacity + ')'; if (isCurrentRecord === false) { - browserCanvasContext.strokeStyle = 'rgba(105, 27, 7, 1)'; - browserCanvasContext.fillStyle = 'rgba(217, 64, 26, 1)'; + browserCanvasContext.fillStyle = 'rgba(50, 108, 201, ' + opacity + ')'; + + } else { + + browserCanvasContext.fillStyle = 'rgba(255, 233, 31, ' + opacity + ')'; /* highlight the current record */ } browserCanvasContext.arc(point.x, point.y, radius2, 0, Math.PI * 2, true); - //browserCanvasContext.closePath(); - //browserCanvasContext.beginPath(); + browserCanvasContext.closePath(); + browserCanvasContext.fill(); + + /* Inner Circle */ + + browserCanvasContext.beginPath(); + + browserCanvasContext.strokeStyle = 'rgba(27, 7, 105, ' + opacity + ')'; if (isCurrentRecord === false) { - browserCanvasContext.strokeStyle = 'rgba(27, 7, 105, 1)'; - browserCanvasContext.fillStyle = 'rgba(64, 26, 217, 1)'; + browserCanvasContext.fillStyle = 'rgba(64, 26, 217, ' + opacity + ')'; + + } else { + + browserCanvasContext.fillStyle = 'rgba(255, 233, 31, ' + opacity + ')'; /* highlight the current record */ } browserCanvasContext.arc(point.x, point.y, radius1, 0, Math.PI * 2, true); browserCanvasContext.closePath(); + browserCanvasContext.fill(); + if ( point.x < viewPort.visibleArea.topLeft.x + 50 diff --git a/obj/Debug/AAMariam-Plotter.njsproj.CoreCompileInputs.cache b/obj/Debug/AAMariam-Plotter.njsproj.CoreCompileInputs.cache new file mode 100644 index 000000000..43ce23bd9 --- /dev/null +++ b/obj/Debug/AAMariam-Plotter.njsproj.CoreCompileInputs.cache @@ -0,0 +1 @@ +a4fca7697da12adc1a74c13ff1ccc52af419c79d diff --git a/obj/Debug/AAMariam-Plotter.njsproj.FileListAbsolute.txt b/obj/Debug/AAMariam-Plotter.njsproj.FileListAbsolute.txt new file mode 100644 index 000000000..f4231dbb4 --- /dev/null +++ b/obj/Debug/AAMariam-Plotter.njsproj.FileListAbsolute.txt @@ -0,0 +1,3 @@ +C:\Users\Luis\source\repos\AAMariam-Plotter\obj\Debug\AAMariam-Plotter.njsprojResolveAssemblyReference.cache +C:\Users\Luis\source\repos\AAMariam-Plotter\obj\Debug\AAMariam-Plotter.njsproj.CoreCompileInputs.cache +C:\Users\Luis\source\repos\AAMariam-Plotter\bin\Microsoft.NodejsTools.WebRole.dll diff --git a/obj/Debug/AAMariam-Plotter.njsprojResolveAssemblyReference.cache b/obj/Debug/AAMariam-Plotter.njsprojResolveAssemblyReference.cache new file mode 100644 index 0000000000000000000000000000000000000000..67d5be9b7a12b38e6fe524eedeba2ea6a1a31246 GIT binary patch literal 2216 zcmb_d+iu%N5T)*RdTpA)&tW2&Cd7K4^8EmeX{a^_^}K>O{gp42hO3tnZvAqmX;w!0b$% zLwqo5wu4Tv8?;(}r^(u^M8-b7-o{|2G(-cA|0w}SaS=4l}-Sv+P}L{la~Zj;ik@ZnU73+{t7>BoTo2t|xY zl^?M%0c9A4f>A1MnAh3r&vo6t#^?SO{ja{i_ay~et&;Orkwgi_HqB_ETt;!w-5);g zpM3S*tN7z& z1%zec5=J+x+udE(@j9Qk_S$!$d2g>ow%*8Fg005XY9uC811)(xwz(ScXc_`RaeKlP z)|&@P33({J3D;QT*i`+vmr&fa$>LFzq~&f)h}d)reou<1Kxr+0lEwNEf~-B(0L2ySaRO}Wl?GcxSQfv{Ynk^4-6>1GX3bE*3e!?BQDPoj_3KYK!UMXaR= zKXkE3L_8*Q$U3Kt%Ug3DDYmgjSoijga%qms{?wJh_Q7o9~R z!~q{Ck`bHE%LQ9_KAo*O`*x>3yIPl5Li^&T{$&2IA#ja>)qYFi$(J`Vdm9Tg6092K z{U;RVEfhy|&+IoEjqZLUBiY8XvXNvP3zBUtS*Ed~kVw|rMpebX@H%}vtf-MI7j(b4 zu3;8`M#g@P%19xuV441jvv&e(-9kznuTbYrFkC Date: Wed, 28 Feb 2018 12:29:35 +0100 Subject: [PATCH 06/54] not fill at borders --- History.js | 28 +++++++++++++--------------- 1 file changed, 13 insertions(+), 15 deletions(-) diff --git a/History.js b/History.js index 1fa7fb78c..e80160e8a 100644 --- a/History.js +++ b/History.js @@ -215,6 +215,8 @@ let radius2 = radius1 + record.movedPositions * radiusFactor; let radius3 = radius2 + record.newTrades * radiusFactor; + browserCanvasContext.lineWidth = 1; + /* Outer Circle */ browserCanvasContext.beginPath(); @@ -234,7 +236,11 @@ browserCanvasContext.arc(point.x, point.y, radius3, 0, Math.PI * 2, true); browserCanvasContext.closePath(); - browserCanvasContext.fill(); + + if (point.x < viewPort.visibleArea.topLeft.x + 50 || point.x > viewPort.visibleArea.bottomRight.x - 50) {/*we leave this history without fill. */ } else { + browserCanvasContext.fill(); + } + browserCanvasContext.stroke(); /* Middle Circle */ @@ -255,7 +261,11 @@ browserCanvasContext.arc(point.x, point.y, radius2, 0, Math.PI * 2, true); browserCanvasContext.closePath(); - browserCanvasContext.fill(); + + if (point.x < viewPort.visibleArea.topLeft.x + 50 || point.x > viewPort.visibleArea.bottomRight.x - 50) {/*we leave this history without fill. */ } else { + browserCanvasContext.fill(); + } + browserCanvasContext.stroke(); /* Inner Circle */ @@ -276,25 +286,13 @@ browserCanvasContext.arc(point.x, point.y, radius1, 0, Math.PI * 2, true); browserCanvasContext.closePath(); - browserCanvasContext.fill(); - - if ( - point.x < viewPort.visibleArea.topLeft.x + 50 - || - point.x > viewPort.visibleArea.bottomRight.x - 50 - ) { - // we leave this history without fill. - } else { + if (point.x < viewPort.visibleArea.topLeft.x + 50 || point.x > viewPort.visibleArea.bottomRight.x - 50) {/*we leave this history without fill. */ } else { browserCanvasContext.fill(); } - - browserCanvasContext.lineWidth = 1; browserCanvasContext.stroke(); - } - } function onLayerStatusChanged(eventData) { From ba2bfbc9139eb772adc51908d3f7d71735161fc5 Mon Sep 17 00:00:00 2001 From: Luis Fernando Molina Date: Thu, 1 Mar 2018 11:07:51 +0100 Subject: [PATCH 07/54] new function renamed --- .vs/Plotters-Trading/v15/.suo | Bin 0 -> 18944 bytes Details.js | 2 +- History.js | 2 +- AAMariam-Plotter.sln => Plotters-Trading.sln | 2 +- AAMariam-Plotter.njsproj => Project.njsproj | 2 +- 5 files changed, 4 insertions(+), 4 deletions(-) create mode 100644 .vs/Plotters-Trading/v15/.suo rename AAMariam-Plotter.sln => Plotters-Trading.sln (87%) rename AAMariam-Plotter.njsproj => Project.njsproj (99%) diff --git a/.vs/Plotters-Trading/v15/.suo b/.vs/Plotters-Trading/v15/.suo new file mode 100644 index 0000000000000000000000000000000000000000..90d935b8e6d664078bdaf12512958f535d524283 GIT binary patch literal 18944 zcmeHO&2v*#6u&8;P(?))5mAdGqVi%w(zLIPA8FEvGjw2}1;)uHw67&4G@ZP((4qY+ zoN=6S;keUA?JT!6h_s~Jsd)BLb28czmAU*~99C8!ly3bc? zAMXoYNa###(wx4`7tEZPggPSia zgXy$b21-HX(SFjrhMY!8Nq@0H9{95T19)bNKZ3eYcA2Lw*oSXY7xsf* z2E77e`2k#C1-%A(9W(?w1bPGXCWv){w6zlG<@n!$K5UtOO6}(Of0~sZpYh+e{pt1i ze+uI4bo?uA+m3J04zLgD^PdFm1nmM1f;cuwyOAgV>^|DiJ)q}7dqKhYRnmNPuH*1{ zMR7%3g|{o=YU=mU-7+17=Fyc=7uagAwDoTSkB?TWOaa#g?kV^>7oPB(xGa5eSXej0L0rQ1Iyj*JUjaWezTTg{Yd~;J(59K<$5EH# zjfrswql^-Ke-3d#2Dk;>yFx`K4)`dG6nJBN=E&cwRL0PL`cq;v$&dQ{aGa_tX?&NG zzFPV61>i4=S(IJ_2SxCa2WnoTS5ej5LPUU18^O7NDgF@Z-mVCs75+5PDVem4#BzA+ z!4w8QZ4qsdDZbwRb7)yXYMR$ZPtJ2_@jOaP64`t5AT~>m0iX7eF|8>+sW4;PJFbi@7x)=$0Nc-9YT(khkBNcxVo2hke z@2M{TX=odx?i_T^0o7`KBaN#?VEa8}@3;18jX7Z}>n8;4&t}_A@#!mQFPZA~UA3L_ z;dnO1ttG_{BiK$fQKuPbrEBOKDQMgM=R~;9M@F-j6LQm zO{>SJyWgX2%6nJlR4i?gtUj83>RkcEZh+^vj1 zZ?<5;uh34;O3OKq8h)wU{=akA%;z-YgLaI>)Cn)pvqACw@ReP~zkmGXyRWzZ^0~eK zt@;oH9iMa>&pmv+6cVr1#^Yglp9M&I2~y=QnQw)A_#DwmEB)$IKOTiB^b4Bd3ODAs zNan&3P&m_-_MVKuBj|tD=3VQY{tok7nYeyFiIG-7v+{^~*|-vZm(k}+&O&^E-FT)G zavk6Xc(g@AjKk{LixE7rkxSy&mSqu?rsRDL@7So3#@(n`hX`k} z=2MI7&3biIYG`d8#hbS}$+|nG-|i)EC%~f+z5HTWoP`2$eU+=uj#vZ2A|mY}NaqX` zDU5j;S0uRld>Od{q@&B>qn`6qjlbLFg|pZs_@v&fpe-rzJ}r;v!|BxZq_X>mu8%7$yqA8*)xS=xr|5FR4F%`U!2dTopLT;aKj7k z+S-k1JRKde6HzNOF&wqxiFn$wqtU39iYGJCXnG`V+sXAUWbS0%Ef-6xZ7>I88=}Ew z%746tthO)50g?Vs^EX&+Qlc}B>hQH=Ip_FDE^#ShIkEV#6+b>YYT1d|IcwO-&Bg4v z?mDCXPK!gY_&f5`oJx*k*fIO?i(n_is%P;2j|_#D?tPOZ*gn4bSoXD>|g zhXCHo^B*+&+ygbm*V|ve$J)X954rcx8L}yUug`xFmwVc#`29Hl!8pVeUzdLm&VNW; zVl#ma-_#Di$@vfNz0yzi1E0~5&-st8_TPJT{)1-NRjT0p2lr4qIR6pic?O7XSbN literal 0 HcmV?d00001 diff --git a/Details.js b/Details.js index c0dcd6005..ab0804398 100644 --- a/Details.js +++ b/Details.js @@ -1,4 +1,4 @@ -function newAAMastersAAOliviaVolumes() { +function newAAMastersPlottersTradingDetails() { let thisObject = { diff --git a/History.js b/History.js index e80160e8a..318dc3d24 100644 --- a/History.js +++ b/History.js @@ -1,4 +1,4 @@ -function newAAMastersAAMariamTradingHistory() { +function newAAMastersPlottersTradingHistory() { let thisObject = { diff --git a/AAMariam-Plotter.sln b/Plotters-Trading.sln similarity index 87% rename from AAMariam-Plotter.sln rename to Plotters-Trading.sln index 83a9e865a..661fcc076 100644 --- a/AAMariam-Plotter.sln +++ b/Plotters-Trading.sln @@ -3,7 +3,7 @@ Microsoft Visual Studio Solution File, Format Version 12.00 # Visual Studio 15 VisualStudioVersion = 15.0.27130.2027 MinimumVisualStudioVersion = 10.0.40219.1 -Project("{9092AA53-FB77-4645-B42D-1CCCA6BD08BD}") = "AAMariam-Plotter", "AAMariam-Plotter.njsproj", "{096B35AD-F86F-47B9-A99F-04CA93397DA8}" +Project("{9092AA53-FB77-4645-B42D-1CCCA6BD08BD}") = "Project", "Project.njsproj", "{096B35AD-F86F-47B9-A99F-04CA93397DA8}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution diff --git a/AAMariam-Plotter.njsproj b/Project.njsproj similarity index 99% rename from AAMariam-Plotter.njsproj rename to Project.njsproj index 762c10990..b8ebdeb8f 100644 --- a/AAMariam-Plotter.njsproj +++ b/Project.njsproj @@ -12,7 +12,7 @@ {3AF33F2E-1136-4D97-BBB7-1795711AC8B8};{349c5851-65df-11da-9384-00065b846f21};{9092AA53-FB77-4645-B42D-1CCCA6BD08BD} 14.0 $(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion) - AAMariam-Plotter + Project From 1fdf40f091fd5c290f275a96ca20defd511eaea7 Mon Sep 17 00:00:00 2001 From: Luis Fernando Molina Date: Thu, 1 Mar 2018 14:12:13 +0100 Subject: [PATCH 08/54] layerStatus removed --- .vs/Plotters-Trading/v15/.suo | Bin 18944 -> 19968 bytes Details.js | 26 ++------------------------ History.js | 21 +-------------------- 3 files changed, 3 insertions(+), 44 deletions(-) diff --git a/.vs/Plotters-Trading/v15/.suo b/.vs/Plotters-Trading/v15/.suo index 90d935b8e6d664078bdaf12512958f535d524283..1616f7cdc0ef74eb823171a81cfba22ca4b99c19 100644 GIT binary patch delta 2317 zcmeHIOH5Ni6rCAfODV5~@@s*%U}-4}q3G5hO8zLiiapA&5qhR+&gA2n3jXPtED>tlMGyx;ldmlXh;L;6~oOI^iJ7?zIx#w1S$dyNY zrbBQe91?lv@7-6wU7G#O?Tj(S0^?$wH$hB(4$-13<0aVYV|0ztQm=w z0#=9}k%aR^gaKhh=n=^XC^qCvZk$X9e9$RLvu6i5{eoo6r|+~`-KprcAkq-&hzvv~ zA`3y(1n9BZVNxSD^)XgP}BO2je5aYPkzrF&{|b_#JC;X~9R>JbfyMuf^Y9axMM zhj$am*-`&QKaVMHW)7LGEkm1la9VaM3>X&xrtNu=pi&Gy!A@3l-VIudZ|h@MN3*3HQ&-2%upk>^A=b+V!Q}Kpk3Ap0TXR6MH|kO_lmX8<9&uzC zpK)5@&_f{61wKc4N+%m+*I7UAy^IVcpg8>IdJLmT!Xv)tL9HUPx6=#Gq70aGp3ALe z^ahO8Fe-)#R>rEa9O_vG-s@f7>8O%7A~JhJ!M=f^lK!E|n^>=uUBO;L&=XARuB$r} z918UgLfqBFx7!xo4hXx7Qs~BXT^fD9?NPW>60C6-Gpu-$c`Hm86l^)jv6~G>3jId9 z8jT%fYd3-W?wy3_+d;VK?#ZLq*G3^uNCQ;Ps|jO}?aakAx@ZX&du`(R1*#PWw~DGk z@%r>6?T7nSg0m<~PfcPqD0@e_VA*uDPBs8>tLJ~}+^FfCE^9_;WluUchB?XFFKc?x zoTz2aqRXXi+@v-KO6MjY>b%oH9dEO3sr>hb?kmD1^NKFRX636LB5hKY{tb?juWXm8 z@lo&Am~?6rh2_H&8{%(M#ZS7`qKIip?vUx3NQatzpQcdRF4R`ExxYk1RSyy*1qt?) z;(_K5G_Q64t(xECFXELmBl^ZGIFt!F_1?nN6*0;SCm;W`pM3KEIecoFfqJ_W{u%Wb D!a8~* delta 1607 zcmeHHOKVd>6wXX;Voc{Y&!%mf*tAVwn1Z#frjI}&v6iF~LJ>;cR6%heZcJ+*N^cRQ z;>O-1B2-XuEA){+5K$0xA)=eETnd7&l0^hl&q*>#aOcX610Q$hoNvy(bME(z_JnB< z+3pNy&CtQy8+RYgb)4Dz#C!%EHdy7WY#j1@-PDNd$FO2tGoQxU4+H!(&O1CfZAP>p zS`lqkLG}yjjB{pV7^w-T&tK64VdAGLmZH54Tj6Fpbh09B@~?h z!lwzJX2cPM1#uK%MHFds$P%E}@35@}MGvLfDOeOqVXRQ74Ao~NkPof1VOUh}>+Wfb z8}l+}4&dTIfmQcAL1(5$$Q<*)VpCGkm(Ul;u&D_b90~(Tn0AIiYm7qF8PRPqLA{|K zNhYLipDnbYL0VT_`uD2snV|PW1Z|;b#*N6hE)4`@QhvE4=izNcV!&lzn~*aZDclf~#3>ZVUUwI6an)wvf732h6))Y)!8Lg z(n;h-aEx6y&V8`rnIn+xn|v`GXZ9Q~4xLkO-|RVf^Zv`gcPpe4JFt-0_*Xwl7t$Rh zWs*Zxap(>-4XK=tQw@_{l0u42hE1de0~ChVYR-w5`bSEZEXcW&YRL*DKp8FhY1TsB zlcBPgGKGOSQyE<;WN(>7`y@-&vghhdGkA+UGB|6gw<@HaTFo>=2|?Ee`B~O7mF|yB XVI;u?8KB;CnRNJp@xO}yLdCxU;8Pk+ diff --git a/Details.js b/Details.js index ab0804398..5face1c38 100644 --- a/Details.js +++ b/Details.js @@ -9,11 +9,7 @@ getContainer: getContainer, setTimePeriod: setTimePeriod, setDatetime: setDatetime, - draw: draw, - - // Secondary functions and properties. - - onLayerStatusChanged: onLayerStatusChanged + draw: draw }; /* this is part of the module template */ @@ -22,8 +18,6 @@ container.initialize(); thisObject.container = container; - let layerStatus = 'off'; // Since the moduleis a layer, it must handle the different possible layer status. - let plotArea = newPlotArea(); // Needed to be able to plot on the timeline, otherwise not. let plotAreaFrame = newPlotArea(); // This chart uses this extra object. @@ -42,7 +36,7 @@ return thisObject; - function initialize(pExchange, pMarket, pDatetime, pTimePeriod, pLayerStatus, callBackFunction) { + function initialize(pExchange, pMarket, pDatetime, pTimePeriod, callBackFunction) { let cursorCacheInProgress = false; let finaleStepsInProgress = false; @@ -98,8 +92,6 @@ fileCursor = newFileCursor; - layerStatus = pLayerStatus; - recalculateScaleX(); recalculate(); recalculateScaleY(); @@ -119,8 +111,6 @@ function getContainer(point) { - if (layerStatus !== 'on') { return; } - let container; /* First we check if this point is inside this space. */ @@ -202,8 +192,6 @@ function draw() { - if (layerStatus !== 'on') { return; } - this.container.frame.draw(); if (timePeriod < _1_HOUR_IN_MILISECONDS) { @@ -223,8 +211,6 @@ function recalculate() { - if (layerStatus === 'off') { return; } - if (timePeriod >= _1_HOUR_IN_MILISECONDS) { recalculateUsingMarketFiles(); @@ -735,14 +721,6 @@ } } - function onLayerStatusChanged(eventData) { - - if (eventData.layer === 'Mariam Trades Details') { - layerStatus = eventData.status; - } - - } - function onZoomChanged(event) { recalculateScaleX(); diff --git a/History.js b/History.js index 318dc3d24..fd2ea69de 100644 --- a/History.js +++ b/History.js @@ -9,12 +9,7 @@ getContainer: getContainer, setTimePeriod: setTimePeriod, setDatetime: setDatetime, - draw: draw, - - // Secondary functions and properties. - - currentCandle: undefined, - onLayerStatusChanged: onLayerStatusChanged + draw: draw }; /* this is part of the module template */ @@ -23,8 +18,6 @@ container.initialize(); thisObject.container = container; - let layerStatus = 'off'; // Since the moduleis a layer, it must handle the different possible layer status. - let plotArea = newPlotArea(); // Needed to be able to plot on the timeline, otherwise not. let timePeriod; // This will hold the current Time Period the user is at. @@ -57,8 +50,6 @@ function getContainer(point) { - if (layerStatus !== 'on') { return; } - let container; /* First we check if this point is inside this space. */ @@ -92,8 +83,6 @@ function draw() { - if (layerStatus !== 'on') { return; } - plotChart(); } @@ -295,14 +284,6 @@ } } - function onLayerStatusChanged(eventData) { - - if (eventData.layer === 'Mariam Trades History') { - layerStatus = eventData.status; - } - - } - function onZoomChanged(event) { } From e65cda1f35fda7893c6aa6a7b066e0e877699b3d Mon Sep 17 00:00:00 2001 From: Luis Fernando Molina Date: Thu, 1 Mar 2018 19:23:31 +0100 Subject: [PATCH 09/54] Set Changed --- .vs/Plotters-Trading/v15/.suo | Bin 19968 -> 14336 bytes History.js | 2 +- 2 files changed, 1 insertion(+), 1 deletion(-) diff --git a/.vs/Plotters-Trading/v15/.suo b/.vs/Plotters-Trading/v15/.suo index 1616f7cdc0ef74eb823171a81cfba22ca4b99c19..b44f9c127c6f1320e86e96c1fa192a810db5f92e 100644 GIT binary patch delta 1033 zcma)4&u?97xlcxm-zTHr?T z3!~<5Z{O@*sBLqZF&4MOx{!o~ILXtnBW%e8>QR58z_NP`T4KOrL|_orh3Y|tkmPkA zz)Krn4dW@H9z=B$)+p-=ynHcG5z>DcEk`#s#*$5AOu~*KBl|Fh*ho~y_#qt>#dM!i z27F#(BUaMhvIY>RvRqUar6TE;Wk9U9yus^(E^a)F#v*DP%DT^WIl)cLgrj?=J4%OtHy2oX8YHh*zB}|h- zr50^hgK>+MEEIVlUXId&PpEW5!9>?XU)R@fE12U!m7Yix}vh!xm%MACR(LVp6! zHAEE5$JjK?iebY%-lTmqHmEb+10(QEJfg0wfUmnhqEDi+ZxcEj5d5DFz+hE6(}0l) tN9@(`>UhL{`d)Q+vbK5d{A2PHTd#D27<;t!U_~hMac!~|XSn~~{06k}VPOCO delta 879 zcmZWnJ#W)c6!mkQ);Q0uctj{{9YE^vhL$Pt1FFWC zu@k=l;-5f-x^-Zw7yvQx1I!Q!QSNnRj7~y%$c!ZC=;6_4%E>W$J?DZ4Gs}U&vI2*NAy-gPq${%g ziz}TQNGu{$goao^ln|619HqlH;F;=Tjj&m|n2g>`wFZOd%8w~`na*@nQr_%Jp$94* zXkEQ=+XJ_L55_w#?V;`Jtbl*eD>IR>6VcR~F;3P|L0K@a1aM~Gf!EcKaAs|RxOoh+ zbDvY?mAp`xK3_t@%9F9>b3uHab8}%e5Bhlybm03%JNU8l|Z(AnxdflkoSYt3Scfo8Qz=_d; I@6G?oKZ2b)g8%>k diff --git a/History.js b/History.js index fd2ea69de..2e25c5597 100644 --- a/History.js +++ b/History.js @@ -36,7 +36,7 @@ timePeriod = pTimePeriod; let File = newFile(); - File.initialize("AAMasters", "AAMariam", "Trading History", "Trading History", pExchange, pMarket, onFileReady) + File.initialize("AAMasters", "AAMariam", "Trading History", "Trading History File", pExchange, pMarket, onFileReady) function onFileReady() { From 37c8424ad036b2d1db7b767021d388554b724ae5 Mon Sep 17 00:00:00 2001 From: Luis Fernando Molina Date: Fri, 2 Mar 2018 12:48:39 +0100 Subject: [PATCH 10/54] Final Details --- .vs/Plotters-Trading/v15/.suo | Bin 14336 -> 14336 bytes History.js | 2 +- .../Project.njsproj.CoreCompileInputs.cache | 1 + .../Project.njsproj.FileListAbsolute.txt | 3 +++ ...ject.njsprojResolveAssemblyReference.cache | Bin 0 -> 2216 bytes 5 files changed, 5 insertions(+), 1 deletion(-) create mode 100644 obj/Debug/Project.njsproj.CoreCompileInputs.cache create mode 100644 obj/Debug/Project.njsproj.FileListAbsolute.txt create mode 100644 obj/Debug/Project.njsprojResolveAssemblyReference.cache diff --git a/.vs/Plotters-Trading/v15/.suo b/.vs/Plotters-Trading/v15/.suo index b44f9c127c6f1320e86e96c1fa192a810db5f92e..f96154e6a7dd9557b2ed7d0fc120bf1cab877655 100644 GIT binary patch delta 765 zcmb7C%`O8`6z;hlOvjy}lU9qiQ&JLyRw7oK5F!?$wYKsG5|voiPON0kLhQUkJCDGc zCOmjm%cHtP;)Ri&ww(NJ&0X_cl$%VzDIf z3E?xR#Ory3Pvg5ud4SL)&uge#i-r5!Wg zXI!fBW~SKlCl=B5YL delta 776 zcma)4yGjF55Y4?=^YUhQ6BCU_Oq76y0Zn|QF(McQQOxEC#1F7Yv4U9T6Ld$gvGNa+ zMNm+iq_9#!J3DI&ixn&+I&)(*0YwMSKF-XYIh?tba;3aC&mz_QB=iLPO|?5F(7| zL-Zn=*lGaZK14ra@RMs+ONY$jTdF>B(o%zoN*H$eE?a>YUKB|rNC*Xq`Bf!2-lRb@ zXcnPUqZj$VG|~i$wnh)0sg{mdEs$cYxnFv)L_?4ZG=vJJ97hy`vbDRDHG?-~Y0ol} zr%=*Xp`e|^rdEJPVgU}aVTjD7t(-1fm`OvBc{KRDZ?XtWxeF^+5K-jG#IKwgD?;6q zv7MN~1hKS+@9fa6B;#FV+z_-BGXAU5iMJ|ggKg59R_xbdAA`r)teu^?X0=pap2V6~ z&`w?U`c%zb3pBVG#lQbJ61|5jPZ~^JY6nL*gn~!u7PV)C8Innb)(5W%!x!nw{_GPv goy#AOaZ6p2*Vt4Id247@?asC{qB8Q`j?6u=4RdTpA)&tW2&Cd7K4^8EmeX{a^_^}K>O{gp42hO3tnZvAqmX;w!0b$% zLwqo5wu4Tv8?;(}r^(u^M8-b7-o{|2G(-cA|0w}SaS=4l}-Sv+P}L{la~Zj;ik@ZnU73+{t7>BoTo2t|xY zl^?M%0c9A4f>A1MnAh3r&vo6t#^?SO{ja{i_ay~et&;Orkwgi_HqB_ETt;!w-5);g zpM3S*tN7z& z1%zec5=J+x+udE(@j9Qk_S$!$d2g>ow%*8Fg005XY9uC811)(xwz(ScXc_`RaeKlP z)|&@P33({J3D;QT*i`+vmr&fa$>LFzq~&f)h}d)reou<1Kxr+0lEwNEf~-B(0L2ySaRO}Wl?GcxSQfv{Ynk^4-6>1GX3bE*3e!?BQDPoj_3KYK!UMXaR= zKXkE3L_8*Q$U3Kt%Ug3DDYmgjSoijga%qms{?wJh_Q7o9~R z!~q{Ck`bHE%LQ9_KAo*O`*x>3yIPl5Li^&T{$&2IA#ja>)qYFi$(J`Vdm9Tg6092K z{U;RVEfhy|&+IoEjqZLUBiY8XvXNvP3zBUtS*Ed~kVw|rMpebX@H%}vtf-MI7j(b4 zu3;8`M#g@P%19xuV441jvv&e(-9kznuTbYrFkC Date: Fri, 2 Mar 2018 21:48:10 +0100 Subject: [PATCH 11/54] Initialize improved --- .vs/Plotters-Trading/v15/.suo | Bin 14336 -> 14336 bytes History.js | 15 +++++---------- 2 files changed, 5 insertions(+), 10 deletions(-) diff --git a/.vs/Plotters-Trading/v15/.suo b/.vs/Plotters-Trading/v15/.suo index f96154e6a7dd9557b2ed7d0fc120bf1cab877655..10c5d0f49f2d48a8d4f69d19914587ed7930194d 100644 GIT binary patch delta 563 zcmZ8eyGjE=6rI_`%_N!4Zp6Hd(KQM}R7fg2MY4im$V1Xth=o`PB1^K`3Hg8&n)?G5 zR#vj}1riZE1@jlSY0^aR1oIp?Gk4BC_spG{hTX7V3JP6-Rb|C*|D09w?l%pK8?{I^ zq7p((#4iq@`Z{zy*%U`2h|mxLgn{UzAcU(f_Ps%cGU=w?KW`u8T~SkyDVIeiV(jEI z`7#ndL=y2(DZmwDe(5BSO^G}9?$rh-d2l}}bRr%2P`AJ_O3+qw&^1aLRsI!YRqTsL zW=P@0o74?h9`41A>}V{Hd_vne6_3#;I;fKu9A*b~Ez{!u8AEW)GMCNIPpF}bq%74Z zNoS|Zu=m$C&khy*CDrd~YZT}?C`I1mxzXLumks|j9BFLqA;g>*jwGh_8&bolfZOx0MsVjEu49cisIn;0L5eYg># zpyOUcwAGz>&6$iUP^F(1Jkt-_JyH9`wSB0&U3jsN!TF9ssVA~2jq++f3ymHZJ1G{t zY9u$5nE%a!}OyT5~}&#Y*rjKir=&@-Z8w2d3#k IE;^z91*-?WPXGV_ diff --git a/History.js b/History.js index 94f007a89..6e1d047dc 100644 --- a/History.js +++ b/History.js @@ -30,22 +30,17 @@ return thisObject; - function initialize(pExchange, pMarket, pDatetime, pTimePeriod, callBackFunction) { + function initialize(pStorage, pExchange, pMarket, pDatetime, pTimePeriod, callBackFunction) { datetime = pDatetime; timePeriod = pTimePeriod; - let File = newFile(); - File.initialize("AAMasters", "AAMariam", "Trading History", "Trading History File", pExchange, pMarket, onFileReady) + file = pStorage.file.getFile(); - function onFileReady() { + recalculate(); + recalculateScale(); + callBackFunction(); - file = File.getFile(); - recalculate(); - recalculateScale(); - callBackFunction(); - - } } function getContainer(point) { From 62a3e83915e4d7763f5e357bc231fd072510b723 Mon Sep 17 00:00:00 2001 From: Luis Fernando Molina Date: Sat, 3 Mar 2018 12:10:14 +0100 Subject: [PATCH 12/54] plotArea refactored Part 1 --- .vs/Plotters-Trading/v15/.suo | Bin 14336 -> 22016 bytes Details.js | 36 +++++++++++++++++----------------- History.js | 8 ++++---- 3 files changed, 22 insertions(+), 22 deletions(-) diff --git a/.vs/Plotters-Trading/v15/.suo b/.vs/Plotters-Trading/v15/.suo index 10c5d0f49f2d48a8d4f69d19914587ed7930194d..bd5502151b3d2a5c5bfe41d05ae6723126125842 100644 GIT binary patch delta 625 zcmZ{gy-vbV6vumS`KWkH)u=%raHEXI)JYc?Wzd8eP?uluQ$LEzMv0Ulmtz8SZfLbFj8^l)Lb^KHU$xt z{v@g{8x@YY8T}-slUcJDd>C|sq^fuU-rlwf)`dwf znhY$r1syES4*>=%7_?F|z^S++>FEZw(xbDeVCzII)4KSrqO+q;?NNSMJf6qio*+uB i{hj2L2JC@Lj+ieIQH&a$e=gCc$7T@4G-QcLMnpf+s@bRj delta 474 zcmZ9J&q~8U5XLi`Hd*S%RH13rVj}h=3VnfkiGqTtQSUy1(86B4mBLNA`*j_K zy2ma-SjYnu+EVrDwp3!a*93wkl!L0Ea9%cOS$9e<1Fp81UmiT}9fqoBT|B%paDaLO z)MAj`;x>W})O~c~G%@=qy2#SEd}4B%JNHX56|~g+18Xz&!FHAOuCknXXAZDm$D*}9 z6Lo3w1+fo8$G$?2ocak70ZRy-tm>` viewPort.visibleArea.bottomLeft.y && frameHeightInViewPort > visibleHeight * 2 / 3) { - if (calculateBuys(plotArea, visibleHeight) === false) { continue; } // We snap t to the view port. + if (calculateBuys(timeLineCoordinateSystem, visibleHeight) === false) { continue; } // We snap t to the view port. /* Now we set the real value of y. */ volumePointA1.y = viewPort.visibleArea.bottomRight.y; - volumePointA2.y = viewPort.visibleArea.bottomRight.y - volume.amountBuy * plotArea.scale.y; - volumePointA3.y = viewPort.visibleArea.bottomRight.y - volume.amountBuy * plotArea.scale.y; + volumePointA2.y = viewPort.visibleArea.bottomRight.y - volume.amountBuy * timeLineCoordinateSystem.scale.y; + volumePointA3.y = viewPort.visibleArea.bottomRight.y - volume.amountBuy * timeLineCoordinateSystem.scale.y; volumePointA4.y = viewPort.visibleArea.bottomRight.y; } @@ -553,17 +553,17 @@ } - calculateSells(plotAreaFrame, thisObject.container.frame.height); // We try to see if it fits in the visible area. + calculateSells(timeLineCoordinateSystemFrame, thisObject.container.frame.height); // We try to see if it fits in the visible area. if (volumePointB1.y < viewPort.visibleArea.topLeft.y && frameHeightInViewPort > visibleHeight * 2 / 3) { - calculateSells(plotArea, visibleHeight); // We snap it to the view port. + calculateSells(timeLineCoordinateSystem, visibleHeight); // We snap it to the view port. /* Now we set the real value of y. */ volumePointB1.y = viewPort.visibleArea.topLeft.y; - volumePointB2.y = viewPort.visibleArea.topLeft.y + volume.amountSell * plotArea.scale.y; - volumePointB3.y = viewPort.visibleArea.topLeft.y + volume.amountSell * plotArea.scale.y; + volumePointB2.y = viewPort.visibleArea.topLeft.y + volume.amountSell * timeLineCoordinateSystem.scale.y; + volumePointB3.y = viewPort.visibleArea.topLeft.y + volume.amountSell * timeLineCoordinateSystem.scale.y; volumePointB4.y = viewPort.visibleArea.topLeft.y; } diff --git a/History.js b/History.js index 6e1d047dc..a2a6efe7e 100644 --- a/History.js +++ b/History.js @@ -18,7 +18,7 @@ container.initialize(); thisObject.container = container; - let plotArea = newPlotArea(); // Needed to be able to plot on the timeline, otherwise not. + let timeLineCoordinateSystem = newTimeLineCoordinateSystem(); // Needed to be able to plot on the timeline, otherwise not. let timePeriod; // This will hold the current Time Period the user is at. let datetime; // This will hold the current Datetime the user is at. @@ -119,7 +119,7 @@ if (file === undefined) { return; } // We need the market file to be loaded to make the calculation. - if (plotArea.maxValue > 0) { return; } // Already calculated. + if (timeLineCoordinateSystem.maxValue > 0) { return; } // Already calculated. let minValue = { x: EARLIEST_DATE.valueOf(), @@ -132,7 +132,7 @@ }; - plotArea.initialize( + timeLineCoordinateSystem.initialize( minValue, maxValue, thisObject.container.frame.width, @@ -169,7 +169,7 @@ y: record.rate }; - point = plotArea.inverseTransform(point, thisObject.container.frame.height); + point = timeLineCoordinateSystem.inverseTransform(point, thisObject.container.frame.height); point = transformThisPoint(point, thisObject.container); From ab9c116859326701328f60560736e6b79ee98152 Mon Sep 17 00:00:00 2001 From: Luis Fernando Molina Date: Sat, 3 Mar 2018 12:54:10 +0100 Subject: [PATCH 13/54] Refactoring Coordinate System Completed --- .vs/Plotters-Trading/v15/.suo | Bin 22016 -> 22016 bytes Details.js | 16 ++++++++-------- History.js | 2 +- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/.vs/Plotters-Trading/v15/.suo b/.vs/Plotters-Trading/v15/.suo index bd5502151b3d2a5c5bfe41d05ae6723126125842..8145f729d09c816243d8f4f9fdee080ccceffd06 100644 GIT binary patch delta 383 zcmZoz!`QHfaYGIh>w#oWsGv3DO}8RZ|0iGM zSD9SG+q1}yX_J5l2M0(D1VG}OOC&BZ@_G4|IY9&xFoWDfc%QGHqs* Date: Sat, 3 Mar 2018 18:30:10 +0100 Subject: [PATCH 14/54] vainas --- .vs/Plotters-Trading/v15/.suo | Bin 22016 -> 22016 bytes Details.js | 17 ++--------------- 2 files changed, 2 insertions(+), 15 deletions(-) diff --git a/.vs/Plotters-Trading/v15/.suo b/.vs/Plotters-Trading/v15/.suo index 8145f729d09c816243d8f4f9fdee080ccceffd06..98af444ac5da635f59b8065cdf0091e5fef1d94a 100644 GIT binary patch delta 220 zcmZoz!`QHfaYGIhTS9`&1g_1SiI0b2(eslJTf}Z&V6lX8v5N!? z4@iasNyX+8nLftNObW*sIhc`zCx20t*(_jpMNn`VP!t9>0vW8EzZ$-m#VX9r1^}>9 BL!tlx delta 238 zcmZoz!`QHfaYGIh+k$zaT#q+xE@BE~oP3zwb`pziN|NH;{KQEBx z0%E?+jx5?tYyu~jt$PC0#deX8mjNjKAEXvUPrfLtGPy+b{A6c~hRKJ`4L5%g3t;5| z>E=LEvAM*ik9jkb+%ZND1tj6gU*u&r3n=~In*2eZYqGJv#$+qqy2%#|j3&R*?SYAH kUZH2hEXc Date: Sat, 10 Mar 2018 19:27:41 +0100 Subject: [PATCH 15/54] Update to Cloud.1.0 --- .vs/Plotters-Trading/v15/.suo | Bin 22016 -> 15360 bytes History.js | 46 +++++++++++----------------------- 2 files changed, 14 insertions(+), 32 deletions(-) diff --git a/.vs/Plotters-Trading/v15/.suo b/.vs/Plotters-Trading/v15/.suo index 98af444ac5da635f59b8065cdf0091e5fef1d94a..8079e31e521845176451af6bcdbe870e5ee28194 100644 GIT binary patch delta 778 zcmZWn&ubG=5Z>8r+n2bTZZvJOc9*0fQV+&%s#cI5ED_m5X=^DS1gn38Y^5Sd!CwXU z(jD|F#e+R4guIJ*@Dh(=QvC}=y?7GL!3tGp(p{3$2Osm^H}lQ+cHXYPg7vlfoC+F_ ztA(Vy`}WKIH=m)1tLjHX8CMi#fbfqN?l@(MU{ z;*O-EGfR0D=$w>y#A686Ida=kiz2*x`vI99m83^Hd3A{%qYY6mwq;Y(Dnqk=JM`G`F6_yK5?TS z>ja1N=&c@6NIHpI-AFjy+6~^0$_8nI>5b`<*v~J!Os*6Wv8I4jj~AM&&d>?nLLRXD)+GM zPT`MA5OZ?-^i#+zkt|-fXmd)=yU)OS6mt|`M|=M75_0eSWx$$UML)McNZ&D~HZ_w7 zPYCqReK0F8et-JDF}u>d_OYs;Lp01k{_3d=aegA9T3in>FTz@XVP22Dv7n%^? delta 918 zcmZpuXjsFz!H0=aWU?ZYJZD0J%ml8@ml*{&m$G#;GICC4WRaejz%q%8MV60&fq@%{ zd4N~|i2wcn|DOv;^8zvdWJfM>UU48x0*EDnSZeb^mUzaA2{x0Md?04CC1^KJ;@Uj9 zh$(RLVP?b0U)atAY1>I0BAjeM4bng?KiQDQcw&MKuMCjG4#XfkWH(o`v@>qv@?hc+ z1quO0{!eb?SD9SGb78WJ@SaIh&YPW;S{WywkhYj4=fVSW8pshab&~{GCRfOv;Q={c z2}yi%iG0r{E@viQ21cMLNEb}U<`SMB#!V8=jJym?P+^!9*f7bCNn#!xAR!O{xdkY^ zxkAQ=aqVp_Au3%T*7yLva^Kk zBn1~9P}m3~OOz=1Gx9QuL4{y$Vg+dq+5A(LpL6mBBcsVy`gM~(7;;T+FwmI%O1}pr zwt0oYR7S!1Ky@&%8pyEU>}NEMQF0kf3`lPTVpbpqMLqN8zoyR2lN;1HCVN<(5e$)A zTdw%*;w4tS<_mUupWiV6qfmIVh1DFvE#d`gCc>6Y3;q~x+!_=*6)dy)hZP6oCKJ42 d>jL&WC{4ipf)c(W9vmDxO viewPort.visibleArea.bottomRight.x) { - continue; - } + if (point.x < viewPort.visibleArea.bottomLeft.x || point.x > viewPort.visibleArea.bottomRight.x) { continue;} point = viewPort.fitIntoVisibleArea(point); let isCurrentRecord = false; if (datetime !== undefined) { - let dateValue = datetime.valueOf(); - if (dateValue >= record.date - timePeriod / 2 && dateValue <= record.date + timePeriod / 2 - 1) { - isCurrentRecord = true; - } } @@ -208,42 +207,32 @@ browserCanvasContext.strokeStyle = 'rgba(27, 105, 7, ' + opacity + ')'; if (isCurrentRecord === false) { - browserCanvasContext.fillStyle = 'rgba(64, 217, 26, ' + opacity + ')'; - } else { - browserCanvasContext.fillStyle = 'rgba(255, 233, 31, ' + opacity + ')'; /* highlight the current record */ - } browserCanvasContext.arc(point.x, point.y, radius3, 0, Math.PI * 2, true); - browserCanvasContext.closePath(); if (point.x < viewPort.visibleArea.topLeft.x + 50 || point.x > viewPort.visibleArea.bottomRight.x - 50) {/*we leave this history without fill. */ } else { browserCanvasContext.fill(); } + browserCanvasContext.stroke(); /* Middle Circle */ browserCanvasContext.beginPath(); - browserCanvasContext.strokeStyle = 'rgba(44, 61, 89, ' + opacity + ')'; if (isCurrentRecord === false) { - browserCanvasContext.fillStyle = 'rgba(50, 108, 201, ' + opacity + ')'; - } else { - browserCanvasContext.fillStyle = 'rgba(255, 233, 31, ' + opacity + ')'; /* highlight the current record */ - } browserCanvasContext.arc(point.x, point.y, radius2, 0, Math.PI * 2, true); - browserCanvasContext.closePath(); if (point.x < viewPort.visibleArea.topLeft.x + 50 || point.x > viewPort.visibleArea.bottomRight.x - 50) {/*we leave this history without fill. */ } else { @@ -254,28 +243,21 @@ /* Inner Circle */ browserCanvasContext.beginPath(); - browserCanvasContext.strokeStyle = 'rgba(27, 7, 105, ' + opacity + ')'; if (isCurrentRecord === false) { - browserCanvasContext.fillStyle = 'rgba(64, 26, 217, ' + opacity + ')'; - } else { - browserCanvasContext.fillStyle = 'rgba(255, 233, 31, ' + opacity + ')'; /* highlight the current record */ - } browserCanvasContext.arc(point.x, point.y, radius1, 0, Math.PI * 2, true); - browserCanvasContext.closePath(); if (point.x < viewPort.visibleArea.topLeft.x + 50 || point.x > viewPort.visibleArea.bottomRight.x - 50) {/*we leave this history without fill. */ } else { browserCanvasContext.fill(); } browserCanvasContext.stroke(); - } } From 20569b2225ce19fc112be4f6dca30bf579eb5ade Mon Sep 17 00:00:00 2001 From: Julian Molina Date: Thu, 29 Mar 2018 19:50:42 +0200 Subject: [PATCH 16/54] Create LICENSE --- LICENSE | 661 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 661 insertions(+) create mode 100644 LICENSE diff --git a/LICENSE b/LICENSE new file mode 100644 index 000000000..dbbe35581 --- /dev/null +++ b/LICENSE @@ -0,0 +1,661 @@ + GNU AFFERO GENERAL PUBLIC LICENSE + Version 3, 19 November 2007 + + Copyright (C) 2007 Free Software Foundation, Inc. + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The GNU Affero General Public License is a free, copyleft license for +software and other kinds of works, specifically designed to ensure +cooperation with the community in the case of network server software. + + The licenses for most software and other practical works are designed +to take away your freedom to share and change the works. By contrast, +our General Public Licenses are intended to guarantee your freedom to +share and change all versions of a program--to make sure it remains free +software for all its users. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +them if you wish), that you receive source code or can get it if you +want it, that you can change the software or use pieces of it in new +free programs, and that you know you can do these things. + + Developers that use our General Public Licenses protect your rights +with two steps: (1) assert copyright on the software, and (2) offer +you this License which gives you legal permission to copy, distribute +and/or modify the software. + + A secondary benefit of defending all users' freedom is that +improvements made in alternate versions of the program, if they +receive widespread use, become available for other developers to +incorporate. Many developers of free software are heartened and +encouraged by the resulting cooperation. However, in the case of +software used on network servers, this result may fail to come about. +The GNU General Public License permits making a modified version and +letting the public access it on a server without ever releasing its +source code to the public. + + The GNU Affero General Public License is designed specifically to +ensure that, in such cases, the modified source code becomes available +to the community. It requires the operator of a network server to +provide the source code of the modified version running there to the +users of that server. Therefore, public use of a modified version, on +a publicly accessible server, gives the public access to the source +code of the modified version. + + An older license, called the Affero General Public License and +published by Affero, was designed to accomplish similar goals. This is +a different license, not a version of the Affero GPL, but Affero has +released a new version of the Affero GPL which permits relicensing under +this license. + + The precise terms and conditions for copying, distribution and +modification follow. + + TERMS AND CONDITIONS + + 0. Definitions. + + "This License" refers to version 3 of the GNU Affero General Public License. + + "Copyright" also means copyright-like laws that apply to other kinds of +works, such as semiconductor masks. + + "The Program" refers to any copyrightable work licensed under this +License. Each licensee is addressed as "you". "Licensees" and +"recipients" may be individuals or organizations. + + To "modify" a work means to copy from or adapt all or part of the work +in a fashion requiring copyright permission, other than the making of an +exact copy. The resulting work is called a "modified version" of the +earlier work or a work "based on" the earlier work. + + A "covered work" means either the unmodified Program or a work based +on the Program. + + To "propagate" a work means to do anything with it that, without +permission, would make you directly or secondarily liable for +infringement under applicable copyright law, except executing it on a +computer or modifying a private copy. Propagation includes copying, +distribution (with or without modification), making available to the +public, and in some countries other activities as well. + + To "convey" a work means any kind of propagation that enables other +parties to make or receive copies. Mere interaction with a user through +a computer network, with no transfer of a copy, is not conveying. + + An interactive user interface displays "Appropriate Legal Notices" +to the extent that it includes a convenient and prominently visible +feature that (1) displays an appropriate copyright notice, and (2) +tells the user that there is no warranty for the work (except to the +extent that warranties are provided), that licensees may convey the +work under this License, and how to view a copy of this License. If +the interface presents a list of user commands or options, such as a +menu, a prominent item in the list meets this criterion. + + 1. Source Code. + + The "source code" for a work means the preferred form of the work +for making modifications to it. "Object code" means any non-source +form of a work. + + A "Standard Interface" means an interface that either is an official +standard defined by a recognized standards body, or, in the case of +interfaces specified for a particular programming language, one that +is widely used among developers working in that language. + + The "System Libraries" of an executable work include anything, other +than the work as a whole, that (a) is included in the normal form of +packaging a Major Component, but which is not part of that Major +Component, and (b) serves only to enable use of the work with that +Major Component, or to implement a Standard Interface for which an +implementation is available to the public in source code form. A +"Major Component", in this context, means a major essential component +(kernel, window system, and so on) of the specific operating system +(if any) on which the executable work runs, or a compiler used to +produce the work, or an object code interpreter used to run it. + + The "Corresponding Source" for a work in object code form means all +the source code needed to generate, install, and (for an executable +work) run the object code and to modify the work, including scripts to +control those activities. However, it does not include the work's +System Libraries, or general-purpose tools or generally available free +programs which are used unmodified in performing those activities but +which are not part of the work. For example, Corresponding Source +includes interface definition files associated with source files for +the work, and the source code for shared libraries and dynamically +linked subprograms that the work is specifically designed to require, +such as by intimate data communication or control flow between those +subprograms and other parts of the work. + + The Corresponding Source need not include anything that users +can regenerate automatically from other parts of the Corresponding +Source. + + The Corresponding Source for a work in source code form is that +same work. + + 2. Basic Permissions. + + All rights granted under this License are granted for the term of +copyright on the Program, and are irrevocable provided the stated +conditions are met. This License explicitly affirms your unlimited +permission to run the unmodified Program. The output from running a +covered work is covered by this License only if the output, given its +content, constitutes a covered work. This License acknowledges your +rights of fair use or other equivalent, as provided by copyright law. + + You may make, run and propagate covered works that you do not +convey, without conditions so long as your license otherwise remains +in force. You may convey covered works to others for the sole purpose +of having them make modifications exclusively for you, or provide you +with facilities for running those works, provided that you comply with +the terms of this License in conveying all material for which you do +not control copyright. Those thus making or running the covered works +for you must do so exclusively on your behalf, under your direction +and control, on terms that prohibit them from making any copies of +your copyrighted material outside their relationship with you. + + Conveying under any other circumstances is permitted solely under +the conditions stated below. Sublicensing is not allowed; section 10 +makes it unnecessary. + + 3. Protecting Users' Legal Rights From Anti-Circumvention Law. + + No covered work shall be deemed part of an effective technological +measure under any applicable law fulfilling obligations under article +11 of the WIPO copyright treaty adopted on 20 December 1996, or +similar laws prohibiting or restricting circumvention of such +measures. + + When you convey a covered work, you waive any legal power to forbid +circumvention of technological measures to the extent such circumvention +is effected by exercising rights under this License with respect to +the covered work, and you disclaim any intention to limit operation or +modification of the work as a means of enforcing, against the work's +users, your or third parties' legal rights to forbid circumvention of +technological measures. + + 4. Conveying Verbatim Copies. + + You may convey verbatim copies of the Program's source code as you +receive it, in any medium, provided that you conspicuously and +appropriately publish on each copy an appropriate copyright notice; +keep intact all notices stating that this License and any +non-permissive terms added in accord with section 7 apply to the code; +keep intact all notices of the absence of any warranty; and give all +recipients a copy of this License along with the Program. + + You may charge any price or no price for each copy that you convey, +and you may offer support or warranty protection for a fee. + + 5. Conveying Modified Source Versions. + + You may convey a work based on the Program, or the modifications to +produce it from the Program, in the form of source code under the +terms of section 4, provided that you also meet all of these conditions: + + a) The work must carry prominent notices stating that you modified + it, and giving a relevant date. + + b) The work must carry prominent notices stating that it is + released under this License and any conditions added under section + 7. This requirement modifies the requirement in section 4 to + "keep intact all notices". + + c) You must license the entire work, as a whole, under this + License to anyone who comes into possession of a copy. This + License will therefore apply, along with any applicable section 7 + additional terms, to the whole of the work, and all its parts, + regardless of how they are packaged. This License gives no + permission to license the work in any other way, but it does not + invalidate such permission if you have separately received it. + + d) If the work has interactive user interfaces, each must display + Appropriate Legal Notices; however, if the Program has interactive + interfaces that do not display Appropriate Legal Notices, your + work need not make them do so. + + A compilation of a covered work with other separate and independent +works, which are not by their nature extensions of the covered work, +and which are not combined with it such as to form a larger program, +in or on a volume of a storage or distribution medium, is called an +"aggregate" if the compilation and its resulting copyright are not +used to limit the access or legal rights of the compilation's users +beyond what the individual works permit. Inclusion of a covered work +in an aggregate does not cause this License to apply to the other +parts of the aggregate. + + 6. Conveying Non-Source Forms. + + You may convey a covered work in object code form under the terms +of sections 4 and 5, provided that you also convey the +machine-readable Corresponding Source under the terms of this License, +in one of these ways: + + a) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by the + Corresponding Source fixed on a durable physical medium + customarily used for software interchange. + + b) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by a + written offer, valid for at least three years and valid for as + long as you offer spare parts or customer support for that product + model, to give anyone who possesses the object code either (1) a + copy of the Corresponding Source for all the software in the + product that is covered by this License, on a durable physical + medium customarily used for software interchange, for a price no + more than your reasonable cost of physically performing this + conveying of source, or (2) access to copy the + Corresponding Source from a network server at no charge. + + c) Convey individual copies of the object code with a copy of the + written offer to provide the Corresponding Source. This + alternative is allowed only occasionally and noncommercially, and + only if you received the object code with such an offer, in accord + with subsection 6b. + + d) Convey the object code by offering access from a designated + place (gratis or for a charge), and offer equivalent access to the + Corresponding Source in the same way through the same place at no + further charge. You need not require recipients to copy the + Corresponding Source along with the object code. If the place to + copy the object code is a network server, the Corresponding Source + may be on a different server (operated by you or a third party) + that supports equivalent copying facilities, provided you maintain + clear directions next to the object code saying where to find the + Corresponding Source. Regardless of what server hosts the + Corresponding Source, you remain obligated to ensure that it is + available for as long as needed to satisfy these requirements. + + e) Convey the object code using peer-to-peer transmission, provided + you inform other peers where the object code and Corresponding + Source of the work are being offered to the general public at no + charge under subsection 6d. + + A separable portion of the object code, whose source code is excluded +from the Corresponding Source as a System Library, need not be +included in conveying the object code work. + + A "User Product" is either (1) a "consumer product", which means any +tangible personal property which is normally used for personal, family, +or household purposes, or (2) anything designed or sold for incorporation +into a dwelling. In determining whether a product is a consumer product, +doubtful cases shall be resolved in favor of coverage. For a particular +product received by a particular user, "normally used" refers to a +typical or common use of that class of product, regardless of the status +of the particular user or of the way in which the particular user +actually uses, or expects or is expected to use, the product. A product +is a consumer product regardless of whether the product has substantial +commercial, industrial or non-consumer uses, unless such uses represent +the only significant mode of use of the product. + + "Installation Information" for a User Product means any methods, +procedures, authorization keys, or other information required to install +and execute modified versions of a covered work in that User Product from +a modified version of its Corresponding Source. The information must +suffice to ensure that the continued functioning of the modified object +code is in no case prevented or interfered with solely because +modification has been made. + + If you convey an object code work under this section in, or with, or +specifically for use in, a User Product, and the conveying occurs as +part of a transaction in which the right of possession and use of the +User Product is transferred to the recipient in perpetuity or for a +fixed term (regardless of how the transaction is characterized), the +Corresponding Source conveyed under this section must be accompanied +by the Installation Information. But this requirement does not apply +if neither you nor any third party retains the ability to install +modified object code on the User Product (for example, the work has +been installed in ROM). + + The requirement to provide Installation Information does not include a +requirement to continue to provide support service, warranty, or updates +for a work that has been modified or installed by the recipient, or for +the User Product in which it has been modified or installed. Access to a +network may be denied when the modification itself materially and +adversely affects the operation of the network or violates the rules and +protocols for communication across the network. + + Corresponding Source conveyed, and Installation Information provided, +in accord with this section must be in a format that is publicly +documented (and with an implementation available to the public in +source code form), and must require no special password or key for +unpacking, reading or copying. + + 7. Additional Terms. + + "Additional permissions" are terms that supplement the terms of this +License by making exceptions from one or more of its conditions. +Additional permissions that are applicable to the entire Program shall +be treated as though they were included in this License, to the extent +that they are valid under applicable law. If additional permissions +apply only to part of the Program, that part may be used separately +under those permissions, but the entire Program remains governed by +this License without regard to the additional permissions. + + When you convey a copy of a covered work, you may at your option +remove any additional permissions from that copy, or from any part of +it. (Additional permissions may be written to require their own +removal in certain cases when you modify the work.) You may place +additional permissions on material, added by you to a covered work, +for which you have or can give appropriate copyright permission. + + Notwithstanding any other provision of this License, for material you +add to a covered work, you may (if authorized by the copyright holders of +that material) supplement the terms of this License with terms: + + a) Disclaiming warranty or limiting liability differently from the + terms of sections 15 and 16 of this License; or + + b) Requiring preservation of specified reasonable legal notices or + author attributions in that material or in the Appropriate Legal + Notices displayed by works containing it; or + + c) Prohibiting misrepresentation of the origin of that material, or + requiring that modified versions of such material be marked in + reasonable ways as different from the original version; or + + d) Limiting the use for publicity purposes of names of licensors or + authors of the material; or + + e) Declining to grant rights under trademark law for use of some + trade names, trademarks, or service marks; or + + f) Requiring indemnification of licensors and authors of that + material by anyone who conveys the material (or modified versions of + it) with contractual assumptions of liability to the recipient, for + any liability that these contractual assumptions directly impose on + those licensors and authors. + + All other non-permissive additional terms are considered "further +restrictions" within the meaning of section 10. If the Program as you +received it, or any part of it, contains a notice stating that it is +governed by this License along with a term that is a further +restriction, you may remove that term. If a license document contains +a further restriction but permits relicensing or conveying under this +License, you may add to a covered work material governed by the terms +of that license document, provided that the further restriction does +not survive such relicensing or conveying. + + If you add terms to a covered work in accord with this section, you +must place, in the relevant source files, a statement of the +additional terms that apply to those files, or a notice indicating +where to find the applicable terms. + + Additional terms, permissive or non-permissive, may be stated in the +form of a separately written license, or stated as exceptions; +the above requirements apply either way. + + 8. Termination. + + You may not propagate or modify a covered work except as expressly +provided under this License. Any attempt otherwise to propagate or +modify it is void, and will automatically terminate your rights under +this License (including any patent licenses granted under the third +paragraph of section 11). + + However, if you cease all violation of this License, then your +license from a particular copyright holder is reinstated (a) +provisionally, unless and until the copyright holder explicitly and +finally terminates your license, and (b) permanently, if the copyright +holder fails to notify you of the violation by some reasonable means +prior to 60 days after the cessation. + + Moreover, your license from a particular copyright holder is +reinstated permanently if the copyright holder notifies you of the +violation by some reasonable means, this is the first time you have +received notice of violation of this License (for any work) from that +copyright holder, and you cure the violation prior to 30 days after +your receipt of the notice. + + Termination of your rights under this section does not terminate the +licenses of parties who have received copies or rights from you under +this License. If your rights have been terminated and not permanently +reinstated, you do not qualify to receive new licenses for the same +material under section 10. + + 9. Acceptance Not Required for Having Copies. + + You are not required to accept this License in order to receive or +run a copy of the Program. Ancillary propagation of a covered work +occurring solely as a consequence of using peer-to-peer transmission +to receive a copy likewise does not require acceptance. However, +nothing other than this License grants you permission to propagate or +modify any covered work. These actions infringe copyright if you do +not accept this License. Therefore, by modifying or propagating a +covered work, you indicate your acceptance of this License to do so. + + 10. Automatic Licensing of Downstream Recipients. + + Each time you convey a covered work, the recipient automatically +receives a license from the original licensors, to run, modify and +propagate that work, subject to this License. You are not responsible +for enforcing compliance by third parties with this License. + + An "entity transaction" is a transaction transferring control of an +organization, or substantially all assets of one, or subdividing an +organization, or merging organizations. If propagation of a covered +work results from an entity transaction, each party to that +transaction who receives a copy of the work also receives whatever +licenses to the work the party's predecessor in interest had or could +give under the previous paragraph, plus a right to possession of the +Corresponding Source of the work from the predecessor in interest, if +the predecessor has it or can get it with reasonable efforts. + + You may not impose any further restrictions on the exercise of the +rights granted or affirmed under this License. For example, you may +not impose a license fee, royalty, or other charge for exercise of +rights granted under this License, and you may not initiate litigation +(including a cross-claim or counterclaim in a lawsuit) alleging that +any patent claim is infringed by making, using, selling, offering for +sale, or importing the Program or any portion of it. + + 11. Patents. + + A "contributor" is a copyright holder who authorizes use under this +License of the Program or a work on which the Program is based. The +work thus licensed is called the contributor's "contributor version". + + A contributor's "essential patent claims" are all patent claims +owned or controlled by the contributor, whether already acquired or +hereafter acquired, that would be infringed by some manner, permitted +by this License, of making, using, or selling its contributor version, +but do not include claims that would be infringed only as a +consequence of further modification of the contributor version. For +purposes of this definition, "control" includes the right to grant +patent sublicenses in a manner consistent with the requirements of +this License. + + Each contributor grants you a non-exclusive, worldwide, royalty-free +patent license under the contributor's essential patent claims, to +make, use, sell, offer for sale, import and otherwise run, modify and +propagate the contents of its contributor version. + + In the following three paragraphs, a "patent license" is any express +agreement or commitment, however denominated, not to enforce a patent +(such as an express permission to practice a patent or covenant not to +sue for patent infringement). To "grant" such a patent license to a +party means to make such an agreement or commitment not to enforce a +patent against the party. + + If you convey a covered work, knowingly relying on a patent license, +and the Corresponding Source of the work is not available for anyone +to copy, free of charge and under the terms of this License, through a +publicly available network server or other readily accessible means, +then you must either (1) cause the Corresponding Source to be so +available, or (2) arrange to deprive yourself of the benefit of the +patent license for this particular work, or (3) arrange, in a manner +consistent with the requirements of this License, to extend the patent +license to downstream recipients. "Knowingly relying" means you have +actual knowledge that, but for the patent license, your conveying the +covered work in a country, or your recipient's use of the covered work +in a country, would infringe one or more identifiable patents in that +country that you have reason to believe are valid. + + If, pursuant to or in connection with a single transaction or +arrangement, you convey, or propagate by procuring conveyance of, a +covered work, and grant a patent license to some of the parties +receiving the covered work authorizing them to use, propagate, modify +or convey a specific copy of the covered work, then the patent license +you grant is automatically extended to all recipients of the covered +work and works based on it. + + A patent license is "discriminatory" if it does not include within +the scope of its coverage, prohibits the exercise of, or is +conditioned on the non-exercise of one or more of the rights that are +specifically granted under this License. You may not convey a covered +work if you are a party to an arrangement with a third party that is +in the business of distributing software, under which you make payment +to the third party based on the extent of your activity of conveying +the work, and under which the third party grants, to any of the +parties who would receive the covered work from you, a discriminatory +patent license (a) in connection with copies of the covered work +conveyed by you (or copies made from those copies), or (b) primarily +for and in connection with specific products or compilations that +contain the covered work, unless you entered into that arrangement, +or that patent license was granted, prior to 28 March 2007. + + Nothing in this License shall be construed as excluding or limiting +any implied license or other defenses to infringement that may +otherwise be available to you under applicable patent law. + + 12. No Surrender of Others' Freedom. + + If conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot convey a +covered work so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you may +not convey it at all. For example, if you agree to terms that obligate you +to collect a royalty for further conveying from those to whom you convey +the Program, the only way you could satisfy both those terms and this +License would be to refrain entirely from conveying the Program. + + 13. Remote Network Interaction; Use with the GNU General Public License. + + Notwithstanding any other provision of this License, if you modify the +Program, your modified version must prominently offer all users +interacting with it remotely through a computer network (if your version +supports such interaction) an opportunity to receive the Corresponding +Source of your version by providing access to the Corresponding Source +from a network server at no charge, through some standard or customary +means of facilitating copying of software. This Corresponding Source +shall include the Corresponding Source for any work covered by version 3 +of the GNU General Public License that is incorporated pursuant to the +following paragraph. + + Notwithstanding any other provision of this License, you have +permission to link or combine any covered work with a work licensed +under version 3 of the GNU General Public License into a single +combined work, and to convey the resulting work. The terms of this +License will continue to apply to the part which is the covered work, +but the work with which it is combined will remain governed by version +3 of the GNU General Public License. + + 14. Revised Versions of this License. + + The Free Software Foundation may publish revised and/or new versions of +the GNU Affero General Public License from time to time. Such new versions +will be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + + Each version is given a distinguishing version number. If the +Program specifies that a certain numbered version of the GNU Affero General +Public License "or any later version" applies to it, you have the +option of following the terms and conditions either of that numbered +version or of any later version published by the Free Software +Foundation. If the Program does not specify a version number of the +GNU Affero General Public License, you may choose any version ever published +by the Free Software Foundation. + + If the Program specifies that a proxy can decide which future +versions of the GNU Affero General Public License can be used, that proxy's +public statement of acceptance of a version permanently authorizes you +to choose that version for the Program. + + Later license versions may give you additional or different +permissions. However, no additional obligations are imposed on any +author or copyright holder as a result of your choosing to follow a +later version. + + 15. Disclaimer of Warranty. + + THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY +APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT +HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY +OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, +THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM +IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF +ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. Limitation of Liability. + + IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS +THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY +GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE +USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF +DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD +PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), +EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF +SUCH DAMAGES. + + 17. Interpretation of Sections 15 and 16. + + If the disclaimer of warranty and limitation of liability provided +above cannot be given local legal effect according to their terms, +reviewing courts shall apply local law that most closely approximates +an absolute waiver of all civil liability in connection with the +Program, unless a warranty or assumption of liability accompanies a +copy of the Program in return for a fee. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +state the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU Affero General Public License as published + by the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Affero General Public License for more details. + + You should have received a copy of the GNU Affero General Public License + along with this program. If not, see . + +Also add information on how to contact you by electronic and paper mail. + + If your software can interact with users remotely through a computer +network, you should also make sure that it provides a way for users to +get its source. For example, if your program is a web application, its +interface could display a "Source" link that leads users to an archive +of the code. There are many ways you could offer source, and different +solutions will be better for different programs; see section 13 for the +specific requirements. + + You should also get your employer (if you work as a programmer) or school, +if any, to sign a "copyright disclaimer" for the program, if necessary. +For more information on this, and how to apply and follow the GNU AGPL, see +. From 29d33c8c582d8e124d23aca800c30d61cc0eb395 Mon Sep 17 00:00:00 2001 From: Luis Fernando Molina Date: Thu, 19 Apr 2018 11:05:49 +0200 Subject: [PATCH 17/54] Profile Picture --- .vs/Plotters-Trading/v15/.suo | Bin 15360 -> 26112 bytes History.png | Bin 0 -> 8630 bytes Project.njsproj | 3 +++ this.plotter.config.json | 20 ++++++++++++++++++++ 4 files changed, 23 insertions(+) create mode 100644 History.png create mode 100644 this.plotter.config.json diff --git a/.vs/Plotters-Trading/v15/.suo b/.vs/Plotters-Trading/v15/.suo index 8079e31e521845176451af6bcdbe870e5ee28194..c22a93075ddbc25135582d54f4ab3803a02c8dd1 100644 GIT binary patch literal 26112 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 C!=d~D delta 1784 zcmdT^-%ndr96#rBFI+D7LZM}pwLqDu#KLkrHa51BA=Eh6(t?{26iuhwgNxB*YZnBx zHIk^wG_)UH7x$zli*eXJ7~=zGJer{KAJCV*X*90M`rzvKd%ahSM&CWj=bm%E=X`&C z?)Q9)U(4e1h8R zC@V6Bs*<+EAW1X=>DD2mL(Ltuxg)XC^aN%CF)L2n1Fkn6Qtc^a)gXH^>44`xSGkww z(!4!vxO+CpV}SOpgnj}$J3x4VfU8EZa!XIiQr1^iQWWU7O2jI!URkF&yXZngoQ1!l zI&C)7S%kpGIbzKT5w(_(^x-SD=TXZ&Y^RyC=_IrfSkX@i5V{Hb2t9-#VLyQlhG-5~ zw)6~zm9RKJ4@9Kl*Ekb{SI8RbFp=+A=WzdS+0$cQaNZbF-K2-qQI^~?MlfXf@Us!= z^R7Nl2d4owSnR4$6?slKm znTbCIxqaW5yy3Jxp~@~%noc1RjsHK=KBM!$^Ad14$e8?_BaPyJC1uX!0_MW@On`~u zn&2AngnNi7cO^_NoJQu5>&oD^5|izy(rQPsrG>mdWAeLbX|N>CO4Z+{l*2QY^B%Yg zJul7tDAqNsgws0Lk|)RA@SMqKT*jVI29fVOqkC2EJOQRcL9H|C#K$anw<*4&6I&X$ zM~`6HpE9{WG)AT|6Dn#w89ls5Gf0_5j^JJ}X-T%nk$85cj(l%HV>>!((WJ@wc)h@> z&1U3B3Q|LLq^_~cv#5oVNIYWyN47;bIetu@C(TW6U=_ufisi^!nWlS@HP{Mm2b0{V z+8*OT2sBWz-@}G|jIIav;QDlybj&6xBtY-@xsz35vx~DJ$+Ti zAHMl<`>wt7Yr41m+egno_W>)h>&C${9`EnIb6#1N53ODMB^HPOU^u+IwcQOY6 diff --git a/History.png b/History.png new file mode 100644 index 0000000000000000000000000000000000000000..cffcd436b279fa3ae5c8b4567614cf91783a517c GIT binary patch literal 8630 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 + + + diff --git a/this.plotter.config.json b/this.plotter.config.json new file mode 100644 index 000000000..565709a0e --- /dev/null +++ b/this.plotter.config.json @@ -0,0 +1,20 @@ +{ + "displayName": "Plotters Trading", + "codeName": "PlottersTrading", + "devTeam": "AAMasters", + "modules": [ + { + "codeName": "Details", + "moduleName": "Details", + "description": "Plots trading decitions in an easy to understand way.", + "panels": [] + }, + { + "codeName": "History", + "moduleName": "History", + "description": "Plots trading positions history.", + "profilePicture": "History.png", + "panels": [] + } + ] +} \ No newline at end of file From 1a9747c7b7179ae27e2743a1d1399ab19e6f1ce0 Mon Sep 17 00:00:00 2001 From: Luis Fernando Molina Date: Thu, 19 Apr 2018 11:16:35 +0200 Subject: [PATCH 18/54] Picture modified --- History.png | Bin 8630 -> 6492 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/History.png b/History.png index cffcd436b279fa3ae5c8b4567614cf91783a517c..248e8ba6026027d2841cf2515a1e6ccf3f44a27d 100644 GIT binary patch literal 6492 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 literal 8630 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 Date: Sun, 22 Apr 2018 10:37:12 +0200 Subject: [PATCH 19/54] Profile Picture being shown --- .vs/Plotters-Trading/v15/.suo | Bin 26112 -> 26624 bytes History.js | 28 ++++++++++++++++++++++++++-- 2 files changed, 26 insertions(+), 2 deletions(-) diff --git a/.vs/Plotters-Trading/v15/.suo b/.vs/Plotters-Trading/v15/.suo index c22a93075ddbc25135582d54f4ab3803a02c8dd1..756b29c887ca32abee0c3f07134156d2b842a9f5 100644 GIT binary patch delta 1575 zcmb_bO-~bH5bnFXrAyr{3oW!lg_agtTbe8yh47J7S`$=gOJX2JNJ@eqKcF5kfZ)M+ z;6Qf{UOXW2tk8`YgYh6oO={%i!FV zgbUGH;o9(YBhDa#h}=XFHbkL5j6VIQN8c8cESC}T)^#S|MD`ZqHsT281ZOTYrb#iG zF(iy<%G;0%64k^bC{LM`Q&RQRiPVeolUfo}b5)7gHXWSS6hnaw!%EXz5(;GPDT(%I zsS4GLc8SwMafy~j!upvbl!REQ7gSDQU*WJhz%Ia3i%+7hQxF*yY@SDA4{{^dARZpl zT1G_@jd2UvmOar>T)AmyQf2~%&}xh@Gu8AM4jZrjR`HtV8Wm|lMkHiiSeK($FZxpq z;&#1Ak3TVXvBtlMGn0d=6pF-fH{VNxn3>TBp>SqMr6yJg6 z^b#Z{T<~Skqwin$Ff;vQJg|^{V3Y$l#=9VsP+@Caf%XX>6ZA_{Zy4Cp(=tibFdNt= zAL1i+&0o?|P1DzlfdVVFP+n7cQF?J$;_@TW`aevJ{nE!t4Rec&x^1YFLFe%2&1nuc zCc97WpEW?PZw6*&p0Ve!I&~jj_o@EAvw{7W+pGPNSJCe;+<`~bvQeLLqIP<;Sw&Z- f4@%Pgrx~8pBSU`_H@Pw*n>&P;s}Vj7&}n{)5)oO|v$_s%Tm+43e^ z8{(J?8n}Qn|KaP!sn1(1U^1CvKDf)Bg>`$FO~Q9h5gJf*Bak1LA!$vid|iVB=jDii z_z*wx1D~>@wZZ#w&&pLV+gTa$G#^A&LMT%satLWcT96QO80j!p2#z35nvpQF^J=7r zsoYSp%=An7$(c`EtO{Kv$}|rPRF8y_dff%9#43tg3{W@ZwHK`yZ6)GFT*wakJZP&C z5vf5az7}mAA|q`^G7(k<-hBjxR-_(jN3iZema(N7^*^WD`^!uWW!l3yMSEVLBcuWh z!JW!DONN_&hdYL0qd5cxk5a~XROv2^MBW_qOJPXXr?e_gtx527r-rNMBTt(_ChC|Kw#;9%Q*&e-W!W7%Xyiovqqm31|}W;{jdDF<*Mz_w4>-OZnpjc)9EHyBHg zdTM=78^dg0Wo8R~`Mp(C55k5Rf~2UQAcQ!ceS;MlRbMZx%5kzLHw8KqcfY{z@6xQh;@mO?v%LO3y?e3nhlJa8HC32TAVUx5;1G(6&$Nv?6|qG zv~(|gJRXj8b%xtd)6u~5?q1calyMWS-dbmF*!4P{c>VvAvrfs z3EC#6jz%V6t@Du{nC_Ng?#de6h&b8bwaUEN6yGIeznm;*|F=$L5aa}yjXo&usWEf5 sujefTWwaKh^X?aV`Nr!Rnh4yAKGv?8Gt&-cp?YTAOA+0ZmnR2LJ#7 diff --git a/History.js b/History.js index b540a3ed8..227de904e 100644 --- a/History.js +++ b/History.js @@ -9,7 +9,14 @@ getContainer: getContainer, setTimePeriod: setTimePeriod, setDatetime: setDatetime, - draw: draw + draw: draw, + profile: { + position: { + x: 0, + y: 0, + }, + visible: false + } }; /* this is part of the module template */ @@ -119,6 +126,7 @@ } thisObject.container.eventHandler.raiseEvent("History Changed", history); + } function recalculateScale() { @@ -166,11 +174,13 @@ function plotChart() { + let point; + for (let i = 0; i < history.length; i++) { record = history[i]; - let point = { + point = { x: record.date, y: record.sellAvgRate }; @@ -258,7 +268,21 @@ browserCanvasContext.fill(); } browserCanvasContext.stroke(); + + /* Since there is at least some point plotted, then the profile should be visible. */ + + thisObject.profile.visible = true; } + + /* + + We replace the coordinate of the profile point so that whoever has a reference to it, gets the new position. + We will use the last point plotted on screen as the profilePoint. + + */ + + thisObject.profile.position.x = point.x; + thisObject.profile.position.y = point.y; } function onZoomChanged(event) { From fa363bd92251b21649c2d412caee38377e4c9b16 Mon Sep 17 00:00:00 2001 From: Luis Fernando Molina Date: Thu, 26 Apr 2018 12:50:39 +0200 Subject: [PATCH 20/54] Plotting Sequence Files implemented --- .vs/Plotters-Trading/v15/.suo | Bin 26624 -> 27136 bytes History.js | 243 ++++++++++++++++++---------------- this.plotter.config.json | 2 +- 3 files changed, 131 insertions(+), 114 deletions(-) diff --git a/.vs/Plotters-Trading/v15/.suo b/.vs/Plotters-Trading/v15/.suo index 756b29c887ca32abee0c3f07134156d2b842a9f5..a8a02b08f4cda5dfd3d58ab296e372119088c5bf 100644 GIT binary patch delta 1536 zcmd5+Ur1A76!*Kk`=@tvo2F}Sdi~q{f0qQ-CR9@jn@vTbk&r|WRhC@JAlWQbfopC_vUp2RAaCqFY*2K8K>&9Of1jl6x$_MtBhSGhrWDg@X?_|C1u zQ!W4*ga245`pOZQB438wqRW)ihH|B@li#k(F632+YJ^C8CMF#NO}di;iJDPwK^#E% z5p4*vcj&wmxunZv51^b|9tpA}7s2}P9}y9p+Q&2a`2Y2W_DC1#z z*h*;!T9@k+MYj0;VvE)HA)Ns&&ghLzqtWA;?UM1qlC zU?W`an*m#2Da;>v=rE#%{(x(X-@KuF=_N?`C5Q*(H2A$Em3VNBwapxVuYTAl|FZS* z=4R^o^if>8{cx6WgH_ZQaYEw^a-j+PCi!)0XE4>bkPNN=Ym&KQ2ITEbnL4+?rzTCq zKKy?M(KL^o9@qwQ8eSDX-bZ+*ulP`Y;BDjZo?7tP(&ZzyYT4P$teiVE;=&KLJiX B1JwWk delta 1209 zcmb`F&ubG=5XW~mn`ZN4(`^%zR=4SA**RDbLJd6#UTpT_!GqGA)M`Xe{Tn=3h+rkg`d&>#o`5ML{m3T*=5i&S7O`4PZ@QL$Z7FK%?YHs3=teLIYo#pAf{7=i`- zEWU9AJL?1%Q!y+#Vy*3DkdVEUZRZH9Iy?9VA9}+OWcxsrY!A^&=tL*6o9H6Ci5{Yl zs4MQNpK;9-whGcPm|`3n@SUjpjJfD9!}O7#PE^Bm>2r;BAyRhJ*FEyT{+-7eZSqK$}gdf8-)(o04^!A=9#3uzRx$za|y01`iihBu9m zyr;5B$@Go60q9SD!j3cTE6N;;*CK9l`N{ zf$7jRmjX+nqRf-S^JZ)EqoP&rb&2`z0$@QgoJZ+Ow#xl3$<)Sw7q<+#k%nAcG$Z4G zlz`7pfYf>Ak5wE_o-G~ECvKpU@Zi#kCn_h*>*|9oZDghJ7_YY(R_5e1sL!rMy^Htv zm#&@d+t|FlwTRDCnwgmKbI%r(OGMDeihWaZ*QFwFF|)bUQ3<*WOwcVre!UhUY2t6;!p2kcJKnO3?{b&!Z#^B BdguTE diff --git a/History.js b/History.js index 227de904e..50378b898 100644 --- a/History.js +++ b/History.js @@ -32,8 +32,8 @@ /* these are module specific variables: */ - let file; // Here we keep the history records to be ploted every time the Draw() function is called by the AAWebPlatform. - let history = []; // This is where the history records are stored before plotting. + let files = []; // Here we keep the history records to be ploted every time the Draw() function is called by the AAWebPlatform. + let plotElements = []; // This is where the elements to be plotted are stored before plotting. return thisObject; @@ -42,7 +42,13 @@ datetime = pDatetime; timePeriod = pTimePeriod; - file = pStorage.file.getFile(); + let maxSequence = pStorage.fileSequence.getExpectedFiles(); + + for (let i = 0; i < maxSequence; i++) { + + file.push(pStorage.fileSequence.getFile(i)); + + } recalculate(); recalculateScale(); @@ -91,7 +97,7 @@ function recalculate() { - if (file === undefined) { return; } + if (files === undefined | files = []) { return; } /* @@ -100,29 +106,36 @@ */ - history = []; + for (let j = 0; j < files.length; j++) { - let oneMin = 60000; - let step = timePeriod / oneMin; + let file = files[j]; - for (let i = 0; i < file.length; i = i + step) { + let history = []; - let newHistoryRecord = { + let oneMin = 60000; + let step = timePeriod / oneMin; - date: Math.trunc(file[i][0] / 60000) * 60000 + 30000, - buyAvgRate: file[i][1], - sellAvgRate: file[i][2], - marketRate: file[i][3], - newPositions: file[i][4], - newTrades: file[i][5], - movedPositions: file[i][6], - profitsAssetA: file[i][7], - profitsAssetB: file[i][8], - combinedProfitsA: file[i][9], - combinedProfitsB: file[i][10] - }; + for (let i = 0; i < file.length; i = i + step) { - history.push(newHistoryRecord); + let newHistoryRecord = { + + date: Math.trunc(file[i][0] / 60000) * 60000 + 30000, + buyAvgRate: file[i][1], + sellAvgRate: file[i][2], + marketRate: file[i][3], + newPositions: file[i][4], + newTrades: file[i][5], + movedPositions: file[i][6], + profitsAssetA: file[i][7], + profitsAssetB: file[i][8], + combinedProfitsA: file[i][9], + combinedProfitsB: file[i][10] + }; + + history.push(newHistoryRecord); + } + + plotElements.push(history); } thisObject.container.eventHandler.raiseEvent("History Changed", history); @@ -157,121 +170,132 @@ let maxValue = 0; - for (let i = 0; i < file.length; i++) { + for (let j = 0; j < files.length; j++) { - let currentMax = file[i][1] + file[i][2]; // 1 = rates. + let file = files[j]; - if (maxValue < currentMax) { - maxValue = currentMax; + for (let i = 0; i < file.length; i++) { + + let currentMax = file[i][1] + file[i][2]; // 1 = rates. + + if (maxValue < currentMax) { + maxValue = currentMax; + } } } return maxValue; } - } function plotChart() { let point; + let history; - for (let i = 0; i < history.length; i++) { + for (let j = 0; j < plotElements.length; j++) { - record = history[i]; + let history = plotElements[j]; - point = { - x: record.date, - y: record.sellAvgRate - }; + for (let i = 0; i < history.length; i++) { - point = timeLineCoordinateSystem.transformThisPoint(point); - point = transformThisPoint(point, thisObject.container); + record = history[i]; - if (point.x < viewPort.visibleArea.bottomLeft.x || point.x > viewPort.visibleArea.bottomRight.x) { continue;} + point = { + x: record.date, + y: record.sellAvgRate + }; - point = viewPort.fitIntoVisibleArea(point); + point = timeLineCoordinateSystem.transformThisPoint(point); + point = transformThisPoint(point, thisObject.container); - let isCurrentRecord = false; + if (point.x < viewPort.visibleArea.bottomLeft.x || point.x > viewPort.visibleArea.bottomRight.x) { continue;} - if (datetime !== undefined) { - let dateValue = datetime.valueOf(); - if (dateValue >= record.date - timePeriod / 2 && dateValue <= record.date + timePeriod / 2 - 1) { - isCurrentRecord = true; + point = viewPort.fitIntoVisibleArea(point); + + let isCurrentRecord = false; + + if (datetime !== undefined) { + let dateValue = datetime.valueOf(); + if (dateValue >= record.date - timePeriod / 2 && dateValue <= record.date + timePeriod / 2 - 1) { + isCurrentRecord = true; + } } - } - let radiusFactor = 3; - let opacity = '0.2'; + let radiusFactor = 3; + let opacity = '0.2'; - let radius1 = record.newPositions * radiusFactor; - let radius2 = radius1 + record.movedPositions * radiusFactor; - let radius3 = radius2 + record.newTrades * radiusFactor; + let radius1 = record.newPositions * radiusFactor; + let radius2 = radius1 + record.movedPositions * radiusFactor; + let radius3 = radius2 + record.newTrades * radiusFactor; - browserCanvasContext.lineWidth = 1; + browserCanvasContext.lineWidth = 1; - /* Outer Circle */ + /* Outer Circle */ - browserCanvasContext.beginPath(); + browserCanvasContext.beginPath(); - browserCanvasContext.strokeStyle = 'rgba(27, 105, 7, ' + opacity + ')'; + browserCanvasContext.strokeStyle = 'rgba(27, 105, 7, ' + opacity + ')'; - if (isCurrentRecord === false) { - browserCanvasContext.fillStyle = 'rgba(64, 217, 26, ' + opacity + ')'; - } else { - browserCanvasContext.fillStyle = 'rgba(255, 233, 31, ' + opacity + ')'; /* highlight the current record */ + if (isCurrentRecord === false) { + browserCanvasContext.fillStyle = 'rgba(64, 217, 26, ' + opacity + ')'; + } else { + browserCanvasContext.fillStyle = 'rgba(255, 233, 31, ' + opacity + ')'; /* highlight the current record */ + } + + browserCanvasContext.arc(point.x, point.y, radius3, 0, Math.PI * 2, true); + browserCanvasContext.closePath(); + + if (point.x < viewPort.visibleArea.topLeft.x + 50 || point.x > viewPort.visibleArea.bottomRight.x - 50) {/*we leave this history without fill. */ } else { + browserCanvasContext.fill(); + } + + browserCanvasContext.stroke(); + + /* Middle Circle */ + + browserCanvasContext.beginPath(); + browserCanvasContext.strokeStyle = 'rgba(44, 61, 89, ' + opacity + ')'; + + if (isCurrentRecord === false) { + browserCanvasContext.fillStyle = 'rgba(50, 108, 201, ' + opacity + ')'; + } else { + browserCanvasContext.fillStyle = 'rgba(255, 233, 31, ' + opacity + ')'; /* highlight the current record */ + } + + browserCanvasContext.arc(point.x, point.y, radius2, 0, Math.PI * 2, true); + browserCanvasContext.closePath(); + + if (point.x < viewPort.visibleArea.topLeft.x + 50 || point.x > viewPort.visibleArea.bottomRight.x - 50) {/*we leave this history without fill. */ } else { + browserCanvasContext.fill(); + } + browserCanvasContext.stroke(); + + /* Inner Circle */ + + browserCanvasContext.beginPath(); + browserCanvasContext.strokeStyle = 'rgba(27, 7, 105, ' + opacity + ')'; + + if (isCurrentRecord === false) { + browserCanvasContext.fillStyle = 'rgba(64, 26, 217, ' + opacity + ')'; + } else { + browserCanvasContext.fillStyle = 'rgba(255, 233, 31, ' + opacity + ')'; /* highlight the current record */ + } + + browserCanvasContext.arc(point.x, point.y, radius1, 0, Math.PI * 2, true); + browserCanvasContext.closePath(); + + if (point.x < viewPort.visibleArea.topLeft.x + 50 || point.x > viewPort.visibleArea.bottomRight.x - 50) {/*we leave this history without fill. */ } else { + browserCanvasContext.fill(); + } + browserCanvasContext.stroke(); + + /* Since there is at least some point plotted, then the profile should be visible. */ + + thisObject.profile.visible = true; } - browserCanvasContext.arc(point.x, point.y, radius3, 0, Math.PI * 2, true); - browserCanvasContext.closePath(); - - if (point.x < viewPort.visibleArea.topLeft.x + 50 || point.x > viewPort.visibleArea.bottomRight.x - 50) {/*we leave this history without fill. */ } else { - browserCanvasContext.fill(); - } - - browserCanvasContext.stroke(); - - /* Middle Circle */ - - browserCanvasContext.beginPath(); - browserCanvasContext.strokeStyle = 'rgba(44, 61, 89, ' + opacity + ')'; - - if (isCurrentRecord === false) { - browserCanvasContext.fillStyle = 'rgba(50, 108, 201, ' + opacity + ')'; - } else { - browserCanvasContext.fillStyle = 'rgba(255, 233, 31, ' + opacity + ')'; /* highlight the current record */ - } - - browserCanvasContext.arc(point.x, point.y, radius2, 0, Math.PI * 2, true); - browserCanvasContext.closePath(); - - if (point.x < viewPort.visibleArea.topLeft.x + 50 || point.x > viewPort.visibleArea.bottomRight.x - 50) {/*we leave this history without fill. */ } else { - browserCanvasContext.fill(); - } - browserCanvasContext.stroke(); - - /* Inner Circle */ - - browserCanvasContext.beginPath(); - browserCanvasContext.strokeStyle = 'rgba(27, 7, 105, ' + opacity + ')'; - - if (isCurrentRecord === false) { - browserCanvasContext.fillStyle = 'rgba(64, 26, 217, ' + opacity + ')'; - } else { - browserCanvasContext.fillStyle = 'rgba(255, 233, 31, ' + opacity + ')'; /* highlight the current record */ - } - - browserCanvasContext.arc(point.x, point.y, radius1, 0, Math.PI * 2, true); - browserCanvasContext.closePath(); - - if (point.x < viewPort.visibleArea.topLeft.x + 50 || point.x > viewPort.visibleArea.bottomRight.x - 50) {/*we leave this history without fill. */ } else { - browserCanvasContext.fill(); - } - browserCanvasContext.stroke(); - - /* Since there is at least some point plotted, then the profile should be visible. */ - - thisObject.profile.visible = true; } /* @@ -285,12 +309,5 @@ thisObject.profile.position.y = point.y; } - function onZoomChanged(event) { - - } - - function onDragFinished() { - - } } diff --git a/this.plotter.config.json b/this.plotter.config.json index 565709a0e..73cd0f511 100644 --- a/this.plotter.config.json +++ b/this.plotter.config.json @@ -12,7 +12,7 @@ { "codeName": "History", "moduleName": "History", - "description": "Plots trading positions history.", + "description": "Plots trading history.", "profilePicture": "History.png", "panels": [] } From d86d4c32d93b391519c7a9d92f53c40aa2150e80 Mon Sep 17 00:00:00 2001 From: Luis Fernando Molina Date: Thu, 26 Apr 2018 13:37:19 +0200 Subject: [PATCH 21/54] Working with Sequence Files --- .vs/Plotters-Trading/v15/.suo | Bin 27136 -> 27136 bytes History.js | 8 +++++--- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/.vs/Plotters-Trading/v15/.suo b/.vs/Plotters-Trading/v15/.suo index a8a02b08f4cda5dfd3d58ab296e372119088c5bf..81d63ea8096aee45beb90e27903b18b528938726 100644 GIT binary patch delta 77 zcmZp;!q{+yaYGIh>jJ)GpM5tMGW}*|y)fyyncwC@wwD2ddJG7V3}ni0&JKUiC^#D- P%CHW|me`yfIaL4v&<_-k delta 77 zcmZp;!q{+yaYGIhtH6~C8K2FCOuv~~6|7GO0hw$s0|aj|Ab>U_ki9uO{5_*!8$y%; JDjYdg003qe5 0) { return; } // Already calculated. From 9a01c58dea924e337bae374579c03220fcef8f5f Mon Sep 17 00:00:00 2001 From: Luis Fernando Molina Date: Sun, 29 Apr 2018 08:05:05 +0200 Subject: [PATCH 22/54] Plotting Triangles --- .vs/Plotters-Trading/v15/.suo | Bin 27136 -> 26112 bytes History.js | 277 +++++++++++++++++++++++++++++----- 2 files changed, 238 insertions(+), 39 deletions(-) diff --git a/.vs/Plotters-Trading/v15/.suo b/.vs/Plotters-Trading/v15/.suo index 81d63ea8096aee45beb90e27903b18b528938726..ef729813fbb889af55e3dfe4f4f21100ff784d26 100644 GIT binary patch delta 317 zcmZp;!q{+zae~2Q0ewyp0R{#(1_lO3ApZCN|9>FGz&QC}vhc1BEUGNbh7QYJsf$%n-aCx2mAu#^C51L}qYVI)2$5*wrdWDU?( zuzD$wRh&FPo*)oQZqDSm&%y%YPQH+=vAKlz3L6VIoF~%5I!VHL@?oXe%?p$gm>0>h zY?5(d;sBYc1Xm>2!?;O}iDxsD*g-~4upJ=pfsEq@DPjU*AlUrhkdbAP4%;TXC`mzY gkmtcb=|Db^Ex0*5{5_+f1CnqAkgdBpJ8~)y0It_?JOBUy delta 300 zcmZoT!`N_zae{#?69W_oFfgzHnT$aE@Bjb*AW`PY2a|<2Ch#z^E#N!$+4t_|BBoo+ zlYN*JI4?|kZsvFQGNbh7Ql@UkNgN`UJV5n8ZEzrr#0MIUBF72jgX{nSNst|!Qa}+2 zAQs%5$#I{BMFGg1d?8t5a|!Piw#^<# WKrFF2J8~+| viewPort.visibleArea.bottomRight.x - 50) {/*we leave this history without fill. */ } else { @@ -255,43 +258,239 @@ browserCanvasContext.stroke(); - /* Middle Circle */ - browserCanvasContext.beginPath(); - browserCanvasContext.strokeStyle = 'rgba(44, 61, 89, ' + opacity + ')'; + /* Draw a red inverted triangle on exec sell */ + + if (record.sellExecRate > 0) { + + opacity = '1'; + + let point1 = { + x: record.date, + y: record.sellExecRate + }; + + let point2 = { + x: record.date + timePeriod / 7 * 2, + y: record.sellExecRate + }; + + let point3 = { + x: record.date - timePeriod / 7 * 2, + y: record.sellExecRate + }; + + point1 = timeLineCoordinateSystem.transformThisPoint(point1); + point1 = transformThisPoint(point1, thisObject.container); + point1 = viewPort.fitIntoVisibleArea(point1); + + point2 = timeLineCoordinateSystem.transformThisPoint(point2); + point2 = transformThisPoint(point2, thisObject.container); + point2 = viewPort.fitIntoVisibleArea(point2); + + point3 = timeLineCoordinateSystem.transformThisPoint(point3); + point3 = transformThisPoint(point3, thisObject.container); + point3 = viewPort.fitIntoVisibleArea(point3); + + let diff = point2.x - point3.x; + point2.y = point2.y - diff; + point3.y = point3.y - diff; + + point2 = viewPort.fitIntoVisibleArea(point2); + point3 = viewPort.fitIntoVisibleArea(point3); + + browserCanvasContext.beginPath(); + + browserCanvasContext.moveTo(point1.x, point1.y); + browserCanvasContext.lineTo(point2.x, point2.y); + browserCanvasContext.lineTo(point3.x, point3.y); + browserCanvasContext.lineTo(point1.x, point1.y); + + browserCanvasContext.closePath(); + + browserCanvasContext.strokeStyle = 'rgba(130, 9, 9, ' + opacity + ')'; + browserCanvasContext.stroke(); - if (isCurrentRecord === false) { - browserCanvasContext.fillStyle = 'rgba(50, 108, 201, ' + opacity + ')'; - } else { - browserCanvasContext.fillStyle = 'rgba(255, 233, 31, ' + opacity + ')'; /* highlight the current record */ } - browserCanvasContext.arc(point.x, point.y, radius2, 0, Math.PI * 2, true); - browserCanvasContext.closePath(); + /* Draw a green triangle on exec buy */ + + if (record.buyExecRate > 0) { + + opacity = '1'; + + let point1 = { + x: record.date, + y: record.buyExecRate + }; + + let point2 = { + x: record.date + timePeriod / 7 * 2, + y: record.buyExecRate + }; + + let point3 = { + x: record.date - timePeriod / 7 * 2, + y: record.buyExecRate + }; + + point1 = timeLineCoordinateSystem.transformThisPoint(point1); + point1 = transformThisPoint(point1, thisObject.container); + point1 = viewPort.fitIntoVisibleArea(point1); + + point2 = timeLineCoordinateSystem.transformThisPoint(point2); + point2 = transformThisPoint(point2, thisObject.container); + point2 = viewPort.fitIntoVisibleArea(point2); + + point3 = timeLineCoordinateSystem.transformThisPoint(point3); + point3 = transformThisPoint(point3, thisObject.container); + point3 = viewPort.fitIntoVisibleArea(point3); + + let diff = point2.x - point3.x; + point2.y = point2.y + diff; + point3.y = point3.y + diff; + + point2 = viewPort.fitIntoVisibleArea(point2); + point3 = viewPort.fitIntoVisibleArea(point3); + + browserCanvasContext.beginPath(); + + browserCanvasContext.moveTo(point1.x, point1.y); + browserCanvasContext.lineTo(point2.x, point2.y); + browserCanvasContext.lineTo(point3.x, point3.y); + browserCanvasContext.lineTo(point1.x, point1.y); + + browserCanvasContext.closePath(); + + browserCanvasContext.strokeStyle = 'rgba(27, 105, 7, ' + opacity + ')'; + browserCanvasContext.stroke(); + + } + + /* Draw a red inverted triangle on sell */ + + if (record.lastSellRate > 0) { + + opacity = '1'; + + let point1 = { + x: record.date, + y: record.lastSellRate + }; + + let point2 = { + x: record.date + timePeriod / 7 * 2, + y: record.lastSellRate + }; + + let point3 = { + x: record.date - timePeriod / 7 * 2, + y: record.lastSellRate + }; + + point1 = timeLineCoordinateSystem.transformThisPoint(point1); + point1 = transformThisPoint(point1, thisObject.container); + point1 = viewPort.fitIntoVisibleArea(point1); + + point2 = timeLineCoordinateSystem.transformThisPoint(point2); + point2 = transformThisPoint(point2, thisObject.container); + point2 = viewPort.fitIntoVisibleArea(point2); + + point3 = timeLineCoordinateSystem.transformThisPoint(point3); + point3 = transformThisPoint(point3, thisObject.container); + point3 = viewPort.fitIntoVisibleArea(point3); + + let diff = point2.x - point3.x; + point2.y = point2.y - diff; + point3.y = point3.y - diff; + + point2 = viewPort.fitIntoVisibleArea(point2); + point3 = viewPort.fitIntoVisibleArea(point3); + + browserCanvasContext.beginPath(); + + browserCanvasContext.moveTo(point1.x, point1.y); + browserCanvasContext.lineTo(point2.x, point2.y); + browserCanvasContext.lineTo(point3.x, point3.y); + browserCanvasContext.lineTo(point1.x, point1.y); + + browserCanvasContext.closePath(); + + if (isCurrentRecord === false) { + browserCanvasContext.fillStyle = 'rgba(219, 18, 18, ' + opacity + ')'; + } else { + browserCanvasContext.fillStyle = 'rgba(255, 233, 31, ' + opacity + ')'; /* highlight the current record */ + } - if (point.x < viewPort.visibleArea.topLeft.x + 50 || point.x > viewPort.visibleArea.bottomRight.x - 50) {/*we leave this history without fill. */ } else { browserCanvasContext.fill(); - } - browserCanvasContext.stroke(); - /* Inner Circle */ + browserCanvasContext.strokeStyle = 'rgba(130, 9, 9, ' + opacity + ')'; + browserCanvasContext.stroke(); - browserCanvasContext.beginPath(); - browserCanvasContext.strokeStyle = 'rgba(27, 7, 105, ' + opacity + ')'; - - if (isCurrentRecord === false) { - browserCanvasContext.fillStyle = 'rgba(64, 26, 217, ' + opacity + ')'; - } else { - browserCanvasContext.fillStyle = 'rgba(255, 233, 31, ' + opacity + ')'; /* highlight the current record */ } - browserCanvasContext.arc(point.x, point.y, radius1, 0, Math.PI * 2, true); - browserCanvasContext.closePath(); + /* Draw a green triangle on buy */ + + if (record.lastBuyRate > 0) { + + opacity = '1'; + + let point1 = { + x: record.date, + y: record.lastBuyRate + }; + + let point2 = { + x: record.date + timePeriod / 7 * 2, + y: record.lastBuyRate + }; + + let point3 = { + x: record.date - timePeriod / 7 * 2, + y: record.lastBuyRate + }; + + point1 = timeLineCoordinateSystem.transformThisPoint(point1); + point1 = transformThisPoint(point1, thisObject.container); + point1 = viewPort.fitIntoVisibleArea(point1); + + point2 = timeLineCoordinateSystem.transformThisPoint(point2); + point2 = transformThisPoint(point2, thisObject.container); + point2 = viewPort.fitIntoVisibleArea(point2); + + point3 = timeLineCoordinateSystem.transformThisPoint(point3); + point3 = transformThisPoint(point3, thisObject.container); + point3 = viewPort.fitIntoVisibleArea(point3); + + let diff = point2.x - point3.x; + point2.y = point2.y + diff; + point3.y = point3.y + diff; + + point2 = viewPort.fitIntoVisibleArea(point2); + point3 = viewPort.fitIntoVisibleArea(point3); + + browserCanvasContext.beginPath(); + + browserCanvasContext.moveTo(point1.x, point1.y); + browserCanvasContext.lineTo(point2.x, point2.y); + browserCanvasContext.lineTo(point3.x, point3.y); + browserCanvasContext.lineTo(point1.x, point1.y); + + browserCanvasContext.closePath(); + + if (isCurrentRecord === false) { + browserCanvasContext.fillStyle = 'rgba(64, 217, 26, ' + opacity + ')'; + } else { + browserCanvasContext.fillStyle = 'rgba(255, 233, 31, ' + opacity + ')'; /* highlight the current record */ + } - if (point.x < viewPort.visibleArea.topLeft.x + 50 || point.x > viewPort.visibleArea.bottomRight.x - 50) {/*we leave this history without fill. */ } else { browserCanvasContext.fill(); + + browserCanvasContext.strokeStyle = 'rgba(27, 105, 7, ' + opacity + ')'; + browserCanvasContext.stroke(); + } - browserCanvasContext.stroke(); + /* Since there is at least some point plotted, then the profile should be visible. */ From e0faaa6ca8c515c502fe7e823867e5944875104f Mon Sep 17 00:00:00 2001 From: Luis Fernando Molina Date: Sun, 29 Apr 2018 17:18:48 +0200 Subject: [PATCH 23/54] Bugs fixed with Line --- .vs/Plotters-Trading/v15/.suo | Bin 26112 -> 26112 bytes History.js | 110 +++++++++++++++++++++++++++++++++- 2 files changed, 108 insertions(+), 2 deletions(-) diff --git a/.vs/Plotters-Trading/v15/.suo b/.vs/Plotters-Trading/v15/.suo index ef729813fbb889af55e3dfe4f4f21100ff784d26..8b64b92127ef6e7b616acade86705e4a8f114ec2 100644 GIT binary patch delta 1311 zcmd5*Ur19?7(eIirgwL{HJzE}bWUf8e_+#!l3GI-q$QJV-px&LsbmyUwuwp5pqC)Y zx$ij`vxlIF>h##d4TBz17WC3vy_ZllA$w?j$A(Bm&9@Hs$N8P#cfUX9JLe>pX=0fs zUA2r9hJ_FbDMkFq=kr1}z>6{KlhIF<)`NrDRafxie*OJhx*Kg?xW@Wm$>63DSYtQY z6$-PZeNqXUV0o;qB!J`*h3|%j_FYI71V+v8#94$F!-Tv7As1{yQ+cmsV1;~-N4~DS z-e$hi7S+5Zo)z43qgt~?F+x<SwqY^m$LcfCak)=P&veGe(15e z!Nny0%_h@7`PBJj1O6|XD|X9cb$)83;=bXv+mIk<&x#a0*SwPgtLz4!)kRw%UO6c4 z6XYrrv>xJn{IWP5wcxeGj)cK_&B?#jbc+5fJI^&`St0#^v8dG4&eu9k($lVaiLDS= z@H~Xe9y_ca3zS94I5|%)k#i(MVq_9G=sw$u7Ax2LrkQe>93baT7Oyd<|8J=gS-wdXaVpJ>c8h(^!Ar*dZn>-zeagQZbLXaCWl_*W2Y%dh@A-f3xi|a_!p~sD zg*la`!W=;`2!a5F$wVSSOOhYmbO$g2Es%xRN^IhWc*U{t7ciHkVLZ%y_(XKW08X$I zj4?c-Yr-eYZRjNND~4Zn4%tj>Hi29wvS>A?cpgI{K0meR@;PdgUdKR(c2+9&<<$6U zDAasXm^GA7q?83)${wFv7f#2`TqfnE&beO`x{YNL=h7r%zp=woNjfVudMnjO`f7-n z59OEAsf}PK@Ju=IoY|VQj1DRY&XfS}nMX{UY12k%N4q&s-b&myLKmT%u$|CD=q2mxO7KSnm z+5JBaNrr>;7=E$%B;XNrTC-rTf9jM!g>-y1o-67iRu7I@T^O|b`G}*7>DAAUW=LKO zcR8&cEcQcEC0-Jna#p4l#}|n3OK054tj^TUa8989qb?2dtmwCfumHEz+V{?@V$4{ z-8uz+W4^i0rS4yA0JFQw+MrYibkoEcsZ@4${kfep9vpWJ`PFRjn_)^aIB~* zn;&!PjPcJ*z|-Y5k*zNNsR`={{6`~F6TQGxrNjPjJmLFV=XCokG6f-nV(i25u11V@ z=SJG|vA(hZM~deCa8nfvtCyC)yFWU-T7IZ}zEfO&h9}48N=rCg;W} zFKOkYT3`}{2lPrm(2w(p`oZYI87(tTNF_-ZVrO=-L$LVhm5;@>SI2H*Yx_y(!OMf= ur(VO;9l=0zOXC|#e8w=H!IU|5@?u~ 0) { + + lastSellRate = newHistoryRecord.lastSellRate; + lastSellDate = newHistoryRecord.date; + + } + + if (newHistoryRecord.sellExecRate > 0) { + + let newLine = { + type: "sell", + x1: lastSellDate, + y1: lastSellRate, + x2: newHistoryRecord.date, + y2: newHistoryRecord.sellExecRate + }; + + lines.push(newLine); + + } + + if (newHistoryRecord.lastBuyRate > 0) { + + lastBuyRate = newHistoryRecord.lastBuyRate; + lastBuyDate = newHistoryRecord.date; + + } + + if (newHistoryRecord.buyExecRate > 0) { + + let newLine = { + type: "buy", + x1: lastBuyDate, + y1: lastBuyRate, + x2: newHistoryRecord.date, + y2: newHistoryRecord.buyExecRate + }; + + lines.push(newLine); + + } + } } plotElements.push(history); + plotLines.push(lines); } thisObject.container.eventHandler.raiseEvent("History Changed", history); @@ -258,7 +317,6 @@ browserCanvasContext.stroke(); - /* Draw a red inverted triangle on exec sell */ if (record.sellExecRate > 0) { @@ -497,6 +555,54 @@ thisObject.profile.visible = true; } + /* Draw the lines connecting plot elements. */ + + let lines = plotLines[j]; + + for (let i = 0; i < lines.length; i++) { + + let line = lines[i]; + + opacity = '0.5'; + + let point1 = { + x: line.x1, + y: line.y1 + }; + + let point2 = { + x: line.x2, + y: line.y2 + }; + + point1 = timeLineCoordinateSystem.transformThisPoint(point1); + point1 = transformThisPoint(point1, thisObject.container); + point1 = viewPort.fitIntoVisibleArea(point1); + + point2 = timeLineCoordinateSystem.transformThisPoint(point2); + point2 = transformThisPoint(point2, thisObject.container); + point2 = viewPort.fitIntoVisibleArea(point2); + + browserCanvasContext.beginPath(); + + browserCanvasContext.moveTo(point1.x, point1.y); + browserCanvasContext.lineTo(point2.x, point2.y); + + browserCanvasContext.closePath(); + + if (line.type === "sell") { + + browserCanvasContext.strokeStyle = 'rgba(130, 9, 9, ' + opacity + ')'; + + } else { + + browserCanvasContext.strokeStyle = 'rgba(27, 105, 7, ' + opacity + ')'; + + } + + browserCanvasContext.stroke(); + + } } /* From 936ecbddd33d03baf28e82da0ac2dabcfda6d856 Mon Sep 17 00:00:00 2001 From: Luis Fernando Molina Date: Mon, 30 Apr 2018 08:52:56 +0200 Subject: [PATCH 24/54] Removed Files Array snapshot and now working with FileSequnce Object directly --- History.js | 26 ++++++++++++-------------- 1 file changed, 12 insertions(+), 14 deletions(-) diff --git a/History.js b/History.js index 476f8664e..dc1529837 100644 --- a/History.js +++ b/History.js @@ -32,7 +32,7 @@ /* these are module specific variables: */ - let files = []; // Here we keep the history records to be ploted every time the Draw() function is called by the AAWebPlatform. + let fileSequence; let plotElements = []; // This is where the elements to be plotted are stored before plotting. let plotLines = []; // Here we store the lines of open positions. @@ -43,13 +43,7 @@ datetime = pDatetime; timePeriod = pTimePeriod; - let maxSequence = pStorage.fileSequence.getExpectedFiles(); - - for (let i = 0; i < maxSequence; i++) { - - files.push(pStorage.fileSequence.getFile(i)); - - } + fileSequence = pStorage.fileSequence; recalculate(); recalculateScale(); @@ -98,7 +92,7 @@ function recalculate() { - if (files === undefined) { return; } + if (fileSequence === undefined) { return; } /* @@ -118,9 +112,11 @@ let lastBuyDate; let buyExecRate; - for (let j = 0; j < files.length; j++) { + let maxSequence = fileSequence.getFilesLoaded(); - let file = files[j]; + for (let j = 0; j < maxSequence; j++) { + + let file = fileSequence.getFile(j); let history = []; let lines = []; @@ -211,7 +207,7 @@ function recalculateScale() { - if (files === undefined) { return; } // We need the market file to be loaded to make the calculation. + if (fileSequence === undefined) { return; } // We need the market file to be loaded to make the calculation. if (timeLineCoordinateSystem.maxValue > 0) { return; } // Already calculated. @@ -237,9 +233,11 @@ let maxValue = 0; - for (let j = 0; j < files.length; j++) { + let maxSequence = fileSequence.getFilesLoaded(); - let file = files[j]; + for (let j = 0; j < maxSequence; j++) { + + let file = fileSequence.getFile(j); for (let i = 0; i < file.length; i++) { From 7d38472aa1127d4be3cfb9a831bbd14c49c17ee9 Mon Sep 17 00:00:00 2001 From: Luis Fernando Molina Date: Mon, 30 Apr 2018 10:09:06 +0200 Subject: [PATCH 25/54] Any Number of DataSets per Plotter --- .vs/Plotters-Trading/v15/.suo | Bin 26112 -> 26112 bytes History.js | 2 +- 2 files changed, 1 insertion(+), 1 deletion(-) diff --git a/.vs/Plotters-Trading/v15/.suo b/.vs/Plotters-Trading/v15/.suo index 8b64b92127ef6e7b616acade86705e4a8f114ec2..4eb066d87f5e73b31b769ee5bdf896b031ae38e7 100644 GIT binary patch delta 460 zcmZoT!`N_!ae~2Q0ewz!0R{#(1_lO3ApZCN|9>C_W^W8!&p7!%V=m_e?UH?A4=yu` zO)h2fn|zqZkTHJqS0-jgrWB^hznG(VfO`Im12riC@x(xd$qg(fJo-R3NZbHOZ$7}X zhD$I8$chExI3NaD^KW9H@Z<^Hn|Z;Oi2_AI>L*{6P}y7}aGsTykp(IQ6P{cmc7C$6 zg5l&6@e7lWNEl2mk?@~;z zCT|RNp4{ufHQCprR}d5wFrWisY<}$_%D55{1v*5_; J%@-04SOD*Aq16BY delta 244 zcmZoT!`N_!ae{#Y69W_oFfgzHnT$aE@Bjb*AW>!@-Wa%^aq@r0TvmgK*Cq!x7qay; zPGSk+5d%tz1F-@SPYhI;+`wYOV*q3Wb%Md>11xK}Hs^3pVcI0*%(B^8YA@p?375?- zN_!YLNgZaMd|1_XlHB3Vhc)aOH!~UiV_c-fv&evHkrmS-BY{OWOp^;;%O>lF8f{+T z62ZF2hhvh*Ex`pq;~_xlzyTmba`S5sQO3z}aUz>VLf$ZLigI9{>=1ciQ3TVbxHn9j X-^7V9GO}%Uj9tw*c};xCq9hgo=R!_F diff --git a/History.js b/History.js index dc1529837..7793b13bb 100644 --- a/History.js +++ b/History.js @@ -43,7 +43,7 @@ datetime = pDatetime; timePeriod = pTimePeriod; - fileSequence = pStorage.fileSequence; + fileSequence = pStorage.fileSequence[0]; recalculate(); recalculateScale(); From 1a6f6809ab2f5e609340fc8b818bc04ee110e161 Mon Sep 17 00:00:00 2001 From: Luis Fernando Molina Date: Thu, 3 May 2018 20:54:49 +0200 Subject: [PATCH 26/54] Bubbles Support --- .vs/Plotters-Trading/v15/.suo | Bin 26112 -> 27136 bytes History.js | 304 +++++++++++++++++++++------------- 2 files changed, 188 insertions(+), 116 deletions(-) diff --git a/.vs/Plotters-Trading/v15/.suo b/.vs/Plotters-Trading/v15/.suo index 4eb066d87f5e73b31b769ee5bdf896b031ae38e7..66b6f607e074b466776bb22996f226aa8dd33e3b 100644 GIT binary patch literal 27136 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 G4F3W38kvd! diff --git a/History.js b/History.js index 7793b13bb..b8305292c 100644 --- a/History.js +++ b/History.js @@ -16,7 +16,8 @@ y: 0 }, visible: false - } + }, + bubbles: undefined }; /* this is part of the module template */ @@ -35,6 +36,7 @@ let fileSequence; let plotElements = []; // This is where the elements to be plotted are stored before plotting. let plotLines = []; // Here we store the lines of open positions. + let bubbles = []; // Here we store the bubbles with messages from the bot. return thisObject; @@ -103,6 +105,7 @@ plotElements = []; plotLines = []; + bubbles = []; let lastSellRate; let lastSellDate; @@ -144,12 +147,16 @@ profitsAssetA: file[i][11], profitsAssetB: file[i][12], combinedProfitsA: file[i][13], - combinedProfitsB: file[i][14] + combinedProfitsB: file[i][14], + + messageRelevance: file[i][15], + messageTitle: file[i][16], + messageBody: file[i][17] }; history.push(newHistoryRecord); - if (timePeriod === 60000) { + if (timePeriod <= 1 * 60 * 1000) { /* Here we build the lines. */ @@ -195,6 +202,32 @@ } } + + /* Finally we process the text on the file. */ + + /* + if (newHistoryRecord.messageTitle !== "" && newHistoryRecord.messageBody !== "") { + + if (newHistoryRecord.messageRelevance >= 0 && newHistoryRecord.messageRelevance <= 10) { + + if (timePeriod <= dailyFilePeriods[newHistoryRecord.messageRelevance][0]) { + + let bubble = { + title: newHistoryRecord.messageTitle, + body: newHistoryRecord.messageBody, + date: newHistoryRecord.date, + rate: newHistoryRecord.marketRate, + position: { + x: 0, + y: 0 + } + }; + + bubbles.push(bubble); + } + } + } + */ } plotElements.push(history); @@ -218,7 +251,7 @@ let maxValue = { x: MAX_PLOTABLE_DATE.valueOf(), - y: nextPorwerOf10(getMaxRate()) + y: nextPorwerOf10(USDT_BTC_HTH) }; @@ -319,7 +352,7 @@ if (record.sellExecRate > 0) { - opacity = '1'; + opacity = '0.3'; let point1 = { x: record.date, @@ -364,114 +397,6 @@ browserCanvasContext.closePath(); - browserCanvasContext.strokeStyle = 'rgba(130, 9, 9, ' + opacity + ')'; - browserCanvasContext.stroke(); - - } - - /* Draw a green triangle on exec buy */ - - if (record.buyExecRate > 0) { - - opacity = '1'; - - let point1 = { - x: record.date, - y: record.buyExecRate - }; - - let point2 = { - x: record.date + timePeriod / 7 * 2, - y: record.buyExecRate - }; - - let point3 = { - x: record.date - timePeriod / 7 * 2, - y: record.buyExecRate - }; - - point1 = timeLineCoordinateSystem.transformThisPoint(point1); - point1 = transformThisPoint(point1, thisObject.container); - point1 = viewPort.fitIntoVisibleArea(point1); - - point2 = timeLineCoordinateSystem.transformThisPoint(point2); - point2 = transformThisPoint(point2, thisObject.container); - point2 = viewPort.fitIntoVisibleArea(point2); - - point3 = timeLineCoordinateSystem.transformThisPoint(point3); - point3 = transformThisPoint(point3, thisObject.container); - point3 = viewPort.fitIntoVisibleArea(point3); - - let diff = point2.x - point3.x; - point2.y = point2.y + diff; - point3.y = point3.y + diff; - - point2 = viewPort.fitIntoVisibleArea(point2); - point3 = viewPort.fitIntoVisibleArea(point3); - - browserCanvasContext.beginPath(); - - browserCanvasContext.moveTo(point1.x, point1.y); - browserCanvasContext.lineTo(point2.x, point2.y); - browserCanvasContext.lineTo(point3.x, point3.y); - browserCanvasContext.lineTo(point1.x, point1.y); - - browserCanvasContext.closePath(); - - browserCanvasContext.strokeStyle = 'rgba(27, 105, 7, ' + opacity + ')'; - browserCanvasContext.stroke(); - - } - - /* Draw a red inverted triangle on sell */ - - if (record.lastSellRate > 0) { - - opacity = '1'; - - let point1 = { - x: record.date, - y: record.lastSellRate - }; - - let point2 = { - x: record.date + timePeriod / 7 * 2, - y: record.lastSellRate - }; - - let point3 = { - x: record.date - timePeriod / 7 * 2, - y: record.lastSellRate - }; - - point1 = timeLineCoordinateSystem.transformThisPoint(point1); - point1 = transformThisPoint(point1, thisObject.container); - point1 = viewPort.fitIntoVisibleArea(point1); - - point2 = timeLineCoordinateSystem.transformThisPoint(point2); - point2 = transformThisPoint(point2, thisObject.container); - point2 = viewPort.fitIntoVisibleArea(point2); - - point3 = timeLineCoordinateSystem.transformThisPoint(point3); - point3 = transformThisPoint(point3, thisObject.container); - point3 = viewPort.fitIntoVisibleArea(point3); - - let diff = point2.x - point3.x; - point2.y = point2.y - diff; - point3.y = point3.y - diff; - - point2 = viewPort.fitIntoVisibleArea(point2); - point3 = viewPort.fitIntoVisibleArea(point3); - - browserCanvasContext.beginPath(); - - browserCanvasContext.moveTo(point1.x, point1.y); - browserCanvasContext.lineTo(point2.x, point2.y); - browserCanvasContext.lineTo(point3.x, point3.y); - browserCanvasContext.lineTo(point1.x, point1.y); - - browserCanvasContext.closePath(); - if (isCurrentRecord === false) { browserCanvasContext.fillStyle = 'rgba(219, 18, 18, ' + opacity + ')'; } else { @@ -485,11 +410,135 @@ } + /* Draw a green triangle on exec buy */ + + if (record.buyExecRate > 0) { + + opacity = '0.3'; + + let point1 = { + x: record.date, + y: record.buyExecRate + }; + + let point2 = { + x: record.date + timePeriod / 7 * 2, + y: record.buyExecRate + }; + + let point3 = { + x: record.date - timePeriod / 7 * 2, + y: record.buyExecRate + }; + + point1 = timeLineCoordinateSystem.transformThisPoint(point1); + point1 = transformThisPoint(point1, thisObject.container); + point1 = viewPort.fitIntoVisibleArea(point1); + + point2 = timeLineCoordinateSystem.transformThisPoint(point2); + point2 = transformThisPoint(point2, thisObject.container); + point2 = viewPort.fitIntoVisibleArea(point2); + + point3 = timeLineCoordinateSystem.transformThisPoint(point3); + point3 = transformThisPoint(point3, thisObject.container); + point3 = viewPort.fitIntoVisibleArea(point3); + + let diff = point2.x - point3.x; + point2.y = point2.y + diff; + point3.y = point3.y + diff; + + point2 = viewPort.fitIntoVisibleArea(point2); + point3 = viewPort.fitIntoVisibleArea(point3); + + browserCanvasContext.beginPath(); + + browserCanvasContext.moveTo(point1.x, point1.y); + browserCanvasContext.lineTo(point2.x, point2.y); + browserCanvasContext.lineTo(point3.x, point3.y); + browserCanvasContext.lineTo(point1.x, point1.y); + + browserCanvasContext.closePath(); + + if (isCurrentRecord === false) { + browserCanvasContext.fillStyle = 'rgba(64, 217, 26, ' + opacity + ')'; + } else { + browserCanvasContext.fillStyle = 'rgba(255, 233, 31, ' + opacity + ')'; /* highlight the current record */ + } + + browserCanvasContext.fill(); + + browserCanvasContext.strokeStyle = 'rgba(27, 105, 7, ' + opacity + ')'; + browserCanvasContext.stroke(); + + } + + /* Draw a red inverted triangle on sell */ + + if (record.lastSellRate > 0) { + + opacity = '0.3'; + + let point1 = { + x: record.date, + y: record.lastSellRate + }; + + let point2 = { + x: record.date + timePeriod / 7 * 2, + y: record.lastSellRate + }; + + let point3 = { + x: record.date - timePeriod / 7 * 2, + y: record.lastSellRate + }; + + point1 = timeLineCoordinateSystem.transformThisPoint(point1); + point1 = transformThisPoint(point1, thisObject.container); + point1 = viewPort.fitIntoVisibleArea(point1); + + point2 = timeLineCoordinateSystem.transformThisPoint(point2); + point2 = transformThisPoint(point2, thisObject.container); + point2 = viewPort.fitIntoVisibleArea(point2); + + point3 = timeLineCoordinateSystem.transformThisPoint(point3); + point3 = transformThisPoint(point3, thisObject.container); + point3 = viewPort.fitIntoVisibleArea(point3); + + let diff = point2.x - point3.x; + point2.y = point2.y - diff; + point3.y = point3.y - diff; + + point2 = viewPort.fitIntoVisibleArea(point2); + point3 = viewPort.fitIntoVisibleArea(point3); + + browserCanvasContext.beginPath(); + + browserCanvasContext.moveTo(point1.x, point1.y); + browserCanvasContext.lineTo(point2.x, point2.y); + browserCanvasContext.lineTo(point3.x, point3.y); + browserCanvasContext.lineTo(point1.x, point1.y); + + browserCanvasContext.closePath(); + + if (isCurrentRecord === false) { + browserCanvasContext.fillStyle = 'rgba(255, 255, 255, ' + opacity + ')'; + } else { + browserCanvasContext.fillStyle = 'rgba(255, 233, 31, ' + opacity + ')'; /* highlight the current record */ + } + + browserCanvasContext.fill(); + + browserCanvasContext.strokeStyle = 'rgba(130, 9, 9, ' + opacity + ')'; + browserCanvasContext.stroke(); + + } + /* Draw a green triangle on buy */ if (record.lastBuyRate > 0) { - opacity = '1'; + opacity = '0.3'; let point1 = { x: record.date, @@ -535,7 +584,7 @@ browserCanvasContext.closePath(); if (isCurrentRecord === false) { - browserCanvasContext.fillStyle = 'rgba(64, 217, 26, ' + opacity + ')'; + browserCanvasContext.fillStyle = 'rgba(255, 255, 255, ' + opacity + ')'; } else { browserCanvasContext.fillStyle = 'rgba(255, 233, 31, ' + opacity + ')'; /* highlight the current record */ } @@ -561,7 +610,7 @@ let line = lines[i]; - opacity = '0.5'; + opacity = '0.2'; let point1 = { x: line.x1, @@ -601,6 +650,29 @@ browserCanvasContext.stroke(); } + + /* Now we calculate the anchor position of bubbles. */ + + /* + for (let i = 0; i < bubbles.length; i++) { + + let bubble = bubbles[i]; + + opacity = '0.2'; + + bubble.position = { + x: bubble.date, + y: bubble.rate + }; + + bubble.position = timeLineCoordinateSystem.transformThisPoint(bubble.position); + bubble.position = transformThisPoint(bubble.position, thisObject.container); + bubble.position = viewPort.fitIntoVisibleArea(bubble.position); + + } + + thisObject.bubbles = bubbles; + */ } /* From afc95ec9f7277bc2361a494c9c834c7530eeb4da Mon Sep 17 00:00:00 2001 From: Luis Fernando Molina Date: Sat, 5 May 2018 13:07:45 +0200 Subject: [PATCH 27/54] Visibility Improved --- .vs/Plotters-Trading/v15/.suo | Bin 27136 -> 29184 bytes History.js | 96 +++++++++++++++++++++++++++------- 2 files changed, 77 insertions(+), 19 deletions(-) diff --git a/.vs/Plotters-Trading/v15/.suo b/.vs/Plotters-Trading/v15/.suo index 66b6f607e074b466776bb22996f226aa8dd33e3b..f7a2443e1ff908f97355adaec05d51fd7c4ad529 100644 GIT binary patch delta 519 zcmZp;!r1VHae{#?69W_oFfgzHnT$aE@Bjb*AW`PYjG4k46L^@|8kG3|Bs|$%#B_*J zR1hd51jHOb%mc(gjSO6yJz12Q*aTE>gO#x@Vq{bUX`YzCGFgX1!&L>S259JiRVb|h zq}72~1IpKg(jYY;+mV43P)-tvxi`<`SjEH12r>&~_hf-gjm;&ZS6Em;rb2j97Z_PU zZkx=Lsk6C6<~-x%!%T*gOXLDLxPYQs5Oq46f5>@5WfU%OC;>(JAu>Soy!~0gdcOFd z-+WlbmT^%K%O)LXMs#a+*Dy_1kkUZ1+N6hZa$tJ&=4hj(jFSRRuz-vOJL-$dc_vOq zkPks_012^zycDwer#U;=)h?pyKeJqcTuKEGA`J>;}pVz#VcL` iEYctgKwkgi#lyTQ=$0@xb5liG7I`o&iep-o#sUCkO_t~Y delta 535 zcmZ9JO-lk{5XYVMSy^pKEjGwZHuE*CwhqxX6nYl}>EfkJgxAm&KqO^VuR%nOOCPONt3RXBb4pxQwrq7CG|KlALk(|hUAf()r zJNSu1M)89tEqdFUWa-&)@O*&{&}iv?UUfHONDTB= 0 && newHistoryRecord.messageRelevance <= 10) { - if (timePeriod <= dailyFilePeriods[newHistoryRecord.messageRelevance][0]) { + let relevanceTimePeriod = (dailyFilePeriods[10 - newHistoryRecord.messageRelevance][0]); + + if (timePeriod <= relevanceTimePeriod) { let bubble = { title: newHistoryRecord.messageTitle, - body: newHistoryRecord.messageBody, + body: newHistoryRecord.messageRelevance + ". " + newHistoryRecord.messageBody, date: newHistoryRecord.date, rate: newHistoryRecord.marketRate, position: { x: 0, y: 0 - } + }, + visible: false }; bubbles.push(bubble); } } } - */ } plotElements.push(history); plotLines.push(lines); + + bubblesChangedEventRaised = false; } thisObject.container.eventHandler.raiseEvent("History Changed", history); @@ -599,7 +644,7 @@ /* Since there is at least some point plotted, then the profile should be visible. */ - thisObject.profile.visible = true; + thisObject.payload.profile.visible = true; } /* Draw the lines connecting plot elements. */ @@ -653,7 +698,7 @@ /* Now we calculate the anchor position of bubbles. */ - /* + for (let i = 0; i < bubbles.length; i++) { let bubble = bubbles[i]; @@ -667,12 +712,25 @@ bubble.position = timeLineCoordinateSystem.transformThisPoint(bubble.position); bubble.position = transformThisPoint(bubble.position, thisObject.container); + + if (bubble.position.x < (viewPort.visibleArea.bottomRight.x) * (-1) || bubble.position.x > (viewPort.visibleArea.bottomRight.x) * (2)) { + bubble.visible = false; + } else { + bubble.visible = true; + } + bubble.position = viewPort.fitIntoVisibleArea(bubble.position); } - thisObject.bubbles = bubbles; - */ + if (bubblesChangedEventRaised === false) { + + thisObject.container.eventHandler.raiseEvent("Bubbles Changed", bubbles); + thisObject.payload.bubbles = bubbles; + + bubblesChangedEventRaised = true; + } + } /* @@ -682,8 +740,8 @@ */ - thisObject.profile.position.x = point.x; - thisObject.profile.position.y = point.y; + thisObject.payload.profile.position.x = point.x; + thisObject.payload.profile.position.y = point.y; } } From d2e7ad7e3c85fce529df04c3d38c13621548a9ab Mon Sep 17 00:00:00 2001 From: Luis Fernando Molina Date: Sat, 5 May 2018 13:25:59 +0200 Subject: [PATCH 28/54] Bubbles Working Well --- .vs/Plotters-Trading/v15/.suo | Bin 29184 -> 27136 bytes History.js | 12 +----------- 2 files changed, 1 insertion(+), 11 deletions(-) diff --git a/.vs/Plotters-Trading/v15/.suo b/.vs/Plotters-Trading/v15/.suo index f7a2443e1ff908f97355adaec05d51fd7c4ad529..86211ee2d1cde587b6b08418a3574fac068a0938 100644 GIT binary patch delta 80 zcmZp8!q{+yae{#?0}Kc-Ft7pHj6nSF|Ns9WVaCafnZg?rc$iof-X~ZmZ!ToYbQN5~ R1d@V)<3P6H=GX3`N&v=y5p@6n delta 73 zcmZp;!r1VHae{#?69W_oFfgzHnT$aE@Bjb*AW`PYjG4k46L^?d8 Date: Sat, 5 May 2018 19:13:49 +0200 Subject: [PATCH 29/54] Refactoring --- .vs/Plotters-Trading/v15/.suo | Bin 27136 -> 29184 bytes History.js | 44 +++++++++++++++++----------------- 2 files changed, 22 insertions(+), 22 deletions(-) diff --git a/.vs/Plotters-Trading/v15/.suo b/.vs/Plotters-Trading/v15/.suo index 86211ee2d1cde587b6b08418a3574fac068a0938..8365e412f001a76e90456d825c2206f179b36f21 100644 GIT binary patch delta 89 zcmZp;!r1VHae{#?69W_oFfgzHnT$aE@Bjb*AW`PYjG4k46L{EI8w_{fp1iq`Ei+#5 bF-QgqegbKg&975MSr&OPEsA4Wl*R%8qf`~x delta 80 zcmZp8!q{+yae{#?0}Kc-Ft7pHj6nSF|Ns9WVaCafnZg?rc-UA4RB!)D*j&h#885h< U2_yvqLI+L**>#&=r;4%w0N}h6L;wH) diff --git a/History.js b/History.js index e9b00f1d2..5e9b51fdf 100644 --- a/History.js +++ b/History.js @@ -18,7 +18,7 @@ }, visible: false }, - bubbles: [] + notes: [] } }; @@ -38,9 +38,9 @@ let fileSequence; let plotElements = []; // This is where the elements to be plotted are stored before plotting. let plotLines = []; // Here we store the lines of open positions. - let bubbles = []; // Here we store the bubbles with messages from the bot. + let notes = []; // Here we store the notes with messages from the bot. - let bubblesChangedEventRaised = true; // This controls when to raise the event that bubbles changed. + let notesChangedEventRaised = true; // This controls when to raise the event that notes changed. return thisObject; @@ -109,7 +109,7 @@ plotElements = []; plotLines = []; - bubbles = []; + notes = []; let lastSellRate; let lastSellDate; @@ -247,7 +247,7 @@ if (timePeriod <= relevanceTimePeriod) { - let bubble = { + let note = { title: newHistoryRecord.messageTitle, body: newHistoryRecord.messageBody, date: newHistoryRecord.date, @@ -259,7 +259,7 @@ visible: false }; - bubbles.push(bubble); + notes.push(note); } } } @@ -268,7 +268,7 @@ plotElements.push(history); plotLines.push(lines); - bubblesChangedEventRaised = false; + notesChangedEventRaised = false; } thisObject.container.eventHandler.raiseEvent("History Changed", history); @@ -688,37 +688,37 @@ } - /* Now we calculate the anchor position of bubbles. */ + /* Now we calculate the anchor position of notes. */ - for (let i = 0; i < bubbles.length; i++) { + for (let i = 0; i < notes.length; i++) { - let bubble = bubbles[i]; + let note = notes[i]; opacity = '0.2'; - bubble.position = { - x: bubble.date, - y: bubble.rate + note.position = { + x: note.date, + y: note.rate }; - bubble.position = timeLineCoordinateSystem.transformThisPoint(bubble.position); - bubble.position = transformThisPoint(bubble.position, thisObject.container); + note.position = timeLineCoordinateSystem.transformThisPoint(note.position); + note.position = transformThisPoint(note.position, thisObject.container); - if (bubble.position.x < (viewPort.visibleArea.bottomRight.x) * (-1) || bubble.position.x > (viewPort.visibleArea.bottomRight.x) * (2)) { - bubble.visible = false; + if (note.position.x < (viewPort.visibleArea.bottomRight.x) * (-1) || note.position.x > (viewPort.visibleArea.bottomRight.x) * (2)) { + note.visible = false; } else { - bubble.visible = true; + note.visible = true; } } - if (bubblesChangedEventRaised === false) { + if (notesChangedEventRaised === false) { - thisObject.container.eventHandler.raiseEvent("Bubbles Changed", bubbles); - thisObject.payload.bubbles = bubbles; + thisObject.container.eventHandler.raiseEvent("Notes Changed", notes); + thisObject.payload.notes = notes; - bubblesChangedEventRaised = true; + notesChangedEventRaised = true; } } From 9f1acb734ba32aaa5a2279bbf8f900d6d1979c33 Mon Sep 17 00:00:00 2001 From: Luis Fernando Molina Date: Mon, 7 May 2018 15:03:32 +0200 Subject: [PATCH 30/54] Logging And Error Handling --- .vs/Plotters-Trading/v15/.suo | Bin 29184 -> 27136 bytes History.js | 1171 ++++++++++++++++++--------------- 2 files changed, 628 insertions(+), 543 deletions(-) diff --git a/.vs/Plotters-Trading/v15/.suo b/.vs/Plotters-Trading/v15/.suo index 8365e412f001a76e90456d825c2206f179b36f21..dee52a83bba925c37e15b914f76551ce02c1a6e8 100644 GIT binary patch delta 116 zcmZp8!q{+yae{#?0}Kc-Ft7pHj6nSF|Ns9WVaCafnZg?rc$nB4R35Eoezv)Y=@&EG t1l6FcOh7hUhNECFNI4XkG6QvNe(nBVR?r0|#-MZ{8OV;_{5n;X1psZE8=3$B delta 125 zcmZp;!r1VHae{#?69W_oFfgzHnT$aE@Bjb*AW`PYjG4k46L^@|6y7ITCqLO-#Po}q zt-)~j?a4qkTZW_H8n|`_hT}lC;O5uv?_~uagLFf|Pav(b`E{x&%OVe^MR81v(pUh| C2_QfK diff --git a/History.js b/History.js index 5e9b51fdf..6ad071132 100644 --- a/History.js +++ b/History.js @@ -1,5 +1,12 @@ function newAAMastersPlottersTradingHistory() { + const MODULE_NAME = "AAMasters Plotters Trading History"; + const INFO_LOG = true; + const INTENSIVE_LOG = false; + const ERROR_LOG = true; + const logger = newDebugLog(); + logger.fileName = MODULE_NAME; + let thisObject = { // Main functions and properties. @@ -46,262 +53,110 @@ function initialize(pStorage, pExchange, pMarket, pDatetime, pTimePeriod, callBackFunction) { - datetime = pDatetime; - timePeriod = pTimePeriod; + try { - fileSequence = pStorage.fileSequence[0]; + if (INFO_LOG === true) { logger.write("[INFO] initialize -> Entering function."); } - recalculate(); - recalculateScale(); - callBackFunction(); + datetime = pDatetime; + timePeriod = pTimePeriod; + fileSequence = pStorage.fileSequence[0]; + + recalculate(callBackFunction); + recalculateScale(callBackFunction); + + callBackFunction(GLOBAL.DEFAULT_OK_RESPONSE); + + } catch (err) { + + if (ERROR_LOG === true) { logger.write("[ERROR] initialize -> err = " + err); } + callBackFunction(GLOBAL.CUSTOM_FAIL_RESPONSE); + } } function getContainer(point) { - let container; + try { - /* First we check if this point is inside this space. */ + if (INFO_LOG === true) { logger.write("[INFO] getContainer -> Entering function."); } - if (this.container.frame.isThisPointHere(point) === true) { + let container; - return this.container; + /* First we check if this point is inside this space. */ - } else { + if (this.container.frame.isThisPointHere(point) === true) { - /* This point does not belong to this space. */ + return this.container; - return undefined; + } else { + + /* This point does not belong to this space. */ + + return undefined; + } + + } catch (err) { + + if (ERROR_LOG === true) { logger.write("[ERROR] initialize -> err = " + err); } } - } function setTimePeriod(pTimePeriod) { - timePeriod = pTimePeriod; + try { - recalculate(); + if (INFO_LOG === true) { logger.write("[INFO] setTimePeriod -> Entering function."); } + timePeriod = pTimePeriod; + + recalculate(); + + } catch (err) { + + if (ERROR_LOG === true) { logger.write("[ERROR] setTimePeriod -> err = " + err); } + } } function setDatetime(newDatetime) { - datetime = newDatetime; + try { - } + if (INFO_LOG === true) { logger.write("[INFO] setDatetime -> Entering function."); } - function draw() { + datetime = newDatetime; - plotChart(); + } catch (err) { - } - - function recalculate() { - - if (fileSequence === undefined) { return; } - - /* - - We are going to filter the records depending on the Time Period. We want that for a 1 min time peroid all the records appears on screen, - but for higher periods, we will filter out some records, so that they do not overlap ever. - - */ - - plotElements = []; - plotLines = []; - notes = []; - - let lastSellRate; - let lastSellDate; - let sellExecRate; - - let lastBuyRate; - let lastBuyDate; - let buyExecRate; - - let maxSequence = fileSequence.getFilesLoaded(); - - for (let j = 0; j < maxSequence; j++) { - - let file = fileSequence.getFile(j); - - let history = []; - let lines = []; - - let oneMin = 60000; - let step = timePeriod / oneMin; - - /* First the small balls */ - - for (let i = 0; i < file.length; i = i + step) { - - let newHistoryRecord = { - - date: Math.trunc(file[i][0] / 60000) * 60000 + 30000, - buyAvgRate: file[i][1], - sellAvgRate: file[i][2], - - lastSellRate: file[i][3], - sellExecRate: file[i][4], - lastBuyRate: file[i][5], - buyExecRate: file[i][6], - - marketRate: file[i][7], - newPositions: file[i][8], - newTrades: file[i][9], - movedPositions: file[i][10], - profitsAssetA: file[i][11], - profitsAssetB: file[i][12], - combinedProfitsA: file[i][13], - combinedProfitsB: file[i][14], - - messageRelevance: file[i][15], - messageTitle: file[i][16], - messageBody: file[i][17] - }; - - history.push(newHistoryRecord); - - if (timePeriod <= 1 * 60 * 1000) { - - /* Here we build the lines. */ - - if (newHistoryRecord.lastSellRate > 0) { - - lastSellRate = newHistoryRecord.lastSellRate; - lastSellDate = newHistoryRecord.date; - - } - - if (newHistoryRecord.sellExecRate > 0) { - - let newLine = { - type: "sell", - x1: lastSellDate, - y1: lastSellRate, - x2: newHistoryRecord.date, - y2: newHistoryRecord.sellExecRate - }; - - lines.push(newLine); - - } - - if (newHistoryRecord.lastBuyRate > 0) { - - lastBuyRate = newHistoryRecord.lastBuyRate; - lastBuyDate = newHistoryRecord.date; - - } - - if (newHistoryRecord.buyExecRate > 0) { - - let newLine = { - type: "buy", - x1: lastBuyDate, - y1: lastBuyRate, - x2: newHistoryRecord.date, - y2: newHistoryRecord.buyExecRate - }; - - lines.push(newLine); - - } - } - } - - /* Second we process the text */ - - for (let i = 0; i < file.length; i++) { - - let newHistoryRecord = { - - date: Math.trunc(file[i][0] / 60000) * 60000 + 30000, - buyAvgRate: file[i][1], - sellAvgRate: file[i][2], - - lastSellRate: file[i][3], - sellExecRate: file[i][4], - lastBuyRate: file[i][5], - buyExecRate: file[i][6], - - marketRate: file[i][7], - newPositions: file[i][8], - newTrades: file[i][9], - movedPositions: file[i][10], - profitsAssetA: file[i][11], - profitsAssetB: file[i][12], - combinedProfitsA: file[i][13], - combinedProfitsB: file[i][14], - - messageRelevance: file[i][15], - messageTitle: file[i][16], - messageBody: file[i][17] - }; - - if (newHistoryRecord.messageTitle !== "" && newHistoryRecord.messageBody !== "") { - - if (newHistoryRecord.messageRelevance >= 0 && newHistoryRecord.messageRelevance <= 10) { - - let relevanceTimePeriod = (dailyFilePeriods[10 - newHistoryRecord.messageRelevance][0]); - - if (timePeriod <= relevanceTimePeriod) { - - let note = { - title: newHistoryRecord.messageTitle, - body: newHistoryRecord.messageBody, - date: newHistoryRecord.date, - rate: newHistoryRecord.marketRate, - position: { - x: 0, - y: 0 - }, - visible: false - }; - - notes.push(note); - } - } - } - } - - plotElements.push(history); - plotLines.push(lines); - - notesChangedEventRaised = false; + if (ERROR_LOG === true) { logger.write("[ERROR] setTimePeriod -> err = " + err); } } - - thisObject.container.eventHandler.raiseEvent("History Changed", history); - } - function recalculateScale() { + function recalculate(callBackFunction) { - if (fileSequence === undefined) { return; } // We need the market file to be loaded to make the calculation. + try { - if (timeLineCoordinateSystem.maxValue > 0) { return; } // Already calculated. + if (INFO_LOG === true) { logger.write("[INFO] recalculate -> Entering function."); } - let minValue = { - x: EARLIEST_DATE.valueOf(), - y: 0 - }; + if (fileSequence === undefined) { return; } - let maxValue = { - x: MAX_PLOTABLE_DATE.valueOf(), - y: nextPorwerOf10(USDT_BTC_HTH) - }; + /* + + We are going to filter the records depending on the Time Period. We want that for a 1 min time peroid all the records appears on screen, + but for higher periods, we will filter out some records, so that they do not overlap ever. + + */ + plotElements = []; + plotLines = []; + notes = []; - timeLineCoordinateSystem.initialize( - minValue, - maxValue, - thisObject.container.frame.width, - thisObject.container.frame.height - ); + let lastSellRate; + let lastSellDate; + let sellExecRate; - function getMaxRate() { - - let maxValue = 0; + let lastBuyRate; + let lastBuyDate; + let buyExecRate; let maxSequence = fileSequence.getFilesLoaded(); @@ -309,192 +164,292 @@ let file = fileSequence.getFile(j); + let history = []; + let lines = []; + + let oneMin = 60000; + let step = timePeriod / oneMin; + + /* First the small balls */ + + for (let i = 0; i < file.length; i = i + step) { + + let newHistoryRecord = { + + date: Math.trunc(file[i][0] / 60000) * 60000 + 30000, + buyAvgRate: file[i][1], + sellAvgRate: file[i][2], + + lastSellRate: file[i][3], + sellExecRate: file[i][4], + lastBuyRate: file[i][5], + buyExecRate: file[i][6], + + marketRate: file[i][7], + newPositions: file[i][8], + newTrades: file[i][9], + movedPositions: file[i][10], + profitsAssetA: file[i][11], + profitsAssetB: file[i][12], + combinedProfitsA: file[i][13], + combinedProfitsB: file[i][14], + + messageRelevance: file[i][15], + messageTitle: file[i][16], + messageBody: file[i][17] + }; + + history.push(newHistoryRecord); + + if (timePeriod <= 1 * 60 * 1000) { + + /* Here we build the lines. */ + + if (newHistoryRecord.lastSellRate > 0) { + + lastSellRate = newHistoryRecord.lastSellRate; + lastSellDate = newHistoryRecord.date; + + } + + if (newHistoryRecord.sellExecRate > 0) { + + let newLine = { + type: "sell", + x1: lastSellDate, + y1: lastSellRate, + x2: newHistoryRecord.date, + y2: newHistoryRecord.sellExecRate + }; + + lines.push(newLine); + + } + + if (newHistoryRecord.lastBuyRate > 0) { + + lastBuyRate = newHistoryRecord.lastBuyRate; + lastBuyDate = newHistoryRecord.date; + + } + + if (newHistoryRecord.buyExecRate > 0) { + + let newLine = { + type: "buy", + x1: lastBuyDate, + y1: lastBuyRate, + x2: newHistoryRecord.date, + y2: newHistoryRecord.buyExecRate + }; + + lines.push(newLine); + + } + } + } + + /* Second we process the text */ + for (let i = 0; i < file.length; i++) { - let currentMax = file[i][1] + file[i][2]; // 1 = rates. + let newHistoryRecord = { - if (maxValue < currentMax) { - maxValue = currentMax; + date: Math.trunc(file[i][0] / 60000) * 60000 + 30000, + buyAvgRate: file[i][1], + sellAvgRate: file[i][2], + + lastSellRate: file[i][3], + sellExecRate: file[i][4], + lastBuyRate: file[i][5], + buyExecRate: file[i][6], + + marketRate: file[i][7], + newPositions: file[i][8], + newTrades: file[i][9], + movedPositions: file[i][10], + profitsAssetA: file[i][11], + profitsAssetB: file[i][12], + combinedProfitsA: file[i][13], + combinedProfitsB: file[i][14], + + messageRelevance: file[i][15], + messageTitle: file[i][16], + messageBody: file[i][17] + }; + + if (newHistoryRecord.messageTitle !== "" && newHistoryRecord.messageBody !== "") { + + if (newHistoryRecord.messageRelevance >= 0 && newHistoryRecord.messageRelevance <= 10) { + + let relevanceTimePeriod = (dailyFilePeriods[10 - newHistoryRecord.messageRelevance][0]); + + if (timePeriod <= relevanceTimePeriod) { + + let note = { + title: newHistoryRecord.messageTitle, + body: newHistoryRecord.messageBody, + date: newHistoryRecord.date, + rate: newHistoryRecord.marketRate, + position: { + x: 0, + y: 0 + }, + visible: false + }; + + notes.push(note); + } + } } } + + plotElements.push(history); + plotLines.push(lines); + + notesChangedEventRaised = false; + } + + thisObject.container.eventHandler.raiseEvent("History Changed", history); + + } catch (err) { + + if (ERROR_LOG === true) { logger.write("[ERROR] recalculate -> err = " + err); } + callBackFunction(GLOBAL.CUSTOM_FAIL_RESPONSE); + } + } + + function recalculateScale(callBackFunction) { + + try { + + if (INFO_LOG === true) { logger.write("[INFO] recalculateScale -> Entering function."); } + + if (fileSequence === undefined) { return; } // We need the market file to be loaded to make the calculation. + + if (timeLineCoordinateSystem.maxValue > 0) { return; } // Already calculated. + + let minValue = { + x: EARLIEST_DATE.valueOf(), + y: 0 + }; + + let maxValue = { + x: MAX_PLOTABLE_DATE.valueOf(), + y: nextPorwerOf10(USDT_BTC_HTH) + }; + + + timeLineCoordinateSystem.initialize( + minValue, + maxValue, + thisObject.container.frame.width, + thisObject.container.frame.height + ); + + function getMaxRate() { + + try { + + if (INFO_LOG === true) { logger.write("[INFO] recalculateScale -> getMaxRate > Entering function."); } + + let maxValue = 0; + + let maxSequence = fileSequence.getFilesLoaded(); + + for (let j = 0; j < maxSequence; j++) { + + let file = fileSequence.getFile(j); + + for (let i = 0; i < file.length; i++) { + + let currentMax = file[i][1] + file[i][2]; // 1 = rates. + + if (maxValue < currentMax) { + maxValue = currentMax; + } + } + } + + return maxValue; + + } catch (err) { + + if (ERROR_LOG === true) { logger.write("[ERROR] recalculateScale -> getMaxRate -> err = " + err); } + callBackFunction(GLOBAL.CUSTOM_FAIL_RESPONSE); + } } - return maxValue; + } catch (err) { + if (ERROR_LOG === true) { logger.write("[ERROR] recalculateScale -> err = " + err); } + callBackFunction(GLOBAL.CUSTOM_FAIL_RESPONSE); + } + } + + function draw() { + + try { + + if (INTENSIVE_LOG === true) { logger.write("[INFO] draw -> Entering function."); } + + plotChart(); + + } catch (err) { + + if (ERROR_LOG === true) { logger.write("[ERROR] draw -> err = " + err); } } } function plotChart() { - let point; - let history; + try { - for (let j = 0; j < plotElements.length; j++) { + if (INTENSIVE_LOG === true) { logger.write("[INFO] plotChart -> Entering function."); } - let history = plotElements[j]; + let point; + let history; - for (let i = 0; i < history.length; i++) { + for (let j = 0; j < plotElements.length; j++) { - record = history[i]; + let history = plotElements[j]; - point = { - x: record.date, - y: record.marketRate - }; + for (let i = 0; i < history.length; i++) { - point = timeLineCoordinateSystem.transformThisPoint(point); - point = transformThisPoint(point, thisObject.container); + record = history[i]; - if (point.x < viewPort.visibleArea.bottomLeft.x || point.x > viewPort.visibleArea.bottomRight.x) { continue;} - - point = viewPort.fitIntoVisibleArea(point); - - let isCurrentRecord = false; - - if (datetime !== undefined) { - let dateValue = datetime.valueOf(); - if (dateValue >= record.date - timePeriod / 2 && dateValue <= record.date + timePeriod / 2 - 1) { - isCurrentRecord = true; - } - } - - let radius = 3; - - let opacity = '0.2'; - - browserCanvasContext.lineWidth = 1; - - /* Outer Circle */ - - browserCanvasContext.beginPath(); - - browserCanvasContext.strokeStyle = 'rgba(27, 105, 7, ' + opacity + ')'; - - if (isCurrentRecord === false) { - browserCanvasContext.fillStyle = 'rgba(64, 217, 26, ' + opacity + ')'; - } else { - browserCanvasContext.fillStyle = 'rgba(255, 233, 31, ' + opacity + ')'; /* highlight the current record */ - } - - browserCanvasContext.arc(point.x, point.y, radius, 0, Math.PI * 2, true); - browserCanvasContext.closePath(); - - if (point.x < viewPort.visibleArea.topLeft.x + 50 || point.x > viewPort.visibleArea.bottomRight.x - 50) {/*we leave this history without fill. */ } else { - browserCanvasContext.fill(); - } - - browserCanvasContext.stroke(); - - /* Draw a red inverted triangle on exec sell */ - - if (record.sellExecRate > 0) { - - opacity = '0.3'; - - let point1 = { + point = { x: record.date, - y: record.sellExecRate + y: record.marketRate }; - let point2 = { - x: record.date + timePeriod / 7 * 2, - y: record.sellExecRate - }; + point = timeLineCoordinateSystem.transformThisPoint(point); + point = transformThisPoint(point, thisObject.container); - let point3 = { - x: record.date - timePeriod / 7 * 2, - y: record.sellExecRate - }; + if (point.x < viewPort.visibleArea.bottomLeft.x || point.x > viewPort.visibleArea.bottomRight.x) { continue; } - point1 = timeLineCoordinateSystem.transformThisPoint(point1); - point1 = transformThisPoint(point1, thisObject.container); - point1 = viewPort.fitIntoVisibleArea(point1); + point = viewPort.fitIntoVisibleArea(point); - point2 = timeLineCoordinateSystem.transformThisPoint(point2); - point2 = transformThisPoint(point2, thisObject.container); - point2 = viewPort.fitIntoVisibleArea(point2); + let isCurrentRecord = false; - point3 = timeLineCoordinateSystem.transformThisPoint(point3); - point3 = transformThisPoint(point3, thisObject.container); - point3 = viewPort.fitIntoVisibleArea(point3); - - let diff = point2.x - point3.x; - point2.y = point2.y - diff; - point3.y = point3.y - diff; - - point2 = viewPort.fitIntoVisibleArea(point2); - point3 = viewPort.fitIntoVisibleArea(point3); - - browserCanvasContext.beginPath(); - - browserCanvasContext.moveTo(point1.x, point1.y); - browserCanvasContext.lineTo(point2.x, point2.y); - browserCanvasContext.lineTo(point3.x, point3.y); - browserCanvasContext.lineTo(point1.x, point1.y); - - browserCanvasContext.closePath(); - - if (isCurrentRecord === false) { - browserCanvasContext.fillStyle = 'rgba(219, 18, 18, ' + opacity + ')'; - } else { - browserCanvasContext.fillStyle = 'rgba(255, 233, 31, ' + opacity + ')'; /* highlight the current record */ + if (datetime !== undefined) { + let dateValue = datetime.valueOf(); + if (dateValue >= record.date - timePeriod / 2 && dateValue <= record.date + timePeriod / 2 - 1) { + isCurrentRecord = true; + } } - browserCanvasContext.fill(); + let radius = 3; - browserCanvasContext.strokeStyle = 'rgba(130, 9, 9, ' + opacity + ')'; - browserCanvasContext.stroke(); + let opacity = '0.2'; - } + browserCanvasContext.lineWidth = 1; - /* Draw a green triangle on exec buy */ - - if (record.buyExecRate > 0) { - - opacity = '0.3'; - - let point1 = { - x: record.date, - y: record.buyExecRate - }; - - let point2 = { - x: record.date + timePeriod / 7 * 2, - y: record.buyExecRate - }; - - let point3 = { - x: record.date - timePeriod / 7 * 2, - y: record.buyExecRate - }; - - point1 = timeLineCoordinateSystem.transformThisPoint(point1); - point1 = transformThisPoint(point1, thisObject.container); - point1 = viewPort.fitIntoVisibleArea(point1); - - point2 = timeLineCoordinateSystem.transformThisPoint(point2); - point2 = transformThisPoint(point2, thisObject.container); - point2 = viewPort.fitIntoVisibleArea(point2); - - point3 = timeLineCoordinateSystem.transformThisPoint(point3); - point3 = transformThisPoint(point3, thisObject.container); - point3 = viewPort.fitIntoVisibleArea(point3); - - let diff = point2.x - point3.x; - point2.y = point2.y + diff; - point3.y = point3.y + diff; - - point2 = viewPort.fitIntoVisibleArea(point2); - point3 = viewPort.fitIntoVisibleArea(point3); + /* Outer Circle */ browserCanvasContext.beginPath(); - browserCanvasContext.moveTo(point1.x, point1.y); - browserCanvasContext.lineTo(point2.x, point2.y); - browserCanvasContext.lineTo(point3.x, point3.y); - browserCanvasContext.lineTo(point1.x, point1.y); - - browserCanvasContext.closePath(); + browserCanvasContext.strokeStyle = 'rgba(27, 105, 7, ' + opacity + ')'; if (isCurrentRecord === false) { browserCanvasContext.fillStyle = 'rgba(64, 217, 26, ' + opacity + ')'; @@ -502,32 +457,287 @@ browserCanvasContext.fillStyle = 'rgba(255, 233, 31, ' + opacity + ')'; /* highlight the current record */ } - browserCanvasContext.fill(); + browserCanvasContext.arc(point.x, point.y, radius, 0, Math.PI * 2, true); + browserCanvasContext.closePath(); + + if (point.x < viewPort.visibleArea.topLeft.x + 50 || point.x > viewPort.visibleArea.bottomRight.x - 50) {/*we leave this history without fill. */ } else { + browserCanvasContext.fill(); + } - browserCanvasContext.strokeStyle = 'rgba(27, 105, 7, ' + opacity + ')'; browserCanvasContext.stroke(); + /* Draw a red inverted triangle on exec sell */ + + if (record.sellExecRate > 0) { + + opacity = '0.3'; + + let point1 = { + x: record.date, + y: record.sellExecRate + }; + + let point2 = { + x: record.date + timePeriod / 7 * 2, + y: record.sellExecRate + }; + + let point3 = { + x: record.date - timePeriod / 7 * 2, + y: record.sellExecRate + }; + + point1 = timeLineCoordinateSystem.transformThisPoint(point1); + point1 = transformThisPoint(point1, thisObject.container); + point1 = viewPort.fitIntoVisibleArea(point1); + + point2 = timeLineCoordinateSystem.transformThisPoint(point2); + point2 = transformThisPoint(point2, thisObject.container); + point2 = viewPort.fitIntoVisibleArea(point2); + + point3 = timeLineCoordinateSystem.transformThisPoint(point3); + point3 = transformThisPoint(point3, thisObject.container); + point3 = viewPort.fitIntoVisibleArea(point3); + + let diff = point2.x - point3.x; + point2.y = point2.y - diff; + point3.y = point3.y - diff; + + point2 = viewPort.fitIntoVisibleArea(point2); + point3 = viewPort.fitIntoVisibleArea(point3); + + browserCanvasContext.beginPath(); + + browserCanvasContext.moveTo(point1.x, point1.y); + browserCanvasContext.lineTo(point2.x, point2.y); + browserCanvasContext.lineTo(point3.x, point3.y); + browserCanvasContext.lineTo(point1.x, point1.y); + + browserCanvasContext.closePath(); + + if (isCurrentRecord === false) { + browserCanvasContext.fillStyle = 'rgba(219, 18, 18, ' + opacity + ')'; + } else { + browserCanvasContext.fillStyle = 'rgba(255, 233, 31, ' + opacity + ')'; /* highlight the current record */ + } + + browserCanvasContext.fill(); + + browserCanvasContext.strokeStyle = 'rgba(130, 9, 9, ' + opacity + ')'; + browserCanvasContext.stroke(); + + } + + /* Draw a green triangle on exec buy */ + + if (record.buyExecRate > 0) { + + opacity = '0.3'; + + let point1 = { + x: record.date, + y: record.buyExecRate + }; + + let point2 = { + x: record.date + timePeriod / 7 * 2, + y: record.buyExecRate + }; + + let point3 = { + x: record.date - timePeriod / 7 * 2, + y: record.buyExecRate + }; + + point1 = timeLineCoordinateSystem.transformThisPoint(point1); + point1 = transformThisPoint(point1, thisObject.container); + point1 = viewPort.fitIntoVisibleArea(point1); + + point2 = timeLineCoordinateSystem.transformThisPoint(point2); + point2 = transformThisPoint(point2, thisObject.container); + point2 = viewPort.fitIntoVisibleArea(point2); + + point3 = timeLineCoordinateSystem.transformThisPoint(point3); + point3 = transformThisPoint(point3, thisObject.container); + point3 = viewPort.fitIntoVisibleArea(point3); + + let diff = point2.x - point3.x; + point2.y = point2.y + diff; + point3.y = point3.y + diff; + + point2 = viewPort.fitIntoVisibleArea(point2); + point3 = viewPort.fitIntoVisibleArea(point3); + + browserCanvasContext.beginPath(); + + browserCanvasContext.moveTo(point1.x, point1.y); + browserCanvasContext.lineTo(point2.x, point2.y); + browserCanvasContext.lineTo(point3.x, point3.y); + browserCanvasContext.lineTo(point1.x, point1.y); + + browserCanvasContext.closePath(); + + if (isCurrentRecord === false) { + browserCanvasContext.fillStyle = 'rgba(64, 217, 26, ' + opacity + ')'; + } else { + browserCanvasContext.fillStyle = 'rgba(255, 233, 31, ' + opacity + ')'; /* highlight the current record */ + } + + browserCanvasContext.fill(); + + browserCanvasContext.strokeStyle = 'rgba(27, 105, 7, ' + opacity + ')'; + browserCanvasContext.stroke(); + + } + + /* Draw a red inverted triangle on sell */ + + if (record.lastSellRate > 0) { + + opacity = '0.3'; + + let point1 = { + x: record.date, + y: record.lastSellRate + }; + + let point2 = { + x: record.date + timePeriod / 7 * 2, + y: record.lastSellRate + }; + + let point3 = { + x: record.date - timePeriod / 7 * 2, + y: record.lastSellRate + }; + + point1 = timeLineCoordinateSystem.transformThisPoint(point1); + point1 = transformThisPoint(point1, thisObject.container); + point1 = viewPort.fitIntoVisibleArea(point1); + + point2 = timeLineCoordinateSystem.transformThisPoint(point2); + point2 = transformThisPoint(point2, thisObject.container); + point2 = viewPort.fitIntoVisibleArea(point2); + + point3 = timeLineCoordinateSystem.transformThisPoint(point3); + point3 = transformThisPoint(point3, thisObject.container); + point3 = viewPort.fitIntoVisibleArea(point3); + + let diff = point2.x - point3.x; + point2.y = point2.y - diff; + point3.y = point3.y - diff; + + point2 = viewPort.fitIntoVisibleArea(point2); + point3 = viewPort.fitIntoVisibleArea(point3); + + browserCanvasContext.beginPath(); + + browserCanvasContext.moveTo(point1.x, point1.y); + browserCanvasContext.lineTo(point2.x, point2.y); + browserCanvasContext.lineTo(point3.x, point3.y); + browserCanvasContext.lineTo(point1.x, point1.y); + + browserCanvasContext.closePath(); + + if (isCurrentRecord === false) { + browserCanvasContext.fillStyle = 'rgba(255, 255, 255, ' + opacity + ')'; + } else { + browserCanvasContext.fillStyle = 'rgba(255, 233, 31, ' + opacity + ')'; /* highlight the current record */ + } + + browserCanvasContext.fill(); + + browserCanvasContext.strokeStyle = 'rgba(130, 9, 9, ' + opacity + ')'; + browserCanvasContext.stroke(); + + } + + /* Draw a green triangle on buy */ + + if (record.lastBuyRate > 0) { + + opacity = '0.3'; + + let point1 = { + x: record.date, + y: record.lastBuyRate + }; + + let point2 = { + x: record.date + timePeriod / 7 * 2, + y: record.lastBuyRate + }; + + let point3 = { + x: record.date - timePeriod / 7 * 2, + y: record.lastBuyRate + }; + + point1 = timeLineCoordinateSystem.transformThisPoint(point1); + point1 = transformThisPoint(point1, thisObject.container); + point1 = viewPort.fitIntoVisibleArea(point1); + + point2 = timeLineCoordinateSystem.transformThisPoint(point2); + point2 = transformThisPoint(point2, thisObject.container); + point2 = viewPort.fitIntoVisibleArea(point2); + + point3 = timeLineCoordinateSystem.transformThisPoint(point3); + point3 = transformThisPoint(point3, thisObject.container); + point3 = viewPort.fitIntoVisibleArea(point3); + + let diff = point2.x - point3.x; + point2.y = point2.y + diff; + point3.y = point3.y + diff; + + point2 = viewPort.fitIntoVisibleArea(point2); + point3 = viewPort.fitIntoVisibleArea(point3); + + browserCanvasContext.beginPath(); + + browserCanvasContext.moveTo(point1.x, point1.y); + browserCanvasContext.lineTo(point2.x, point2.y); + browserCanvasContext.lineTo(point3.x, point3.y); + browserCanvasContext.lineTo(point1.x, point1.y); + + browserCanvasContext.closePath(); + + if (isCurrentRecord === false) { + browserCanvasContext.fillStyle = 'rgba(255, 255, 255, ' + opacity + ')'; + } else { + browserCanvasContext.fillStyle = 'rgba(255, 233, 31, ' + opacity + ')'; /* highlight the current record */ + } + + browserCanvasContext.fill(); + + browserCanvasContext.strokeStyle = 'rgba(27, 105, 7, ' + opacity + ')'; + browserCanvasContext.stroke(); + + } + + + /* Since there is at least some point plotted, then the profile should be visible. */ + + thisObject.payload.profile.visible = true; } - /* Draw a red inverted triangle on sell */ + /* Draw the lines connecting plot elements. */ - if (record.lastSellRate > 0) { + let lines = plotLines[j]; - opacity = '0.3'; + for (let i = 0; i < lines.length; i++) { + + let line = lines[i]; + + opacity = '0.2'; let point1 = { - x: record.date, - y: record.lastSellRate + x: line.x1, + y: line.y1 }; let point2 = { - x: record.date + timePeriod / 7 * 2, - y: record.lastSellRate - }; - - let point3 = { - x: record.date - timePeriod / 7 * 2, - y: record.lastSellRate + x: line.x2, + y: line.y2 }; point1 = timeLineCoordinateSystem.transformThisPoint(point1); @@ -538,201 +748,76 @@ point2 = transformThisPoint(point2, thisObject.container); point2 = viewPort.fitIntoVisibleArea(point2); - point3 = timeLineCoordinateSystem.transformThisPoint(point3); - point3 = transformThisPoint(point3, thisObject.container); - point3 = viewPort.fitIntoVisibleArea(point3); - - let diff = point2.x - point3.x; - point2.y = point2.y - diff; - point3.y = point3.y - diff; - - point2 = viewPort.fitIntoVisibleArea(point2); - point3 = viewPort.fitIntoVisibleArea(point3); - browserCanvasContext.beginPath(); browserCanvasContext.moveTo(point1.x, point1.y); browserCanvasContext.lineTo(point2.x, point2.y); - browserCanvasContext.lineTo(point3.x, point3.y); - browserCanvasContext.lineTo(point1.x, point1.y); browserCanvasContext.closePath(); - if (isCurrentRecord === false) { - browserCanvasContext.fillStyle = 'rgba(255, 255, 255, ' + opacity + ')'; + if (line.type === "sell") { + + browserCanvasContext.strokeStyle = 'rgba(130, 9, 9, ' + opacity + ')'; + } else { - browserCanvasContext.fillStyle = 'rgba(255, 233, 31, ' + opacity + ')'; /* highlight the current record */ + + browserCanvasContext.strokeStyle = 'rgba(27, 105, 7, ' + opacity + ')'; + } - browserCanvasContext.fill(); - - browserCanvasContext.strokeStyle = 'rgba(130, 9, 9, ' + opacity + ')'; browserCanvasContext.stroke(); } - /* Draw a green triangle on buy */ + /* Now we calculate the anchor position of notes. */ - if (record.lastBuyRate > 0) { - opacity = '0.3'; + for (let i = 0; i < notes.length; i++) { - let point1 = { - x: record.date, - y: record.lastBuyRate + let note = notes[i]; + + opacity = '0.2'; + + note.position = { + x: note.date, + y: note.rate }; - let point2 = { - x: record.date + timePeriod / 7 * 2, - y: record.lastBuyRate - }; + note.position = timeLineCoordinateSystem.transformThisPoint(note.position); + note.position = transformThisPoint(note.position, thisObject.container); - let point3 = { - x: record.date - timePeriod / 7 * 2, - y: record.lastBuyRate - }; - - point1 = timeLineCoordinateSystem.transformThisPoint(point1); - point1 = transformThisPoint(point1, thisObject.container); - point1 = viewPort.fitIntoVisibleArea(point1); - - point2 = timeLineCoordinateSystem.transformThisPoint(point2); - point2 = transformThisPoint(point2, thisObject.container); - point2 = viewPort.fitIntoVisibleArea(point2); - - point3 = timeLineCoordinateSystem.transformThisPoint(point3); - point3 = transformThisPoint(point3, thisObject.container); - point3 = viewPort.fitIntoVisibleArea(point3); - - let diff = point2.x - point3.x; - point2.y = point2.y + diff; - point3.y = point3.y + diff; - - point2 = viewPort.fitIntoVisibleArea(point2); - point3 = viewPort.fitIntoVisibleArea(point3); - - browserCanvasContext.beginPath(); - - browserCanvasContext.moveTo(point1.x, point1.y); - browserCanvasContext.lineTo(point2.x, point2.y); - browserCanvasContext.lineTo(point3.x, point3.y); - browserCanvasContext.lineTo(point1.x, point1.y); - - browserCanvasContext.closePath(); - - if (isCurrentRecord === false) { - browserCanvasContext.fillStyle = 'rgba(255, 255, 255, ' + opacity + ')'; + if (note.position.x < (viewPort.visibleArea.bottomRight.x) * (-1) || note.position.x > (viewPort.visibleArea.bottomRight.x) * (2)) { + note.visible = false; } else { - browserCanvasContext.fillStyle = 'rgba(255, 233, 31, ' + opacity + ')'; /* highlight the current record */ + note.visible = true; } - browserCanvasContext.fill(); - - browserCanvasContext.strokeStyle = 'rgba(27, 105, 7, ' + opacity + ')'; - browserCanvasContext.stroke(); - } + if (notesChangedEventRaised === false) { - /* Since there is at least some point plotted, then the profile should be visible. */ + thisObject.container.eventHandler.raiseEvent("Notes Changed", notes); + thisObject.payload.notes = notes; - thisObject.payload.profile.visible = true; - } - - /* Draw the lines connecting plot elements. */ - - let lines = plotLines[j]; - - for (let i = 0; i < lines.length; i++) { - - let line = lines[i]; - - opacity = '0.2'; - - let point1 = { - x: line.x1, - y: line.y1 - }; - - let point2 = { - x: line.x2, - y: line.y2 - }; - - point1 = timeLineCoordinateSystem.transformThisPoint(point1); - point1 = transformThisPoint(point1, thisObject.container); - point1 = viewPort.fitIntoVisibleArea(point1); - - point2 = timeLineCoordinateSystem.transformThisPoint(point2); - point2 = transformThisPoint(point2, thisObject.container); - point2 = viewPort.fitIntoVisibleArea(point2); - - browserCanvasContext.beginPath(); - - browserCanvasContext.moveTo(point1.x, point1.y); - browserCanvasContext.lineTo(point2.x, point2.y); - - browserCanvasContext.closePath(); - - if (line.type === "sell") { - - browserCanvasContext.strokeStyle = 'rgba(130, 9, 9, ' + opacity + ')'; - - } else { - - browserCanvasContext.strokeStyle = 'rgba(27, 105, 7, ' + opacity + ')'; - - } - - browserCanvasContext.stroke(); - - } - - /* Now we calculate the anchor position of notes. */ - - - for (let i = 0; i < notes.length; i++) { - - let note = notes[i]; - - opacity = '0.2'; - - note.position = { - x: note.date, - y: note.rate - }; - - note.position = timeLineCoordinateSystem.transformThisPoint(note.position); - note.position = transformThisPoint(note.position, thisObject.container); - - if (note.position.x < (viewPort.visibleArea.bottomRight.x) * (-1) || note.position.x > (viewPort.visibleArea.bottomRight.x) * (2)) { - note.visible = false; - } else { - note.visible = true; + notesChangedEventRaised = true; } } - if (notesChangedEventRaised === false) { + /* + + We replace the coordinate of the profile point so that whoever has a reference to it, gets the new position. + We will use the last point plotted on screen as the profilePoint. + + */ - thisObject.container.eventHandler.raiseEvent("Notes Changed", notes); - thisObject.payload.notes = notes; + thisObject.payload.profile.position.x = point.x; + thisObject.payload.profile.position.y = point.y; - notesChangedEventRaised = true; - } + } catch (err) { + if (ERROR_LOG === true) { logger.write("[ERROR] plotChart -> err = " + err); } } - - /* - - We replace the coordinate of the profile point so that whoever has a reference to it, gets the new position. - We will use the last point plotted on screen as the profilePoint. - - */ - - thisObject.payload.profile.position.x = point.x; - thisObject.payload.profile.position.y = point.y; } - } From 51c87278f1a9010fb26fb512dfd818e867b70e2c Mon Sep 17 00:00:00 2001 From: Luis Fernando Molina Date: Mon, 7 May 2018 15:14:15 +0200 Subject: [PATCH 31/54] Minor Bug fix --- .vs/Plotters-Trading/v15/.suo | Bin 27136 -> 27136 bytes History.js | 6 +++++- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/.vs/Plotters-Trading/v15/.suo b/.vs/Plotters-Trading/v15/.suo index dee52a83bba925c37e15b914f76551ce02c1a6e8..9e7c673ee106c2753452b5d084649aa750e26a2c 100644 GIT binary patch delta 77 zcmZp;!q{+yaYGIhE5q9b9xR&+nSL{~3as1f24u2jItngiWPpRYAok|h?(b!>38#v( F003=y6Bqyh delta 77 zcmZp;!q{+yaYGIhYlF(8^~{?KnSL{~PEZZH%CxzVEz?o3myrPuOqm%N7&pIme=jTO S0vA*|kPKu;Z+@LB$^rm;rxUvX diff --git a/History.js b/History.js index 6ad071132..c63d6cbc1 100644 --- a/History.js +++ b/History.js @@ -407,7 +407,11 @@ if (INTENSIVE_LOG === true) { logger.write("[INFO] plotChart -> Entering function."); } - let point; + let point = { + x: 0, + y: 0 + }; + let history; for (let j = 0; j < plotElements.length; j++) { From 9c3945cb51995d698972e9fca26a82dea9562b6e Mon Sep 17 00:00:00 2001 From: Luis Fernando Molina Date: Mon, 7 May 2018 17:25:55 +0200 Subject: [PATCH 32/54] Logo Added --- .vs/Plotters-Trading/v15/.suo | Bin 27136 -> 29696 bytes Competition.png | Bin 0 -> 10340 bytes this.plotter.config.json | 7 +++++++ 3 files changed, 7 insertions(+) create mode 100644 Competition.png diff --git a/.vs/Plotters-Trading/v15/.suo b/.vs/Plotters-Trading/v15/.suo index 9e7c673ee106c2753452b5d084649aa750e26a2c..c65671a12ef50b23edf24f37a4b2818fa3f5a6cb 100644 GIT binary patch delta 391 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%0A$U{8`$w7Keg*VP!&&G|7kx}iPK~DZycY0H>2z8 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 Date: Mon, 7 May 2018 17:37:57 +0200 Subject: [PATCH 33/54] Banner Added --- Live.png | Bin 0 -> 10193 bytes this.plotter.config.json | 7 +++++++ 2 files changed, 7 insertions(+) create mode 100644 Live.png diff --git a/Live.png b/Live.png new file mode 100644 index 0000000000000000000000000000000000000000..71f56528665269cdb6fdc6d3575d51dbfe0f43b5 GIT binary patch literal 10193 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 literal 0 HcmV?d00001 diff --git a/this.plotter.config.json b/this.plotter.config.json index 0e61e62da..1012fe0b2 100644 --- a/this.plotter.config.json +++ b/this.plotter.config.json @@ -22,6 +22,13 @@ "description": "Plots trading history.", "profilePicture": "Competition.png", "panels": [] + }, + { + "codeName": "LiveHistory", + "moduleName": "History", + "description": "Plots trading history.", + "profilePicture": "Live.png", + "panels": [] } ] } \ No newline at end of file From a03c2ea80df1d0ca7c9f966712c3d973d2604acd Mon Sep 17 00:00:00 2001 From: Luis Fernando Molina Date: Mon, 7 May 2018 17:39:30 +0200 Subject: [PATCH 34/54] Name Changes --- .vs/Plotters-Trading/v15/.suo | Bin 29696 -> 27136 bytes History.png => Backtest.png | Bin this.plotter.config.json | 4 ++-- 3 files changed, 2 insertions(+), 2 deletions(-) rename History.png => Backtest.png (100%) diff --git a/.vs/Plotters-Trading/v15/.suo b/.vs/Plotters-Trading/v15/.suo index c65671a12ef50b23edf24f37a4b2818fa3f5a6cb..2192c7f9534de41979cddd6f983febef0d132a10 100644 GIT binary patch delta 735 zcmX|-%TE(g6o>D*ot82TSWBg)6jO+X+LX3Df+3&`?}QjD#u!bZfP|LD7l9cQ!h!); z#z&yXxN+r}xJK{RMHBu2F`{wl!Wg42W#NW;ZlzB0%{{Ms&OJZtJ6QX$m275}&%>CD zY#>@NTZzGw<-Q-STqZy%tZQbk;Kt-(D!;P>GNt~ydmn4;*(M_>^T z9BtRD$*m()!c9=ilI(ko?Bj%&s3mAD(+D3SA0z7mM`zQ~DPtkBPZABnRL-iN7@6&a zY$?IFY6w5OHTw%ft#{5S43(+mmet&476{wRO0G2U^Nq zc~NP$j&eK6@nbZGnXJ2z^NO+f1K?wT?-L2TTfxa(8q=Mv z@C-Kw*Zo6mj?J^1q|XBBWUx3}Vs}^$pLbsM(*)MXy6L~hlB}2Yup!n(Q#ZN>gr3&9 z-OthL>rtmJ-MVWS3(G6*Se(|y&UqK$<8f7Z=5|2ngGC1p4wz_-2GBDQ5pAOZa5hlW zDE=JZEEn#L+1#G+p>;cnXSfeXGW}K8-pLIawq$!z&qQ!D8?a}p(8^d?mkWwu_7%L; Q7Xgd8Q}~I8P|sU`0Xu=(3IG5A delta 809 zcmb7BO=uHA6rQ)4)?~?FlT;S7DGBu_NRTL^B2A1~;}R+xL7}xF_MmBUwGoW8b?_h_ zij=&AC!wzBMGu-m5b+SG2X95J*P<8kpa&rbK`_2CX+coXfp6x`H{aX$y|-c=#3xuz z$28VoLB=?RK={$^b`|SFsD+=-dVM8n6s&BvS40@r-&8Yyf z9)gdc^40QFJVXc)+ypOy$}pV}BWx!qozXwd{;9Yy#Uq4>yuuIb^09sgJfO@C6EIjy z%DQ(6TE;5TO0Q}w8aqQa8Oxvuz2>UuFR~t9a&~AfBd%dQo#eZ=zG2#wuliQLdik*; zju)=?nj5h}1z3;U9#FRT_GBsfZ9)Jfun|#X$TWv7t|rhcW*6O~bWx*FgzVT}&DqJF zv)oB(_-8O9b;Wcf9Sw57|BP*+~Ni)Snr} zhIM08E^nT?rs0$oz(9F4HAl~C)=$_8c9fOaIX1^GvCFiVh-FN>3cKg;el^EdUOmEl zN77Cq;+kC3@k}&>?Q#;UWusXU&V_AKRN8>+RTE1!H$JbL!P{%MF8-EYtflYgs(_*< ba3-2Vkv~14`i}g~ULyW4mj37m{@>3}TJ`vL diff --git a/History.png b/Backtest.png similarity index 100% rename from History.png rename to Backtest.png diff --git a/this.plotter.config.json b/this.plotter.config.json index 1012fe0b2..c31964e7a 100644 --- a/this.plotter.config.json +++ b/this.plotter.config.json @@ -10,10 +10,10 @@ "panels": [] }, { - "codeName": "History", + "codeName": "BackTestHistory", "moduleName": "History", "description": "Plots trading history.", - "profilePicture": "History.png", + "profilePicture": "BackTest.png", "panels": [] }, { From 54cefb287219da11c21cf38b8c2489bf829a98af Mon Sep 17 00:00:00 2001 From: Luis Fernando Molina Date: Mon, 7 May 2018 17:49:30 +0200 Subject: [PATCH 35/54] typo --- .vs/Plotters-Trading/v15/.suo | Bin 27136 -> 29696 bytes this.plotter.config.json | 2 +- 2 files changed, 1 insertion(+), 1 deletion(-) diff --git a/.vs/Plotters-Trading/v15/.suo b/.vs/Plotters-Trading/v15/.suo index 2192c7f9534de41979cddd6f983febef0d132a10..ead93f1ff8c537245a67c1bcac0f9bd8fcd70997 100644 GIT binary patch delta 312 zcmZp;!r1VFae{#?69W_oFfgzHnT$aE@Bjb*AW`PYjG4k46L{D-4Yr$nk$QHSQDbu{ zlRqO1P%Xn`o=hFajLBcw%^6id>Lw+m}&DGz8Op$yg-#aAk_ky z8k0)|dlvC=Z4z=}WZ{IGFu6pyXOWc9A~B{-dLB$H98jg3OAIbZPCmk9u(?F;0waqm zRQ2W(pYx2Ij6y)J7F6Zr5|IE7X&^@hCh*0tVRDJ6KPLmw7ysFyqKtZ*zxvrwBco_&j_41_H9Hrq3m=@{ckj99a*Z!AUg07KX4tqXdz)x1iB0GW{HrNRqV6iQMN;Ux7*l3>wkLW0+x-h^wCix85%`5I^ zPI04Pl=?#iR^@(0h$#vYAwJ|w^vO=1rm!o-g+1W;Ys-@;5E}7QS_zdE4Yp8Mjv<8& zCBg0F6#|`EKWv)1<4mq}vr3<0Dl^x43Dk_h~ diff --git a/this.plotter.config.json b/this.plotter.config.json index c31964e7a..08051dd52 100644 --- a/this.plotter.config.json +++ b/this.plotter.config.json @@ -10,7 +10,7 @@ "panels": [] }, { - "codeName": "BackTestHistory", + "codeName": "BacktestHistory", "moduleName": "History", "description": "Plots trading history.", "profilePicture": "BackTest.png", From d0fdb3d30298272046fe04a82272782251ae09b1 Mon Sep 17 00:00:00 2001 From: Luis Fernando Molina Date: Mon, 7 May 2018 17:51:14 +0200 Subject: [PATCH 36/54] typo 2 --- this.plotter.config.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/this.plotter.config.json b/this.plotter.config.json index 08051dd52..ee9ac5a4e 100644 --- a/this.plotter.config.json +++ b/this.plotter.config.json @@ -13,7 +13,7 @@ "codeName": "BacktestHistory", "moduleName": "History", "description": "Plots trading history.", - "profilePicture": "BackTest.png", + "profilePicture": "Backtest.png", "panels": [] }, { From c32d99b82b6eaa0b68d7bb62727dd9d723c456b4 Mon Sep 17 00:00:00 2001 From: Luis Fernando Molina Date: Mon, 7 May 2018 19:22:17 +0200 Subject: [PATCH 37/54] Revert "typo 2" This reverts commit d0fdb3d30298272046fe04a82272782251ae09b1. --- this.plotter.config.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/this.plotter.config.json b/this.plotter.config.json index ee9ac5a4e..08051dd52 100644 --- a/this.plotter.config.json +++ b/this.plotter.config.json @@ -13,7 +13,7 @@ "codeName": "BacktestHistory", "moduleName": "History", "description": "Plots trading history.", - "profilePicture": "Backtest.png", + "profilePicture": "BackTest.png", "panels": [] }, { From 02c3c18f53330b5fd08093b92b1f92764a1ede99 Mon Sep 17 00:00:00 2001 From: Luis Fernando Molina Date: Mon, 7 May 2018 19:22:23 +0200 Subject: [PATCH 38/54] Revert "Revert "typo 2"" This reverts commit c32d99b82b6eaa0b68d7bb62727dd9d723c456b4. --- this.plotter.config.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/this.plotter.config.json b/this.plotter.config.json index 08051dd52..ee9ac5a4e 100644 --- a/this.plotter.config.json +++ b/this.plotter.config.json @@ -13,7 +13,7 @@ "codeName": "BacktestHistory", "moduleName": "History", "description": "Plots trading history.", - "profilePicture": "BackTest.png", + "profilePicture": "Backtest.png", "panels": [] }, { From 93b64f88f6d2338eca42b1db52975aa461d982db Mon Sep 17 00:00:00 2001 From: Luis Fernando Molina Date: Mon, 7 May 2018 19:28:49 +0200 Subject: [PATCH 39/54] Rollback to previous config --- .vs/Plotters-Trading/v15/.suo | Bin 29696 -> 27136 bytes Backtest.png => History.png | Bin this.plotter.config.json | 18 ++---------------- 3 files changed, 2 insertions(+), 16 deletions(-) rename Backtest.png => History.png (100%) diff --git a/.vs/Plotters-Trading/v15/.suo b/.vs/Plotters-Trading/v15/.suo index ead93f1ff8c537245a67c1bcac0f9bd8fcd70997..5f0edd6877da75c0379834602c2770782f6562c7 100644 GIT binary patch delta 343 zcmZp8!Pszxae{#?0}Kc-Ft7pHj6nSF|Ns9WVaCafnZg?r-Y`z~VN+l&Fg-7?vAK|m zossdyyfT?5 zQ)hCC(1poIm<%SD2wz}P0Z9S{HJo(>=1FQU93Vr5;eu*CjGN33GfqCNYP(6} zJU64u<_pGaSs15Gc68~V%x@XLIma@Qmz5K!UTAWqN7H0!53b1*>@_C0xj*6q3c>*+ K!{#!NE=2%bO<=qL delta 347 zcmZp;!r1VFae{#?69W_oFfgzHnT$aE@Bjb*AW`PYjG4k46W%Z~GEZJ8tH2T?F;Q}J zArm{}w60vnR_h9!^Fu8^{MMED^ji z*+b$FhYC Date: Tue, 8 May 2018 12:21:12 +0200 Subject: [PATCH 40/54] Pic Replaced --- History.js | 2 +- History.png | Bin 6492 -> 6335 bytes 2 files changed, 1 insertion(+), 1 deletion(-) diff --git a/History.js b/History.js index c63d6cbc1..869f44cb7 100644 --- a/History.js +++ b/History.js @@ -1,7 +1,7 @@ function newAAMastersPlottersTradingHistory() { const MODULE_NAME = "AAMasters Plotters Trading History"; - const INFO_LOG = true; + const INFO_LOG = false; const INTENSIVE_LOG = false; const ERROR_LOG = true; const logger = newDebugLog(); diff --git a/History.png b/History.png index 248e8ba6026027d2841cf2515a1e6ccf3f44a27d..a6809adfdc24ab88f48df5711d4555c8f5ba4e68 100644 GIT binary patch literal 6335 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 literal 6492 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 From b765c811cdba30f11d0b16eb8aa841236de28bc7 Mon Sep 17 00:00:00 2001 From: Luis Fernando Molina Date: Tue, 8 May 2018 21:04:23 +0200 Subject: [PATCH 41/54] Adjust in seen notes --- History.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/History.js b/History.js index 869f44cb7..592f2846f 100644 --- a/History.js +++ b/History.js @@ -790,7 +790,7 @@ note.position = timeLineCoordinateSystem.transformThisPoint(note.position); note.position = transformThisPoint(note.position, thisObject.container); - if (note.position.x < (viewPort.visibleArea.bottomRight.x) * (-1) || note.position.x > (viewPort.visibleArea.bottomRight.x) * (2)) { + if (note.position.x < (viewPort.visibleArea.bottomRight.x / 2) * (-1) || note.position.x > (viewPort.visibleArea.bottomRight.x) * (1.5)) { note.visible = false; } else { note.visible = true; From 784ef8debd4cd3ea1ec2baa5a8e5ec43754a4d8d Mon Sep 17 00:00:00 2001 From: Luis Fernando Molina Date: Wed, 9 May 2018 08:54:12 +0200 Subject: [PATCH 42/54] Scale Adjusted --- History.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/History.js b/History.js index 592f2846f..a8cf7e443 100644 --- a/History.js +++ b/History.js @@ -336,7 +336,7 @@ let maxValue = { x: MAX_PLOTABLE_DATE.valueOf(), - y: nextPorwerOf10(USDT_BTC_HTH) + y: nextPorwerOf10(USDT_BTC_HTH) / 4 // TODO: This 4 is temporary }; From eb18c3ffd461dfec2b0aec10e81b7eac61513ce7 Mon Sep 17 00:00:00 2001 From: Luis Fernando Molina Date: Sat, 12 May 2018 18:27:30 +0200 Subject: [PATCH 43/54] Cleaning --- .gitignore | 10 ++++++++++ .vs/AAMariam-Plotter/v15/.suo | Bin 18432 -> 0 bytes .vs/AAOlivia-Plotter/v15/.suo | Bin 17920 -> 0 bytes .vs/Plotters-Trading/v15/.suo | Bin 27136 -> 0 bytes bin/Microsoft.NodejsTools.WebRole.dll | Bin 32992 -> 0 bytes ...riam-Plotter.njsproj.CoreCompileInputs.cache | 1 - ...AMariam-Plotter.njsproj.FileListAbsolute.txt | 3 --- ...lotter.njsprojResolveAssemblyReference.cache | Bin 2216 -> 0 bytes ...ivia-Plotter.njsproj.CoreCompileInputs.cache | 1 - ...AOlivia-Plotter.njsproj.FileListAbsolute.txt | 3 --- ...lotter.njsprojResolveAssemblyReference.cache | Bin 2216 -> 0 bytes .../Project.njsproj.CoreCompileInputs.cache | 1 - obj/Debug/Project.njsproj.FileListAbsolute.txt | 3 --- ...roject.njsprojResolveAssemblyReference.cache | Bin 2216 -> 0 bytes 14 files changed, 10 insertions(+), 12 deletions(-) create mode 100644 .gitignore delete mode 100644 .vs/AAMariam-Plotter/v15/.suo delete mode 100644 .vs/AAOlivia-Plotter/v15/.suo delete mode 100644 .vs/Plotters-Trading/v15/.suo delete mode 100644 bin/Microsoft.NodejsTools.WebRole.dll delete mode 100644 obj/Debug/AAMariam-Plotter.njsproj.CoreCompileInputs.cache delete mode 100644 obj/Debug/AAMariam-Plotter.njsproj.FileListAbsolute.txt delete mode 100644 obj/Debug/AAMariam-Plotter.njsprojResolveAssemblyReference.cache delete mode 100644 obj/Debug/AAOlivia-Plotter.njsproj.CoreCompileInputs.cache delete mode 100644 obj/Debug/AAOlivia-Plotter.njsproj.FileListAbsolute.txt delete mode 100644 obj/Debug/AAOlivia-Plotter.njsprojResolveAssemblyReference.cache delete mode 100644 obj/Debug/Project.njsproj.CoreCompileInputs.cache delete mode 100644 obj/Debug/Project.njsproj.FileListAbsolute.txt delete mode 100644 obj/Debug/Project.njsprojResolveAssemblyReference.cache diff --git a/.gitignore b/.gitignore new file mode 100644 index 000000000..ee165f325 --- /dev/null +++ b/.gitignore @@ -0,0 +1,10 @@ + +.vs/* +.obj/* + +.bin/* + +*.config +*.log +*.cache +node_modules/* \ No newline at end of file diff --git a/.vs/AAMariam-Plotter/v15/.suo b/.vs/AAMariam-Plotter/v15/.suo deleted file mode 100644 index c558203f3923cbf335a6466f815322f523b8867d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 18432 zcmeHO&2Jk;6d$J_wB?&Z3vGcEN-3pl?Amd%DFvLkp%sld6d>(q^-UH2n2 zkq|-%apk}fA#ng9Bsd}d0S;VR!HokdATAs##EAq&hRAjcJ{1lLNBl!O%5T^Yro5FCmgt^T>pQZiZgQp?d ze_fX-y_SSsH$%4nuIYzu|Lk`k`sla+PWxvY!Wy)vAD|u5pWFpp2V4)NU+4V|INu8- z|8(CR?-yMWIDcLSdX?g47RIPe8v0+ti&HpX0tbx$ zE`XmY&*+b_OJ9usk^a+f|1+pdTO%;;WRz(l_A4L`90T1lt}US=Qv-Zd#VB}Vd~V2N zLn_0dPuo-KC|~Mvpk1gcIlPyWK39A5Nzk7aMclmz4l3ZI1ga%Ty+KvArVaK<`={;u z?LT9_wG zC_&m6Z{eadeYO5s)dhX0{EtK1xaulE=L}%8*0<8QW`59r*>Cop(EPOZRX6m#)}uQ? zpK~1Nv!$S)gH$eHmgC&k3Y7kFo(@9)AV$3?Wj_ngSH@_JNsHiUn6N)Dp#IU9F=h-x ze*_~x1^-X|ufXEydk)w1p_AP!z99du*Z;H?#tnql_RoC~`h_Fd6X@jq7>jgIpYs*{ zCBd!ls_)znaq~uQ=>MIN0e!|9);Gfc zOZjuX5M=zR-={$HG=9{$lhWf(AqwCe=nee=?4RoxC4V>l5%6GuhqI7%1-8LCw-X<` z0?_ANHC^kPn?C&w;|?#qQ<9XH>ve4M+#*Kj$75f4S+~ zl&FFBPFxm}n8WYhcFZ<2D6P(Z5l^L%p{de|k9OKR?%+|y>Y?I?Zi_s{; zD>4>fl+>&ZLFkh&`T)WtXv~3V&-tFEF2{P5zVc&1`K0{c0FH`bkr!&kWubf+_D6q|2R3XmFXug2C|=nbeT5`(Bv*j$?on4v85XL?mHqx zd8wG;Do4c>^N86g!Q+rT2kKw~6Rh*6)vr32oNZW^pkbvpC`N=1Tgc+5BXZzt(y%aI zr|{EJBZsRYv4}QBc=rj|3$3UMo13exI)vDd96Vv4)R5*nDsE@&H;z_iv@N;bqv|-{ zlt%r_;71o3aGAn>X%@U_;Bp9e$ZL1}$9v@8-rXXH>*T&~n7r*n-@@+gG59s^&vDn% z5DTC%i;Q_cM)xQ*Dvr3GD_ZVeoDEmh>Je)Su8i4!0&QG&y1u7vN>&RC^M#|2S;=*tLtN0B0ZYbQz?Bg zmmOMM$Y#e2W~p#aJ6f((tA-h$ow4T3%FM#(aQ?Vum{$Jq`I42lD(B59BX1gW6)W#< zlRsFpsugoSK4UE`Tu!EQ$w57n)W!}BB(-!VozwJWGO3NGvt!9*ZZN0o*~R7HGG|l^ zrLv{CEZSU78#b3ko6D(mVLF*C4i>%WLfHS8{bt_@5Q8Vsx2Q@h zVE;eH{r{l*FJArUEPT7~|Et_@knvvu`~O|*KYfMTe^N2J9S2+W+{YormC^pc@)GUO zx556u%zr!y7X9jf$ov2D+k@cy|2^mbWBmSy`s}y=+fg^l|3e6XF!KM5+q=oXJM;gI zRi2&oi1I&oT>hu)`NtW5xyL`s|ET=a9h3i&`M)UtBi(8J5aoaBqUc!QE>o2Mu|=eI z+&T)(^)Sl+v`PF$`5)}ANBJL`OQ-x*l>g~1`__oxqWn*k|5?t=TA#=*Wuhv)6ySzN z)-V$+*%+|do`SJ=u#h>G(2P`iKuhl(8q)MkaatQN3ezb)Z5XMH9#15anRI5s6=&d2 zwajyT@3{RV%KgA)5qtMJ%?*tvUCFQKW+90E7sqnq&sv$gxc2uMC@dSieuXQ);1Hf! zMfUIYjY0^D_=jVp|3>*`U}XQTJ`HKOjS$4Xa_xTyzEW!b2dITf<%IkME{X4%67_$| zI5f{uqz9Z`vad&5eYa=-cWvoto`5{~k3jodfBRcO`%6Jbx9i1kw_bho!{2}V>;2b0 P9{;`k(|h#?cSzwsK4(8n diff --git a/.vs/AAOlivia-Plotter/v15/.suo b/.vs/AAOlivia-Plotter/v15/.suo deleted file mode 100644 index 781901c30705ef98ed61f460e4e1eee3119002de..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 17920 zcmeHOOKclO7#;^&+VU)g@`kjO@~VwpJ9ajOHjdr!P^(038XhtS6K{f3H;%kcXlWvW zgb?C}xN$*9NPrMRNL+g0f&@Zbio}6yIUp_w2?-%Cw0z&}jy-m>>s>$6Lj6bo&g|~Y z{{Q^1`De!Y;q2CPAAE7=&!P$Ti>t)>3!BA8?RiM6i<^YlihDjgf8oLfzG5BKKKzFy za72{xR~3Wepjbdz5vQn1->_Y5sOkLb7QIFvIPm)9=Rbz7L%UHL4`31$%VJ(U4eGO~ z9TX?+7e24s#Xv|Gx1VlVG=lj`Q1nT6QIx&kVPJ7I_=zwU1Fd%e)8egPJey_ zZq7Q+G$EEir6h_NKXFc@oW+xh-f@jO=!fW|w*mdqH_-Mk=UX?U{6`m{Q{Uu#ZyQQ} z|5o4@;PpWAe123$nLx+61F?f?7NGvJMjMY7Hux>)qm1033Su{Z-E{? z;hRLw|6g+)Q2F0_`hOZscG3Ssv|*(W&+$7iFDL(3d~X16j04J->Hn-#r}Y18fNuV; zzQIz(0M^-G#UxC{6Ia5wNl;6uQNfsX(m1?~Zcff3+iz$h>V+zX5Y z6Tl&$qOZykJlh9+Tzhu_^-=A9{Um;QQ5r+WQx?a?31mAJlz#Ibh)%-Y$bUkpDZh6f zdltiZOWhKtK-U7@L&$Y3WI{*9%Q6S6iW!+1S#~qmEAyWLyrmsdvaSua7b(;k-w4y7 zIwfUL5-*`V2@aV5ErXw#mf4>WJ3*g05p!C<^pj|-a%JY7%rYy;{qo2I$3eG*d#jci zo8Y4=GT@E*xhb!8sf>U=eQz)TefkBOOUQs4HDEy!MST4gS4yf!W7$srtJ6P*@i6Po zivp+@nnqn8XCu}69pqn|d;Q8k2>n*;k=>9#V;tjIFX(3>m1RUZ#2~NJ zg>}t1Qm4&R3l&7zqtHo7dSFpnUIZR$Yl)V)B(0GA>~BNJM;LHC)obweAe(3A|HwMq2 zLHwVC)!BAcs99PT@3;#00{Wk#?RWf)*UTFT&33NhEV(I(3G4|}AtA=zwPg`$!~Qu} zFjpd|^^YCpt=ibR9%|-|+)z(CBr$&GSYj-PY2nt!qw8)w=R^2=56EJnM4C{V^s zFo~;$doKw@L7(}b(gCV1VFy}lMgJJ6Ga7l>0pu_B&v@c@{JQ-$%h=ZcEJi&C zsZ^u|+WMF5UUWhHmGqep`=!q{(K3@3zyz|6d2v|Uzp_0w$4?7pO5VWygKOEVfPU$7 zPsSk+*_z;B3H0Zrtj92B6Qe#3TPsUjs6q?6RW$OGXv6+VTgCro`ZgtIg7!{a8hk85 zKJ-9ZBA@C2`>)xa-|;hFRrars>@dd7EXElYdP!p(Xoo)eXAB@r zfyN>z(az~>969yR+>^55+#i*zAG>|?^%3Zw`sDh`@A!55ZZf7 zqt2p89P5;b)Nt=F2|7(?ltN70~reFFDJu3b-kH1d;6tvA1K?$wh0rUggpO^d( zL)Isxm7i+xx<;$3^P}=V?#=ieKV!v|^9kA^{oztUH)yL^rjMbMXZm+~T@Q6AeHF*r z<&*M%0hkdZA}7?0YoUG!{>ONf1J->p2cKj#U}lgLY5YyVLyB^}oX76WB<^^gWUpy+ zE!pZ+|L1-Wp7ZKVao#2p+TjIuwncn4bbNF9?=w$+^8VG|ziX_1tUkm**8=F*Hhpvo ziD)Z{Mi3q6A^Sz>f#+szbh$=SvWNRts8@;)J`f>Fy<#RKXZ8YYlk;~(O7IvYPenZy z#RRMWg==@-HN6k(gnB7&{ap^j(@OA|B4$0VcPh9p$*jQEu@Fzl{EoYr+y^)fGKNTs zG3Z}UL-61%{B|6uRgX;dD{mb8>Q9h7bD^bEQnUbJu_3RfWiV!%m*QzNkq>G z&akta!$8E#S zfcP+!9f{)abksfaVWd|Xp&6S9#nE2!%v@9;f z&ocI|%d@rFvw5dQaokuAwz2-^%;&cLUwi+nk*0q4P#g5Q_c7~yq5epKo3T)PJ-5yyULl(O1;`(>(w6&wtkU{AU+-DH?wPW{E-k7Kj^JG3;mX>IFPYSjOt9 zH@nA;`*zGi`C9>d|IXgMTj&|>X~>1YfU(c~6iwQ$4vZxP6+i4d|JRo%|hT|NO_lu6oh3fBw^%RQu;Yfsc&(=RcR(`A;Vv&_DliKbz{G z|9G86{U6SMf}gDP@+_r$r&P!)*XjJnjpyK!9T3?|A>81MZmD-k203i(xZ9q*xi^(h zz7!3c@x)L#v3GblY$OY_;UP0W8#fZB8BZFKXf&2gBv+azh1&)H&*g2k-oR`A%!J|p zl88O{$?KMSmq23gxLX&*{=BA*BI>(=Tsd*|OZXhBm`15TlP`LHdG0LZc>Cby|8=SR vJz4Mj|JuJ%sE3U%7^1G|4`FoA;6dO2y?+|g1+k~Ku=})A*M0rJ>;L}(48i4e diff --git a/.vs/Plotters-Trading/v15/.suo b/.vs/Plotters-Trading/v15/.suo deleted file mode 100644 index 5f0edd6877da75c0379834602c2770782f6562c7..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 27136 zcmeHQZEPE79lx~Q)^@yXZ0lYatCx+g+v2y_apJ7)=EQN^tyx2zrejODUF=KZ#PNA| zm$u$gi7%jiKp>3?zAynoLLjt>AtXSW5E6Vqd?|u`q(3^X6TDl3eMSv|IXceV=r_qrA_Nmu`~G zXDs`0eSMvem`ApkcF+u*kyQK{Qb3xJO1NrLg-hu>9gwc8u6e-YTjilE2M_=C4}G_w z-Y-96Rh|MyRa%lx0{c926VfG*R_Y%gkaqPsr@Q`XovRFFYS^J;o;2y_M=%nXF2Qt&E8C>rBz@lN(GFcu;9R)Mv3P9VuL*Kw>$nt zw3FXuHFg6o|8+KC=eei%;n^nu`vH3ae8lokBL67>$NX`?#{itqTLD~F*1N;Le%ijW z>~7@m0UQ7v1l$W?c|WfA0YdgY%e>N{t8NVU>{~CjHv|9A{U7;h{9kur{~yL$UF-Y* z-R|xGKJGoS>d1N~=l&PpyAIzXAK)G$e-h=+>-|m2opqSM(XRJd`x?OY0Xxs<4>|Jg zJ$o0P-3ho2a68~Z0C~#8fB`@d5C*WF2(D2;+`ebo5b_DYFkl4WZl85}sWt;7LyCgk z_FRz;sPl2&$nz-!n0EqY0%ZW{jxvCpzO}M*v3vM*+tGj{+V8qyS@paX=by3c&V{<9fo*KaT4Y zc777qCjqAcQ-IF_&H%E2X~0>)4B#B#DZu9ePXnF-%mU5>o&`Jycpf0eBCgao<^c=# zvjVP5fMq}tumUInR6rT93eW&LzyOGLc=eOU(2|PQSD@`^xcb$5fXYmFgL+6qTzBHL zN?U*C@R)1MG!48u@ScLMqhkbFY0=cd3@K-7MjThG1pTLN{cjEplD3&m~Gn`rifgC+DgCNm4)X3mwSs_+{YTV`7&~eV1CMhEqeei)!n z6*X9spS4*T?Lhw{ZP@6|wd?Kw-v00H|Bm;+$@gdj?Zo|m0{kYAKk}6e&N27|B;t*>`ddyA0r2n`dA&Mz`a|4( zV{f=l&XfRt+S;_M{f_@W)D`k4jd4=auGo_09Oi**ph_3fHx(36XgLEB;OBUVn+aLZ zlthiNEr46$KMU-n!d7&^`KK<*HT8?%Nq_D+w$^_hqh7$QXeI?(l+k!t1Hj*pN7R%3 z;t!+l1qxlH)6hDWq)C(h1?>qLKVw=jR=sAQ+<(-=se|~%A3|LlJ@kqq#;D_O24hyR z>h4}N!)%oc{cCp{_?`2A7Su+s8~3{caPNoK*e(5w}332>mT!&4X!`;KJ^*SgGY7qaR#41vnzVx zZ^rioo=)iRqyzsnq+S_P$I^B!9|YwuZGXXgBc}IBV64ABgz-O!B5}@9|FrR)lmDK9 z?4LF z%b*Gsv{CPEvA*N{Jlw(jA4CIRwi|KdC(kAAdD$JJ570l_mjARBg#YV|InS!8>k{vA zjGuSqI+~m`=|bRiUa5cYM*)4ne&?UIM~(jKcOI=j>Z1mzpW1)k<6Ii}+a5pr|1Lj} zy!g+MRjuhK`Om$0IsouH{ygdm`8NZ7d&;zbpMx)&p1uO~J;nA5k~+$mhv%RHh9vsC z-HH2;czL$!7k{h$*O>mDR$+Y);vLLCZFNC^Zu++{as926_!P!p1~;Vlla?q;oeB1D z+v`tznKa1c9N8o&k6u`d6NRuY-2Ww$3Nyefn^tl?SLy^m_Y3_+Oj)dX&bE5!bIt>s zhP8IvrJ<^4fc6>vB!>C@V_1LkbFMv;S?KXGf#+iWNq+$w{}OPM0(ozFWvsaffcl0! z=?K>_FVo&heJdyu?0*|fH`x`%P4K~k=f}&j9XXFFSsl4%Va!a z5PO(;uP~cwtHq*{BR%M$<4Oqxk_)8^W`V3#o*#VX8M|WEq`HB?ik?%oVqtC| zFvE?hmX5|l5&jJX##f65w$ss)vWg8@90*LU&J_zeQ0}z4tdx$<4G+shxuHZf8H+2C zk>vRS(YUi0CuDumkmrhug{uqx->U5K%YU8xuM7U)EyYjy*DCFF|F1c=*N2w(sUQ6O z_z%9d=eJ)=UjDwIWjfUxq?e!*C80NsA?ij{HFt5JbdS)KEKM>5S-u3lu8jT8DBlJZ z(0(JnyqPi=yP1U&nS%OcnU!v))L?w*^a6r)yoQ29w<(OsngQy~?$OeJ!>1>xPCEaB z)w`h3!=P@88nv7#5m)xrVw+YE4QY|>e*rKqjiSrq#7sy26!a(hvt|J`U1}C9L7S2% zdmN&d{ToButrG2Dp8Zgt^Sl2)V*bBP@t^JX|J6(8)>}nLbf^5b2+^XD1gw-Gtf^t! zl1hO~B+ar2O2@GYli(OJd=A5|qGfm4-aYjcW}Uh-R*#g$*gc-`TDF&leMaw;*qrbD zV||^L@KI3UAzYojX$Uyd=urlkn)Qt>6PN@q6McIG-}h<}d}_bc7XMVhp6FqucWVv% zPv8gk2JF$3f7Vw>o2^(w`DULFrqB)hpSILC+W&pD|N8-c`A^UO@7e#PS*GUxhaF@8 zo99pTDf*>%BJS$M{R4MthH9# zOk#s1izDNdQIZcC#g?1NPsZO*LLwF+7Yj{fq*Ic*@%xdHt?-9n#b0#cZAX4v#L>C@ zZq+wG^1D54C4^Jidik9K$yB5Ow3{ht-yy{AGoppj>x;-Sj?y{%kGfWW^Rr*$Uu&SG zcKSk&k&?RQYdB9;?FQRtv3FcuDa)Fo?WMONTX<1{Cb##MR!$MyIWqAAoQDOYA{ux; zx}_eH^QIempD;G}Fmp9_6Wx;Nwcp4;+^Q#QwxfU7P8`QUyL{_}nlv?}=9Kk_G&@yP z4Fe9UAmccx`|XzA>PwGC@b^+AnHY-=rP9I7NFo!A5052-sbn$}jKs%N$yh8ooKB5g zUW3=(Co?cve%&s$NAln@UZ>NzF=C{L`A8hr4#x zSS;wFvel~)T-5W0h0v0&me$r@N=8!XP--|h9!o3>;^|;A8jS|WRTgRer|K$3E*%$tP(?2I}Yt;YO;M+cnjk_a-)g8^G-MKB2qFdGOfUFD- z%Za&2P>IEdf^mxFWFkKw98%=@STe3Cu|zTyi9{3e!8JE&-yxZi_l{x)Vlxmez0;)m z{+a@Ca+6EA6)m-~ObH*$B=mr7UZ(bynEkb{Y<8KpqNPrjsoqJ`S^Te4HaK=;)2#FS zw`OJZ;(vKG=@oC~p43j_kGdWIE8e|x>ILq8I`4Vr*^B?RW@P*0e>eaBCq?c<0KeK|FGDr_;&;CP>E^$^`0r~g{<|0d z*^B?&iul!D{O8Vy|Ag3(+KXSQKfe^VoaqJaBz^_x#qo>T7yDx~WpHIV!;M=9H93)r z{52H+*UnV+;=eYY*Md&3rueT6_9M3>!B_m(7DiXpyB6HRvFzd3xB2ix{P+Y3n*wXg zBS1Eu-}d4^cmmyv|7aee+A6{&)Z&!hD;C9y|G?B+$?~RuN!;T4x}E1MI#wXAPfjGhm)(l34jSw%LSh)FjQ@67k^y!HL{2Y+*5`SGv*k<)6PoAB&JB$oM2t#Dbtq~E%wuUvUKzw1)p Np-$rmTet50^nYE1R~7&O diff --git a/bin/Microsoft.NodejsTools.WebRole.dll b/bin/Microsoft.NodejsTools.WebRole.dll deleted file mode 100644 index 03b93f4a1c5dfb1659630bf8ea0ad76d2a599ed4..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 32992 zcmeIb2Ut@}(>T5-2}uY=I*1?v6p(sCM*-=A6p<>5VhEuqB$xyd5h*HG>|$3?u{Z43 zhP^lJyQZYkHV<h(Yk#5|2<1oav9yNGt^9Cjg<_zECJZ zNF5$}fQQ-n+aGQ->r@jqltWuJc9aQ+$e^s{4hhsz#DVYDA1-j^D3MA80Hk>94;ehr z&hTyZ@dI@^N`%>BK*YRap0Ny&AADPV{1Ads{rGtd^f)R1fIKqD=D<&eA6wV1EY$rg@7Wq0I;pz zj}TLP*W1j(^d5Lo&%o;uq>M^UFvQ_!$;S3t^?5P6v`?g*r8 ztT0i`gaRv;u4pGOi>;x`mPQwIKzgFZE={UU96G7E7@P9J!}^fBNU`d}Uuzo1fzK4_Jq4|=5NgTkBXg9SidzX*&1=;M-{ zKJbX?V?ZnV3oL^2R-4qO}J9_n;4WyoNv z9H}cL9VMqRrW?-ci@{lNG!zygxdauelwF8D0N%OgOfm}G z4H=f?8Sp_X#6~6dg3fF})l8aR5qJ;=OAINqb0zLX3i9Pp&|*+NgI0(U#9aWWX9FGC zsk7||u_Rs$n2F%8nQXBSRB7nYZNLk29J^kEJYG<`)YpyLO0SdxXx4m|U|!-9v$;ciV+@DHRdiHrLLuYePcu}COk1T0WU7>z3e5)0(e6fn&;zXySLmwHhT-Qoeb7X^7NM!w zgaIY1n?|}!mNt{p%T0A%7E7BY&x7_|nnx#Rx;r#LOe4o^C9BHkFD!=xCX9gl5JYJc zfeXJMh0$M+Vh$zzzcUJTT{cUb-OPEdl5@mt>liARJ;jWkO(bw5j>5@LM%Y%#%WsXa z4aLg8G(r%eDoa~c!3azhtZjHuMxaM2`(`-Pz$t_!F=Q%jM{Zs{fF~nyG^7f9!vF&@ zcx4Vy<*>9l&BF^lBC4{Vh;I{==Ud}7)gQnOSKdjmT; z$WR;$-CV!fR#%N?_Dwz)sY$4V)R+)4qz1LZ*gj{(EMbd>lbp$s(9as}KP@BtNRLoaEN$pbhT z9reL*4#2lTW*@*|m(dKz>}mq+F?=yS@SETYvERfCCHT#e(1vN)#R95nTs)Qvn6*R^EENn-ZwwrUS5BKmpv01-DAh+R z#Oo`q5Tn7o$B&6wv_gz3?ggmgBuKEI>aRqV z_61Z!a84AL{h&ZiBwdCML+;LfDc?k~sm&+?VJi7#&}?8`u)8Uu6=Ep3(qZ`7%9~SM zGHm>SC`;0Z)jU6N|Kb#Y8g<$D?fZ8yQx$BFR3DTKv{hP}X$x3xrv4@{2>4(f4+0tC z-70jf)G?Of4?121^}s0T81FnlMzCyS9hX2G(6JE~Gq+jC(*D3#5$s7Bo({NX81$x8 z^put%;EfKg5TnrwF@~6rC6@{b)~^7b3jN|fLBHnsLG5wyItX6G?uG^?Ux+I}zxeS@ zAJ~-Z7q310J(MAYh1GYFF9xa-t6~Z8(kDoCV{AFNd>>_{GEX5#b z)`Dscy@2LvHsIhW&0;9lEPl4qEXAKvvu)VTn#E#KXm(#K%~E|(qyIs(EnuYsYOUK0 zkWU_bTj>^a*R0!s*zN&@+$~YQWw5Iw>F7eb@Vr2=uyf3YbPPz;ayUXw@SFu>vW%5U zvP2nDj4=TwYbeY#%lKGy9&7^EC1lwxJ}d~H_n^E7W}9U|HdZS2p@EGg8ZJ^(1v=;x z;R0JRs`pSRg6l;fA_NQ~7!_;*5CVx~6zY5iZSh`~`T|)B21CR9bBYFjVzSVhiQ!06jL)F}yd0uTJGt+1J>bXfkso;P@b1YtF*0;#s(r18W;o z6ZK-@+J2B{A~S?}NTp3s(L^B}3?B}o)6wd;C^!f&O!6&nA_zl zx@sJ>mm`8+G+5d+CTdi{t!h~qUPz7T4n?ON#t8kYVJS_ZXuhW~XV5UdJ8+_jcxr1P z-4A2bM5@4#Cd#C^-2fai(P+TeM8R}iyAM*Vvp$sSuuT$RO$_D^nh%vPh0-v(o2oyQ zSXA9;wVNz;um(8e5n3o8+7>~{fGTaLO4_i_;W{;-Sp+s^jI_}o#5B4#y2h-8^tH+y zx;Y|g)96f8Pp^XX7;7=4daBDH4NzM}C%{9lgER$gg|re?LfS~B&csg02M~K8H9`j= z%|ge1qVrbuTr;)h%u9enplbkOa&TKCbcH&rS(S`4ZX`yP*PdRfrS7KrP@7Et){twA1RTSh?7vKj;@o%kpBIA00M)ND%}gIF?t0l6A_e52}+iH0z(QYcqx^RC89ajs1{x4V2fDH4ut$0P8g(<=m}^x zkxkb^)kF-D4EgygsQ_QV$wDiLn<`>dORQt&!Aupa4Mi&`YO{&!fWHE*WtE`4L;<9w z=(tKbI!X+sjROh^;HTubQ5~FCr#B3yDClac}J;DuoKS}h3yfuf3RB0bnbBQFNnFr|tW+Bm&l2uQlj#&z= zGStc;Kp|q!B|0G7wga-}`~f&>;6rC49p-Mp>8^H&c!a#^Cx|+eT0+;z1Jgb>5otocHoeYsM7RTJk` zy3o8~MBQn3&;%kD(rxr?3NjY*tBJ|9AgWaa)hdE&<&C1%_R+G4-Y_4pfF@7S9KkD) z3`eAkydZ6ddO>Q5_>kJ6N=RL(vnZ$p~GyiJ=1I9xhT`%|d{nuOMXeh;Ec2=<0F35^bOgF)>j zrf_iJC0^AY(i$30TOc$z!O&q|slwc$!8llu>OhGGqfrBxJu-(BkB5m!$TN{MV78Mgc^(Xay7ku+sc_NE7`6 zy9Fz%5&>6wLrDerWx|&Q-&nL5zMJ5?2j*Z5QH(O-yN0Nt@+7So&V$8hGkh-r2go}$ zFFjo-@pVf{;URCCK&r_3=3zh_Upg>QoRga^lx2xUvEn?5K-ganRy_Rk`B^fd1WNuA z3BMp#n2{qC$)L!WWB@^dj3VfayfHy%6p|+r^oLTSFf~>z7$}s*2nXc}rLs`IC@mY< zNP}KopqV(gAVeb0f!(E$pA#o;M#l_c4gn|d&u|jOl7R|Rt|&|-b9Zea*g{CGpsgSX zI7))Q;Ity>hP?BYtYbc)EED7gW@o{maoHVZ2xTepaUq__J5rpMmo4-~u?13@Fvl^h zhcX8ppd6_{EXmGFMKMBtn!mI_BtWr3ks=qEEtU%9z(fg%SDuX#3WQmM6@`>+zEl>L zhQ}wA!0V5J!ZbwbB3>lrrweFgu%%HLK79AS;*+ z6lZ4(1-MG;7@I2;Wbw1JhC+2p7N7{FQm9A?7D1P}x!G9)iUw82qlpvaniyejHeVn_ zt-Fa64-_h_2!+aWvV(*IcqfK1YkY|?c!(gAFUk<2u%Ikyu2{-X%@!({j}hj{i(%3P zF=iQRBC`Y%u~eKcbBr#KWr{^{VsWn+u~rHqi4|lDbA*Tza72~} zx~0S%E91+Ak$gcW2E__xKa{1dE3sUo#DLXoFp(e`euglvAXkVI_}O{#TsNVNg5XXA z#h@>dyxiO@S|T1&5WttpM;jxA!Hb{}DwE|l7vv%VS;2&m$q^~eS~`~(y?uEpDHNOX zkx{}0aY?!fMM4QQP4kz*ku5b3h;+-#YE=pnrsid2V4=5QfMyc1q**_}{H0Q1PHJ{R zT$Zdg>Mz1;p%MqaKqw1=7o);_n42vX@-Bsv(5$pHp{NC}>>>mhPY_D5wf$NdCQ27e zawyZ|Xa6Y{2s}M2BM(OYTOvV1sX&sI`(q`x$1LT<$mS2B+Dd=r06PpxRz{}mcU550 zqJox+m^_gzD@RC~x-2U-D?3Zpsy3hi)S;MqFg;-s!J!(pGMHcy%oGe$ASuW>D#nd# z;;=`<8L&4+4qIr?JfWmOQH~I2pp@xo?zYV-6$vqO5dq{9xeJsv`HsC`u^9CZZ_GM*=GVl2QwS+#7&1 zRfs`82JBRRbu%bMkSCGATvNC!YC5%YSIv?XrYk%hiUI?rrfrM&Lt#C@EeR@Au$Tf7V;%XK2Gd3g%T78uf-Kvf4m@I zwWS5*Wo2WGX3Z)Aphsoa+gFy7lBz(I!cqeGEiSUP4wbVGT!Va-ZRVFUArQBG z!E3IUbJ=PYR@8@K52aYSTl~}7>P;3$~|H>@T1Y4z?uYBZ+Y%2|=1WP1h333$3 zAXV6XP!>N!B$mpu1X3kPITfgtP@Eeplnl-i2!E-TPimp0xn3>?U;@@@Ko1@aw&E{= zP?oo^Yf6d?u5&1RXr7UdSS8X{Vg=`z$Ip(H<)vkbsTGE@NSHq2d~iGp1B9GNv6jkb zfD}9)jKM!GO#%ysvKKIYN4c3agFrEOLHh}c5nDl<$bq3Nav69zqc%P$PPqkw?TA1EtExyw z^$;iquh+a^0M;b3A9f6K2zGPPVyMCtmB!f&P?!^fMG~|s4HahRM)Na-O0ay9r1p?X z6lE1A7ba~Ur4sBf!1MVRaHM#!FbZExQMzHA$J9ZT)P)s)X)Z{Auc6^=$N8hvNwWingL)D zkl?~o3Muwa`S27%jt?DTGHGz&;UaG+bAcfVK++)yX^px@ieX*j$c!?%G@zHBaTI+nl>fY^AKT(_;hwMt@R)?~51TOV z4=Czl+YkU3*+3ayWG9>u0>5 zN2KIR3ccn*8$3q21k!*`KIB^{VLQs9-1&fw4_u85gaWJi$&MeiPwn-begKZPRUW4j!-93g-at$jMM?K6$t5+oP^gOIwkdT z3iT>nC|sb@D?ndU6Jn_}NHO>h5Y%KK05VxLZ9VNQh?9$XJ*^8U@rTTdVW75fiK4DBb z6y&3vyN}RHQ&ZE5rOwt-*NN0F8KqM)R$sfMg3yW7DVd^EGDD|iHkHoTDXC_{IBN(R ztQh(_r39gi)U^nDdjzcFf507<2?8P zAf*#&suRglWHEirf-YhySW)B96gi3zR3Ld1P>)U|n*mbG<8bLPfKpXW?L6E;sRkaQ zcB!_i7D4gS9^v8ZBKg3pby!RoGMggHrp8^Z$z@O+uuWCiZ0$T4EpWzW%27B97TDTG zEG}IWqu`o92o*M$PMGQXdAz2*Oj|E9M89 z>u_oE;ZyZMRy&Wa1jxCB7V1hlKx0rif_7j*Y!2>N&a|RS6ZY1j$q8*;Z;xfK@0wDq zeSy=tqzd0-VwAu&ZkP^C8YEDTiS_5<_W<}MEUW%g;(@hSUM_YVxw6gLuNsdYejV_1 z(&*3h!Pz4sW>0Oup-bbOD;KWsy)oykyRJEHvYN#EW66x-19$SZCLLns_vrM{S##=R zm8bU}n(wK3@$gkza)kP{y{l&1^i8#2DYQ5JbkRrFSL|^A)$o4n+8n6#u`(H_6DTy| z=Ioi~8rl2oG#ZmbXMzba&3fv@)0k{JQ#%U)>hKk^6t>4;>Xg6>C!Ik!vxdP087efS z6AAcvP?bYxnyLUkHX%0k1Zk?u%OFE0p0zr`)Lcjc;e(+IDcga0Ge}`ZI)ij_wDYhx zFrnKZHhgLDx)AP2z^6SHRUFMAQNquKpl5Srg9;`~3BbdmMeyPSIpJV~;{Yj_IuUc> z49bx(7K2dbo!;ySkGIg%QZuF)BE&IizT>h=cjSofUWBQ&X?G3I|T%WQJoqI=BtD zxrPh4#st!Dj*@T##S&nM3h}^NOCZO6E4aU{b>zYspG(F5q+B?}L(D;#2J5pHfz)`8 zu8uq&>Fnm{fsh}8y0ijt1>&5XELrC?A>W1cBE8atZY~0$mzyA6=BP!wr5n8K8eTn8(Av7^r0Jg7%tTvBu}7snNSH8|eQPl%;KnF}9p8IDl zf{t>;G9fpOig82C2mexMNC9P=&7x3PCGf$Gg_kZ;Zznkc1vROxAX~_lL2Td00-yMu z1X8JmqAT2;Ew@mPi3|9X4v_(ebbd}&c0p&ZlrNGxfSqKecWJ>YQjm6{XyaixWy<;Y zP8FvWD94e>`>zZFTFbjpPRn0p0Y6+4ig4gRjS>hBeYG-s`CQEhsYpR8_FQ;V$IX)A zpE%*)H}PdMcvk`~Wnylg6eOz{5}ylU>~tUNOo*U#c5=!PJLWXMuYpP6l%AiRB^v0| z72doI3=8schRNXJZ0)P$@lRZbw-evj5&VjxTYGMX7&?}BNkxvh4dqk05OoKhFh`1@ zkv&(MpCtoOoCMT>eGaa)P?S zvg`H699rhxz|ZJe>BRJy&o%Z^=#BJqR`?wstOoPtC8$vl^2X)+b9?vW?U&66d^2q6Y86();Q z2PDI!!>{d<*>MnfAj|0W~9t6=9^a~v0g~GR2f0#3{nN)sk z7_bsT;1frA5+HOK1GzBxrDYV9!ypZj|LPL$V!ZfL0w-;JQVxStE{@mWPY1lKh4ZNdFhmduz-L%x+=fCx>ltIHJ7PGtB2mO2 zex;N~;gB$H`9D{PMSu+8_8XQ*AoP|4|L`eY2EE8X5y+sq4xda#aC(k{C&t5{U*l|C zijoB41UQz{n$t1R8v&A%k1z-*Na1vk`Nc6Zc^nGURL1EXsYo3@nJZ&;I65YeVc`(8 z6rwvgw!{Tp$RLj+PdMV@0AGJJ6d?F4j%)Lv2RT2mF@>L|!db1Ej|9NM(WaLEc@R-> zg)a~Ok#G;l4f5DkroruHg3=6*=t)2pxc3%m{3?sTA9G9tO872z365r<2%w)qQO8=r zu`w*A42Tn9{#U@5e(mee$%4ksw75qv7O9#iLBvix@M??_tfXCQF(I1YR;V~+8 zhD&nI|Jwh*Kh}8=$t4uA)ilr%j_>@ejo<4+8S%>jsmLJWi=(=HxPL~%EiL@TWj83} zSdtgy1YkEpxW(lO7SDsH8+=`%-VNZc(9#w3>rVZ1h8(tRPdFkGAU7Ok#SudM!URVs zf5#sQl9PX-;s1U9SqVhTe?z72{?D@Uf4%=R61eRP{nBWNEb~3bRJAP+Eq|{;uxM3f zz6Subhei-QHByzSVy8)`8LJ>Ng2}OC5)7iugGMl_d`WN8uoa{YsY)kM6=M;t1d-;g z+A;Ks8U=aX`J7yCbf7=k-cW<*4iO6vo`;*K zt5%$b@l-M>d5&zkHgFSQp1X60tWp(`jhm>V1$)!EG>(9^*= zi09_O3-k=&btEn212XyTfD~6i$TGsBwSWn@Mq5U-0ec`gv@(J~Yn~OC?|HWc4C1zLAEv z`!fpT{FwZCas6j*Dmww~9x@=)WR%8HEsTXxLi=dNPy zI!$ERIenAVtXsEWMCQzEPQAzXDZSL8V(6m-n=f4-$$1;Qq}@|mw>45-*@|IH&pxbM zdsRQuE?AfJn^tLRw)`8z_}w>`uird^D<;i5kZHL7&6eTw$6eKGve6xLIL7&!t-b*H zopZRqWmt6ue~zk-`pr>$Jue*fXFR@f%<8h?RbAGE`vW%RovCb;wKcusct(@AX$K7q znpj*$sDeaPNK+80sV2jKp?5Fa*vt6vv|gJ++=Z+IXlsGtJZ;K^Of4Bkq(OjoAV`yz z2Um!ln$?KSlCnxLN=HB;dokHCDOFTh1i^?PyOW{HGD$0kpb!;&$j{IJT?azRUr?5j zx|rXN3~YjmF6ivm<^uB(%!NP`Z*HkLH2g}*fVrExkGtjm)HSZDVbLPT(ON;V^+oNR z8U#JNY<(WpY0P`h^@UA?K05Tidw0#qwMVV$-2Sktd};3APk-sC+Hv#p2h9;0)*ovs z{jhZpy}x&y<=o8&cdfcsKJq}SOVXsx+lmK^U5{n6pYOSTj;A5L6fke#s7u}xS^AYV zDMo5V+xAWAd&K5ir`Wh74t?pTA{}H^#!uc>tz9%^oqha$ z+3J}Ao3<6)dl=NTV3*NqseftegXB}QO^4h}$pkO<1iaX}7B5B&>DYVoNy|eiGhknY zh#@~ojV$<&_zFwXTt4ZIo2>-`x@iz*&dLzske||zd61qwo-@hg@!aHotffenmi19zE z)1hg{yGir*f3FwpS@Oi(xBkR_l@nQK(qG=2SKhT@)XFdQ-M*fyD|q&Op6veY1D=E1 ze7t>OoZpLuFAsm3FlY;RVM<}z?kjaihqw3I-GzT;Rwwqp5k9-!I~7+x?zJmYOK;4J zDbMb1FrLgk(>UVusrPp7%Qe~`{`5zA%rSr0Y40zERGseJ_W7t6IrRmdZEXjQ_c&_7 z7Cm=c8HGmLEiu2c>SkHOqeYpTNp<=@O25<}B$fQTc}j2PtR_CpX)`GB`IW9gD>6I8 zH{Czh-_e8YiRZR91Kh=u5Hg7Oqk3FPXKY9+x^~XaUY?|j9gm-y?j>|fcMu5ENC#JE zp}Pa$-7U=_&CA7&^m6k`7m~ss{NHiyhsVxtGU!Dd^>B1CF!&>44#$j4zrQ5b=qxpY$%(?oYOO5$@mt9@_T3Q`7vf^BEPdQ1^R~X- zYRef%ANho5e6&8?w8q$lFHo-u(-+OutJyo?X3vjvhHiVB(8D-p$bp;cj#9%#Mvup6 zUwnH0bG=q|Tff~AhL7j?7HX@_+xO(|i%B0pO*}Bl*ZcO7Dl>}-o%~j*b9Vj_;j`v( z<;HGX8(tQ;I6m)lNUh25(h0rOZhMA~U7HbkZAOHzC~#4N%EW0SHwE21Fkkd$!i-_1 zx4yN@=o2-{;=-QdBC1O}c&T4}sDY-3~R%be=KbIRYdvI*FZ@Y`)6USdY9{6ph zf!6I?on<48w>nihKmC4lUqF=Q1qr(5mdF`1F2X$nc7qT?OHT=5}LU{o3)? z{Jb%zS4xA5FO^<)!JtPfI#! z*;pL*i1Mj&_L+RL+LJjdIVz#d##Y67Yxt!eg2uBBsjq^48dtN?yO8Py^?fE-#XcOm zvis|h(;nWQ3pV8^*BCCSIIcY@!F%s&)fDAT3`gd8*6EF4NdD($% z+l-_~W2m?1P_eI6h{*Z>;L9{um-Y8cu%3CpqwW{mJDk`VN%xkJ(Q;oFMs_2Es{*V1 z%e(%4U)F5z5-@E6ST^Ow;*?$syjUm+PFYz7FXs98yqNsgKzPF7`2tjb^|KekJ)D5$a*UaNOd{T=(kZ{uBZuhf0a~qdyETY#W+}<`W zJn{96fO)Upym)@M+|1Q`Tf&@|v6iE3mz0@IYnaY5eccfCVM6t>hq^UWqK>pXJ4rIb zc2Le-;}0e;V=rc$u=t*AdUDZ(UDg{41PMWldY=6FXmPKE8*^#FK~5=6SJ$2|a~6GB zGDG*?ldQ%Si|ltFvD4BNPMm%1?V?XQR;ohJ>92;Gb>C5cC*k3lA(ckSN8JokZcH-` zo9M86jcbs}b1i*i)c1y4AM;bQ4y!&Nr8%KTj;3yu&#+FR^Cb0evXAY3n!7l0YGTp! zimG;@^xp4JFV5h|YTTbWI2j&!Ao0*?64!cXlzoiZP~l=AY_B=)hStrrCh@6|^XCj7 z6&zq}I``TBmf5%kt2v)_t^L;A`*>$XamWr<|8Bzmeo^ZKo<=>}IJn?4$5l1Qq=aYI zpc!}Le)Z@3-L%%E&H5f~;5e*K#e8VP41epa{nIARI9hReuK8Mx}eU7Y_5mIt}j1x-zLP-dUbh^_!#wjboy z^R^Mw{TtiA^yDl6LW8M88NMzPupy& zQTyfn+zrGji}1MbA6546;J8jJIGpV=D7XI^dR>e zk2bBzzjmsiXCzVUC>zu#M_qT-sojN>wmF{HSu`Ohbz36scobJRdiIT>ehrB`*7cfW za>tY?U%g|<>+xrvb|IcO?4HC?IZ_eY@G@5aMvqlf?=@BoxKOh9!SvTmr&07rQ*1j} zPJMuW!=ldv*?yY?s{=}D;wi!N&8ee?S&92|#x+gn})B+06$4bnflgD-p5hnK` z3^{t5XRqqbdh7j1dasQRPK_T&m7nOD@Njbl}GOADd)x0gENuj8DvH+;L*^T-6tqv^Zm zn~v5=qxm?jOPaLpp85UF>yHUG4T)1Z@9!ABdiwgBA*(i4RpuFAnL1iG&%()hIa^fK zXF|uisuv@VnO}U;zQ@ry&%W^Ew8Se zeY@>*_0b3JAMu^sc%bvi;U9M7shU;n%DWKQD0LXVvofWJXu9r%#%(Kaj_+>Od5`%4 zX1)Ei7|YG$Kh)0dzHRf%nO~mus$QL$tLeaDL&nBFoe`R$1^WL=&%O7q$ z{`Qu%PyMW^Q;IHn2MFSZotiCtyT@H4%5_IopR2dN)-|?UH{->yE3+5b7cznXu@50_9f<7^@?!rl*eZAF) zTPwpmj(vb0Oi0!7nwp~@KT1^RcK6<=bKg4I7Phk*>|()?OyXavJuzUqN@1|kKOBDd^>;JFxRwe^*-Oa*h988 zVFlR_PxUtBSrldbzk&h#+m6SM)r&iqE&b3df$9aV1kbRl&Ug~GT3CpYZUs!mY6WwuQ_+w_5Wa ze>D=kBk_`FeJ!&%%wa{&M!~|N+qZN!@3U#v+KTf_N~;d$9khQ@=4ZRLG&cW@fZ*&r zPPGPW zt-$H-I*sHkmk~^u_%A~$l{a*U%ob|e3 zMb{WLhL^%o8?W4n7sF1xP#(7Eh+jc9+jj(;PzDm{t)s%rbo-i_kBxswf4;!b{qgI# zF>YIzX|7f%OI7k6ieG*35PI^WsZ%{5){LnI|s zly*N_Z-$Y7J93|i6Pidc*5Az(Js%V2jMIkSiB@K?Fh z=H0zu96nEb_&}=zH65C61)cA(ed7T3*x7TA^BQyKe%CWy&+;n1M|RP*xT$$$M#c`& z@DIagESX&9F>UFHb78c-tJfsGn6hO(Qodm`Gd?lS*dEDe_M9$tUIgI+J{qfCKscl%lkY(!w`P1)=Z2& z@p{(SHw*Qr9bq02#PDf75<^Yie$LZ5w)tbzzO0lT)$=v7Mp!=?;cGgOxBt23s{P@py5#APmiy&4_8}vNm7I^xSXA>|^NG*qSN99r z-+9}st$4@SoFNU|ULC*R3*Go&-K!0L48xG<^Xl1C^opJzYj|gMvt1WPMo-5!OAOx! zeD6ACEbqgzog43Wj=65@Qrtalitw^fd&{)}TQ_CLe5o5h$l!qeDe0W5M}66QgM({2 zl|LnTIsIgZ62M)Sv4%phJXINJ(VTpia{ct5jD;*6^B?i85Db_5{!T5v|Ief8Evop-O4iJ+0r&p;m+OIbjX!yng4Q?#JoLlwslSIqJam{7X$}+7; z*X^&j^fF%<(9U+?qu$Xgw=q498DZOt_p7(R;W6-#&SkZip8IAq*B|k^KlTE~dz9Jl?5(-68#wm+*Iij*w|1!Nx=WQw$NC$qJW3z@&^g9R$Ek4@ zJNop-psjr`A8@4St;&3JJm*d4>LyGdy>pMbtYeCi&6X3^Hl7`4d3AR`J*;->S`*7A0-aV|a5xR8!^pogr1( zv(DbWIA%g~Wa=5LhmXi#gG()UIDWer{lzPRAEH*jys*Ichm@B;Bo3Wvyvc!o=&3~A zdA#f}uikR3E7=<(m@!}_B70OtR)v>`{rwjPFnwX(LQEfCeKjw3DWpq^vop2W^;0fx zu-L_r(PWge42xaB-+OiN7xZOh=|aprmr**CES*l4PH7I=Inv3}5oA|ocQnGl<*&NK zi+7q>Acbo!Svh=3fgo3k|11*e*Gzy$y0&-bnzp*rn?l`1&W5|I0=QF}0yj+YFXHi? zV&&~?N3Q8l4wYJcGhUb1%(@*{VC;DAvMj@5u3Dw`9l_Mu0hL8(3)Cm?6{a}a`+nFj zsm~elZFkp)oMT<;x~*9JChMA@&cdx`W?$jR$wlKsqT?^CPaSsFINaoocfk0VGwZ(& zyz9$y>@@d*PrI7)n@#hldo?^tI~wFOWT@pE-J+$FWg{w@j$6?}Z1;`R+OcGXiu&AV znV&KpXH?mCwH??iOkk#(CF(t^^4^H1J(J#q*xmfn<;*U(7ov`9@2|6dcIL(#&2_VF zX3mP#^ig}w9(&Pjzq3)p%YzQ5`YhNK=EXV0*>`Bo+WQ->T+<)ZGq{(h^B`;E;@T$b z4>#>QbF*e`NE(|d5--~-+wZ5sTuRv5_?C6mjZ9bDvoZ4Rok_(eV*R4vWrOeg*$Nl$ z?;Dd^zTZ^fKC}GR)i)nr8&uD+zH_o>=9%Yx1^##Yu;z{SW#%*MnYDRldb|1j%`dMX zYRA}p%m1*Z&GVZ=r>8UDRVPrsx`aB>WBYGt5?f?q*r?cEN|bfm_38Hay82V*K>6$Ls>5@b4ElT4v@wSoi76_$O*5 zkF&b0`$9frL`=MOD=$Yd#ixFLLR62sl0=K@A==L7LtprFYP)`3equ@Az13spCJsu7 z3Ju;9aCGkAKAe)!fnN(2?%kD>GvH{9R99nY^hsWsKAivb@%fJ|o$*gET=EdYZ;pVi zPL@@r&)_;EM;WVX%iuvgocRA9_i}29JTQ0`46fbG)=>waGHX*rkUXKZW zc^zk@AKH*)KI!Hxvu#i2UJS8cwa3o6KQUrzgu|Cx=Wa+Y*Qa%Nw;5i!Q(t<2;p*?_ zg~GONL-bVrjV|ou2yKRLoM||@=*`{1!{(2ktbc|qT+`1YGxkeAU*@6uN$31LAKwi1 ziFMw6qDZgbfKQtTrY~a7s4SEOs<+*@v?o1t*-W*^>@O=j6;Cakt+T=Rg0O0XTf~PM zpOUs;3A++H(m1oIy5C@Z$E>O~Zw9EU?XBqd(yp&Y=dHDGX;15RC-kb!y5OScG$SW_ z(lFPZz8%t+SSRi6)`wS`OV{ula7fEmv${+-j4aa)Za%)z=@8q{bpsf$S(`Yvp=$x4 z_B4Y2Yiy&8@MfwhjYtc^8)bwY#Eh(AMYIHaQji{*#Gw;#gXYJ;2!or!S#$Rf@9Z(F zUc^q^RUhNwD)>@5%}i_htJ;<9*?0H3(3nZLR~nU5ojVj=agiMMA30-Kksah`4AYh~#*a6r@wtKo+xvCj z-ukBT3R8`p`P$<;bDw_Eo%!}tan|&KvN){^H5^nn>hrTwZXhw;gzS~953tNvp~#s#WhirnVO-WYIW+Uko^GSRARaj?dj z$8Wopo~-N8-?>-+kk`Gsl{=4YFXLxSNhyu1Jv}XA>fQrO`_}VyMK*_wKbDv5xW)ex zve(+QLxzsT*nHf&@U*efskME-=9~GvOw3!oYg|C2U(fnB^O(LF#c$L1&?|$6zc>^A zRdj#OvD)RYhuU&@FRw;1r)(L+c6&I)Wc{PrC%qe;g0?Sfx}LUc39*-}I&H|wFFW@f z4eHy^U>>2;!y-}{$9VvfYWT~2>jgpQL2)(h_v zj!$~HC^ycK9^3-F*@*Hy|mZ7ufzcw68?&T1Gox&ZTY|9(%zrYhW%<4wO_^e ziD2a~ol2HY`eDmjO8PYKI0*yZpKe*B!^7nJ)xhXjr!-+YAN~^H-`KE5!_UxKHmvyP zc7JQb%6c%Sr$)n}+q1fs4x;+pcF>kk02nVkewv>aR0y@CiRZ|GC$b4ZkOU>}TjUt3yJ# z>_vdqk#%*&hl*c&6!q?E@_Keb_bD-Goo5@vw@wA6!YeB_54?By)VpItkvNR{o0 z`Wd~Za#B*Kom;*#?&L0X?r!}xex1{|E%zt7>_|+@ip0@2iNHD+9JZJyB#f!W@6&FPz|TDe95i_#%mb? zBercWnQP(6-Q4kh+SB(NdEDv4v{-$I&f1o&j zMd|Tns;j+rJUw*$a@i)yNzj=jsuS_}N28OS`Zi%yM{KaofdF zr_I4a))+9X;LFKk|0@N834zwbRLSJ7mt`w*-Z6XODAg zci4Pg(&n|-gS=-(54u!+_F(+otec5@>u-{KzMgmx`B|f`Z;waw+qd;}+IhN{isK87 zs%W>XFI25fE^Hj`)}Fons{6HbDU)u>#)Rp>f^!948SHKK%3z(_r0?e}f(M6FtIxWh zSD$~@rMLb?4E)^=`3nR24`guhf92x;FW0GQ5Bep~L=3Q6*(0jq_^8D9? zt8aefYOL*%Th;a9YP(IWX}i~sIC`Z)HYJz8UVms%)5s|rU#@jDWFP`QXEY z?e&wq9XmY>cjMkJ-Tvvq2t)n3d9ic6iv^R9SFzKa-tgaae>v`DaMYLz?}3vmP{TmW zu+;?_+(x0x+E4c^_6BI=3EP~Xf3p2u^5*K^<;MF)jqcXr`7rMWiKmy5$UCp%0deJU ze(vI{pOXF<>z6cT%fZ(>MmfyCU{ri}T02Q`t?C*r`r3mXtr|}*9=>Svwzu6cxatj? z^tx=nJNqm-#y#&6yY0YK!zt(J0UM+f>h+iBbz1$sBv>uD_J-tLlG`6K%u^4>6n}SE zy}JI(?Zv0Rn0T38JEL{(T6GycAA+n-`hV~7U{Oa7oXK0>{nPc)<;Sb_9mI|` z4okn%=+O-&?Y>1>R+a80OLs3R-9eUa`;TnAfBeP9uRjcoii@Rw80hTo?&jbc=n~=( z=oS>rvm-mn_v;ov?$^2U|Fs1-68@(O@UuerOUig55 zFE%;%ZU(qJ^C$qB4?8URl^i%{!s~e_*!po41RzQedH8c#H0^gZxa$pPM##5SAj~@* zgc00ZHK+05Eq3#r9_rv)#Ua_a8QtJ+|7vBv{m7D^Sf+ljk)2exH>=OHgxTS`FTK{} zb1pjmv2lCyaksNphM&||EYvuywL15G%79ThLk?Fim=N|RZr|-))_%{{MIL%dy1ix> z44&Kec=uhkqwaNxm=HT<&=cPt+p*dBHF*;V&*C+`q1Voy(HMAj_4)qiBs){t&P zPaoeQ?5kaL&|$!(p4Cnd)%xGtaWVf!AD<5esjqln&&4`b%z59oU-$Fog)w@?MIq(( zqt`EZTe{}-jT=iE4O#5Ix7)~^KhXw;^wf-Ut(|iEsI%jQ7a?J0YI@x_2|dCcc0P%z zz2GnScxzB;u0XH&mN$Hw)2*Ov$lsr+vCe&qN=Yj5Osf=e`S zVd}l2rrxxF_8ce=gZ*Y((>e@RMmUqk&Cw3H?4|KTJcIl>u2rXHC0+J?ZM%bxRigP% zm~kl=LhSk6rET6lIN1LAv*2p7w4oINnmVuaELnP*EImP%)-v>dH+$g@Dp^{xWcdF? zVZjBqwb{JGz4|$>>~=Xe{Y}?i=ADC6Lt0xtEIRm-kcP!z#yK@3$I<6MTeuk%N>@~w zRnIkq*K9|C#g$nE+<8fFb~)6p8u|Em&}mPK?Wr! zG9vCQGPK(Ebkd0-S|x!KjhJG!4c@!gt?am|&*LVOl3m9)8mC3%W-q%s{{5luF*c`e zsoGfW+PWpB^XT=d58ss)AFxt6*)Ukgpx@I)`9nirUf+Lz{s7-TWv;0Xv$~j#)0M={@N9B8Hsjmjx5JDQuRf_bx;cE&yJg=l+V^rL x+q|;yb^kiO>i#YDI~A&BCPQ=|G1sr4)edTm$samLW9)U+@hk6`)(u~e{vQLgHC+Gz diff --git a/obj/Debug/AAMariam-Plotter.njsproj.CoreCompileInputs.cache b/obj/Debug/AAMariam-Plotter.njsproj.CoreCompileInputs.cache deleted file mode 100644 index 43ce23bd9..000000000 --- a/obj/Debug/AAMariam-Plotter.njsproj.CoreCompileInputs.cache +++ /dev/null @@ -1 +0,0 @@ -a4fca7697da12adc1a74c13ff1ccc52af419c79d diff --git a/obj/Debug/AAMariam-Plotter.njsproj.FileListAbsolute.txt b/obj/Debug/AAMariam-Plotter.njsproj.FileListAbsolute.txt deleted file mode 100644 index f4231dbb4..000000000 --- a/obj/Debug/AAMariam-Plotter.njsproj.FileListAbsolute.txt +++ /dev/null @@ -1,3 +0,0 @@ -C:\Users\Luis\source\repos\AAMariam-Plotter\obj\Debug\AAMariam-Plotter.njsprojResolveAssemblyReference.cache -C:\Users\Luis\source\repos\AAMariam-Plotter\obj\Debug\AAMariam-Plotter.njsproj.CoreCompileInputs.cache -C:\Users\Luis\source\repos\AAMariam-Plotter\bin\Microsoft.NodejsTools.WebRole.dll diff --git a/obj/Debug/AAMariam-Plotter.njsprojResolveAssemblyReference.cache b/obj/Debug/AAMariam-Plotter.njsprojResolveAssemblyReference.cache deleted file mode 100644 index 67d5be9b7a12b38e6fe524eedeba2ea6a1a31246..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2216 zcmb_d+iu%N5T)*RdTpA)&tW2&Cd7K4^8EmeX{a^_^}K>O{gp42hO3tnZvAqmX;w!0b$% zLwqo5wu4Tv8?;(}r^(u^M8-b7-o{|2G(-cA|0w}SaS=4l}-Sv+P}L{la~Zj;ik@ZnU73+{t7>BoTo2t|xY zl^?M%0c9A4f>A1MnAh3r&vo6t#^?SO{ja{i_ay~et&;Orkwgi_HqB_ETt;!w-5);g zpM3S*tN7z& z1%zec5=J+x+udE(@j9Qk_S$!$d2g>ow%*8Fg005XY9uC811)(xwz(ScXc_`RaeKlP z)|&@P33({J3D;QT*i`+vmr&fa$>LFzq~&f)h}d)reou<1Kxr+0lEwNEf~-B(0L2ySaRO}Wl?GcxSQfv{Ynk^4-6>1GX3bE*3e!?BQDPoj_3KYK!UMXaR= zKXkE3L_8*Q$U3Kt%Ug3DDYmgjSoijga%qms{?wJh_Q7o9~R z!~q{Ck`bHE%LQ9_KAo*O`*x>3yIPl5Li^&T{$&2IA#ja>)qYFi$(J`Vdm9Tg6092K z{U;RVEfhy|&+IoEjqZLUBiY8XvXNvP3zBUtS*Ed~kVw|rMpebX@H%}vtf-MI7j(b4 zu3;8`M#g@P%19xuV441jvv&e(-9kznuTbYrFkCRdTpA)&tW2&Cd7K4^8EmeX{a^_^}K>O{gp42hO3tnZvAqmX;w!0b$% zLwqo5wu4Tv8?;(}r^(u^M8-b7-o{|2G(-cA|0w}SaS=4l}-Sv+P}L{la~Zj;ik@ZnU73+{t7>BoTo2t|xY zl^?M%0c9A4f>A1MnAh3r&vo6t#^?SO{ja{i_ay~et&;Orkwgi_HqB_ETt;!w-5);g zpM3S*tN7z& z1%zec5=J+x+udE(@j9Qk_S$!$d2g>ow%*8Fg005XY9uC811)(xwz(ScXc_`RaeKlP z)|&@P33({J3D;QT*i`+vmr&fa$>LFzq~&f)h}d)reou<1Kxr+0lEwNEf~-B(0L2ySaRO}Wl?GcxSQfv{Ynk^4-6>1GX3bE*3e!?BQDPoj_3KYK!UMXaR= zKXkE3L_8*Q$U3Kt%Ug3DDYmgjSoijga%qms{?wJh_Q7o9~R z!~q{Ck`bHE%LQ9_KAo*O`*x>3yIPl5Li^&T{$&2IA#ja>)qYFi$(J`Vdm9Tg6092K z{U;RVEfhy|&+IoEjqZLUBiY8XvXNvP3zBUtS*Ed~kVw|rMpebX@H%}vtf-MI7j(b4 zu3;8`M#g@P%19xuV441jvv&e(-9kznuTbYrFkCRdTpA)&tW2&Cd7K4^8EmeX{a^_^}K>O{gp42hO3tnZvAqmX;w!0b$% zLwqo5wu4Tv8?;(}r^(u^M8-b7-o{|2G(-cA|0w}SaS=4l}-Sv+P}L{la~Zj;ik@ZnU73+{t7>BoTo2t|xY zl^?M%0c9A4f>A1MnAh3r&vo6t#^?SO{ja{i_ay~et&;Orkwgi_HqB_ETt;!w-5);g zpM3S*tN7z& z1%zec5=J+x+udE(@j9Qk_S$!$d2g>ow%*8Fg005XY9uC811)(xwz(ScXc_`RaeKlP z)|&@P33({J3D;QT*i`+vmr&fa$>LFzq~&f)h}d)reou<1Kxr+0lEwNEf~-B(0L2ySaRO}Wl?GcxSQfv{Ynk^4-6>1GX3bE*3e!?BQDPoj_3KYK!UMXaR= zKXkE3L_8*Q$U3Kt%Ug3DDYmgjSoijga%qms{?wJh_Q7o9~R z!~q{Ck`bHE%LQ9_KAo*O`*x>3yIPl5Li^&T{$&2IA#ja>)qYFi$(J`Vdm9Tg6092K z{U;RVEfhy|&+IoEjqZLUBiY8XvXNvP3zBUtS*Ed~kVw|rMpebX@H%}vtf-MI7j(b4 zu3;8`M#g@P%19xuV441jvv&e(-9kznuTbYrFkC Date: Tue, 15 May 2018 08:47:23 +0200 Subject: [PATCH 44/54] gitignore updated --- .gitignore | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/.gitignore b/.gitignore index ee165f325..82c487bdd 100644 --- a/.gitignore +++ b/.gitignore @@ -1,10 +1,11 @@ .vs/* -.obj/* +obj/* -.bin/* +bin/* *.config *.log *.cache -node_modules/* \ No newline at end of file +node_modules/* + From afbfc891e56a29660632985b2d65fb35b81573ce Mon Sep 17 00:00:00 2001 From: Luis Fernando Molina Date: Thu, 17 May 2018 16:43:39 +0200 Subject: [PATCH 45/54] Automatic Updates --- History.js | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/History.js b/History.js index a8cf7e443..bee26df8e 100644 --- a/History.js +++ b/History.js @@ -60,11 +60,13 @@ datetime = pDatetime; timePeriod = pTimePeriod; - fileSequence = pStorage.fileSequence[0]; + fileSequence = pStorage.fileSequences[0]; recalculate(callBackFunction); recalculateScale(callBackFunction); + fileSequence.eventHandler.listenToEvent("Files Updated", onFilesUpdated); // Only the first sequence is supported right now. + callBackFunction(GLOBAL.DEFAULT_OK_RESPONSE); } catch (err) { @@ -101,6 +103,12 @@ } } + function onFilesUpdated() { + + recalculate(); + + } + function setTimePeriod(pTimePeriod) { try { From f75e42c5bee0e2e5d69e1196d9cf3f6dce7c3a99 Mon Sep 17 00:00:00 2001 From: Luis Fernando Molina Date: Sat, 19 May 2018 20:30:43 +0200 Subject: [PATCH 46/54] Fast Forward Bug Fix --- History.js | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/History.js b/History.js index bee26df8e..4e8bbf381 100644 --- a/History.js +++ b/History.js @@ -66,6 +66,7 @@ recalculateScale(callBackFunction); fileSequence.eventHandler.listenToEvent("Files Updated", onFilesUpdated); // Only the first sequence is supported right now. + viewPort.eventHandler.listenToEvent("Offset Changed", onOffsetChanged); callBackFunction(GLOBAL.DEFAULT_OK_RESPONSE); @@ -139,6 +140,15 @@ } } + function onOffsetChanged() { + + if (Math.random() * 100 > 95) { + + recalculate() + }; + + } + function recalculate(callBackFunction) { try { From acd61917d1dc3b5e71ae187005ec1867eeb757dd Mon Sep 17 00:00:00 2001 From: Luis Fernando Molina Date: Sat, 26 May 2018 12:31:10 +0200 Subject: [PATCH 47/54] Removing steps --- History.js | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/History.js b/History.js index 4e8bbf381..0853df74e 100644 --- a/History.js +++ b/History.js @@ -4,7 +4,7 @@ const INFO_LOG = false; const INTENSIVE_LOG = false; const ERROR_LOG = true; - const logger = newDebugLog(); + const logger = newWebDebugLog(); logger.fileName = MODULE_NAME; let thisObject = { @@ -184,13 +184,10 @@ let history = []; let lines = []; - - let oneMin = 60000; - let step = timePeriod / oneMin; - + /* First the small balls */ - for (let i = 0; i < file.length; i = i + step) { + for (let i = 0; i < file.length; i++) { let newHistoryRecord = { From a526524978db7c43cd0d8b8b18ceba1f952f5e76 Mon Sep 17 00:00:00 2001 From: Luis Fernando Molina Date: Sat, 30 Jun 2018 23:47:05 +0200 Subject: [PATCH 48/54] Reducing Points --- History.js | 107 +++++++++++++++++++++++++++++++++++++++++++---------- 1 file changed, 87 insertions(+), 20 deletions(-) diff --git a/History.js b/History.js index 0853df74e..391e6b8a8 100644 --- a/History.js +++ b/History.js @@ -16,6 +16,7 @@ getContainer: getContainer, setTimePeriod: setTimePeriod, setDatetime: setDatetime, + recalculateScale: recalculateScale, draw: draw, payload: { profile: { @@ -31,23 +32,26 @@ /* this is part of the module template */ - let container = newContainer(); // Do not touch this 3 lines, they are just needed. + let container = newContainer(); // Do not touch this 3 lines, they are just needed. container.initialize(); thisObject.container = container; let timeLineCoordinateSystem = newTimeLineCoordinateSystem(); // Needed to be able to plot on the timeline, otherwise not. - let timePeriod; // This will hold the current Time Period the user is at. - let datetime; // This will hold the current Datetime the user is at. + let timePeriod; // This will hold the current Time Period the user is at. + let datetime; // This will hold the current Datetime the user is at. /* these are module specific variables: */ let fileSequence; - let plotElements = []; // This is where the elements to be plotted are stored before plotting. - let plotLines = []; // Here we store the lines of open positions. - let notes = []; // Here we store the notes with messages from the bot. + let plotElements = []; // This is where the elements to be plotted are stored before plotting. + let plotLines = []; // Here we store the lines of open positions. + let notes = []; // Here we store the notes with messages from the bot. - let notesChangedEventRaised = true; // This controls when to raise the event that notes changed. + let notesChangedEventRaised = true; // This controls when to raise the event that notes changed. + + let previousNotesSetKey; + let currentNotesSetKey; return thisObject; @@ -187,7 +191,13 @@ /* First the small balls */ - for (let i = 0; i < file.length; i++) { + const ONE_MIN_IN_MILISECONDS = 60 * 1000; + let step = timePeriod / ONE_MIN_IN_MILISECONDS; + + let i = 0; + let lastRecordPushed = 0; + + for (i = 0; i < file.length; i = i + step) { let newHistoryRecord = { @@ -215,11 +225,12 @@ }; history.push(newHistoryRecord); + lastRecordPushed = i; + + /* Here we build the lines. */ if (timePeriod <= 1 * 60 * 1000) { - /* Here we build the lines. */ - if (newHistoryRecord.lastSellRate > 0) { lastSellRate = newHistoryRecord.lastSellRate; @@ -262,8 +273,45 @@ } } + } + /* We allways want to put the last record of the file on the filterd dataset, so as to allways show the latest advance of the bot. */ + + i = file.length - 1; + + if (lastRecordPushed !== i) { + + let newHistoryRecord = { + + date: Math.trunc(file[i][0] / 60000) * 60000 + 30000, + buyAvgRate: file[i][1], + sellAvgRate: file[i][2], + + lastSellRate: file[i][3], + sellExecRate: file[i][4], + lastBuyRate: file[i][5], + buyExecRate: file[i][6], + + marketRate: file[i][7], + newPositions: file[i][8], + newTrades: file[i][9], + movedPositions: file[i][10], + profitsAssetA: file[i][11], + profitsAssetB: file[i][12], + combinedProfitsA: file[i][13], + combinedProfitsB: file[i][14], + + messageRelevance: file[i][15], + messageTitle: file[i][16], + messageBody: file[i][17] + }; + + history.push(newHistoryRecord); + + } + + /* Second we process the text */ for (let i = 0; i < file.length; i++) { @@ -322,9 +370,10 @@ plotElements.push(history); plotLines.push(lines); - notesChangedEventRaised = false; } + notesChangedEventRaised = false; + thisObject.container.eventHandler.raiseEvent("History Changed", history); } catch (err) { @@ -437,8 +486,10 @@ record = history[i]; + let timestamp = Math.trunc(record.date / timePeriod) * timePeriod + timePeriod / 2; + point = { - x: record.date, + x: timestamp, y: record.marketRate }; @@ -468,12 +519,12 @@ browserCanvasContext.beginPath(); - browserCanvasContext.strokeStyle = 'rgba(27, 105, 7, ' + opacity + ')'; + browserCanvasContext.strokeStyle = 'rgba(' + UI_COLOR.DARK + ', ' + opacity + ')'; if (isCurrentRecord === false) { - browserCanvasContext.fillStyle = 'rgba(64, 217, 26, ' + opacity + ')'; + browserCanvasContext.fillStyle = 'rgba(' + UI_COLOR.LIGHT + ', ' + opacity + ')'; } else { - browserCanvasContext.fillStyle = 'rgba(255, 233, 31, ' + opacity + ')'; /* highlight the current record */ + browserCanvasContext.fillStyle = 'rgba(' + UI_COLOR.TITANIUM_YELLOW + ', ' + opacity + ')'; /* highlight the current record */ } browserCanvasContext.arc(point.x, point.y, radius, 0, Math.PI * 2, true); @@ -489,7 +540,7 @@ if (record.sellExecRate > 0) { - opacity = '0.3'; + opacity = '0.5'; let point1 = { x: record.date, @@ -551,7 +602,7 @@ if (record.buyExecRate > 0) { - opacity = '0.3'; + opacity = '0.5'; let point1 = { x: record.date, @@ -613,7 +664,7 @@ if (record.lastSellRate > 0) { - opacity = '0.3'; + opacity = '0.5'; let point1 = { x: record.date, @@ -675,7 +726,7 @@ if (record.lastBuyRate > 0) { - opacity = '0.3'; + opacity = '0.5'; let point1 = { x: record.date, @@ -790,6 +841,7 @@ /* Now we calculate the anchor position of notes. */ + currentNotesSetKey = ""; for (let i = 0; i < notes.length; i++) { @@ -807,18 +859,33 @@ if (note.position.x < (viewPort.visibleArea.bottomRight.x / 2) * (-1) || note.position.x > (viewPort.visibleArea.bottomRight.x) * (1.5)) { note.visible = false; + currentNotesSetKey = currentNotesSetKey + "0"; } else { note.visible = true; + currentNotesSetKey = currentNotesSetKey + "1"; } - } if (notesChangedEventRaised === false) { + /* In this case the event is raised because we might have a different set of notes. */ + thisObject.container.eventHandler.raiseEvent("Notes Changed", notes); thisObject.payload.notes = notes; notesChangedEventRaised = true; + + } else { + + if (currentNotesSetKey !== previousNotesSetKey) { + + /* In this case the event is raised because the visibility of some of the notes changed. */ + + thisObject.container.eventHandler.raiseEvent("Notes Changed", notes); + thisObject.payload.notes = notes; + + previousNotesSetKey = currentNotesSetKey; + } } } From 837a95bb433426f5918117ec9f324106bff8cbbc Mon Sep 17 00:00:00 2001 From: Julian Molina Date: Wed, 5 Dec 2018 14:25:21 +0100 Subject: [PATCH 49/54] Update LICENSE --- LICENSE | 685 ++------------------------------------------------------ 1 file changed, 24 insertions(+), 661 deletions(-) diff --git a/LICENSE b/LICENSE index dbbe35581..10e295746 100644 --- a/LICENSE +++ b/LICENSE @@ -1,661 +1,24 @@ - GNU AFFERO GENERAL PUBLIC LICENSE - Version 3, 19 November 2007 - - Copyright (C) 2007 Free Software Foundation, Inc. - Everyone is permitted to copy and distribute verbatim copies - of this license document, but changing it is not allowed. - - Preamble - - The GNU Affero General Public License is a free, copyleft license for -software and other kinds of works, specifically designed to ensure -cooperation with the community in the case of network server software. - - The licenses for most software and other practical works are designed -to take away your freedom to share and change the works. By contrast, -our General Public Licenses are intended to guarantee your freedom to -share and change all versions of a program--to make sure it remains free -software for all its users. - - When we speak of free software, we are referring to freedom, not -price. Our General Public Licenses are designed to make sure that you -have the freedom to distribute copies of free software (and charge for -them if you wish), that you receive source code or can get it if you -want it, that you can change the software or use pieces of it in new -free programs, and that you know you can do these things. - - Developers that use our General Public Licenses protect your rights -with two steps: (1) assert copyright on the software, and (2) offer -you this License which gives you legal permission to copy, distribute -and/or modify the software. - - A secondary benefit of defending all users' freedom is that -improvements made in alternate versions of the program, if they -receive widespread use, become available for other developers to -incorporate. Many developers of free software are heartened and -encouraged by the resulting cooperation. However, in the case of -software used on network servers, this result may fail to come about. -The GNU General Public License permits making a modified version and -letting the public access it on a server without ever releasing its -source code to the public. - - The GNU Affero General Public License is designed specifically to -ensure that, in such cases, the modified source code becomes available -to the community. It requires the operator of a network server to -provide the source code of the modified version running there to the -users of that server. Therefore, public use of a modified version, on -a publicly accessible server, gives the public access to the source -code of the modified version. - - An older license, called the Affero General Public License and -published by Affero, was designed to accomplish similar goals. This is -a different license, not a version of the Affero GPL, but Affero has -released a new version of the Affero GPL which permits relicensing under -this license. - - The precise terms and conditions for copying, distribution and -modification follow. - - TERMS AND CONDITIONS - - 0. Definitions. - - "This License" refers to version 3 of the GNU Affero General Public License. - - "Copyright" also means copyright-like laws that apply to other kinds of -works, such as semiconductor masks. - - "The Program" refers to any copyrightable work licensed under this -License. Each licensee is addressed as "you". "Licensees" and -"recipients" may be individuals or organizations. - - To "modify" a work means to copy from or adapt all or part of the work -in a fashion requiring copyright permission, other than the making of an -exact copy. The resulting work is called a "modified version" of the -earlier work or a work "based on" the earlier work. - - A "covered work" means either the unmodified Program or a work based -on the Program. - - To "propagate" a work means to do anything with it that, without -permission, would make you directly or secondarily liable for -infringement under applicable copyright law, except executing it on a -computer or modifying a private copy. Propagation includes copying, -distribution (with or without modification), making available to the -public, and in some countries other activities as well. - - To "convey" a work means any kind of propagation that enables other -parties to make or receive copies. Mere interaction with a user through -a computer network, with no transfer of a copy, is not conveying. - - An interactive user interface displays "Appropriate Legal Notices" -to the extent that it includes a convenient and prominently visible -feature that (1) displays an appropriate copyright notice, and (2) -tells the user that there is no warranty for the work (except to the -extent that warranties are provided), that licensees may convey the -work under this License, and how to view a copy of this License. If -the interface presents a list of user commands or options, such as a -menu, a prominent item in the list meets this criterion. - - 1. Source Code. - - The "source code" for a work means the preferred form of the work -for making modifications to it. "Object code" means any non-source -form of a work. - - A "Standard Interface" means an interface that either is an official -standard defined by a recognized standards body, or, in the case of -interfaces specified for a particular programming language, one that -is widely used among developers working in that language. - - The "System Libraries" of an executable work include anything, other -than the work as a whole, that (a) is included in the normal form of -packaging a Major Component, but which is not part of that Major -Component, and (b) serves only to enable use of the work with that -Major Component, or to implement a Standard Interface for which an -implementation is available to the public in source code form. A -"Major Component", in this context, means a major essential component -(kernel, window system, and so on) of the specific operating system -(if any) on which the executable work runs, or a compiler used to -produce the work, or an object code interpreter used to run it. - - The "Corresponding Source" for a work in object code form means all -the source code needed to generate, install, and (for an executable -work) run the object code and to modify the work, including scripts to -control those activities. However, it does not include the work's -System Libraries, or general-purpose tools or generally available free -programs which are used unmodified in performing those activities but -which are not part of the work. For example, Corresponding Source -includes interface definition files associated with source files for -the work, and the source code for shared libraries and dynamically -linked subprograms that the work is specifically designed to require, -such as by intimate data communication or control flow between those -subprograms and other parts of the work. - - The Corresponding Source need not include anything that users -can regenerate automatically from other parts of the Corresponding -Source. - - The Corresponding Source for a work in source code form is that -same work. - - 2. Basic Permissions. - - All rights granted under this License are granted for the term of -copyright on the Program, and are irrevocable provided the stated -conditions are met. This License explicitly affirms your unlimited -permission to run the unmodified Program. The output from running a -covered work is covered by this License only if the output, given its -content, constitutes a covered work. This License acknowledges your -rights of fair use or other equivalent, as provided by copyright law. - - You may make, run and propagate covered works that you do not -convey, without conditions so long as your license otherwise remains -in force. You may convey covered works to others for the sole purpose -of having them make modifications exclusively for you, or provide you -with facilities for running those works, provided that you comply with -the terms of this License in conveying all material for which you do -not control copyright. Those thus making or running the covered works -for you must do so exclusively on your behalf, under your direction -and control, on terms that prohibit them from making any copies of -your copyrighted material outside their relationship with you. - - Conveying under any other circumstances is permitted solely under -the conditions stated below. Sublicensing is not allowed; section 10 -makes it unnecessary. - - 3. Protecting Users' Legal Rights From Anti-Circumvention Law. - - No covered work shall be deemed part of an effective technological -measure under any applicable law fulfilling obligations under article -11 of the WIPO copyright treaty adopted on 20 December 1996, or -similar laws prohibiting or restricting circumvention of such -measures. - - When you convey a covered work, you waive any legal power to forbid -circumvention of technological measures to the extent such circumvention -is effected by exercising rights under this License with respect to -the covered work, and you disclaim any intention to limit operation or -modification of the work as a means of enforcing, against the work's -users, your or third parties' legal rights to forbid circumvention of -technological measures. - - 4. Conveying Verbatim Copies. - - You may convey verbatim copies of the Program's source code as you -receive it, in any medium, provided that you conspicuously and -appropriately publish on each copy an appropriate copyright notice; -keep intact all notices stating that this License and any -non-permissive terms added in accord with section 7 apply to the code; -keep intact all notices of the absence of any warranty; and give all -recipients a copy of this License along with the Program. - - You may charge any price or no price for each copy that you convey, -and you may offer support or warranty protection for a fee. - - 5. Conveying Modified Source Versions. - - You may convey a work based on the Program, or the modifications to -produce it from the Program, in the form of source code under the -terms of section 4, provided that you also meet all of these conditions: - - a) The work must carry prominent notices stating that you modified - it, and giving a relevant date. - - b) The work must carry prominent notices stating that it is - released under this License and any conditions added under section - 7. This requirement modifies the requirement in section 4 to - "keep intact all notices". - - c) You must license the entire work, as a whole, under this - License to anyone who comes into possession of a copy. This - License will therefore apply, along with any applicable section 7 - additional terms, to the whole of the work, and all its parts, - regardless of how they are packaged. This License gives no - permission to license the work in any other way, but it does not - invalidate such permission if you have separately received it. - - d) If the work has interactive user interfaces, each must display - Appropriate Legal Notices; however, if the Program has interactive - interfaces that do not display Appropriate Legal Notices, your - work need not make them do so. - - A compilation of a covered work with other separate and independent -works, which are not by their nature extensions of the covered work, -and which are not combined with it such as to form a larger program, -in or on a volume of a storage or distribution medium, is called an -"aggregate" if the compilation and its resulting copyright are not -used to limit the access or legal rights of the compilation's users -beyond what the individual works permit. Inclusion of a covered work -in an aggregate does not cause this License to apply to the other -parts of the aggregate. - - 6. Conveying Non-Source Forms. - - You may convey a covered work in object code form under the terms -of sections 4 and 5, provided that you also convey the -machine-readable Corresponding Source under the terms of this License, -in one of these ways: - - a) Convey the object code in, or embodied in, a physical product - (including a physical distribution medium), accompanied by the - Corresponding Source fixed on a durable physical medium - customarily used for software interchange. - - b) Convey the object code in, or embodied in, a physical product - (including a physical distribution medium), accompanied by a - written offer, valid for at least three years and valid for as - long as you offer spare parts or customer support for that product - model, to give anyone who possesses the object code either (1) a - copy of the Corresponding Source for all the software in the - product that is covered by this License, on a durable physical - medium customarily used for software interchange, for a price no - more than your reasonable cost of physically performing this - conveying of source, or (2) access to copy the - Corresponding Source from a network server at no charge. - - c) Convey individual copies of the object code with a copy of the - written offer to provide the Corresponding Source. This - alternative is allowed only occasionally and noncommercially, and - only if you received the object code with such an offer, in accord - with subsection 6b. - - d) Convey the object code by offering access from a designated - place (gratis or for a charge), and offer equivalent access to the - Corresponding Source in the same way through the same place at no - further charge. You need not require recipients to copy the - Corresponding Source along with the object code. If the place to - copy the object code is a network server, the Corresponding Source - may be on a different server (operated by you or a third party) - that supports equivalent copying facilities, provided you maintain - clear directions next to the object code saying where to find the - Corresponding Source. Regardless of what server hosts the - Corresponding Source, you remain obligated to ensure that it is - available for as long as needed to satisfy these requirements. - - e) Convey the object code using peer-to-peer transmission, provided - you inform other peers where the object code and Corresponding - Source of the work are being offered to the general public at no - charge under subsection 6d. - - A separable portion of the object code, whose source code is excluded -from the Corresponding Source as a System Library, need not be -included in conveying the object code work. - - A "User Product" is either (1) a "consumer product", which means any -tangible personal property which is normally used for personal, family, -or household purposes, or (2) anything designed or sold for incorporation -into a dwelling. In determining whether a product is a consumer product, -doubtful cases shall be resolved in favor of coverage. For a particular -product received by a particular user, "normally used" refers to a -typical or common use of that class of product, regardless of the status -of the particular user or of the way in which the particular user -actually uses, or expects or is expected to use, the product. A product -is a consumer product regardless of whether the product has substantial -commercial, industrial or non-consumer uses, unless such uses represent -the only significant mode of use of the product. - - "Installation Information" for a User Product means any methods, -procedures, authorization keys, or other information required to install -and execute modified versions of a covered work in that User Product from -a modified version of its Corresponding Source. The information must -suffice to ensure that the continued functioning of the modified object -code is in no case prevented or interfered with solely because -modification has been made. - - If you convey an object code work under this section in, or with, or -specifically for use in, a User Product, and the conveying occurs as -part of a transaction in which the right of possession and use of the -User Product is transferred to the recipient in perpetuity or for a -fixed term (regardless of how the transaction is characterized), the -Corresponding Source conveyed under this section must be accompanied -by the Installation Information. But this requirement does not apply -if neither you nor any third party retains the ability to install -modified object code on the User Product (for example, the work has -been installed in ROM). - - The requirement to provide Installation Information does not include a -requirement to continue to provide support service, warranty, or updates -for a work that has been modified or installed by the recipient, or for -the User Product in which it has been modified or installed. Access to a -network may be denied when the modification itself materially and -adversely affects the operation of the network or violates the rules and -protocols for communication across the network. - - Corresponding Source conveyed, and Installation Information provided, -in accord with this section must be in a format that is publicly -documented (and with an implementation available to the public in -source code form), and must require no special password or key for -unpacking, reading or copying. - - 7. Additional Terms. - - "Additional permissions" are terms that supplement the terms of this -License by making exceptions from one or more of its conditions. -Additional permissions that are applicable to the entire Program shall -be treated as though they were included in this License, to the extent -that they are valid under applicable law. If additional permissions -apply only to part of the Program, that part may be used separately -under those permissions, but the entire Program remains governed by -this License without regard to the additional permissions. - - When you convey a copy of a covered work, you may at your option -remove any additional permissions from that copy, or from any part of -it. (Additional permissions may be written to require their own -removal in certain cases when you modify the work.) You may place -additional permissions on material, added by you to a covered work, -for which you have or can give appropriate copyright permission. - - Notwithstanding any other provision of this License, for material you -add to a covered work, you may (if authorized by the copyright holders of -that material) supplement the terms of this License with terms: - - a) Disclaiming warranty or limiting liability differently from the - terms of sections 15 and 16 of this License; or - - b) Requiring preservation of specified reasonable legal notices or - author attributions in that material or in the Appropriate Legal - Notices displayed by works containing it; or - - c) Prohibiting misrepresentation of the origin of that material, or - requiring that modified versions of such material be marked in - reasonable ways as different from the original version; or - - d) Limiting the use for publicity purposes of names of licensors or - authors of the material; or - - e) Declining to grant rights under trademark law for use of some - trade names, trademarks, or service marks; or - - f) Requiring indemnification of licensors and authors of that - material by anyone who conveys the material (or modified versions of - it) with contractual assumptions of liability to the recipient, for - any liability that these contractual assumptions directly impose on - those licensors and authors. - - All other non-permissive additional terms are considered "further -restrictions" within the meaning of section 10. If the Program as you -received it, or any part of it, contains a notice stating that it is -governed by this License along with a term that is a further -restriction, you may remove that term. If a license document contains -a further restriction but permits relicensing or conveying under this -License, you may add to a covered work material governed by the terms -of that license document, provided that the further restriction does -not survive such relicensing or conveying. - - If you add terms to a covered work in accord with this section, you -must place, in the relevant source files, a statement of the -additional terms that apply to those files, or a notice indicating -where to find the applicable terms. - - Additional terms, permissive or non-permissive, may be stated in the -form of a separately written license, or stated as exceptions; -the above requirements apply either way. - - 8. Termination. - - You may not propagate or modify a covered work except as expressly -provided under this License. Any attempt otherwise to propagate or -modify it is void, and will automatically terminate your rights under -this License (including any patent licenses granted under the third -paragraph of section 11). - - However, if you cease all violation of this License, then your -license from a particular copyright holder is reinstated (a) -provisionally, unless and until the copyright holder explicitly and -finally terminates your license, and (b) permanently, if the copyright -holder fails to notify you of the violation by some reasonable means -prior to 60 days after the cessation. - - Moreover, your license from a particular copyright holder is -reinstated permanently if the copyright holder notifies you of the -violation by some reasonable means, this is the first time you have -received notice of violation of this License (for any work) from that -copyright holder, and you cure the violation prior to 30 days after -your receipt of the notice. - - Termination of your rights under this section does not terminate the -licenses of parties who have received copies or rights from you under -this License. If your rights have been terminated and not permanently -reinstated, you do not qualify to receive new licenses for the same -material under section 10. - - 9. Acceptance Not Required for Having Copies. - - You are not required to accept this License in order to receive or -run a copy of the Program. Ancillary propagation of a covered work -occurring solely as a consequence of using peer-to-peer transmission -to receive a copy likewise does not require acceptance. However, -nothing other than this License grants you permission to propagate or -modify any covered work. These actions infringe copyright if you do -not accept this License. Therefore, by modifying or propagating a -covered work, you indicate your acceptance of this License to do so. - - 10. Automatic Licensing of Downstream Recipients. - - Each time you convey a covered work, the recipient automatically -receives a license from the original licensors, to run, modify and -propagate that work, subject to this License. You are not responsible -for enforcing compliance by third parties with this License. - - An "entity transaction" is a transaction transferring control of an -organization, or substantially all assets of one, or subdividing an -organization, or merging organizations. If propagation of a covered -work results from an entity transaction, each party to that -transaction who receives a copy of the work also receives whatever -licenses to the work the party's predecessor in interest had or could -give under the previous paragraph, plus a right to possession of the -Corresponding Source of the work from the predecessor in interest, if -the predecessor has it or can get it with reasonable efforts. - - You may not impose any further restrictions on the exercise of the -rights granted or affirmed under this License. For example, you may -not impose a license fee, royalty, or other charge for exercise of -rights granted under this License, and you may not initiate litigation -(including a cross-claim or counterclaim in a lawsuit) alleging that -any patent claim is infringed by making, using, selling, offering for -sale, or importing the Program or any portion of it. - - 11. Patents. - - A "contributor" is a copyright holder who authorizes use under this -License of the Program or a work on which the Program is based. The -work thus licensed is called the contributor's "contributor version". - - A contributor's "essential patent claims" are all patent claims -owned or controlled by the contributor, whether already acquired or -hereafter acquired, that would be infringed by some manner, permitted -by this License, of making, using, or selling its contributor version, -but do not include claims that would be infringed only as a -consequence of further modification of the contributor version. For -purposes of this definition, "control" includes the right to grant -patent sublicenses in a manner consistent with the requirements of -this License. - - Each contributor grants you a non-exclusive, worldwide, royalty-free -patent license under the contributor's essential patent claims, to -make, use, sell, offer for sale, import and otherwise run, modify and -propagate the contents of its contributor version. - - In the following three paragraphs, a "patent license" is any express -agreement or commitment, however denominated, not to enforce a patent -(such as an express permission to practice a patent or covenant not to -sue for patent infringement). To "grant" such a patent license to a -party means to make such an agreement or commitment not to enforce a -patent against the party. - - If you convey a covered work, knowingly relying on a patent license, -and the Corresponding Source of the work is not available for anyone -to copy, free of charge and under the terms of this License, through a -publicly available network server or other readily accessible means, -then you must either (1) cause the Corresponding Source to be so -available, or (2) arrange to deprive yourself of the benefit of the -patent license for this particular work, or (3) arrange, in a manner -consistent with the requirements of this License, to extend the patent -license to downstream recipients. "Knowingly relying" means you have -actual knowledge that, but for the patent license, your conveying the -covered work in a country, or your recipient's use of the covered work -in a country, would infringe one or more identifiable patents in that -country that you have reason to believe are valid. - - If, pursuant to or in connection with a single transaction or -arrangement, you convey, or propagate by procuring conveyance of, a -covered work, and grant a patent license to some of the parties -receiving the covered work authorizing them to use, propagate, modify -or convey a specific copy of the covered work, then the patent license -you grant is automatically extended to all recipients of the covered -work and works based on it. - - A patent license is "discriminatory" if it does not include within -the scope of its coverage, prohibits the exercise of, or is -conditioned on the non-exercise of one or more of the rights that are -specifically granted under this License. You may not convey a covered -work if you are a party to an arrangement with a third party that is -in the business of distributing software, under which you make payment -to the third party based on the extent of your activity of conveying -the work, and under which the third party grants, to any of the -parties who would receive the covered work from you, a discriminatory -patent license (a) in connection with copies of the covered work -conveyed by you (or copies made from those copies), or (b) primarily -for and in connection with specific products or compilations that -contain the covered work, unless you entered into that arrangement, -or that patent license was granted, prior to 28 March 2007. - - Nothing in this License shall be construed as excluding or limiting -any implied license or other defenses to infringement that may -otherwise be available to you under applicable patent law. - - 12. No Surrender of Others' Freedom. - - If conditions are imposed on you (whether by court order, agreement or -otherwise) that contradict the conditions of this License, they do not -excuse you from the conditions of this License. If you cannot convey a -covered work so as to satisfy simultaneously your obligations under this -License and any other pertinent obligations, then as a consequence you may -not convey it at all. For example, if you agree to terms that obligate you -to collect a royalty for further conveying from those to whom you convey -the Program, the only way you could satisfy both those terms and this -License would be to refrain entirely from conveying the Program. - - 13. Remote Network Interaction; Use with the GNU General Public License. - - Notwithstanding any other provision of this License, if you modify the -Program, your modified version must prominently offer all users -interacting with it remotely through a computer network (if your version -supports such interaction) an opportunity to receive the Corresponding -Source of your version by providing access to the Corresponding Source -from a network server at no charge, through some standard or customary -means of facilitating copying of software. This Corresponding Source -shall include the Corresponding Source for any work covered by version 3 -of the GNU General Public License that is incorporated pursuant to the -following paragraph. - - Notwithstanding any other provision of this License, you have -permission to link or combine any covered work with a work licensed -under version 3 of the GNU General Public License into a single -combined work, and to convey the resulting work. The terms of this -License will continue to apply to the part which is the covered work, -but the work with which it is combined will remain governed by version -3 of the GNU General Public License. - - 14. Revised Versions of this License. - - The Free Software Foundation may publish revised and/or new versions of -the GNU Affero General Public License from time to time. Such new versions -will be similar in spirit to the present version, but may differ in detail to -address new problems or concerns. - - Each version is given a distinguishing version number. If the -Program specifies that a certain numbered version of the GNU Affero General -Public License "or any later version" applies to it, you have the -option of following the terms and conditions either of that numbered -version or of any later version published by the Free Software -Foundation. If the Program does not specify a version number of the -GNU Affero General Public License, you may choose any version ever published -by the Free Software Foundation. - - If the Program specifies that a proxy can decide which future -versions of the GNU Affero General Public License can be used, that proxy's -public statement of acceptance of a version permanently authorizes you -to choose that version for the Program. - - Later license versions may give you additional or different -permissions. However, no additional obligations are imposed on any -author or copyright holder as a result of your choosing to follow a -later version. - - 15. Disclaimer of Warranty. - - THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY -APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT -HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY -OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, -THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR -PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM -IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF -ALL NECESSARY SERVICING, REPAIR OR CORRECTION. - - 16. Limitation of Liability. - - IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING -WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS -THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY -GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE -USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF -DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD -PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), -EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF -SUCH DAMAGES. - - 17. Interpretation of Sections 15 and 16. - - If the disclaimer of warranty and limitation of liability provided -above cannot be given local legal effect according to their terms, -reviewing courts shall apply local law that most closely approximates -an absolute waiver of all civil liability in connection with the -Program, unless a warranty or assumption of liability accompanies a -copy of the Program in return for a fee. - - END OF TERMS AND CONDITIONS - - How to Apply These Terms to Your New Programs - - If you develop a new program, and you want it to be of the greatest -possible use to the public, the best way to achieve this is to make it -free software which everyone can redistribute and change under these terms. - - To do so, attach the following notices to the program. It is safest -to attach them to the start of each source file to most effectively -state the exclusion of warranty; and each file should have at least -the "copyright" line and a pointer to where the full notice is found. - - - Copyright (C) - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU Affero General Public License as published - by the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU Affero General Public License for more details. - - You should have received a copy of the GNU Affero General Public License - along with this program. If not, see . - -Also add information on how to contact you by electronic and paper mail. - - If your software can interact with users remotely through a computer -network, you should also make sure that it provides a way for users to -get its source. For example, if your program is a web application, its -interface could display a "Source" link that leads users to an archive -of the code. There are many ways you could offer source, and different -solutions will be better for different programs; see section 13 for the -specific requirements. - - You should also get your employer (if you work as a programmer) or school, -if any, to sign a "copyright disclaimer" for the program, if necessary. -For more information on this, and how to apply and follow the GNU AGPL, see -. +Financial Beings License + +Collective Copyright by the Advanced Algos Community + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software including without limitation the rights to use, copy, modify, +merge, publish, distribute and sublicense copies of the Software, and to permit +persons to whom the Software is furnished to do so, subject to the following +conditions: + + 1. Using, copying, modifying, publishing, distributing and sublicensing rights + are restricted to the Advanced Algos Platform, meaning the rights granted can + only be exercised through the Advanced Algos Service. + + 2. The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, +INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT +HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. From 26e166caeee4e3a9ff017aa81c5f14a1eb5559d8 Mon Sep 17 00:00:00 2001 From: Luis Fernando Molina Date: Tue, 26 Mar 2019 10:02:50 +0100 Subject: [PATCH 50/54] Finalize() function implemented --- History.js | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/History.js b/History.js index 391e6b8a8..842b9bd12 100644 --- a/History.js +++ b/History.js @@ -12,6 +12,7 @@ // Main functions and properties. initialize: initialize, + finalize: finalize, container: undefined, getContainer: getContainer, setTimePeriod: setTimePeriod, @@ -55,6 +56,32 @@ return thisObject; + function finalize() { + try { + + if (INFO_LOG === true) { logger.write("[INFO] finalize -> Entering function."); } + + /* Stop listening to the necesary events. */ + + viewPort.eventHandler.stopListening("Offset Changed", onOffsetChanged); + marketFiles.eventHandler.stopListening("Files Updated", onFilesUpdated); + + /* Destroyd References */ + + datetime = undefined; + timePeriod = undefined; + + fileSequence = undefined; + plotElements = undefined; + plotLines = undefined; + notes = undefined; + + } catch (err) { + + if (ERROR_LOG === true) { logger.write("[ERROR] finalize -> err.message = " + err.message); } + } + } + function initialize(pStorage, pExchange, pMarket, pDatetime, pTimePeriod, callBackFunction) { try { From 7830458f3d0bde159d2f3835327e0dcbbd991d1f Mon Sep 17 00:00:00 2001 From: Luis Fernando Molina Date: Thu, 11 Apr 2019 13:56:52 +0200 Subject: [PATCH 51/54] Adapted to new version of Canvas App --- History.js | 45 ++++++++++++++++++++++++--------------------- 1 file changed, 24 insertions(+), 21 deletions(-) diff --git a/History.js b/History.js index 842b9bd12..0917aa012 100644 --- a/History.js +++ b/History.js @@ -33,9 +33,8 @@ /* this is part of the module template */ - let container = newContainer(); // Do not touch this 3 lines, they are just needed. - container.initialize(); - thisObject.container = container; + thisObject.container = newContainer() + thisObject.container.initialize(MODULE_NAME) let timeLineCoordinateSystem = newTimeLineCoordinateSystem(); // Needed to be able to plot on the timeline, otherwise not. @@ -65,6 +64,7 @@ viewPort.eventHandler.stopListening("Offset Changed", onOffsetChanged); marketFiles.eventHandler.stopListening("Files Updated", onFilesUpdated); + thisObject.container.eventHandler.stopListening('Dimmensions Changed') /* Destroyd References */ @@ -99,11 +99,16 @@ fileSequence.eventHandler.listenToEvent("Files Updated", onFilesUpdated); // Only the first sequence is supported right now. viewPort.eventHandler.listenToEvent("Offset Changed", onOffsetChanged); + thisObject.container.eventHandler.listenToEvent('Dimmensions Changed', function () { + recalculate(callBackFunction); + recalculateScale(callBackFunction); + }) + callBackFunction(GLOBAL.DEFAULT_OK_RESPONSE); } catch (err) { - if (ERROR_LOG === true) { logger.write("[ERROR] initialize -> err = " + err); } + if (ERROR_LOG === true) { logger.write("[ERROR] initialize -> err = " + err.stack); } callBackFunction(GLOBAL.CUSTOM_FAIL_RESPONSE); } } @@ -118,9 +123,9 @@ /* First we check if this point is inside this space. */ - if (this.container.frame.isThisPointHere(point) === true) { + if (thisObject.container.frame.isThisPointHere(point) === true) { - return this.container; + return thisObject.container; } else { @@ -131,7 +136,7 @@ } catch (err) { - if (ERROR_LOG === true) { logger.write("[ERROR] initialize -> err = " + err); } + if (ERROR_LOG === true) { logger.write("[ERROR] initialize -> err = " + err.stack); } } } @@ -153,7 +158,7 @@ } catch (err) { - if (ERROR_LOG === true) { logger.write("[ERROR] setTimePeriod -> err = " + err); } + if (ERROR_LOG === true) { logger.write("[ERROR] setTimePeriod -> err = " + err.stack); } } } @@ -167,7 +172,7 @@ } catch (err) { - if (ERROR_LOG === true) { logger.write("[ERROR] setTimePeriod -> err = " + err); } + if (ERROR_LOG === true) { logger.write("[ERROR] setTimePeriod -> err = " + err.stack); } } } @@ -405,7 +410,7 @@ } catch (err) { - if (ERROR_LOG === true) { logger.write("[ERROR] recalculate -> err = " + err); } + if (ERROR_LOG === true) { logger.write("[ERROR] recalculate -> err = " + err.stack); } callBackFunction(GLOBAL.CUSTOM_FAIL_RESPONSE); } } @@ -466,14 +471,14 @@ } catch (err) { - if (ERROR_LOG === true) { logger.write("[ERROR] recalculateScale -> getMaxRate -> err = " + err); } + if (ERROR_LOG === true) { logger.write("[ERROR] recalculateScale -> getMaxRate -> err = " + err.stack); } callBackFunction(GLOBAL.CUSTOM_FAIL_RESPONSE); } } } catch (err) { - if (ERROR_LOG === true) { logger.write("[ERROR] recalculateScale -> err = " + err); } + if (ERROR_LOG === true) { logger.write("[ERROR] recalculateScale -> err = " + err.stack); } callBackFunction(GLOBAL.CUSTOM_FAIL_RESPONSE); } } @@ -488,7 +493,7 @@ } catch (err) { - if (ERROR_LOG === true) { logger.write("[ERROR] draw -> err = " + err); } + if (ERROR_LOG === true) { logger.write("[ERROR] draw -> err = " + err.stack); } } } @@ -496,7 +501,8 @@ try { - if (INTENSIVE_LOG === true) { logger.write("[INFO] plotChart -> Entering function."); } + let userPosition = getUserPosition() + let userPositionDate = userPosition.point.x let point = { x: 0, @@ -529,13 +535,10 @@ let isCurrentRecord = false; - if (datetime !== undefined) { - let dateValue = datetime.valueOf(); - if (dateValue >= record.date - timePeriod / 2 && dateValue <= record.date + timePeriod / 2 - 1) { - isCurrentRecord = true; - } + if (userPositionDate >= record.date - timePeriod / 2 && userPositionDate <= record.date + timePeriod / 2 - 1) { + isCurrentRecord = true; } - + let radius = 3; let opacity = '0.2'; @@ -929,7 +932,7 @@ } catch (err) { - if (ERROR_LOG === true) { logger.write("[ERROR] plotChart -> err = " + err); } + if (ERROR_LOG === true) { logger.write("[ERROR] plotChart -> err = " + err.stack); } } } } From 70c13b6e1135fddad51ea2b1c29e3f41556b32b8 Mon Sep 17 00:00:00 2001 From: Luis Fernando Molina Date: Wed, 17 Apr 2019 20:40:45 +0200 Subject: [PATCH 52/54] Variable Name Standarization --- Details.js | 2 +- History.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Details.js b/Details.js index f2977c987..fc3db73c1 100644 --- a/Details.js +++ b/Details.js @@ -338,7 +338,7 @@ var minValue = { - x: EARLIEST_DATE.valueOf() + x: MIN_PLOTABLE_DATE.valueOf() }; var maxValue = { diff --git a/History.js b/History.js index 0917aa012..824303d7b 100644 --- a/History.js +++ b/History.js @@ -426,7 +426,7 @@ if (timeLineCoordinateSystem.maxValue > 0) { return; } // Already calculated. let minValue = { - x: EARLIEST_DATE.valueOf(), + x: MIN_PLOTABLE_DATE.valueOf(), y: 0 }; From be7f12da2a6402796912b9b70ef85fe7150cf096 Mon Sep 17 00:00:00 2001 From: Luis Fernando Molina Date: Wed, 24 Apr 2019 20:37:53 +0200 Subject: [PATCH 53/54] EventHandling Improved --- History.js | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/History.js b/History.js index 824303d7b..10ad588bd 100644 --- a/History.js +++ b/History.js @@ -53,6 +53,10 @@ let previousNotesSetKey; let currentNotesSetKey; + let offsetChangedEventSubscriptionId + let filesUpdatedEventSubscriptionId + let dimmensionsChangedEventSubscriptionId + return thisObject; function finalize() { @@ -62,9 +66,9 @@ /* Stop listening to the necesary events. */ - viewPort.eventHandler.stopListening("Offset Changed", onOffsetChanged); - marketFiles.eventHandler.stopListening("Files Updated", onFilesUpdated); - thisObject.container.eventHandler.stopListening('Dimmensions Changed') + viewPort.eventHandler.stopListening(offsetChangedEventSubscriptionId); + fileSequence.eventHandler.stopListening(filesUpdatedEventSubscriptionId); + thisObject.container.eventHandler.stopListening(dimmensionsChangedEventSubscriptionId) /* Destroyd References */ @@ -96,10 +100,10 @@ recalculate(callBackFunction); recalculateScale(callBackFunction); - fileSequence.eventHandler.listenToEvent("Files Updated", onFilesUpdated); // Only the first sequence is supported right now. - viewPort.eventHandler.listenToEvent("Offset Changed", onOffsetChanged); + filesUpdatedEventSubscriptionId = fileSequence.eventHandler.listenToEvent("Files Updated", onFilesUpdated);// Only the first sequence is supported right now. + offsetChangedEventSubscriptionId = viewPort.eventHandler.listenToEvent("Offset Changed", onOffsetChanged); - thisObject.container.eventHandler.listenToEvent('Dimmensions Changed', function () { + immensionsChangedEventSubscriptionId = thisObject.container.eventHandler.listenToEvent('Dimmensions Changed', function () { recalculate(callBackFunction); recalculateScale(callBackFunction); }) From 316a2a8476eefd058bc2bd3baf3e88b36c12e6be Mon Sep 17 00:00:00 2001 From: Luis Fernando Molina Date: Sun, 28 Apr 2019 08:16:53 +0200 Subject: [PATCH 54/54] Removing INFO LOG and fixing BUG when scaling --- History.js | 17 ----------------- 1 file changed, 17 deletions(-) diff --git a/History.js b/History.js index 10ad588bd..aaf61d035 100644 --- a/History.js +++ b/History.js @@ -1,7 +1,6 @@ function newAAMastersPlottersTradingHistory() { const MODULE_NAME = "AAMasters Plotters Trading History"; - const INFO_LOG = false; const INTENSIVE_LOG = false; const ERROR_LOG = true; const logger = newWebDebugLog(); @@ -62,8 +61,6 @@ function finalize() { try { - if (INFO_LOG === true) { logger.write("[INFO] finalize -> Entering function."); } - /* Stop listening to the necesary events. */ viewPort.eventHandler.stopListening(offsetChangedEventSubscriptionId); @@ -90,8 +87,6 @@ try { - if (INFO_LOG === true) { logger.write("[INFO] initialize -> Entering function."); } - datetime = pDatetime; timePeriod = pTimePeriod; @@ -121,8 +116,6 @@ try { - if (INFO_LOG === true) { logger.write("[INFO] getContainer -> Entering function."); } - let container; /* First we check if this point is inside this space. */ @@ -154,8 +147,6 @@ try { - if (INFO_LOG === true) { logger.write("[INFO] setTimePeriod -> Entering function."); } - timePeriod = pTimePeriod; recalculate(); @@ -170,8 +161,6 @@ try { - if (INFO_LOG === true) { logger.write("[INFO] setDatetime -> Entering function."); } - datetime = newDatetime; } catch (err) { @@ -193,8 +182,6 @@ try { - if (INFO_LOG === true) { logger.write("[INFO] recalculate -> Entering function."); } - if (fileSequence === undefined) { return; } /* @@ -423,8 +410,6 @@ try { - if (INFO_LOG === true) { logger.write("[INFO] recalculateScale -> Entering function."); } - if (fileSequence === undefined) { return; } // We need the market file to be loaded to make the calculation. if (timeLineCoordinateSystem.maxValue > 0) { return; } // Already calculated. @@ -451,8 +436,6 @@ try { - if (INFO_LOG === true) { logger.write("[INFO] recalculateScale -> getMaxRate > Entering function."); } - let maxValue = 0; let maxSequence = fileSequence.getFilesLoaded();