text: /**
   * @license Highstock JS v7.2.2 (2020-08-24)
   *
   * All technical indicators for Highstock
   *
   * (c) 2010-2019 Pawel Fus
   *
   * License: www.highcharts.com/license
   */
  'use strict';
  (function (factory) {
      if (typeof module === 'object' && module.exports) {
          factory['default'] = factory;
          module.exports = factory;
      } else if (typeof define === 'function' && define.amd) {
          define('highcharts/indicators/indicators-all', ['highcharts', 'highcharts/modules/stock'], function (Highcharts) {
              factory(Highcharts);
              factory.Highcharts = Highcharts;
              return factory;
          });
      } else {
          factory(typeof Highcharts !== 'undefined' ? Highcharts : undefined);
      }
  }(function (Highcharts) {
      var _modules = Highcharts ? Highcharts._modules : {};
      function _registerModule(obj, path, args, fn) {
          if (!obj.hasOwnProperty(path)) {
              obj[path] = fn.apply(null, args);
          }
      }
      _registerModule(_modules, 'mixins/indicator-required.js', [_modules['parts/Globals.js']], function (H) {
          /**
           *
           *  (c) 2010-2019 Daniel Studencki
           *
           *  License: www.highcharts.com/license
           *
           *  !!!!!!! SOURCE GETS TRANSPILED BY TYPESCRIPT. EDIT TS FILE ONLY. !!!!!!!
           *
           * */
          var error = H.error;
          /* eslint-disable no-invalid-this, valid-jsdoc */
          var requiredIndicatorMixin = {
              /**
               * Check whether given indicator is loaded, else throw error.
               * @private
               * @param {Highcharts.Indicator} indicator
               *        Indicator constructor function.
               * @param {string} requiredIndicator
               *        Required indicator type.
               * @param {string} type
               *        Type of indicator where function was called (parent).
               * @param {Highcharts.IndicatorCallbackFunction} callback
               *        Callback which is triggered if the given indicator is loaded.
               *        Takes indicator as an argument.
               * @param {string} errMessage
               *        Error message that will be logged in console.
               * @return {boolean}
               *         Returns false when there is no required indicator loaded.
               */
              isParentLoaded: function (indicator, requiredIndicator, type, callback, errMessage) {
                  if (indicator) {
                      return callback ? callback(indicator) : true;
                  }
                  error(errMessage || this.generateMessage(type, requiredIndicator));
                  return false;
              },
              /**
               * @private
               * @param {string} indicatorType
               *        Indicator type
               * @param {string} required
               *        Required indicator
               * @return {string}
               *         Error message
               */
              generateMessage: function (indicatorType, required) {
                  return 'Error: "' + indicatorType +
                      '" indicator type requires "' + required +
                      '" indicator loaded before. Please read docs: ' +
                      'https://api.highcharts.com/highstock/plotOptions.' +
                      indicatorType;
              }
          };
  
          return requiredIndicatorMixin;
      });
      _registerModule(_modules, 'indicators/indicators.src.js', [_modules['parts/Globals.js'], _modules['parts/Utilities.js'], _modules['mixins/indicator-required.js']], function (H, U, requiredIndicatorMixin) {
          /* *
           *
           *  License: www.highcharts.com/license
           *
           *  !!!!!!! SOURCE GETS TRANSPILED BY TYPESCRIPT. EDIT TS FILE ONLY. !!!!!!!
           *
           * */
          var extend = U.extend, isArray = U.isArray, pick = U.pick, splat = U.splat;
          var error = H.error, Series = H.Series, addEvent = H.addEvent, seriesType = H.seriesType, seriesTypes = H.seriesTypes, ohlcProto = H.seriesTypes.ohlc.prototype, generateMessage = requiredIndicatorMixin.generateMessage;
          /**
           * The parameter allows setting line series type and use OHLC indicators. Data
           * in OHLC format is required.
           *
           * @sample {highstock} stock/indicators/use-ohlc-data
           *         Plot line on Y axis
           *
           * @type      {boolean}
           * @product   highstock
           * @apioption plotOptions.line.useOhlcData
           */
          /* eslint-disable no-invalid-this */
          addEvent(H.Series, 'init', function (eventOptions) {
              var series = this, options = eventOptions.options;
              if (options.useOhlcData &&
                  options.id !== 'highcharts-navigator-series') {
                  extend(series, {
                      pointValKey: ohlcProto.pointValKey,
                      keys: ohlcProto.keys,
                      pointArrayMap: ohlcProto.pointArrayMap,
                      toYData: ohlcProto.toYData
                  });
              }
          });
          addEvent(Series, 'afterSetOptions', function (e) {
              var options = e.options, dataGrouping = options.dataGrouping;
              if (dataGrouping &&
                  options.useOhlcData &&
                  options.id !== 'highcharts-navigator-series') {
                  dataGrouping.approximation = 'ohlc';
              }
          });
          /* eslint-enable no-invalid-this */
          /**
           * The SMA series type.
           *
           * @private
           * @class
           * @name Highcharts.seriesTypes.sma
           *
           * @augments Highcharts.Series
           */
          seriesType('sma', 'line', 
          /**
           * Simple moving average indicator (SMA). This series requires `linkedTo`
           * option to be set.
           *
           * @sample stock/indicators/sma
           *         Simple moving average indicator
           *
           * @extends      plotOptions.line
           * @since        6.0.0
           * @excluding    allAreas, colorAxis, dragDrop, joinBy, keys,
           *               navigatorOptions, pointInterval, pointIntervalUnit,
           *               pointPlacement, pointRange, pointStart, showInNavigator,
           *               stacking, useOhlcData
           * @product      highstock
           * @requires     stock/indicators/indicators
           * @optionparent plotOptions.sma
           */
          {
              /**
               * The name of the series as shown in the legend, tooltip etc. If not
               * set, it will be based on a technical indicator type and default
               * params.
               *
               * @type {string}
               */
              name: undefined,
              tooltip: {
                  /**
                   * Number of decimals in indicator series.
                   */
                  valueDecimals: 4
              },
              /**
               * The main series ID that indicator will be based on. Required for this
               * indicator.
               *
               * @type {string}
               */
              linkedTo: undefined,
              /**
               * Whether to compare indicator to the main series values
               * or indicator values.
               *
               * @sample {highstock} stock/plotoptions/series-comparetomain/
               *         Difference between comparing SMA values to the main series
               *         and its own values.
               *
               * @type {boolean}
               */
              compareToMain: false,
              /**
               * Paramters used in calculation of regression series' points.
               */
              params: {
                  /**
                   * The point index which indicator calculations will base. For
                   * example using OHLC data, index=2 means the indicator will be
                   * calculated using Low values.
                   */
                  index: 0,
                  /**
                   * The base period for indicator calculations. This is the number of
                   * data points which are taken into account for the indicator
                   * calculations.
                   */
                  period: 14
              }
          }, 
          /**
           * @lends Highcharts.Series.prototype
           */
          {
              processData: function () {
                  var series = this, compareToMain = series.options.compareToMain, linkedParent = series.linkedParent;
                  Series.prototype.processData.apply(series, arguments);
                  if (linkedParent && linkedParent.compareValue && compareToMain) {
                      series.compareValue = linkedParent.compareValue;
                  }
                  return;
              },
              bindTo: {
                  series: true,
                  eventName: 'updatedData'
              },
              hasDerivedData: true,
              useCommonDataGrouping: true,
              nameComponents: ['period'],
              nameSuffixes: [],
              calculateOn: 'init',
              // Defines on which other indicators is this indicator based on.
              requiredIndicators: [],
              requireIndicators: function () {
                  var obj = {
                      allLoaded: true
                  };
                  // Check whether all required indicators are loaded, else return
                  // the object with missing indicator's name.
                  this.requiredIndicators.forEach(function (indicator) {
                      if (seriesTypes[indicator]) {
                          seriesTypes[indicator].prototype.requireIndicators();
                      }
                      else {
                          obj.allLoaded = false;
                          obj.needed = indicator;
                      }
                  });
                  return obj;
              },
              init: function (chart, options) {
                  var indicator = this, requiredIndicators = indicator.requireIndicators();
                  // Check whether all required indicators are loaded.
                  if (!requiredIndicators.allLoaded) {
                      return error(generateMessage(indicator.type, requiredIndicators.needed));
                  }
                  Series.prototype.init.call(indicator, chart, options);
                  // Make sure we find series which is a base for an indicator
                  chart.linkSeries();
                  indicator.dataEventsToUnbind = [];
                  /**
                   * @private
                   * @return {void}
                   */
                  function recalculateValues() {
                      var oldData = indicator.points || [], oldDataLength = (indicator.xData || []).length, processedData = indicator.getValues(indicator.linkedParent, indicator.options.params) || {
                          values: [],
                          xData: [],
                          yData: []
                      }, croppedDataValues = [], overwriteData = true, oldFirstPointIndex, oldLastPointIndex, croppedData, min, max, i;
                      // We need to update points to reflect changes in all,
                      // x and y's, values. However, do it only for non-grouped
                      // data - grouping does it for us (#8572)
                      if (oldDataLength &&
                          !indicator.hasGroupedData &&
                          indicator.visible &&
                          indicator.points) {
                          // When data is cropped update only avaliable points (#9493)
                          if (indicator.cropped) {
                              if (indicator.xAxis) {
                                  min = indicator.xAxis.min;
                                  max = indicator.xAxis.max;
                              }
                              croppedData = indicator.cropData(processedData.xData, processedData.yData, min, max);
                              for (i = 0; i < croppedData.xData.length; i++) {
                                  // (#10774)
                                  croppedDataValues.push([
                                      croppedData.xData[i]
                                  ].concat(splat(croppedData.yData[i])));
                              }
                              oldFirstPointIndex = processedData.xData.indexOf(indicator.xData[0]);
                              oldLastPointIndex = processedData.xData.indexOf(indicator.xData[indicator.xData.length - 1]);
                              // Check if indicator points should be shifted (#8572)
                              if (oldFirstPointIndex === -1 &&
                                  oldLastPointIndex === processedData.xData.length - 2) {
                                  if (croppedDataValues[0][0] === oldData[0].x) {
                                      croppedDataValues.shift();
                                  }
                              }
                              indicator.updateData(croppedDataValues);
                              // Omit addPoint() and removePoint() cases
                          }
                          else if (processedData.xData.length !== oldDataLength - 1 &&
                              processedData.xData.length !== oldDataLength + 1) {
                              overwriteData = false;
                              indicator.updateData(processedData.values);
                          }
                      }
                      if (overwriteData) {
                          indicator.xData = processedData.xData;
                          indicator.yData = processedData.yData;
                          indicator.options.data = processedData.values;
                      }
                      // Removal of processedXData property is required because on
                      // first translate processedXData array is empty
                      if (indicator.bindTo.series === false) {
                          delete indicator.processedXData;
                          indicator.isDirty = true;
                          indicator.redraw();
                      }
                      indicator.isDirtyData = false;
                  }
                  if (!indicator.linkedParent) {
                      return error('Series ' +
                          indicator.options.linkedTo +
                          ' not found! Check `linkedTo`.', false, chart);
                  }
                  indicator.dataEventsToUnbind.push(addEvent(indicator.bindTo.series ?
                      indicator.linkedParent : indicator.linkedParent.xAxis, indicator.bindTo.eventName, recalculateValues));
                  if (indicator.calculateOn === 'init') {
                      recalculateValues();
                  }
                  else {
                      var unbinder = addEvent(indicator.chart, indicator.calculateOn, function () {
                          recalculateValues();
                          // Call this just once, on init
                          unbinder();
                      });
                  }
                  return indicator;
              },
              getName: function () {
                  var name = this.name, params = [];
                  if (!name) {
                      (this.nameComponents || []).forEach(function (component, index) {
                          params.push(this.options.params[component] +
                              pick(this.nameSuffixes[index], ''));
                      }, this);
                      name = (this.nameBase || this.type.toUpperCase()) +
                          (this.nameComponents ? ' (' + params.join(', ') + ')' : '');
                  }
                  return name;
              },
              getValues: function (series, params) {
                  var period = params.period, xVal = series.xData, yVal = series.yData, yValLen = yVal.length, range = 0, sum = 0, SMA = [], xData = [], yData = [], index = -1, i, SMAPoint;
                  if (xVal.length < period) {
                      return false;
                  }
                  // Switch index for OHLC / Candlestick / Arearange
                  if (isArray(yVal[0])) {
                      index = params.index ? params.index : 0;
                  }
                  // Accumulate first N-points
                  while (range < period - 1) {
                      sum += index < 0 ? yVal[range] : yVal[range][index];
                      range++;
                  }
                  // Calculate value one-by-one for each period in visible data
                  for (i = range; i < yValLen; i++) {
                      sum += index < 0 ? yVal[i] : yVal[i][index];
                      SMAPoint = [xVal[i], sum / period];
                      SMA.push(SMAPoint);
                      xData.push(SMAPoint[0]);
                      yData.push(SMAPoint[1]);
                      sum -= (index < 0 ?
                          yVal[i - range] :
                          yVal[i - range][index]);
                  }
                  return {
                      values: SMA,
                      xData: xData,
                      yData: yData
                  };
              },
              destroy: function () {
                  this.dataEventsToUnbind.forEach(function (unbinder) {
                      unbinder();
                  });
                  Series.prototype.destroy.call(this);
              }
          });
          /**
           * A `SMA` series. If the [type](#series.sma.type) option is not specified, it
           * is inherited from [chart.type](#chart.type).
           *
           * @extends   series,plotOptions.sma
           * @since     6.0.0
           * @product   highstock
           * @excluding dataParser, dataURL, useOhlcData
           * @requires  stock/indicators/indicators
           * @apioption series.sma
           */
          ''; // adds doclet above to the transpiled file
  
      });
      _registerModule(_modules, 'indicators/accumulation-distribution.src.js', [_modules['parts/Globals.js']], function (H) {
          /* *
           *
           *  License: www.highcharts.com/license
           *
           *  !!!!!!! SOURCE GETS TRANSPILED BY TYPESCRIPT. EDIT TS FILE ONLY. !!!!!!!
           * */
          var seriesType = H.seriesType;
          /* eslint-disable valid-jsdoc */
          // Utils:
          /**
           * @private
           */
          function populateAverage(xVal, yVal, yValVolume, i) {
              var high = yVal[i][1], low = yVal[i][2], close = yVal[i][3], volume = yValVolume[i], adY = close === high && close === low || high === low ?
                  0 :
                  ((2 * close - low - high) / (high - low)) * volume, adX = xVal[i];
              return [adX, adY];
          }
          /* eslint-enable valid-jsdoc */
          /**
           * The AD series type.
           *
           * @private
           * @class
           * @name Highcharts.seriesTypes.ad
           *
           * @augments Highcharts.Series
           */
          seriesType('ad', 'sma', 
          /**
           * Accumulation Distribution (AD). This series requires `linkedTo` option to
           * be set.
           *
           * @sample stock/indicators/accumulation-distribution
           *         Accumulation/Distribution indicator
           *
           * @extends      plotOptions.sma
           * @since        6.0.0
           * @product      highstock
           * @requires     stock/indicators/indicators
           * @requires     stock/indicators/accumulation-distribution
           * @optionparent plotOptions.ad
           */
          {
              params: {
                  /**
                   * The id of volume series which is mandatory.
                   * For example using OHLC data, volumeSeriesID='volume' means
                   * the indicator will be calculated using OHLC and volume values.
                   *
                   * @since 6.0.0
                   */
                  volumeSeriesID: 'volume'
              }
          }, 
          /**
           * @lends Highcharts.Series#
           */
          {
              nameComponents: false,
              nameBase: 'Accumulation/Distribution',
              getValues: function (series, params) {
                  var period = params.period, xVal = series.xData, yVal = series.yData, volumeSeriesID = params.volumeSeriesID, volumeSeries = series.chart.get(volumeSeriesID), yValVolume = volumeSeries && volumeSeries.yData, yValLen = yVal ? yVal.length : 0, AD = [], xData = [], yData = [], len, i, ADPoint;
                  if (xVal.length <= period &&
                      yValLen &&
                      yVal[0].length !== 4) {
                      return false;
                  }
                  if (!volumeSeries) {
                      return H.error('Series ' +
                          volumeSeriesID +
                          ' not found! Check `volumeSeriesID`.', true, series.chart);
                  }
                  // i = period <-- skip first N-points
                  // Calculate value one-by-one for each period in visible data
                  for (i = period; i < yValLen; i++) {
                      len = AD.length;
                      ADPoint = populateAverage(xVal, yVal, yValVolume, i, period);
                      if (len > 0) {
                          ADPoint[1] += AD[len - 1][1];
                      }
                      AD.push(ADPoint);
                      xData.push(ADPoint[0]);
                      yData.push(ADPoint[1]);
                  }
                  return {
                      values: AD,
                      xData: xData,
                      yData: yData
                  };
              }
          });
          /**
           * A `AD` series. If the [type](#series.ad.type) option is not
           * specified, it is inherited from [chart.type](#chart.type).
           *
           * @extends   series,plotOptions.ad
           * @since     6.0.0
           * @excluding dataParser, dataURL
           * @product   highstock
           * @requires  stock/indicators/indicators
           * @requires  stock/indicators/accumulation-distribution
           * @apioption series.ad
           */
          ''; // add doclet above to transpiled file
  
      });
      _registerModule(_modules, 'indicators/ao.src.js', [_modules['parts/Globals.js'], _modules['parts/Utilities.js']], function (H, U) {
          /* *
           *
           *  License: www.highcharts.com/license
           *
           *  !!!!!!! SOURCE GETS TRANSPILED BY TYPESCRIPT. EDIT TS FILE ONLY. !!!!!!!
           *
           * */
          var isArray = U.isArray;
          var correctFloat = H.correctFloat, noop = H.noop;
          /**
           * The AO series type
           *
           * @private
           * @class
           * @name Highcharts.seriesTypes.ao
           *
           * @augments Highcharts.Series
           */
          H.seriesType('ao', 'sma', 
          /**
           * Awesome Oscillator. This series requires the `linkedTo` option to
           * be set and should be loaded after the `stock/indicators/indicators.js`
           *
           * @sample {highstock} stock/indicators/ao
           *         Awesome
           *
           * @extends      plotOptions.sma
           * @since        7.0.0
           * @product      highstock
           * @excluding    allAreas, colorAxis, joinBy, keys, navigatorOptions,
           *               params, pointInterval, pointIntervalUnit, pointPlacement,
           *               pointRange, pointStart, showInNavigator, stacking
           * @requires     stock/indicators/indicators
           * @requires     stock/indicators/ao
           * @optionparent plotOptions.ao
           */
          {
              /**
               * Color of the Awesome oscillator series bar that is greater than the
               * previous one. Note that if a `color` is defined, the `color`
               * takes precedence and the `greaterBarColor` is ignored.
               *
               * @sample {highstock} stock/indicators/ao/
               *         greaterBarColor
               *
               * @type  {Highcharts.ColorString|Highcharts.GradientColorObject|Highcharts.PatternObject}
               * @since 7.0.0
               */
              greaterBarColor: '#06B535',
              /**
               * Color of the Awesome oscillator series bar that is lower than the
               * previous one. Note that if a `color` is defined, the `color`
               * takes precedence and the `lowerBarColor` is ignored.
               *
               * @sample {highstock} stock/indicators/ao/
               *         lowerBarColor
               *
               * @type  {Highcharts.ColorString|Highcharts.GradientColorObject|Highcharts.PatternObject}
               * @since 7.0.0
               */
              lowerBarColor: '#F21313',
              threshold: 0,
              groupPadding: 0.2,
              pointPadding: 0.2,
              states: {
                  hover: {
                      halo: {
                          size: 0
                      }
                  }
              }
          }, 
          /**
           * @lends Highcharts.Series#
           */
          {
              nameBase: 'AO',
              nameComponents: false,
              // Columns support:
              markerAttribs: noop,
              getColumnMetrics: H.seriesTypes.column.prototype.getColumnMetrics,
              crispCol: H.seriesTypes.column.prototype.crispCol,
              translate: H.seriesTypes.column.prototype.translate,
              drawPoints: H.seriesTypes.column.prototype.drawPoints,
              drawGraph: function () {
                  var indicator = this, options = indicator.options, points = indicator.points, userColor = indicator.userOptions.color, positiveColor = options.greaterBarColor, negativeColor = options.lowerBarColor, firstPoint = points[0], i;
                  if (!userColor && firstPoint) {
                      firstPoint.color = positiveColor;
                      for (i = 1; i < points.length; i++) {
                          if (points[i].y > points[i - 1].y) {
                              points[i].color = positiveColor;
                          }
                          else if (points[i].y < points[i - 1].y) {
                              points[i].color = negativeColor;
                          }
                          else {
                              points[i].color = points[i - 1].color;
                          }
                      }
                  }
              },
              getValues: function (series) {
                  var shortPeriod = 5, longPeriod = 34, xVal = series.xData || [], yVal = series.yData || [], yValLen = yVal.length, AO = [], // 0- date, 1- Awesome Oscillator
                  xData = [], yData = [], high = 1, low = 2, shortSum = 0, longSum = 0, shortSMA, // Shorter Period SMA
                  longSMA, // Longer Period SMA
                  awesome, shortLastIndex, longLastIndex, price, i, j;
                  if (xVal.length <= longPeriod ||
                      !isArray(yVal[0]) ||
                      yVal[0].length !== 4) {
                      return false;
                  }
                  for (i = 0; i < longPeriod - 1; i++) {
                      price = (yVal[i][high] + yVal[i][low]) / 2;
                      if (i >= longPeriod - shortPeriod) {
                          shortSum = correctFloat(shortSum + price);
                      }
                      longSum = correctFloat(longSum + price);
                  }
                  for (j = longPeriod - 1; j < yValLen; j++) {
                      price = (yVal[j][high] + yVal[j][low]) / 2;
                      shortSum = correctFloat(shortSum + price);
                      longSum = correctFloat(longSum + price);
                      shortSMA = shortSum / shortPeriod;
                      longSMA = longSum / longPeriod;
                      awesome = correctFloat(shortSMA - longSMA);
                      AO.push([xVal[j], awesome]);
                      xData.push(xVal[j]);
                      yData.push(awesome);
                      shortLastIndex = j + 1 - shortPeriod;
                      longLastIndex = j + 1 - longPeriod;
                      shortSum = correctFloat(shortSum -
                          (yVal[shortLastIndex][high] +
                              yVal[shortLastIndex][low]) / 2);
                      longSum = correctFloat(longSum -
                          (yVal[longLastIndex][high] +
                              yVal[longLastIndex][low]) / 2);
                  }
                  return {
                      values: AO,
                      xData: xData,
                      yData: yData
                  };
              }
          });
          /**
           * An `AO` series. If the [type](#series.ao.type)
           * option is not specified, it is inherited from [chart.type](#chart.type).
           *
           * @extends   series,plotOptions.ao
           * @since     7.0.0
           * @product   highstock
           * @excluding allAreas, colorAxis, dataParser, dataURL, joinBy, keys,
           *            navigatorOptions, pointInterval, pointIntervalUnit,
           *            pointPlacement, pointRange, pointStart, showInNavigator, stacking
           * @requires  stock/indicators/indicators
           * @requires  stock/indicators/ao
           * @apioption series.ao
           */
          ''; // for including the above in the doclets
  
      });
      _registerModule(_modules, 'mixins/multipe-lines.js', [_modules['parts/Globals.js'], _modules['parts/Utilities.js']], function (H, U) {
          /**
           *
           *  (c) 2010-2019 Wojciech Chmiel
           *
           *  License: www.highcharts.com/license
           *
           *  !!!!!!! SOURCE GETS TRANSPILED BY TYPESCRIPT. EDIT TS FILE ONLY. !!!!!!!
           *
           * */
          var defined = U.defined;
          var each = H.each, merge = H.merge, error = H.error, SMA = H.seriesTypes.sma;
          /**
           * Mixin useful for all indicators that have more than one line.
           * Merge it with your implementation where you will provide
           * getValues method appropriate to your indicator and pointArrayMap,
           * pointValKey, linesApiNames properites. Notice that pointArrayMap
           * should be consistent with amount of lines calculated in getValues method.
           *
           * @private
           * @mixin multipleLinesMixin
           */
          var multipleLinesMixin = {
              /* eslint-disable valid-jsdoc */
              /**
               * Lines ids. Required to plot appropriate amount of lines.
               * Notice that pointArrayMap should have more elements than
               * linesApiNames, because it contains main line and additional lines ids.
               * Also it should be consistent with amount of lines calculated in
               * getValues method from your implementation.
               *
               * @private
               * @name multipleLinesMixin.pointArrayMap
               * @type {Array<string>}
               */
              pointArrayMap: ['top', 'bottom'],
              /**
               * Main line id.
               *
               * @private
               * @name multipleLinesMixin.pointValKey
               * @type {string}
               */
              pointValKey: 'top',
              /**
               * Additional lines DOCS names. Elements of linesApiNames array should
               * be consistent with DOCS line names defined in your implementation.
               * Notice that linesApiNames should have decreased amount of elements
               * relative to pointArrayMap (without pointValKey).
               *
               * @private
               * @name multipleLinesMixin.linesApiNames
               * @type {Array<string>}
               */
              linesApiNames: ['bottomLine'],
              /**
               * Create translatedLines Collection based on pointArrayMap.
               *
               * @private
               * @function multipleLinesMixin.getTranslatedLinesNames
               * @param {string} [excludedValue]
               *        Main line id
               * @return {Array<string>}
               *         Returns translated lines names without excluded value.
               */
              getTranslatedLinesNames: function (excludedValue) {
                  var translatedLines = [];
                  each(this.pointArrayMap, function (propertyName) {
                      if (propertyName !== excludedValue) {
                          translatedLines.push('plot' +
                              propertyName.charAt(0).toUpperCase() +
                              propertyName.slice(1));
                      }
                  });
                  return translatedLines;
              },
              /**
               * @private
               * @function multipleLinesMixin.toYData
               * @param {Highcharts.Point} point
               *        Indicator point
               * @return {Array<number>}
               *         Returns point Y value for all lines
               */
              toYData: function (point) {
                  var pointColl = [];
                  each(this.pointArrayMap, function (propertyName) {
                      pointColl.push(point[propertyName]);
                  });
                  return pointColl;
              },
              /**
               * Add lines plot pixel values.
               *
               * @private
               * @function multipleLinesMixin.translate
               * @return {void}
               */
              translate: function () {
                  var indicator = this, pointArrayMap = indicator.pointArrayMap, LinesNames = [], value;
                  LinesNames = indicator.getTranslatedLinesNames();
                  SMA.prototype.translate.apply(indicator, arguments);
                  each(indicator.points, function (point) {
                      each(pointArrayMap, function (propertyName, i) {
                          value = point[propertyName];
                          if (value !== null) {
                              point[LinesNames[i]] = indicator.yAxis.toPixels(value, true);
                          }
                      });
                  });
              },
              /**
               * Draw main and additional lines.
               *
               * @private
               * @function multipleLinesMixin.drawGraph
               * @return {void}
               */
              drawGraph: function () {
                  var indicator = this, pointValKey = indicator.pointValKey, linesApiNames = indicator.linesApiNames, mainLinePoints = indicator.points, pointsLength = mainLinePoints.length, mainLineOptions = indicator.options, mainLinePath = indicator.graph, gappedExtend = {
                      options: {
                          gapSize: mainLineOptions.gapSize
                      }
                  }, 
                  // additional lines point place holders:
                  secondaryLines = [], secondaryLinesNames = indicator.getTranslatedLinesNames(pointValKey), point;
                  // Generate points for additional lines:
                  each(secondaryLinesNames, function (plotLine, index) {
                      // create additional lines point place holders
                      secondaryLines[index] = [];
                      while (pointsLength--) {
                          point = mainLinePoints[pointsLength];
                          secondaryLines[index].push({
                              x: point.x,
                              plotX: point.plotX,
                              plotY: point[plotLine],
                              isNull: !defined(point[plotLine])
                          });
                      }
                      pointsLength = mainLinePoints.length;
                  });
                  // Modify options and generate additional lines:
                  each(linesApiNames, function (lineName, i) {
                      if (secondaryLines[i]) {
                          indicator.points = secondaryLines[i];
                          if (mainLineOptions[lineName]) {
                              indicator.options = merge(mainLineOptions[lineName].styles, gappedExtend);
                          }
                          else {
                              error('Error: "There is no ' + lineName +
                                  ' in DOCS options declared. Check if linesApiNames' +
                                  ' are consistent with your DOCS line names."' +
                                  ' at mixin/multiple-line.js:34');
                          }
                          indicator.graph = indicator['graph' + lineName];
                          SMA.prototype.drawGraph.call(indicator);
                          // Now save lines:
                          indicator['graph' + lineName] = indicator.graph;
                      }
                      else {
                          error('Error: "' + lineName + ' doesn\'t have equivalent ' +
                              'in pointArrayMap. To many elements in linesApiNames ' +
                              'relative to pointArrayMap."');
                      }
                  });
                  // Restore options and draw a main line:
                  indicator.points = mainLinePoints;
                  indicator.options = mainLineOptions;
                  indicator.graph = mainLinePath;
                  SMA.prototype.drawGraph.call(indicator);
              }
          };
  
          return multipleLinesMixin;
      });
      _registerModule(_modules, 'indicators/aroon.src.js', [_modules['parts/Globals.js'], _modules['parts/Utilities.js'], _modules['mixins/multipe-lines.js']], function (H, U, multipleLinesMixin) {
          /* *
           *
           *  License: www.highcharts.com/license
           *
           *  !!!!!!! SOURCE GETS TRANSPILED BY TYPESCRIPT. EDIT TS FILE ONLY. !!!!!!!
           *
           * */
          var pick = U.pick;
          /* eslint-disable valid-jsdoc */
          // Utils
          // Index of element with extreme value from array (min or max)
          /**
           * @private
           */
          function getExtremeIndexInArray(arr, extreme) {
              var extremeValue = arr[0], valueIndex = 0, i;
              for (i = 1; i < arr.length; i++) {
                  if (extreme === 'max' && arr[i] >= extremeValue ||
                      extreme === 'min' && arr[i] <= extremeValue) {
                      extremeValue = arr[i];
                      valueIndex = i;
                  }
              }
              return valueIndex;
          }
          /* eslint-enable valid-jsdoc */
          /**
           * The Aroon series type.
           *
           * @private
           * @class
           * @name Highcharts.seriesTypes.aroon
           *
           * @augments Highcharts.Series
           */
          H.seriesType('aroon', 'sma', 
          /**
           * Aroon. This series requires the `linkedTo` option to be
           * set and should be loaded after the `stock/indicators/indicators.js`.
           *
           * @sample {highstock} stock/indicators/aroon
           *         Aroon
           *
           * @extends      plotOptions.sma
           * @since        7.0.0
           * @product      highstock
           * @excluding    allAreas, colorAxis, compare, compareBase, joinBy, keys,
           *               navigatorOptions, pointInterval, pointIntervalUnit,
           *               pointPlacement, pointRange, pointStart, showInNavigator,
           *               stacking
           * @requires     stock/indicators/indicators
           * @requires     stock/indicators/aroon
           * @optionparent plotOptions.aroon
           */
          {
              /**
               * Paramters used in calculation of aroon series points.
               *
               * @excluding periods, index
               */
              params: {
                  /**
                   * Period for Aroon indicator
                   */
                  period: 25
              },
              marker: {
                  enabled: false
              },
              tooltip: {
                  pointFormat: '<span style="color:{point.color}">\u25CF</span><b> {series.name}</b><br/>Aroon Up: {point.y}<br/>Aroon Down: {point.aroonDown}<br/>'
              },
              /**
               * aroonDown line options.
               */
              aroonDown: {
                  /**
                   * Styles for an aroonDown line.
                   */
                  styles: {
                      /**
                       * Pixel width of the line.
                       */
                      lineWidth: 1,
                      /**
                       * Color of the line. If not set, it's inherited from
                       * [plotOptions.aroon.color](#plotOptions.aroon.color).
                       *
                       * @type {Highcharts.ColorString}
                       */
                      lineColor: undefined
                  }
              },
              dataGrouping: {
                  approximation: 'averages'
              }
          }, 
          /**
           * @lends Highcharts.Series#
           */
          H.merge(multipleLinesMixin, {
              nameBase: 'Aroon',
              pointArrayMap: ['y', 'aroonDown'],
              pointValKey: 'y',
              linesApiNames: ['aroonDown'],
              getValues: function (series, params) {
                  var period = params.period, xVal = series.xData, yVal = series.yData, yValLen = yVal ? yVal.length : 0, 
                  // 0- date, 1- Aroon Up, 2- Aroon Down
                  AR = [], xData = [], yData = [], slicedY, low = 2, high = 1, aroonUp, aroonDown, xLow, xHigh, i;
                  // 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 = period - 1; i < yValLen; i++) {
                      slicedY = yVal.slice(i - period + 1, i + 2);
                      xLow = getExtremeIndexInArray(slicedY.map(function (elem) {
                          return pick(elem[low], elem);
                      }), 'min');
                      xHigh = getExtremeIndexInArray(slicedY.map(function (elem) {
                          return pick(elem[high], elem);
                      }), 'max');
                      aroonUp = (xHigh / period) * 100;
                      aroonDown = (xLow / period) * 100;
                      if (xVal[i + 1]) {
                          AR.push([xVal[i + 1], aroonUp, aroonDown]);
                          xData.push(xVal[i + 1]);
                          yData.push([aroonUp, aroonDown]);
                      }
                  }
                  return {
                      values: AR,
                      xData: xData,
                      yData: yData
                  };
              }
          }));
          /**
           * A Aroon indicator. If the [type](#series.aroon.type) option is not
           * specified, it is inherited from [chart.type](#chart.type).
           *
           * @extends   series,plotOptions.aroon
           * @since     7.0.0
           * @product   highstock
           * @excluding allAreas, colorAxis, compare, compareBase, dataParser, dataURL,
           *            joinBy, keys, navigatorOptions, pointInterval, pointIntervalUnit,
           *            pointPlacement, pointRange, pointStart, showInNavigator, stacking
           * @requires  stock/indicators/indicators
           * @requires  stock/indicators/aroon
           * @apioption series.aroon
           */
          ''; // to avoid removal of the above jsdoc
  
      });
      _registerModule(_modules, 'indicators/aroon-oscillator.src.js', [_modules['parts/Globals.js'], _modules['mixins/multipe-lines.js'], _modules['mixins/indicator-required.js']], function (H, multipleLinesMixin, requiredIndicatorMixin) {
          /* *
           *
           *  License: www.highcharts.com/license
           *
           *  !!!!!!! SOURCE GETS TRANSPILED BY TYPESCRIPT. EDIT TS FILE ONLY. !!!!!!!
           *
           * */
          var AROON = H.seriesTypes.aroon, requiredIndicator = requiredIndicatorMixin;
          /**
           * The Aroon Oscillator series type.
           *
           * @private
           * @class
           * @name Highcharts.seriesTypes.aroonoscillator
           *
           * @augments Highcharts.Series
           */
          H.seriesType('aroonoscillator', 'aroon', 
          /**
           * Aroon Oscillator. This series requires the `linkedTo` option to be set
           * and should be loaded after the `stock/indicators/indicators.js` and
           * `stock/indicators/aroon.js`.
           *
           * @sample {highstock} stock/indicators/aroon-oscillator
           *         Aroon Oscillator
           *
           * @extends      plotOptions.aroon
           * @since        7.0.0
           * @product      highstock
           * @excluding    allAreas, aroonDown, colorAxis, compare, compareBase,
           *               joinBy, keys, navigatorOptions, pointInterval,
           *               pointIntervalUnit, pointPlacement, pointRange, pointStart,
           *               showInNavigator, stacking
           * @requires     stock/indicators/indicators
           * @requires     stock/indicators/aroon
           * @requires     stock/indicators/aroon-oscillator
           * @optionparent plotOptions.aroonoscillator
           */
          {
              /**
               * Paramters used in calculation of aroon oscillator series points.
               *
               * @excluding periods, index
               */
              params: {
                  /**
                   * Period for Aroon Oscillator
                   *
                   * @since   7.0.0
                   * @product highstock
                   */
                  period: 25
              },
              tooltip: {
                  pointFormat: '<span style="color:{point.color}">\u25CF</span><b> {series.name}</b>: {point.y}'
              }
          }, 
          /**
           * @lends Highcharts.Series#
           */
          H.merge(multipleLinesMixin, {
              nameBase: 'Aroon Oscillator',
              pointArrayMap: ['y'],
              pointValKey: 'y',
              linesApiNames: [],
              init: function () {
                  var args = arguments, ctx = this;
                  requiredIndicator.isParentLoaded(AROON, 'aroon', ctx.type, function (indicator) {
                      indicator.prototype.init.apply(ctx, args);
                      return;
                  });
              },
              getValues: function (series, params) {
                  // 0- date, 1- Aroon Oscillator
                  var ARO = [], xData = [], yData = [], aroon, aroonUp, aroonDown, oscillator, i;
                  aroon = AROON.prototype.getValues.call(this, series, params);
                  for (i = 0; i < aroon.yData.length; i++) {
                      aroonUp = aroon.yData[i][0];
                      aroonDown = aroon.yData[i][1];
                      oscillator = aroonUp - aroonDown;
                      ARO.push([aroon.xData[i], oscillator]);
                      xData.push(aroon.xData[i]);
                      yData.push(oscillator);
                  }
                  return {
                      values: ARO,
                      xData: xData,
                      yData: yData
                  };
              }
          }));
          /**
           * An `Aroon Oscillator` series. If the [type](#series.aroonoscillator.type)
           * option is not specified, it is inherited from [chart.type](#chart.type).
           *
           * @extends   series,plotOptions.aroonoscillator
           * @since     7.0.0
           * @product   highstock
           * @excluding allAreas, aroonDown, colorAxis, compare, compareBase, dataParser,
           *            dataURL, joinBy, keys, navigatorOptions, pointInterval,
           *            pointIntervalUnit, pointPlacement, pointRange, pointStart,
           *            showInNavigator, stacking
           * @requires  stock/indicators/indicators
           * @requires  stock/indicators/aroon
           * @requires  stock/indicators/aroon-oscillator
           * @apioption series.aroonoscillator
           */
          ''; // adds doclet above to the transpiled file
  
      });
      _registerModule(_modules, 'indicators/atr.src.js', [_modules['parts/Globals.js'], _modules['parts/Utilities.js']], function (H, U) {
          /* *
           *
           *  License: www.highcharts.com/license
           *
           *  !!!!!!! SOURCE GETS TRANSPILED BY TYPESCRIPT. EDIT TS FILE ONLY. !!!!!!!
           *
           * */
          var isArray = U.isArray;
          var seriesType = H.seriesType, UNDEFINED;
          /* eslint-disable valid-jsdoc */
          // Utils:
          /**
           * @private
           */
          function accumulateAverage(points, xVal, yVal, i) {
              var xValue = xVal[i], yValue = yVal[i];
              points.push([xValue, yValue]);
          }
          /**
           * @private
           */
          function getTR(currentPoint, prevPoint) {
              var pointY = currentPoint, prevY = prevPoint, HL = pointY[1] - pointY[2], HCp = prevY === UNDEFINED ? 0 : Math.abs(pointY[1] - prevY[3]), LCp = prevY === UNDEFINED ? 0 : Math.abs(pointY[2] - prevY[3]), TR = Math.max(HL, HCp, LCp);
              return TR;
          }
          /**
           * @private
           */
          function populateAverage(points, xVal, yVal, i, period, prevATR) {
              var x = xVal[i - 1], TR = getTR(yVal[i - 1], yVal[i - 2]), y;
              y = (((prevATR * (period - 1)) + TR) / period);
              return [x, y];
          }
          /* eslint-enable valid-jsdoc */
          /**
           * The ATR series type.
           *
           * @private
           * @class
           * @name Highcharts.seriesTypes.atr
           *
           * @augments Highcharts.Series
           */
          seriesType('atr', 'sma', 
          /**
           * Average true range indicator (ATR). This series requires `linkedTo`
           * option to be set.
           *
           * @sample stock/indicators/atr
           *         ATR indicator
           *
           * @extends      plotOptions.sma
           * @since        6.0.0
           * @product      highstock
           * @requires     stock/indicators/indicators
           * @requires     stock/indicators/atr
           * @optionparent plotOptions.atr
           */
          {
              params: {
                  period: 14
              }
          }, 
          /**
           * @lends Highcharts.Series#
           */
          {
              getValues: function (series, params) {
                  var period = params.period, xVal = series.xData, yVal = series.yData, yValLen = yVal ? yVal.length : 0, xValue = xVal[0], yValue = yVal[0], range = 1, prevATR = 0, TR = 0, ATR = [], xData = [], yData = [], point, i, points;
                  points = [[xValue, yValue]];
                  if ((xVal.length <= period) ||
                      !isArray(yVal[0]) ||
                      yVal[0].length !== 4) {
                      return false;
                  }
                  for (i = 1; i <= yValLen; i++) {
                      accumulateAverage(points, xVal, yVal, i);
                      if (period < range) {
                          point = populateAverage(points, xVal, yVal, i, period, prevATR);
                          prevATR = point[1];
                          ATR.push(point);
                          xData.push(point[0]);
                          yData.push(point[1]);
                      }
                      else if (period === range) {
                          prevATR = TR / (i - 1);
                          ATR.push([xVal[i - 1], prevATR]);
                          xData.push(xVal[i - 1]);
                          yData.push(prevATR);
                          range++;
                      }
                      else {
                          TR += getTR(yVal[i - 1], yVal[i - 2]);
                          range++;
                      }
                  }
                  return {
                      values: ATR,
                      xData: xData,
                      yData: yData
                  };
              }
          });
          /**
           * A `ATR` series. If the [type](#series.atr.type) option is not specified, it
           * is inherited from [chart.type](#chart.type).
           *
           * @extends   series,plotOptions.atr
           * @since     6.0.0
           * @product   highstock
           * @excluding dataParser, dataURL
           * @requires  stock/indicators/indicators
           * @requires  stock/indicators/atr
           * @apioption series.atr
           */
          ''; // to include the above in the js output
  
      });
      _registerModule(_modules, 'indicators/bollinger-bands.src.js', [_modules['parts/Globals.js'], _modules['parts/Utilities.js'], _modules['mixins/multipe-lines.js']], function (H, U, multipleLinesMixin) {
          /**
           *
           *  License: www.highcharts.com/license
           *
           *  !!!!!!! SOURCE GETS TRANSPILED BY TYPESCRIPT. EDIT TS FILE ONLY. !!!!!!!
           *
           * */
          var isArray = U.isArray;
          var merge = H.merge, SMA = H.seriesTypes.sma;
          /* eslint-disable valid-jsdoc */
          // Utils:
          /**
           * @private
           */
          function getStandardDeviation(arr, index, isOHLC, mean) {
              var variance = 0, arrLen = arr.length, std = 0, i = 0, value;
              for (; i < arrLen; i++) {
                  value = (isOHLC ? arr[i][index] : arr[i]) - mean;
                  variance += value * value;
              }
              variance = variance / (arrLen - 1);
              std = Math.sqrt(variance);
              return std;
          }
          /* eslint-enable valid-jsdoc */
          /**
           * Bollinger Bands series type.
           *
           * @private
           * @class
           * @name Highcharts.seriesTypes.bb
           *
           * @augments Highcharts.Series
           */
          H.seriesType('bb', 'sma', 
          /**
           * Bollinger bands (BB). This series requires the `linkedTo` option to be
           * set and should be loaded after the `stock/indicators/indicators.js` file.
           *
           * @sample stock/indicators/bollinger-bands
           *         Bollinger bands
           *
           * @extends      plotOptions.sma
           * @since        6.0.0
           * @product      highstock
           * @requires     stock/indicators/indicators
           * @requires     stock/indicators/bollinger-bands
           * @optionparent plotOptions.bb
           */
          {
              params: {
                  period: 20,
                  /**
                   * Standard deviation for top and bottom bands.
                   */
                  standardDeviation: 2,
                  index: 3
              },
              /**
               * Bottom line options.
               */
              bottomLine: {
                  /**
                   * Styles for a bottom line.
                   */
                  styles: {
                      /**
                       * Pixel width of the line.
                       */
                      lineWidth: 1,
                      /**
                       * Color of the line. If not set, it's inherited from
                       * [plotOptions.bb.color](#plotOptions.bb.color).
                       *
                       * @type  {Highcharts.ColorString}
                       */
                      lineColor: undefined
                  }
              },
              /**
               * Top line options.
               *
               * @extends plotOptions.bb.bottomLine
               */
              topLine: {
                  styles: {
                      lineWidth: 1,
                      /**
                       * @type {Highcharts.ColorString}
                       */
                      lineColor: undefined
                  }
              },
              tooltip: {
                  pointFormat: '<span style="color:{point.color}">\u25CF</span><b> {series.name}</b><br/>Top: {point.top}<br/>Middle: {point.middle}<br/>Bottom: {point.bottom}<br/>'
              },
              marker: {
                  enabled: false
              },
              dataGrouping: {
                  approximation: 'averages'
              }
          }, 
          /**
           * @lends Highcharts.Series#
           */
          H.merge(multipleLinesMixin, {
              pointArrayMap: ['top', 'middle', 'bottom'],
              pointValKey: 'middle',
              nameComponents: ['period', 'standardDeviation'],
              linesApiNames: ['topLine', 'bottomLine'],
              init: function () {
                  SMA.prototype.init.apply(this, arguments);
                  // Set default color for lines:
                  this.options = merge({
                      topLine: {
                          styles: {
                              lineColor: this.color
                          }
                      },
                      bottomLine: {
                          styles: {
                              lineColor: this.color
                          }
                      }
                  }, this.options);
              },
              getValues: function (series, params) {
                  var period = params.period, standardDeviation = params.standardDeviation, xVal = series.xData, yVal = series.yData, yValLen = yVal ? yVal.length : 0, 
                  // 0- date, 1-middle line, 2-top line, 3-bottom line
                  BB = [], 
                  // middle line, top line and bottom line
                  ML, TL, BL, date, xData = [], yData = [], slicedX, slicedY, stdDev, isOHLC, point, i;
                  if (xVal.length < period) {
                      return false;
                  }
                  isOHLC = isArray(yVal[0]);
                  for (i = period; i <= yValLen; i++) {
                      slicedX = xVal.slice(i - period, i);
                      slicedY = yVal.slice(i - period, i);
                      point = SMA.prototype.getValues.call(this, {
                          xData: slicedX,
                          yData: slicedY
                      }, params);
                      date = point.xData[0];
                      ML = point.yData[0];
                      stdDev = getStandardDeviation(slicedY, params.index, isOHLC, ML);
                      TL = ML + standardDeviation * stdDev;
                      BL = ML - standardDeviation * stdDev;
                      BB.push([date, TL, ML, BL]);
                      xData.push(date);
                      yData.push([TL, ML, BL]);
                  }
                  return {
                      values: BB,
                      xData: xData,
                      yData: yData
                  };
              }
          }));
          /**
           * A bollinger bands indicator. If the [type](#series.bb.type) option is not
           * specified, it is inherited from [chart.type](#chart.type).
           *
           * @extends   series,plotOptions.bb
           * @since     6.0.0
           * @excluding dataParser, dataURL
           * @product   highstock
           * @requires  stock/indicators/indicators
           * @requires  stock/indicators/bollinger-bands
           * @apioption series.bb
           */
          ''; // to include the above in the js output
  
      });
      _registerModule(_modules, 'indicators/cci.src.js', [_modules['parts/Globals.js'], _modules['parts/Utilities.js']], function (H, U) {
          /* *
           *
           *  License: www.highcharts.com/license
           *
           *  !!!!!!! SOURCE GETS TRANSPILED BY TYPESCRIPT. EDIT TS FILE ONLY. !!!!!!!
           * */
          var isArray = U.isArray;
          var seriesType = H.seriesType;
          /* eslint-disable valid-jsdoc */
          // Utils:
          /**
           * @private
           */
          function sumArray(array) {
              return array.reduce(function (prev, cur) {
                  return prev + cur;
              }, 0);
          }
          /**
           * @private
           */
          function meanDeviation(arr, sma) {
              var len = arr.length, sum = 0, i;
              for (i = 0; i < len; i++) {
                  sum += Math.abs(sma - (arr[i]));
              }
              return sum;
          }
          /* eslint-enable valid-jsdoc */
          /**
           * The CCI series type.
           *
           * @private
           * @class
           * @name Highcharts.seriesTypes.cci
           *
           * @augments Highcharts.Series
           */
          seriesType('cci', 'sma', 
          /**
           * Commodity Channel Index (CCI). This series requires `linkedTo` option to
           * be set.
           *
           * @sample stock/indicators/cci
           *         CCI indicator
           *
           * @extends      plotOptions.sma
           * @since        6.0.0
           * @product      highstock
           * @requires     stock/indicators/indicators
           * @requires     stock/indicators/cci
           * @optionparent plotOptions.cci
           */
          {
              params: {
                  period: 14
              }
          }, 
          /**
           * @lends Highcharts.Series#
           */
          {
              getValues: function (series, params) {
                  var period = params.period, xVal = series.xData, yVal = series.yData, yValLen = yVal ? yVal.length : 0, TP = [], periodTP = [], range = 1, CCI = [], xData = [], yData = [], CCIPoint, p, len, smaTP, TPtemp, meanDev, i;
                  // CCI requires close value
                  if (xVal.length <= period ||
                      !isArray(yVal[0]) ||
                      yVal[0].length !== 4) {
                      return false;
                  }
                  // accumulate first N-points
                  while (range < period) {
                      p = yVal[range - 1];
                      TP.push((p[1] + p[2] + p[3]) / 3);
                      range++;
                  }
                  for (i = period; i <= yValLen; i++) {
                      p = yVal[i - 1];
                      TPtemp = (p[1] + p[2] + p[3]) / 3;
                      len = TP.push(TPtemp);
                      periodTP = TP.slice(len - period);
                      smaTP = sumArray(periodTP) / period;
                      meanDev = meanDeviation(periodTP, smaTP) / period;
                      CCIPoint = ((TPtemp - smaTP) / (0.015 * meanDev));
                      CCI.push([xVal[i - 1], CCIPoint]);
                      xData.push(xVal[i - 1]);
                      yData.push(CCIPoint);
                  }
                  return {
                      values: CCI,
                      xData: xData,
                      yData: yData
                  };
              }
          });
          /**
           * A `CCI` series. If the [type](#series.cci.type) option is not
           * specified, it is inherited from [chart.type](#chart.type).
           *
           * @extends   series,plotOptions.cci
           * @since     6.0.0
           * @excluding dataParser, dataURL
           * @product   highstock
           * @requires  stock/indicators/indicators
           * @requires  stock/indicators/cci
           * @apioption series.cci
           */
          ''; // to include the above in the js output
  
      });
      _registerModule(_modules, 'indicators/cmf.src.js', [_modules['parts/Globals.js']], function (H) {
          /* *
           *
           *  (c) 2010-2019 Highsoft AS
           *
           *  Author: Sebastian Domas
           *
           *  Chaikin Money Flow indicator for Highstock
           *
           *  License: www.highcharts.com/license
           *
           *  !!!!!!! SOURCE GETS TRANSPILED BY TYPESCRIPT. EDIT TS FILE ONLY. !!!!!!!
           *
           * */
          /**
           * The CMF series type.
           *
           * @private
           * @class
           * @name Highcharts.seriesTypes.cmf
           *
           * @augments Highcharts.Series
           */
          H.seriesType('cmf', 'sma', 
          /**
           * Chaikin Money Flow indicator (cmf).
           *
           * @sample stock/indicators/cmf/
           *         Chaikin Money Flow indicator
           *
           * @extends      plotOptions.sma
           * @since        6.0.0
           * @excluding    animationLimit
           * @product      highstock
           * @requires     stock/indicators/indicators
           * @requires     stock/indicators/cmf
           * @optionparent plotOptions.cmf
           */
          {
              params: {
                  period: 14,
                  /**
                   * The id of another series to use its data as volume data for the
                   * indiator calculation.
                   */
                  volumeSeriesID: 'volume'
              }
          }, 
          /**
           * @lends Highcharts.Series#
           */
          {
              nameBase: 'Chaikin Money Flow',
              /**
               * Checks if the series and volumeSeries are accessible, number of
               * points.x is longer than period, is series has OHLC data
               * @private
               * @param {Highcharts.CMFIndicator} this indicator to use.
               * @return {boolean} True if series is valid and can be computed,
               * otherwise false.
               */
              isValid: function () {
                  var chart = this.chart, options = this.options, series = this.linkedParent, volumeSeries = (this.volumeSeries ||
                      (this.volumeSeries =
                          chart.get(options.params.volumeSeriesID))), isSeriesOHLC = (series &&
                      series.yData &&
                      series.yData[0].length === 4);
                  /**
                   * @private
                   * @param {Highcharts.Series} serie to check length validity on.
                   * @return {boolean|undefined} true if length is valid.
                   */
                  function isLengthValid(serie) {
                      return serie.xData &&
                          serie.xData.length >= options.params.period;
                  }
                  return !!(series &&
                      volumeSeries &&
                      isLengthValid(series) &&
                      isLengthValid(volumeSeries) && isSeriesOHLC);
              },
              /**
               * Returns indicator's data.
               * @private
               * @param {Highcharts.CMFIndicator} this indicator to use.
               * @param {Highcharts.Series} series to calculate values from
               * @param {Highcharts.CMFIndicatorParamsOptions} params to pass
               * @return {boolean|Highcharts.IndicatorNullableValuesObject} Returns false if the
               * indicator is not valid, otherwise returns Values object.
               */
              getValues: function (series, params) {
                  if (!this.isValid()) {
                      return false;
                  }
                  return this.getMoneyFlow(series.xData, series.yData, this.volumeSeries.yData, params.period);
              },
              /**
               * @private
               * @param {Array<number>} xData - x timestamp values
               * @param {Array<number>} seriesYData - yData of basic series
               * @param {Array<number>} volumeSeriesYData - yData of volume series
               * @param {number} period - indicator's param
               * @return {Highcharts.IndicatorNullableValuesObject} object containing computed money
               * flow data
               */
              getMoneyFlow: function (xData, seriesYData, volumeSeriesYData, period) {
                  var len = seriesYData.length, moneyFlowVolume = [], sumVolume = 0, sumMoneyFlowVolume = 0, moneyFlowXData = [], moneyFlowYData = [], values = [], i, point, nullIndex = -1;
                  /**
                   * Calculates money flow volume, changes i, nullIndex vars from
                   * upper scope!
                   * @private
                   * @param {Array<number>} ohlc - OHLC point
                   * @param {number} volume - Volume point's y value
                   * @return {number|null} - volume * moneyFlowMultiplier
                   **/
                  function getMoneyFlowVolume(ohlc, volume) {
                      var high = ohlc[1], low = ohlc[2], close = ohlc[3], isValid = volume !== null &&
                          high !== null &&
                          low !== null &&
                          close !== null &&
                          high !== low;
                      /**
                       * @private
                       * @param {number} h - High value
                       * @param {number} l - Low value
                       * @param {number} c - Close value
                       * @return {number} calculated multiplier for the point
                       **/
                      function getMoneyFlowMultiplier(h, l, c) {
                          return ((c - l) - (h - c)) / (h - l);
                      }
                      return isValid ?
                          getMoneyFlowMultiplier(high, low, close) * volume :
                          ((nullIndex = i), null);
                  }
                  if (period > 0 && period <= len) {
                      for (i = 0; i < period; i++) {
                          moneyFlowVolume[i] = getMoneyFlowVolume(seriesYData[i], volumeSeriesYData[i]);
                          sumVolume += volumeSeriesYData[i];
                          sumMoneyFlowVolume += moneyFlowVolume[i];
                      }
                      moneyFlowXData.push(xData[i - 1]);
                      moneyFlowYData.push(i - nullIndex >= period && sumVolume !== 0 ?
                          sumMoneyFlowVolume / sumVolume :
                          null);
                      values.push([moneyFlowXData[0], moneyFlowYData[0]]);
                      for (; i < len; i++) {
                          moneyFlowVolume[i] = getMoneyFlowVolume(seriesYData[i], volumeSeriesYData[i]);
                          sumVolume -= volumeSeriesYData[i - period];
                          sumVolume += volumeSeriesYData[i];
                          sumMoneyFlowVolume -= moneyFlowVolume[i - period];
                          sumMoneyFlowVolume += moneyFlowVolume[i];
                          point = [
                              xData[i],
                              i - nullIndex >= period ?
                                  sumMoneyFlowVolume / sumVolume :
                                  null
                          ];
                          moneyFlowXData.push(point[0]);
                          moneyFlowYData.push(point[1]);
                          values.push([point[0], point[1]]);
                      }
                  }
                  return {
                      values: values,
                      xData: moneyFlowXData,
                      yData: moneyFlowYData
                  };
              }
          });
          /**
           * A `CMF` series. If the [type](#series.cmf.type) option is not
           * specified, it is inherited from [chart.type](#chart.type).
           *
           * @extends   series,plotOptions.cmf
           * @since     6.0.0
           * @product   highstock
           * @excluding dataParser, dataURL
           * @requires  stock/indicators/indicators
           * @requires  stock/indicators/cmf
           * @apioption series.cmf
           */
          ''; // adds doclet above to the transpiled file
  
      });
      _registerModule(_modules, 'indicators/dpo.src.js', [_modules['parts/Globals.js'], _modules['parts/Utilities.js']], function (H, U) {
          /* *
           *
           *  License: www.highcharts.com/license
           *
           *  !!!!!!! SOURCE GETS TRANSPILED BY TYPESCRIPT. EDIT TS FILE ONLY. !!!!!!!
           *
           * */
          var pick = U.pick;
          var correctFloat = H.correctFloat;
          /* eslint-disable valid-jsdoc */
          // Utils
          /**
           * @private
           */
          function accumulatePoints(sum, yVal, i, index, subtract) {
              var price = pick(yVal[i][index], yVal[i]);
              if (subtract) {
                  return correctFloat(sum - price);
              }
              return correctFloat(sum + price);
          }
          /* eslint-enable valid-jsdoc */
          /**
           * The DPO series type.
           *
           * @private
           * @class
           * @name Highcharts.seriesTypes.dpo
           *
           * @augments Highcharts.Series
           */
          H.seriesType('dpo', 'sma', 
          /**
           * Detrended Price Oscillator. This series requires the `linkedTo` option to
           * be set and should be loaded after the `stock/indicators/indicators.js`.
           *
           * @sample {highstock} stock/indicators/dpo
           *         Detrended Price Oscillator
           *
           * @extends      plotOptions.sma
           * @since        7.0.0
           * @product      highstock
           * @excluding    allAreas, colorAxis, compare, compareBase, joinBy, keys,
           *               navigatorOptions, pointInterval, pointIntervalUnit,
           *               pointPlacement, pointRange, pointStart, showInNavigator,
           *               stacking
           * @requires     stock/indicators/indicators
           * @requires     stock/indicators/dpo
           * @optionparent plotOptions.dpo
           */
          {
              /**
               * Parameters used in calculation of Detrended Price Oscillator series
               * points.
               */
              params: {
                  /**
                   * Period for Detrended Price Oscillator
                   */
                  period: 21
              }
          }, 
          /**
           * @lends Highcharts.Series#
           */
          {
              nameBase: 'DPO',
              getValues: function (series, params) {
                  var period = params.period, index = params.index, offset = Math.floor(period / 2 + 1), range = period + offset, xVal = series.xData || [], yVal = series.yData || [], yValLen = yVal.length, 
                  // 0- date, 1- Detrended Price Oscillator
                  DPO = [], xData = [], yData = [], sum = 0, oscillator, periodIndex, rangeIndex, price, i, j;
                  if (xVal.length <= range) {
                      return false;
                  }
                  // Accumulate first N-points for SMA
                  for (i = 0; i < period - 1; i++) {
                      sum = accumulatePoints(sum, yVal, i, index);
                  }
                  // Detrended Price Oscillator formula:
                  // DPO = Price - Simple moving average [from (n / 2 + 1) days ago]
                  for (j = 0; j <= yValLen - range; j++) {
                      periodIndex = j + period - 1;
                      rangeIndex = j + range - 1;
                      // adding the last period point
                      sum = accumulatePoints(sum, yVal, periodIndex, index);
                      price = pick(yVal[rangeIndex][index], yVal[rangeIndex]);
                      oscillator = price - sum / period;
                      // substracting the first period point
                      sum = accumulatePoints(sum, yVal, j, index, true);
                      DPO.push([xVal[rangeIndex], oscillator]);
                      xData.push(xVal[rangeIndex]);
                      yData.push(oscillator);
                  }
                  return {
                      values: DPO,
                      xData: xData,
                      yData: yData
                  };
              }
          });
          /**
           * A Detrended Price Oscillator. If the [type](#series.dpo.type) option is not
           * specified, it is inherited from [chart.type](#chart.type).
           *
           * @extends   series,plotOptions.dpo
           * @since     7.0.0
           * @product   highstock
           * @excluding allAreas, colorAxis, compare, compareBase, dataParser, dataURL,
           *            joinBy, keys, navigatorOptions, pointInterval, pointIntervalUnit,
           *            pointPlacement, pointRange, pointStart, showInNavigator, stacking
           * @requires  stock/indicators/indicators
           * @requires  stock/indicators/dpo
           * @apioption series.dpo
           */
          ''; // to include the above in the js output'
  
      });
      _registerModule(_modules, 'indicators/ema.src.js', [_modules['parts/Globals.js'], _modules['parts/Utilities.js']], function (H, U) {
          /* *
           *
           *  License: www.highcharts.com/license
           *
           *  !!!!!!! SOURCE GETS TRANSPILED BY TYPESCRIPT. EDIT TS FILE ONLY. !!!!!!!
           *
           * */
          var isArray = U.isArray;
          var seriesType = H.seriesType, correctFloat = H.correctFloat;
          /**
           * The EMA series type.
           *
           * @private
           * @class
           * @name Highcharts.seriesTypes.ema
           *
           * @augments Highcharts.Series
           */
          seriesType('ema', 'sma', 
          /**
           * Exponential moving average indicator (EMA). This series requires the
           * `linkedTo` option to be set.
           *
           * @sample stock/indicators/ema
           *         Exponential moving average indicator
           *
           * @extends      plotOptions.sma
           * @since        6.0.0
           * @product      highstock
           * @requires     stock/indicators/indicators
           * @requires     stock/indicators/ema
           * @optionparent plotOptions.ema
           */
          {
              params: {
                  /**
                   * The point index which indicator calculations will base. For
                   * example using OHLC data, index=2 means the indicator will be
                   * calculated using Low values.
                   *
                   * By default index value used to be set to 0. Since Highstock 7
                   * by default index is set to 3 which means that the ema
                   * indicator will be calculated using Close values.
                   */
                  index: 3,
                  period: 9 // @merge 14 in v6.2
              }
          }, 
          /**
           * @lends Highcharts.Series#
           */
          {
              accumulatePeriodPoints: function (period, index, yVal) {
                  var sum = 0, i = 0, y = 0;
                  while (i < period) {
                      y = index < 0 ? yVal[i] : yVal[i][index];
                      sum = sum + y;
                      i++;
                  }
                  return sum;
              },
              calculateEma: function (xVal, yVal, i, EMApercent, calEMA, index, SMA) {
                  var x = xVal[i - 1], yValue = index < 0 ?
                      yVal[i - 1] :
                      yVal[i - 1][index], y;
                  y = calEMA === undefined ?
                      SMA : correctFloat((yValue * EMApercent) +
                      (calEMA * (1 - EMApercent)));
                  return [x, y];
              },
              getValues: function (series, params) {
                  var period = params.period, xVal = series.xData, yVal = series.yData, yValLen = yVal ? yVal.length : 0, EMApercent = 2 / (period + 1), sum = 0, EMA = [], xData = [], yData = [], index = -1, SMA = 0, calEMA, EMAPoint, i;
                  // Check period, if bigger than points length, skip
                  if (yValLen < period) {
                      return false;
                  }
                  // Switch index for OHLC / Candlestick / Arearange
                  if (isArray(yVal[0])) {
                      index = params.index ? params.index : 0;
                  }
                  // Accumulate first N-points
                  sum = this.accumulatePeriodPoints(period, index, yVal);
                  // first point
                  SMA = sum / period;
                  // Calculate value one-by-one for each period in visible data
                  for (i = period; i < yValLen + 1; i++) {
                      EMAPoint = this.calculateEma(xVal, yVal, i, EMApercent, calEMA, index, SMA);
                      EMA.push(EMAPoint);
                      xData.push(EMAPoint[0]);
                      yData.push(EMAPoint[1]);
                      calEMA = EMAPoint[1];
                  }
                  return {
                      values: EMA,
                      xData: xData,
                      yData: yData
                  };
              }
          });
          /**
           * A `EMA` series. If the [type](#series.ema.type) option is not
           * specified, it is inherited from [chart.type](#chart.type).
           *
           * @extends   series,plotOptions.ema
           * @since     6.0.0
           * @product   highstock
           * @excluding dataParser, dataURL
           * @requires  stock/indicators/indicators
           * @requires  stock/indicators/ema
           * @apioption series.ema
           */
          ''; // adds doclet above to the transpiled file
  
      });
      _registerModule(_modules, 'indicators/chaikin.src.js', [_modules['parts/Globals.js'], _modules['mixins/indicator-required.js']], function (H, requiredIndicatorMixin) {
          /* *
           *
           *  License: www.highcharts.com/license
           *
           *  !!!!!!! SOURCE GETS TRANSPILED BY TYPESCRIPT. EDIT TS FILE ONLY. !!!!!!!
           *
           * */
          var EMA = H.seriesTypes.ema, AD = H.seriesTypes.ad, error = H.error, correctFloat = H.correctFloat, requiredIndicator = requiredIndicatorMixin;
          /**
           * The Chaikin series type.
           *
           * @private
           * @class
           * @name Highcharts.seriesTypes.chaikin
           *
           * @augments Highcharts.Series
           */
          H.seriesType('chaikin', 'ema', 
          /**
           * Chaikin Oscillator. This series requires the `linkedTo` option to
           * be set and should be loaded after the `stock/indicators/indicators.js`
           * and `stock/indicators/ema.js`.
           *
           * @sample {highstock} stock/indicators/chaikin
           *         Chaikin Oscillator
           *
           * @extends      plotOptions.ema
           * @since        7.0.0
           * @product      highstock
           * @excluding    allAreas, colorAxis, joinBy, keys, navigatorOptions,
           *               pointInterval, pointIntervalUnit, pointPlacement,
           *               pointRange, pointStart, showInNavigator, stacking
           * @requires     stock/indicators/indicators
           * @requires     stock/indicators/ema
           * @requires     stock/indicators/chaikin
           * @optionparent plotOptions.chaikin
           */
          {
              /**
               * Paramters used in calculation of Chaikin Oscillator
               * series points.
               *
               * @excluding index, period
               */
              params: {
                  /**
                   * The id of volume series which is mandatory.
                   * For example using OHLC data, volumeSeriesID='volume' means
                   * the indicator will be calculated using OHLC and volume values.
                   */
                  volumeSeriesID: 'volume',
                  /**
                   * Periods for Chaikin Oscillator calculations.
                   *
                   * @type    {Array<number>}
                   * @default [3, 10]
                   */
                  periods: [3, 10]
              }
          }, 
          /**
           * @lends Highcharts.Series#
           */
          {
              nameBase: 'Chaikin Osc',
              nameComponents: ['periods'],
              init: function () {
                  var args = arguments, ctx = this;
                  requiredIndicator.isParentLoaded(EMA, 'ema', ctx.type, function (indicator) {
                      indicator.prototype.init.apply(ctx, args);
                      return;
                  });
              },
              getValues: function (series, params) {
                  var periods = params.periods, period = params.period, 
                  // Accumulation Distribution Line data
                  ADL, 
                  // 0- date, 1- Chaikin Oscillator
                  CHA = [], xData = [], yData = [], periodsOffset, 
                  // Shorter Period EMA
                  SPE, 
                  // Longer Period EMA
                  LPE, oscillator, i;
                  // Check if periods are correct
                  if (periods.length !== 2 || periods[1] <= periods[0]) {
                      error('Error: "Chaikin requires two periods. Notice, first ' +
                          'period should be lower than the second one."');
                      return false;
                  }
                  ADL = AD.prototype.getValues.call(this, series, {
                      volumeSeriesID: params.volumeSeriesID,
                      period: period
                  });
                  // Check if adl is calculated properly, if not skip
                  if (!ADL) {
                      return false;
                  }
                  SPE = EMA.prototype.getValues.call(this, ADL, {
                      period: periods[0]
                  });
                  LPE = EMA.prototype.getValues.call(this, ADL, {
                      period: periods[1]
                  });
                  // Check if ema is calculated properly, if not skip
                  if (!SPE || !LPE) {
                      return false;
                  }
                  periodsOffset = periods[1] - periods[0];
                  for (i = 0; i < LPE.yData.length; i++) {
                      oscillator = correctFloat(SPE.yData[i + periodsOffset] -
                          LPE.yData[i]);
                      CHA.push([LPE.xData[i], oscillator]);
                      xData.push(LPE.xData[i]);
                      yData.push(oscillator);
                  }
                  return {
                      values: CHA,
                      xData: xData,
                      yData: yData
                  };
              }
          });
          /**
           * A `Chaikin Oscillator` series. If the [type](#series.chaikin.type)
           * option is not specified, it is inherited from [chart.type](#chart.type).
           *
           * @extends   series,plotOptions.chaikin
           * @since     7.0.0
           * @product   highstock
           * @excluding allAreas, colorAxis, dataParser, dataURL, joinBy, keys,
           *            navigatorOptions, pointInterval, pointIntervalUnit,
           *            pointPlacement, pointRange, pointStart, stacking, showInNavigator
           * @requires  stock/indicators/indicators
           * @requires  stock/indicators/ema
           * @requires  stock/indicators/chaikin
           * @apioption series.chaikin
           */
          ''; // to include the above in the js output
  
      });
      _registerModule(_modules, 'indicators/dema.src.js', [_modules['parts/Globals.js'], _modules['parts/Utilities.js'], _modules['mixins/indicator-required.js']], function (H, U, requiredIndicatorMixin) {
          /* *
           *
           *  License: www.highcharts.com/license
           *
           *  !!!!!!! SOURCE GETS TRANSPILED BY TYPESCRIPT. EDIT TS FILE ONLY. !!!!!!!
           *
           * */
          var isArray = U.isArray;
          var EMAindicator = H.seriesTypes.ema, requiredIndicator = requiredIndicatorMixin, correctFloat = H.correctFloat;
          /**
           * The DEMA series Type
           *
           * @private
           * @class
           * @name Highcharts.seriesTypes.dema
           *
           * @augments Highcharts.Series
           */
          H.seriesType('dema', 'ema', 
          /**
           * Double exponential moving average (DEMA) indicator. This series requires
           * `linkedTo` option to be set and should be loaded after the
           * `stock/indicators/indicators.js` and `stock/indicators/ema.js`.
           *
           * @sample {highstock} stock/indicators/dema
           *         DEMA indicator
           *
           * @extends      plotOptions.ema
           * @since        7.0.0
           * @product      highstock
           * @excluding    allAreas, colorAxis, compare, compareBase, joinBy, keys,
           *               navigatorOptions, pointInterval, pointIntervalUnit,
           *               pointPlacement, pointRange, pointStart, showInNavigator,
           *               stacking
           * @requires     stock/indicators/indicators
           * @requires     stock/indicators/ema
           * @requires     stock/indicators/dema
           * @optionparent plotOptions.dema
           */
          {}, 
          /**
           * @lends Highcharts.Series#
           */
          {
              init: function () {
                  var args = arguments, ctx = this;
                  requiredIndicator.isParentLoaded(EMAindicator, 'ema', ctx.type, function (indicator) {
                      indicator.prototype.init.apply(ctx, args);
                      return;
                  });
              },
              getEMA: function (yVal, prevEMA, SMA, index, i, xVal) {
                  return EMAindicator.prototype.calculateEma(xVal || [], yVal, i === undefined ? 1 : i, this.chart.series[0].EMApercent, prevEMA, index === undefined ? -1 : index, SMA);
              },
              getValues: function (series, params) {
                  var period = params.period, doubledPeriod = 2 * period, xVal = series.xData, yVal = series.yData, yValLen = yVal ? yVal.length : 0, index = -1, accumulatePeriodPoints = 0, SMA = 0, DEMA = [], xDataDema = [], yDataDema = [], EMA = 0, 
                  // EMA(EMA)
                  EMAlevel2, 
                  // EMA of previous point
                  prevEMA, prevEMAlevel2, 
                  // EMA values array
                  EMAvalues = [], i, DEMAPoint;
                  series.EMApercent = (2 / (period + 1));
                  // Check period, if bigger than EMA points length, skip
                  if (yValLen < 2 * period - 1) {
                      return false;
                  }
                  // Switch index for OHLC / Candlestick / Arearange
                  if (isArray(yVal[0])) {
                      index = params.index ? params.index : 0;
                  }
                  // Accumulate first N-points
                  accumulatePeriodPoints =
                      EMAindicator.prototype.accumulatePeriodPoints(period, index, yVal);
                  // first point
                  SMA = accumulatePeriodPoints / period;
                  accumulatePeriodPoints = 0;
                  // Calculate value one-by-one for each period in visible data
                  for (i = period; i < yValLen + 2; i++) {
                      if (i < yValLen + 1) {
                          EMA = this.getEMA(yVal, prevEMA, SMA, index, i)[1];
                          EMAvalues.push(EMA);
                      }
                      prevEMA = EMA;
                      // Summing first period points for EMA(EMA)
                      if (i < doubledPeriod) {
                          accumulatePeriodPoints += EMA;
                      }
                      else {
                          // Calculate DEMA
                          // First DEMA point
                          if (i === doubledPeriod) {
                              SMA = accumulatePeriodPoints / period;
                          }
                          EMA = EMAvalues[i - period - 1];
                          EMAlevel2 = this.getEMA([EMA], prevEMAlevel2, SMA)[1];
                          DEMAPoint = [
                              xVal[i - 2],
                              correctFloat(2 * EMA - EMAlevel2)
                          ];
                          DEMA.push(DEMAPoint);
                          xDataDema.push(DEMAPoint[0]);
                          yDataDema.push(DEMAPoint[1]);
                          prevEMAlevel2 = EMAlevel2;
                      }
                  }
                  return {
                      values: DEMA,
                      xData: xDataDema,
                      yData: yDataDema
                  };
              }
          });
          /**
           * A `DEMA` series. If the [type](#series.ema.type) option is not
           * specified, it is inherited from [chart.type](#chart.type).
           *
           * @extends   series,plotOptions.ema
           * @since     7.0.0
           * @product   highstock
           * @excluding allAreas, colorAxis, compare, compareBase, dataParser, dataURL,
           *            joinBy, keys, navigatorOptions, pointInterval, pointIntervalUnit,
           *            pointPlacement, pointRange, pointStart, showInNavigator, stacking
           * @requires  stock/indicators/indicators
           * @requires  stock/indicators/ema
           * @requires  stock/indicators/dema
           * @apioption series.dema
           */
          ''; // adds doclet above to the transpiled file
  
      });
      _registerModule(_modules, 'indicators/tema.src.js', [_modules['parts/Globals.js'], _modules['parts/Utilities.js'], _modules['mixins/indicator-required.js']], function (H, U, requiredIndicatorMixin) {
          /* *
           *
           *  License: www.highcharts.com/license
           *
           *  !!!!!!! SOURCE GETS TRANSPILED BY TYPESCRIPT. EDIT TS FILE ONLY. !!!!!!!
           *
           * */
          var isArray = U.isArray;
          var EMAindicator = H.seriesTypes.ema, requiredIndicator = requiredIndicatorMixin, correctFloat = H.correctFloat;
          /**
           * The TEMA series type.
           *
           * @private
           * @class
           * @name Highcharts.seriesTypes.tema
           *
           * @augments Highcharts.Series
           */
          H.seriesType('tema', 'ema', 
          /**
           * Triple exponential moving average (TEMA) indicator. This series requires
           * `linkedTo` option to be set and should be loaded after the
           * `stock/indicators/indicators.js` and `stock/indicators/ema.js`.
           *
           * @sample {highstock} stock/indicators/tema
           *         TEMA indicator
           *
           * @extends      plotOptions.ema
           * @since        7.0.0
           * @product      highstock
           * @excluding    allAreas, colorAxis, compare, compareBase, joinBy, keys,
           *               navigatorOptions, pointInterval, pointIntervalUnit,
           *               pointPlacement, pointRange, pointStart, showInNavigator,
           *               stacking
           * @requires     stock/indicators/indicators
           * @requires     stock/indicators/ema
           * @requires     stock/indicators/tema
           * @optionparent plotOptions.tema
           */
          {}, 
          /**
           * @lends Highcharts.Series#
           */
          {
              init: function () {
                  var args = arguments, ctx = this;
                  requiredIndicator.isParentLoaded(EMAindicator, 'ema', ctx.type, function (indicator) {
                      indicator.prototype.init.apply(ctx, args);
                      return;
                  });
              },
              getEMA: function (yVal, prevEMA, SMA, index, i, xVal) {
                  return EMAindicator.prototype.calculateEma(xVal || [], yVal, i === undefined ? 1 : i, this.chart.series[0].EMApercent, prevEMA, index === undefined ? -1 : index, SMA);
              },
              getTemaPoint: function (xVal, tripledPeriod, EMAlevels, i) {
                  var TEMAPoint = [
                      xVal[i - 3],
                      correctFloat(3 * EMAlevels.level1 -
                          3 * EMAlevels.level2 + EMAlevels.level3)
                  ];
                  return TEMAPoint;
              },
              getValues: function (series, params) {
                  var period = params.period, doubledPeriod = 2 * period, tripledPeriod = 3 * period, xVal = series.xData, yVal = series.yData, yValLen = yVal ? yVal.length : 0, index = -1, accumulatePeriodPoints = 0, SMA = 0, TEMA = [], xDataTema = [], yDataTema = [], 
                  // EMA of previous point
                  prevEMA, prevEMAlevel2, 
                  // EMA values array
                  EMAvalues = [], EMAlevel2values = [], i, TEMAPoint, 
                  // This object contains all EMA EMAlevels calculated like below
                  // EMA = level1
                  // EMA(EMA) = level2,
                  // EMA(EMA(EMA)) = level3,
                  EMAlevels = {};
                  series.EMApercent = (2 / (period + 1));
                  // Check period, if bigger than EMA points length, skip
                  if (yValLen < 3 * period - 2) {
                      return false;
                  }
                  // Switch index for OHLC / Candlestick / Arearange
                  if (isArray(yVal[0])) {
                      index = params.index ? params.index : 0;
                  }
                  // Accumulate first N-points
                  accumulatePeriodPoints =
                      EMAindicator.prototype.accumulatePeriodPoints(period, index, yVal);
                  // first point
                  SMA = accumulatePeriodPoints / period;
                  accumulatePeriodPoints = 0;
                  // Calculate value one-by-one for each period in visible data
                  for (i = period; i < yValLen + 3; i++) {
                      if (i < yValLen + 1) {
                          EMAlevels.level1 = this.getEMA(yVal, prevEMA, SMA, index, i)[1];
                          EMAvalues.push(EMAlevels.level1);
                      }
                      prevEMA = EMAlevels.level1;
                      // Summing first period points for ema(ema)
                      if (i < doubledPeriod) {
                          accumulatePeriodPoints += EMAlevels.level1;
                      }
                      else {
                          // Calculate dema
                          // First dema point
                          if (i === doubledPeriod) {
                              SMA = accumulatePeriodPoints / period;
                              accumulatePeriodPoints = 0;
                          }
                          EMAlevels.level1 = EMAvalues[i - period - 1];
                          EMAlevels.level2 = this.getEMA([EMAlevels.level1], prevEMAlevel2, SMA)[1];
                          EMAlevel2values.push(EMAlevels.level2);
                          prevEMAlevel2 = EMAlevels.level2;
                          // Summing first period points for ema(ema(ema))
                          if (i < tripledPeriod) {
                              accumulatePeriodPoints += EMAlevels.level2;
                          }
                          else {
                              // Calculate tema
                              // First tema point
                              if (i === tripledPeriod) {
                                  SMA = accumulatePeriodPoints / period;
                              }
                              if (i === yValLen + 1) {
                                  // Calculate the last ema and emaEMA points
                                  EMAlevels.level1 = EMAvalues[i - period - 1];
                                  EMAlevels.level2 = this.getEMA([EMAlevels.level1], prevEMAlevel2, SMA)[1];
                                  EMAlevel2values.push(EMAlevels.level2);
                              }
                              EMAlevels.level1 = EMAvalues[i - period - 2];
                              EMAlevels.level2 = EMAlevel2values[i - 2 * period - 1];
                              EMAlevels.level3 = this.getEMA([EMAlevels.level2], EMAlevels.prevLevel3, SMA)[1];
                              TEMAPoint = this.getTemaPoint(xVal, tripledPeriod, EMAlevels, i);
                              // Make sure that point exists (for TRIX oscillator)
                              if (TEMAPoint) {
                                  TEMA.push(TEMAPoint);
                                  xDataTema.push(TEMAPoint[0]);
                                  yDataTema.push(TEMAPoint[1]);
                              }
                              EMAlevels.prevLevel3 = EMAlevels.level3;
                          }
                      }
                  }
                  return {
                      values: TEMA,
                      xData: xDataTema,
                      yData: yDataTema
                  };
              }
          });
          /**
           * A `TEMA` series. If the [type](#series.ema.type) option is not
           * specified, it is inherited from [chart.type](#chart.type).
           *
           * @extends   series,plotOptions.ema
           * @since     7.0.0
           * @product   highstock
           * @excluding allAreas, colorAxis, compare, compareBase, dataParser, dataURL,
           *            joinBy, keys, navigatorOptions, pointInterval, pointIntervalUnit,
           *            pointPlacement, pointRange, pointStart, showInNavigator, stacking
           * @requires  stock/indicators/indicators
           * @requires  stock/indicators/ema
           * @requires  stock/indicators/tema
           * @apioption series.tema
           */
          ''; // to include the above in the js output
  
      });
      _registerModule(_modules, 'indicators/trix.src.js', [_modules['parts/Globals.js'], _modules['mixins/indicator-required.js']], function (H, requiredIndicator) {
          /* *
           *
           *  License: www.highcharts.com/license
           *
           *  !!!!!!! SOURCE GETS TRANSPILED BY TYPESCRIPT. EDIT TS FILE ONLY. !!!!!!!
           *
           * */
          var correctFloat = H.correctFloat, TEMA = H.seriesTypes.tema;
          /**
           * The TRIX series type.
           *
           * @private
           * @class
           * @name Highcharts.seriesTypes.trix
           *
           * @augments Highcharts.Series
           */
          H.seriesType('trix', 'tema', 
          /**
           * Triple exponential average (TRIX) oscillator. This series requires
           * `linkedTo` option to be set.
           *
           * Requires https://code.highcharts.com/stock/indicators/ema.js
           * and https://code.highcharts.com/stock/indicators/tema.js.
           *
           * @sample {highstock} stock/indicators/trix
           *         TRIX indicator
           *
           * @extends      plotOptions.tema
           * @since        7.0.0
           * @product      highstock
           * @excluding    allAreas, colorAxis, compare, compareBase, joinBy, keys,
           *               navigatorOptions, pointInterval, pointIntervalUnit,
           *               pointPlacement, pointRange, pointStart, showInNavigator,
           *               stacking
           * @optionparent plotOptions.trix
           */
          {}, 
          /**
           * @lends Highcharts.Series#
           */
          {
              init: function () {
                  var args = arguments, ctx = this;
                  requiredIndicator.isParentLoaded(TEMA, 'tema', ctx.type, function (indicator) {
                      indicator.prototype.init.apply(ctx, args);
                      return;
                  });
              },
              // TRIX is calculated using TEMA so we just extend getTemaPoint method.
              getTemaPoint: function (xVal, tripledPeriod, EMAlevels, i) {
                  if (i > tripledPeriod) {
                      var TRIXPoint = [
                          xVal[i - 3],
                          EMAlevels.prevLevel3 !== 0 ?
                              correctFloat(EMAlevels.level3 - EMAlevels.prevLevel3) /
                                  EMAlevels.prevLevel3 * 100 : null
                      ];
                  }
                  return TRIXPoint;
              }
          });
          /**
           * A `TRIX` series. If the [type](#series.tema.type) option is not specified, it
           * is inherited from [chart.type](#chart.type).
           *
           * @extends   series,plotOptions.tema
           * @since     7.0.0
           * @product   highstock
           * @excluding allAreas, colorAxis, compare, compareBase, dataParser, dataURL,
           *            joinBy, keys, navigatorOptions, pointInterval, pointIntervalUnit,
           *            pointPlacement, pointRange, pointStart, showInNavigator, stacking
           * @apioption series.trix
           */
          ''; // to include the above in the js output
  
      });
      _registerModule(_modules, 'indicators/apo.src.js', [_modules['parts/Globals.js'], _modules['mixins/indicator-required.js']], function (H, requiredIndicatorMixin) {
          /* *
           *
           *  License: www.highcharts.com/license
           *
           *  !!!!!!! SOURCE GETS TRANSPILED BY TYPESCRIPT. EDIT TS FILE ONLY. !!!!!!!
           *
           * */
          var EMA = H.seriesTypes.ema, error = H.error, requiredIndicator = requiredIndicatorMixin;
          /**
           * The APO series type.
           *
           * @private
           * @class
           * @name Highcharts.seriesTypes.apo
           *
           * @augments Highcharts.Series
           */
          H.seriesType('apo', 'ema', 
          /**
           * Absolute Price Oscillator. This series requires the `linkedTo` option to
           * be set and should be loaded after the `stock/indicators/indicators.js`
           * and `stock/indicators/ema.js`.
           *
           * @sample {highstock} stock/indicators/apo
           *         Absolute Price Oscillator
           *
           * @extends      plotOptions.ema
           * @since        7.0.0
           * @product      highstock
           * @excluding    allAreas, colorAxis, joinBy, keys, navigatorOptions,
           *               pointInterval, pointIntervalUnit, pointPlacement,
           *               pointRange, pointStart, showInNavigator, stacking
           * @requires     stock/indicators/indicators
           * @requires     stock/indicators/ema
           * @requires     stock/indicators/apo
           * @optionparent plotOptions.apo
           */
          {
              /**
               * Paramters used in calculation of Absolute Price Oscillator
               * series points.
               *
               * @excluding period
               */
              params: {
                  /**
                   * Periods for Absolute Price Oscillator calculations.
                   *
                   * @type    {Array<number>}
                   * @default [10, 20]
                   * @since   7.0.0
                   */
                  periods: [10, 20]
              }
          }, 
          /**
           * @lends Highcharts.Series.prototype
           */
          {
              nameBase: 'APO',
              nameComponents: ['periods'],
              init: function () {
                  var args = arguments, ctx = this;
                  requiredIndicator.isParentLoaded(EMA, 'ema', ctx.type, function (indicator) {
                      indicator.prototype.init.apply(ctx, args);
                      return;
                  });
              },
              getValues: function (series, params) {
                  var periods = params.periods, index = params.index, 
                  // 0- date, 1- Absolute price oscillator
                  APO = [], xData = [], yData = [], periodsOffset, 
                  // Shorter Period EMA
                  SPE, 
                  // Longer Period EMA
                  LPE, oscillator, i;
                  // Check if periods are correct
                  if (periods.length !== 2 || periods[1] <= periods[0]) {
                      error('Error: "APO requires two periods. Notice, first period ' +
                          'should be lower than the second one."');
                      return false;
                  }
                  SPE = EMA.prototype.getValues.call(this, series, {
                      index: index,
                      period: periods[0]
                  });
                  LPE = EMA.prototype.getValues.call(this, series, {
                      index: index,
                      period: periods[1]
                  });
                  // Check if ema is calculated properly, if not skip
                  if (!SPE || !LPE) {
                      return false;
                  }
                  periodsOffset = periods[1] - periods[0];
                  for (i = 0; i < LPE.yData.length; i++) {
                      oscillator = (SPE.yData[i + periodsOffset] -
                          LPE.yData[i]);
                      APO.push([LPE.xData[i], oscillator]);
                      xData.push(LPE.xData[i]);
                      yData.push(oscillator);
                  }
                  return {
                      values: APO,
                      xData: xData,
                      yData: yData
                  };
              }
          });
          /**
           * An `Absolute Price Oscillator` series. If the [type](#series.apo.type) option
           * is not specified, it is inherited from [chart.type](#chart.type).
           *
           * @extends   series,plotOptions.apo
           * @since     7.0.0
           * @product   highstock
           * @excluding allAreas, colorAxis, dataParser, dataURL, joinBy, keys,
           *            navigatorOptions, pointInterval, pointIntervalUnit,
           *            pointPlacement, pointRange, pointStart, showInNavigator, stacking
           * @requires  stock/indicators/indicators
           * @requires  stock/indicators/ema
           * @requires  stock/indicators/apo
           * @apioption series.apo
           */
          ''; // to include the above in the js output
  
      });
      _registerModule(_modules, 'indicators/ichimoku-kinko-hyo.src.js', [_modules['parts/Globals.js'], _modules['parts/Utilities.js']], function (H, U) {
          /* *
           *
           *  License: www.highcharts.com/license
           *
           *  !!!!!!! SOURCE GETS TRANSPILED BY TYPESCRIPT. EDIT TS FILE ONLY. !!!!!!!
           *
           * */
          /* eslint-enable @typescript-eslint/interface-name-prefix */
          var defined = U.defined, isArray = U.isArray, objectEach = U.objectEach;
          var UNDEFINED, seriesType = H.seriesType, merge = H.merge, color = H.color, SMA = H.seriesTypes.sma;
          /* eslint-disable require-jsdoc */
          // Utils:
          function maxHigh(arr) {
              return arr.reduce(function (max, res) {
                  return Math.max(max, res[1]);
              }, -Infinity);
          }
          function minLow(arr) {
              return arr.reduce(function (min, res) {
                  return Math.min(min, res[2]);
              }, Infinity);
          }
          function highlowLevel(arr) {
              return {
                  high: maxHigh(arr),
                  low: minLow(arr)
              };
          }
          function getClosestPointRange(axis) {
              var closestDataRange, loopLength, distance, xData, i;
              axis.series.forEach(function (series) {
                  if (series.xData) {
                      xData = series.xData;
                      loopLength = series.xIncrement ? 1 : xData.length - 1;
                      for (i = loopLength; i > 0; i--) {
                          distance = xData[i] - xData[i - 1];
                          if (closestDataRange === UNDEFINED ||
                              distance < closestDataRange) {
                              closestDataRange = distance;
                          }
                      }
                  }
              });
              return closestDataRange;
          }
          // Check two lines intersection (line a1-a2 and b1-b2)
          // Source: https://en.wikipedia.org/wiki/Line%E2%80%93line_intersection
          function checkLineIntersection(a1, a2, b1, b2) {
              if (a1 && a2 && b1 && b2) {
                  var saX = a2.plotX - a1.plotX, // Auxiliary section a2-a1 X
                  saY = a2.plotY - a1.plotY, // Auxiliary section a2-a1 Y
                  sbX = b2.plotX - b1.plotX, // Auxiliary section b2-b1 X
                  sbY = b2.plotY - b1.plotY, // Auxiliary section b2-b1 Y
                  sabX = a1.plotX - b1.plotX, // Auxiliary section a1-b1 X
                  sabY = a1.plotY - b1.plotY, // Auxiliary section a1-b1 Y
                  // First degree Bézier parameters
                  u, t;
                  u = (-saY * sabX + saX * sabY) / (-sbX * saY + saX * sbY);
                  t = (sbX * sabY - sbY * sabX) / (-sbX * saY + saX * sbY);
                  if (u >= 0 && u <= 1 && t >= 0 && t <= 1) {
                      return {
                          plotX: a1.plotX + (t * saX),
                          plotY: a1.plotY + (t * saY)
                      };
                  }
              }
              return false;
          }
          // Parameter opt (indicator options object) include indicator, points,
          // nextPoints, color, options, gappedExtend and graph properties
          function drawSenkouSpan(opt) {
              var indicator = opt.indicator;
              indicator.points = opt.points;
              indicator.nextPoints = opt.nextPoints;
              indicator.color = opt.color;
              indicator.options = merge(opt.options.senkouSpan.styles, opt.gap);
              indicator.graph = opt.graph;
              indicator.fillGraph = true;
              SMA.prototype.drawGraph.call(indicator);
          }
          // Data integrity in Ichimoku is different than default "averages":
          // Point: [undefined, value, value, ...] is correct
          // Point: [undefined, undefined, undefined, ...] is incorrect
          H.approximations['ichimoku-averages'] = function () {
              var ret = [], isEmptyRange;
              [].forEach.call(arguments, function (arr, i) {
                  ret.push(H.approximations.average(arr));
                  isEmptyRange = !isEmptyRange && ret[i] === undefined;
              });
              // Return undefined when first elem. is undefined and let
              // sum method handle null (#7377)
              return isEmptyRange ? undefined : ret;
          };
          /* eslint-enable require-jsdoc */
          /**
           * The IKH series type.
           *
           * @private
           * @class
           * @name Highcharts.seriesTypes.ikh
           *
           * @augments Highcharts.Series
           */
          seriesType('ikh', 'sma', 
          /**
           * Ichimoku Kinko Hyo (IKH). This series requires `linkedTo` option to be
           * set.
           *
           * @sample stock/indicators/ichimoku-kinko-hyo
           *         Ichimoku Kinko Hyo indicator
           *
           * @extends      plotOptions.sma
           * @since        6.0.0
           * @excluding    allAreas, colorAxis, compare, compareBase, joinBy, keys,
           *               navigatorOptions, pointInterval, pointIntervalUnit,
           *               pointPlacement, pointRange, pointStart, showInNavigator,
           *               stacking
           * @product      highstock
           * @requires     stock/indicators/indicators
           * @requires     stock/indicators/ichimoku-kinko-hyo
           * @optionparent plotOptions.ikh
           */
          {
              params: {
                  period: 26,
                  /**
                   * The base period for Tenkan calculations.
                   */
                  periodTenkan: 9,
                  /**
                   * The base period for Senkou Span B calculations
                   */
                  periodSenkouSpanB: 52
              },
              marker: {
                  enabled: false
              },
              tooltip: {
                  pointFormat: '<span style="color:{point.color}">\u25CF</span> <b> {series.name}</b><br/>' +
                      'TENKAN SEN: {point.tenkanSen:.3f}<br/>' +
                      'KIJUN SEN: {point.kijunSen:.3f}<br/>' +
                      'CHIKOU SPAN: {point.chikouSpan:.3f}<br/>' +
                      'SENKOU SPAN A: {point.senkouSpanA:.3f}<br/>' +
                      'SENKOU SPAN B: {point.senkouSpanB:.3f}<br/>'
              },
              /**
               * The styles for Tenkan line
               */
              tenkanLine: {
                  styles: {
                      /**
                       * Pixel width of the line.
                       */
                      lineWidth: 1,
                      /**
                       * Color of the line.
                       *
                       * @type {Highcharts.ColorString}
                       */
                      lineColor: undefined
                  }
              },
              /**
               * The styles for Kijun line
               */
              kijunLine: {
                  styles: {
                      /**
                       * Pixel width of the line.
                       */
                      lineWidth: 1,
                      /**
                       * Color of the line.
                       *
                       * @type {Highcharts.ColorString}
                       */
                      lineColor: undefined
                  }
              },
              /**
               * The styles for Chikou line
               */
              chikouLine: {
                  styles: {
                      /**
                       * Pixel width of the line.
                       */
                      lineWidth: 1,
                      /**
                       * Color of the line.
                       *
                       * @type {Highcharts.ColorString}
                       */
                      lineColor: undefined
                  }
              },
              /**
               * The styles for Senkou Span A line
               */
              senkouSpanA: {
                  styles: {
                      /**
                       * Pixel width of the line.
                       */
                      lineWidth: 1,
                      /**
                       * Color of the line.
                       *
                       * @type {Highcharts.ColorString}
                       */
                      lineColor: undefined
                  }
              },
              /**
               * The styles for Senkou Span B line
               */
              senkouSpanB: {
                  styles: {
                      /**
                       * Pixel width of the line.
                       */
                      lineWidth: 1,
                      /**
                       * Color of the line.
                       *
                       * @type {Highcharts.ColorString}
                       */
                      lineColor: undefined
                  }
              },
              /**
               * The styles for area between Senkou Span A and B.
               */
              senkouSpan: {
                  /**
                  * Color of the area between Senkou Span A and B,
                  * when Senkou Span A is above Senkou Span B. Note that if
                  * a `style.fill` is defined, the `color` takes precedence and
                  * the `style.fill` is ignored.
                  *
                  * @see [senkouSpan.styles.fill](#series.ikh.senkouSpan.styles.fill)
                  *
                  * @sample stock/indicators/ichimoku-kinko-hyo
                  *         Ichimoku Kinko Hyo color
                  *
                  * @type      {Highcharts.ColorString|Highcharts.GradientColorObject|Highcharts.PatternObject}
                  * @since     7.0.0
                  * @apioption plotOptions.ikh.senkouSpan.color
                  */
                  /**
                  * Color of the area between Senkou Span A and B,
                  * when Senkou Span A is under Senkou Span B.
                  *
                  * @sample stock/indicators/ikh-negative-color
                  *         Ichimoku Kinko Hyo negativeColor
                  *
                  * @type      {Highcharts.ColorString|Highcharts.GradientColorObject|Highcharts.PatternObject}
                  * @since     7.0.0
                  * @apioption plotOptions.ikh.senkouSpan.negativeColor
                  */
                  styles: {
                      /**
                       * Color of the area between Senkou Span A and B.
                       *
                       * @deprecated
                       * @type {Highcharts.ColorString|Highcharts.GradientColorObject|Highcharts.PatternObject}
                       */
                      fill: 'rgba(255, 0, 0, 0.5)'
                  }
              },
              dataGrouping: {
                  approximation: 'ichimoku-averages'
              }
          }, 
          /**
           * @lends Highcharts.Series#
           */
          {
              pointArrayMap: [
                  'tenkanSen',
                  'kijunSen',
                  'chikouSpan',
                  'senkouSpanA',
                  'senkouSpanB'
              ],
              pointValKey: 'tenkanSen',
              nameComponents: ['periodSenkouSpanB', 'period', 'periodTenkan'],
              init: function () {
                  SMA.prototype.init.apply(this, arguments);
                  // Set default color for lines:
                  this.options = merge({
                      tenkanLine: {
                          styles: {
                              lineColor: this.color
                          }
                      },
                      kijunLine: {
                          styles: {
                              lineColor: this.color
                          }
                      },
                      chikouLine: {
                          styles: {
                              lineColor: this.color
                          }
                      },
                      senkouSpanA: {
                          styles: {
                              lineColor: this.color,
                              fill: color(this.color).setOpacity(0.5).get()
                          }
                      },
                      senkouSpanB: {
                          styles: {
                              lineColor: this.color,
                              fill: color(this.color).setOpacity(0.5).get()
                          }
                      },
                      senkouSpan: {
                          styles: {
                              fill: color(this.color).setOpacity(0.2).get()
                          }
                      }
                  }, this.options);
              },
              toYData: function (point) {
                  return [
                      point.tenkanSen,
                      point.kijunSen,
                      point.chikouSpan,
                      point.senkouSpanA,
                      point.senkouSpanB
                  ];
              },
              translate: function () {
                  var indicator = this;
                  SMA.prototype.translate.apply(indicator);
                  indicator.points.forEach(function (point) {
                      indicator.pointArrayMap.forEach(function (value) {
                          if (defined(point[value])) {
                              point['plot' + value] =
                                  indicator.yAxis.toPixels(point[value], true);
                              // Add extra parameters for support tooltip in moved
                              // lines
                              point.plotY = point['plot' + value];
                              point.tooltipPos = [
                                  point.plotX,
                                  point['plot' + value]
                              ];
                              point.isNull = false;
                          }
                      });
                  });
              },
              // One does not simply
              // Render five linesZ
              // And an arearange
              // In just one series..
              drawGraph: function () {
                  var indicator = this, mainLinePoints = (indicator.points), pointsLength = mainLinePoints.length, mainLineOptions = (indicator.options), mainLinePath = (indicator.graph), mainColor = indicator.color, gappedExtend = {
                      options: {
                          gapSize: mainLineOptions.gapSize
                      }
                  }, pointArrayMapLength = indicator.pointArrayMap.length, allIchimokuPoints = [[], [], [], [], [], []], ikhMap = {
                      tenkanLine: allIchimokuPoints[0],
                      kijunLine: allIchimokuPoints[1],
                      chikouLine: allIchimokuPoints[2],
                      senkouSpanA: allIchimokuPoints[3],
                      senkouSpanB: allIchimokuPoints[4],
                      senkouSpan: allIchimokuPoints[5]
                  }, intersectIndexColl = [], senkouSpanOptions = indicator.options.senkouSpan, color = (senkouSpanOptions.color ||
                      senkouSpanOptions.styles.fill), negativeColor = (senkouSpanOptions.negativeColor), 
                  // Points to create color and negativeColor senkouSpan
                  points = [
                      [],
                      [] // Points negative color
                  ], 
                  // For span, we need an access to the next points, used in
                  // getGraphPath()
                  nextPoints = [
                      [],
                      [] // NextPoints negative color
                  ], lineIndex = 0, position, point, i, startIntersect, endIntersect, sectionPoints, sectionNextPoints, pointsPlotYSum, nextPointsPlotYSum, senkouSpanTempColor, concatArrIndex, j, k;
                  indicator.ikhMap = ikhMap;
                  // Generate points for all lines and spans lines:
                  while (pointsLength--) {
                      point = mainLinePoints[pointsLength];
                      for (i = 0; i < pointArrayMapLength; i++) {
                          position = indicator.pointArrayMap[i];
                          if (defined(point[position])) {
                              allIchimokuPoints[i].push({
                                  plotX: point.plotX,
                                  plotY: point['plot' + position],
                                  isNull: false
                              });
                          }
                      }
                      if (negativeColor &&
                          pointsLength !== mainLinePoints.length - 1) {
                          // Check if lines intersect
                          var index = ikhMap.senkouSpanB.length - 1, intersect = checkLineIntersection(ikhMap.senkouSpanA[index - 1], ikhMap.senkouSpanA[index], ikhMap.senkouSpanB[index - 1], ikhMap.senkouSpanB[index]), intersectPointObj = {
                              plotX: intersect.plotX,
                              plotY: intersect.plotY,
                              isNull: false,
                              intersectPoint: true
                          };
                          if (intersect) {
                              // Add intersect point to ichimoku points collection
                              // Create senkouSpan sections
                              ikhMap.senkouSpanA.splice(index, 0, intersectPointObj);
                              ikhMap.senkouSpanB.splice(index, 0, intersectPointObj);
                              intersectIndexColl.push(index);
                          }
                      }
                  }
                  // Modify options and generate lines:
                  objectEach(ikhMap, function (values, lineName) {
                      if (mainLineOptions[lineName] &&
                          lineName !== 'senkouSpan') {
                          // First line is rendered by default option
                          indicator.points = allIchimokuPoints[lineIndex];
                          indicator.options = merge(mainLineOptions[lineName].styles, gappedExtend);
                          indicator.graph = indicator['graph' + lineName];
                          indicator.fillGraph = false;
                          indicator.color = mainColor;
                          SMA.prototype.drawGraph.call(indicator);
                          // Now save line
                          indicator['graph' + lineName] = indicator.graph;
                      }
                      lineIndex++;
                  });
                  // Generate senkouSpan area:
                  // If graphColection exist then remove svg
                  // element and indicator property
                  if (indicator.graphCollection) {
                      indicator.graphCollection.forEach(function (graphName) {
                          indicator[graphName].destroy();
                          delete indicator[graphName];
                      });
                  }
                  // Clean grapCollection or initialize it
                  indicator.graphCollection = [];
                  // When user set negativeColor property
                  if (negativeColor &&
                      ikhMap.senkouSpanA[0] &&
                      ikhMap.senkouSpanB[0]) {
                      // Add first and last point to senkouSpan area sections
                      intersectIndexColl.unshift(0);
                      intersectIndexColl.push(ikhMap.senkouSpanA.length - 1);
                      // Populate points and nextPoints arrays
                      for (j = 0; j < intersectIndexColl.length - 1; j++) {
                          startIntersect = intersectIndexColl[j];
                          endIntersect = intersectIndexColl[j + 1];
                          sectionPoints = ikhMap.senkouSpanB.slice(startIntersect, endIntersect + 1);
                          sectionNextPoints = ikhMap.senkouSpanA.slice(startIntersect, endIntersect + 1);
                          // Add points to color or negativeColor arrays
                          // Check the middle point (if exist)
                          if (Math.floor(sectionPoints.length / 2) >= 1) {
                              var x = Math.floor(sectionPoints.length / 2);
                              // When middle points has equal values
                              // Compare all ponints plotY value sum
                              if (sectionPoints[x].plotY ===
                                  sectionNextPoints[x].plotY) {
                                  pointsPlotYSum = 0;
                                  nextPointsPlotYSum = 0;
                                  for (k = 0; k < sectionPoints.length; k++) {
                                      pointsPlotYSum +=
                                          sectionPoints[k].plotY;
                                      nextPointsPlotYSum +=
                                          sectionNextPoints[k].plotY;
                                  }
                                  concatArrIndex = (pointsPlotYSum > nextPointsPlotYSum ? 0 : 1);
                                  points[concatArrIndex] = (points[concatArrIndex].concat(sectionPoints));
                                  nextPoints[concatArrIndex] = (nextPoints[concatArrIndex].concat(sectionNextPoints));
                              }
                              else {
                                  // Compare middle point of the section
                                  concatArrIndex = (sectionPoints[x].plotY >
                                      sectionNextPoints[x].plotY ?
                                      0 : 1);
                                  points[concatArrIndex] = (points[concatArrIndex].concat(sectionPoints));
                                  nextPoints[concatArrIndex] = (nextPoints[concatArrIndex].concat(sectionNextPoints));
                              }
                          }
                          else {
                              // Compare first point of the section
                              concatArrIndex = (sectionPoints[0].plotY >
                                  sectionNextPoints[0].plotY ?
                                  0 : 1);
                              points[concatArrIndex] = (points[concatArrIndex].concat(sectionPoints));
                              nextPoints[concatArrIndex] = (nextPoints[concatArrIndex].concat(sectionNextPoints));
                          }
                      }
                      // Render color and negativeColor paths
                      [
                          'graphsenkouSpanColor', 'graphsenkouSpanNegativeColor'
                      ].forEach(function (areaName, i) {
                          if (points[i].length && nextPoints[i].length) {
                              senkouSpanTempColor = (i === 0) ?
                                  color : negativeColor;
                              drawSenkouSpan({
                                  indicator: indicator,
                                  points: points[i],
                                  nextPoints: nextPoints[i],
                                  color: senkouSpanTempColor,
                                  options: mainLineOptions,
                                  gap: gappedExtend,
                                  graph: indicator[areaName]
                              });
                              // Now save line
                              indicator[areaName] = indicator.graph;
                              indicator.graphCollection.push(areaName);
                          }
                      });
                  }
                  else {
                      // When user set only senkouSpan style.fill property
                      drawSenkouSpan({
                          indicator: indicator,
                          points: ikhMap.senkouSpanB,
                          nextPoints: ikhMap.senkouSpanA,
                          color: color,
                          options: mainLineOptions,
                          gap: gappedExtend,
                          graph: indicator.graphsenkouSpan
                      });
                      // Now save line
                      indicator.graphsenkouSpan = indicator.graph;
                  }
                  // Clean temporary properties:
                  delete indicator.nextPoints;
                  delete indicator.fillGraph;
                  // Restore options and draw the Tenkan line:
                  indicator.points = mainLinePoints;
                  indicator.options = mainLineOptions;
                  indicator.graph = mainLinePath;
              },
              getGraphPath: function (points) {
                  var indicator = this, path = [], spanA, fillArray = [], spanAarr = [];
                  points = points || this.points;
                  // Render Senkou Span
                  if (indicator.fillGraph && indicator.nextPoints) {
                      spanA = SMA.prototype.getGraphPath.call(indicator, 
                      // Reverse points, so Senkou Span A will start from the end:
                      indicator.nextPoints);
                      spanA[0] = 'L';
                      path = SMA.prototype.getGraphPath.call(indicator, points);
                      spanAarr = spanA.slice(0, path.length);
                      for (var i = (spanAarr.length - 1); i > 0; i -= 3) {
                          fillArray.push(spanAarr[i - 2], spanAarr[i - 1], spanAarr[i]);
                      }
                      path = path.concat(fillArray);
                  }
                  else {
                      path = SMA.prototype.getGraphPath.apply(indicator, arguments);
                  }
                  return path;
              },
              getValues: function (series, params) {
                  var period = params.period, periodTenkan = params.periodTenkan, periodSenkouSpanB = params.periodSenkouSpanB, xVal = series.xData, yVal = series.yData, xAxis = series.xAxis, yValLen = (yVal && yVal.length) || 0, closestPointRange = getClosestPointRange(xAxis), IKH = [], xData = [], dateStart, date, slicedTSY, slicedKSY, slicedSSBY, pointTS, pointKS, pointSSB, i, TS, KS, CS, SSA, SSB;
                  // Ikh requires close value
                  if (xVal.length <= period ||
                      !isArray(yVal[0]) ||
                      yVal[0].length !== 4) {
                      return false;
                  }
                  // Add timestamps at the beginning
                  dateStart = xVal[0] - (period * closestPointRange);
                  for (i = 0; i < period; i++) {
                      xData.push(dateStart + i * closestPointRange);
                  }
                  for (i = 0; i < yValLen; i++) {
                      // Tenkan Sen
                      if (i >= periodTenkan) {
                          slicedTSY = yVal.slice(i - periodTenkan, i);
                          pointTS = highlowLevel(slicedTSY);
                          TS = (pointTS.high + pointTS.low) / 2;
                      }
                      if (i >= period) {
                          slicedKSY = yVal.slice(i - period, i);
                          pointKS = highlowLevel(slicedKSY);
                          KS = (pointKS.high + pointKS.low) / 2;
                          SSA = (TS + KS) / 2;
                      }
                      if (i >= periodSenkouSpanB) {
                          slicedSSBY = yVal.slice(i - periodSenkouSpanB, i);
                          pointSSB = highlowLevel(slicedSSBY);
                          SSB = (pointSSB.high + pointSSB.low) / 2;
                      }
                      CS = yVal[i][3];
                      date = xVal[i];
                      if (IKH[i] === UNDEFINED) {
                          IKH[i] = [];
                      }
                      if (IKH[i + period] === UNDEFINED) {
                          IKH[i + period] = [];
                      }
                      IKH[i + period][0] = TS;
                      IKH[i + period][1] = KS;
                      IKH[i + period][2] = UNDEFINED;
                      IKH[i][2] = CS;
                      if (i <= period) {
                          IKH[i + period][3] = UNDEFINED;
                          IKH[i + period][4] = UNDEFINED;
                      }
                      if (IKH[i + 2 * period] === UNDEFINED) {
                          IKH[i + 2 * period] = [];
                      }
                      IKH[i + 2 * period][3] = SSA;
                      IKH[i + 2 * period][4] = SSB;
                      xData.push(date);
                  }
                  // Add timestamps for further points
                  for (i = 1; i <= period; i++) {
                      xData.push(date + i * closestPointRange);
                  }
                  return {
                      values: IKH,
                      xData: xData,
                      yData: IKH
                  };
              }
          });
          /**
           * A `IKH` series. If the [type](#series.ikh.type) option is not
           * specified, it is inherited from [chart.type](#chart.type).
           *
           * @extends   series,plotOptions.ikh
           * @since     6.0.0
           * @product   highstock
           * @excluding dataParser, dataURL
           * @requires  stock/indicators/indicators
           * @requires  stock/indicators/ichimoku-kinko-hyo
           * @apioption series.ikh
           */
          ''; // add doclet above to transpiled file
  
      });
      _registerModule(_modules, 'indicators/keltner-channels.src.js', [_modules['parts/Globals.js'], _modules['mixins/multipe-lines.js']], function (H, multipleLinesMixin) {
          /* *
           *
           *  License: www.highcharts.com/license
           *
           *  !!!!!!! SOURCE GETS TRANSPILED BY TYPESCRIPT. EDIT TS FILE ONLY. !!!!!!!
           *
           * */
          var SMA = H.seriesTypes.sma, EMA = H.seriesTypes.ema, ATR = H.seriesTypes.atr, merge = H.merge, correctFloat = H.correctFloat;
          /**
           * The Keltner Channels series type.
           *
           * @private
           * @class
           * @name Highcharts.seriesTypes.keltnerchannels
           *
           * @augments Highcharts.Series
           */
          H.seriesType('keltnerchannels', 'sma', 
          /**
           * Keltner Channels. This series requires the `linkedTo` option to be set
           * and should be loaded after the `stock/indicators/indicators.js`,
           * `stock/indicators/atr.js`, and `stock/ema/.js`.
           *
           * @sample {highstock} stock/indicators/keltner-channels
           *         Keltner Channels
           *
           * @extends      plotOptions.sma
           * @since        7.0.0
           * @product      highstock
           * @excluding    allAreas, colorAxis, compare, compareBase, joinBy, keys,
           *               navigatorOptions, pointInterval, pointIntervalUnit,
           *               pointPlacement, pointRange, pointStart,showInNavigator,
           *               stacking
           * @requires     stock/indicators/indicators
           * @requires     stock/indicators/keltner-channels
           * @optionparent plotOptions.keltnerchannels
           */
          {
              params: {
                  period: 20,
                  /**
                   * The ATR period.
                   */
                  periodATR: 10,
                  /**
                   * The ATR multiplier.
                   */
                  multiplierATR: 2
              },
              /**
               * Bottom line options.
               *
               */
              bottomLine: {
                  /**
                   * Styles for a bottom line.
                   *
                   */
                  styles: {
                      /**
                       * Pixel width of the line.
                       */
                      lineWidth: 1,
                      /**
                       * Color of the line. If not set, it's inherited from
                       * `plotOptions.keltnerchannels.color`
                       */
                      lineColor: undefined
                  }
              },
              /**
               * Top line options.
               *
               * @extends plotOptions.keltnerchannels.bottomLine
               */
              topLine: {
                  styles: {
                      lineWidth: 1,
                      lineColor: undefined
                  }
              },
              tooltip: {
                  pointFormat: '<span style="color:{point.color}">\u25CF</span><b> {series.name}</b><br/>Upper Channel: {point.top}<br/>EMA({series.options.params.period}): {point.middle}<br/>Lower Channel: {point.bottom}<br/>'
              },
              marker: {
                  enabled: false
              },
              dataGrouping: {
                  approximation: 'averages'
              },
              lineWidth: 1
          }, 
          /**
           * @lends Highcharts.Series#
           */
          merge(multipleLinesMixin, {
              pointArrayMap: ['top', 'middle', 'bottom'],
              pointValKey: 'middle',
              nameBase: 'Keltner Channels',
              nameComponents: ['period', 'periodATR', 'multiplierATR'],
              linesApiNames: ['topLine', 'bottomLine'],
              requiredIndicators: ['ema', 'atr'],
              init: function () {
                  SMA.prototype.init.apply(this, arguments);
                  // Set default color for lines:
                  this.options = merge({
                      topLine: {
                          styles: {
                              lineColor: this.color
                          }
                      },
                      bottomLine: {
                          styles: {
                              lineColor: this.color
                          }
                      }
                  }, this.options);
              },
              getValues: function (series, params) {
                  var period = params.period, periodATR = params.periodATR, multiplierATR = params.multiplierATR, index = params.index, yVal = series.yData, yValLen = yVal ? yVal.length : 0, 
                  // Keltner Channels array structure:
                  // 0-date, 1-top line, 2-middle line, 3-bottom line
                  KC = [], 
                  // middle line, top line and bottom lineI
                  ML, TL, BL, date, seriesEMA = EMA.prototype.getValues(series, {
                      period: period,
                      index: index
                  }), seriesATR = ATR.prototype.getValues(series, {
                      period: periodATR
                  }), pointEMA, pointATR, xData = [], yData = [], i;
                  if (yValLen < period) {
                      return false;
                  }
                  for (i = period; i <= yValLen; i++) {
                      pointEMA = seriesEMA.values[i - period];
                      pointATR = seriesATR.values[i - periodATR];
                      date = pointEMA[0];
                      TL = correctFloat(pointEMA[1] + (multiplierATR * pointATR[1]));
                      BL = correctFloat(pointEMA[1] - (multiplierATR * pointATR[1]));
                      ML = pointEMA[1];
                      KC.push([date, TL, ML, BL]);
                      xData.push(date);
                      yData.push([TL, ML, BL]);
                  }
                  return {
                      values: KC,
                      xData: xData,
                      yData: yData
                  };
              }
          }));
          /**
           * A Keltner Channels indicator. If the [type](#series.keltnerchannels.type)
           * option is not specified, it is inherited from[chart.type](#chart.type).
           *
           * @extends      series,plotOptions.keltnerchannels
           * @since        7.0.0
           * @product      highstock
           * @excluding    allAreas, colorAxis, compare, compareBase, dataParser, dataURL,
           *               joinBy, keys, navigatorOptions, pointInterval,
           *               pointIntervalUnit, pointPlacement, pointRange, pointStart,
           *               stacking, showInNavigator
           * @requires     stock/indicators/indicators
           * @requires     stock/indicators/keltner-channels
           * @apioption    series.keltnerchannels
           */
          ''; // to include the above in the js output
  
      });
      _registerModule(_modules, 'indicators/macd.src.js', [_modules['parts/Globals.js'], _modules['parts/Utilities.js']], function (H, U) {
          /* *
           *
           *  License: www.highcharts.com/license
           *
           *  !!!!!!! SOURCE GETS TRANSPILED BY TYPESCRIPT. EDIT TS FILE ONLY. !!!!!!!
           *
           * */
          var defined = U.defined;
          var seriesType = H.seriesType, noop = H.noop, merge = H.merge, SMA = H.seriesTypes.sma, EMA = H.seriesTypes.ema, correctFloat = H.correctFloat;
          /**
           * The MACD series type.
           *
           * @private
           * @class
           * @name Highcharts.seriesTypes.macd
           *
           * @augments Highcharts.Series
           */
          seriesType('macd', 'sma', 
          /**
           * Moving Average Convergence Divergence (MACD). This series requires
           * `linkedTo` option to be set and should be loaded after the
           * `stock/indicators/indicators.js` and `stock/indicators/ema.js`.
           *
           * @sample stock/indicators/macd
           *         MACD indicator
           *
           * @extends      plotOptions.sma
           * @since        6.0.0
           * @product      highstock
           * @requires     stock/indicators/indicators
           * @requires     stock/indicators/macd
           * @optionparent plotOptions.macd
           */
          {
              params: {
                  /**
                   * The short period for indicator calculations.
                   */
                  shortPeriod: 12,
                  /**
                   * The long period for indicator calculations.
                   */
                  longPeriod: 26,
                  /**
                   * The base period for signal calculations.
                   */
                  signalPeriod: 9,
                  period: 26
              },
              /**
               * The styles for signal line
               */
              signalLine: {
                  /**
                   * @sample stock/indicators/macd-zones
                   *         Zones in MACD
                   *
                   * @extends plotOptions.macd.zones
                   */
                  zones: [],
                  styles: {
                      /**
                       * Pixel width of the line.
                       */
                      lineWidth: 1,
                      /**
                       * Color of the line.
                       *
                       * @type  {Highcharts.ColorString}
                       */
                      lineColor: undefined
                  }
              },
              /**
               * The styles for macd line
               */
              macdLine: {
                  /**
                   * @sample stock/indicators/macd-zones
                   *         Zones in MACD
                   *
                   * @extends plotOptions.macd.zones
                   */
                  zones: [],
                  styles: {
                      /**
                       * Pixel width of the line.
                       */
                      lineWidth: 1,
                      /**
                       * Color of the line.
                       *
                       * @type  {Highcharts.ColorString}
                       */
                      lineColor: undefined
                  }
              },
              threshold: 0,
              groupPadding: 0.1,
              pointPadding: 0.1,
              states: {
                  hover: {
                      halo: {
                          size: 0
                      }
                  }
              },
              tooltip: {
                  pointFormat: '<span style="color:{point.color}">\u25CF</span> <b> {series.name}</b><br/>' +
                      'Value: {point.MACD}<br/>' +
                      'Signal: {point.signal}<br/>' +
                      'Histogram: {point.y}<br/>'
              },
              dataGrouping: {
                  approximation: 'averages'
              },
              minPointLength: 0
          }, 
          /**
           * @lends Highcharts.Series#
           */
          {
              nameComponents: ['longPeriod', 'shortPeriod', 'signalPeriod'],
              requiredIndicators: ['ema'],
              // "y" value is treated as Histogram data
              pointArrayMap: ['y', 'signal', 'MACD'],
              parallelArrays: ['x', 'y', 'signal', 'MACD'],
              pointValKey: 'y',
              // Columns support:
              markerAttribs: noop,
              getColumnMetrics: H.seriesTypes.column.prototype.getColumnMetrics,
              crispCol: H.seriesTypes.column.prototype.crispCol,
              // Colors and lines:
              init: function () {
                  SMA.prototype.init.apply(this, arguments);
                  // Check whether series is initialized. It may be not initialized,
                  // when any of required indicators is missing.
                  if (this.options) {
                      // Set default color for a signal line and the histogram:
                      this.options = merge({
                          signalLine: {
                              styles: {
                                  lineColor: this.color
                              }
                          },
                          macdLine: {
                              styles: {
                                  color: this.color
                              }
                          }
                      }, this.options);
                      // Zones have indexes automatically calculated, we need to
                      // translate them to support multiple lines within one indicator
                      this.macdZones = {
                          zones: this.options.macdLine.zones,
                          startIndex: 0
                      };
                      this.signalZones = {
                          zones: this.macdZones.zones.concat(this.options.signalLine.zones),
                          startIndex: this.macdZones.zones.length
                      };
                      this.resetZones = true;
                  }
              },
              toYData: function (point) {
                  return [point.y, point.signal, point.MACD];
              },
              translate: function () {
                  var indicator = this, plotNames = ['plotSignal', 'plotMACD'];
                  H.seriesTypes.column.prototype.translate.apply(indicator);
                  indicator.points.forEach(function (point) {
                      [point.signal, point.MACD].forEach(function (value, i) {
                          if (value !== null) {
                              point[plotNames[i]] =
                                  indicator.yAxis.toPixels(value, true);
                          }
                      });
                  });
              },
              destroy: function () {
                  // this.graph is null due to removing two times the same SVG element
                  this.graph = null;
                  this.graphmacd = this.graphmacd && this.graphmacd.destroy();
                  this.graphsignal = this.graphsignal && this.graphsignal.destroy();
                  SMA.prototype.destroy.apply(this, arguments);
              },
              drawPoints: H.seriesTypes.column.prototype.drawPoints,
              drawGraph: function () {
                  var indicator = this, mainLinePoints = indicator.points, pointsLength = mainLinePoints.length, mainLineOptions = indicator.options, histogramZones = indicator.zones, gappedExtend = {
                      options: {
                          gapSize: mainLineOptions.gapSize
                      }
                  }, otherSignals = [[], []], point;
                  // Generate points for top and bottom lines:
                  while (pointsLength--) {
                      point = mainLinePoints[pointsLength];
                      if (defined(point.plotMACD)) {
                          otherSignals[0].push({
                              plotX: point.plotX,
                              plotY: point.plotMACD,
                              isNull: !defined(point.plotMACD)
                          });
                      }
                      if (defined(point.plotSignal)) {
                          otherSignals[1].push({
                              plotX: point.plotX,
                              plotY: point.plotSignal,
                              isNull: !defined(point.plotMACD)
                          });
                      }
                  }
                  // Modify options and generate smoothing line:
                  ['macd', 'signal'].forEach(function (lineName, i) {
                      indicator.points = otherSignals[i];
                      indicator.options = merge(mainLineOptions[lineName + 'Line'].styles, gappedExtend);
                      indicator.graph = indicator['graph' + lineName];
                      // Zones extension:
                      indicator.currentLineZone = lineName + 'Zones';
                      indicator.zones =
                          indicator[indicator.currentLineZone].zones;
                      SMA.prototype.drawGraph.call(indicator);
                      indicator['graph' + lineName] = indicator.graph;
                  });
                  // Restore options:
                  indicator.points = mainLinePoints;
                  indicator.options = mainLineOptions;
                  indicator.zones = histogramZones;
                  indicator.currentLineZone = null;
                  // indicator.graph = null;
              },
              getZonesGraphs: function (props) {
                  var allZones = SMA.prototype.getZonesGraphs.call(this, props), currentZones = allZones;
                  if (this.currentLineZone) {
                      currentZones = allZones.splice(this[this.currentLineZone].startIndex + 1);
                      if (!currentZones.length) {
                          // Line has no zones, return basic graph "zone"
                          currentZones = [props[0]];
                      }
                      else {
                          // Add back basic prop:
                          currentZones.splice(0, 0, props[0]);
                      }
                  }
                  return currentZones;
              },
              applyZones: function () {
                  // Histogram zones are handled by drawPoints method
                  // Here we need to apply zones for all lines
                  var histogramZones = this.zones;
                  // signalZones.zones contains all zones:
                  this.zones = this.signalZones.zones;
                  SMA.prototype.applyZones.call(this);
                  // applyZones hides only main series.graph, hide macd line manually
                  if (this.graphmacd && this.options.macdLine.zones.length) {
                      this.graphmacd.hide();
                  }
                  this.zones = histogramZones;
              },
              getValues: function (series, params) {
                  var j = 0, MACD = [], xMACD = [], yMACD = [], signalLine = [], shortEMA, longEMA, i;
                  if (series.xData.length <
                      params.longPeriod + params.signalPeriod) {
                      return false;
                  }
                  // Calculating the short and long EMA used when calculating the MACD
                  shortEMA = EMA.prototype.getValues(series, {
                      period: params.shortPeriod
                  });
                  longEMA = EMA.prototype.getValues(series, {
                      period: params.longPeriod
                  });
                  shortEMA = shortEMA.values;
                  longEMA = longEMA.values;
                  // Subtract each Y value from the EMA's and create the new dataset
                  // (MACD)
                  for (i = 1; i <= shortEMA.length; i++) {
                      if (defined(longEMA[i - 1]) &&
                          defined(longEMA[i - 1][1]) &&
                          defined(shortEMA[i + params.shortPeriod + 1]) &&
                          defined(shortEMA[i + params.shortPeriod + 1][0])) {
                          MACD.push([
                              shortEMA[i + params.shortPeriod + 1][0],
                              0,
                              null,
                              shortEMA[i + params.shortPeriod + 1][1] -
                                  longEMA[i - 1][1]
                          ]);
                      }
                  }
                  // Set the Y and X data of the MACD. This is used in calculating the
                  // signal line.
                  for (i = 0; i < MACD.length; i++) {
                      xMACD.push(MACD[i][0]);
                      yMACD.push([0, null, MACD[i][3]]);
                  }
                  // Setting the signalline (Signal Line: X-day EMA of MACD line).
                  signalLine = EMA.prototype.getValues({
                      xData: xMACD,
                      yData: yMACD
                  }, {
                      period: params.signalPeriod,
                      index: 2
                  });
                  signalLine = signalLine.values;
                  // Setting the MACD Histogram. In comparison to the loop with pure
                  // MACD this loop uses MACD x value not xData.
                  for (i = 0; i < MACD.length; i++) {
                      if (MACD[i][0] >= signalLine[0][0]) { // detect the first point
                          MACD[i][2] = signalLine[j][1];
                          yMACD[i] = [0, signalLine[j][1], MACD[i][3]];
                          if (MACD[i][3] === null) {
                              MACD[i][1] = 0;
                              yMACD[i][0] = 0;
                          }
                          else {
                              MACD[i][1] = correctFloat(MACD[i][3] -
                                  signalLine[j][1]);
                              yMACD[i][0] = correctFloat(MACD[i][3] -
                                  signalLine[j][1]);
                          }
                          j++;
                      }
                  }
                  return {
                      values: MACD,
                      xData: xMACD,
                      yData: yMACD
                  };
              }
          });
          /**
           * A `MACD` series. If the [type](#series.macd.type) option is not
           * specified, it is inherited from [chart.type](#chart.type).
           *
           * @extends   series,plotOptions.macd
           * @since     6.0.0
           * @product   highstock
           * @excluding dataParser, dataURL
           * @requires  stock/indicators/indicators
           * @requires  stock/indicators/macd
           * @apioption series.macd
           */
          ''; // to include the above in the js output
  
      });
      _registerModule(_modules, 'indicators/mfi.src.js', [_modules['parts/Globals.js'], _modules['parts/Utilities.js']], function (H, U) {
          /* *
           *
           *  Money Flow Index indicator for Highstock
           *
           *  (c) 2010-2019 Grzegorz Blachliński
           *
           *  License: www.highcharts.com/license
           *
           *  !!!!!!! SOURCE GETS TRANSPILED BY TYPESCRIPT. EDIT TS FILE ONLY. !!!!!!!
           *
           * */
          var isArray = U.isArray;
          /* eslint-disable require-jsdoc */
          // Utils:
          function sumArray(array) {
              return array.reduce(function (prev, cur) {
                  return prev + cur;
              });
          }
          function toFixed(a, n) {
              return parseFloat(a.toFixed(n));
          }
          function calculateTypicalPrice(point) {
              return (point[1] + point[2] + point[3]) / 3;
          }
          function calculateRawMoneyFlow(typicalPrice, volume) {
              return typicalPrice * volume;
          }
          /* eslint-enable require-jsdoc */
          /**
           * The MFI series type.
           *
           * @private
           * @class
           * @name Highcharts.seriesTypes.mfi
           *
           * @augments Highcharts.Series
           */
          H.seriesType('mfi', 'sma', 
          /**
           * Money Flow Index. This series requires `linkedTo` option to be set and
           * should be loaded after the `stock/indicators/indicators.js` file.
           *
           * @sample stock/indicators/mfi
           *         Money Flow Index Indicator
           *
           * @extends      plotOptions.sma
           * @since        6.0.0
           * @product      highstock
           * @requires     stock/indicators/indicators
           * @requires     stock/indicators/mfi
           * @optionparent plotOptions.mfi
           */
          {
              /**
               * @excluding index
               */
              params: {
                  period: 14,
                  /**
                   * The id of volume series which is mandatory.
                   * For example using OHLC data, volumeSeriesID='volume' means
                   * the indicator will be calculated using OHLC and volume values.
                   */
                  volumeSeriesID: 'volume',
                  /**
                   * Number of maximum decimals that are used in MFI calculations.
                   */
                  decimals: 4
              }
          }, 
          /**
           * @lends Highcharts.Series#
           */
          {
              nameBase: 'Money Flow Index',
              getValues: function (series, params) {
                  var period = params.period, xVal = series.xData, yVal = series.yData, yValLen = yVal ? yVal.length : 0, decimals = params.decimals, 
                  // MFI starts calculations from the second point
                  // Cause we need to calculate change between two points
                  range = 1, volumeSeries = series.chart.get(params.volumeSeriesID), yValVolume = (volumeSeries && volumeSeries.yData), MFI = [], isUp = false, xData = [], yData = [], positiveMoneyFlow = [], negativeMoneyFlow = [], newTypicalPrice, oldTypicalPrice, rawMoneyFlow, negativeMoneyFlowSum, positiveMoneyFlowSum, moneyFlowRatio, MFIPoint, i;
                  if (!volumeSeries) {
                      return H.error('Series ' +
                          params.volumeSeriesID +
                          ' not found! Check `volumeSeriesID`.', true, series.chart);
                  }
                  // MFI requires high low and close values
                  if ((xVal.length <= period) || !isArray(yVal[0]) ||
                      yVal[0].length !== 4 ||
                      !yValVolume) {
                      return false;
                  }
                  // Calculate first typical price
                  newTypicalPrice = calculateTypicalPrice(yVal[range]);
                  // Accumulate first N-points
                  while (range < period + 1) {
                      // Calculate if up or down
                      oldTypicalPrice = newTypicalPrice;
                      newTypicalPrice = calculateTypicalPrice(yVal[range]);
                      isUp = newTypicalPrice >= oldTypicalPrice;
                      // Calculate raw money flow
                      rawMoneyFlow = calculateRawMoneyFlow(newTypicalPrice, yValVolume[range]);
                      // Add to array
                      positiveMoneyFlow.push(isUp ? rawMoneyFlow : 0);
                      negativeMoneyFlow.push(isUp ? 0 : rawMoneyFlow);
                      range++;
                  }
                  for (i = range - 1; i < yValLen; i++) {
                      if (i > range - 1) {
                          // Remove first point from array
                          positiveMoneyFlow.shift();
                          negativeMoneyFlow.shift();
                          // Calculate if up or down
                          oldTypicalPrice = newTypicalPrice;
                          newTypicalPrice = calculateTypicalPrice(yVal[i]);
                          isUp = newTypicalPrice > oldTypicalPrice;
                          // Calculate raw money flow
                          rawMoneyFlow = calculateRawMoneyFlow(newTypicalPrice, yValVolume[i]);
                          // Add to array
                          positiveMoneyFlow.push(isUp ? rawMoneyFlow : 0);
                          negativeMoneyFlow.push(isUp ? 0 : rawMoneyFlow);
                      }
                      // Calculate sum of negative and positive money flow:
                      negativeMoneyFlowSum = sumArray(negativeMoneyFlow);
                      positiveMoneyFlowSum = sumArray(positiveMoneyFlow);
                      moneyFlowRatio = positiveMoneyFlowSum / negativeMoneyFlowSum;
                      MFIPoint = toFixed(100 - (100 / (1 + moneyFlowRatio)), decimals);
                      MFI.push([xVal[i], MFIPoint]);
                      xData.push(xVal[i]);
                      yData.push(MFIPoint);
                  }
                  return {
                      values: MFI,
                      xData: xData,
                      yData: yData
                  };
              }
          });
          /**
           * A `MFI` series. If the [type](#series.mfi.type) option is not specified, it
           * is inherited from [chart.type](#chart.type).
           *
           * @extends   series,plotOptions.mfi
           * @since     6.0.0
           * @excluding dataParser, dataURL
           * @product   highstock
           * @requires  stock/indicators/indicators
           * @requires  stock/indicators/mfi
           * @apioption series.mfi
           */
          ''; // to include the above in the js output
  
      });
      _registerModule(_modules, 'indicators/momentum.src.js', [_modules['parts/Globals.js'], _modules['parts/Utilities.js']], function (H, U) {
          /* *
           *
           *  License: www.highcharts.com/license
           *
           *  !!!!!!! SOURCE GETS TRANSPILED BY TYPESCRIPT. EDIT TS FILE ONLY. !!!!!!!
           *
           * */
          var isArray = U.isArray;
          var seriesType = H.seriesType;
          /* eslint-disable require-jsdoc */
          function populateAverage(points, xVal, yVal, i, period) {
              var mmY = yVal[i - 1][3] - yVal[i - period - 1][3], mmX = xVal[i - 1];
              points.shift(); // remove point until range < period
              return [mmX, mmY];
          }
          /* eslint-enable require-jsdoc */
          /**
           * The Momentum series type.
           *
           * @private
           * @class
           * @name Highcharts.seriesTypes.momentum
           *
           * @augments Highcharts.Series
           */
          seriesType('momentum', 'sma', 
          /**
           * Momentum. This series requires `linkedTo` option to be set.
           *
           * @sample stock/indicators/momentum
           *         Momentum indicator
           *
           * @extends      plotOptions.sma
           * @since        6.0.0
           * @product      highstock
           * @requires     stock/indicators/indicators
           * @requires     stock/indicators/momentum
           * @optionparent plotOptions.momentum
           */
          {
              params: {
                  period: 14
              }
          }, 
          /**
           * @lends Highcharts.Series#
           */
          {
              nameBase: 'Momentum',
              getValues: function (series, params) {
                  var period = params.period, xVal = series.xData, yVal = series.yData, yValLen = yVal ? yVal.length : 0, xValue = xVal[0], yValue = yVal[0], MM = [], xData = [], yData = [], index, i, points, MMPoint;
                  if (xVal.length <= period) {
                      return false;
                  }
                  // Switch index for OHLC / Candlestick / Arearange
                  if (isArray(yVal[0])) {
                      yValue = yVal[0][3];
                  }
                  else {
                      return false;
                  }
                  // Starting point
                  points = [
                      [xValue, yValue]
                  ];
                  // Calculate value one-by-one for each period in visible data
                  for (i = (period + 1); i < yValLen; i++) {
                      MMPoint = populateAverage(points, xVal, yVal, i, period, index);
                      MM.push(MMPoint);
                      xData.push(MMPoint[0]);
                      yData.push(MMPoint[1]);
                  }
                  MMPoint = populateAverage(points, xVal, yVal, i, period, index);
                  MM.push(MMPoint);
                  xData.push(MMPoint[0]);
                  yData.push(MMPoint[1]);
                  return {
                      values: MM,
                      xData: xData,
                      yData: yData
                  };
              }
          });
          /**
           * A `Momentum` series. If the [type](#series.momentum.type) option is not
           * specified, it is inherited from [chart.type](#chart.type).
           *
           * @extends   series,plotOptions.momentum
           * @since     6.0.0
           * @excluding dataParser, dataURL
           * @product   highstock
           * @requires  stock/indicators/indicators
           * @requires  stock/indicators/momentum
           * @apioption series.momentum
           */
          ''; // to include the above in the js output
  
      });
      _registerModule(_modules, 'indicators/natr.src.js', [_modules['parts/Globals.js']], function (H) {
          /* *
           *
           *  License: www.highcharts.com/license
           *
           *  !!!!!!! SOURCE GETS TRANSPILED BY TYPESCRIPT. EDIT TS FILE ONLY. !!!!!!!
           *
           * */
          var ATR = H.seriesTypes.atr;
          /**
           * The NATR series type.
           *
           * @private
           * @class
           * @name Highcharts.seriesTypes.natr
           *
           * @augments Highcharts.Series
           */
          H.seriesType('natr', 'sma', 
          /**
           * Normalized average true range indicator (NATR). This series requires
           * `linkedTo` option to be set and should be loaded after the
           * `stock/indicators/indicators.js` and `stock/indicators/atr.js`.
           *
           * @sample {highstock} stock/indicators/natr
           *         NATR indicator
           *
           * @extends      plotOptions.atr
           * @since        7.0.0
           * @product      highstock
           * @requires     stock/indicators/indicators
           * @requires     stock/indicators/natr
           * @optionparent plotOptions.natr
           */
          {
              tooltip: {
                  valueSuffix: '%'
              }
          }, 
          /**
           * @lends Highcharts.Series#
           */
          {
              requiredIndicators: ['atr'],
              getValues: function (series, params) {
                  var atrData = ATR.prototype.getValues.apply(this, arguments), atrLength = atrData.values.length, period = params.period - 1, yVal = series.yData, i = 0;
                  for (; i < atrLength; i++) {
                      atrData.yData[i] = atrData.values[i][1] / yVal[period][3] * 100;
                      atrData.values[i][1] = atrData.yData[i];
                      period++;
                  }
                  return atrData;
              }
          });
          /**
           * A `NATR` series. If the [type](#series.natr.type) option is not specified, it
           * is inherited from [chart.type](#chart.type).
           *
           * @extends   series,plotOptions.natr
           * @since     7.0.0
           * @product   highstock
           * @excluding dataParser, dataURL
           * @requires  stock/indicators/indicators
           * @requires  stock/indicators/natr
           * @apioption series.natr
           */
          ''; // to include the above in the js output'
  
      });
      _registerModule(_modules, 'indicators/pivot-points.src.js', [_modules['parts/Globals.js'], _modules['parts/Utilities.js']], function (H, U) {
          /* *
           *
           *  License: www.highcharts.com/license
           *
           *  !!!!!!! SOURCE GETS TRANSPILED BY TYPESCRIPT. EDIT TS FILE ONLY. !!!!!!!
           *
           * */
          var defined = U.defined, isArray = U.isArray;
          var SMA = H.seriesTypes.sma;
          /* eslint-disable valid-jsdoc */
          /**
           * @private
           */
          function destroyExtraLabels(point, functionName) {
              var props = point.series.pointArrayMap, prop, i = props.length;
              SMA.prototype.pointClass.prototype[functionName].call(point);
              while (i--) {
                  prop = 'dataLabel' + props[i];
                  // S4 dataLabel could be removed by parent method:
                  if (point[prop] && point[prop].element) {
                      point[prop].destroy();
                  }
                  point[prop] = null;
              }
          }
          /* eslint-enable valid-jsdoc */
          /**
           * The Pivot Points series type.
           *
           * @private
           * @class
           * @name Highcharts.seriesTypes.pivotpoints
           *
           * @augments Highcharts.Series
           */
          H.seriesType('pivotpoints', 'sma', 
          /**
           * Pivot points indicator. This series requires the `linkedTo` option to be
           * set and should be loaded after `stock/indicators/indicators.js` file.
           *
           * @sample stock/indicators/pivot-points
           *         Pivot points
           *
           * @extends      plotOptions.sma
           * @since        6.0.0
           * @product      highstock
           * @requires     stock/indicators/indicators
           * @requires     stock/indicators/pivotpoints
           * @optionparent plotOptions.pivotpoints
           */
          {
              /**
               * @excluding index
               */
              params: {
                  period: 28,
                  /**
                   * Algorithm used to calculate ressistance and support lines based
                   * on pivot points. Implemented algorithms: `'standard'`,
                   * `'fibonacci'` and `'camarilla'`
                   */
                  algorithm: 'standard'
              },
              marker: {
                  enabled: false
              },
              enableMouseTracking: false,
              dataLabels: {
                  /** @ignore-option */
                  enabled: true,
                  /** @ignore-option */
                  format: '{point.pivotLine}'
              },
              dataGrouping: {
                  approximation: 'averages'
              }
          }, 
          /**
           * @lends Highcharts.Series#
           */
          {
              nameBase: 'Pivot Points',
              pointArrayMap: ['R4', 'R3', 'R2', 'R1', 'P', 'S1', 'S2', 'S3', 'S4'],
              pointValKey: 'P',
              toYData: function (point) {
                  return [point.P]; // The rest should not affect extremes
              },
              translate: function () {
                  var indicator = this;
                  SMA.prototype.translate.apply(indicator);
                  indicator.points.forEach(function (point) {
                      indicator.pointArrayMap.forEach(function (value) {
                          if (defined(point[value])) {
                              point['plot' + value] = (indicator.yAxis.toPixels(point[value], true));
                          }
                      });
                  });
                  // Pivot points are rendered as horizontal lines
                  // And last point start not from the next one (as it's the last one)
                  // But from the approximated last position in a given range
                  indicator.plotEndPoint = indicator.xAxis.toPixels(indicator.endPoint, true);
              },
              getGraphPath: function (points) {
                  var indicator = this, pointsLength = points.length, allPivotPoints = ([[], [], [], [], [], [], [], [], []]), path = [], endPoint = indicator.plotEndPoint, pointArrayMapLength = indicator.pointArrayMap.length, position, point, i;
                  while (pointsLength--) {
                      point = points[pointsLength];
                      for (i = 0; i < pointArrayMapLength; i++) {
                          position = indicator.pointArrayMap[i];
                          if (defined(point[position])) {
                              allPivotPoints[i].push({
                                  // Start left:
                                  plotX: point.plotX,
                                  plotY: point['plot' + position],
                                  isNull: false
                              }, {
                                  // Go to right:
                                  plotX: endPoint,
                                  plotY: point['plot' + position],
                                  isNull: false
                              }, {
                                  // And add null points in path to generate breaks:
                                  plotX: endPoint,
                                  plotY: null,
                                  isNull: true
                              });
                          }
                      }
                      endPoint = point.plotX;
                  }
                  allPivotPoints.forEach(function (pivotPoints) {
                      path = path.concat(SMA.prototype.getGraphPath.call(indicator, pivotPoints));
                  });
                  return path;
              },
              // TODO: Rewrite this logic to use multiple datalabels
              drawDataLabels: function () {
                  var indicator = this, pointMapping = indicator.pointArrayMap, currentLabel, pointsLength, point, i;
                  if (indicator.options.dataLabels.enabled) {
                      pointsLength = indicator.points.length;
                      // For every Ressitance/Support group we need to render labels.
                      // Add one more item, which will just store dataLabels from
                      // previous iteration
                      pointMapping.concat([false]).forEach(function (position, k) {
                          i = pointsLength;
                          while (i--) {
                              point = indicator.points[i];
                              if (!position) {
                                  // Store S4 dataLabel too:
                                  point['dataLabel' + pointMapping[k - 1]] =
                                      point.dataLabel;
                              }
                              else {
                                  point.y = point[position];
                                  point.pivotLine = position;
                                  point.plotY = point['plot' + position];
                                  currentLabel = point['dataLabel' + position];
                                  // Store previous label
                                  if (k) {
                                      point['dataLabel' + pointMapping[k - 1]] = point.dataLabel;
                                  }
                                  if (!point.dataLabels) {
                                      point.dataLabels = [];
                                  }
                                  point.dataLabels[0] = point.dataLabel =
                                      currentLabel =
                                          currentLabel && currentLabel.element ?
                                              currentLabel :
                                              null;
                              }
                          }
                          SMA.prototype.drawDataLabels.apply(indicator, arguments);
                      });
                  }
              },
              getValues: function (series, params) {
                  var period = params.period, xVal = series.xData, yVal = series.yData, yValLen = yVal ? yVal.length : 0, placement = this[params.algorithm + 'Placement'], 
                  // 0- from, 1- to, 2- R1, 3- R2, 4- pivot, 5- S1 etc.
                  PP = [], endTimestamp, xData = [], yData = [], slicedXLen, slicedX, slicedY, lastPP, pivot, avg, i;
                  // Pivot Points requires high, low and close values
                  if (xVal.length < period ||
                      !isArray(yVal[0]) ||
                      yVal[0].length !== 4) {
                      return false;
                  }
                  for (i = period + 1; i <= yValLen + period; i += period) {
                      slicedX = xVal.slice(i - period - 1, i);
                      slicedY = yVal.slice(i - period - 1, i);
                      slicedXLen = slicedX.length;
                      endTimestamp = slicedX[slicedXLen - 1];
                      pivot = this.getPivotAndHLC(slicedY);
                      avg = placement(pivot);
                      lastPP = PP.push([endTimestamp]
                          .concat(avg));
                      xData.push(endTimestamp);
                      yData.push(PP[lastPP - 1].slice(1));
                  }
                  // We don't know exact position in ordinal axis
                  // So we use simple logic:
                  // Get first point in last range, calculate visible average range
                  // and multiply by period
                  this.endPoint = slicedX[0] + ((endTimestamp - slicedX[0]) /
                      slicedXLen) * period;
                  return {
                      values: PP,
                      xData: xData,
                      yData: yData
                  };
              },
              getPivotAndHLC: function (values) {
                  var high = -Infinity, low = Infinity, close = values[values.length - 1][3], pivot;
                  values.forEach(function (p) {
                      high = Math.max(high, p[1]);
                      low = Math.min(low, p[2]);
                  });
                  pivot = (high + low + close) / 3;
                  return [pivot, high, low, close];
              },
              standardPlacement: function (values) {
                  var diff = values[1] - values[2], avg = [
                      null,
                      null,
                      values[0] + diff,
                      values[0] * 2 - values[2],
                      values[0],
                      values[0] * 2 - values[1],
                      values[0] - diff,
                      null,
                      null
                  ];
                  return avg;
              },
              camarillaPlacement: function (values) {
                  var diff = values[1] - values[2], avg = [
                      values[3] + diff * 1.5,
                      values[3] + diff * 1.25,
                      values[3] + diff * 1.1666,
                      values[3] + diff * 1.0833,
                      values[0],
                      values[3] - diff * 1.0833,
                      values[3] - diff * 1.1666,
                      values[3] - diff * 1.25,
                      values[3] - diff * 1.5
                  ];
                  return avg;
              },
              fibonacciPlacement: function (values) {
                  var diff = values[1] - values[2], avg = [
                      null,
                      values[0] + diff,
                      values[0] + diff * 0.618,
                      values[0] + diff * 0.382,
                      values[0],
                      values[0] - diff * 0.382,
                      values[0] - diff * 0.618,
                      values[0] - diff,
                      null
                  ];
                  return avg;
              }
          }, 
          /**
           * @lends Highcharts.Point#
           */
          {
              // Destroy labels:
              // This method is called when cropping data:
              destroyElements: function () {
                  destroyExtraLabels(this, 'destroyElements');
              },
              // This method is called when removing points, e.g. series.update()
              destroy: function () {
                  destroyExtraLabels(this, 'destroyElements');
              }
          });
          /**
           * A pivot points indicator. If the [type](#series.pivotpoints.type) option is
           * not specified, it is inherited from [chart.type](#chart.type).
           *
           * @extends   series,plotOptions.pivotpoints
           * @since     6.0.0
           * @product   highstock
           * @excluding dataParser, dataURL
           * @requires  stock/indicators/indicators
           * @requires  stock/indicators/pivotpoints
           * @apioption series.pivotpoints
           */
          ''; // to include the above in the js output'
  
      });
      _registerModule(_modules, 'indicators/ppo.src.js', [_modules['parts/Globals.js'], _modules['mixins/indicator-required.js']], function (H, requiredIndicatorMixin) {
          /* *
           *
           *  License: www.highcharts.com/license
           *
           *  !!!!!!! SOURCE GETS TRANSPILED BY TYPESCRIPT. EDIT TS FILE ONLY. !!!!!!!
           *
           * */
          var EMA = H.seriesTypes.ema, error = H.error, correctFloat = H.correctFloat, requiredIndicator = requiredIndicatorMixin;
          /**
           * The PPO series type.
           *
           * @private
           * @class
           * @name Highcharts.seriesTypes.ppo
           *
           * @augments Highcharts.Series
           */
          H.seriesType('ppo', 'ema', 
          /**
           * Percentage Price Oscillator. This series requires the
           * `linkedTo` option to be set and should be loaded after the
           * `stock/indicators/indicators.js` and `stock/indicators/ema.js`.
           *
           * @sample {highstock} stock/indicators/ppo
           *         Percentage Price Oscillator
           *
           * @extends      plotOptions.ema
           * @since        7.0.0
           * @product      highstock
           * @excluding    allAreas, colorAxis, joinBy, keys, navigatorOptions,
           *               pointInterval, pointIntervalUnit, pointPlacement,
           *               pointRange, pointStart, showInNavigator, stacking
           * @requires     stock/indicators/indicators
           * @requires     stock/indicators/ema
           * @requires     stock/indicators/ppo
           * @optionparent plotOptions.ppo
           */
          {
              /**
               * Paramters used in calculation of Percentage Price Oscillator series
               * points.
               *
               * @excluding period
               */
              params: {
                  /**
                   * Periods for Percentage Price Oscillator calculations.
                   *
                   * @type    {Array<number>}
                   * @default [12, 26]
                   */
                  periods: [12, 26]
              }
          }, 
          /**
           * @lends Highcharts.Series.prototype
           */
          {
              nameBase: 'PPO',
              nameComponents: ['periods'],
              init: function () {
                  var args = arguments, ctx = this;
                  requiredIndicator.isParentLoaded(EMA, 'ema', ctx.type, function (indicator) {
                      indicator.prototype.init.apply(ctx, args);
                      return;
                  });
              },
              getValues: function (series, params) {
                  var periods = params.periods, index = params.index, 
                  // 0- date, 1- Percentage Price Oscillator
                  PPO = [], xData = [], yData = [], periodsOffset, 
                  // Shorter Period EMA
                  SPE, 
                  // Longer Period EMA
                  LPE, oscillator, i;
                  // Check if periods are correct
                  if (periods.length !== 2 || periods[1] <= periods[0]) {
                      error('Error: "PPO requires two periods. Notice, first period ' +
                          'should be lower than the second one."');
                      return false;
                  }
                  SPE = EMA.prototype.getValues.call(this, series, {
                      index: index,
                      period: periods[0]
                  });
                  LPE = EMA.prototype.getValues.call(this, series, {
                      index: index,
                      period: periods[1]
                  });
                  // Check if ema is calculated properly, if not skip
                  if (!SPE || !LPE) {
                      return false;
                  }
                  periodsOffset = periods[1] - periods[0];
                  for (i = 0; i < LPE.yData.length; i++) {
                      oscillator = correctFloat((SPE.yData[i + periodsOffset] -
                          LPE.yData[i]) /
                          LPE.yData[i] *
                          100);
                      PPO.push([LPE.xData[i], oscillator]);
                      xData.push(LPE.xData[i]);
                      yData.push(oscillator);
                  }
                  return {
                      values: PPO,
                      xData: xData,
                      yData: yData
                  };
              }
          });
          /**
           * A `Percentage Price Oscillator` series. If the [type](#series.ppo.type)
           * option is not specified, it is inherited from [chart.type](#chart.type).
           *
           * @extends   series,plotOptions.ppo
           * @since     7.0.0
           * @product   highstock
           * @excluding allAreas, colorAxis, dataParser, dataURL, joinBy, keys,
           *            navigatorOptions, pointInterval, pointIntervalUnit,
           *            pointPlacement, pointRange, pointStart, showInNavigator, stacking
           * @requires  stock/indicators/indicators
           * @requires  stock/indicators/ema
           * @requires  stock/indicators/ppo
           * @apioption series.ppo
           */
          ''; // to include the above in the js output
  
      });
      _registerModule(_modules, 'mixins/reduce-array.js', [_modules['parts/Globals.js']], function (H) {
          /**
           *
           *  (c) 2010-2019 Pawel Fus & Daniel Studencki
           *
           *  License: www.highcharts.com/license
           *
           *  !!!!!!! SOURCE GETS TRANSPILED BY TYPESCRIPT. EDIT TS FILE ONLY. !!!!!!!
           *
           * */
          var reduce = H.reduce;
          var reduceArrayMixin = {
              /**
               * Get min value of array filled by OHLC data.
               * @private
               * @param {Array<*>} arr Array of OHLC points (arrays).
               * @param {string} index Index of "low" value in point array.
               * @return {number} Returns min value.
               */
              minInArray: function (arr, index) {
                  return reduce(arr, function (min, target) {
                      return Math.min(min, target[index]);
                  }, Number.MAX_VALUE);
              },
              /**
               * Get max value of array filled by OHLC data.
               * @private
               * @param {Array<*>} arr Array of OHLC points (arrays).
               * @param {string} index Index of "high" value in point array.
               * @return {number} Returns max value.
               */
              maxInArray: function (arr, index) {
                  return reduce(arr, function (max, target) {
                      return Math.max(max, target[index]);
                  }, -Number.MAX_VALUE);
              },
              /**
               * Get extremes of array filled by OHLC data.
               * @private
               * @param {Array<*>} arr Array of OHLC points (arrays).
               * @param {string} minIndex Index of "low" value in point array.
               * @param {string} maxIndex Index of "high" value in point array.
               * @return {Array<number,number>} Returns array with min and max value.
               */
              getArrayExtremes: function (arr, minIndex, maxIndex) {
                  return reduce(arr, function (prev, target) {
                      return [
                          Math.min(prev[0], target[minIndex]),
                          Math.max(prev[1], target[maxIndex])
                      ];
                  }, [Number.MAX_VALUE, -Number.MAX_VALUE]);
              }
          };
  
          return reduceArrayMixin;
      });
      _registerModule(_modules, 'indicators/price-channel.src.js', [_modules['parts/Globals.js'], _modules['mixins/reduce-array.js'], _modules['mixins/multipe-lines.js']], function (H, reduceArrayMixin, multipleLinesMixin) {
          /* *
           *
           *  License: www.highcharts.com/license
           *
           *  !!!!!!! SOURCE GETS TRANSPILED BY TYPESCRIPT. EDIT TS FILE ONLY. !!!!!!!
           *
           * */
          var getArrayExtremes = reduceArrayMixin.getArrayExtremes, merge = H.merge;
          /**
           * The Price Channel series type.
           *
           * @private
           * @class
           * @name Highcharts.seriesTypes.pc
           *
           * @augments Highcharts.Series
           */
          H.seriesType('pc', 'sma', 
          /**
           * Price channel (PC). This series requires the `linkedTo` option to be
           * set and should be loaded after the `stock/indicators/indicators.js`.
           *
           * @sample {highstock} stock/indicators/price-channel
           *         Price Channel
           *
           * @extends      plotOptions.sma
           * @since        7.0.0
           * @product      highstock
           * @excluding    allAreas, colorAxis, compare, compareBase, joinBy, keys,
           *               navigatorOptions, pointInterval, pointIntervalUnit,
           *               pointPlacement, pointRange, pointStart, showInNavigator,
           *               stacking
           * @requires     stock/indicators/indicators
           * @requires     stock/indicators/price-channel
           * @optionparent plotOptions.pc
           */
          {
              /**
               * @excluding index
               */
              params: {
                  period: 20
              },
              lineWidth: 1,
              topLine: {
                  styles: {
                      /**
                       * Color of the top line. If not set, it's inherited from
                       * [plotOptions.pc.color](#plotOptions.pc.color).
                       *
                       * @type {Highcharts.ColorString}
                       */
                      lineColor: '#7cb5ec #434348 #90ed7d #f7a35c #8085e9 #f15c80 #e4d354 #2b908f #f45b5b #91e8e1'.split(' ')[2],
                      /**
                       * Pixel width of the line.
                       */
                      lineWidth: 1
                  }
              },
              bottomLine: {
                  styles: {
                      /**
                       * Color of the bottom line. If not set, it's inherited from
                       * [plotOptions.pc.color](#plotOptions.pc.color).
                       *
                       * @type {Highcharts.ColorString}
                       */
                      lineColor: '#7cb5ec #434348 #90ed7d #f7a35c #8085e9 #f15c80 #e4d354 #2b908f #f45b5b #91e8e1'.split(' ')[8],
                      /**
                       * Pixel width of the line.
                       */
                      lineWidth: 1
                  }
              },
              dataGrouping: {
                  approximation: 'averages'
              }
          }, 
          /**
           * @lends Highcharts.Series#
           */
          merge(multipleLinesMixin, {
              pointArrayMap: ['top', 'middle', 'bottom'],
              pointValKey: 'middle',
              nameBase: 'Price Channel',
              nameComponents: ['period'],
              linesApiNames: ['topLine', 'bottomLine'],
              getValues: function (series, params) {
                  var period = params.period, xVal = series.xData, yVal = series.yData, yValLen = yVal ? yVal.length : 0, 
                  // 0- date, 1-top line, 2-middle line, 3-bottom line
                  PC = [], 
                  // middle line, top line and bottom line
                  ML, TL, BL, date, low = 2, high = 1, xData = [], yData = [], slicedY, extremes, i;
                  if (yValLen < period) {
                      return false;
                  }
                  for (i = period; i <= yValLen; i++) {
                      date = xVal[i - 1];
                      slicedY = yVal.slice(i - period, i);
                      extremes = getArrayExtremes(slicedY, low, high);
                      TL = extremes[1];
                      BL = extremes[0];
                      ML = (TL + BL) / 2;
                      PC.push([date, TL, ML, BL]);
                      xData.push(date);
                      yData.push([TL, ML, BL]);
                  }
                  return {
                      values: PC,
                      xData: xData,
                      yData: yData
                  };
              }
          }));
          /**
           * A Price channel indicator. If the [type](#series.pc.type) option is not
           * specified, it is inherited from [chart.type](#chart.type).
           *
           * @extends      series,plotOptions.pc
           * @since        7.0.0
           * @product      highstock
           * @excluding    allAreas, colorAxis, compare, compareBase, dataParser, dataURL,
           *               joinBy, keys, navigatorOptions, pointInterval,
           *               pointIntervalUnit, pointPlacement, pointRange, pointStart,
           *               showInNavigator, stacking
           * @requires     stock/indicators/indicators
           * @requires     stock/indicators/price-channel
           * @apioption    series.pc
           */
          ''; // to include the above in the js output
  
      });
      _registerModule(_modules, 'indicators/price-envelopes.src.js', [_modules['parts/Globals.js'], _modules['parts/Utilities.js']], function (H, U) {
          /* *
           *
           *  License: www.highcharts.com/license
           *
           *  !!!!!!! SOURCE GETS TRANSPILED BY TYPESCRIPT. EDIT TS FILE ONLY. !!!!!!!
           *
           * */
          var isArray = U.isArray;
          var merge = H.merge, SMA = H.seriesTypes.sma;
          /**
           * The Price Envelopes series type.
           *
           * @private
           * @class
           * @name Highcharts.seriesTypes.priceenvelopes
           *
           * @augments Highcharts.Series
           */
          H.seriesType('priceenvelopes', 'sma', 
          /**
           * Price envelopes indicator based on [SMA](#plotOptions.sma) calculations.
           * This series requires the `linkedTo` option to be set and should be loaded
           * after the `stock/indicators/indicators.js` file.
           *
           * @sample stock/indicators/price-envelopes
           *         Price envelopes
           *
           * @extends      plotOptions.sma
           * @since        6.0.0
           * @product      highstock
           * @requires     stock/indicators/indicators
           * @requires     stock/indicators/price-envelopes
           * @optionparent plotOptions.priceenvelopes
           */
          {
              marker: {
                  enabled: false
              },
              tooltip: {
                  pointFormat: '<span style="color:{point.color}">\u25CF</span><b> {series.name}</b><br/>Top: {point.top}<br/>Middle: {point.middle}<br/>Bottom: {point.bottom}<br/>'
              },
              params: {
                  period: 20,
                  /**
                   * Percentage above the moving average that should be displayed.
                   * 0.1 means 110%. Relative to the calculated value.
                   */
                  topBand: 0.1,
                  /**
                   * Percentage below the moving average that should be displayed.
                   * 0.1 means 90%. Relative to the calculated value.
                   */
                  bottomBand: 0.1
              },
              /**
               * Bottom line options.
               */
              bottomLine: {
                  styles: {
                      /**
                       * Pixel width of the line.
                       */
                      lineWidth: 1,
                      /**
                       * Color of the line. If not set, it's inherited from
                       * [plotOptions.priceenvelopes.color](
                       * #plotOptions.priceenvelopes.color).
                       *
                       * @type {Highcharts.ColorString}
                       */
                      lineColor: undefined
                  }
              },
              /**
               * Top line options.
               *
               * @extends plotOptions.priceenvelopes.bottomLine
               */
              topLine: {
                  styles: {
                      lineWidth: 1
                  }
              },
              dataGrouping: {
                  approximation: 'averages'
              }
          }, 
          /**
           * @lends Highcharts.Series#
           */
          {
              nameComponents: ['period', 'topBand', 'bottomBand'],
              nameBase: 'Price envelopes',
              pointArrayMap: ['top', 'middle', 'bottom'],
              parallelArrays: ['x', 'y', 'top', 'bottom'],
              pointValKey: 'middle',
              init: function () {
                  SMA.prototype.init.apply(this, arguments);
                  // Set default color for lines:
                  this.options = merge({
                      topLine: {
                          styles: {
                              lineColor: this.color
                          }
                      },
                      bottomLine: {
                          styles: {
                              lineColor: this.color
                          }
                      }
                  }, this.options);
              },
              toYData: function (point) {
                  return [point.top, point.middle, point.bottom];
              },
              translate: function () {
                  var indicator = this, translatedEnvelopes = ['plotTop', 'plotMiddle', 'plotBottom'];
                  SMA.prototype.translate.apply(indicator);
                  indicator.points.forEach(function (point) {
                      [point.top, point.middle, point.bottom].forEach(function (value, i) {
                          if (value !== null) {
                              point[translatedEnvelopes[i]] =
                                  indicator.yAxis.toPixels(value, true);
                          }
                      });
                  });
              },
              drawGraph: function () {
                  var indicator = this, middleLinePoints = indicator.points, pointsLength = middleLinePoints.length, middleLineOptions = (indicator.options), middleLinePath = indicator.graph, gappedExtend = {
                      options: {
                          gapSize: middleLineOptions.gapSize
                      }
                  }, deviations = [[], []], // top and bottom point place holders
                  point;
                  // Generate points for top and bottom lines:
                  while (pointsLength--) {
                      point = middleLinePoints[pointsLength];
                      deviations[0].push({
                          plotX: point.plotX,
                          plotY: point.plotTop,
                          isNull: point.isNull
                      });
                      deviations[1].push({
                          plotX: point.plotX,
                          plotY: point.plotBottom,
                          isNull: point.isNull
                      });
                  }
                  // Modify options and generate lines:
                  ['topLine', 'bottomLine'].forEach(function (lineName, i) {
                      indicator.points = deviations[i];
                      indicator.options = merge(middleLineOptions[lineName].styles, gappedExtend);
                      indicator.graph = indicator['graph' + lineName];
                      SMA.prototype.drawGraph.call(indicator);
                      // Now save lines:
                      indicator['graph' + lineName] = indicator.graph;
                  });
                  // Restore options and draw a middle line:
                  indicator.points = middleLinePoints;
                  indicator.options = middleLineOptions;
                  indicator.graph = middleLinePath;
                  SMA.prototype.drawGraph.call(indicator);
              },
              getValues: function (series, params) {
                  var period = params.period, topPercent = params.topBand, botPercent = params.bottomBand, xVal = series.xData, yVal = series.yData, yValLen = yVal ? yVal.length : 0, 
                  // 0- date, 1-top line, 2-middle line, 3-bottom line
                  PE = [], 
                  // middle line, top line and bottom line
                  ML, TL, BL, date, xData = [], yData = [], slicedX, slicedY, point, i;
                  // Price envelopes requires close value
                  if (xVal.length < period ||
                      !isArray(yVal[0]) ||
                      yVal[0].length !== 4) {
                      return false;
                  }
                  for (i = period; i <= yValLen; i++) {
                      slicedX = xVal.slice(i - period, i);
                      slicedY = yVal.slice(i - period, i);
                      point = SMA.prototype.getValues.call(this, {
                          xData: slicedX,
                          yData: slicedY
                      }, params);
                      date = point.xData[0];
                      ML = point.yData[0];
                      TL = ML * (1 + topPercent);
                      BL = ML * (1 - botPercent);
                      PE.push([date, TL, ML, BL]);
                      xData.push(date);
                      yData.push([TL, ML, BL]);
                  }
                  return {
                      values: PE,
                      xData: xData,
                      yData: yData
                  };
              }
          });
          /**
           * A price envelopes indicator. If the [type](#series.priceenvelopes.type)
           * option is not specified, it is inherited from [chart.type](#chart.type).
           *
           * @extends   series,plotOptions.priceenvelopes
           * @since     6.0.0
           * @excluding dataParser, dataURL
           * @product   highstock
           * @requires  stock/indicators/indicators
           * @requires  stock/indicators/price-envelopes
           * @apioption series.priceenvelopes
           */
          ''; // to include the above in the js output
  
      });
      _registerModule(_modules, 'indicators/psar.src.js', [_modules['parts/Globals.js']], function (H) {
          /* *
           *
           *  Parabolic SAR indicator for Highstock
           *
           *  (c) 2010-2019 Grzegorz Blachliński
           *
           *  License: www.highcharts.com/license
           *
           *  !!!!!!! SOURCE GETS TRANSPILED BY TYPESCRIPT. EDIT TS FILE ONLY. !!!!!!!
           *
           * */
          /* eslint-disable require-jsdoc */
          // Utils:
          function toFixed(a, n) {
              return parseFloat(a.toFixed(n));
          }
          function calculateDirection(previousDirection, low, high, PSAR) {
              if ((previousDirection === 1 && low > PSAR) ||
                  (previousDirection === -1 && high > PSAR)) {
                  return 1;
              }
              return -1;
          }
          /* *
           * Method for calculating acceleration factor
           * dir - direction
           * pDir - previous Direction
           * eP - extreme point
           * pEP - previous extreme point
           * inc - increment for acceleration factor
           * maxAcc - maximum acceleration factor
           * initAcc - initial acceleration factor
           */
          function getAccelerationFactor(dir, pDir, eP, pEP, pAcc, inc, maxAcc, initAcc) {
              if (dir === pDir) {
                  if (dir === 1 && (eP > pEP)) {
                      return (pAcc === maxAcc) ? maxAcc : toFixed(pAcc + inc, 2);
                  }
                  if (dir === -1 && (eP < pEP)) {
                      return (pAcc === maxAcc) ? maxAcc : toFixed(pAcc + inc, 2);
                  }
                  return pAcc;
              }
              return initAcc;
          }
          function getExtremePoint(high, low, previousDirection, previousExtremePoint) {
              if (previousDirection === 1) {
                  return (high > previousExtremePoint) ? high : previousExtremePoint;
              }
              return (low < previousExtremePoint) ? low : previousExtremePoint;
          }
          function getEPMinusPSAR(EP, PSAR) {
              return EP - PSAR;
          }
          function getAccelerationFactorMultiply(accelerationFactor, EPMinusSAR) {
              return accelerationFactor * EPMinusSAR;
          }
          /* *
           * Method for calculating PSAR
           * pdir - previous direction
           * sDir - second previous Direction
           * PSAR - previous PSAR
           * pACCMultiply - previous acceleration factor multiply
           * sLow - second previous low
           * pLow - previous low
           * sHigh - second previous high
           * pHigh - previous high
           * pEP - previous extreme point
           */
          function getPSAR(pdir, sDir, PSAR, pACCMulti, sLow, pLow, pHigh, sHigh, pEP) {
              if (pdir === sDir) {
                  if (pdir === 1) {
                      return (PSAR + pACCMulti < Math.min(sLow, pLow)) ?
                          PSAR + pACCMulti :
                          Math.min(sLow, pLow);
                  }
                  return (PSAR + pACCMulti > Math.max(sHigh, pHigh)) ?
                      PSAR + pACCMulti :
                      Math.max(sHigh, pHigh);
              }
              return pEP;
          }
          /* eslint-enable require-jsdoc */
          /**
           * The Parabolic SAR series type.
           *
           * @private
           * @class
           * @name Highcharts.seriesTypes.psar
           *
           * @augments Highcharts.Series
           */
          H.seriesType('psar', 'sma', 
          /**
           * Parabolic SAR. This series requires `linkedTo`
           * option to be set and should be loaded
           * after `stock/indicators/indicators.js` file.
           *
           * @sample stock/indicators/psar
           *         Parabolic SAR Indicator
           *
           * @extends      plotOptions.sma
           * @since        6.0.0
           * @product      highstock
           * @requires     stock/indicators/indicators
           * @requires     stock/indicators/psar
           * @optionparent plotOptions.psar
           */
          {
              lineWidth: 0,
              marker: {
                  enabled: true
              },
              states: {
                  hover: {
                      lineWidthPlus: 0
                  }
              },
              /**
               * @excluding period
               */
              params: {
                  /**
                   * The initial value for acceleration factor.
                   * Acceleration factor is starting with this value
                   * and increases by specified increment each time
                   * the extreme point makes a new high.
                   * AF can reach a maximum of maxAccelerationFactor,
                   * no matter how long the uptrend extends.
                   */
                  initialAccelerationFactor: 0.02,
                  /**
                   * The Maximum value for acceleration factor.
                   * AF can reach a maximum of maxAccelerationFactor,
                   * no matter how long the uptrend extends.
                   */
                  maxAccelerationFactor: 0.2,
                  /**
                   * Acceleration factor increases by increment each time
                   * the extreme point makes a new high.
                   *
                   * @since 6.0.0
                   */
                  increment: 0.02,
                  /**
                   * Index from which PSAR is starting calculation
                   *
                   * @since 6.0.0
                   */
                  index: 2,
                  /**
                   * Number of maximum decimals that are used in PSAR calculations.
                   *
                   * @since 6.0.0
                   */
                  decimals: 4
              }
          }, {
              nameComponents: false,
              getValues: function (series, params) {
                  var xVal = series.xData, yVal = series.yData, 
                  // Extreme point is the lowest low for falling and highest high
                  // for rising psar - and we are starting with falling
                  extremePoint = yVal[0][1], accelerationFactor = params.initialAccelerationFactor, maxAccelerationFactor = params.maxAccelerationFactor, increment = params.increment, 
                  // Set initial acc factor (for every new trend!)
                  initialAccelerationFactor = params.initialAccelerationFactor, PSAR = yVal[0][2], decimals = params.decimals, index = params.index, PSARArr = [], xData = [], yData = [], previousDirection = 1, direction, EPMinusPSAR, accelerationFactorMultiply, newDirection, prevLow, prevPrevLow, prevHigh, prevPrevHigh, newExtremePoint, high, low, ind;
                  if (index >= yVal.length) {
                      return false;
                  }
                  for (ind = 0; ind < index; ind++) {
                      extremePoint = Math.max(yVal[ind][1], extremePoint);
                      PSAR = Math.min(yVal[ind][2], toFixed(PSAR, decimals));
                  }
                  direction = (yVal[ind][1] > PSAR) ? 1 : -1;
                  EPMinusPSAR = getEPMinusPSAR(extremePoint, PSAR);
                  accelerationFactor = params.initialAccelerationFactor;
                  accelerationFactorMultiply = getAccelerationFactorMultiply(accelerationFactor, EPMinusPSAR);
                  PSARArr.push([xVal[index], PSAR]);
                  xData.push(xVal[index]);
                  yData.push(toFixed(PSAR, decimals));
                  for (ind = index + 1; ind < yVal.length; ind++) {
                      prevLow = yVal[ind - 1][2];
                      prevPrevLow = yVal[ind - 2][2];
                      prevHigh = yVal[ind - 1][1];
                      prevPrevHigh = yVal[ind - 2][1];
                      high = yVal[ind][1];
                      low = yVal[ind][2];
                      // Null points break PSAR
                      if (prevPrevLow !== null &&
                          prevPrevHigh !== null &&
                          prevLow !== null &&
                          prevHigh !== null &&
                          high !== null &&
                          low !== null) {
                          PSAR = getPSAR(direction, previousDirection, PSAR, accelerationFactorMultiply, prevPrevLow, prevLow, prevHigh, prevPrevHigh, extremePoint);
                          newExtremePoint = getExtremePoint(high, low, direction, extremePoint);
                          newDirection = calculateDirection(previousDirection, low, high, PSAR);
                          accelerationFactor = getAccelerationFactor(newDirection, direction, newExtremePoint, extremePoint, accelerationFactor, increment, maxAccelerationFactor, initialAccelerationFactor);
                          EPMinusPSAR = getEPMinusPSAR(newExtremePoint, PSAR);
                          accelerationFactorMultiply = getAccelerationFactorMultiply(accelerationFactor, EPMinusPSAR);
                          PSARArr.push([xVal[ind], toFixed(PSAR, decimals)]);
                          xData.push(xVal[ind]);
                          yData.push(toFixed(PSAR, decimals));
                          previousDirection = direction;
                          direction = newDirection;
                          extremePoint = newExtremePoint;
                      }
                  }
                  return {
                      values: PSARArr,
                      xData: xData,
                      yData: yData
                  };
              }
          });
          /**
           * A `PSAR` series. If the [type](#series.psar.type) option is not specified, it
           * is inherited from [chart.type](#chart.type).
           *
           * @extends   series,plotOptions.psar
           * @since     6.0.0
           * @product   highstock
           * @excluding dataParser, dataURL
           * @requires  stock/indicators/indicators
           * @requires  stock/indicators/psar
           * @apioption series.psar
           */
          ''; // to include the above in the js output
  
      });
      _registerModule(_modules, 'indicators/roc.src.js', [_modules['parts/Globals.js'], _modules['parts/Utilities.js']], function (H, U) {
          /* *
           *
           *  (c) 2010-2019 Kacper Madej
           *
           *  License: www.highcharts.com/license
           *
           *  !!!!!!! SOURCE GETS TRANSPILED BY TYPESCRIPT. EDIT TS FILE ONLY. !!!!!!!
           *
           * */
          var isArray = U.isArray;
          var seriesType = H.seriesType;
          /* eslint-disable require-jsdoc */
          // Utils:
          function populateAverage(xVal, yVal, i, period, index) {
              /* Calculated as:
  
                 (Closing Price [today] - Closing Price [n days ago]) /
                  Closing Price [n days ago] * 100
  
                 Return y as null when avoiding division by zero */
              var nDaysAgoY, rocY;
              if (index < 0) {
                  // y data given as an array of values
                  nDaysAgoY = yVal[i - period];
                  rocY = nDaysAgoY ?
                      (yVal[i] - nDaysAgoY) / nDaysAgoY * 100 :
                      null;
              }
              else {
                  // y data given as an array of arrays and the index should be used
                  nDaysAgoY = yVal[i - period][index];
                  rocY = nDaysAgoY ?
                      (yVal[i][index] - nDaysAgoY) / nDaysAgoY * 100 :
                      null;
              }
              return [xVal[i], rocY];
          }
          /* eslint-enable require-jsdoc */
          /**
           * The ROC series type.
           *
           * @private
           * @class
           * @name Highcharts.seriesTypes.roc
           *
           * @augments Highcharts.Series
           */
          seriesType('roc', 'sma', 
          /**
           * Rate of change indicator (ROC). The indicator value for each point
           * is defined as:
           *
           * `(C - Cn) / Cn * 100`
           *
           * where: `C` is the close value of the point of the same x in the
           * linked series and `Cn` is the close value of the point `n` periods
           * ago. `n` is set through [period](#plotOptions.roc.params.period).
           *
           * This series requires `linkedTo` option to be set.
           *
           * @sample stock/indicators/roc
           *         Rate of change indicator
           *
           * @extends      plotOptions.sma
           * @since        6.0.0
           * @product      highstock
           * @requires     stock/indicators/indicators
           * @requires     stock/indicators/roc
           * @optionparent plotOptions.roc
           */
          {
              params: {
                  index: 3,
                  period: 9
              }
          }, 
          /**
           * @lends Highcharts.Series#
           */
          {
              nameBase: 'Rate of Change',
              getValues: function (series, params) {
                  var period = params.period, xVal = series.xData, yVal = series.yData, yValLen = yVal ? yVal.length : 0, ROC = [], xData = [], yData = [], i, index = -1, ROCPoint;
                  // Period is used as a number of time periods ago, so we need more
                  // (at least 1 more) data than the period value
                  if (xVal.length <= period) {
                      return false;
                  }
                  // Switch index for OHLC / Candlestick / Arearange
                  if (isArray(yVal[0])) {
                      index = params.index;
                  }
                  // i = period <-- skip first N-points
                  // Calculate value one-by-one for each period in visible data
                  for (i = period; i < yValLen; i++) {
                      ROCPoint = populateAverage(xVal, yVal, i, period, index);
                      ROC.push(ROCPoint);
                      xData.push(ROCPoint[0]);
                      yData.push(ROCPoint[1]);
                  }
                  return {
                      values: ROC,
                      xData: xData,
                      yData: yData
                  };
              }
          });
          /**
           * A `ROC` series. If the [type](#series.wma.type) option is not
           * specified, it is inherited from [chart.type](#chart.type).
           *
           * Rate of change indicator (ROC). The indicator value for each point
           * is defined as:
           *
           * `(C - Cn) / Cn * 100`
           *
           * where: `C` is the close value of the point of the same x in the
           * linked series and `Cn` is the close value of the point `n` periods
           * ago. `n` is set through [period](#series.roc.params.period).
           *
           * This series requires `linkedTo` option to be set.
           *
           * @extends   series,plotOptions.roc
           * @since     6.0.0
           * @product   highstock
           * @excluding dataParser, dataURL
           * @requires  stock/indicators/indicators
           * @requires  stock/indicators/roc
           * @apioption series.roc
           */
          ''; // to include the above in the js output
  
      });
      _registerModule(_modules, 'indicators/rsi.src.js', [_modules['parts/Globals.js'], _modules['parts/Utilities.js']], function (H, U) {
          /* *
           *
           *  License: www.highcharts.com/license
           *
           *  !!!!!!! SOURCE GETS TRANSPILED BY TYPESCRIPT. EDIT TS FILE ONLY. !!!!!!!
           *
           * */
          var isArray = U.isArray;
          /* eslint-disable require-jsdoc */
          // Utils:
          function toFixed(a, n) {
              return parseFloat(a.toFixed(n));
          }
          /* eslint-enable require-jsdoc */
          /**
           * The RSI series type.
           *
           * @private
           * @class
           * @name Highcharts.seriesTypes.rsi
           *
           * @augments Highcharts.Series
           */
          H.seriesType('rsi', 'sma', 
          /**
           * Relative strength index (RSI) technical indicator. This series
           * requires the `linkedTo` option to be set and should be loaded after
           * the `stock/indicators/indicators.js` file.
           *
           * @sample stock/indicators/rsi
           *         RSI indicator
           *
           * @extends      plotOptions.sma
           * @since        6.0.0
           * @product      highstock
           * @requires     stock/indicators/indicators
           * @requires     stock/indicators/rsi
           * @optionparent plotOptions.rsi
           */
          {
              /**
               * @excluding index
               */
              params: {
                  period: 14,
                  /**
                   * Number of maximum decimals that are used in RSI calculations.
                   */
                  decimals: 4
              }
          }, 
          /**
           * @lends Highcharts.Series#
           */
          {
              getValues: function (series, params) {
                  var period = params.period, xVal = series.xData, yVal = series.yData, yValLen = yVal ? yVal.length : 0, decimals = params.decimals, 
                  // RSI starts calculations from the second point
                  // Cause we need to calculate change between two points
                  range = 1, RSI = [], xData = [], yData = [], index = 3, gain = 0, loss = 0, RSIPoint, change, avgGain, avgLoss, i;
                  // RSI requires close value
                  if ((xVal.length < period) || !isArray(yVal[0]) ||
                      yVal[0].length !== 4) {
                      return false;
                  }
                  // Calculate changes for first N points
                  while (range < period) {
                      change = toFixed(yVal[range][index] - yVal[range - 1][index], decimals);
                      if (change > 0) {
                          gain += change;
                      }
                      else {
                          loss += Math.abs(change);
                      }
                      range++;
                  }
                  // Average for first n-1 points:
                  avgGain = toFixed(gain / (period - 1), decimals);
                  avgLoss = toFixed(loss / (period - 1), decimals);
                  for (i = range; i < yValLen; i++) {
                      change = toFixed(yVal[i][index] - yVal[i - 1][index], decimals);
                      if (change > 0) {
                          gain = change;
                          loss = 0;
                      }
                      else {
                          gain = 0;
                          loss = Math.abs(change);
                      }
                      // Calculate smoothed averages, RS, RSI values:
                      avgGain = toFixed((avgGain * (period - 1) + gain) / period, decimals);
                      avgLoss = toFixed((avgLoss * (period - 1) + loss) / period, decimals);
                      // If average-loss is equal zero, then by definition RSI is set
                      // to 100:
                      if (avgLoss === 0) {
                          RSIPoint = 100;
                          // If average-gain is equal zero, then by definition RSI is set
                          // to 0:
                      }
                      else if (avgGain === 0) {
                          RSIPoint = 0;
                      }
                      else {
                          RSIPoint = toFixed(100 - (100 / (1 + (avgGain / avgLoss))), decimals);
                      }
                      RSI.push([xVal[i], RSIPoint]);
                      xData.push(xVal[i]);
                      yData.push(RSIPoint);
                  }
                  return {
                      values: RSI,
                      xData: xData,
                      yData: yData
                  };
              }
          });
          /**
           * A `RSI` series. If the [type](#series.rsi.type) option is not
           * specified, it is inherited from [chart.type](#chart.type).
           *
           * @extends   series,plotOptions.rsi
           * @since     6.0.0
           * @product   highstock
           * @excluding dataParser, dataURL
           * @requires  stock/indicators/indicators
           * @requires  stock/indicators/rsi
           * @apioption series.rsi
           */
          ''; // to include the above in the js output
  
      });
      _registerModule(_modules, 'indicators/stochastic.src.js', [_modules['parts/Globals.js'], _modules['parts/Utilities.js'], _modules['mixins/reduce-array.js'], _modules['mixins/multipe-lines.js']], function (H, U, reduceArrayMixin, multipleLinesMixin) {
          /* *
           *
           *  License: www.highcharts.com/license
           *
           *  !!!!!!! SOURCE GETS TRANSPILED BY TYPESCRIPT. EDIT TS FILE ONLY. !!!!!!!
           *
           * */
          var isArray = U.isArray;
          var merge = H.merge, 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
           * @requires     stock/indicators/indicators
           * @requires     stock/indicators/stochastic
           * @optionparent plotOptions.stochastic
           */
          {
              /**
               * @excluding index, period
               */
              params: {
                  /**
                   * Periods for Stochastic oscillator: [%K, %D].
                   *
                   * @type    {Array<number,number>}
                   * @default [14, 3]
                   */
                  periods: [14, 3]
              },
              marker: {
                  enabled: false
              },
              tooltip: {
                  pointFormat: '<span style="color:{point.color}">\u25CF</span><b> {series.name}</b><br/>%K: {point.y}<br/>%D: {point.smoothed}<br/>'
              },
              /**
               * 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, 
                  // 0- date, 1-%K, 2-%D
                  SO = [], 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
           * @requires  stock/indicators/indicators
           * @requires  stock/indicators/stochastic
           * @apioption series.stochastic
           */
          ''; // to include the above in the js output
  
      });
      _registerModule(_modules, 'indicators/supertrend.src.js', [_modules['parts/Globals.js'], _modules['parts/Utilities.js']], function (H, U) {
          /* *
           *
           *  License: www.highcharts.com/license
           *
           *  !!!!!!! SOURCE GETS TRANSPILED BY TYPESCRIPT. EDIT TS FILE ONLY. !!!!!!!
           *
           * */
          var isArray = U.isArray, objectEach = U.objectEach;
          var ATR = H.seriesTypes.atr, SMA = H.seriesTypes.sma, merge = H.merge, correctFloat = H.correctFloat;
          /* eslint-disable require-jsdoc */
          // Utils:
          function createPointObj(mainSeries, index, close) {
              return {
                  index: index,
                  close: mainSeries.yData[index][close],
                  x: mainSeries.xData[index]
              };
          }
          /* eslint-enable require-jsdoc */
          /**
           * The Supertrend series type.
           *
           * @private
           * @class
           * @name Highcharts.seriesTypes.supertrend
           *
           * @augments Highcharts.Series
           */
          H.seriesType('supertrend', 'sma', 
          /**
           * Supertrend indicator. This series requires the `linkedTo` option to be
           * set and should be loaded after the `stock/indicators/indicators.js` and
           * `stock/indicators/sma.js`.
           *
           * @sample {highstock} stock/indicators/supertrend
           *         Supertrend indicator
           *
           * @extends      plotOptions.sma
           * @since        7.0.0
           * @product      highstock
           * @excluding    allAreas, color, cropThreshold, negativeColor, colorAxis,
           *               joinBy, keys, navigatorOptions, pointInterval,
           *               pointIntervalUnit, pointPlacement, pointRange, pointStart,
           *               showInNavigator, stacking, threshold
           * @requires     stock/indicators/indicators
           * @requires     stock/indicators/supertrend
           * @optionparent plotOptions.supertrend
           */
          {
              /**
               * Paramters used in calculation of Supertrend indicator series points.
               *
               * @excluding index
               */
              params: {
                  /**
                   * Multiplier for Supertrend Indicator.
                   */
                  multiplier: 3,
                  /**
                   * The base period for indicator Supertrend Indicator calculations.
                   * This is the number of data points which are taken into account
                   * for the indicator calculations.
                   */
                  period: 10
              },
              /**
               * Color of the Supertrend series line that is beneath the main series.
               *
               * @sample {highstock} stock/indicators/supertrend/
               *         Example with risingTrendColor
               *
               * @type {Highcharts.ColorString}
               */
              risingTrendColor: '#06B535',
              /**
               * Color of the Supertrend series line that is above the main series.
               *
               * @sample {highstock} stock/indicators/supertrend/
               *         Example with fallingTrendColor
               *
               * @type {Highcharts.ColorString}
               */
              fallingTrendColor: '#F21313',
              /**
               * The styles for the Supertrend line that intersect main series.
               *
               * @sample {highstock} stock/indicators/supertrend/
               *         Example with changeTrendLine
               */
              changeTrendLine: {
                  styles: {
                      /**
                       * Pixel width of the line.
                       */
                      lineWidth: 1,
                      /**
                       * Color of the line.
                       *
                       * @type {Highcharts.ColorString}
                       */
                      lineColor: '#333333',
                      /**
                       * The dash or dot style of the grid lines. For possible
                       * values, see
                       * [this demonstration](https://jsfiddle.net/gh/get/library/pure/highcharts/highcharts/tree/master/samples/highcharts/plotoptions/series-dashstyle-all/).
                       *
                       * @sample {highcharts} highcharts/yaxis/gridlinedashstyle/
                       *         Long dashes
                       * @sample {highstock} stock/xaxis/gridlinedashstyle/
                       *         Long dashes
                       *
                       * @type  {Highcharts.DashStyleValue}
                       * @since 7.0.0
                       */
                      dashStyle: 'LongDash'
                  }
              }
          }, 
          /**
           * @lends Highcharts.Series.prototype
           */
          {
              nameBase: 'Supertrend',
              nameComponents: ['multiplier', 'period'],
              requiredIndicators: ['atr'],
              init: function () {
                  var options, parentOptions;
                  SMA.prototype.init.apply(this, arguments);
                  options = this.options;
                  parentOptions = this.linkedParent.options;
                  // Indicator cropThreshold has to be equal linked series one
                  // reduced by period due to points comparison in drawGraph method
                  // (#9787)
                  options.cropThreshold = (parentOptions.cropThreshold -
                      (options.params.period - 1));
              },
              drawGraph: function () {
                  var indicator = this, indicOptions = indicator.options, 
                  // Series that indicator is linked to
                  mainSeries = indicator.linkedParent, mainLinePoints = (mainSeries ? mainSeries.points : []), indicPoints = indicator.points, indicPath = indicator.graph, indicPointsLen = indicPoints.length, 
                  // Points offset between lines
                  tempOffset = mainLinePoints.length - indicPointsLen, offset = tempOffset > 0 ? tempOffset : 0, 
                  // @todo: fix when ichi-moku indicator is merged to master.
                  gappedExtend = {
                      options: {
                          gapSize: indicOptions.gapSize
                      }
                  }, 
                  // Sorted supertrend points array
                  groupedPoitns = {
                      top: [],
                      bottom: [],
                      intersect: [] // Change trend line points
                  }, 
                  // Options for trend lines
                  supertrendLineOptions = {
                      top: {
                          styles: {
                              lineWidth: indicOptions.lineWidth,
                              lineColor: indicOptions.fallingTrendColor,
                              dashStyle: indicOptions.dashStyle
                          }
                      },
                      bottom: {
                          styles: {
                              lineWidth: indicOptions.lineWidth,
                              lineColor: indicOptions.risingTrendColor,
                              dashStyle: indicOptions.dashStyle
                          }
                      },
                      intersect: indicOptions.changeTrendLine
                  }, close = 3, 
                  // Supertrend line point
                  point, 
                  // Supertrend line next point (has smaller x pos than point)
                  nextPoint, 
                  // Main series points
                  mainPoint, nextMainPoint, 
                  // Used when supertrend and main points are shifted
                  // relative to each other
                  prevMainPoint, prevPrevMainPoint, 
                  // Used when particular point color is set
                  pointColor, 
                  // Temporary points that fill groupedPoitns array
                  newPoint, newNextPoint;
                  // Loop which sort supertrend points
                  while (indicPointsLen--) {
                      point = indicPoints[indicPointsLen];
                      nextPoint = indicPoints[indicPointsLen - 1];
                      mainPoint = mainLinePoints[indicPointsLen - 1 + offset];
                      nextMainPoint = mainLinePoints[indicPointsLen - 2 + offset];
                      prevMainPoint = mainLinePoints[indicPointsLen + offset];
                      prevPrevMainPoint = mainLinePoints[indicPointsLen + offset + 1];
                      pointColor = point.options.color;
                      newPoint = {
                          x: point.x,
                          plotX: point.plotX,
                          plotY: point.plotY,
                          isNull: false
                      };
                      // When mainPoint is the last one (left plot area edge)
                      // but supertrend has additional one
                      if (!nextMainPoint &&
                          mainPoint && mainSeries.yData[mainPoint.index - 1]) {
                          nextMainPoint = createPointObj(mainSeries, mainPoint.index - 1, close);
                      }
                      // When prevMainPoint is the last one (right plot area edge)
                      // but supertrend has additional one (and points are shifted)
                      if (!prevPrevMainPoint &&
                          prevMainPoint && mainSeries.yData[prevMainPoint.index + 1]) {
                          prevPrevMainPoint = createPointObj(mainSeries, prevMainPoint.index + 1, close);
                      }
                      // When points are shifted (right or left plot area edge)
                      if (!mainPoint &&
                          nextMainPoint && mainSeries.yData[nextMainPoint.index + 1]) {
                          mainPoint = createPointObj(mainSeries, nextMainPoint.index + 1, close);
                      }
                      else if (!mainPoint &&
                          prevMainPoint && mainSeries.yData[prevMainPoint.index - 1]) {
                          mainPoint = createPointObj(mainSeries, prevMainPoint.index - 1, close);
                      }
                      // Check if points are shifted relative to each other
                      if (point &&
                          mainPoint &&
                          prevMainPoint &&
                          nextMainPoint &&
                          point.x !== mainPoint.x) {
                          if (point.x === prevMainPoint.x) {
                              nextMainPoint = mainPoint;
                              mainPoint = prevMainPoint;
                          }
                          else if (point.x === nextMainPoint.x) {
                              mainPoint = nextMainPoint;
                              nextMainPoint = {
                                  close: mainSeries.yData[mainPoint.index - 1][close],
                                  x: mainSeries.xData[mainPoint.index - 1]
                              };
                          }
                          else if (prevPrevMainPoint && point.x === prevPrevMainPoint.x) {
                              mainPoint = prevPrevMainPoint;
                              nextMainPoint = prevMainPoint;
                          }
                      }
                      if (nextPoint && nextMainPoint && mainPoint) {
                          newNextPoint = {
                              x: nextPoint.x,
                              plotX: nextPoint.plotX,
                              plotY: nextPoint.plotY,
                              isNull: false
                          };
                          if (point.y >= mainPoint.close &&
                              nextPoint.y >= nextMainPoint.close) {
                              point.color =
                                  pointColor || indicOptions.fallingTrendColor;
                              groupedPoitns.top.push(newPoint);
                          }
                          else if (point.y < mainPoint.close &&
                              nextPoint.y < nextMainPoint.close) {
                              point.color =
                                  pointColor || indicOptions.risingTrendColor;
                              groupedPoitns.bottom.push(newPoint);
                          }
                          else {
                              groupedPoitns.intersect.push(newPoint);
                              groupedPoitns.intersect.push(newNextPoint);
                              // Additional null point to make a gap in line
                              groupedPoitns.intersect.push(merge(newNextPoint, {
                                  isNull: true
                              }));
                              if (point.y >= mainPoint.close &&
                                  nextPoint.y < nextMainPoint.close) {
                                  point.color =
                                      pointColor || indicOptions.fallingTrendColor;
                                  nextPoint.color =
                                      pointColor || indicOptions.risingTrendColor;
                                  groupedPoitns.top.push(newPoint);
                                  groupedPoitns.top.push(merge(newNextPoint, {
                                      isNull: true
                                  }));
                              }
                              else if (point.y < mainPoint.close &&
                                  nextPoint.y >= nextMainPoint.close) {
                                  point.color =
                                      pointColor || indicOptions.risingTrendColor;
                                  nextPoint.color =
                                      pointColor || indicOptions.fallingTrendColor;
                                  groupedPoitns.bottom.push(newPoint);
                                  groupedPoitns.bottom.push(merge(newNextPoint, {
                                      isNull: true
                                  }));
                              }
                          }
                      }
                      else if (mainPoint) {
                          if (point.y >= mainPoint.close) {
                              point.color =
                                  pointColor || indicOptions.fallingTrendColor;
                              groupedPoitns.top.push(newPoint);
                          }
                          else {
                              point.color =
                                  pointColor || indicOptions.risingTrendColor;
                              groupedPoitns.bottom.push(newPoint);
                          }
                      }
                  }
                  // Generate lines:
                  objectEach(groupedPoitns, function (values, lineName) {
                      indicator.points = values;
                      indicator.options = merge(supertrendLineOptions[lineName].styles, gappedExtend);
                      indicator.graph = indicator['graph' + lineName + 'Line'];
                      SMA.prototype.drawGraph.call(indicator);
                      // Now save line
                      indicator['graph' + lineName + 'Line'] = indicator.graph;
                  });
                  // Restore options:
                  indicator.points = indicPoints;
                  indicator.options = indicOptions;
                  indicator.graph = indicPath;
              },
              // Supertrend (Multiplier, Period) Formula:
              // BASIC UPPERBAND = (HIGH + LOW) / 2 + Multiplier * ATR(Period)
              // BASIC LOWERBAND = (HIGH + LOW) / 2 - Multiplier * ATR(Period)
              // FINAL UPPERBAND =
              //     IF(
              //      Current BASICUPPERBAND  < Previous FINAL UPPERBAND AND
              //      Previous Close > Previous FINAL UPPERBAND
              //     ) THEN (Current BASIC UPPERBAND)
              //     ELSE (Previous FINALUPPERBAND)
              // FINAL LOWERBAND =
              //     IF(
              //      Current BASIC LOWERBAND  > Previous FINAL LOWERBAND AND
              //      Previous Close < Previous FINAL LOWERBAND
              //     ) THEN (Current BASIC LOWERBAND)
              //     ELSE (Previous FINAL LOWERBAND)
              // SUPERTREND =
              //     IF(
              //      Previous Supertrend == Previous FINAL UPPERBAND AND
              //      Current Close < Current FINAL UPPERBAND
              //     ) THAN Current FINAL UPPERBAND
              //     ELSE IF(
              //      Previous Supertrend == Previous FINAL LOWERBAND AND
              //      Current Close < Current FINAL LOWERBAND
              //     ) THAN Current FINAL UPPERBAND
              //     ELSE IF(
              //      Previous Supertrend == Previous FINAL UPPERBAND AND
              //      Current Close > Current FINAL UPPERBAND
              //     ) THAN Current FINAL LOWERBAND
              //     ELSE IF(
              //      Previous Supertrend == Previous FINAL LOWERBAND AND
              //      Current Close > Current FINAL LOWERBAND
              //     ) THAN Current FINAL LOWERBAND
              getValues: function (series, params) {
                  var period = params.period, multiplier = params.multiplier, xVal = series.xData, yVal = series.yData, ATRData = [], 
                  // 0- date, 1- Supertrend indicator
                  ST = [], xData = [], yData = [], close = 3, low = 2, high = 1, periodsOffset = (period === 0) ? 0 : period - 1, basicUp, basicDown, finalUp = [], finalDown = [], supertrend, prevFinalUp, prevFinalDown, prevST, // previous Supertrend
                  prevY, y, i;
                  if ((xVal.length <= period) || !isArray(yVal[0]) ||
                      yVal[0].length !== 4 || period < 0) {
                      return false;
                  }
                  ATRData = ATR.prototype.getValues.call(this, series, {
                      period: period
                  }).yData;
                  for (i = 0; i < ATRData.length; i++) {
                      y = yVal[periodsOffset + i];
                      prevY = yVal[periodsOffset + i - 1] || [];
                      prevFinalUp = finalUp[i - 1];
                      prevFinalDown = finalDown[i - 1];
                      prevST = yData[i - 1];
                      if (i === 0) {
                          prevFinalUp = prevFinalDown = prevST = 0;
                      }
                      basicUp = correctFloat((y[high] + y[low]) / 2 + multiplier * ATRData[i]);
                      basicDown = correctFloat((y[high] + y[low]) / 2 - multiplier * ATRData[i]);
                      if ((basicUp < prevFinalUp) ||
                          (prevY[close] > prevFinalUp)) {
                          finalUp[i] = basicUp;
                      }
                      else {
                          finalUp[i] = prevFinalUp;
                      }
                      if ((basicDown > prevFinalDown) ||
                          (prevY[close] < prevFinalDown)) {
                          finalDown[i] = basicDown;
                      }
                      else {
                          finalDown[i] = prevFinalDown;
                      }
                      if (prevST === prevFinalUp && y[close] < finalUp[i] ||
                          prevST === prevFinalDown && y[close] < finalDown[i]) {
                          supertrend = finalUp[i];
                      }
                      else if (prevST === prevFinalUp && y[close] > finalUp[i] ||
                          prevST === prevFinalDown && y[close] > finalDown[i]) {
                          supertrend = finalDown[i];
                      }
                      ST.push([xVal[periodsOffset + i], supertrend]);
                      xData.push(xVal[periodsOffset + i]);
                      yData.push(supertrend);
                  }
                  return {
                      values: ST,
                      xData: xData,
                      yData: yData
                  };
              }
          });
          /**
           * A `Supertrend indicator` series. If the [type](#series.supertrend.type)
           * option is not specified, it is inherited from [chart.type](#chart.type).
           *
           * @extends   series,plotOptions.supertrend
           * @since     7.0.0
           * @product   highstock
           * @excluding allAreas, color, colorAxis, cropThreshold, data, dataParser,
           *            dataURL, joinBy, keys, navigatorOptions, negativeColor,
           *            pointInterval, pointIntervalUnit, pointPlacement, pointRange,
           *            pointStart, showInNavigator, stacking, threshold
           * @requires  stock/indicators/indicators
           * @requires  stock/indicators/supertrend
           * @apioption series.supertrend
           */
          ''; // to include the above in the js output
  
      });
      _registerModule(_modules, 'indicators/volume-by-price.src.js', [_modules['parts/Globals.js'], _modules['parts/Utilities.js']], function (H, U) {
          /* *
           *
           *  (c) 2010-2019 Paweł Dalek
           *
           *  Volume By Price (VBP) indicator for Highstock
           *
           *  License: www.highcharts.com/license
           *
           *  !!!!!!! SOURCE GETS TRANSPILED BY TYPESCRIPT. EDIT TS FILE ONLY. !!!!!!!
           *
           * */
          var arrayMax = U.arrayMax, arrayMin = U.arrayMin, extend = U.extend, isArray = U.isArray;
          /* eslint-disable require-jsdoc */
          // Utils
          function arrayExtremesOHLC(data) {
              var dataLength = data.length, min = data[0][3], max = min, i = 1, currentPoint;
              for (; i < dataLength; i++) {
                  currentPoint = data[i][3];
                  if (currentPoint < min) {
                      min = currentPoint;
                  }
                  if (currentPoint > max) {
                      max = currentPoint;
                  }
              }
              return {
                  min: min,
                  max: max
              };
          }
          /* eslint-enable require-jsdoc */
          var abs = Math.abs, noop = H.noop, addEvent = H.addEvent, correctFloat = H.correctFloat, seriesType = H.seriesType, columnPrototype = H.seriesTypes.column.prototype;
          /**
           * The Volume By Price (VBP) series type.
           *
           * @private
           * @class
           * @name Highcharts.seriesTypes.vbp
           *
           * @augments Highcharts.Series
           */
          seriesType('vbp', 'sma', 
          /**
           * Volume By Price indicator.
           *
           * This series requires `linkedTo` option to be set.
           *
           * @sample stock/indicators/volume-by-price
           *         Volume By Price indicator
           *
           * @extends      plotOptions.sma
           * @since        6.0.0
           * @product      highstock
           * @requires     stock/indicators/indicators
           * @requires     stock/indicators/volume-by-price
           * @optionparent plotOptions.vbp
           */
          {
              /**
               * @excluding index, period
               */
              params: {
                  /**
                   * The number of price zones.
                   */
                  ranges: 12,
                  /**
                   * The id of volume series which is mandatory. For example using
                   * OHLC data, volumeSeriesID='volume' means the indicator will be
                   * calculated using OHLC and volume values.
                   */
                  volumeSeriesID: 'volume'
              },
              /**
               * The styles for lines which determine price zones.
               */
              zoneLines: {
                  /**
                   * Enable/disable zone lines.
                   */
                  enabled: true,
                  /**
                   * Specify the style of zone lines.
                   *
                   * @type    {Highcharts.CSSObject}
                   * @default {"color": "#0A9AC9", "dashStyle": "LongDash", "lineWidth": 1}
                   */
                  styles: {
                      /** @ignore-options */
                      color: '#0A9AC9',
                      /** @ignore-options */
                      dashStyle: 'LongDash',
                      /** @ignore-options */
                      lineWidth: 1
                  }
              },
              /**
               * The styles for bars when volume is divided into positive/negative.
               */
              volumeDivision: {
                  /**
                   * Option to control if volume is divided.
                   */
                  enabled: true,
                  styles: {
                      /**
                       * Color of positive volume bars.
                       *
                       * @type {Highcharts.ColorString}
                       */
                      positiveColor: 'rgba(144, 237, 125, 0.8)',
                      /**
                       * Color of negative volume bars.
                       *
                       * @type {Highcharts.ColorString}
                       */
                      negativeColor: 'rgba(244, 91, 91, 0.8)'
                  }
              },
              // To enable series animation; must be animationLimit > pointCount
              animationLimit: 1000,
              enableMouseTracking: false,
              pointPadding: 0,
              zIndex: -1,
              crisp: true,
              dataGrouping: {
                  enabled: false
              },
              dataLabels: {
                  /** @ignore-option */
                  allowOverlap: true,
                  /** @ignore-option */
                  enabled: true,
                  /** @ignore-option */
                  format: 'P: {point.volumePos:.2f} | N: {point.volumeNeg:.2f}',
                  /** @ignore-option */
                  padding: 0,
                  /** @ignore-option */
                  style: {
                      fontSize: '7px'
                  },
                  /** @ignore-option */
                  verticalAlign: 'top'
              }
          }, 
          /**
           * @lends Highcharts.Series#
           */
          {
              nameBase: 'Volume by Price',
              bindTo: {
                  series: false,
                  eventName: 'afterSetExtremes'
              },
              calculateOn: 'render',
              markerAttribs: noop,
              drawGraph: noop,
              getColumnMetrics: columnPrototype.getColumnMetrics,
              crispCol: columnPrototype.crispCol,
              init: function (chart) {
                  var indicator = this, params, baseSeries, volumeSeries;
                  H.seriesTypes.sma.prototype.init.apply(indicator, arguments);
                  params = indicator.options.params;
                  baseSeries = indicator.linkedParent;
                  volumeSeries = chart.get(params.volumeSeriesID);
                  indicator.addCustomEvents(baseSeries, volumeSeries);
                  return indicator;
              },
              // Adds events related with removing series
              addCustomEvents: function (baseSeries, volumeSeries) {
                  var indicator = this;
                  /* eslint-disable require-jsdoc */
                  function toEmptyIndicator() {
                      indicator.chart.redraw();
                      indicator.setData([]);
                      indicator.zoneStarts = [];
                      if (indicator.zoneLinesSVG) {
                          indicator.zoneLinesSVG.destroy();
                          delete indicator.zoneLinesSVG;
                      }
                  }
                  /* eslint-enable require-jsdoc */
                  // If base series is deleted, indicator series data is filled with
                  // an empty array
                  indicator.dataEventsToUnbind.push(addEvent(baseSeries, 'remove', function () {
                      toEmptyIndicator();
                  }));
                  // If volume series is deleted, indicator series data is filled with
                  // an empty array
                  if (volumeSeries) {
                      indicator.dataEventsToUnbind.push(addEvent(volumeSeries, 'remove', function () {
                          toEmptyIndicator();
                      }));
                  }
                  return indicator;
              },
              // Initial animation
              animate: function (init) {
                  var series = this, attr = {};
                  if (H.svg && !init) {
                      attr.translateX = series.yAxis.pos;
                      series.group.animate(attr, extend(H.animObject(series.options.animation), {
                          step: function (val, fx) {
                              series.group.attr({
                                  scaleX: Math.max(0.001, fx.pos)
                              });
                          }
                      }));
                      // Delete this function to allow it only once
                      series.animate = null;
                  }
              },
              drawPoints: function () {
                  var indicator = this;
                  if (indicator.options.volumeDivision.enabled) {
                      indicator.posNegVolume(true, true);
                      columnPrototype.drawPoints.apply(indicator, arguments);
                      indicator.posNegVolume(false, false);
                  }
                  columnPrototype.drawPoints.apply(indicator, arguments);
              },
              // Function responsible for dividing volume into positive and negative
              posNegVolume: function (initVol, pos) {
                  var indicator = this, signOrder = pos ?
                      ['positive', 'negative'] :
                      ['negative', 'positive'], volumeDivision = indicator.options.volumeDivision, pointLength = indicator.points.length, posWidths = [], negWidths = [], i = 0, pointWidth, priceZone, wholeVol, point;
                  if (initVol) {
                      indicator.posWidths = posWidths;
                      indicator.negWidths = negWidths;
                  }
                  else {
                      posWidths = indicator.posWidths;
                      negWidths = indicator.negWidths;
                  }
                  for (; i < pointLength; i++) {
                      point = indicator.points[i];
                      point[signOrder[0] + 'Graphic'] = point.graphic;
                      point.graphic = point[signOrder[1] + 'Graphic'];
                      if (initVol) {
                          pointWidth = point.shapeArgs.width;
                          priceZone = indicator.priceZones[i];
                          wholeVol = priceZone.wholeVolumeData;
                          if (wholeVol) {
                              posWidths.push(pointWidth / wholeVol * priceZone.positiveVolumeData);
                              negWidths.push(pointWidth / wholeVol * priceZone.negativeVolumeData);
                          }
                          else {
                              posWidths.push(0);
                              negWidths.push(0);
                          }
                      }
                      point.color = pos ?
                          volumeDivision.styles.positiveColor :
                          volumeDivision.styles.negativeColor;
                      point.shapeArgs.width = pos ?
                          indicator.posWidths[i] :
                          indicator.negWidths[i];
                      point.shapeArgs.x = pos ?
                          point.shapeArgs.x :
                          indicator.posWidths[i];
                  }
              },
              translate: function () {
                  var indicator = this, options = indicator.options, chart = indicator.chart, yAxis = indicator.yAxis, yAxisMin = yAxis.min, zoneLinesOptions = indicator.options.zoneLines, priceZones = (indicator.priceZones), yBarOffset = 0, indicatorPoints, volumeDataArray, maxVolume, primalBarWidth, barHeight, barHeightP, oldBarHeight, barWidth, pointPadding, chartPlotTop, barX, barY;
                  columnPrototype.translate.apply(indicator);
                  indicatorPoints = indicator.points;
                  // Do translate operation when points exist
                  if (indicatorPoints.length) {
                      pointPadding = options.pointPadding < 0.5 ?
                          options.pointPadding :
                          0.1;
                      volumeDataArray = indicator.volumeDataArray;
                      maxVolume = arrayMax(volumeDataArray);
                      primalBarWidth = chart.plotWidth / 2;
                      chartPlotTop = chart.plotTop;
                      barHeight = abs(yAxis.toPixels(yAxisMin) -
                          yAxis.toPixels(yAxisMin + indicator.rangeStep));
                      oldBarHeight = abs(yAxis.toPixels(yAxisMin) -
                          yAxis.toPixels(yAxisMin + indicator.rangeStep));
                      if (pointPadding) {
                          barHeightP = abs(barHeight * (1 - 2 * pointPadding));
                          yBarOffset = abs((barHeight - barHeightP) / 2);
                          barHeight = abs(barHeightP);
                      }
                      indicatorPoints.forEach(function (point, index) {
                          barX = point.barX = point.plotX = 0;
                          barY = point.plotY = (yAxis.toPixels(priceZones[index].start) -
                              chartPlotTop -
                              (yAxis.reversed ?
                                  (barHeight - oldBarHeight) :
                                  barHeight) -
                              yBarOffset);
                          barWidth = correctFloat(primalBarWidth *
                              priceZones[index].wholeVolumeData / maxVolume);
                          point.pointWidth = barWidth;
                          point.shapeArgs = indicator.crispCol.apply(// eslint-disable-line no-useless-call
                          indicator, [barX, barY, barWidth, barHeight]);
                          point.volumeNeg = priceZones[index].negativeVolumeData;
                          point.volumePos = priceZones[index].positiveVolumeData;
                          point.volumeAll = priceZones[index].wholeVolumeData;
                      });
                      if (zoneLinesOptions.enabled) {
                          indicator.drawZones(chart, yAxis, indicator.zoneStarts, zoneLinesOptions.styles);
                      }
                  }
              },
              getValues: function (series, params) {
                  var indicator = this, xValues = series.processedXData, yValues = series.processedYData, chart = indicator.chart, ranges = params.ranges, VBP = [], xData = [], yData = [], isOHLC, volumeSeries, priceZones;
                  // Checks if base series exists
                  if (!series.chart) {
                      return H.error('Base series not found! In case it has been removed, add ' +
                          'a new one.', true, chart);
                  }
                  // Checks if volume series exists
                  if (!(volumeSeries = (chart.get(params.volumeSeriesID)))) {
                      return H.error('Series ' +
                          params.volumeSeriesID +
                          ' not found! Check `volumeSeriesID`.', true, chart);
                  }
                  // Checks if series data fits the OHLC format
                  isOHLC = isArray(yValues[0]);
                  if (isOHLC && yValues[0].length !== 4) {
                      return H.error('Type of ' +
                          series.name +
                          ' series is different than line, OHLC or candlestick.', true, chart);
                  }
                  // Price zones contains all the information about the zones (index,
                  // start, end, volumes, etc.)
                  priceZones = indicator.priceZones = indicator.specifyZones(isOHLC, xValues, yValues, ranges, volumeSeries);
                  priceZones.forEach(function (zone, index) {
                      VBP.push([zone.x, zone.end]);
                      xData.push(VBP[index][0]);
                      yData.push(VBP[index][1]);
                  });
                  return {
                      values: VBP,
                      xData: xData,
                      yData: yData
                  };
              },
              // Specifing where each zone should start ans end
              specifyZones: function (isOHLC, xValues, yValues, ranges, volumeSeries) {
                  var indicator = this, rangeExtremes = (isOHLC ? arrayExtremesOHLC(yValues) : false), lowRange = rangeExtremes ?
                      rangeExtremes.min :
                      arrayMin(yValues), highRange = rangeExtremes ?
                      rangeExtremes.max :
                      arrayMax(yValues), zoneStarts = indicator.zoneStarts = [], priceZones = [], i = 0, j = 1, rangeStep, zoneStartsLength;
                  if (!lowRange || !highRange) {
                      if (this.points.length) {
                          this.setData([]);
                          this.zoneStarts = [];
                          this.zoneLinesSVG.destroy();
                      }
                      return [];
                  }
                  rangeStep = indicator.rangeStep =
                      correctFloat(highRange - lowRange) / ranges;
                  zoneStarts.push(lowRange);
                  for (; i < ranges - 1; i++) {
                      zoneStarts.push(correctFloat(zoneStarts[i] + rangeStep));
                  }
                  zoneStarts.push(highRange);
                  zoneStartsLength = zoneStarts.length;
                  //    Creating zones
                  for (; j < zoneStartsLength; j++) {
                      priceZones.push({
                          index: j - 1,
                          x: xValues[0],
                          start: zoneStarts[j - 1],
                          end: zoneStarts[j]
                      });
                  }
                  return indicator.volumePerZone(isOHLC, priceZones, volumeSeries, xValues, yValues);
              },
              // Calculating sum of volume values for a specific zone
              volumePerZone: function (isOHLC, priceZones, volumeSeries, xValues, yValues) {
                  var indicator = this, volumeXData = volumeSeries.processedXData, volumeYData = volumeSeries.processedYData, lastZoneIndex = priceZones.length - 1, baseSeriesLength = yValues.length, volumeSeriesLength = volumeYData.length, previousValue, startFlag, endFlag, value, i;
                  // Checks if each point has a corresponding volume value
                  if (abs(baseSeriesLength - volumeSeriesLength)) {
                      // If the first point don't have volume, add 0 value at the
                      // beggining of the volume array
                      if (xValues[0] !== volumeXData[0]) {
                          volumeYData.unshift(0);
                      }
                      // If the last point don't have volume, add 0 value at the end
                      // of the volume array
                      if (xValues[baseSeriesLength - 1] !==
                          volumeXData[volumeSeriesLength - 1]) {
                          volumeYData.push(0);
                      }
                  }
                  indicator.volumeDataArray = [];
                  priceZones.forEach(function (zone) {
                      zone.wholeVolumeData = 0;
                      zone.positiveVolumeData = 0;
                      zone.negativeVolumeData = 0;
                      for (i = 0; i < baseSeriesLength; i++) {
                          startFlag = false;
                          endFlag = false;
                          value = isOHLC ? yValues[i][3] : yValues[i];
                          previousValue = i ?
                              (isOHLC ?
                                  yValues[i - 1][3] :
                                  yValues[i - 1]) :
                              value;
                          // Checks if this is the point with the
                          // lowest close value and if so, adds it calculations
                          if (value <= zone.start && zone.index === 0) {
                              startFlag = true;
                          }
                          // Checks if this is the point with the highest
                          // close value and if so, adds it calculations
                          if (value >= zone.end && zone.index === lastZoneIndex) {
                              endFlag = true;
                          }
                          if ((value > zone.start || startFlag) &&
                              (value < zone.end || endFlag)) {
                              zone.wholeVolumeData += volumeYData[i];
                              if (previousValue > value) {
                                  zone.negativeVolumeData += volumeYData[i];
                              }
                              else {
                                  zone.positiveVolumeData += volumeYData[i];
                              }
                          }
                      }
                      indicator.volumeDataArray.push(zone.wholeVolumeData);
                  });
                  return priceZones;
              },
              // Function responsoble for drawing additional lines indicating zones
              drawZones: function (chart, yAxis, zonesValues, zonesStyles) {
                  var indicator = this, renderer = chart.renderer, zoneLinesSVG = indicator.zoneLinesSVG, zoneLinesPath = [], leftLinePos = 0, rightLinePos = chart.plotWidth, verticalOffset = chart.plotTop, verticalLinePos;
                  zonesValues.forEach(function (value) {
                      verticalLinePos = yAxis.toPixels(value) - verticalOffset;
                      zoneLinesPath = zoneLinesPath.concat(chart.renderer.crispLine([
                          'M',
                          leftLinePos,
                          verticalLinePos,
                          'L',
                          rightLinePos,
                          verticalLinePos
                      ], zonesStyles.lineWidth));
                  });
                  // Create zone lines one path or update it while animating
                  if (zoneLinesSVG) {
                      zoneLinesSVG.animate({
                          d: zoneLinesPath
                      });
                  }
                  else {
                      zoneLinesSVG = indicator.zoneLinesSVG =
                          renderer.path(zoneLinesPath).attr({
                              'stroke-width': zonesStyles.lineWidth,
                              'stroke': zonesStyles.color,
                              'dashstyle': zonesStyles.dashStyle,
                              'zIndex': indicator.group.zIndex + 0.1
                          })
                              .add(indicator.group);
                  }
              }
          }, 
          /**
           * @lends Highcharts.Point#
           */
          {
              // Required for destroying negative part of volume
              destroy: function () {
                  // @todo: this.negativeGraphic doesn't seem to be used anywhere
                  if (this.negativeGraphic) {
                      this.negativeGraphic = this.negativeGraphic.destroy();
                  }
                  return H.Point.prototype.destroy.apply(this, arguments);
              }
          });
          /**
           * A `Volume By Price (VBP)` series. If the [type](#series.vbp.type) option is
           * not specified, it is inherited from [chart.type](#chart.type).
           *
           * @extends   series,plotOptions.vbp
           * @since     6.0.0
           * @product   highstock
           * @excluding dataParser, dataURL
           * @requires  stock/indicators/indicators
           * @requires  stock/indicators/volume-by-price
           * @apioption series.vbp
           */
          ''; // to include the above in the js output
  
      });
      _registerModule(_modules, 'indicators/vwap.src.js', [_modules['parts/Globals.js'], _modules['parts/Utilities.js']], function (H, U) {
          /* *
           *
           *  (c) 2010-2019 Paweł Dalek
           *
           *  Volume Weighted Average Price (VWAP) indicator for Highstock
           *
           *  License: www.highcharts.com/license
           *
           *  !!!!!!! SOURCE GETS TRANSPILED BY TYPESCRIPT. EDIT TS FILE ONLY. !!!!!!!
           *
           * */
          var isArray = U.isArray;
          var seriesType = H.seriesType;
          /**
           * The Volume Weighted Average Price (VWAP) series type.
           *
           * @private
           * @class
           * @name Highcharts.seriesTypes.vwap
           *
           * @augments Highcharts.Series
           */
          seriesType('vwap', 'sma', 
          /**
           * Volume Weighted Average Price indicator.
           *
           * This series requires `linkedTo` option to be set.
           *
           * @sample stock/indicators/vwap
           *         Volume Weighted Average Price indicator
           *
           * @extends      plotOptions.sma
           * @since        6.0.0
           * @product      highstock
           * @requires     stock/indicators/indicators
           * @requires     stock/indicators/vwap
           * @optionparent plotOptions.vwap
           */
          {
              /**
               * @excluding index
               */
              params: {
                  period: 30,
                  /**
                   * The id of volume series which is mandatory. For example using
                   * OHLC data, volumeSeriesID='volume' means the indicator will be
                   * calculated using OHLC and volume values.
                   */
                  volumeSeriesID: 'volume'
              }
          }, 
          /**
           * @lends Highcharts.Series#
           */
          {
              /**
               * Returns the final values of the indicator ready to be presented on a
               * chart
               * @private
               * @param {Highcharts.VWAPIndicator} this indicator
               * @param {Highcharts.Series} series - series for indicator
               * @param {object} params - params
               * @return {object} - computed VWAP
               **/
              getValues: function (series, params) {
                  var indicator = this, chart = series.chart, xValues = series.xData, yValues = series.yData, period = params.period, isOHLC = true, volumeSeries;
                  // Checks if volume series exists
                  if (!(volumeSeries = (chart.get(params.volumeSeriesID)))) {
                      return H.error('Series ' +
                          params.volumeSeriesID +
                          ' not found! Check `volumeSeriesID`.', true, chart);
                  }
                  // Checks if series data fits the OHLC format
                  if (!(isArray(yValues[0]))) {
                      isOHLC = false;
                  }
                  return indicator.calculateVWAPValues(isOHLC, xValues, yValues, volumeSeries, period);
              },
              /**
               * Main algorithm used to calculate Volume Weighted Average Price (VWAP)
               * values
               * @private
               * @param {boolean} isOHLC - says if data has OHLC format
               * @param {Array<number>} xValues - array of timestamps
               * @param {Array<number|Array<number,number,number,number>>} yValues -
               * array of yValues, can be an array of a four arrays (OHLC) or array of
               * values (line)
               * @param {Array<*>} volumeSeries - volume series
               * @param {number} period - number of points to be calculated
               * @return {object} - Object contains computed VWAP
               **/
              calculateVWAPValues: function (isOHLC, xValues, yValues, volumeSeries, period) {
                  var volumeValues = volumeSeries.yData, volumeLength = volumeSeries.xData.length, pointsLength = xValues.length, cumulativePrice = [], cumulativeVolume = [], xData = [], yData = [], VWAP = [], commonLength, typicalPrice, cPrice, cVolume, i, j;
                  if (pointsLength <= volumeLength) {
                      commonLength = pointsLength;
                  }
                  else {
                      commonLength = volumeLength;
                  }
                  for (i = 0, j = 0; i < commonLength; i++) {
                      // Depending on whether series is OHLC or line type, price is
                      // average of the high, low and close or a simple value
                      typicalPrice = isOHLC ?
                          ((yValues[i][1] + yValues[i][2] +
                              yValues[i][3]) / 3) :
                          yValues[i];
                      typicalPrice *= volumeValues[i];
                      cPrice = j ?
                          (cumulativePrice[i - 1] + typicalPrice) :
                          typicalPrice;
                      cVolume = j ?
                          (cumulativeVolume[i - 1] + volumeValues[i]) :
                          volumeValues[i];
                      cumulativePrice.push(cPrice);
                      cumulativeVolume.push(cVolume);
                      VWAP.push([xValues[i], (cPrice / cVolume)]);
                      xData.push(VWAP[i][0]);
                      yData.push(VWAP[i][1]);
                      j++;
                      if (j === period) {
                          j = 0;
                      }
                  }
                  return {
                      values: VWAP,
                      xData: xData,
                      yData: yData
                  };
              }
          });
          /**
           * A `Volume Weighted Average Price (VWAP)` series. If the
           * [type](#series.vwap.type) option is not specified, it is inherited from
           * [chart.type](#chart.type).
           *
           * @extends   series,plotOptions.vwap
           * @since     6.0.0
           * @product   highstock
           * @excluding dataParser, dataURL
           * @requires  stock/indicators/indicators
           * @requires  stock/indicators/vwap
           * @apioption series.vwap
           */
          ''; // to include the above in the js output
  
      });
      _registerModule(_modules, 'indicators/williams-r.src.js', [_modules['parts/Globals.js'], _modules['parts/Utilities.js'], _modules['mixins/reduce-array.js']], function (H, U, reduceArrayMixin) {
          /* *
           *
           *  License: www.highcharts.com/license
           *
           *  !!!!!!! SOURCE GETS TRANSPILED BY TYPESCRIPT. EDIT TS FILE ONLY. !!!!!!!
           *
           * */
          var isArray = U.isArray;
          var getArrayExtremes = reduceArrayMixin.getArrayExtremes;
          /**
           * The Williams %R series type.
           *
           * @private
           * @class
           * @name Highcharts.seriesTypes.williamsr
           *
           * @augments Highcharts.Series
           */
          H.seriesType('williamsr', 'sma', 
          /**
           * Williams %R. This series requires the `linkedTo` option to be
           * set and should be loaded after the `stock/indicators/indicators.js`.
           *
           * @sample {highstock} stock/indicators/williams-r
           *         Williams %R
           *
           * @extends      plotOptions.sma
           * @since        7.0.0
           * @product      highstock
           * @excluding    allAreas, colorAxis, joinBy, keys, navigatorOptions,
           *               pointInterval, pointIntervalUnit, pointPlacement,
           *               pointRange, pointStart, showInNavigator, stacking
           * @requires     stock/indicators/indicators
           * @requires     stock/indicators/williams-r
           * @optionparent plotOptions.williamsr
           */
          {
              /**
               * Paramters used in calculation of Williams %R series points.
               * @excluding index
               */
              params: {
                  /**
                   * Period for Williams %R oscillator
                   */
                  period: 14
              }
          }, 
          /**
           * @lends Highcharts.Series#
           */
          {
              nameBase: 'Williams %R',
              getValues: function (series, params) {
                  var period = params.period, xVal = series.xData, yVal = series.yData, yValLen = yVal ? yVal.length : 0, WR = [], // 0- date, 1- Williams %R
                  xData = [], yData = [], slicedY, close = 3, low = 2, high = 1, extremes, R, HH, // Highest high value in period
                  LL, // Lowest low value in period
                  CC, // Current close value
                  i;
                  // Williams %R requires close value
                  if (xVal.length < period ||
                      !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 = period - 1; i < yValLen; i++) {
                      slicedY = yVal.slice(i - period + 1, i + 1);
                      extremes = getArrayExtremes(slicedY, low, high);
                      LL = extremes[0];
                      HH = extremes[1];
                      CC = yVal[i][close];
                      R = ((HH - CC) / (HH - LL)) * -100;
                      if (xVal[i]) {
                          WR.push([xVal[i], R]);
                          xData.push(xVal[i]);
                          yData.push(R);
                      }
                  }
                  return {
                      values: WR,
                      xData: xData,
                      yData: yData
                  };
              }
          });
          /**
           * A `Williams %R Oscillator` series. If the [type](#series.williamsr.type)
           * option is not specified, it is inherited from [chart.type](#chart.type).
           *
           * @extends   series,plotOptions.williamsr
           * @since     7.0.0
           * @product   highstock
           * @excluding allAreas, colorAxis, dataParser, dataURL, joinBy, keys,
           *            navigatorOptions, pointInterval, pointIntervalUnit,
           *            pointPlacement, pointRange, pointStart, showInNavigator, stacking
           * @requires  stock/indicators/indicators
           * @requires  stock/indicators/williams-r
           * @apioption series.williamsr
           */
          ''; // adds doclets above to the transpiled file
  
      });
      _registerModule(_modules, 'indicators/wma.src.js', [_modules['parts/Globals.js'], _modules['parts/Utilities.js']], function (H, U) {
          /* *
           *
           *  (c) 2010-2019 Kacper Madej
           *
           *  License: www.highcharts.com/license
           *
           *  !!!!!!! SOURCE GETS TRANSPILED BY TYPESCRIPT. EDIT TS FILE ONLY. !!!!!!!
           *
           * */
          var isArray = U.isArray;
          var seriesType = H.seriesType;
          /* eslint-disable valid-jsdoc */
          // Utils:
          /**
           * @private
           */
          function accumulateAverage(points, xVal, yVal, i, index) {
              var xValue = xVal[i], yValue = index < 0 ? yVal[i] : yVal[i][index];
              points.push([xValue, yValue]);
          }
          /**
           * @private
           */
          function weightedSumArray(array, pLen) {
              // The denominator is the sum of the number of days as a triangular number.
              // If there are 5 days, the triangular numbers are 5, 4, 3, 2, and 1.
              // The sum is 5 + 4 + 3 + 2 + 1 = 15.
              var denominator = (pLen + 1) / 2 * pLen;
              // reduce VS loop => reduce
              return array.reduce(function (prev, cur, i) {
                  return [null, prev[1] + cur[1] * (i + 1)];
              })[1] / denominator;
          }
          /**
           * @private
           */
          function populateAverage(points, xVal, yVal, i) {
              var pLen = points.length, wmaY = weightedSumArray(points, pLen), wmaX = xVal[i - 1];
              points.shift(); // remove point until range < period
              return [wmaX, wmaY];
          }
          /* eslint-enable valid-jsdoc */
          /**
           * The SMA series type.
           *
           * @private
           * @class
           * @name Highcharts.seriesTypes.wma
           *
           * @augments Highcharts.Series
           */
          seriesType('wma', 'sma', 
          /**
           * Weighted moving average indicator (WMA). This series requires `linkedTo`
           * option to be set.
           *
           * @sample stock/indicators/wma
           *         Weighted moving average indicator
           *
           * @extends      plotOptions.sma
           * @since        6.0.0
           * @product      highstock
           * @requires     stock/indicators/indicators
           * @requires     stock/indicators/wma
           * @optionparent plotOptions.wma
           */
          {
              params: {
                  index: 3,
                  period: 9
              }
          }, 
          /**
           * @lends Highcharts.Series#
           */
          {
              getValues: function (series, params) {
                  var period = params.period, xVal = series.xData, yVal = series.yData, yValLen = yVal ? yVal.length : 0, range = 1, xValue = xVal[0], yValue = yVal[0], WMA = [], xData = [], yData = [], index = -1, i, points, WMAPoint;
                  if (xVal.length < period) {
                      return false;
                  }
                  // Switch index for OHLC / Candlestick
                  if (isArray(yVal[0])) {
                      index = params.index;
                      yValue = yVal[0][index];
                  }
                  // Starting point
                  points = [[xValue, yValue]];
                  // Accumulate first N-points
                  while (range !== period) {
                      accumulateAverage(points, xVal, yVal, range, index);
                      range++;
                  }
                  // Calculate value one-by-one for each period in visible data
                  for (i = range; i < yValLen; i++) {
                      WMAPoint = populateAverage(points, xVal, yVal, i);
                      WMA.push(WMAPoint);
                      xData.push(WMAPoint[0]);
                      yData.push(WMAPoint[1]);
                      accumulateAverage(points, xVal, yVal, i, index);
                  }
                  WMAPoint = populateAverage(points, xVal, yVal, i);
                  WMA.push(WMAPoint);
                  xData.push(WMAPoint[0]);
                  yData.push(WMAPoint[1]);
                  return {
                      values: WMA,
                      xData: xData,
                      yData: yData
                  };
              }
          });
          /**
           * A `WMA` series. If the [type](#series.wma.type) option is not specified, it
           * is inherited from [chart.type](#chart.type).
           *
           * @extends   series,plotOptions.wma
           * @since     6.0.0
           * @product   highstock
           * @excluding dataParser, dataURL
           * @requires  stock/indicators/indicators
           * @requires  stock/indicators/wma
           * @apioption series.wma
           */
          ''; // adds doclet above to the transpiled file
  
      });
      _registerModule(_modules, 'indicators/zigzag.src.js', [_modules['parts/Globals.js']], function (H) {
          /* *
           *
           *  (c) 2010-2019 Kacper Madej
           *
           *  License: www.highcharts.com/license
           *
           *  !!!!!!! SOURCE GETS TRANSPILED BY TYPESCRIPT. EDIT TS FILE ONLY. !!!!!!!
           *
           * */
          var seriesType = H.seriesType, UNDEFINED;
          /**
           * The Zig Zag series type.
           *
           * @private
           * @class
           * @name Highcharts.seriesTypes.zigzag
           *
           * @augments Highcharts.Series
           */
          seriesType('zigzag', 'sma', 
          /**
           * Zig Zag indicator.
           *
           * This series requires `linkedTo` option to be set.
           *
           * @sample stock/indicators/zigzag
           *         Zig Zag indicator
           *
           * @extends      plotOptions.sma
           * @since        6.0.0
           * @product      highstock
           * @requires     stock/indicators/indicators
           * @requires     stock/indicators/zigzag
           * @optionparent plotOptions.zigzag
           */
          {
              /**
               * @excluding index, period
               */
              params: {
                  /**
                   * The point index which indicator calculations will base - low
                   * value.
                   *
                   * For example using OHLC data, index=2 means the indicator will be
                   * calculated using Low values.
                   */
                  lowIndex: 2,
                  /**
                   * The point index which indicator calculations will base - high
                   * value.
                   *
                   * For example using OHLC data, index=1 means the indicator will be
                   * calculated using High values.
                   */
                  highIndex: 1,
                  /**
                   * The threshold for the value change.
                   *
                   * For example deviation=1 means the indicator will ignore all price
                   * movements less than 1%.
                   */
                  deviation: 1
              }
          }, 
          /**
           * @lends Highcharts.Series#
           */
          {
              nameComponents: ['deviation'],
              nameSuffixes: ['%'],
              nameBase: 'Zig Zag',
              getValues: function (series, params) {
                  var lowIndex = params.lowIndex, highIndex = params.highIndex, deviation = params.deviation / 100, deviations = {
                      'low': 1 + deviation,
                      'high': 1 - deviation
                  }, xVal = series.xData, yVal = series.yData, yValLen = yVal ? yVal.length : 0, zigzag = [], xData = [], yData = [], i, j, zigzagPoint, firstZigzagLow, firstZigzagHigh, directionUp, zigzagLen, exitLoop = false, yIndex = false;
                  // Exit if not enught points or no low or high values
                  if (xVal.length <= 1 ||
                      (yValLen &&
                          (yVal[0][lowIndex] === UNDEFINED ||
                              yVal[0][highIndex] === UNDEFINED))) {
                      return false;
                  }
                  // Set first zigzag point candidate
                  firstZigzagLow = yVal[0][lowIndex];
                  firstZigzagHigh = yVal[0][highIndex];
                  // Search for a second zigzag point candidate,
                  // this will also set first zigzag point
                  for (i = 1; i < yValLen; i++) {
                      // requried change to go down
                      if (yVal[i][lowIndex] <= firstZigzagHigh * deviations.high) {
                          zigzag.push([xVal[0], firstZigzagHigh]);
                          // second zigzag point candidate
                          zigzagPoint = [xVal[i], yVal[i][lowIndex]];
                          // next line will be going up
                          directionUp = true;
                          exitLoop = true;
                          // requried change to go up
                      }
                      else if (yVal[i][highIndex] >= firstZigzagLow * deviations.low) {
                          zigzag.push([xVal[0], firstZigzagLow]);
                          // second zigzag point candidate
                          zigzagPoint = [xVal[i], yVal[i][highIndex]];
                          // next line will be going down
                          directionUp = false;
                          exitLoop = true;
                      }
                      if (exitLoop) {
                          xData.push(zigzag[0][0]);
                          yData.push(zigzag[0][1]);
                          j = i++;
                          i = yValLen;
                      }
                  }
                  // Search for next zigzags
                  for (i = j; i < yValLen; i++) {
                      if (directionUp) { // next line up
                          // lower when going down -> change zigzag candidate
                          if (yVal[i][lowIndex] <= zigzagPoint[1]) {
                              zigzagPoint = [xVal[i], yVal[i][lowIndex]];
                          }
                          // requried change to go down -> new zigzagpoint and
                          // direction change
                          if (yVal[i][highIndex] >=
                              zigzagPoint[1] * deviations.low) {
                              yIndex = highIndex;
                          }
                      }
                      else { // next line down
                          // higher when going up -> change zigzag candidate
                          if (yVal[i][highIndex] >= zigzagPoint[1]) {
                              zigzagPoint = [xVal[i], yVal[i][highIndex]];
                          }
                          // requried change to go down -> new zigzagpoint and
                          // direction change
                          if (yVal[i][lowIndex] <=
                              zigzagPoint[1] * deviations.high) {
                              yIndex = lowIndex;
                          }
                      }
                      if (yIndex !== false) { // new zigzag point and direction change
                          zigzag.push(zigzagPoint);
                          xData.push(zigzagPoint[0]);
                          yData.push(zigzagPoint[1]);
                          zigzagPoint = [xVal[i], yVal[i][yIndex]];
                          directionUp = !directionUp;
                          yIndex = false;
                      }
                  }
                  zigzagLen = zigzag.length;
                  // no zigzag for last point
                  if (zigzagLen !== 0 &&
                      zigzag[zigzagLen - 1][0] < xVal[yValLen - 1]) {
                      // set last point from zigzag candidate
                      zigzag.push(zigzagPoint);
                      xData.push(zigzagPoint[0]);
                      yData.push(zigzagPoint[1]);
                  }
                  return {
                      values: zigzag,
                      xData: xData,
                      yData: yData
                  };
              }
          });
          /**
           * A `Zig Zag` series. If the [type](#series.zigzag.type) option is not
           * specified, it is inherited from [chart.type](#chart.type).
           *
           * @extends   series,plotOptions.zigzag
           * @since     6.0.0
           * @product   highstock
           * @excluding dataParser, dataURL
           * @requires  stock/indicators/indicators
           * @requires  stock/indicators/zigzag
           * @apioption series.zigzag
           */
          ''; // adds doclets above to transpiled file
  
      });
      _registerModule(_modules, 'indicators/regressions.src.js', [_modules['parts/Globals.js'], _modules['parts/Utilities.js']], function (H, U) {
          /**
           *
           *  (c) 2010-2019 Kamil Kulig
           *
           *  License: www.highcharts.com/license
           *
           *  !!!!!!! SOURCE GETS TRANSPILED BY TYPESCRIPT. EDIT TS FILE ONLY. !!!!!!!
           *
           * */
          var isArray = U.isArray;
          var seriesType = H.seriesType;
          /**
           * Linear regression series type.
           *
           * @private
           * @class
           * @name Highcharts.seriesTypes.linearregression
           *
           * @augments Highcharts.Series
           */
          seriesType('linearRegression', 'sma', 
          /**
           * Linear regression indicator. This series requires `linkedTo` option to be
           * set.
           *
           * @sample {highstock} stock/indicators/linear-regression
           *         Linear regression indicator
           *
           * @extends      plotOptions.sma
           * @since        7.0.0
           * @product      highstock
           * @requires     stock/indicators/indicators
           * @requires     stock/indicators/regressions
           * @optionparent plotOptions.linearregression
           */
          {
              params: {
                  /**
                   * Unit (in milliseconds) for the x axis distances used to compute
                   * the regression line paramters (slope & intercept) for every
                   * range. In Highstock the x axis values are always represented in
                   * milliseconds which may cause that distances between points are
                   * "big" integer numbers.
                   *
                   * Highstock's linear regression algorithm (least squares method)
                   * will utilize these "big" integers for finding the slope and the
                   * intercept of the regression line for each period. In consequence,
                   * this value may be a very "small" decimal number that's hard to
                   * interpret by a human.
                   *
                   * For instance: `xAxisUnit` equealed to `86400000` ms (1 day)
                   * forces the algorithm to treat `86400000` as `1` while computing
                   * the slope and the intercept. This may enchance the legiblitity of
                   * the indicator's values.
                   *
                   * Default value is the closest distance between two data points.
                   *
                   * @sample {highstock} stock/plotoptions/linear-regression-xaxisunit
                   *         xAxisUnit set to 1 minute
                   *
                   * @example
                   * // In Liniear Regression Slope Indicator series `xAxisUnit` is
                   * // `86400000` (1 day) and period is `3`. There're 3 points in the
                   * // base series:
                   *
                   * data: [
                   *   [Date.UTC(2019, 0, 1), 1],
                   *   [Date.UTC(2019, 0, 2), 3],
                   *   [Date.UTC(2019, 0, 3), 5]
                   * ]
                   *
                   * // This will produce one point in the indicator series that has a
                   * // `y` value of `2` (slope of the regression line). If we change
                   * // the `xAxisUnit` to `1` (ms) the value of the indicator's point
                   * // will be `2.3148148148148148e-8` which is harder to interpert
                   * // for a human.
                   *
                   * @type    {number}
                   * @product highstock
                   */
                  xAxisUnit: undefined
              },
              tooltip: {
                  valueDecimals: 4
              }
          }, 
          /**
           * @lends Highcharts.Series#
           */
          {
              nameBase: 'Linear Regression Indicator',
              /**
               * Return the slope and intercept of a straight line function.
               * @private
               * @param {Highcharts.LinearRegressionIndicator} this indicator to use
               * @param {Array<number>} xData -  list of all x coordinates in a period
               * @param {Array<number>} yData - list of all y coordinates in a period
               * @return {Highcharts.RegressionLineParametersObject}
               *          object that contains the slope and the intercept
               *          of a straight line function
               */
              getRegressionLineParameters: function (xData, yData) {
                  // least squares method
                  var yIndex = this.options.params.index, getSingleYValue = function (yValue, yIndex) {
                      return isArray(yValue) ? yValue[yIndex] : yValue;
                  }, xSum = xData.reduce(function (accX, val) {
                      return val + accX;
                  }, 0), ySum = yData.reduce(function (accY, val) {
                      return getSingleYValue(val, yIndex) + accY;
                  }, 0), xMean = xSum / xData.length, yMean = ySum / yData.length, xError, yError, formulaNumerator = 0, formulaDenominator = 0, i, slope;
                  for (i = 0; i < xData.length; i++) {
                      xError = xData[i] - xMean;
                      yError = getSingleYValue(yData[i], yIndex) - yMean;
                      formulaNumerator += xError * yError;
                      formulaDenominator += Math.pow(xError, 2);
                  }
                  slope = formulaDenominator ?
                      formulaNumerator / formulaDenominator : 0; // don't divide by 0
                  return {
                      slope: slope,
                      intercept: yMean - slope * xMean
                  };
              },
              /**
               * Return the y value on a straight line.
               * @private
               * @param {Highcharts.RegressionLineParametersObject} lineParameters
               *          object that contains the slope and the intercept
               *          of a straight line function
               * @param {number} endPointX - x coordinate of the point
               * @return {number} - y value of the point that lies on the line
               */
              getEndPointY: function (lineParameters, endPointX) {
                  return lineParameters.slope * endPointX + lineParameters.intercept;
              },
              /**
               * Transform the coordinate system so that x values start at 0 and
               * apply xAxisUnit.
               * @private
               * @param {Array<number>} xData - list of all x coordinates in a period
               * @param {number} xAxisUnit - option (see the API)
               * @return {Array<number>} - array of transformed x data
               */
              transformXData: function (xData, xAxisUnit) {
                  var xOffset = xData[0];
                  return xData.map(function (xValue) {
                      return (xValue - xOffset) / xAxisUnit;
                  });
              },
              /**
               * Find the closest distance between points in the base series.
               * @private
               * @param {Array<number>} xData
                          list of all x coordinates in the base series
               * @return {number} - closest distance between points in the base series
               */
              findClosestDistance: function (xData) {
                  var distance, closestDistance, i;
                  for (i = 1; i < xData.length - 1; i++) {
                      distance = xData[i] - xData[i - 1];
                      if (distance > 0 && (closestDistance === undefined ||
                          distance < closestDistance)) {
                          closestDistance = distance;
                      }
                  }
                  return closestDistance;
              },
              // Required to be implemented - starting point for indicator's logic
              getValues: function (baseSeries, regressionSeriesParams) {
                  var xData = baseSeries.xData, yData = baseSeries.yData, period = regressionSeriesParams.period, lineParameters, i, periodStart, periodEnd, 
                  // format required to be returned
                  indicatorData = {
                      xData: [],
                      yData: [],
                      values: []
                  }, endPointX, endPointY, periodXData, periodYData, periodTransformedXData, xAxisUnit = this.options.params.xAxisUnit ||
                      this.findClosestDistance(xData);
                  // Iteration logic: x value of the last point within the period
                  // (end point) is used to represent the y value (regression)
                  // of the entire period.
                  for (i = period - 1; i <= xData.length - 1; i++) {
                      periodStart = i - period + 1; // adjusted for slice() function
                      periodEnd = i + 1; // (as above)
                      endPointX = xData[i];
                      periodXData = xData.slice(periodStart, periodEnd);
                      periodYData = yData.slice(periodStart, periodEnd);
                      periodTransformedXData = this.transformXData(periodXData, xAxisUnit);
                      lineParameters = this.getRegressionLineParameters(periodTransformedXData, periodYData);
                      endPointY = this.getEndPointY(lineParameters, periodTransformedXData[periodTransformedXData.length - 1]);
                      // @todo this is probably not used anywhere
                      indicatorData.values.push({
                          regressionLineParameters: lineParameters,
                          x: endPointX,
                          y: endPointY
                      });
                      indicatorData.xData.push(endPointX);
                      indicatorData.yData.push(endPointY);
                  }
                  return indicatorData;
              }
          });
          /**
           * A linear regression series. If the [type](#series.linearregression.type)
           * option is not specified, it is inherited from [chart.type](#chart.type).
           *
           * @extends   series,plotOptions.linearregression
           * @since     7.0.0
           * @product   highstock
           * @excluding dataParser,dataURL
           * @requires  stock/indicators/indicators
           * @requires  stock/indicators/regressions
           * @apioption series.linearregression
           */
          /* ************************************************************************** */
          /**
           * The Linear Regression Slope series type.
           *
           * @private
           * @class
           * @name Highcharts.seriesTypes.linearRegressionSlope
           *
           * @augments Highcharts.Series
           */
          seriesType('linearRegressionSlope', 'linearRegression', 
          /**
           * Linear regression slope indicator. This series requires `linkedTo`
           * option to be set.
           *
           * @sample {highstock} stock/indicators/linear-regression-slope
           *         Linear regression slope indicator
           *
           * @extends      plotOptions.linearregression
           * @since        7.0.0
           * @product      highstock
           * @requires     stock/indicators/indicators
           * @requires     stock/indicators/regressions
           * @optionparent plotOptions.linearregressionslope
           */
          {}, 
          /**
           * @lends Highcharts.Series#
           */
          {
              nameBase: 'Linear Regression Slope Indicator',
              getEndPointY: function (lineParameters) {
                  return lineParameters.slope;
              }
          });
          /**
           * A linear regression slope series. If the
           * [type](#series.linearregressionslope.type) option is not specified, it is
           * inherited from [chart.type](#chart.type).
           *
           * @extends   series,plotOptions.linearregressionslope
           * @since     7.0.0
           * @product   highstock
           * @excluding dataParser,dataURL
           * @requires  stock/indicators/indicators
           * @requires  stock/indicators/regressions
           * @apioption series.linearregressionslope
           */
          /* ************************************************************************** */
          /**
           * The Linear Regression Intercept series type.
           *
           * @private
           * @class
           * @name Highcharts.seriesTypes.linearRegressionIntercept
           *
           * @augments Highcharts.Series
           */
          seriesType('linearRegressionIntercept', 'linearRegression', 
          /**
           * Linear regression intercept indicator. This series requires `linkedTo`
           * option to be set.
           *
           * @sample {highstock} stock/indicators/linear-regression-intercept
           *         Linear intercept slope indicator
           *
           * @extends      plotOptions.linearregression
           * @since        7.0.0
           * @product      highstock
           * @requires     stock/indicators/indicators
           * @requires     stock/indicators/regressions
           * @optionparent plotOptions.linearregressionintercept
           */
          {}, 
          /**
           * @lends Highcharts.Series#
           */
          {
              nameBase: 'Linear Regression Intercept Indicator',
              getEndPointY: function (lineParameters) {
                  return lineParameters.intercept;
              }
          });
          /**
           * A linear regression intercept series. If the
           * [type](#series.linearregressionintercept.type) option is not specified, it is
           * inherited from [chart.type](#chart.type).
           *
           * @extends   series,plotOptions.linearregressionintercept
           * @since     7.0.0
           * @product   highstock
           * @excluding dataParser,dataURL
           * @requires  stock/indicators/indicators
           * @requires  stock/indicators/regressions
           * @apioption series.linearregressionintercept
           */
          /* ************************************************************************** */
          /**
           * The Linear Regression Angle series type.
           *
           * @private
           * @class
           * @name Highcharts.seriesTypes.linearRegressionAngle
           *
           * @augments Highcharts.Series
           */
          seriesType('linearRegressionAngle', 'linearRegression', 
          /**
           * Linear regression angle indicator. This series requires `linkedTo`
           * option to be set.
           *
           * @sample {highstock} stock/indicators/linear-regression-angle
           *         Linear intercept angle indicator
           *
           * @extends      plotOptions.linearregression
           * @since        7.0.0
           * @product      highstock
           * @requires     stock/indicators/indicators
           * @requires     stock/indicators/regressions
           * @optionparent plotOptions.linearregressionangle
           */
          {
              tooltip: {
                  pointFormat: '<span style="color:{point.color}">\u25CF</span>' +
                      '{series.name}: <b>{point.y}°</b><br/>'
              }
          }, 
          /**
           * @lends Highcharts.Series#
           */
          {
              nameBase: 'Linear Regression Angle Indicator',
              /**
              * Convert a slope of a line to angle (in degrees) between
              * the line and x axis
              * @private
              * @param {number} slope of the straight line function
              * @return {number} angle in degrees
              */
              slopeToAngle: function (slope) {
                  return Math.atan(slope) * (180 / Math.PI); // rad to deg
              },
              getEndPointY: function (lineParameters) {
                  return this.slopeToAngle(lineParameters.slope);
              }
          });
          /**
           * A linear regression intercept series. If the
           * [type](#series.linearregressionangle.type) option is not specified, it is
           * inherited from [chart.type](#chart.type).
           *
           * @extends   series,plotOptions.linearregressionangle
           * @since     7.0.0
           * @product   highstock
           * @excluding dataParser,dataURL
           * @requires  stock/indicators/indicators
           * @requires  stock/indicators/regressions
           * @apioption series.linearregressionangle
           */
          ''; // to include the above in the js output
  
      });
      _registerModule(_modules, 'indicators/acceleration-bands.src.js', [_modules['parts/Globals.js'], _modules['mixins/multipe-lines.js']], function (H, multipleLinesMixin) {
          /* *
           *
           *  License: www.highcharts.com/license
           *
           *  !!!!!!! SOURCE GETS TRANSPILED BY TYPESCRIPT. EDIT TS FILE ONLY. !!!!!!!
           *
           * */
          var SMA = H.seriesTypes.sma, merge = H.merge, correctFloat = H.correctFloat;
          /* eslint-disable valid-jsdoc */
          /**
           * @private
           */
          function getBaseForBand(low, high, factor) {
              return (((correctFloat(high - low)) /
                  ((correctFloat(high + low)) / 2)) * 1000) * factor;
          }
          /**
           * @private
           */
          function getPointUB(high, base) {
              return high * (correctFloat(1 + 2 * base));
          }
          /**
           * @private
           */
          function getPointLB(low, base) {
              return low * (correctFloat(1 - 2 * base));
          }
          /* eslint-enable valid-jsdoc */
          /**
           * The ABands series type
           *
           * @private
           * @class
           * @name Highcharts.seriesTypes.abands
           *
           * @augments Highcharts.Series
           */
          H.seriesType('abands', 'sma', 
          /**
           * Acceleration bands (ABANDS). This series requires the `linkedTo` option
           * to be set and should be loaded after the
           * `stock/indicators/indicators.js`.
           *
           * @sample {highstock} stock/indicators/acceleration-bands
           *         Acceleration Bands
           *
           * @extends      plotOptions.sma
           * @mixes        Highcharts.MultipleLinesMixin
           * @since        7.0.0
           * @product      highstock
           * @excluding    allAreas, colorAxis, compare, compareBase, joinBy, keys,
           *               navigatorOptions, pointInterval, pointIntervalUnit,
           *               pointPlacement, pointRange, pointStart, showInNavigator,
           *               stacking,
           * @requires     stock/indicators/indicators
           * @requires     stock/indicators/acceleration-bands
           * @optionparent plotOptions.abands
           */
          {
              params: {
                  period: 20,
                  /**
                   * The algorithms factor value used to calculate bands.
                   *
                   * @product highstock
                   */
                  factor: 0.001,
                  index: 3
              },
              lineWidth: 1,
              topLine: {
                  styles: {
                      /**
                       * Pixel width of the line.
                       */
                      lineWidth: 1
                  }
              },
              bottomLine: {
                  styles: {
                      /**
                       * Pixel width of the line.
                       */
                      lineWidth: 1
                  }
              },
              dataGrouping: {
                  approximation: 'averages'
              }
          }, 
          /**
           * @lends Highcharts.Series#
           */
          merge(multipleLinesMixin, {
              pointArrayMap: ['top', 'middle', 'bottom'],
              pointValKey: 'middle',
              nameBase: 'Acceleration Bands',
              nameComponents: ['period', 'factor'],
              linesApiNames: ['topLine', 'bottomLine'],
              getValues: function (series, params) {
                  var period = params.period, factor = params.factor, index = params.index, xVal = series.xData, yVal = series.yData, yValLen = yVal ? yVal.length : 0, 
                  // Upperbands
                  UB = [], 
                  // Lowerbands
                  LB = [], 
                  // ABANDS array structure:
                  // 0-date, 1-top line, 2-middle line, 3-bottom line
                  ABANDS = [], 
                  // middle line, top line and bottom line
                  ML, TL, BL, date, bandBase, pointSMA, ubSMA, lbSMA, low = 2, high = 1, xData = [], yData = [], slicedX, slicedY, i;
                  if (yValLen < period) {
                      return false;
                  }
                  for (i = 0; i <= yValLen; i++) {
                      // Get UB and LB values of every point. This condition
                      // is necessary, because there is a need to calculate current
                      // UB nad LB values simultaneously with given period SMA
                      // in one for loop.
                      if (i < yValLen) {
                          bandBase = getBaseForBand(yVal[i][low], yVal[i][high], factor);
                          UB.push(getPointUB(yVal[i][high], bandBase));
                          LB.push(getPointLB(yVal[i][low], bandBase));
                      }
                      if (i >= period) {
                          slicedX = xVal.slice(i - period, i);
                          slicedY = yVal.slice(i - period, i);
                          ubSMA = SMA.prototype.getValues.call(this, {
                              xData: slicedX,
                              yData: UB.slice(i - period, i)
                          }, {
                              period: period
                          });
                          lbSMA = SMA.prototype.getValues.call(this, {
                              xData: slicedX,
                              yData: LB.slice(i - period, i)
                          }, {
                              period: period
                          });
                          pointSMA = SMA.prototype.getValues.call(this, {
                              xData: slicedX,
                              yData: slicedY
                          }, {
                              period: period,
                              index: index
                          });
                          date = pointSMA.xData[0];
                          TL = ubSMA.yData[0];
                          BL = lbSMA.yData[0];
                          ML = pointSMA.yData[0];
                          ABANDS.push([date, TL, ML, BL]);
                          xData.push(date);
                          yData.push([TL, ML, BL]);
                      }
                  }
                  return {
                      values: ABANDS,
                      xData: xData,
                      yData: yData
                  };
              }
          }));
          /**
           * An Acceleration bands indicator. If the [type](#series.abands.type) option is not
           * specified, it is inherited from [chart.type](#chart.type).
           *
           * @extends   series,plotOptions.abands
           * @since     7.0.0
           * @product   highstock
           * @excluding allAreas, colorAxis, compare, compareBase, dataParser, dataURL,
           *            joinBy, keys, navigatorOptions, pointInterval,
           *            pointIntervalUnit, pointPlacement, pointRange, pointStart,
           *            stacking, showInNavigator,
           * @requires  stock/indicators/indicators
           * @requires  stock/indicators/acceleration-bands
           * @apioption series.abands
           */
          ''; // to include the above in jsdoc
  
      });
      _registerModule(_modules, 'indicators/trendline.src.js', [_modules['parts/Globals.js'], _modules['parts/Utilities.js']], function (H, U) {
          /* *
           *
           *  License: www.highcharts.com/license
           *
           *  !!!!!!! SOURCE GETS TRANSPILED BY TYPESCRIPT. EDIT TS FILE ONLY. !!!!!!!
           *
           * */
          var isArray = U.isArray;
          var seriesType = H.seriesType;
          /**
           * The Trend line series type.
           *
           * @private
           * @class
           * @name Highcharts.seriesTypes.trendline
           *
           * @augments Highcharts.Series
           */
          seriesType('trendline', 'sma', 
          /**
           * Trendline (linear regression) fits a straight line to the selected data
           * using a method called the Sum Of Least Squares. This series requires the
           * `linkedTo` option to be set.
           *
           * @sample stock/indicators/trendline
           *         Trendline indicator
           *
           * @extends      plotOptions.sma
           * @since        7.1.3
           * @product      highstock
           * @requires     stock/indicators/indicators
           * @requires     stock/indicators/trendline
           * @optionparent plotOptions.trendline
           */
          {
              /**
               * @excluding period
               */
              params: {
                  /**
                   * The point index which indicator calculations will base. For
                   * example using OHLC data, index=2 means the indicator will be
                   * calculated using Low values.
                   *
                   * @default 3
                   */
                  index: 3
              }
          }, 
          /**
           * @lends Highcharts.Series#
           */
          {
              nameBase: 'Trendline',
              nameComponents: false,
              getValues: function (series, params) {
                  var xVal = series.xData, yVal = series.yData, LR = [], xData = [], yData = [], sumX = 0, sumY = 0, sumXY = 0, sumX2 = 0, xValLength = xVal.length, index = params.index, alpha, beta, i, x, y;
                  // Get sums:
                  for (i = 0; i < xValLength; i++) {
                      x = xVal[i];
                      y = isArray(yVal[i]) ? yVal[i][index] : yVal[i];
                      sumX += x;
                      sumY += y;
                      sumXY += x * y;
                      sumX2 += x * x;
                  }
                  // Get slope and offset:
                  alpha = (xValLength * sumXY - sumX * sumY) /
                      (xValLength * sumX2 - sumX * sumX);
                  if (isNaN(alpha)) {
                      alpha = 0;
                  }
                  beta = (sumY - alpha * sumX) / xValLength;
                  // Calculate linear regression:
                  for (i = 0; i < xValLength; i++) {
                      x = xVal[i];
                      y = alpha * x + beta;
                      // Prepare arrays required for getValues() method
                      LR[i] = [x, y];
                      xData[i] = x;
                      yData[i] = y;
                  }
                  return {
                      xData: xData,
                      yData: yData,
                      values: LR
                  };
              }
          });
          /**
           * A `TrendLine` series. If the [type](#series.trendline.type) option is not
           * specified, it is inherited from [chart.type](#chart.type).
           *
           * @extends   series,plotOptions.trendline
           * @since     7.1.3
           * @product   highstock
           * @excluding dataParser, dataURL
           * @requires  stock/indicators/indicators
           * @requires  stock/indicators/trendline
           * @apioption series.trendline
           */
          ''; // to include the above in the js output
  
      });
      _registerModule(_modules, 'masters/indicators/indicators-all.src.js', [], function () {
  
  
  
      });
  }));