highcharts
Version:
JavaScript charting framework
14 lines • 5.57 kB
JavaScript
/**
* Highcharts Stock JS v13.0.1 (2026-08-17)
* @module highcharts/indicators/klinger
* @requires highcharts
* @requires highcharts/modules/stock
*
* Indicator series type for Highcharts Stock
*
* (c) 2010-2026 Highsoft AS
* Author: Karol Kołodziej
*
* A commercial license may be required depending on use,
* see www.highcharts.com/license
*/import*as e from"../highcharts.js";let t={};t.n=e=>{let r=e&&e.__esModule?()=>e.default:()=>e;return t.d(r,{a:r}),r},t.d=(e,r)=>{if(Array.isArray(r))for(var a=0;a<r.length;){var i=r[a++],o=r[a++];t.o(e,i)?0===o&&a++:0===o?Object.defineProperty(e,i,{enumerable:!0,value:r[a++]}):Object.defineProperty(e,i,{enumerable:!0,get:o})}else for(var i in r)t.o(r,i)&&!t.o(e,i)&&Object.defineProperty(e,i,{enumerable:!0,get:r[i]})},t.o=(e,t)=>Object.prototype.hasOwnProperty.call(e,t);let r=e.default;var a,i=t.n(r);let o=e.default.SeriesRegistry;var s=t.n(o);let{sma:{prototype:l}}=s().seriesTypes;!function(e){let t=["bottomLine"],a=["top","bottom"],i=["top"];function o(e){return"plot"+e.charAt(0).toUpperCase()+e.slice(1)}function s(e,t){let r=[];return(e.pointArrayMap||[]).forEach(e=>{e!==t&&r.push(o(e))}),r}function n(){let e=this,t=e.pointValKey,a=e.linesApiNames,i=e.areaLinesNames,n=e.points,p=e.options,h=e.graph,g={options:{gapSize:p.gapSize}},u=[],c=s(e,t),d=n.length,f;if(c.forEach((e,t)=>{for(u[t]=[];d--;)f=n[d],u[t].push({x:f.x,plotX:f.plotX,plotY:f[e],isNull:!(0,r.defined)(f[e])});d=n.length}),e.userOptions.fillColor&&i.length){let t=u[c.indexOf(o(i[0]))],a=1===i.length?n:u[c.indexOf(o(i[1]))],s=e.color;e.points=a,e.nextPoints=t,e.color=e.userOptions.fillColor,e.options=(0,r.merge)(n,g),e.graph=e.area,e.fillGraph=!0,l.drawGraph.call(e),e.area=e.graph,delete e.nextPoints,delete e.fillGraph,e.color=s}a.forEach((t,a)=>{u[a]?(e.points=u[a],p[t]?e.options=(0,r.merge)(p[t].styles,g):(0,r.error)('Error: "There is no '+t+' in DOCS options declared. Check if linesApiNames are consistent with your DOCS line names."'),e.graph=e["graph"+t],l.drawGraph.call(e),e["graph"+t]=e.graph):(0,r.error)('Error: "'+t+" doesn't have equivalent in pointArrayMap. To many elements in linesApiNames relative to pointArrayMap.\"")}),e.points=n,e.options=p,e.graph=h,l.drawGraph.call(e)}function p(e){let t,r=[],a=[];if(e=e||this.points,this.fillGraph&&this.nextPoints){if((t=l.getGraphPath.call(this,this.nextPoints))&&t.length){t[0][0]="L",r=l.getGraphPath.call(this,e),a=t.slice(0,r.length);for(let e=a.length-1;e>=0;e--)r.push(a[e])}}else r=l.getGraphPath.apply(this,arguments);return r}function h(e){let t=[];return(this.pointArrayMap||[]).forEach(r=>{t.push(e[r])}),t}function g(){let e=this.pointArrayMap,t=[],r;t=s(this),l.translate.apply(this,arguments),this.points.forEach(a=>{e.forEach((e,i)=>{r=a[e],this.dataModify&&(r=this.dataModify.modifyValue(r)),null!==r&&(a[t[i]]=this.yAxis.toPixels(r,!0))})})}e.compose=function(e){let r=e.prototype;return r.linesApiNames=r.linesApiNames||t.slice(),r.pointArrayMap=r.pointArrayMap||a.slice(),r.pointValKey=r.pointValKey||"top",r.areaLinesNames=r.areaLinesNames||i.slice(),r.drawGraph=n,r.getGraphPath=p,r.toYData=h,r.translate=g,e}}(a||(a={}));let n=a,{ema:p,sma:h}=s().seriesTypes;class g extends h{calculateTrend(e,t){return e[t][1]+e[t][2]+e[t][3]>e[t-1][1]+e[t-1][2]+e[t-1][3]?1:-1}isValidData(e){let t=this.chart,a=this.options,i=this.linkedParent,o=(0,r.isArray)(e)&&4===e.length,s=this.volumeSeries||(this.volumeSeries=t.get(a.params.volumeSeriesID));return s||(0,r.error)("Series "+a.params.volumeSeriesID+" not found! Check `volumeSeriesID`.",!0,i.chart),!!([i,s].every(function(e){return e&&e.dataTable.rowCount>=a.params.slowAvgPeriod})&&o)}getCM(e,t,a,i,o){return(0,r.correctFloat)(t+(a===i?e:o))}getDM(e,t){return(0,r.correctFloat)(e-t)}getVolumeForce(e){let t=[],r=0,a,i=1,o=0,s=e[0][1]-e[0][2],l=0,n;for(;i<e.length;i++)n=this.calculateTrend(e,i),a=this.getDM(e[i][1],e[i][2]),r=this.getCM(o,a,n,l,s),t.push([this.volumeSeries.getColumn("y")[i]*n*Math.abs(2*(a/r-1))*100]),l=n,o=r,s=a;return t}getEMA(e,t,r,a,i,o,s){return p.prototype.calculateEma(s||[],e,void 0===o?1:o,a,t,void 0===i?-1:i,r)}getSMA(e,t,r){return p.prototype.accumulatePeriodPoints(e,t,r)/e}getValues(e,t){let a=[],i=e.xData,o=e.yData,s=[],l=[],n=[],p,h=0,g=0,u,c,d,f=null;if(!this.isValidData(o[0]))return;let m=this.getVolumeForce(o),y=this.getSMA(t.fastAvgPeriod,0,m),A=this.getSMA(t.slowAvgPeriod,0,m),v=2/(t.fastAvgPeriod+1),P=2/(t.slowAvgPeriod+1);for(;h<o.length;h++)h>=t.fastAvgPeriod&&(c=g=this.getEMA(m,c,y,v,0,h,i)[1]),h>=t.slowAvgPeriod&&(d=u=this.getEMA(m,d,A,P,0,h,i)[1],n.push(p=(0,r.correctFloat)(g-u)),n.length>=t.signalPeriod&&(f=n.slice(-t.signalPeriod).reduce((e,t)=>e+t)/t.signalPeriod),a.push([i[h],p,f]),s.push(i[h]),l.push([p,f]));return{values:a,xData:s,yData:l}}}g.defaultOptions=(0,r.merge)(h.defaultOptions,{params:{fastAvgPeriod:34,slowAvgPeriod:55,signalPeriod:13,volumeSeriesID:"volume"},signalLine:{styles:{lineWidth:1,lineColor:"#ff0000"}},dataGrouping:{approximation:"averages"},tooltip:{pointFormat:'<span style="color: {point.color}">●</span><b> {series.name}</b><br/><span style="color: {point.color}">Klinger</span>: {point.y}<br/><span style="color: {point.series.options.signalLine.styles.lineColor}">Signal</span>: {point.signal}<br/>'}}),(0,r.extend)(g.prototype,{areaLinesNames:[],linesApiNames:["signalLine"],nameBase:"Klinger",nameComponents:["fastAvgPeriod","slowAvgPeriod"],pointArrayMap:["y","signal"],parallelArrays:["x","y","signal"],pointValKey:"y"}),n.compose(g),s().registerSeriesType("klinger",g);let u=i();export{u as default};