TEMAIndicator.js 6.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167
  1. /* *
  2. *
  3. * License: www.highcharts.com/license
  4. *
  5. * !!!!!!! SOURCE GETS TRANSPILED BY TYPESCRIPT. EDIT TS FILE ONLY. !!!!!!!
  6. *
  7. * */
  8. 'use strict';
  9. import H from '../../Core/Globals.js';
  10. import U from '../../Core/Utilities.js';
  11. var correctFloat = U.correctFloat, isArray = U.isArray, seriesType = U.seriesType;
  12. import requiredIndicator from '../../Mixins/IndicatorRequired.js';
  13. var EMAindicator = H.seriesTypes.ema;
  14. /**
  15. * The TEMA series type.
  16. *
  17. * @private
  18. * @class
  19. * @name Highcharts.seriesTypes.tema
  20. *
  21. * @augments Highcharts.Series
  22. */
  23. seriesType('tema', 'ema',
  24. /**
  25. * Triple exponential moving average (TEMA) indicator. This series requires
  26. * `linkedTo` option to be set and should be loaded after the
  27. * `stock/indicators/indicators.js` and `stock/indicators/ema.js`.
  28. *
  29. * @sample {highstock} stock/indicators/tema
  30. * TEMA indicator
  31. *
  32. * @extends plotOptions.ema
  33. * @since 7.0.0
  34. * @product highstock
  35. * @excluding allAreas, colorAxis, compare, compareBase, joinBy, keys,
  36. * navigatorOptions, pointInterval, pointIntervalUnit,
  37. * pointPlacement, pointRange, pointStart, showInNavigator,
  38. * stacking
  39. * @requires stock/indicators/indicators
  40. * @requires stock/indicators/ema
  41. * @requires stock/indicators/tema
  42. * @optionparent plotOptions.tema
  43. */
  44. {},
  45. /**
  46. * @lends Highcharts.Series#
  47. */
  48. {
  49. init: function () {
  50. var args = arguments, ctx = this;
  51. requiredIndicator.isParentLoaded(EMAindicator, 'ema', ctx.type, function (indicator) {
  52. indicator.prototype.init.apply(ctx, args);
  53. return;
  54. });
  55. },
  56. getEMA: function (yVal, prevEMA, SMA, index, i, xVal) {
  57. return EMAindicator.prototype.calculateEma(xVal || [], yVal, typeof i === 'undefined' ? 1 : i, this.chart.series[0].EMApercent, prevEMA, typeof index === 'undefined' ? -1 : index, SMA);
  58. },
  59. getTemaPoint: function (xVal, tripledPeriod, EMAlevels, i) {
  60. var TEMAPoint = [
  61. xVal[i - 3],
  62. correctFloat(3 * EMAlevels.level1 -
  63. 3 * EMAlevels.level2 + EMAlevels.level3)
  64. ];
  65. return TEMAPoint;
  66. },
  67. getValues: function (series, params) {
  68. 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 = [],
  69. // EMA of previous point
  70. prevEMA, prevEMAlevel2,
  71. // EMA values array
  72. EMAvalues = [], EMAlevel2values = [], i, TEMAPoint,
  73. // This object contains all EMA EMAlevels calculated like below
  74. // EMA = level1
  75. // EMA(EMA) = level2,
  76. // EMA(EMA(EMA)) = level3,
  77. EMAlevels = {};
  78. series.EMApercent = (2 / (period + 1));
  79. // Check period, if bigger than EMA points length, skip
  80. if (yValLen < 3 * period - 2) {
  81. return;
  82. }
  83. // Switch index for OHLC / Candlestick / Arearange
  84. if (isArray(yVal[0])) {
  85. index = params.index ? params.index : 0;
  86. }
  87. // Accumulate first N-points
  88. accumulatePeriodPoints =
  89. EMAindicator.prototype.accumulatePeriodPoints(period, index, yVal);
  90. // first point
  91. SMA = accumulatePeriodPoints / period;
  92. accumulatePeriodPoints = 0;
  93. // Calculate value one-by-one for each period in visible data
  94. for (i = period; i < yValLen + 3; i++) {
  95. if (i < yValLen + 1) {
  96. EMAlevels.level1 = this.getEMA(yVal, prevEMA, SMA, index, i)[1];
  97. EMAvalues.push(EMAlevels.level1);
  98. }
  99. prevEMA = EMAlevels.level1;
  100. // Summing first period points for ema(ema)
  101. if (i < doubledPeriod) {
  102. accumulatePeriodPoints += EMAlevels.level1;
  103. }
  104. else {
  105. // Calculate dema
  106. // First dema point
  107. if (i === doubledPeriod) {
  108. SMA = accumulatePeriodPoints / period;
  109. accumulatePeriodPoints = 0;
  110. }
  111. EMAlevels.level1 = EMAvalues[i - period - 1];
  112. EMAlevels.level2 = this.getEMA([EMAlevels.level1], prevEMAlevel2, SMA)[1];
  113. EMAlevel2values.push(EMAlevels.level2);
  114. prevEMAlevel2 = EMAlevels.level2;
  115. // Summing first period points for ema(ema(ema))
  116. if (i < tripledPeriod) {
  117. accumulatePeriodPoints += EMAlevels.level2;
  118. }
  119. else {
  120. // Calculate tema
  121. // First tema point
  122. if (i === tripledPeriod) {
  123. SMA = accumulatePeriodPoints / period;
  124. }
  125. if (i === yValLen + 1) {
  126. // Calculate the last ema and emaEMA points
  127. EMAlevels.level1 = EMAvalues[i - period - 1];
  128. EMAlevels.level2 = this.getEMA([EMAlevels.level1], prevEMAlevel2, SMA)[1];
  129. EMAlevel2values.push(EMAlevels.level2);
  130. }
  131. EMAlevels.level1 = EMAvalues[i - period - 2];
  132. EMAlevels.level2 = EMAlevel2values[i - 2 * period - 1];
  133. EMAlevels.level3 = this.getEMA([EMAlevels.level2], EMAlevels.prevLevel3, SMA)[1];
  134. TEMAPoint = this.getTemaPoint(xVal, tripledPeriod, EMAlevels, i);
  135. // Make sure that point exists (for TRIX oscillator)
  136. if (TEMAPoint) {
  137. TEMA.push(TEMAPoint);
  138. xDataTema.push(TEMAPoint[0]);
  139. yDataTema.push(TEMAPoint[1]);
  140. }
  141. EMAlevels.prevLevel3 = EMAlevels.level3;
  142. }
  143. }
  144. }
  145. return {
  146. values: TEMA,
  147. xData: xDataTema,
  148. yData: yDataTema
  149. };
  150. }
  151. });
  152. /**
  153. * A `TEMA` series. If the [type](#series.ema.type) option is not
  154. * specified, it is inherited from [chart.type](#chart.type).
  155. *
  156. * @extends series,plotOptions.ema
  157. * @since 7.0.0
  158. * @product highstock
  159. * @excluding allAreas, colorAxis, compare, compareBase, dataParser, dataURL,
  160. * joinBy, keys, navigatorOptions, pointInterval, pointIntervalUnit,
  161. * pointPlacement, pointRange, pointStart, showInNavigator, stacking
  162. * @requires stock/indicators/indicators
  163. * @requires stock/indicators/ema
  164. * @requires stock/indicators/tema
  165. * @apioption series.tema
  166. */
  167. ''; // to include the above in the js output