/* * * * License: www.highcharts.com/license * * */ 'use strict'; import H from '../parts/Globals.js'; import '../parts/Utilities.js'; import reduceArrayMixin from '../mixins/reduce-array.js'; import multipleLinesMixin from '../mixins/multipe-lines.js'; var merge = H.merge, isArray = H.isArray, SMA = H.seriesTypes.sma, getArrayExtremes = reduceArrayMixin.getArrayExtremes; /** * The Stochastic series type. * * @private * @class * @name Highcharts.seriesTypes.stochastic * * @augments Highcharts.Series */ H.seriesType( 'stochastic', 'sma', /** * Stochastic oscillator. This series requires the `linkedTo` option to be * set and should be loaded after the `stock/indicators/indicators.js` file. * * @sample stock/indicators/stochastic * Stochastic oscillator * * @extends plotOptions.sma * @since 6.0.0 * @product highstock * @excluding allAreas, colorAxis, joinBy, keys, navigatorOptions, * pointInterval, pointIntervalUnit, pointPlacement, * pointRange, pointStart, showInNavigator, stacking * @optionparent plotOptions.stochastic */ { /** * @excluding index, period */ params: { /** * Periods for Stochastic oscillator: [%K, %D]. * * @type {Array} * @default [14, 3] */ periods: [14, 3] }, marker: { enabled: false }, tooltip: { pointFormat: '\u25CF {series.name}
%K: {point.y}
%D: {point.smoothed}
' }, /** * Smoothed line options. */ smoothedLine: { /** * Styles for a smoothed line. */ styles: { /** * Pixel width of the line. */ lineWidth: 1, /** * Color of the line. If not set, it's inherited from * [plotOptions.stochastic.color * ](#plotOptions.stochastic.color). * * @type {Highcharts.ColorString} */ lineColor: undefined } }, dataGrouping: { approximation: 'averages' } }, /** * @lends Highcharts.Series# */ H.merge(multipleLinesMixin, { nameComponents: ['periods'], nameBase: 'Stochastic', pointArrayMap: ['y', 'smoothed'], parallelArrays: ['x', 'y', 'smoothed'], pointValKey: 'y', linesApiNames: ['smoothedLine'], init: function () { SMA.prototype.init.apply(this, arguments); // Set default color for lines: this.options = merge({ smoothedLine: { styles: { lineColor: this.color } } }, this.options); }, getValues: function (series, params) { var periodK = params.periods[0], periodD = params.periods[1], xVal = series.xData, yVal = series.yData, yValLen = yVal ? yVal.length : 0, SO = [], // 0- date, 1-%K, 2-%D xData = [], yData = [], slicedY, close = 3, low = 2, high = 1, CL, HL, LL, K, D = null, points, extremes, i; // Stochastic requires close value if ( yValLen < periodK || !isArray(yVal[0]) || yVal[0].length !== 4 ) { return false; } // For a N-period, we start from N-1 point, to calculate Nth point // That is why we later need to comprehend slice() elements list // with (+1) for (i = periodK - 1; i < yValLen; i++) { slicedY = yVal.slice(i - periodK + 1, i + 1); // Calculate %K extremes = getArrayExtremes(slicedY, low, high); LL = extremes[0]; // Lowest low in %K periods CL = yVal[i][close] - LL; HL = extremes[1] - LL; K = CL / HL * 100; xData.push(xVal[i]); yData.push([K, null]); // Calculate smoothed %D, which is SMA of %K if (i >= (periodK - 1) + (periodD - 1)) { points = SMA.prototype.getValues.call(this, { xData: xData.slice(-periodD), yData: yData.slice(-periodD) }, { period: periodD }); D = points.yData[0]; } SO.push([xVal[i], K, D]); yData[yData.length - 1][1] = D; } return { values: SO, xData: xData, yData: yData }; } }) ); /** * A Stochastic indicator. If the [type](#series.stochastic.type) option is not * specified, it is inherited from [chart.type](#chart.type). * * @extends series,plotOptions.stochastic * @since 6.0.0 * @product highstock * @excluding allAreas, colorAxis, dataParser, dataURL, joinBy, keys, * navigatorOptions, pointInterval, pointIntervalUnit, * pointPlacement, pointRange, pointStart, showInNavigator, stacking * @apioption series.stochastic */