ohlcv-indicators 1.2.5 → 1.2.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,2 +1 @@
1
- /*! For license information please see ohlcv-indicators.min.js.LICENSE.txt */
2
- var OHLCV_INDICATORS;(()=>{var t={978:function(t,i){!function(t){"use strict";var i=function(t,e){return(i=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(t,i){t.__proto__=i}||function(t,i){for(var e in i)Object.prototype.hasOwnProperty.call(i,e)&&(t[e]=i[e])})(t,e)},e=function(){return(e=Object.assign||function(t){for(var i,e=arguments,s=1,n=arguments.length;s<n;s++)for(var o in i=e[s])Object.prototype.hasOwnProperty.call(i,o)&&(t[o]=i[o]);return t}).apply(this,arguments)};function s(){for(var t=arguments,i=0,e=0,s=arguments.length;e<s;e++)i+=t[e].length;var n=Array(i),o=0;for(e=0;e<s;e++)for(var r=arguments[e],h=0,l=r.length;h<l;h++,o++)n[o]=r[h];return n}var n=function(){function t(t,i,e,s,n,o){void 0===o&&(o=null),this.forked=!1,this.forkedAt=0,this.lastForkY=null,this.step=s,this.index=n,this.length=0,this.startPoint=o?{y:t?o.h:o.l,x:o.x}:{y:t||i,x:e},this.init(t,i,e),this.thisPoint=this.startPoint}return t.prototype.init=function(t,i,e){this.type||(this.type=t?"h":"l"),this.candlePoint={y:"h"==this.type?t:i,x:e},this.thisPoint&&(this.prevPoint=this.thisPoint,this.nextPoint&&(this.thisPoint=this.nextPoint),this.nextPoint={y:this.k*(this.candlePoint.x+this.step)+this.b,x:this.candlePoint.x+this.step})},t.prototype.update=function(t,i,e){var s=null;if(this.length++,this.init(t,i,e),this.k&&!isNaN(this.k)||(this.k=(this.candlePoint.y-this.startPoint.y)/(this.candlePoint.x-this.startPoint.x),this.b=this.candlePoint.y-this.k*this.candlePoint.x,this.prevPoint=this.startPoint,this.thisPoint=this.candlePoint,this.nextPoint={y:this.k*(this.candlePoint.x+this.step)+this.b,x:this.candlePoint.x+this.step},s={condition:"h"==this.type?"lt":"gt",value:this.nextPoint.y,action:"fork",lineIndex:this.index}),"h"==this.type&&this.thisPoint.y<=this.candlePoint.y||"l"==this.type&&this.thisPoint.y>=this.candlePoint.y){this.k=(this.candlePoint.y-this.startPoint.y)/(this.candlePoint.x-this.startPoint.x),this.b=this.candlePoint.y-this.k*this.candlePoint.x,this.thisPoint=this.candlePoint,this.length=0,this.nextPoint={y:this.k*(this.candlePoint.x+this.step)+this.b,x:this.candlePoint.x+this.step};var n=this.rollback?this.rollback.length:0,o=this.candlePoint.y-this.prevPoint.y;("h"==this.type?o>0:o<0)?(this.rollback={k:o,b:this.candlePoint.y-o*this.candlePoint.x,length:n+1,lastForkTime:this.forkedAt||(this.rollback?this.rollback.lastForkTime:0),lastForkValue:this.forkedValue||(this.rollback?this.rollback.lastForkValue:0)},this.forked=!1,this.forkedAt=null,this.forkedValue=null):(this.forkedAt=this.candlePoint.x,this.forkedValue=this.candlePoint.y,this.forked=!0,this.rollback=null),s={condition:"h"==this.type?"lt":"gt",value:this.nextPoint.y,action:"fork",lineIndex:this.index}}else this.rollback=null;return s},t.prototype.updateStep=function(t){this.step=t},t}(),o=function(){function t(t){this.lineIndex=0,this.forkDiffH=null,this.forkDiffL=null,this.step=t,this.list=[[],[]],this.id={}}return t.prototype.add=function(t,i,e,s,o){void 0===s&&(s=null),void 0===o&&(o=null);var r,h,l,a=null;if(null==o?(r=this.lineIndex,this.lineIndex++,null!=t?this.list[0].push(r):this.list[1].push(r)):(r=o,a=this.id[r].lastForkY||(null!=t?s.h:s.l)),this.id[r]=new n(t,i,e,this.step,r,s),a&&(this.id[r].lastForkY=a),r>1||null!=o&&null!=this.id[o]){h=null!=o?o:this.list["h"==this.id[r].type?0:1][this.list["h"==this.id[r].type?0:1].indexOf(r)-1],l=null!=o?o:this.list["h"==this.id[r].type?0:1][this.list["h"==this.id[r].type?0:1].indexOf(r)-2];var u=this.id[h].lastForkY;l&&!u&&(u=this.id[l].lastForkY);var c=null!=t?s.h:s.l;u&&(t?this.forkDiffH=u>=c?-h-1:h+1:this.forkDiffL=u>=c?-h-1:h+1),this.id[h].lastForkY=c}return r},t.prototype.update=function(t,i,e,s){return this.id[t].update(i,e,s)},t.prototype.delete=function(t){this.id[t]&&("h"==this.id[t].type?this.list[0].splice(this.list[0].indexOf(t),1):this.list[1].splice(this.list[1].indexOf(t),1),delete this.id[t])},t}(),r=function(){function t(t,i){this.kdiff=[],this.env=i,this.lines=t,this.in={state:null,lineIndex:null,line:null},this.is={state:null,lineIndex:null,line:null,start:null,size:0},this.was={state:null,lineIndex:null,line:null,size:null},this.width=0,this.speed=0,this.at=0}return t.prototype.update=function(t,i){var s=this;if(t.length>1?this.hlMaxDuration=t.map((function(t){return s.lines.id[t]})).filter((function(t){return!s.is.line||(t.forkedAt?t.forkedAt>s.is.line.startPoint.x:!!t.rollback&&t.rollback.lastForkTime>s.is.line.startPoint.x)})).reduce((function(t,i){return t.length>i.length?t:i}),this.lines.id[t[0]]):this.hlMaxDuration=this.lines.id[t[0]],i.length>1?this.llMaxDuration=i.map((function(t){return s.lines.id[t]})).filter((function(t){return!s.is.line||(t.forkedAt?t.forkedAt>s.is.line.startPoint.x:!!t.rollback&&t.rollback.lastForkTime>s.is.line.startPoint.x)})).reduce((function(t,i){return t.length>i.length?t:i}),this.lines.id[i[0]]):this.llMaxDuration=this.lines.id[i[0]],null==this.is.state&&null==this.was.state&&(this.is.line=this.llMaxDuration&&this.llMaxDuration.length>this.env.minLength&&this.hlMaxDuration.length<this.env.minLength?this.llMaxDuration:this.hlMaxDuration&&this.hlMaxDuration.length>this.env.minLength&&this.llMaxDuration.length<this.env.minLength?this.hlMaxDuration:null,this.is.line&&(this.is.lineIndex=this.is.line.index,this.is.state="h"==this.is.line.type?"fall":"rise",this.is.start=this.is.line.candlePoint)),this.is.state){this.is.size=Math.max(this.is.size,Math.abs(this.is.start.y-this.is.line.candlePoint.y));var n,o=this.lines.id[this.is.lineIndex]||this.lines.id["h"==this.is.line.type?0:1],r=null,h=null,l=this.lines.list["h"==o.type?1:0].filter((function(t){return s.lines.id[t].forked&&s.lines.id[t].thisPoint.x-s.lines.id[t].forkedAt>12}));l.length>1?l[1]:l.length>0&&l[0];var a=l.filter((function(t){return s.lines.id[t].forkedAt>s.is.start.x}));if(o&&this.lines.list["h"==o.type?0:1].forEach((function(t,i){var e=s.lines.id[t];if(t>=o.index&&null!=e.rollback){n=s.lines.list["h"==o.type?0:1][i-1];var l=1==s.env.deltaModel&&i>1&&n&&s.lines.id[n]?i>1&&n&&s.lines.id[n].lastForkY:s.lines.id[t>0?t-1:0];h=l?s.lines.id[t>1?n:"h"==o.type?0:1].lastForkY-e.candlePoint.y:e.rollback?e.rollback.lastForkValue-e.candlePoint.y:0,e.rollback.lastForkValue>0&&e.thisPoint.x-e.rollback.lastForkTime>s.env.minRightLeg&&("fall"==s.is.state?s.llMaxDuration.length>1:s.hlMaxDuration.length>1)&&(("h"==o.type?h<0:h>0)||e.rollback.length>s.env.rollbackLength||2*s.is.size/3>Math.abs(s.is.start.y-s.is.line.candlePoint.y)&&s.is.size>s.is.line.candlePoint.y*s.env.minIsSizeOnRollback&&a.length>1||("h"==o.type?e.candlePoint.y>s.is.start.y&&1==s.lines.list[0].length:e.candlePoint.y<s.is.start.y&&1==s.lines.list[1].length))&&(e.candlePoint.x-e.rollback.lastForkTime>s.env.forkDurationMin&&e.candlePoint.x-e.rollback.lastForkTime<s.env.forkDurationMax||("h"==o.type?e.candlePoint.y>e.startPoint.y:e.candlePoint.y<e.startPoint.y)||("h"==o.type?e.candlePoint.y>s.is.start.y&&1==s.lines.list[0].length:e.candlePoint.y<s.is.start.y&&1==s.lines.list[1].length))&&(r=t+1)}})),r){this.in.size=(this.was.size||0)+this.is.size;var u=this.lines.id[0].candlePoint.y-this.is.start.y,c="rise"==this.is.state?u>=0:u<0;this.was.size&&(this.in.state=this.was.size>this.is.size?this.was.state:this.is.state),this.was=e({},this.is),this.was.success=c,this.is.line="fall"==this.is.state?this.llMaxDuration:this.hlMaxDuration,this.is.state="h"==this.is.line.type?"fall":"rise",this.is.lineIndex=this.is.line.index,this.is.start=this.lines.id[0].candlePoint,this.is.size=0}}},t}(),h=function(){function t(t){this.hLineDirectives=[],this.lLineDirectives=[],this.step=1,this.i=0,this.localCounter=0,this.prevPoint=null,this.env=Object.assign({step:1,minLength:5,minRightLeg:3,maxForks:500,minLog:0,maxLog:0,rollbackLength:3,deltaModel:1,minIsSizeOnRollback:.05},t),this.env.minLength=Math.round(this.env.minLength/this.env.step)||1,this.env.minRightLeg=Math.round(this.env.minRightLeg/this.env.step)||1,this.env.rollbackLength=Math.round(this.env.rollbackLength/this.env.step)||1,this.env.forkDurationMin=Math.round(this.env.forkDurationMin/this.env.step)||1,this.env.forkDurationMax=Math.round(this.env.forkDurationMax/this.env.step)||1,this.lines=new o(this.step),this.trend=new r(this.lines,this.env)}return t.prototype.log=function(t){for(var i=arguments,e=[],n=1;n<arguments.length;n++)e[n-1]=i[n];this.consoleWindow=this.env.minLog<this.localCounter&&this.localCounter<this.env.maxLog,this.consoleWindow&&console.log.apply(console,s([t],e))},t.prototype.nextValue=function(t,i,e,s){var n,o=this;this.localCounter++,this.lLineDirectives.length>0&&this.lLineDirectives.forEach((function(t,i){var e=o.lines.id[t.lineIndex];"gt"==t.condition&&s>t.value&&"fork"==t.action&&e&&(null!=t.lineIndex&&null!=e&&e.k<0?o.lines.add(null,s,o.i-1,o.prevPoint,t.lineIndex):(e.forked=!0,e.forkedAt=e.thisPoint.x,e.forkedValue=e.thisPoint.y,o.lines.add(null,s,o.i-1,o.prevPoint)))})),this.hLineDirectives.length>0&&this.hLineDirectives.forEach((function(t,i){var s=o.lines.id[t.lineIndex];"lt"==t.condition&&e<t.value&&"fork"==t.action&&s&&(s.k>0?o.lines.add(e,null,o.i-1,o.prevPoint,t.lineIndex):(s.forked=!0,s.forkedAt=s.thisPoint.x,s.forkedValue=s.thisPoint.y,o.lines.add(e,null,o.i-1,o.prevPoint)))})),this.hLineDirectives.length=0,this.lLineDirectives.length=0,this.lines.list[0].length<1?(this.lines.add(e,null,this.i),this.lines.add(null,s,this.i)):this.lines.list.forEach((function(t){return t.forEach((function(t){var i=o.lines.id[t];if(i&&i.type){n=null,i&&i.startPoint.x<o.i&&(n=o.lines.update(t,e,s,o.i));var r=i.type;n&&("h"==r?o.hLineDirectives.push(n):o.lLineDirectives.push(n))}}))}));var r=[];return this.lines.list.forEach((function(t){t&&(r=[],t.forEach((function(i,e){var s=o.lines.id[t[e]],n=o.lines.id[t[e-1]];(e>0&&s&&n&&"h"==s.type&&s.thisPoint&&n.thisPoint.y<=s.thisPoint.y||e>o.env.maxForks||e>0&&s&&n&&"l"==s.type&&s.thisPoint&&n.thisPoint.y>=s.thisPoint.y||e>o.env.maxForks)&&r.push(i)})),r.forEach((function(t){return o.lines.delete(t)})))})),this.prevPoint={x:this.i,h:e,l:s},this.trend.update(this.lines.list[0],this.lines.list[1]),this.i++,this.lines},t}(),l=Object.freeze({__proto__:null,Indicator:h}),a=function(){function t(t){this.length=t,this.filled=!1,this.pointer=0,this.buffer=new Array(t),this.maxIndex=t-1}return t.prototype.push=function(t){var i=this.buffer[this.pointer];return this.buffer[this.pointer]=t,this.iteratorNext(),i},t.prototype.pushback=function(t){this.iteratorPrev();var i=this.buffer[this.pointer];return this.buffer[this.pointer]=t,i},t.prototype.peek=function(){return this.buffer[this.pointer]},t.prototype.forEach=function(t){for(var i=this.pointer,e=0;e!==this.length;)t(this.buffer[i],e),i=(this.length+i+1)%this.length,e++},t.prototype.forEachRight=function(t){for(var i=(this.length+this.pointer-1)%this.length,e=this.length-1;e!==this.length;)t(this.buffer[i],e),i=(this.length+i-1)%this.length,e--},t.prototype.fill=function(t){this.buffer.fill(t),this.filled=!0},t.prototype.toArray=function(){return this.buffer},t.prototype.iteratorNext=function(){this.pointer++,this.pointer>this.maxIndex&&(this.pointer=0,this.filled=!0)},t.prototype.iteratorPrev=function(){this.pointer--,this.pointer<0&&(this.pointer=this.maxIndex)},t}(),u=function(t){function e(i,e){void 0===i&&(i=100);var s=t.call(this,i)||this;return s.period=i,s.mode=e,s.comparator="max"===e?s.maxComporator:s.mminComporator,s}return function(t,e){function s(){this.constructor=t}i(t,e),t.prototype=null===e?Object.create(e):(s.prototype=e.prototype,new s)}(e,t),e.prototype.nextValue=function(t){return this.push(t),this.getExtremum()},e.prototype.momentValue=function(t){var i=this.push(t),e=this.getExtremum();return this.pushback(i),e},e.prototype.maxComporator=function(t,i){return t>i},e.prototype.mminComporator=function(t,i){return t<i},e.prototype.getExtremum=function(t){var i=(this.length+this.pointer-2)%this.length,e="max"===this.mode?-1/0:1/0;if(!this.filled)return 0;for(;i!==this.pointer;){var s=this.buffer[(this.length+i-1)%this.length],n=this.buffer[(this.length+i+1)%this.length],o=this.buffer[i];if(this.comparator(o,e)&&this.comparator(o,s)&&this.comparator(o,n)){if(e=o,this.prevIx===i)return null;if(this.prevIx=i,t)return e}i=(this.length+i-1)%this.length}return isFinite(e)?e:(this.prevIx=null,null)},e}(a),c=function(){function t(t){this.period=t,this.sum=0,this.circular=new a(t)}return t.prototype.nextValue=function(t){var i=this;if(this.circular.push(t),this.sum+=t,this.circular.filled)return this.nextValue=function(t){return i.sum=i.sum-i.circular.push(t)+t,i.sum/i.period},this.momentValue=function(t){return(i.sum-i.circular.peek()+t)/i.period},this.sum/this.period},t.prototype.momentValue=function(t){},t}(),p=function(){function t(t){this.period=t,this.smooth=1/this.period,this.sma=new c(this.period)}return t.prototype.nextValue=function(t){return this.wema?this.wema=(t-this.wema)*this.smooth+this.wema:this.wema=this.sma.nextValue(t)},t.prototype.momentValue=function(t){return this.wema?(t-this.wema)*this.smooth+this.wema:this.sma.momentValue(t)},t}(),d=function(){function t(t){this.period=t,this.smooth=2/(this.period+1),this.sma=new c(this.period)}return t.prototype.nextValue=function(t){var i=this,e=this.sma.nextValue(t);return e&&(this.ema=e,this.nextValue=function(t){return i.ema=(t-i.ema)*i.smooth+i.ema},this.momentValue=function(t){return(t-i.ema)*i.smooth+i.ema}),e},t.prototype.momentValue=function(t){},t}(),f=function(){function t(t,i){this.indicator=t,this.samples=i,this._indicators=[]}return t.prototype.create=function(){for(var t,i=arguments,e=[],n=0;n<arguments.length;n++)e[n]=i[n];for(var o=0;o<this.samples;o++)this._indicators.push(new((t=this.indicator).bind.apply(t,s([void 0],e))))},t.prototype.nextValue=function(t){for(var i=0;i<this.samples;i++)if(void 0===(t=this._indicators[i].nextValue(t)))return t;return t},t.prototype.momentValue=function(t){for(var i=0;i<this.samples;i++)if(null==(t=this._indicators[i].momentValue(t)))return t;return t},t}(),m=function(){function t(t,i,e,s,n){void 0===t&&(t=.85),void 0===s&&(s=1),void 0===n&&(n=1),this.redunant=t,this.multiplier=s,this.offset=n,this.prevValue=0,this.lastUpperValue=0,this.lastLowerValue=0,this.samplerUp=new f(i,e),this.samplerLow=new f(i,e)}return t.prototype.create=function(){for(var t,i,e=arguments,s=[],n=0;n<arguments.length;n++)s[n]=e[n];(t=this.samplerUp).create.apply(t,s),(i=this.samplerLow).create.apply(i,s)},t.prototype.nextValue=function(t){this.lastUpperValue=t>0?Math.max(t,this.prevValue):Math.max(0,this.lastUpperValue)*this.redunant,this.lastLowerValue=t<=0?Math.min(t,this.prevValue):Math.min(0,this.lastLowerValue)*this.redunant;var i=(t<=0?t:this.lastLowerValue)*this.multiplier,e=(t>=0?t:this.lastUpperValue)*this.multiplier;return[this.samplerUp.nextValue(e)+this.offset,this.samplerLow.nextValue(i)-this.offset]},t}(),v=function(){function t(t,i,e,s){void 0===e&&(e=.85),void 0===s&&(s="WEMA"),this.period=t,this.samples=i,this.redunant=e,this.type=s,this.upper=0,this.lower=0,this.lastUpperValue=0,this.lastLowerValue=0,this.sample1Up=this.createSample(),this.sample2Up=this.createSample(),this.sample3Up=this.createSample(),this.sample1Low=this.createSample(),this.sample2Low=this.createSample(),this.sample3Low=this.createSample()}return t.prototype.nextValue=function(t){return t>0?(this.upper=this.getUp(t),this.lastLowerValue*=this.redunant,this.lower=this.getDown(this.lastLowerValue),this.lastUpperValue=t):t<0&&(this.lower=this.getDown(t),this.lastUpperValue*=this.redunant,this.upper=this.getUp(this.lastUpperValue),this.lastLowerValue=t),{upper:this.upper,lower:this.lower}},t.prototype.getUp=function(t){var i=this.sample1Up.nextValue(t),e=null;return 1===this.samples?i:(i&&(e=this.sample2Up.nextValue(i)),2===this.samples?e:e?this.sample3Up.nextValue(e):null)},t.prototype.getDown=function(t){var i=this.sample1Low.nextValue(t),e=null;return 1===this.samples?i:(i&&(e=this.sample2Low.nextValue(i)),2===this.samples?e:e?this.sample3Low.nextValue(e):null)},t.prototype.createSample=function(){switch(this.type){case"EMA":return new d(this.period);case"WEMA":return new p(this.period);case"SMA":return new c(this.period)}},t}(),g=function(){function t(t){this.period=t,this.SMAx=new c(this.period),this.SMAy=new c(this.period),this.pricesX=new a(this.period),this.pricesY=new a(this.period)}return t.prototype.nextValue=function(t,i){this.pricesX.push(t),this.pricesY.push(i),this.SMAxValue=this.SMAx.nextValue(t),this.SMAyValue=this.SMAy.nextValue(i);for(var e=0,s=0,n=0,o=0;o<this.period;o++){var r=this.pricesX.toArray()[o],h=this.pricesY.toArray()[o];e+=(r-this.SMAxValue)*(h-this.SMAyValue),s+=Math.pow(r-this.SMAxValue,2),n+=Math.pow(h-this.SMAyValue,2)}return e/Math.sqrt(s*n)},t}(),w=function(){function t(t){this.period=t,this.denominator=t*(t+1)/2,this.buffer=new a(t),this.values=[]}return t.prototype.nextValue=function(t){var i=this;if(this.buffer.push(t),this.buffer.filled){var e=0;return this.buffer.forEach((function(t,s){e+=t*(s+1)/i.denominator})),e}},t.prototype.momentValue=function(t){var i=this,e=this.buffer.push(t);if(this.buffer.filled){var s=0;return this.buffer.forEach((function(t,e){s+=t*(e+1)/i.denominator})),this.buffer.pushback(e),s}this.buffer.pushback(e)},t}(),x=function(){function t(t){void 0===t&&(t=.2),this.alpha=t,this.filled=!1}return t.prototype.nextValue=function(t){var i=this.alpha*t+(1-this.alpha)*(this.prevValue||1);if(this.filled=this.filled||void 0!==this.prevValue,this.prevValue=i,this.filled)return i},t.prototype.momentValue=function(t){if(this.filled)return this.alpha*t+(1-this.alpha)*(this.prevValue||1)},t}(),V=function(){function t(t){this.period=t,this.sum=0,this.avg=0,this.filled=!1,this.fill=0}return t.prototype.nextValue=function(t){var i=this;return this.filled?(this.nextValue=function(t){return i.avg=(i.avg*(i.period-1)+t)/i.period},this.nextValue(t)):(this.sum+=t,this.fill++,this.fill===this.period?(this.filled=!0,this.avg=this.sum/this.period,this.avg):void 0)},t.prototype.momentValue=function(t){if(this.filled)return(this.avg*(this.period-1)+t)/this.period},t}(),y=function(){function t(t){void 0===t&&(t=14),this.period=t,this.alpha=1/t,this.sma=new c(this.period)}return t.prototype.nextValue=function(t){var i=this;return this.prevValue?(this.prevValue=this.alpha*t+(1-this.alpha)*this.prevValue,this.nextValue=function(t){return i.prevValue=i.alpha*t+(1-i.alpha)*i.prevValue,i.prevValue}):this.prevValue=this.sma.nextValue(t),this.prevValue},t.prototype.momentValue=function(t){if(this.prevValue)return this.alpha*t+(1-this.alpha)*this.prevValue},t}(),M=function(){function t(t,i){void 0===t&&(t=5),void 0===i&&(i=34),this.smaSlow=new c(i),this.smaFast=new c(t)}return t.prototype.nextValue=function(t,i){var e=this;if(this.smaSlowValue=this.smaSlow.nextValue((t+i)/2),this.smaFastValue=this.smaFast.nextValue((t+i)/2),void 0!==this.smaSlowValue&&void 0!==this.smaFastValue)return this.nextValue=function(t,i){return e.smaSlowValue=e.smaSlow.nextValue((t+i)/2),e.smaFastValue=e.smaFast.nextValue((t+i)/2),e.smaFastValue-e.smaSlowValue},this.momentValue=function(t,i){return e.smaFast.momentValue((t+i)/2)-e.smaSlow.momentValue((t+i)/2)},this.smaFastValue-this.smaSlowValue},t.prototype.momentValue=function(t,i){},t}(),P=function(){function t(){this.sma=new c(5),this.ao=new M}return t.prototype.nextValue=function(t,i){var e=this;if(this.aoValue=this.ao.nextValue(t,i),void 0!==this.aoValue&&(this.smaValue=this.sma.nextValue(this.aoValue),void 0!==this.smaValue))return this.nextValue=function(t,i){return e.aoValue=e.ao.nextValue(t,i),e.smaValue=e.sma.nextValue(e.aoValue),e.aoValue-e.smaValue},this.momentValue=function(t,i){return e.ao.momentValue(t,i)-e.sma.momentValue(e.aoValue)},this.aoValue-this.smaValue},t.prototype.momentValue=function(t,i){},t}(),k=function(t,i){return(t-i)/i*100},b=function(){function t(t){this.period=t,this.value=0,this.changes=new a(t)}return t.prototype.nextValue=function(t){if(this.prevPrice){var i=k(t,this.prevPrice);return this.calculate(i),this.prevPrice=t,this.value}this.prevPrice=t},t.prototype.calculate=function(t){return this.value+=t,this.value-=this.changes.push(t),this.value},t}();function A(t){return t.consolidate=0,t.power=0,t.streak=0,t.diff=0,t.startPrice=0,t.prevPeak=0,t}var S=function(){function t(){this.up={consolidate:0,power:0,streak:0,startPrice:0,diff:0,prevPeak:0},this.down={consolidate:0,power:0,streak:0,startPrice:0,diff:0,prevPeak:0}}return t.prototype.nextValue=function(t,i,s,n){if(t<i||this.up.streak&&this.up.prevPeak<n){this.up.startPrice||(this.up.startPrice=t),this.down.streak&&A(this.down);var o=i-t;this.up.streak++,this.up.prevPeak=n,this.up.diff>o?this.up.consolidate++:this.up.consolidate=0,this.up.diff=o,this.up.power=k(i,this.up.startPrice)}return(t>i||this.down.streak&&this.down.prevPeak>s)&&(this.down.startPrice||(this.down.startPrice=t),this.up.streak&&A(this.up),o=t-i,this.down.streak++,this.down.prevPeak=s,this.down.diff>o?this.down.consolidate++:this.down.consolidate=0,this.down.diff=o,this.down.power=k(i,this.down.startPrice)),t===i&&(this.up.streak++,this.down.streak++,this.up.diff=this.down.diff=0),this.up.streak>this.down.streak?e({},this.up):e({},this.down)},t}(),L=function(){function t(t){this.max=-1/0,this.highest=new a(t)}return t.prototype.filled=function(){return this.highest.filled},t.prototype.nextValue=function(t){return this.max<t&&(this.max=t),this.highest.push(t)===this.max&&t!==this.max&&(this.max=function(t){for(var i=-1/0,e=t.length-1;e>=0;e--){var s=t[e];i<s&&(i=s)}return i}(this.highest.toArray())),this.max},t.prototype.momentValue=function(t){return this.max>t?this.max:t},t}(),D=function(){function t(t){this.min=1/0,this.lowest=new a(t)}return t.prototype.filled=function(){return this.lowest.filled},t.prototype.nextValue=function(t){return this.min>t&&(this.min=t),this.lowest.push(t)===this.min&&t!==this.min&&(this.min=function(t){for(var i=1/0,e=t.length-1;e>=0;e--){var s=t[e];i>s&&(i=s)}return i}(this.lowest.toArray())),this.min},t.prototype.momentValue=function(t){return this.min<t?this.min:t},t}(),C=function(){function t(t,i){void 0===t&&(t=14),void 0===i&&(i=3),this.period=t,this.smaPeriod=i,this.sma=new c(this.smaPeriod),this.max=new L(t),this.min=new D(t)}return t.prototype.nextValue=function(t,i,e){var s=this.max.nextValue(t),n=this.min.nextValue(i);if(this.max.filled()){var o=(e-n)/(s-n)*100;return{k:o,d:this.sma.nextValue(o)}}},t.prototype.momentValue=function(t,i,e){if(this.max.filled()){var s=this.max.momentValue(t),n=this.min.momentValue(i),o=(e-n)/(s-n)*100;return{k:o,d:this.sma.momentValue(o)}}},t}(),F=function(){function t(t){this.avgGain=new V(t),this.avgLoss=new V(t)}return t.prototype.nextValue=function(t){var i=t-this.prev;if(this.prev){var e=i>0?i:0,s=i<0?i:0,n=this.avgGain.nextValue(e),o=this.avgLoss.nextValue(s);return this.prev=t,{upAvg:n,downAvg:o}}this.prev=t},t.prototype.momentValue=function(t){var i=t-this.prev,e=i>0?i:0,s=i<0?i:0;return{upAvg:this.avgGain.momentValue(e),downAvg:this.avgLoss.momentValue(s)}},t}(),_=function(){function t(t){void 0===t&&(t=14),this.period=t,this.change=new F(this.period)}return t.prototype.nextValue=function(t){var i=this.change.nextValue(t)||{},e=i.downAvg,s=i.upAvg;if(void 0!==s&&void 0!==e)return 100-100/(1+s/-e)},t.prototype.momentValue=function(t){var i=this.change.momentValue(t)||{},e=i.downAvg,s=i.upAvg;if(void 0!==s&&void 0!==e)return 100-100/(1+s/-e)},t}(),B=function(){function t(t,i,e,s){void 0===t&&(t=14),void 0===i&&(i=3),void 0===e&&(e=3),void 0===s&&(s=14),this.rsi=new _(t),this.sma1=new c(i),this.sma2=new c(e),this.max=new L(s),this.min=new D(s)}return t.prototype.nextValue=function(t){var i=this.rsi.nextValue(t);if(void 0!==i){var e=this.max.nextValue(i),s=this.min.nextValue(i);if(this.max.filled()){var n=(i-s)/(e-s)*100,o=this.sma1.nextValue(n);if(void 0!==o)return{k:o,d:this.sma2.nextValue(o),stochRsi:n}}}},t.prototype.momentValue=function(t){if(this.max.filled()){var i=this.rsi.momentValue(t),e=this.max.momentValue(i),s=this.min.momentValue(i),n=(i-s)/(e-s)*100,o=this.sma1.momentValue(n);return{k:o,d:this.sma2.momentValue(o),stochRsi:n}}},t}(),I=function(){function t(t){this.period=t,this.values=new a(t)}return t.prototype.nextValue=function(t,i){if(i)return this.nextValue=this.pureNextValue,this.momentValue=this.pureMomentValue,this.pureNextValue(t,i);this.values.push(t)},t.prototype.momentValue=function(t,i){},t.prototype.pureNextValue=function(t,i){var e=this;return this.values.push(t),this.values.toArray().reduce((function(t,s){return t+e.positiveDelta(i,s)}),0)/this.period},t.prototype.pureMomentValue=function(t,i){var e=this,s=this.values.push(t),n=this.values.toArray().reduce((function(t,s){return t+e.positiveDelta(i,s)}),0);return this.values.pushback(s),n/this.period},t.prototype.positiveDelta=function(t,i){return t>i?t-i:i-t},t}(),T=function(){function t(t){void 0===t&&(t=20),this.md=new I(t),this.sma=new c(t)}return t.prototype.nextValue=function(t,i,e){var s=(t+i+e)/3,n=this.sma.nextValue(s),o=this.md.nextValue(s,n);return o&&(s-n)/(.015*o)},t.prototype.momentValue=function(t,i,e){var s=(t+i+e)/3,n=this.sma.momentValue(s),o=this.md.momentValue(s,n);return o&&(s-n)/(.015*o)},t}(),E=function(){function t(t){this.period=t,this.arr=[],this.filled=!1,this.devider=0,this.lastSum=0,this.devider=function(t){for(var i=0,e=t.length;e>0;)i+=t[--e];return i}(Array.from(Array(this.period).keys()).map((function(t){return t+1})))}return t.prototype.nextValue=function(t){if(this.filled=this.filled||this.arr.length===this.period,this.arr.push(t),this.filled)return this.arr.shift(),this.arr.reduce((function(t,i,e){return t+i*(e+1)}),0)/this.devider},t.prototype.momentValue=function(t){if(this.filled){var i=this.arr.slice(1);return i.push(t),i.reduce((function(t,i,e){return t+i*(e+1)}),0)/this.devider}},t}();function O(t,i,e){if(e){var s=t-i,n=t>e?t-e:e-t,o=i>e?i-e:e-i;return s>=n&&s>=o?s:n>=s&&n>=o?n:o}}var R=function(){function t(t,i){switch(void 0===t&&(t=14),void 0===i&&(i="WEMA"),i){case"SMA":this.avg=new c(t);break;case"EMA":this.avg=new d(t);break;case"SMMA":this.avg=new V(t);break;case"WEMA":this.avg=new p(t);break;case"LWMA":this.avg=new E(t);break;case"EWMA":this.avg=new x(.2);break;case"RMA":this.avg=new y(t)}this.prevClose=0}return t.prototype.nextValue=function(t,i,e){var s=O(t,i,this.prevClose);if(this.prevClose=e,void 0!==s)return this.avg.nextValue(s)},t.prototype.momentValue=function(t,i){var e=O(t,i,this.prevClose);if(void 0!==e)return this.avg.momentValue(e)},t}(),U=function(){function t(t){void 0===t&&(t=5),this.values=new a(t)}return t.prototype.nextValue=function(t){var i=this.values.push(t);if(i)return(t-i)/i*100},t.prototype.momentValue=function(t){var i=this.values.peek();if(i)return(t-i)/i*100},t}(),N=function(){function t(t){void 0===t&&(t=20),this.maxProvider=new L(t),this.minProvider=new D(t)}return t.prototype.nextValue=function(t,i){var e=this.maxProvider.nextValue(t),s=this.minProvider.nextValue(i);return{upper:e,middle:(e+s)/2,lower:s}},t.prototype.momentValue=function(t,i){var e=this.maxProvider.momentValue(t),s=this.minProvider.momentValue(i);return{upper:e,middle:(e+s)/2,lower:s}},t}(),W=function(){function t(t){this.period=t,this.fill=0,this.values=new a(t)}return t.prototype.nextValue=function(t){var i=this;if(this.values.push(t),this.fill++,this.fill===this.period)return this.nextValue=function(t){var e=i.calc(t);return i.values.push(t),e},this.momentValue=this.calc,this.calc(t)},t.prototype.momentValue=function(t){},t.prototype.calc=function(t){var i=0;return this.values.toArray().forEach((function(e){e<=t&&i++})),i/this.period*100},t}(),H=function(){function t(t,i,e){void 0===t&&(t=3),void 0===i&&(i=2),void 0===e&&(e=100),this.period=t,this.rsi=new _(this.period),this.updownRsi=new _(i),this.roc=new U(1),this.percentRank=new W(e),this.updownPeriod=0,this.prevClose=0}return t.prototype.nextValue=function(t){var i=this.rsi.nextValue(t),e=this.percentRank.nextValue(this.roc.nextValue(t));if(this.updownPeriod=this.getUpdownPeriod(t),this.prevClose=t,this.updownValue=this.updownRsi.nextValue(this.updownPeriod),this.updownValue)return(i+this.updownValue+e)/3},t.prototype.momentValue=function(t){var i=this.rsi.momentValue(t),e=this.percentRank.momentValue(this.roc.momentValue(t)),s=this.getUpdownPeriod(t),n=this.updownRsi.momentValue(s);if(void 0!==n)return(i+n+e)/3},t.prototype.getUpdownPeriod=function(t){var i=this.updownPeriod;return t>this.prevClose?(this.updownPeriod<0&&(i=0),i++):t<this.prevClose?(this.updownPeriod>0&&(i=0),i--):i=0,i},t}(),j=function(){function t(t){this.period=t,this.values=new a(t)}return t.prototype.nextValue=function(t,i){return this.values.push(t),Math.sqrt(this.values.toArray().reduce((function(t,e){return t+Math.pow(e-i,2)}),0)/this.period)},t.prototype.momentValue=function(t,i){var e=this.values.push(t),s=Math.sqrt(this.values.toArray().reduce((function(t,e){return t+Math.pow(e-i,2)}),0)/this.period);return this.values.pushback(e),s},t}(),z=function(){function t(t,i){void 0===t&&(t=20),void 0===i&&(i=2),this.period=t,this.stdDev=i,this.fill=0,this.sma=new c(t),this.sd=new j(t)}return t.prototype.nextValue=function(t){var i=this,e=this.sma.nextValue(t),s=this.sd.nextValue(t,e);if(this.fill++,this.fill===this.period){var n=e-this.stdDev*s,o=e+this.stdDev*s;return this.nextValue=function(t){var e=i.sma.nextValue(t),s=i.sd.nextValue(t,e);return{lower:e-i.stdDev*s,middle:e,upper:e+i.stdDev*s}},{lower:n,middle:e,upper:o}}},t.prototype.momentValue=function(t){var i=this.sma.momentValue(t),e=this.sd.momentValue(t,i);return{lower:i-this.stdDev*e,middle:i,upper:i+this.stdDev*e}},t}(),$=function(){function t(t,i,e){void 0===t&&(t=12),void 0===i&&(i=26),void 0===e&&(e=9),this.periodEmaFast=t,this.periodEmaSlow=i,this.periodSignal=e,this.emaFastIndicator=new d(t),this.emaSlowIndicator=new d(i),this.emaSignalIndicator=new d(e)}return t.prototype.nextValue=function(t){var i=this.emaFastIndicator.nextValue(t),e=this.emaSlowIndicator.nextValue(t),s=i-e,n=s&&this.emaSignalIndicator.nextValue(s)||void 0,o=s-n||void 0;if(!isNaN(s))return{macd:s,emaFast:i,emaSlow:e,signal:n,histogram:o}},t.prototype.momentValue=function(t){var i=this.emaFastIndicator.momentValue(t),e=this.emaSlowIndicator.momentValue(t),s=i-e,n=s&&this.emaSignalIndicator.momentValue(s);return{macd:s,emaFast:i,emaSlow:e,signal:n,histogram:s-n}},t}(),Y=function(){function t(){this.prevOpen=0,this.prevClose=0}return t.prototype.nextValue=function(t,i,e,s){var n=this.calculate(t,i,e,s);return this.prevClose=n.c,this.prevOpen=n.o,n},t.prototype.momentValue=function(t,i,e,s){return this.calculate(t,i,e,s)},t.prototype.calculate=function(t,i,e,s){return s=(t+i+e+s)/4,this.prevOpen&&(t=(this.prevOpen+this.prevClose)/2),{o:t,h:i=Math.max(i,t,s),l:e=Math.min(e,t,s),c:s}},t}(),q=function(){function t(t){switch(void 0===t&&(t="classic"),this.mode=t,this.mode){case"classic":this.calculator=this.classic;break;case"camarilla":this.calculator=this.camarilla;break;case"woodie":this.calculator=this.woodie;break;case"fibonacci":this.calculator=this.fibonacci}}return t.prototype.nextValue=function(t,i,e){return this.calculator(t,i,e)},t.prototype.classic=function(t,i,e){var s=(t+i+e)/3;return{r3:t+2*(s-i),r2:s+(t-i),r1:2*s-i,pp:s,s1:2*s-t,s2:s-(t-i),s3:i-2*(t-s)}},t.prototype.woodie=function(t,i,e){var s=(t+i+2*e)/4;return{r2:s+t-i,r1:2*s-i,pp:s,s1:2*s-t,s2:s-t+i}},t.prototype.camarilla=function(t,i,e){var s=1.1*(t-i),n=t/i*e,o=e+s/2,r=n+1.168*(n-o);return{r6:r,r5:n,r4:o,r3:e+s/4,r2:e+s/6,r1:e+s/12,pp:(t+i+e)/3,s1:e-s/12,s2:e-s/6,s3:e-s/4,s4:e-s/2,s5:e-(n-e),s6:e-(r-e)}},t.prototype.fibonacci=function(t,i,e){var s=t-i,n=(t+i+e)/3;return{r3:n+s,r2:n+.618*s,r1:n+.382*s,pp:n,s1:n-.382*s,s2:n-.618*s,s3:n-s}},t}(),X=function(){function t(t,i,e){void 0===t&&(t=.02),void 0===i&&(i=.02),void 0===e&&(e=.2),this.start=t,this.acceleration=i,this.max=e,this.result=0,this.isBullTrend=!0}return t.prototype.nextValue=function(t,i,e){if(!this.result)return this.result=e,this.low1=i,this.high1=t,this.low2=i,this.high2=t,this.highest=t,this.lowest=i,this.accelerationFactor=this.start,i;if(this.isBullTrend?this.psar=this.result+this.accelerationFactor*(this.highest-this.result):this.psar=this.result+this.accelerationFactor*(this.lowest-this.result),this.isBullTrend)if(i<this.psar)this.isBullTrend=!1,this.psar=this.highest,this.lowest=i,this.accelerationFactor=this.start;else{if(t>this.highest){this.highest=t;var s=this.accelerationFactor+this.acceleration;this.accelerationFactor=s>this.max?this.max:s}this.low1<this.psar&&(this.psar=this.low1),this.low2<this.psar&&(this.psar=this.low2)}else t>this.psar?(this.isBullTrend=!0,this.psar=this.lowest,this.highest=t,this.accelerationFactor=this.start):(i<this.lowest&&(this.lowest=i,s=this.accelerationFactor+this.acceleration,this.accelerationFactor=s>this.max?this.max:s),this.high1>this.psar&&(this.psar=this.high1),this.high2>this.psar&&(this.psar=this.high2));return this.low2=this.low1,this.low1=i,this.high2=this.high1,this.high1=t,this.result=this.psar,this.result},t.prototype.momentValue=function(t,i){if(!this.result)return i;var e,s=this.isBullTrend,n=this.result,o=this.low1,r=this.high1,h=this.low2,l=this.high2,a=this.highest,u=this.lowest,c=this.accelerationFactor;return e=s?n+c*(a-n):n+c*(u-n),s?i<e?e=a:(o<e&&(e=o),h<e&&(e=h)):t>e?e=u:(r>e&&(e=r),l>e&&(e=l)),e},t}(),G=function(){function t(t){this.period=t,this.prevValue=0,this.sumCount=1}return t.prototype.nextValue=function(t){var i=this;return this.sumCount<this.period?(this.prevValue+=t,void this.sumCount++):this.sumCount===this.period?(this.prevValue+=t,this.sumCount++,this.nextValue=function(t){return i.prevValue=i.prevValue-i.prevValue/i.period+t},this.prevValue):void 0},t.prototype.momentValue=function(t){if(!(this.sumCount<this.period))return this.prevValue-this.prevValue/this.period+t},t}(),K=function(){function t(t){void 0===t&&(t=14),this.period=t,this.wma1=new G(t),this.wma2=new G(t),this.wma3=new G(t),this.wema=new p(t)}return t.prototype.nextValue=function(t,i,e){if(!this.prevClose)return this.prevHigh=t,this.prevLow=i,void(this.prevClose=e);var s=0,n=0,o=t-this.prevHigh,r=this.prevLow-i;o>r&&o>0&&(s=o),r>o&&r>0&&(n=r),(s>n||n<0)&&(n=0);var h=this.wma1.nextValue(O(t,i,this.prevClose)),l=this.wma2.nextValue(s),a=this.wma3.nextValue(n);if(this.prevHigh=t,this.prevLow=i,this.prevClose=e,void 0!==l&&void 0!==a){var u=100*l/h,c=100*a/h,p=u>c?u-c:c-u;return{adx:this.wema.nextValue(p/(u+c)*100),pdi:u,mdi:c}}},t.prototype.momentValue=function(t,i,e){if(this.prevClose){var s=0,n=0,o=t-this.prevHigh,r=this.prevLow-i;o>r&&o>0&&(s=o),r>o&&r>0&&(n=r),(s>n||n<0)&&(n=0);var h=this.wma1.momentValue(O(t,i,this.prevClose)),l=this.wma2.momentValue(s),a=this.wma3.momentValue(n);if(void 0!==l&&void 0!==a){var u=100*l/h,c=100*a/h,p=u>c?u-c:c-u;return{adx:this.wema.momentValue(p/(u+c)*100),pdi:u,mdi:c}}}},t}(),J=function(){function t(t,i,e){void 0===t&&(t=10),void 0===i&&(i=3),void 0===e&&(e="WEMA"),this.multiplier=i,this.atr=new R(t,e)}return t.prototype.nextValue=function(t,i,e){var s=this.atr.nextValue(t,i,e);if(s){var n=(t+i)/2,o=n+this.multiplier*s,r=n-this.multiplier*s;this.prevLower&&(r=r>this.prevLower||this.prevClose<this.prevLower?r:this.prevLower,o=o<this.prevUpper||this.prevClose>this.prevUpper?o:this.prevUpper);var h,l=(h=this.prevSuper===this.prevUpper?e>o?r:o:e<r?o:r)===o?1:-1;return this.prevUpper=o,this.prevLower=r,this.prevSuper=h,this.prevClose=e,{upper:o,lower:r,superTrend:h,direction:l}}},t.prototype.momentValue=function(t,i,e){var s=this.atr.momentValue(t,i),n=(t+i)/2,o=n+this.multiplier*s,r=n-this.multiplier*s;this.prevLower&&(r=r>this.prevLower||this.prevClose<this.prevLower?r:this.prevLower,o=o<this.prevSuper||this.prevClose>this.prevUpper?o:this.prevUpper);var h;return{upper:o,lower:r,superTrend:h=this.prevSuper===this.prevUpper?e>o?r:o:e<r?o:r,direction:h===o?1:-1}},t}(),Q=function(t){return(t.o+t.h+t.l+t.c)/4},Z=function(){function t(t,i){void 0===t&&(t=4),void 0===i&&(i=Q),this.sum=0,this.sessionPricesLookup=new Set,this.sessionVolumes={},this.prevCandle=null,this.source=i,this.precision=t,this.valueToRoundWith=Math.pow(10,this.precision)}return t.prototype.getSession=function(t,i){var e=this;void 0===i&&(i=15);var s=this.source(t),n=1/0,o=s;this.sessionPricesLookup.forEach((function(t){var r=e.diffPercent(t,s);r>i?(e.sessionPricesLookup.delete(t),delete e.sessionVolumes[t]):r<n&&(n=r,o=t)}));var r=Array.from(this.sessionPricesLookup).sort(),h=r.indexOf(o),l=new Map;if(-1===h)return l;for(var a=Math.round(r.length/4),u=0,c=0;c<4;c++){for(var p=c*a,d=p+a,f=0,m=0,v=p;v<d;v++){var g=r[p],w=this.sessionVolumes[g];f<w&&(f=w,m=g)}this.diffPercent(u,m)<1&&(f=l.get(u)+f,m=this.roundPrice((m+u)/2),l.delete(u)),l.set(m,f),u=m}return l},t.prototype.getSessionAvg=function(){return this.sum/this.sessionPricesLookup.size},t.prototype.getRawSession=function(){return this.sessionVolumes},t.prototype.nextValue=function(t){var i,e=this.roundPrice(this.source(t)),s=(null===(i=this.prevCandle)||void 0===i?void 0:i.time)===t.time?t.v-this.prevCandle.v:t.v;this.addToSession(e,s),this.sum+=s,this.lastPrice=e,this.prevCandle=t},t.prototype.roundPrice=function(t){return Math.round((t+Number.EPSILON)*this.valueToRoundWith)/this.valueToRoundWith},t.prototype.addToSession=function(t,i){this.sessionPricesLookup.has(t)?this.sessionVolumes[t]+=i:(this.sessionPricesLookup.add(t),this.sessionVolumes[t]=i)},t.prototype.diffPercent=function(t,i){return t<i?100*(i-t)/t:100*(t-i)/i},t}(),tt=function(){function t(t,i){void 0===t&&(t=3),void 0===i&&(i=10),this.accDistribution=0,this.emaFast=new d(t),this.emaSlow=new d(i)}return t.prototype.nextValue=function(t,i,e,s){return this.accDistribution+=e===t&&e===i||t===i?0:(2*e-i-t)/(t-i)*s,this.emaFast.nextValue(this.accDistribution)-this.emaSlow.nextValue(this.accDistribution)},t.prototype.momentValue=function(t,i,e,s){var n=this.accDistribution+(e===t&&e===i||t===i?0:(2*e-i-t)/(t-i)*s);return this.emaFast.momentValue(n)-this.emaSlow.momentValue(n)},t}();t.AC=P,t.ADX=K,t.AO=M,t.ATR=R,t.BollingerBands=z,t.CCI=T,t.ChaikinOscillator=tt,t.CircularBuffer=a,t.Correlation=g,t.DC=N,t.EMA=d,t.EWMA=x,t.Extremums=u,t.HeikenAshi=Y,t.LWMA=E,t.Level=v,t.MACD=$,t.Move=b,t.PSAR=X,t.Pivot=q,t.RMA=y,t.ROC=U,t.RSI=_,t.SMA=c,t.SMMA=V,t.Sampler=f,t.StandardDeviation=j,t.Stochastic=C,t.StochasticRSI=B,t.SuperTrend=J,t.TrendLines=l,t.UniLevel=m,t.VolumeProfile=Z,t.WEMA=p,t.WMA=w,t.WWS=G,t.Wave=S,t.cRSI=H,Object.defineProperty(t,"__esModule",{value:!0})}(i)}},i={};function e(s){var n=i[s];if(void 0!==n)return n.exports;var o=i[s]={exports:{}};return t[s].call(o.exports,o,o.exports,e),o.exports}e.d=(t,i)=>{for(var s in i)e.o(i,s)&&!e.o(t,s)&&Object.defineProperty(t,s,{enumerable:!0,get:i[s]})},e.o=(t,i)=>Object.prototype.hasOwnProperty.call(t,i),e.r=t=>{"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(t,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(t,"__esModule",{value:!0})};var s={};(()=>{"use strict";e.r(s),e.d(s,{default:()=>u});var t=e(978);const i=(i,e)=>{const s=[],n=new t.EMA(e);return i.forEach((t=>{s.push(n.nextValue(t))})),s},n=(i,e)=>{const s=[],n=new t.SMA(e);return i.forEach((t=>{s.push(n.nextValue(t))})),s},o=(t,i)=>{var e;return(0===(e=t.map(((t,e)=>t>i[e]?"up":t<i[e]?"down":"neutral")).reverse()).length?[]:e.reduce(((t,i,e,s)=>{if(0===e)t.push([i]);else{const n=s[e-1],o=t[t.length-1];i!==n?t.push([i]):o.push(i)}return t}),[])).map((t=>{const i=t.length;return t.map(((t,e)=>{let s=i-e;return"down"===t?-s:"up"===t?s:0}))})).flat().reverse()},r=(t,i)=>{let{upper:e,lower:s}=i;const n=e.map(((t,i)=>t-s[i]));return t.map(((t,i)=>(t-s[i])/n[i]*100))},h={getSMA:n,getEMA:i},l=t=>{if(!t||0===t.length)throw new Error("Bins array is empty or not provided");let i=t[0],e=t[0];return t.forEach((t=>{t.grossVolume>i.grossVolume&&(i=t),t.grossVolume<e.grossVolume&&(e=t)})),{high:i,low:e}};class a{constructor(t,i=100){const e=["open","high","low","close"];for(let[s,n]of Object.entries(t))e.includes(s)&&(this[s]=n.splice(-i))}init(){if(this.close.length<50)return console.log("PatternRecognizer requires at least 50 datapoints"),{chart_pattern:"Neutral",chart_score:0};const t=[{name:"Bullish Flag",condition:this.isBullishFlag.bind(this),score:2},{name:"Bearish Flag",condition:this.isBearishFlag.bind(this),score:-2},{name:"Bullish Pennant",condition:this.isBullishPennant.bind(this),score:2},{name:"Bearish Pennant",condition:this.isBearishPennant.bind(this),score:-2},{name:"Bearish Double Top",condition:this.isDoubleTop.bind(this),score:-1},{name:"Bullish Double Bottom",condition:this.isDoubleBottom.bind(this),score:1},{name:"Bearish Triple Top",condition:this.isTripleTop.bind(this),score:-1},{name:"Bullish Triple Bottom",condition:this.isTripleBottom.bind(this),score:1},{name:"Bearish Head And Shoulders",condition:this.isHeadAndShoulders.bind(this),score:-1},{name:"Bullish Inverse Head And Shoulders",condition:this.isInverseHeadAndShoulders.bind(this),score:1},{name:"Bearish Rising Wedge",condition:this.isRisingWedge.bind(this),score:-1},{name:"Bullish Falling Wedge",condition:this.isFallingWedge.bind(this),score:1},{name:"Bullish Triangle",condition:this.isBullishTriangle.bind(this),score:1},{name:"Bearish Triangle",condition:this.isBearishTriangle.bind(this),score:-1},{name:"Bullish Rectangle",condition:this.isBullishRectangle.bind(this),score:1},{name:"Bearish Rectangle",condition:this.isBearishRectangle.bind(this),score:-1}];for(const{name:i,condition:e,score:s}of t)if(e())return{chart_pattern:i,chart_score:s};return{chart_pattern:"Neutral",chart_score:0}}isBullishFlag(){const t=this.close.length,i=Math.floor(t/3),e=(Math.floor(i/2),this.close[t-2*i]);if((this.close[t-i]-e)/e<.15)return!1;const s=this.close[t-i];if((s-this.close[t-1])/s>.05)return!1;for(let e=t-i;e<t-1;e++)if(this.high[e]>this.high[e+1]||this.low[e]>this.low[e+1])return!1;return!0}isBearishFlag(){const t=this.close.length,i=Math.floor(t/3),e=(Math.floor(i/2),this.close[t-2*i]);if((e-this.close[t-i])/e<.15)return!1;const s=this.close[t-i];if((this.close[t-1]-s)/s>.05)return!1;for(let e=t-i;e<t-1;e++)if(this.high[e]<this.high[e+1]||this.low[e]<this.low[e+1])return!1;return!0}isBullishPennant(){const t=this.close.length,i=Math.floor(t/3),e=Math.floor(i/2),s=this.close[t-2*i];if((this.close[t-i]-s)/s<.15)return!1;const n=this.close[t-i];if((n-this.close[t-1])/n>.05)return!1;for(let i=t-e;i<t-1;i++)if(this.high[i]<this.high[i+1]&&this.low[i]<this.low[i+1]||this.high[i]>this.high[i+1]&&this.low[i]>this.low[i+1])return!1;return!0}isBearishPennant(){const t=this.close.length,i=Math.floor(t/3),e=Math.floor(i/2),s=this.close[t-2*i];if((s-this.close[t-i])/s<.15)return!1;const n=this.close[t-i];if((this.close[t-1]-n)/n>.05)return!1;for(let i=t-e;i<t-1;i++)if(this.high[i]>this.high[i+1]&&this.low[i]>this.low[i+1]||this.high[i]<this.high[i+1]&&this.low[i]<this.low[i+1])return!1;return!0}isDoubleTop(){const t=this.close.length,i=Math.floor(t/2),e=Math.max(...this.close.slice(0,i)),s=Math.max(...this.close.slice(i));if(e<=0||s<=0)return!1;const n=Math.min(...this.close.slice(0,i)),o=Math.min(...this.close.slice(i));return!((e-n)/e<.1||(s-o)/s<.1)&&Math.abs(e-s)/e<.03}isDoubleBottom(){const t=this.close.length,i=Math.floor(t/2),e=Math.min(...this.close.slice(0,i)),s=Math.min(...this.close.slice(i));if(e<=0||s<=0)return!1;const n=Math.max(...this.close.slice(0,i)),o=Math.max(...this.close.slice(i));return!((n-e)/e<.1||(o-s)/s<.1)&&Math.abs(e-s)/e<.03}isTripleTop(){const t=this.close.length,i=Math.floor(t/3),e=Math.max(...this.close.slice(0,i)),s=Math.max(...this.close.slice(i,2*i)),n=Math.max(...this.close.slice(2*i));if(e<=0||s<=0||n<=0)return!1;const o=(e-Math.min(...this.close.slice(0,i)))/e,r=(s-Math.min(...this.close.slice(i,2*i)))/s,h=(n-Math.min(...this.close.slice(2*i)))/n;return!(o<.1||r<.1||h<.1)&&Math.abs(e-s)/e<.03&&Math.abs(e-n)/e<.03}isTripleBottom(){const t=this.close.length,i=Math.floor(t/3),e=Math.min(...this.close.slice(0,i)),s=Math.min(...this.close.slice(i,2*i)),n=Math.min(...this.close.slice(2*i));if(e<=0||s<=0||n<=0)return!1;const o=(Math.max(...this.close.slice(0,i))-e)/e,r=(Math.max(...this.close.slice(i,2*i))-s)/s,h=(Math.max(...this.close.slice(2*i))-n)/n;return!(o<.1||r<.1||h<.1)&&Math.abs(e-s)/e<.03&&Math.abs(e-n)/e<.03}isHeadAndShoulders(){const t=this.close.length,i=Math.floor(t/3),e=Math.max(...this.close.slice(0,i)),s=Math.max(...this.close.slice(i,2*i)),n=Math.max(...this.close.slice(2*i));if(e<=0||s<=0||n<=0)return!1;const o=Math.min(...this.close.slice(0,i)),r=Math.min(...this.close.slice(i,2*i)),h=Math.min(...this.close.slice(2*i)),l=(s-r)/s,a=(Math.max(o,h)-Math.min(o,h))/Math.min(o,h);return l>.15&&a<.03}isInverseHeadAndShoulders(){const t=this.close.length,i=Math.floor(t/3),e=Math.min(...this.close.slice(0,i)),s=Math.min(...this.close.slice(i,2*i)),n=Math.min(...this.close.slice(2*i));if(e<=0||s<=0||n<=0)return!1;const o=Math.max(...this.close.slice(0,i)),r=Math.max(...this.close.slice(i,2*i)),h=Math.max(...this.close.slice(2*i)),l=(r-s)/s,a=(Math.min(o,h)-Math.max(o,h))/Math.max(o,h);return l>.15&&a<.03}isRisingWedge(){const t=this.close.length,i=Math.floor(t/3),e=Math.max(...this.close.slice(0,i)),s=Math.max(...this.close.slice(i,2*i)),n=Math.max(...this.close.slice(2*i)),o=Math.min(...this.close.slice(0,i)),r=Math.min(...this.close.slice(i,2*i)),h=Math.min(...this.close.slice(2*i));return e<s&&s<n&&o<r&&r<h}isFallingWedge(){const t=this.close.length,i=Math.floor(t/3),e=Math.max(...this.close.slice(0,i)),s=Math.max(...this.close.slice(i,2*i)),n=Math.max(...this.close.slice(2*i)),o=Math.min(...this.close.slice(0,i)),r=Math.min(...this.close.slice(i,2*i)),h=Math.min(...this.close.slice(2*i));return e>s&&s>n&&o>r&&r>h}isBullishTriangle(){const t=this.close.length,i=Math.floor(t/2),e=Math.max(...this.high.slice(0,i)),s=Math.max(...this.high.slice(i)),n=Math.min(...this.low.slice(0,i)),o=Math.min(...this.low.slice(i));return e>s&&n<o}isBearishTriangle(){const t=this.close.length,i=Math.floor(t/2),e=Math.max(...this.high.slice(0,i)),s=Math.max(...this.high.slice(i));return Math.min(...this.low.slice(0,i))<Math.min(...this.low.slice(i))&&e>s}isBullishRectangle(){const t=this.close.length,i=Math.floor(t/3),e=Math.max(...this.high.slice(0,i)),s=Math.max(...this.high.slice(i,2*i)),n=Math.max(...this.high.slice(2*i)),o=Math.min(...this.low.slice(0,i)),r=Math.min(...this.low.slice(i,2*i)),h=Math.min(...this.low.slice(2*i)),l=Math.abs(e-s)/e<.03&&Math.abs(s-n)/s<.03,a=Math.abs(o-r)/o<.03&&Math.abs(r-h)/r<.03;return l&&a}isBearishRectangle(){const t=this.close.length,i=Math.floor(t/3),e=Math.max(...this.high.slice(0,i)),s=Math.max(...this.high.slice(i,2*i)),n=Math.max(...this.high.slice(2*i)),o=Math.min(...this.low.slice(0,i)),r=Math.min(...this.low.slice(i,2*i)),h=Math.min(...this.low.slice(2*i)),l=Math.abs(e-s)/e<.03&&Math.abs(s-n)/s<.03,a=Math.abs(o-r)/o<.03&&Math.abs(r-h)/r<.03;return l&&a}}class u{constructor(){this.ChartPatterns=t=>new a(t).init()}init(t){return this.rawOhlcv=t,this.ohlcv=t.reduce(((t,{open:i,high:e,low:s,close:n,volume:o,...r})=>{t.open.push(i),t.high.push(e),t.low.push(s),t.close.push(n),t.volume.push(o);for(const i of Object.keys(r))t[i]||(t[i]=[]),t[i].push(r[i]);return t}),{open:[],high:[],low:[],close:[],volume:[]}),this}getHeaders(){return Object.keys(this.ohlcv)}getData(){const{ohlcv:t}=this,i=Object.keys(t),e=i.length;return t.open.map(((s,n)=>{const o={};for(let s=0;s<e;s++){const e=i[s];o[e]=t[e][n]}return o}))}getLastValues(){const t={};for(const[i,e]of Object.entries(this.ohlcv)){let s=e[e.length-1];t[i]=s}return t}addColumn(t,i){const e=this.ohlcv.open.length;if(i.length>e)throw new Error("Invalid column data: The length of the new column exceeds the length of the OHLCV data");i=[...new Array(e-i.length).fill(null),...i],this.ohlcv[t]=i}crossPairs(t){const i=this.ohlcv,e={},s=t=>{if(!i.hasOwnProperty(t)&&"string"==typeof t){const[i,...e]=t.split("_");this[i]&&e.length>0&&this[i](...e)}};for(const{fast:n,slow:r}of t)if(n&&r)if(s(n),s(r),"number"!=typeof r||e[r]||(e[r]=i.close.map((()=>r))),i[n]&&i[r]){const t=o(i[n],i[r]);this.addColumn(`${n}_x_${r}`,t)}else if(i[n]&&e[r]){const t=o(i[n],e[r]);this.addColumn(`${n}_x_${r}`,t)}else console.error(`Missing ohlcv properties for ${n} or ${r}`)}ema(t){return((t,e)=>{const{ohlcv:s}=t,n=s.close,o=i(n,e);t.addColumn(`ema_${e}`,o)})(this,t),this}sma(t){return((t,i)=>{const{ohlcv:e}=t,s=e.close,o=n(s,i);t.addColumn(`sma_${i}`,o)})(this,t),this}macd(t,e,s){return((t,e=12,s=26,n=9)=>{const{ohlcv:r}=t,h=((t,e=12,s=26,n=9)=>{const r=i(t,e),h=i(t,s),l=r.map(((t,i)=>isNaN(t)||isNaN(h[i])?null:t-h[i])),a=i(l,n),u=l.map(((t,i)=>t-a[i])),c=o(l,a);return{macd_diff:l,macd_dea:a,macd_histogram:u,macd_diff_x_macd_dea:c}})(r.close,e,s,n);for(let i in h)t.addColumn(i,h[i])})(this,t,e,s),this}bollingerBands(i,e,s){return((i,e,s)=>{const{ohlcv:n}=i,o=((i,e=20,s=2)=>{const n={lower:[],middle:[],upper:[]},o=new t.BollingerBands(e,s);i.forEach((t=>{const i=o.nextValue(t);if("object"==typeof i){const{lower:t,middle:e,upper:s}=i;n.lower.push(t),n.middle.push(e),n.upper.push(s)}else n.lower.push(null),n.middle.push(null),n.upper.push(null)}));const h=r(i,{upper:n.upper,lower:n.lower});return{...n,range:h}})(n.close,e,s);for(let t in o)i.addColumn(`bollinger_bands_${t}`,o[t])})(this,i,e),this}rsi(i,e,s){return((i,e,s,n)=>{const{ohlcv:r}=i;"number"==typeof e&&void 0===n&&(n=e);const l=((i,e=14,s="SMA",n=14)=>{if(i.length<e)return[];let r=[];e=parseInt(e),n=parseInt(n);const l=new t.RSI(e);i.forEach((t=>{r.push(l.nextValue(t))})),r=r.filter((t=>t));let a={[`rsi_${e}`]:r};if("string"==typeof s&&"number"==typeof n&&h.hasOwnProperty(`get${s}`)){const t=h[`get${s}`](r,n);a[`rsi_${s}_${n}`]=t,a[`rsi_${e}_x_rsi_${s}_${n}`]=o(r,t)}return a})(r.close,e,s,n);for(let t in l)i.addColumn(`${t}`.toLowerCase(),l[t])})(this,i,e,s),this}candles(){return(t=>{const{ohlcv:i}=t,e=(t=>{const{open:i,high:e,low:s,close:n}=t,o=i.length;if(![i,e,s,n].every((t=>Array.isArray(t)&&t.length>1&&t.length===o)))return{pattern:Array(o).fill("Neutral"),name:Array(o).fill("No Pattern"),score:Array(o).fill(0)};const r=(t,i,e=1e-4)=>Math.abs(t-i)<e,h={bullish:[{name:"Marubozu",condition:(t,i)=>r(i.open,i.low)&&r(i.close,i.high),score:2},{name:"Engulfing",condition:(t,i)=>i.open<t.close&&i.close>t.open&&i.low<t.low&&i.high>t.high,score:2},{name:"Kicker",condition:(t,i)=>i.open<t.open&&i.close>i.open&&t.close<t.open,score:2},{name:"Morning Star",condition:(t,i)=>i.close>t.close&&i.open<t.open&&t.close<t.open,score:2},{name:"Piercing Line",condition:(t,i)=>i.close>t.close&&i.open<t.open&&i.close>(t.open+t.close)/2,score:1},{name:"Belt Hold",condition:(t,i)=>i.open>t.open&&r(i.close,i.high)&&r(t.close,t.low),score:1},{name:"Harami",condition:(t,i)=>i.open>t.close&&i.close<t.open&&i.open<t.open&&i.close>t.close,score:1},{name:"Doji",condition:(t,i)=>r(i.close,i.open)&&i.high-i.low>Math.abs(i.close-i.open),score:0}],bearish:[{name:"Marubozu",condition:(t,i)=>r(i.open,i.high)&&r(i.close,i.low),score:-2},{name:"Engulfing",condition:(t,i)=>i.open>t.close&&i.close<t.open&&i.high>t.high&&i.low<t.low,score:-2},{name:"Kicker",condition:(t,i)=>i.open>t.open&&i.close<i.open&&t.close>t.open,score:-2},{name:"Evening Star",condition:(t,i)=>i.close<t.close&&i.open>t.open&&t.close<t.open,score:-2},{name:"Dark Cloud Cover",condition:(t,i)=>i.close<t.close&&i.open>t.open&&i.close<(t.open+t.close)/2,score:-1},{name:"Belt Hold",condition:(t,i)=>i.open<t.open&&r(i.close,i.low)&&r(t.close,t.high),score:-1},{name:"Harami",condition:(t,i)=>i.open<t.close&&i.close>t.open&&i.open>t.open&&i.close<t.close,score:-1},{name:"Doji",condition:(t,i)=>r(i.close,i.open)&&i.high-i.low>Math.abs(i.close-i.open),score:0}]},l=(t,i,e)=>{for(const{name:s,condition:n,score:o}of e)if(n(t,i))return{name:s,score:o};return null},a=["Neutral"],u=["No Pattern"],c=[0];for(let t=1;t<o;t++){const o={open:i[t-1],high:e[t-1],low:s[t-1],close:n[t-1]},r={open:i[t],high:e[t],low:s[t],close:n[t]},p=l(o,r,h.bullish)||l(o,r,h.bearish);p?(a.push(p.score>0?"Bullish":"Bearish"),u.push(p.name),c.push(p.score)):(a.push("Neutral"),u.push("No Pattern"),c.push(0))}return{pattern:a,name:u,score:c}})(i);for(let i in e)t.addColumn(`candle_${i}`.toLowerCase(),e[i])})(this),this}volumeProfile(t,i,e){return((t,i,e=1,s)=>{let{ohlcv:n}=t;const o=((t,i,e)=>{const s=new Date(t[e][t[e].length-1]),n=new Date(s);n.setDate(n.getDate()-i),n.setHours(0,0,0,0);const o={open:[],high:[],low:[],close:[],volume:[],[e]:[]};for(let i=0;i<t[e].length;i++)new Date(t[e][i])>=n&&(o.open.push(t.open[i]),o.high.push(t.high[i]),o.low.push(t.low[i]),o.close.push(t.close[i]),o.volume.push(t.volume[i]),o[e].push(t[e][i]));return o})(n,e,s),r=((t,i=5)=>{const{open:e,high:s,low:n,close:o,volume:r}=t,h=Math.min(...n),a=(Math.max(...s)-h)/i,u={upVolume:0,downVolume:0,grossVolume:0},c=Array.from({length:i},((t,i)=>({price:h+a*i,upVolume:0,downVolume:0,grossVolume:0}))),p=1/a;for(let t=0;t<o.length;t++){const l=o[t],a=e[t],u=s[t],d=n[t],f=r[t],m=l>=a?f:0,v=l<a?f:0,g=Math.max(0,Math.floor((d-h)*p)),w=Math.min(i,Math.ceil((u-h)*p));for(let t=g;t<w;t++)c[t].upVolume+=m,c[t].downVolume+=v,c[t].grossVolume+=m+v}for(const{upVolume:t,downVolume:i,grossVolume:e}of c)u.upVolume+=t,u.downVolume+=i,u.grossVolume+=e;return{bins:c,nodes:l(c)}})(o,i),h=r.nodes.high.price,a=r.nodes.low.price;t.addColumn("volume_profile_high",[h]),t.addColumn("volume_profile_low",[a])})(this,t,i,e),this}}})(),OHLCV_INDICATORS=s})();
1
+ var OHLCV_INDICATORS;(()=>{"use strict";var t={d:(e,s)=>{for(var i in s)t.o(s,i)&&!t.o(e,i)&&Object.defineProperty(e,i,{enumerable:!0,get:s[i]})},o:(t,e)=>Object.prototype.hasOwnProperty.call(t,e),r:t=>{"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(t,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(t,"__esModule",{value:!0})}},e={};(()=>{t.r(e),t.d(e,{default:()=>V});var s=1e6,i="[big.js] ",o=i+"Invalid ",h=o+"decimal places",r=o+"rounding mode",n=i+"Division by zero",l={},c=void 0,a=/^-?(\d+(\.\d*)?|\.\d+)(e[+-]?\d+)?$/i;function u(t,e,s,i){var o=t.c;if(s===c&&(s=t.constructor.RM),0!==s&&1!==s&&2!==s&&3!==s)throw Error(r);if(e<1)i=3===s&&(i||!!o[0])||0===e&&(1===s&&o[0]>=5||2===s&&(o[0]>5||5===o[0]&&(i||o[1]!==c))),o.length=1,i?(t.e=t.e-e+1,o[0]=1):o[0]=t.e=0;else if(e<o.length){if(i=1===s&&o[e]>=5||2===s&&(o[e]>5||5===o[e]&&(i||o[e+1]!==c||1&o[e-1]))||3===s&&(i||!!o[0]),o.length=e,i)for(;++o[--e]>9;)if(o[e]=0,0===e){++t.e,o.unshift(1);break}for(e=o.length;!o[--e];)o.pop()}return t}function p(t,e,s){var i=t.e,o=t.c.join(""),h=o.length;if(e)o=o.charAt(0)+(h>1?"."+o.slice(1):"")+(i<0?"e":"e+")+i;else if(i<0){for(;++i;)o="0"+o;o="0."+o}else if(i>0)if(++i>h)for(i-=h;i--;)o+="0";else i<h&&(o=o.slice(0,i)+"."+o.slice(i));else h>1&&(o=o.charAt(0)+"."+o.slice(1));return t.s<0&&s?"-"+o:o}l.abs=function(){var t=new this.constructor(this);return t.s=1,t},l.cmp=function(t){var e,s=this,i=s.c,o=(t=new s.constructor(t)).c,h=s.s,r=t.s,n=s.e,l=t.e;if(!i[0]||!o[0])return i[0]?h:o[0]?-r:0;if(h!=r)return h;if(e=h<0,n!=l)return n>l^e?1:-1;for(r=(n=i.length)<(l=o.length)?n:l,h=-1;++h<r;)if(i[h]!=o[h])return i[h]>o[h]^e?1:-1;return n==l?0:n>l^e?1:-1},l.div=function(t){var e=this,i=e.constructor,o=e.c,r=(t=new i(t)).c,l=e.s==t.s?1:-1,a=i.DP;if(a!==~~a||a<0||a>s)throw Error(h);if(!r[0])throw Error(n);if(!o[0])return t.s=l,t.c=[t.e=0],t;var p,g,v,f,d,m=r.slice(),w=p=r.length,M=o.length,b=o.slice(0,p),x=b.length,R=t,B=R.c=[],y=0,P=a+(R.e=e.e-t.e)+1;for(R.s=l,l=P<0?0:P,m.unshift(0);x++<p;)b.push(0);do{for(v=0;v<10;v++){if(p!=(x=b.length))f=p>x?1:-1;else for(d=-1,f=0;++d<p;)if(r[d]!=b[d]){f=r[d]>b[d]?1:-1;break}if(!(f<0))break;for(g=x==p?r:m;x;){if(b[--x]<g[x]){for(d=x;d&&!b[--d];)b[d]=9;--b[d],b[x]+=10}b[x]-=g[x]}for(;!b[0];)b.shift()}B[y++]=f?v:++v,b[0]&&f?b[x]=o[w]||0:b=[o[w]]}while((w++<M||b[0]!==c)&&l--);return B[0]||1==y||(B.shift(),R.e--,P--),y>P&&u(R,P,i.RM,b[0]!==c),R},l.eq=function(t){return 0===this.cmp(t)},l.gt=function(t){return this.cmp(t)>0},l.gte=function(t){return this.cmp(t)>-1},l.lt=function(t){return this.cmp(t)<0},l.lte=function(t){return this.cmp(t)<1},l.minus=l.sub=function(t){var e,s,i,o,h=this,r=h.constructor,n=h.s,l=(t=new r(t)).s;if(n!=l)return t.s=-l,h.plus(t);var c=h.c.slice(),a=h.e,u=t.c,p=t.e;if(!c[0]||!u[0])return u[0]?t.s=-l:c[0]?t=new r(h):t.s=1,t;if(n=a-p){for((o=n<0)?(n=-n,i=c):(p=a,i=u),i.reverse(),l=n;l--;)i.push(0);i.reverse()}else for(s=((o=c.length<u.length)?c:u).length,n=l=0;l<s;l++)if(c[l]!=u[l]){o=c[l]<u[l];break}if(o&&(i=c,c=u,u=i,t.s=-t.s),(l=(s=u.length)-(e=c.length))>0)for(;l--;)c[e++]=0;for(l=e;s>n;){if(c[--s]<u[s]){for(e=s;e&&!c[--e];)c[e]=9;--c[e],c[s]+=10}c[s]-=u[s]}for(;0===c[--l];)c.pop();for(;0===c[0];)c.shift(),--p;return c[0]||(t.s=1,c=[p=0]),t.c=c,t.e=p,t},l.mod=function(t){var e,s=this,i=s.constructor,o=s.s,h=(t=new i(t)).s;if(!t.c[0])throw Error(n);return s.s=t.s=1,e=1==t.cmp(s),s.s=o,t.s=h,e?new i(s):(o=i.DP,h=i.RM,i.DP=i.RM=0,s=s.div(t),i.DP=o,i.RM=h,this.minus(s.times(t)))},l.neg=function(){var t=new this.constructor(this);return t.s=-t.s,t},l.plus=l.add=function(t){var e,s,i,o=this,h=o.constructor;if(t=new h(t),o.s!=t.s)return t.s=-t.s,o.minus(t);var r=o.e,n=o.c,l=t.e,c=t.c;if(!n[0]||!c[0])return c[0]||(n[0]?t=new h(o):t.s=o.s),t;if(n=n.slice(),e=r-l){for(e>0?(l=r,i=c):(e=-e,i=n),i.reverse();e--;)i.push(0);i.reverse()}for(n.length-c.length<0&&(i=c,c=n,n=i),e=c.length,s=0;e;n[e]%=10)s=(n[--e]=n[e]+c[e]+s)/10|0;for(s&&(n.unshift(s),++l),e=n.length;0===n[--e];)n.pop();return t.c=n,t.e=l,t},l.pow=function(t){var e=this,s=new e.constructor("1"),i=s,h=t<0;if(t!==~~t||t<-1e6||t>1e6)throw Error(o+"exponent");for(h&&(t=-t);1&t&&(i=i.times(e)),t>>=1;)e=e.times(e);return h?s.div(i):i},l.prec=function(t,e){if(t!==~~t||t<1||t>s)throw Error(o+"precision");return u(new this.constructor(this),t,e)},l.round=function(t,e){if(t===c)t=0;else if(t!==~~t||t<-s||t>s)throw Error(h);return u(new this.constructor(this),t+this.e+1,e)},l.sqrt=function(){var t,e,s,o=this,h=o.constructor,r=o.s,n=o.e,l=new h("0.5");if(!o.c[0])return new h(o);if(r<0)throw Error(i+"No square root");0===(r=Math.sqrt(o+""))||r===1/0?((e=o.c.join("")).length+n&1||(e+="0"),n=((n+1)/2|0)-(n<0||1&n),t=new h(((r=Math.sqrt(e))==1/0?"5e":(r=r.toExponential()).slice(0,r.indexOf("e")+1))+n)):t=new h(r+""),n=t.e+(h.DP+=4);do{s=t,t=l.times(s.plus(o.div(s)))}while(s.c.slice(0,n).join("")!==t.c.slice(0,n).join(""));return u(t,(h.DP-=4)+t.e+1,h.RM)},l.times=l.mul=function(t){var e,s=this,i=s.constructor,o=s.c,h=(t=new i(t)).c,r=o.length,n=h.length,l=s.e,c=t.e;if(t.s=s.s==t.s?1:-1,!o[0]||!h[0])return t.c=[t.e=0],t;for(t.e=l+c,r<n&&(e=o,o=h,h=e,c=r,r=n,n=c),e=new Array(c=r+n);c--;)e[c]=0;for(l=n;l--;){for(n=0,c=r+l;c>l;)n=e[c]+h[l]*o[c-l-1]+n,e[c--]=n%10,n=n/10|0;e[c]=n}for(n?++t.e:e.shift(),l=e.length;!e[--l];)e.pop();return t.c=e,t},l.toExponential=function(t,e){var i=this,o=i.c[0];if(t!==c){if(t!==~~t||t<0||t>s)throw Error(h);for(i=u(new i.constructor(i),++t,e);i.c.length<t;)i.c.push(0)}return p(i,!0,!!o)},l.toFixed=function(t,e){var i=this,o=i.c[0];if(t!==c){if(t!==~~t||t<0||t>s)throw Error(h);for(t=t+(i=u(new i.constructor(i),t+i.e+1,e)).e+1;i.c.length<t;)i.c.push(0)}return p(i,!1,!!o)},l[Symbol.for("nodejs.util.inspect.custom")]=l.toJSON=l.toString=function(){var t=this,e=t.constructor;return p(t,t.e<=e.NE||t.e>=e.PE,!!t.c[0])},l.toNumber=function(){var t=Number(p(this,!0,!0));if(!0===this.constructor.strict&&!this.eq(t.toString()))throw Error(i+"Imprecise conversion");return t},l.toPrecision=function(t,e){var i=this,h=i.constructor,r=i.c[0];if(t!==c){if(t!==~~t||t<1||t>s)throw Error(o+"precision");for(i=u(new h(i),t,e);i.c.length<t;)i.c.push(0)}return p(i,t<=i.e||i.e<=h.NE||i.e>=h.PE,!!r)},l.valueOf=function(){var t=this,e=t.constructor;if(!0===e.strict)throw Error(i+"valueOf disallowed");return p(t,t.e<=e.NE||t.e>=e.PE,!0)};const g=function t(){function e(s){var i=this;if(!(i instanceof e))return s===c?t():new e(s);if(s instanceof e)i.s=s.s,i.e=s.e,i.c=s.c.slice();else{if("string"!=typeof s){if(!0===e.strict&&"bigint"!=typeof s)throw TypeError(o+"value");s=0===s&&1/s<0?"-0":String(s)}!function(t,e){var s,i,h;if(!a.test(e))throw Error(o+"number");for(t.s="-"==e.charAt(0)?(e=e.slice(1),-1):1,(s=e.indexOf("."))>-1&&(e=e.replace(".","")),(i=e.search(/e/i))>0?(s<0&&(s=i),s+=+e.slice(i+1),e=e.substring(0,i)):s<0&&(s=e.length),h=e.length,i=0;i<h&&"0"==e.charAt(i);)++i;if(i==h)t.c=[t.e=0];else{for(;h>0&&"0"==e.charAt(--h););for(t.e=s-i-1,t.c=[],s=0;i<=h;)t.c[s++]=+e.charAt(i++)}}(i,s)}i.constructor=e}return e.prototype=l,e.DP=20,e.RM=1,e.NE=-7,e.PE=21,e.strict=!1,e.roundDown=0,e.roundHalfUp=1,e.roundHalfEven=2,e.roundUp=3,e}();class v extends Error{constructor(t="Not enough data"){super(t),Object.setPrototypeOf(this,new.target.prototype),this.name="NotEnoughDataError"}}class f{previousHighest;highest;previousLowest;lowest;previousResult;result;get isStable(){return void 0!==this.result}getResult(){if(void 0===this.result)throw new v;return this.result}setResult(t,e){return e&&(this.highest=this.previousHighest,this.lowest=this.previousLowest,this.result=this.previousResult),void 0===this.highest?this.highest=t:t.gt(this.highest)?(this.previousHighest=this.highest,this.highest=t):this.previousHighest=this.highest,void 0===this.lowest?this.lowest=t:t.lt(this.lowest)?(this.previousLowest=this.lowest,this.lowest=t):this.previousLowest=this.lowest,this.previousResult=this.result,this.result=t}replace(t){return this.update(t,!0)}}class d extends f{interval;constructor(t){super(),this.interval=t}updates(t){return t.forEach((t=>this.update(t))),this.result}replace(t){return this.update(t,!0)}}class m extends d{prices=[];update(t,e=!1){if(this.prices.length&&e?this.prices[this.prices.length-1]=t:this.prices.push(t),this.prices.length>this.interval&&this.prices.shift(),this.prices.length===this.interval)return this.setResult(m.getResultFromBatch(this.prices),e)}static getResultFromBatch(t){return t.reduce(((t,e)=>t.plus(e)),new g("0")).div(t.length||1)}}class w extends d{interval;indicator;smoothingFactor;constructor(t){super(t),this.interval=t,this.indicator=new m(t),this.smoothingFactor=new g(1).div(this.interval)}updates(t){return t.forEach((t=>this.update(t))),this.result}update(t,e=!1){const s=this.indicator.update(t,e);if(e&&this.previousResult){const s=new g(t).minus(this.previousResult).mul(this.smoothingFactor);return this.setResult(s.plus(this.previousResult),e)}if(!e&&this.result){const s=new g(t).minus(this.result).mul(this.smoothingFactor);return this.setResult(s.plus(this.result),e)}if(void 0===this.result&&s)return this.setResult(s,e)}}function M(t){return t.reduce(((t,e)=>t.add(e)),new g(0)).div(t.length||1)}class b{interval;deviationMultiplier;prices=[];result;constructor(t,e=2){this.interval=t,this.deviationMultiplier=e}get isStable(){return void 0!==this.result}update(t){if(this.prices.push(new g(t)),this.prices.length>this.interval){this.prices.shift();const t=m.getResultFromBatch(this.prices),e=function(t,e){const s=e||M(t);return M(t.map((t=>new g(t).sub(s).pow(2)))).sqrt()}(this.prices,t);return this.result={lower:t.sub(e.times(this.deviationMultiplier)),middle:t,upper:t.add(e.times(this.deviationMultiplier))}}}getResult(){if(void 0===this.result)throw new v;return this.result}}class x extends d{interval;pricesCounter=0;weightFactor;constructor(t){super(t),this.interval=t,this.weightFactor=2/(this.interval+1)}update(t,e=!1){e?e&&0===this.pricesCounter&&this.pricesCounter++:this.pricesCounter++;const s=new g(t);return e&&this.previousResult?this.setResult(s.times(this.weightFactor).add(this.previousResult.times(1-this.weightFactor)),e):this.setResult(s.times(this.weightFactor).add((this.result??s).times(1-this.weightFactor)),e)}getResult(){if(this.pricesCounter<this.interval)throw new v;return this.result}get isStable(){try{return this.getResult(),!0}catch{return!1}}}class R{prices=[];long;short;signal;result;constructor(t){this.long=new t.indicator(t.longInterval),this.short=new t.indicator(t.shortInterval),this.signal=new t.indicator(t.signalInterval)}get isStable(){return void 0!==this.result}update(t,e=!1){const s=new g(t);this.prices.length&&e?this.prices[this.prices.length-1]=s:this.prices.push(s);const i=this.short.update(s,e),o=this.long.update(s,e);if(this.prices.length>this.long.interval&&this.prices.shift(),this.prices.length===this.long.interval){const t=i.sub(o),e=this.signal.update(t);return this.result={histogram:t.sub(e),macd:t,signal:e}}}getResult(){if(!this.isStable||void 0===this.result)throw new v;return this.result}}class B extends f{interval;previousPrices=[];avgGain;avgLoss;maxValue=new g(100);constructor(t,e=w){super(),this.interval=t,this.avgGain=new e(this.interval),this.avgLoss=new e(this.interval)}update(t,e=!1){if(this.previousPrices.length&&e?this.previousPrices[this.previousPrices.length-1]=t:this.previousPrices.push(t),this.previousPrices.length<2)return;const s=new g(t),i=new g(this.previousPrices[this.previousPrices.length-2]);if(s.gt(i)?(this.avgLoss.update(new g(0),e),this.avgGain.update(s.sub(i),e)):(this.avgLoss.update(i.sub(s),e),this.avgGain.update(new g(0),e)),this.avgGain.isStable){const t=this.avgLoss.getResult();if(t.eq(0))return this.setResult(new g(100),e);const s=this.avgGain.getResult().div(t);return this.setResult(this.maxValue.minus(this.maxValue.div(s.add(1))),e)}}}const y=(t,e)=>{const s=[],i=new x(e),o=t.length;for(let e=0;e<o;e++){let o=null;i.update(t[e]);try{o=i.getResult()}catch(t){o=null}s.push(o)}return s},P=(t,e)=>{const s=[],i=new m(e),o=t.length;for(let e=0;e<o;e++){let o=null;i.update(t[e]);try{o=i.getResult()}catch(t){o=null}s.push(o)}return s},E=(t,e)=>{t=t.filter((t=>t instanceof g)),e=e.filter((t=>t instanceof g));const s=Math.min(t.length,e.length);t=t.slice(-s),e=e.slice(-s);let i=t.map(((t,s)=>{if(t.eq(e[s]))return"neutral";if(t.gt(e[s]))return"up";if(t.lt(e[s]))return"down";throw Error("undefined error in findCrosses")}));const o=_(i),h=o.map((t=>t.length));return o.map(((t,e)=>{let s=h[e];return t.map(((t,e)=>{let i=s-e;return"neutral"===t&&(i=0),"up"===t&&(i*=1),"down"===t&&(i*=-1),i})).reverse()})).flat()},_=t=>0===t.length?[]:t.reduce(((t,e,s,i)=>{if(0===s)t.push([e]);else{const o=i[s-1],h=t[t.length-1];e!==o?t.push([e]):h.push(e)}return t}),[]),S=(t,e)=>{const{upper:s,lower:i}=e,o=new Array(t.length);for(let e=0;e<t.length;e++)if(null!=s[e]&&null!=i[e]&&null!=t[e]){const h=new g(s[e]),r=new g(i[e]),n=new g(t[e]),l=h.minus(r);o[e]=n.minus(r).div(l).times(100).toNumber()}else o[e]=null;return o},C={getSMA:P,getEMA:y},D=t=>{if(!t||0===t.length)throw new Error("Bins array is empty or not provided");let e=t[0],s=t[0];return t.forEach((t=>{t.grossVolume>e.grossVolume&&(e=t),t.grossVolume<s.grossVolume&&(s=t)})),{high:e,low:s}};class A{constructor(t,e=100){const s=["open","high","low","close"];this.ohlcv={};for(let i of Object.keys(t))s.includes(i)&&(this.ohlcv[i]=t[i].slice(-e))}init(){if(this.ohlcv.close.length<50)return console.log("PatternRecognizer requires at least 50 datapoints"),{chart_pattern:"Neutral",chart_score:0};const t=[{name:"Bullish Flag",condition:this.isBullishFlag.bind(this),score:2},{name:"Bearish Flag",condition:this.isBearishFlag.bind(this),score:-2},{name:"Bullish Pennant",condition:this.isBullishPennant.bind(this),score:2},{name:"Bearish Pennant",condition:this.isBearishPennant.bind(this),score:-2},{name:"Bearish Double Top",condition:this.isDoubleTop.bind(this),score:-1},{name:"Bullish Double Bottom",condition:this.isDoubleBottom.bind(this),score:1},{name:"Bearish Triple Top",condition:this.isTripleTop.bind(this),score:-1},{name:"Bullish Triple Bottom",condition:this.isTripleBottom.bind(this),score:1},{name:"Bearish Head And Shoulders",condition:this.isHeadAndShoulders.bind(this),score:-1},{name:"Bullish Inverse Head And Shoulders",condition:this.isInverseHeadAndShoulders.bind(this),score:1},{name:"Bearish Rising Wedge",condition:this.isRisingWedge.bind(this),score:-1},{name:"Bullish Falling Wedge",condition:this.isFallingWedge.bind(this),score:1},{name:"Bullish Triangle",condition:this.isBullishTriangle.bind(this),score:1},{name:"Bearish Triangle",condition:this.isBearishTriangle.bind(this),score:-1},{name:"Bullish Rectangle",condition:this.isBullishRectangle.bind(this),score:1},{name:"Bearish Rectangle",condition:this.isBearishRectangle.bind(this),score:-1}];for(const{name:e,condition:s,score:i}of t)if(s())return{chart_pattern:e,chart_score:i};return{chart_pattern:"Neutral",chart_score:0}}isBullishFlag(){const t=this.ohlcv.close.length,e=Math.floor(t/3),s=(Math.floor(e/2),this.ohlcv.close[t-2*e]);if((this.ohlcv.close[t-e]-s)/s<.15)return!1;const i=this.ohlcv.close[t-e];if((i-this.ohlcv.close[t-1])/i>.05)return!1;for(let s=t-e;s<t-1;s++)if(this.ohlcv.high[s]>this.ohlcv.high[s+1]||this.ohlcv.low[s]>this.ohlcv.low[s+1])return!1;return!0}isBearishFlag(){const t=this.ohlcv.close.length,e=Math.floor(t/3),s=(Math.floor(e/2),this.ohlcv.close[t-2*e]);if((s-this.ohlcv.close[t-e])/s<.15)return!1;const i=this.ohlcv.close[t-e];if((this.ohlcv.close[t-1]-i)/i>.05)return!1;for(let s=t-e;s<t-1;s++)if(this.ohlcv.high[s]<this.ohlcv.high[s+1]||this.ohlcv.low[s]<this.ohlcv.low[s+1])return!1;return!0}isBullishPennant(){const t=this.ohlcv.close.length,e=Math.floor(t/3),s=Math.floor(e/2),i=this.ohlcv.close[t-2*e];if((this.ohlcv.close[t-e]-i)/i<.15)return!1;const o=this.ohlcv.close[t-e];if((o-this.ohlcv.close[t-1])/o>.05)return!1;for(let e=t-s;e<t-1;e++)if(this.ohlcv.high[e]<this.ohlcv.high[e+1]&&this.ohlcv.low[e]<this.ohlcv.low[e+1]||this.ohlcv.high[e]>this.ohlcv.high[e+1]&&this.ohlcv.low[e]>this.ohlcv.low[e+1])return!1;return!0}isBearishPennant(){const t=this.ohlcv.close.length,e=Math.floor(t/3),s=Math.floor(e/2),i=this.ohlcv.close[t-2*e];if((i-this.ohlcv.close[t-e])/i<.15)return!1;const o=this.ohlcv.close[t-e];if((this.ohlcv.close[t-1]-o)/o>.05)return!1;for(let e=t-s;e<t-1;e++)if(this.ohlcv.high[e]>this.ohlcv.high[e+1]&&this.ohlcv.low[e]>this.ohlcv.low[e+1]||this.ohlcv.high[e]<this.ohlcv.high[e+1]&&this.ohlcv.low[e]<this.ohlcv.low[e+1])return!1;return!0}isDoubleTop(){const t=this.ohlcv.close.length,e=Math.floor(t/2),s=Math.max(...this.ohlcv.close.slice(0,e)),i=Math.max(...this.ohlcv.close.slice(e));if(s<=0||i<=0)return!1;const o=Math.min(...this.ohlcv.close.slice(0,e)),h=Math.min(...this.ohlcv.close.slice(e));return!((s-o)/s<.1||(i-h)/i<.1)&&Math.abs(s-i)/s<.03}isDoubleBottom(){const t=this.ohlcv.close.length,e=Math.floor(t/2),s=Math.min(...this.ohlcv.close.slice(0,e)),i=Math.min(...this.ohlcv.close.slice(e));if(s<=0||i<=0)return!1;const o=Math.max(...this.ohlcv.close.slice(0,e)),h=Math.max(...this.ohlcv.close.slice(e));return!((o-s)/s<.1||(h-i)/i<.1)&&Math.abs(s-i)/s<.03}isTripleTop(){const t=this.ohlcv.close.length,e=Math.floor(t/3),s=Math.max(...this.ohlcv.close.slice(0,e)),i=Math.max(...this.ohlcv.close.slice(e,2*e)),o=Math.max(...this.ohlcv.close.slice(2*e));if(s<=0||i<=0||o<=0)return!1;const h=(s-Math.min(...this.ohlcv.close.slice(0,e)))/s,r=(i-Math.min(...this.ohlcv.close.slice(e,2*e)))/i,n=(o-Math.min(...this.ohlcv.close.slice(2*e)))/o;return!(h<.1||r<.1||n<.1)&&Math.abs(s-i)/s<.03&&Math.abs(s-o)/s<.03}isTripleBottom(){const t=this.ohlcv.close.length,e=Math.floor(t/3),s=Math.min(...this.ohlcv.close.slice(0,e)),i=Math.min(...this.ohlcv.close.slice(e,2*e)),o=Math.min(...this.ohlcv.close.slice(2*e));if(s<=0||i<=0||o<=0)return!1;const h=(Math.max(...this.ohlcv.close.slice(0,e))-s)/s,r=(Math.max(...this.ohlcv.close.slice(e,2*e))-i)/i,n=(Math.max(...this.ohlcv.close.slice(2*e))-o)/o;return!(h<.1||r<.1||n<.1)&&Math.abs(s-i)/s<.03&&Math.abs(s-o)/s<.03}isHeadAndShoulders(){const t=this.ohlcv.close.length,e=Math.floor(t/3),s=Math.max(...this.ohlcv.close.slice(0,e)),i=Math.max(...this.ohlcv.close.slice(e,2*e)),o=Math.max(...this.ohlcv.close.slice(2*e));if(s<=0||i<=0||o<=0)return!1;const h=Math.min(...this.ohlcv.close.slice(0,e)),r=Math.min(...this.ohlcv.close.slice(e,2*e)),n=Math.min(...this.ohlcv.close.slice(2*e)),l=(i-r)/i,c=(Math.max(h,n)-Math.min(h,n))/Math.min(h,n);return l>.15&&c<.03}isInverseHeadAndShoulders(){const t=this.ohlcv.close.length,e=Math.floor(t/3),s=Math.min(...this.ohlcv.close.slice(0,e)),i=Math.min(...this.ohlcv.close.slice(e,2*e)),o=Math.min(...this.ohlcv.close.slice(2*e));if(s<=0||i<=0||o<=0)return!1;const h=Math.max(...this.ohlcv.close.slice(0,e)),r=Math.max(...this.ohlcv.close.slice(e,2*e)),n=Math.max(...this.ohlcv.close.slice(2*e)),l=(r-i)/i,c=(Math.min(h,n)-Math.max(h,n))/Math.max(h,n);return l>.15&&c<.03}isRisingWedge(){const t=this.ohlcv.close.length,e=Math.floor(t/3),s=Math.max(...this.ohlcv.close.slice(0,e)),i=Math.max(...this.ohlcv.close.slice(e,2*e)),o=Math.max(...this.ohlcv.close.slice(2*e)),h=Math.min(...this.ohlcv.close.slice(0,e)),r=Math.min(...this.ohlcv.close.slice(e,2*e)),n=Math.min(...this.ohlcv.close.slice(2*e));return s<i&&i<o&&h<r&&r<n}isFallingWedge(){const t=this.ohlcv.close.length,e=Math.floor(t/3),s=Math.max(...this.ohlcv.close.slice(0,e)),i=Math.max(...this.ohlcv.close.slice(e,2*e)),o=Math.max(...this.ohlcv.close.slice(2*e)),h=Math.min(...this.ohlcv.close.slice(0,e)),r=Math.min(...this.ohlcv.close.slice(e,2*e)),n=Math.min(...this.ohlcv.close.slice(2*e));return s>i&&i>o&&h>r&&r>n}isBullishTriangle(){const t=this.ohlcv.close.length,e=Math.floor(t/2),s=Math.max(...this.ohlcv.high.slice(0,e)),i=Math.max(...this.ohlcv.high.slice(e)),o=Math.min(...this.ohlcv.low.slice(0,e)),h=Math.min(...this.ohlcv.low.slice(e));return s>i&&o<h}isBearishTriangle(){const t=this.ohlcv.close.length,e=Math.floor(t/2),s=Math.max(...this.ohlcv.high.slice(0,e)),i=Math.max(...this.ohlcv.high.slice(e));return Math.min(...this.ohlcv.low.slice(0,e))<Math.min(...this.ohlcv.low.slice(e))&&s>i}isBullishRectangle(){const t=this.ohlcv.close.length,e=Math.floor(t/3),s=Math.max(...this.ohlcv.high.slice(0,e)),i=Math.max(...this.ohlcv.high.slice(e,2*e)),o=Math.max(...this.ohlcv.high.slice(2*e)),h=Math.min(...this.ohlcv.low.slice(0,e)),r=Math.min(...this.ohlcv.low.slice(e,2*e)),n=Math.min(...this.ohlcv.low.slice(2*e)),l=Math.abs(s-i)/s<.03&&Math.abs(i-o)/i<.03,c=Math.abs(h-r)/h<.03&&Math.abs(r-n)/r<.03;return l&&c}isBearishRectangle(){const t=this.ohlcv.close.length,e=Math.floor(t/3),s=Math.max(...this.ohlcv.high.slice(0,e)),i=Math.max(...this.ohlcv.high.slice(e,2*e)),o=Math.max(...this.ohlcv.high.slice(2*e)),h=Math.min(...this.ohlcv.low.slice(0,e)),r=Math.min(...this.ohlcv.low.slice(e,2*e)),n=Math.min(...this.ohlcv.low.slice(2*e)),l=Math.abs(s-i)/s<.03&&Math.abs(i-o)/i<.03,c=Math.abs(h-r)/h<.03&&Math.abs(r-n)/r<.03;return l&&c}}class V{constructor(){this.ChartPatterns=t=>new A(t).init()}init(t){return this.ohlcv=t.reduce(((t,{open:e,high:s,low:i,close:o,volume:h,...r})=>{t.open.push(e),t.high.push(s),t.low.push(i),t.close.push(o),t.volume.push(h);for(const e of Object.keys(r))t[e]||(t[e]=[]),t[e].push(r[e]);return t}),{open:[],high:[],low:[],close:[],volume:[]}),this}getHeaders(){return Object.keys(this.ohlcv)}getData(){const{ohlcv:t}=this,e=Object.keys(t),s=e.length;return t.open.map(((i,o)=>{const h={};for(let i=0;i<s;i++){const s=e[i],r=t[s][o];h[s]=r instanceof g?r.toNumber():r}return h}))}getLastValues(){const t={};for(const[e,s]of Object.entries(this.ohlcv)){let i=s[s.length-1];t[e]=i instanceof g?i.toNumber():i}return t}addColumn(t,e){const s=this.ohlcv.open.length;if(e.length>s)throw new Error("Invalid column data: The length of the new column exceeds the length of the OHLCV data");e=[...new Array(s-e.length).fill(null),...e],this.ohlcv[t]=e}crossPairs(t){const e=this.ohlcv,s={},i=t=>{if(!e.hasOwnProperty(t)&&"string"==typeof t){const[e,...s]=t.split("_");this[e]&&s.length>0&&this[e](...s)}};for(const{fast:o,slow:h}of t)if(o&&h)if(i(o),i(h),"number"!=typeof h||s[h]||(s[h]=e.close.map((()=>h))),e[o]&&e[h]){const t=E(e[o],e[h]);this.addColumn(`${o}_x_${h}`,t)}else if(e[o]&&s[h]){const t=E(e[o],s[h]);this.addColumn(`${o}_x_${h}`,t)}else console.error(`Missing ohlcv properties for ${o} or ${h}`)}ema(t){return((t,e)=>{const{ohlcv:s}=t,i=s.close,o=y(i,e);t.addColumn(`ema_${e}`,o)})(this,t),this}sma(t){return((t,e)=>{const{ohlcv:s}=t,i=s.close,o=P(i,e);t.addColumn(`sma_${e}`,o)})(this,t),this}macd(t,e,s){return((t,e=12,s=26,i=9)=>{const{ohlcv:o}=t,h=((t,e=12,s=26,i=9)=>{const o=[],h=[],r=[],n=new R({indicator:x,shortInterval:e,longInterval:s,signalInterval:i}),l=t.length;for(let e=0;e<l;e++){let s={};n.update(t[e]);try{s=n.getResult()}catch(t){s={macd:null,signal:null,histogram:null}}o.push(s.macd),h.push(s.signal),r.push(s.histogram)}return{macd_diff:o,macd_dea:h,macd_histogram:r,macd_diff_x_macd_dea:E(o,h)}})(o.close,e,s,i);for(let e in h)t.addColumn(e,h[e])})(this,t,e,s),this}bollingerBands(t,e,s){return((t,e,s)=>{const{ohlcv:i}=t,o=((t,e=20,s=2)=>{const i=t.length,o={upper:[],middle:[],lower:[]},h=new b(e,s);for(let e=0;e<i;e++){let s={};h.update(t[e]);try{s=h.getResult()}catch(t){s={upper:null,middle:null,lower:null}}o.upper.push(s.upper),o.middle.push(s.middle),o.lower.push(s.lower)}const r=S(t,{upper:o.upper,lower:o.lower});return{...o,range:r}})(i.close,e,s);for(let e in o)t.addColumn(`bollinger_bands_${e}`,o[e])})(this,t,e),this}rsi(t,e,s){return((t,e,s,i)=>{const{ohlcv:o}=t;"number"==typeof e&&void 0===i&&(i=e);const h=((t,e=14,s="SMA",i=14)=>{if(t.length<e)return[];let o=[];e=parseInt(e),i=parseInt(i);const h=new B(e),r=t.length;for(let e=0;e<r;e++){let s=null;h.update(t[e]);try{s=h.getResult()}catch(t){s=null}o.push(s)}o=o.filter((t=>t));let n={[`rsi_${e}`]:o};if("string"==typeof s&&"number"==typeof i&&C.hasOwnProperty(`get${s}`)){const t=C[`get${s}`](o,i);n[`rsi_${s}_${i}`]=t,n[`rsi_${e}_x_rsi_${s}_${i}`]=E(o,t)}return n})(o.close,e,s,i);for(let e in h)t.addColumn(`${e}`.toLowerCase(),h[e])})(this,t,e,s),this}candles(){return(t=>{const{ohlcv:e}=t,s=(t=>{const{open:e,high:s,low:i,close:o}=t,h=e.length;if(![e,s,i,o].every((t=>Array.isArray(t)&&t.length>1&&t.length===h)))return{pattern:Array(h).fill("Neutral"),name:Array(h).fill("No Pattern"),score:Array(h).fill(0)};const r=(t,e,s=1e-4)=>Math.abs(t-e)<s,n={bullish:[{name:"Marubozu",condition:(t,e)=>r(e.open,e.low)&&r(e.close,e.high),score:2},{name:"Engulfing",condition:(t,e)=>e.open<t.close&&e.close>t.open&&e.low<t.low&&e.high>t.high,score:2},{name:"Kicker",condition:(t,e)=>e.open<t.open&&e.close>e.open&&t.close<t.open,score:2},{name:"Morning Star",condition:(t,e)=>e.close>t.close&&e.open<t.open&&t.close<t.open,score:2},{name:"Piercing Line",condition:(t,e)=>e.close>t.close&&e.open<t.open&&e.close>(t.open+t.close)/2,score:1},{name:"Belt Hold",condition:(t,e)=>e.open>t.open&&r(e.close,e.high)&&r(t.close,t.low),score:1},{name:"Harami",condition:(t,e)=>e.open>t.close&&e.close<t.open&&e.open<t.open&&e.close>t.close,score:1},{name:"Doji",condition:(t,e)=>r(e.close,e.open)&&e.high-e.low>Math.abs(e.close-e.open),score:0}],bearish:[{name:"Marubozu",condition:(t,e)=>r(e.open,e.high)&&r(e.close,e.low),score:-2},{name:"Engulfing",condition:(t,e)=>e.open>t.close&&e.close<t.open&&e.high>t.high&&e.low<t.low,score:-2},{name:"Kicker",condition:(t,e)=>e.open>t.open&&e.close<e.open&&t.close>t.open,score:-2},{name:"Evening Star",condition:(t,e)=>e.close<t.close&&e.open>t.open&&t.close<t.open,score:-2},{name:"Dark Cloud Cover",condition:(t,e)=>e.close<t.close&&e.open>t.open&&e.close<(t.open+t.close)/2,score:-1},{name:"Belt Hold",condition:(t,e)=>e.open<t.open&&r(e.close,e.low)&&r(t.close,t.high),score:-1},{name:"Harami",condition:(t,e)=>e.open<t.close&&e.close>t.open&&e.open>t.open&&e.close<t.close,score:-1},{name:"Doji",condition:(t,e)=>r(e.close,e.open)&&e.high-e.low>Math.abs(e.close-e.open),score:0}]},l=(t,e,s)=>{for(const{name:i,condition:o,score:h}of s)if(o(t,e))return{name:i,score:h};return null},c=["Neutral"],a=["No Pattern"],u=[0];for(let t=1;t<h;t++){const h={open:e[t-1],high:s[t-1],low:i[t-1],close:o[t-1]},r={open:e[t],high:s[t],low:i[t],close:o[t]},p=l(h,r,n.bullish)||l(h,r,n.bearish);p?(c.push(p.score>0?"Bullish":"Bearish"),a.push(p.name),u.push(p.score)):(c.push("Neutral"),a.push("No Pattern"),u.push(0))}return{pattern:c,name:a,score:u}})(e);for(let e in s)t.addColumn(`candle_${e}`.toLowerCase(),s[e])})(this),this}volumeProfile(t,e,s){return((t,e,s=1,i)=>{let{ohlcv:o}=t;const h=((t,e,s)=>{const i=new Date(t[s][t[s].length-1]),o=new Date(i);o.setDate(o.getDate()-e),o.setHours(0,0,0,0);const h={open:[],high:[],low:[],close:[],volume:[],[s]:[]};for(let e=0;e<t[s].length;e++)new Date(t[s][e])>=o&&(h.open.push(t.open[e]),h.high.push(t.high[e]),h.low.push(t.low[e]),h.close.push(t.close[e]),h.volume.push(t.volume[e]),h[s].push(t[s][e]));return h})(o,s,i),r=((t,e=5)=>{const{open:s,high:i,low:o,close:h,volume:r}=t,n=Math.min(...o),l=(Math.max(...i)-n)/e,c={upVolume:0,downVolume:0,grossVolume:0},a=Array.from({length:e},((t,e)=>({price:n+l*e,upVolume:0,downVolume:0,grossVolume:0}))),u=1/l;for(let t=0;t<h.length;t++){const l=h[t],c=s[t],p=i[t],g=o[t],v=r[t],f=l>=c?v:0,d=l<c?v:0,m=Math.max(0,Math.floor((g-n)*u)),w=Math.min(e,Math.ceil((p-n)*u));for(let t=m;t<w;t++)a[t].upVolume+=f,a[t].downVolume+=d,a[t].grossVolume+=f+d}for(const{upVolume:t,downVolume:e,grossVolume:s}of a)c.upVolume+=t,c.downVolume+=e,c.grossVolume+=s;return{bins:a,nodes:D(a)}})(h,e),n=r.nodes.high.price,l=r.nodes.low.price;t.addColumn("volume_profile_high",[n]),t.addColumn("volume_profile_low",[l])})(this,t,e,s),this}}})(),OHLCV_INDICATORS=e})();
package/index.js CHANGED
@@ -7,6 +7,7 @@ import { volumeProfile } from './src/studies/volumeProfile.js'
7
7
  import {findCrosses} from './src/utilities.js'
8
8
  import { candles } from './src/studies/candles.js'
9
9
  import ChartPatterns from './src/studies/chart.js'
10
+ import {Big} from 'trading-signals';
10
11
 
11
12
  export default class OHLCV_INDICATORS {
12
13
  constructor() {
@@ -15,7 +16,6 @@ export default class OHLCV_INDICATORS {
15
16
 
16
17
  init(ohlcv) {
17
18
 
18
- this.rawOhlcv = ohlcv
19
19
  this.ohlcv = ohlcv.reduce((acc, { open, high, low, close, volume, ...rest }) => {
20
20
  acc.open.push(open)
21
21
  acc.high.push(high)
@@ -49,7 +49,10 @@ export default class OHLCV_INDICATORS {
49
49
  for(let x = 0; x < keysLength; x++)
50
50
  {
51
51
  const header = keys[x]
52
- row[header] = ohlcv[header][i]
52
+ const value = ohlcv[header][i]
53
+
54
+
55
+ row[header] = (value instanceof Big) ? value.toNumber() : value
53
56
  }
54
57
 
55
58
  return row
@@ -59,8 +62,8 @@ export default class OHLCV_INDICATORS {
59
62
  const output = {}
60
63
 
61
64
  for (const [k, arr] of Object.entries(this.ohlcv)) {
62
- let value = arr[arr.length - 1];
63
- output[k] = value;
65
+ let value = arr[arr.length - 1]
66
+ output[k] = (value instanceof Big) ? value.toNumber(): value;
64
67
  }
65
68
 
66
69
  return output
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ohlcv-indicators",
3
- "version": "1.2.5",
3
+ "version": "1.2.7",
4
4
  "description": "A JavaScript library featuring optimized trading indicators for OHLCV arrays [{open, high, low, close, value}]. This library is optimized for backtesting and trading bot development.",
5
5
  "main": "index.js",
6
6
  "type": "module",
@@ -11,7 +11,7 @@
11
11
  "author": "https://jaimelias.com/",
12
12
  "license": "ISC",
13
13
  "dependencies": {
14
- "@debut/indicators": "^1.3.20"
14
+ "trading-signals": "^5.0.4"
15
15
  },
16
16
  "devDependencies": {
17
17
  "dotenv": "^16.4.5",
@@ -1,4 +1,5 @@
1
- import { BollingerBands } from '@debut/indicators';
1
+
2
+ import {BollingerBands, Big} from 'trading-signals';
2
3
 
3
4
 
4
5
  export const bollingerBands = (main, size, times) => {
@@ -16,46 +17,53 @@ export const bollingerBands = (main, size, times) => {
16
17
 
17
18
  export const getBollingerBands = (data, size = 20, times = 2) => {
18
19
 
19
-
20
- const output = {lower: [], middle: [], upper: []}
20
+ const dataLength = data.length
21
+ const output = {upper: [], middle: [], lower: []}
21
22
  const instance = new BollingerBands(size, times)
22
23
 
23
- data.forEach(c => {
24
24
 
25
+ for(let x = 0; x < dataLength; x++) {
26
+ let obj = {}
27
+ instance.update(data[x])
25
28
 
26
- const bb = instance.nextValue(c)
27
-
28
- if(typeof bb === 'object')
29
+ try
29
30
  {
30
- const {lower, middle, upper} = bb
31
- output.lower.push(lower)
32
- output.middle.push(middle)
33
- output.upper.push(upper)
34
-
31
+ obj = instance.getResult()
35
32
  }
36
- else
33
+ catch(err)
37
34
  {
38
- output.lower.push(null)
39
- output.middle.push(null)
40
- output.upper.push(null)
35
+ obj = {upper: null, middle: null, lower: null}
41
36
  }
42
- })
43
37
 
44
- const range = bollingerBandsRange(data, {upper: output.upper, lower: output.lower})
38
+ output.upper.push(obj.upper)
39
+ output.middle.push(obj.middle)
40
+ output.lower.push(obj.lower)
45
41
 
42
+ }
46
43
 
47
- return {...output, range}
44
+ const range = bollingerBandsRange(data, {upper: output.upper, lower: output.lower})
48
45
 
46
+ return {...output, range}
49
47
  }
50
48
 
51
49
 
52
50
 
53
51
  const bollingerBandsRange = (data, bollingerBands) => {
54
- let {upper, lower} = bollingerBands;
55
-
56
- const range = upper.map((v, i) => v - lower[i]);
57
-
58
- const output = data.map((v, i) => ((v - lower[i]) / range[i]) * 100);
52
+ const { upper, lower } = bollingerBands;
53
+ const output = new Array(data.length);
54
+
55
+ for (let i = 0; i < data.length; i++) {
56
+ if (upper[i] != null && lower[i] != null && data[i] != null) {
57
+ const upperBig = new Big(upper[i]);
58
+ const lowerBig = new Big(lower[i]);
59
+ const dataBig = new Big(data[i]);
60
+
61
+ const range = upperBig.minus(lowerBig);
62
+ output[i] = dataBig.minus(lowerBig).div(range).times(100).toNumber();
63
+ } else {
64
+ output[i] = null;
65
+ }
66
+ }
59
67
 
60
68
  return output;
61
- };
69
+ }
@@ -1,5 +1,5 @@
1
1
 
2
- import { EMA } from '@debut/indicators';
2
+ import {EMA} from 'trading-signals';
3
3
 
4
4
 
5
5
  export const ema = (main, size) => {
@@ -11,15 +11,27 @@ export const ema = (main, size) => {
11
11
 
12
12
  export const getEMA = (data, size) => {
13
13
 
14
-
15
14
  const output = []
16
15
  const instance = new EMA(size)
16
+ const dataLength = data.length
17
+
18
+ for(let x = 0; x < dataLength; x++)
19
+ {
20
+ let value = null
21
+ instance.update(data[x])
22
+
23
+ try
24
+ {
25
+ value = instance.getResult()
26
+ }
27
+ catch(err)
28
+ {
29
+ value = null
30
+ }
31
+
32
+ output.push(value)
33
+ }
17
34
 
18
- data.forEach(c => {
19
-
20
- output.push(instance.nextValue(c))
21
-
22
- })
23
35
 
24
36
  return output
25
37
 
@@ -1,5 +1,5 @@
1
1
  import { findCrosses } from "../utilities.js";
2
- import { getEMA } from "./ema.js";
2
+ import {EMA, MACD} from 'trading-signals';
3
3
 
4
4
 
5
5
  export const macd = (main, fastLine = 12, slowLine = 26, signalLine = 9) => {
@@ -15,23 +15,44 @@ export const macd = (main, fastLine = 12, slowLine = 26, signalLine = 9) => {
15
15
 
16
16
  export const getMACD = (data, fastLine = 12, slowLine = 26, signalLine = 9) => {
17
17
 
18
- const fastEMA = getEMA(data, fastLine)
19
- const slowEMA = getEMA(data, slowLine)
18
+ const diff = []
19
+ const dea = []
20
+ const histogram = []
20
21
 
21
- // Calculate the MACD line (diff)
22
- const diff = fastEMA.map((o, i) => (isNaN(o) || isNaN(slowEMA[i])) ? null : o - slowEMA[i]);
22
+ const instance = new MACD({
23
+ indicator: EMA,
24
+ shortInterval: fastLine,
25
+ longInterval: slowLine,
26
+ signalInterval: signalLine
27
+ })
23
28
 
24
- // Calculate the MACD line (dea)
25
- const dea = getEMA(diff, signalLine)
29
+ const dataLength = data.length
30
+
31
+ for(let x = 0; x < dataLength; x++)
32
+ {
33
+ let obj = {}
34
+ instance.update(data[x])
35
+
36
+ try
37
+ {
38
+ obj = instance.getResult()
39
+ }
40
+ catch(err)
41
+ {
42
+ obj = {macd: null, signal: null, histogram: null}
43
+ }
44
+
45
+ diff.push(obj.macd)
46
+ dea.push(obj.signal)
47
+ histogram.push(obj.histogram)
48
+ }
26
49
 
27
- // Calculate the MACD line (histogram)
28
- const histogram = diff.map((d, i) => d - dea[i])
29
50
  const x = findCrosses(diff, dea)
30
51
 
31
52
  return {
32
- 'macd_diff': diff,
33
- 'macd_dea': dea,
34
- 'macd_histogram': histogram,
35
- 'macd_diff_x_macd_dea': x
53
+ macd_diff: diff,
54
+ macd_dea: dea,
55
+ macd_histogram: histogram,
56
+ macd_diff_x_macd_dea: x
36
57
  }
37
58
  }
@@ -0,0 +1,18 @@
1
+ import { getSMA } from './sma.js'
2
+
3
+ export const RelativeVolume = (main, size) => {
4
+ const {ohlcv} = main
5
+ const data = ohlcv['volume']
6
+ const relVolume = getRelativeVolume(main.BigNumber, data, size)
7
+ main.addColumn(`relative_volume_${size}`, relVolume)
8
+ }
9
+
10
+ export const getRelativeVolume = (BigNumber, data, size = 10) => {
11
+ const sma = getSMA(BigNumber, data, size)
12
+
13
+ return data.map((v, i) => {
14
+ const prevSma = sma[i - 1]
15
+ if (i === 0 || !prevSma || prevSma.isZero()) return null
16
+ return v.dividedBy(prevSma)
17
+ }).filter(v => !Number.isNaN(v))
18
+ }
@@ -1,5 +1,5 @@
1
1
 
2
- import { SMA } from '@debut/indicators';
2
+ import {SMA, Big} from 'trading-signals';
3
3
 
4
4
  export const sma = (main, size) => {
5
5
  const {ohlcv} = main
@@ -10,16 +10,28 @@ export const sma = (main, size) => {
10
10
 
11
11
  export const getSMA = (data, size) => {
12
12
 
13
-
14
13
  const output = []
15
14
  const instance = new SMA(size)
15
+ const dataLength = data.length
16
16
 
17
- data.forEach(c => {
18
-
19
- output.push(instance.nextValue(c))
20
17
 
21
- })
18
+
19
+ for(let x = 0; x < dataLength; x++)
20
+ {
21
+ let value = null
22
+ instance.update(data[x])
23
+
24
+ try
25
+ {
26
+ value = instance.getResult()
27
+ }
28
+ catch(err)
29
+ {
30
+ value = null
31
+ }
32
+
33
+ output.push(value)
34
+ }
22
35
 
23
36
  return output
24
-
25
37
  }
@@ -1,7 +1,7 @@
1
1
  import { getSMA } from "../moving-averages/sma.js";
2
2
  import { getEMA } from "../moving-averages/ema.js";
3
3
  import { findCrosses } from "../utilities.js";
4
- import { RSI } from "@debut/indicators";
4
+ import {RSI} from 'trading-signals';
5
5
 
6
6
  const ma = {getSMA, getEMA}
7
7
 
@@ -34,12 +34,24 @@ export const getRSI = (data, period = 14, movingAverage = 'SMA', movingAveragePe
34
34
  period = parseInt(period)
35
35
  movingAveragePeriod = parseInt(movingAveragePeriod)
36
36
  const instance = new RSI(period)
37
+ const dataLength = data.length
37
38
 
38
- data.forEach(c => {
39
-
40
- rsi.push(instance.nextValue(c))
41
-
42
- })
39
+ for(let x = 0; x < dataLength; x++)
40
+ {
41
+ let value = null
42
+ instance.update(data[x])
43
+
44
+ try
45
+ {
46
+ value = instance.getResult()
47
+ }
48
+ catch(err)
49
+ {
50
+ value = null
51
+ }
52
+
53
+ rsi.push(value)
54
+ }
43
55
 
44
56
  rsi = rsi.filter(v => v)
45
57
 
@@ -1,20 +1,18 @@
1
1
  export default class ChartPatterns {
2
+
2
3
  constructor(ohlcv, period = 100) {
3
-
4
- const validProps = ['open', 'high', 'low', 'close']
5
-
6
- for(let [key, arr] of Object.entries(ohlcv))
7
- {
8
- if(validProps.includes(key))
9
- {
10
- this[key] = arr.splice(-period)
4
+ const validProps = ['open', 'high', 'low', 'close'];
5
+ this.ohlcv = {};
6
+
7
+ for (let key of Object.keys(ohlcv)) {
8
+ if (validProps.includes(key)) {
9
+ this.ohlcv[key] = ohlcv[key].slice(-period);
11
10
  }
12
-
13
11
  }
14
12
  }
15
13
 
16
14
  init() {
17
- const length = this.close.length;
15
+ const length = this.ohlcv.close.length;
18
16
  if (length < 50) {
19
17
  console.log('PatternRecognizer requires at least 50 datapoints')
20
18
  return { chart_pattern: 'Neutral', chart_score: 0 };
@@ -55,13 +53,13 @@ export default class ChartPatterns {
55
53
  isBullishFlag() {
56
54
 
57
55
  // A Bullish Flag is characterized by a sharp price rise followed by a period of consolidation that has a downward slant.
58
- const length = this.close.length;
56
+ const length = this.ohlcv.close.length;
59
57
  const flagpoleLength = Math.floor(length / 3); // Roughly the first third of the data
60
58
  const consolidationLength = Math.floor(flagpoleLength / 2); // Roughly half the length of the flagpole
61
59
 
62
60
  // Sharp price rise (flagpole)
63
- const flagpoleStart = this.close[length - flagpoleLength * 2];
64
- const flagpoleEnd = this.close[length - flagpoleLength];
61
+ const flagpoleStart = this.ohlcv.close[length - flagpoleLength * 2];
62
+ const flagpoleEnd = this.ohlcv.close[length - flagpoleLength];
65
63
  const flagpoleGain = (flagpoleEnd - flagpoleStart) / flagpoleStart;
66
64
 
67
65
  if (flagpoleGain < 0.15) { // A significant gain, at least 15%
@@ -69,8 +67,8 @@ export default class ChartPatterns {
69
67
  }
70
68
 
71
69
  // Consolidation period
72
- const consolidationStart = this.close[length - flagpoleLength];
73
- const consolidationEnd = this.close[length - 1];
70
+ const consolidationStart = this.ohlcv.close[length - flagpoleLength];
71
+ const consolidationEnd = this.ohlcv.close[length - 1];
74
72
  const consolidationDrop = (consolidationStart - consolidationEnd) / consolidationStart;
75
73
 
76
74
  if (consolidationDrop > 0.05) { // A downward slant, less than 5%
@@ -79,7 +77,7 @@ export default class ChartPatterns {
79
77
 
80
78
  // Ensure that the consolidation period has lower highs and lower lows
81
79
  for (let i = length - flagpoleLength; i < length - 1; i++) {
82
- if (this.high[i] > this.high[i + 1] || this.low[i] > this.low[i + 1]) {
80
+ if (this.ohlcv.high[i] > this.ohlcv.high[i + 1] || this.ohlcv.low[i] > this.ohlcv.low[i + 1]) {
83
81
  return false;
84
82
  }
85
83
  }
@@ -91,13 +89,13 @@ export default class ChartPatterns {
91
89
  // https://www.tradingview.com/support/solutions/43000653209-chart-pattern-bullish-flag/
92
90
  isBearishFlag() {
93
91
  // A Bearish Flag is characterized by a sharp price decline followed by a period of consolidation that has an upward slant.
94
- const length = this.close.length;
92
+ const length = this.ohlcv.close.length;
95
93
  const flagpoleLength = Math.floor(length / 3); // Roughly the first third of the data
96
94
  const consolidationLength = Math.floor(flagpoleLength / 2); // Roughly half the length of the flagpole
97
95
 
98
96
  // Sharp price decline (flagpole)
99
- const flagpoleStart = this.close[length - flagpoleLength * 2];
100
- const flagpoleEnd = this.close[length - flagpoleLength];
97
+ const flagpoleStart = this.ohlcv.close[length - flagpoleLength * 2];
98
+ const flagpoleEnd = this.ohlcv.close[length - flagpoleLength];
101
99
  const flagpoleDrop = (flagpoleStart - flagpoleEnd) / flagpoleStart;
102
100
 
103
101
  if (flagpoleDrop < 0.15) { // A significant drop, at least 15%
@@ -105,8 +103,8 @@ export default class ChartPatterns {
105
103
  }
106
104
 
107
105
  // Consolidation period
108
- const consolidationStart = this.close[length - flagpoleLength];
109
- const consolidationEnd = this.close[length - 1];
106
+ const consolidationStart = this.ohlcv.close[length - flagpoleLength];
107
+ const consolidationEnd = this.ohlcv.close[length - 1];
110
108
  const consolidationGain = (consolidationEnd - consolidationStart) / consolidationStart;
111
109
 
112
110
  if (consolidationGain > 0.05) { // An upward slant, less than 5%
@@ -115,7 +113,7 @@ export default class ChartPatterns {
115
113
 
116
114
  // Ensure that the consolidation period has higher lows and higher highs
117
115
  for (let i = length - flagpoleLength; i < length - 1; i++) {
118
- if (this.high[i] < this.high[i + 1] || this.low[i] < this.low[i + 1]) {
116
+ if (this.ohlcv.high[i] < this.ohlcv.high[i + 1] || this.ohlcv.low[i] < this.ohlcv.low[i + 1]) {
119
117
  return false;
120
118
  }
121
119
  }
@@ -127,13 +125,13 @@ export default class ChartPatterns {
127
125
  // https://www.tradingview.com/support/solutions/43000653215-chart-pattern-bullish-pennant/
128
126
  isBullishPennant() {
129
127
  // A Bullish Pennant is characterized by a sharp price rise followed by a small symmetrical triangle consolidation.
130
- const length = this.close.length;
128
+ const length = this.ohlcv.close.length;
131
129
  const flagpoleLength = Math.floor(length / 3); // Roughly the first third of the data
132
130
  const pennantLength = Math.floor(flagpoleLength / 2); // Roughly half the length of the flagpole
133
131
 
134
132
  // Sharp price rise (flagpole)
135
- const flagpoleStart = this.close[length - flagpoleLength * 2];
136
- const flagpoleEnd = this.close[length - flagpoleLength];
133
+ const flagpoleStart = this.ohlcv.close[length - flagpoleLength * 2];
134
+ const flagpoleEnd = this.ohlcv.close[length - flagpoleLength];
137
135
  const flagpoleGain = (flagpoleEnd - flagpoleStart) / flagpoleStart;
138
136
 
139
137
  if (flagpoleGain < 0.15) { // A significant gain, at least 15%
@@ -141,8 +139,8 @@ export default class ChartPatterns {
141
139
  }
142
140
 
143
141
  // Small symmetrical triangle consolidation
144
- const pennantStart = this.close[length - flagpoleLength];
145
- const pennantEnd = this.close[length - 1];
142
+ const pennantStart = this.ohlcv.close[length - flagpoleLength];
143
+ const pennantEnd = this.ohlcv.close[length - 1];
146
144
  const pennantDrop = (pennantStart - pennantEnd) / pennantStart;
147
145
 
148
146
  if (pennantDrop > 0.05) { // A downward slant, less than 5%
@@ -151,8 +149,8 @@ export default class ChartPatterns {
151
149
 
152
150
  // Ensure the consolidation period forms a small symmetrical triangle
153
151
  for (let i = length - pennantLength; i < length - 1; i++) {
154
- if ((this.high[i] < this.high[i + 1] && this.low[i] < this.low[i + 1]) ||
155
- (this.high[i] > this.high[i + 1] && this.low[i] > this.low[i + 1])) {
152
+ if ((this.ohlcv.high[i] < this.ohlcv.high[i + 1] && this.ohlcv.low[i] < this.ohlcv.low[i + 1]) ||
153
+ (this.ohlcv.high[i] > this.ohlcv.high[i + 1] && this.ohlcv.low[i] > this.ohlcv.low[i + 1])) {
156
154
  return false;
157
155
  }
158
156
  }
@@ -163,13 +161,13 @@ export default class ChartPatterns {
163
161
  // Implementation of Bearish Pennant
164
162
  // https://www.tradingview.com/support/solutions/43000697937-chart-pattern-bearish-pennant/
165
163
  isBearishPennant() {
166
- const length = this.close.length;
164
+ const length = this.ohlcv.close.length;
167
165
  const flagpoleLength = Math.floor(length / 3); // Roughly the first third of the data
168
166
  const pennantLength = Math.floor(flagpoleLength / 2); // Roughly half the length of the flagpole
169
167
 
170
168
  // Sharp price decline (flagpole)
171
- const flagpoleStart = this.close[length - flagpoleLength * 2];
172
- const flagpoleEnd = this.close[length - flagpoleLength];
169
+ const flagpoleStart = this.ohlcv.close[length - flagpoleLength * 2];
170
+ const flagpoleEnd = this.ohlcv.close[length - flagpoleLength];
173
171
  const flagpoleDrop = (flagpoleStart - flagpoleEnd) / flagpoleStart;
174
172
 
175
173
  if (flagpoleDrop < 0.15) { // A significant drop, at least 15%
@@ -177,8 +175,8 @@ export default class ChartPatterns {
177
175
  }
178
176
 
179
177
  // Small symmetrical triangle consolidation
180
- const pennantStart = this.close[length - flagpoleLength];
181
- const pennantEnd = this.close[length - 1];
178
+ const pennantStart = this.ohlcv.close[length - flagpoleLength];
179
+ const pennantEnd = this.ohlcv.close[length - 1];
182
180
  const pennantGain = (pennantEnd - pennantStart) / pennantStart;
183
181
 
184
182
  if (pennantGain > 0.05) { // An upward slant, less than 5%
@@ -187,8 +185,8 @@ export default class ChartPatterns {
187
185
 
188
186
  // Ensure the consolidation period forms a small symmetrical triangle
189
187
  for (let i = length - pennantLength; i < length - 1; i++) {
190
- if ((this.high[i] > this.high[i + 1] && this.low[i] > this.low[i + 1]) ||
191
- (this.high[i] < this.high[i + 1] && this.low[i] < this.low[i + 1])) {
188
+ if ((this.ohlcv.high[i] > this.ohlcv.high[i + 1] && this.ohlcv.low[i] > this.ohlcv.low[i + 1]) ||
189
+ (this.ohlcv.high[i] < this.ohlcv.high[i + 1] && this.ohlcv.low[i] < this.ohlcv.low[i + 1])) {
192
190
  return false;
193
191
  }
194
192
  }
@@ -199,18 +197,18 @@ export default class ChartPatterns {
199
197
  // Implementation of Double Top
200
198
  // https://www.tradingview.com/support/solutions/43000653211-chart-pattern-double-top/
201
199
  isDoubleTop() {
202
- const length = this.close.length;
200
+ const length = this.ohlcv.close.length;
203
201
  const midpoint = Math.floor(length / 2);
204
202
 
205
- const firstPeak = Math.max(...this.close.slice(0, midpoint));
206
- const secondPeak = Math.max(...this.close.slice(midpoint));
203
+ const firstPeak = Math.max(...this.ohlcv.close.slice(0, midpoint));
204
+ const secondPeak = Math.max(...this.ohlcv.close.slice(midpoint));
207
205
 
208
206
  if (firstPeak <= 0 || secondPeak <= 0) {
209
207
  return false;
210
208
  }
211
209
 
212
- const firstValley = Math.min(...this.close.slice(0, midpoint));
213
- const secondValley = Math.min(...this.close.slice(midpoint));
210
+ const firstValley = Math.min(...this.ohlcv.close.slice(0, midpoint));
211
+ const secondValley = Math.min(...this.ohlcv.close.slice(midpoint));
214
212
 
215
213
  const dropFromFirstPeak = (firstPeak - firstValley) / firstPeak;
216
214
  const dropFromSecondPeak = (secondPeak - secondValley) / secondPeak;
@@ -225,18 +223,18 @@ export default class ChartPatterns {
225
223
  // Implementation of Double Bottom
226
224
  // https://www.tradingview.com/support/solutions/43000690659-chart-pattern-double-bottom/
227
225
  isDoubleBottom() {
228
- const length = this.close.length;
226
+ const length = this.ohlcv.close.length;
229
227
  const midpoint = Math.floor(length / 2);
230
228
 
231
- const firstValley = Math.min(...this.close.slice(0, midpoint));
232
- const secondValley = Math.min(...this.close.slice(midpoint));
229
+ const firstValley = Math.min(...this.ohlcv.close.slice(0, midpoint));
230
+ const secondValley = Math.min(...this.ohlcv.close.slice(midpoint));
233
231
 
234
232
  if (firstValley <= 0 || secondValley <= 0) {
235
233
  return false;
236
234
  }
237
235
 
238
- const firstPeak = Math.max(...this.close.slice(0, midpoint));
239
- const secondPeak = Math.max(...this.close.slice(midpoint));
236
+ const firstPeak = Math.max(...this.ohlcv.close.slice(0, midpoint));
237
+ const secondPeak = Math.max(...this.ohlcv.close.slice(midpoint));
240
238
 
241
239
  const riseFromFirstValley = (firstPeak - firstValley) / firstValley;
242
240
  const riseFromSecondValley = (secondPeak - secondValley) / secondValley;
@@ -251,20 +249,20 @@ export default class ChartPatterns {
251
249
  // Implementation of Triple Top
252
250
  // https://www.tradingview.com/support/solutions/43000653218-chart-pattern-triple-top/
253
251
  isTripleTop() {
254
- const length = this.close.length;
252
+ const length = this.ohlcv.close.length;
255
253
  const third = Math.floor(length / 3);
256
254
 
257
- const firstPeak = Math.max(...this.close.slice(0, third));
258
- const secondPeak = Math.max(...this.close.slice(third, third * 2));
259
- const thirdPeak = Math.max(...this.close.slice(third * 2));
255
+ const firstPeak = Math.max(...this.ohlcv.close.slice(0, third));
256
+ const secondPeak = Math.max(...this.ohlcv.close.slice(third, third * 2));
257
+ const thirdPeak = Math.max(...this.ohlcv.close.slice(third * 2));
260
258
 
261
259
  if (firstPeak <= 0 || secondPeak <= 0 || thirdPeak <= 0) {
262
260
  return false;
263
261
  }
264
262
 
265
- const dropFromFirstPeak = (firstPeak - Math.min(...this.close.slice(0, third))) / firstPeak;
266
- const dropFromSecondPeak = (secondPeak - Math.min(...this.close.slice(third, third * 2))) / secondPeak;
267
- const dropFromThirdPeak = (thirdPeak - Math.min(...this.close.slice(third * 2))) / thirdPeak;
263
+ const dropFromFirstPeak = (firstPeak - Math.min(...this.ohlcv.close.slice(0, third))) / firstPeak;
264
+ const dropFromSecondPeak = (secondPeak - Math.min(...this.ohlcv.close.slice(third, third * 2))) / secondPeak;
265
+ const dropFromThirdPeak = (thirdPeak - Math.min(...this.ohlcv.close.slice(third * 2))) / thirdPeak;
268
266
 
269
267
  if (dropFromFirstPeak < 0.1 || dropFromSecondPeak < 0.1 || dropFromThirdPeak < 0.1) {
270
268
  return false;
@@ -276,20 +274,20 @@ export default class ChartPatterns {
276
274
  // Implementation of Triple Bottom
277
275
  // https://www.tradingview.com/support/solutions/43000690660-chart-pattern-triple-bottom/
278
276
  isTripleBottom() {
279
- const length = this.close.length;
277
+ const length = this.ohlcv.close.length;
280
278
  const third = Math.floor(length / 3);
281
279
 
282
- const firstValley = Math.min(...this.close.slice(0, third));
283
- const secondValley = Math.min(...this.close.slice(third, third * 2));
284
- const thirdValley = Math.min(...this.close.slice(third * 2));
280
+ const firstValley = Math.min(...this.ohlcv.close.slice(0, third));
281
+ const secondValley = Math.min(...this.ohlcv.close.slice(third, third * 2));
282
+ const thirdValley = Math.min(...this.ohlcv.close.slice(third * 2));
285
283
 
286
284
  if (firstValley <= 0 || secondValley <= 0 || thirdValley <= 0) {
287
285
  return false;
288
286
  }
289
287
 
290
- const riseFromFirstValley = (Math.max(...this.close.slice(0, third)) - firstValley) / firstValley;
291
- const riseFromSecondValley = (Math.max(...this.close.slice(third, third * 2)) - secondValley) / secondValley;
292
- const riseFromThirdValley = (Math.max(...this.close.slice(third * 2)) - thirdValley) / thirdValley;
288
+ const riseFromFirstValley = (Math.max(...this.ohlcv.close.slice(0, third)) - firstValley) / firstValley;
289
+ const riseFromSecondValley = (Math.max(...this.ohlcv.close.slice(third, third * 2)) - secondValley) / secondValley;
290
+ const riseFromThirdValley = (Math.max(...this.ohlcv.close.slice(third * 2)) - thirdValley) / thirdValley;
293
291
 
294
292
  if (riseFromFirstValley < 0.1 || riseFromSecondValley < 0.1 || riseFromThirdValley < 0.1) {
295
293
  return false;
@@ -301,20 +299,20 @@ export default class ChartPatterns {
301
299
  // Implementation of Head and Shoulders
302
300
  // https://www.tradingview.com/support/solutions/43000653213-chart-pattern-head-and-shoulders/
303
301
  isHeadAndShoulders() {
304
- const length = this.close.length;
302
+ const length = this.ohlcv.close.length;
305
303
  const third = Math.floor(length / 3);
306
304
 
307
- const leftShoulder = Math.max(...this.close.slice(0, third));
308
- const head = Math.max(...this.close.slice(third, third * 2));
309
- const rightShoulder = Math.max(...this.close.slice(third * 2));
305
+ const leftShoulder = Math.max(...this.ohlcv.close.slice(0, third));
306
+ const head = Math.max(...this.ohlcv.close.slice(third, third * 2));
307
+ const rightShoulder = Math.max(...this.ohlcv.close.slice(third * 2));
310
308
 
311
309
  if (leftShoulder <= 0 || head <= 0 || rightShoulder <= 0) {
312
310
  return false;
313
311
  }
314
312
 
315
- const leftValley = Math.min(...this.close.slice(0, third));
316
- const middleValley = Math.min(...this.close.slice(third, third * 2));
317
- const rightValley = Math.min(...this.close.slice(third * 2));
313
+ const leftValley = Math.min(...this.ohlcv.close.slice(0, third));
314
+ const middleValley = Math.min(...this.ohlcv.close.slice(third, third * 2));
315
+ const rightValley = Math.min(...this.ohlcv.close.slice(third * 2));
318
316
 
319
317
  const dropFromHead = (head - middleValley) / head;
320
318
  const riseFromValleys = (Math.max(leftValley, rightValley) - Math.min(leftValley, rightValley)) / Math.min(leftValley, rightValley);
@@ -325,20 +323,20 @@ export default class ChartPatterns {
325
323
  // Implementation of Inverse Head and Shoulders
326
324
  // https://www.tradingview.com/support/solutions/43000690666-chart-pattern-inverse-head-and-shoulders/
327
325
  isInverseHeadAndShoulders() {
328
- const length = this.close.length;
326
+ const length = this.ohlcv.close.length;
329
327
  const third = Math.floor(length / 3);
330
328
 
331
- const leftShoulder = Math.min(...this.close.slice(0, third));
332
- const head = Math.min(...this.close.slice(third, third * 2));
333
- const rightShoulder = Math.min(...this.close.slice(third * 2));
329
+ const leftShoulder = Math.min(...this.ohlcv.close.slice(0, third));
330
+ const head = Math.min(...this.ohlcv.close.slice(third, third * 2));
331
+ const rightShoulder = Math.min(...this.ohlcv.close.slice(third * 2));
334
332
 
335
333
  if (leftShoulder <= 0 || head <= 0 || rightShoulder <= 0) {
336
334
  return false;
337
335
  }
338
336
 
339
- const leftPeak = Math.max(...this.close.slice(0, third));
340
- const middlePeak = Math.max(...this.close.slice(third, third * 2));
341
- const rightPeak = Math.max(...this.close.slice(third * 2));
337
+ const leftPeak = Math.max(...this.ohlcv.close.slice(0, third));
338
+ const middlePeak = Math.max(...this.ohlcv.close.slice(third, third * 2));
339
+ const rightPeak = Math.max(...this.ohlcv.close.slice(third * 2));
342
340
 
343
341
  const riseFromHead = (middlePeak - head) / head;
344
342
  const dropFromPeaks = (Math.min(leftPeak, rightPeak) - Math.max(leftPeak, rightPeak)) / Math.max(leftPeak, rightPeak);
@@ -349,16 +347,16 @@ export default class ChartPatterns {
349
347
  // Implementation of Rising Wedge
350
348
  // https://www.tradingview.com/support/solutions/43000653219-chart-pattern-rising-wedge/
351
349
  isRisingWedge() {
352
- const length = this.close.length;
350
+ const length = this.ohlcv.close.length;
353
351
  const third = Math.floor(length / 3);
354
352
 
355
- const firstPeak = Math.max(...this.close.slice(0, third));
356
- const secondPeak = Math.max(...this.close.slice(third, third * 2));
357
- const thirdPeak = Math.max(...this.close.slice(third * 2));
353
+ const firstPeak = Math.max(...this.ohlcv.close.slice(0, third));
354
+ const secondPeak = Math.max(...this.ohlcv.close.slice(third, third * 2));
355
+ const thirdPeak = Math.max(...this.ohlcv.close.slice(third * 2));
358
356
 
359
- const firstValley = Math.min(...this.close.slice(0, third));
360
- const secondValley = Math.min(...this.close.slice(third, third * 2));
361
- const thirdValley = Math.min(...this.close.slice(third * 2));
357
+ const firstValley = Math.min(...this.ohlcv.close.slice(0, third));
358
+ const secondValley = Math.min(...this.ohlcv.close.slice(third, third * 2));
359
+ const thirdValley = Math.min(...this.ohlcv.close.slice(third * 2));
362
360
 
363
361
  const risingPeaks = firstPeak < secondPeak && secondPeak < thirdPeak;
364
362
  const risingValleys = firstValley < secondValley && secondValley < thirdValley;
@@ -369,16 +367,16 @@ export default class ChartPatterns {
369
367
  // Implementation of Falling Wedge
370
368
  // https://www.tradingview.com/support/solutions/43000697938-chart-pattern-falling-wedge/
371
369
  isFallingWedge() {
372
- const length = this.close.length;
370
+ const length = this.ohlcv.close.length;
373
371
  const third = Math.floor(length / 3);
374
372
 
375
- const firstPeak = Math.max(...this.close.slice(0, third));
376
- const secondPeak = Math.max(...this.close.slice(third, third * 2));
377
- const thirdPeak = Math.max(...this.close.slice(third * 2));
373
+ const firstPeak = Math.max(...this.ohlcv.close.slice(0, third));
374
+ const secondPeak = Math.max(...this.ohlcv.close.slice(third, third * 2));
375
+ const thirdPeak = Math.max(...this.ohlcv.close.slice(third * 2));
378
376
 
379
- const firstValley = Math.min(...this.close.slice(0, third));
380
- const secondValley = Math.min(...this.close.slice(third, third * 2));
381
- const thirdValley = Math.min(...this.close.slice(third * 2));
377
+ const firstValley = Math.min(...this.ohlcv.close.slice(0, third));
378
+ const secondValley = Math.min(...this.ohlcv.close.slice(third, third * 2));
379
+ const thirdValley = Math.min(...this.ohlcv.close.slice(third * 2));
382
380
 
383
381
  const fallingPeaks = firstPeak > secondPeak && secondPeak > thirdPeak;
384
382
  const fallingValleys = firstValley > secondValley && secondValley > thirdValley;
@@ -389,14 +387,14 @@ export default class ChartPatterns {
389
387
  // Implementation of Bullish Triangle
390
388
  // https://www.tradingview.com/support/solutions/43000653217/
391
389
  isBullishTriangle() {
392
- const length = this.close.length;
390
+ const length = this.ohlcv.close.length;
393
391
  const half = Math.floor(length / 2);
394
392
 
395
- const firstHalfHigh = Math.max(...this.high.slice(0, half));
396
- const secondHalfHigh = Math.max(...this.high.slice(half));
393
+ const firstHalfHigh = Math.max(...this.ohlcv.high.slice(0, half));
394
+ const secondHalfHigh = Math.max(...this.ohlcv.high.slice(half));
397
395
 
398
- const firstHalfLow = Math.min(...this.low.slice(0, half));
399
- const secondHalfLow = Math.min(...this.low.slice(half));
396
+ const firstHalfLow = Math.min(...this.ohlcv.low.slice(0, half));
397
+ const secondHalfLow = Math.min(...this.ohlcv.low.slice(half));
400
398
 
401
399
  const contractingHighs = firstHalfHigh > secondHalfHigh;
402
400
  const risingLows = firstHalfLow < secondHalfLow;
@@ -407,14 +405,14 @@ export default class ChartPatterns {
407
405
  // Implementation of Bearish Triangle
408
406
  // https://www.tradingview.com/support/solutions/43000653217/
409
407
  isBearishTriangle() {
410
- const length = this.close.length;
408
+ const length = this.ohlcv.close.length;
411
409
  const half = Math.floor(length / 2);
412
410
 
413
- const firstHalfHigh = Math.max(...this.high.slice(0, half));
414
- const secondHalfHigh = Math.max(...this.high.slice(half));
411
+ const firstHalfHigh = Math.max(...this.ohlcv.high.slice(0, half));
412
+ const secondHalfHigh = Math.max(...this.ohlcv.high.slice(half));
415
413
 
416
- const firstHalfLow = Math.min(...this.low.slice(0, half));
417
- const secondHalfLow = Math.min(...this.low.slice(half));
414
+ const firstHalfLow = Math.min(...this.ohlcv.low.slice(0, half));
415
+ const secondHalfLow = Math.min(...this.ohlcv.low.slice(half));
418
416
 
419
417
  const contractingLows = firstHalfLow < secondHalfLow;
420
418
  const fallingHighs = firstHalfHigh > secondHalfHigh;
@@ -425,16 +423,16 @@ export default class ChartPatterns {
425
423
  // Implementation of Bullish Rectangle
426
424
  // https://www.tradingview.com/support/solutions/43000653216/
427
425
  isBullishRectangle() {
428
- const length = this.close.length;
426
+ const length = this.ohlcv.close.length;
429
427
  const third = Math.floor(length / 3);
430
428
 
431
- const firstSectionHigh = Math.max(...this.high.slice(0, third));
432
- const secondSectionHigh = Math.max(...this.high.slice(third, third * 2));
433
- const thirdSectionHigh = Math.max(...this.high.slice(third * 2));
429
+ const firstSectionHigh = Math.max(...this.ohlcv.high.slice(0, third));
430
+ const secondSectionHigh = Math.max(...this.ohlcv.high.slice(third, third * 2));
431
+ const thirdSectionHigh = Math.max(...this.ohlcv.high.slice(third * 2));
434
432
 
435
- const firstSectionLow = Math.min(...this.low.slice(0, third));
436
- const secondSectionLow = Math.min(...this.low.slice(third, third * 2));
437
- const thirdSectionLow = Math.min(...this.low.slice(third * 2));
433
+ const firstSectionLow = Math.min(...this.ohlcv.low.slice(0, third));
434
+ const secondSectionLow = Math.min(...this.ohlcv.low.slice(third, third * 2));
435
+ const thirdSectionLow = Math.min(...this.ohlcv.low.slice(third * 2));
438
436
 
439
437
  const stableHighs = Math.abs(firstSectionHigh - secondSectionHigh) / firstSectionHigh < 0.03 &&
440
438
  Math.abs(secondSectionHigh - thirdSectionHigh) / secondSectionHigh < 0.03;
@@ -447,16 +445,16 @@ export default class ChartPatterns {
447
445
  // Implementation of Bearish Rectangle
448
446
  // https://www.tradingview.com/support/solutions/43000653216/
449
447
  isBearishRectangle() {
450
- const length = this.close.length;
448
+ const length = this.ohlcv.close.length;
451
449
  const third = Math.floor(length / 3);
452
450
 
453
- const firstSectionHigh = Math.max(...this.high.slice(0, third));
454
- const secondSectionHigh = Math.max(...this.high.slice(third, third * 2));
455
- const thirdSectionHigh = Math.max(...this.high.slice(third * 2));
451
+ const firstSectionHigh = Math.max(...this.ohlcv.high.slice(0, third));
452
+ const secondSectionHigh = Math.max(...this.ohlcv.high.slice(third, third * 2));
453
+ const thirdSectionHigh = Math.max(...this.ohlcv.high.slice(third * 2));
456
454
 
457
- const firstSectionLow = Math.min(...this.low.slice(0, third));
458
- const secondSectionLow = Math.min(...this.low.slice(third, third * 2));
459
- const thirdSectionLow = Math.min(...this.low.slice(third * 2));
455
+ const firstSectionLow = Math.min(...this.ohlcv.low.slice(0, third));
456
+ const secondSectionLow = Math.min(...this.ohlcv.low.slice(third, third * 2));
457
+ const thirdSectionLow = Math.min(...this.ohlcv.low.slice(third * 2));
460
458
 
461
459
  const stableHighs = Math.abs(firstSectionHigh - secondSectionHigh) / firstSectionHigh < 0.03 &&
462
460
  Math.abs(secondSectionHigh - thirdSectionHigh) / secondSectionHigh < 0.03;
package/src/utilities.js CHANGED
@@ -1,50 +1,64 @@
1
+ import {Big} from 'trading-signals';
2
+
3
+
1
4
  // Function to find crosses between two arrays: fast and slow
2
5
  export const findCrosses = (fast, slow) => {
3
6
  // Map states based on comparison of fast and slow arrays
4
- const states = fast.map((f, i) => {
5
- if (f > slow[i]) {
6
- return 'up';
7
- } else if (f < slow[i]) {
8
- return 'down';
9
- } else {
10
- return 'neutral';
11
- }
12
- }).reverse(); // Reverse for processing from the end
13
7
 
14
- // Group consecutive values
15
- const groups = groupConsecutiveValues(states);
8
+ fast = fast.filter(o => o instanceof Big)
9
+ slow = slow.filter(o => o instanceof Big)
10
+ const min = Math.min(fast.length, slow.length)
16
11
 
17
- // Map groups to cross values
18
- const crosses = groups.map(chunk => {
19
- const chunkLength = chunk.length;
20
- return chunk.map((state, index) => {
21
- let value = chunkLength - index;
12
+ fast = fast.slice(-min);
13
+ slow = slow.slice(-min);
22
14
 
23
- if (state === 'down') {
24
- return -value;
25
- } else if (state === 'up') {
26
- return value;
27
- } else {
28
- return 0;
15
+ let state = fast.map((f, i) => {
16
+ if(f.eq(slow[i])) return 'neutral'
17
+ else if(f.gt(slow[i])) return 'up'
18
+ else if(f.lt(slow[i])) return 'down'
19
+ else throw Error('undefined error in findCrosses')
20
+ })
21
+
22
+ const groups = groupConsecutiveValues(state)
23
+ const groupLengths = groups.map(g => g.length)
24
+
25
+ return groups.map((group, gIndex) => {
26
+ let initialValue = groupLengths[gIndex]
27
+
28
+ return group.map((s, i) => {
29
+ let v = initialValue - i
30
+
31
+ if(s === 'neutral')
32
+ {
33
+ v = 0
34
+ }
35
+ if(s === 'up')
36
+ {
37
+ v = v * 1
29
38
  }
30
- });
31
- }).flat();
39
+ if(s === 'down')
40
+ {
41
+ v = v * -1
42
+ }
43
+
44
+ return v
45
+ }).reverse()
46
+ }).flat()
32
47
 
33
- return crosses.reverse(); // Reverse back to original order
34
- };
48
+ }
35
49
 
36
50
  // Helper function to group consecutive values
37
- function groupConsecutiveValues(arr) {
38
- if (arr.length === 0) return [];
51
+ const groupConsecutiveValues = arr => {
52
+ if (arr.length === 0) return []
39
53
 
40
54
  return arr.reduce((acc, currentValue, index, array) => {
41
55
  if (index === 0) {
42
56
  // Start the first group with the first element
43
- acc.push([currentValue]);
57
+ acc.push([currentValue])
44
58
  } else {
45
59
  // Get the previous value
46
- const prevValue = array[index - 1];
47
- const currentGroup = acc[acc.length - 1];
60
+ const prevValue = array[index - 1]
61
+ const currentGroup = acc[acc.length - 1]
48
62
 
49
63
  // Check the direction of the previous and current values
50
64
  if (currentValue !== prevValue) {
@@ -55,6 +69,6 @@ function groupConsecutiveValues(arr) {
55
69
  currentGroup.push(currentValue);
56
70
  }
57
71
  }
58
- return acc;
59
- }, []);
72
+ return acc
73
+ }, [])
60
74
  }