highcharts
Version:
JavaScript charting framework
14 lines • 6.2 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
*/function(e,t){"object"==typeof exports&&"object"==typeof module?module.exports=t(e._Highcharts,e._Highcharts.SeriesRegistry):"function"==typeof define&&define.amd?define("highcharts/indicators/klinger",["highcharts/highcharts"],function(e){return t(e,e.SeriesRegistry)}):"object"==typeof exports?exports["highcharts/indicators/klinger"]=t(e._Highcharts,e._Highcharts.SeriesRegistry):e.Highcharts=t(e.Highcharts,e.Highcharts.SeriesRegistry)}("u"<typeof window?this:window,(e,t)=>(()=>{"use strict";var r,i={512(e){e.exports=t},944(t){t.exports=e}};let o={};function a(e){let t=o[e];if(void 0!==t)return t.exports;let r=o[e]={exports:{}};return i[e](r,r.exports,a),r.exports}a.n=e=>{let t=e&&e.__esModule?()=>e.default:()=>e;return a.d(t,{a:t}),t},a.d=(e,t)=>{if(Array.isArray(t))for(var r=0;r<t.length;){var i=t[r++],o=t[r++];a.o(e,i)?0===o&&r++:0===o?Object.defineProperty(e,i,{enumerable:!0,value:t[r++]}):Object.defineProperty(e,i,{enumerable:!0,get:o})}else for(var i in t)a.o(t,i)&&!a.o(e,i)&&Object.defineProperty(e,i,{enumerable:!0,get:t[i]})},a.o=(e,t)=>Object.prototype.hasOwnProperty.call(e,t);let s={};a.d(s,{default:()=>y});var n=a(944),l=a.n(n),p=a(512),h=a.n(p);let{sma:{prototype:g}}=h().seriesTypes;!function(e){let t=["bottomLine"],r=["top","bottom"],i=["top"];function o(e){return"plot"+e.charAt(0).toUpperCase()+e.slice(1)}function a(e,t){let r=[];return(e.pointArrayMap||[]).forEach(e=>{e!==t&&r.push(o(e))}),r}function s(){let e=this,t=e.pointValKey,r=e.linesApiNames,i=e.areaLinesNames,s=e.points,l=e.options,p=e.graph,h={options:{gapSize:l.gapSize}},c=[],u=a(e,t),d=s.length,f;if(u.forEach((e,t)=>{for(c[t]=[];d--;)f=s[d],c[t].push({x:f.x,plotX:f.plotX,plotY:f[e],isNull:!(0,n.defined)(f[e])});d=s.length}),e.userOptions.fillColor&&i.length){let t=c[u.indexOf(o(i[0]))],r=1===i.length?s:c[u.indexOf(o(i[1]))],a=e.color;e.points=r,e.nextPoints=t,e.color=e.userOptions.fillColor,e.options=(0,n.merge)(s,h),e.graph=e.area,e.fillGraph=!0,g.drawGraph.call(e),e.area=e.graph,delete e.nextPoints,delete e.fillGraph,e.color=a}r.forEach((t,r)=>{c[r]?(e.points=c[r],l[t]?e.options=(0,n.merge)(l[t].styles,h):(0,n.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],g.drawGraph.call(e),e["graph"+t]=e.graph):(0,n.error)('Error: "'+t+" doesn't have equivalent in pointArrayMap. To many elements in linesApiNames relative to pointArrayMap.\"")}),e.points=s,e.options=l,e.graph=p,g.drawGraph.call(e)}function l(e){let t,r=[],i=[];if(e=e||this.points,this.fillGraph&&this.nextPoints){if((t=g.getGraphPath.call(this,this.nextPoints))&&t.length){t[0][0]="L",r=g.getGraphPath.call(this,e),i=t.slice(0,r.length);for(let e=i.length-1;e>=0;e--)r.push(i[e])}}else r=g.getGraphPath.apply(this,arguments);return r}function p(e){let t=[];return(this.pointArrayMap||[]).forEach(r=>{t.push(e[r])}),t}function h(){let e=this.pointArrayMap,t=[],r;t=a(this),g.translate.apply(this,arguments),this.points.forEach(i=>{e.forEach((e,o)=>{r=i[e],this.dataModify&&(r=this.dataModify.modifyValue(r)),null!==r&&(i[t[o]]=this.yAxis.toPixels(r,!0))})})}e.compose=function(e){let o=e.prototype;return o.linesApiNames=o.linesApiNames||t.slice(),o.pointArrayMap=o.pointArrayMap||r.slice(),o.pointValKey=o.pointValKey||"top",o.areaLinesNames=o.areaLinesNames||i.slice(),o.drawGraph=s,o.getGraphPath=l,o.toYData=p,o.translate=h,e}}(r||(r={}));let c=r,{ema:u,sma:d}=h().seriesTypes;class f extends d{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,r=this.options,i=this.linkedParent,o=(0,n.isArray)(e)&&4===e.length,a=this.volumeSeries||(this.volumeSeries=t.get(r.params.volumeSeriesID));return a||(0,n.error)("Series "+r.params.volumeSeriesID+" not found! Check `volumeSeriesID`.",!0,i.chart),!!([i,a].every(function(e){return e&&e.dataTable.rowCount>=r.params.slowAvgPeriod})&&o)}getCM(e,t,r,i,o){return(0,n.correctFloat)(t+(r===i?e:o))}getDM(e,t){return(0,n.correctFloat)(e-t)}getVolumeForce(e){let t=[],r=0,i,o=1,a=0,s=e[0][1]-e[0][2],n=0,l;for(;o<e.length;o++)l=this.calculateTrend(e,o),i=this.getDM(e[o][1],e[o][2]),r=this.getCM(a,i,l,n,s),t.push([this.volumeSeries.getColumn("y")[o]*l*Math.abs(2*(i/r-1))*100]),n=l,a=r,s=i;return t}getEMA(e,t,r,i,o,a,s){return u.prototype.calculateEma(s||[],e,void 0===a?1:a,i,t,void 0===o?-1:o,r)}getSMA(e,t,r){return u.prototype.accumulatePeriodPoints(e,t,r)/e}getValues(e,t){let r=[],i=e.xData,o=e.yData,a=[],s=[],l=[],p,h=0,g=0,c,u,d,f=null;if(!this.isValidData(o[0]))return;let y=this.getVolumeForce(o),m=this.getSMA(t.fastAvgPeriod,0,y),A=this.getSMA(t.slowAvgPeriod,0,y),v=2/(t.fastAvgPeriod+1),P=2/(t.slowAvgPeriod+1);for(;h<o.length;h++)h>=t.fastAvgPeriod&&(u=g=this.getEMA(y,u,m,v,0,h,i)[1]),h>=t.slowAvgPeriod&&(d=c=this.getEMA(y,d,A,P,0,h,i)[1],l.push(p=(0,n.correctFloat)(g-c)),l.length>=t.signalPeriod&&(f=l.slice(-t.signalPeriod).reduce((e,t)=>e+t)/t.signalPeriod),r.push([i[h],p,f]),a.push(i[h]),s.push([p,f]));return{values:r,xData:a,yData:s}}}f.defaultOptions=(0,n.merge)(d.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,n.extend)(f.prototype,{areaLinesNames:[],linesApiNames:["signalLine"],nameBase:"Klinger",nameComponents:["fastAvgPeriod","slowAvgPeriod"],pointArrayMap:["y","signal"],parallelArrays:["x","y","signal"],pointValKey:"y"}),c.compose(f),h().registerSeriesType("klinger",f);let y=l();return s.default})());