cmf.src.js 6.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184
  1. /* *
  2. *
  3. * (c) 2010-2019 Highsoft AS
  4. *
  5. * Author: Sebastian Domas
  6. *
  7. * Chaikin Money Flow indicator for Highstock
  8. *
  9. * License: www.highcharts.com/license
  10. *
  11. * !!!!!!! SOURCE GETS TRANSPILED BY TYPESCRIPT. EDIT TS FILE ONLY. !!!!!!!
  12. *
  13. * */
  14. 'use strict';
  15. import H from '../parts/Globals.js';
  16. /**
  17. * The CMF series type.
  18. *
  19. * @private
  20. * @class
  21. * @name Highcharts.seriesTypes.cmf
  22. *
  23. * @augments Highcharts.Series
  24. */
  25. H.seriesType('cmf', 'sma',
  26. /**
  27. * Chaikin Money Flow indicator (cmf).
  28. *
  29. * @sample stock/indicators/cmf/
  30. * Chaikin Money Flow indicator
  31. *
  32. * @extends plotOptions.sma
  33. * @since 6.0.0
  34. * @excluding animationLimit
  35. * @product highstock
  36. * @requires stock/indicators/indicators
  37. * @requires stock/indicators/cmf
  38. * @optionparent plotOptions.cmf
  39. */
  40. {
  41. params: {
  42. period: 14,
  43. /**
  44. * The id of another series to use its data as volume data for the
  45. * indiator calculation.
  46. */
  47. volumeSeriesID: 'volume'
  48. }
  49. },
  50. /**
  51. * @lends Highcharts.Series#
  52. */
  53. {
  54. nameBase: 'Chaikin Money Flow',
  55. /**
  56. * Checks if the series and volumeSeries are accessible, number of
  57. * points.x is longer than period, is series has OHLC data
  58. * @private
  59. * @param {Highcharts.CMFIndicator} this indicator to use.
  60. * @return {boolean} True if series is valid and can be computed,
  61. * otherwise false.
  62. */
  63. isValid: function () {
  64. var chart = this.chart, options = this.options, series = this.linkedParent, volumeSeries = (this.volumeSeries ||
  65. (this.volumeSeries =
  66. chart.get(options.params.volumeSeriesID))), isSeriesOHLC = (series &&
  67. series.yData &&
  68. series.yData[0].length === 4);
  69. /**
  70. * @private
  71. * @param {Highcharts.Series} serie to check length validity on.
  72. * @return {boolean|undefined} true if length is valid.
  73. */
  74. function isLengthValid(serie) {
  75. return serie.xData &&
  76. serie.xData.length >= options.params.period;
  77. }
  78. return !!(series &&
  79. volumeSeries &&
  80. isLengthValid(series) &&
  81. isLengthValid(volumeSeries) && isSeriesOHLC);
  82. },
  83. /**
  84. * Returns indicator's data.
  85. * @private
  86. * @param {Highcharts.CMFIndicator} this indicator to use.
  87. * @param {Highcharts.Series} series to calculate values from
  88. * @param {Highcharts.CMFIndicatorParamsOptions} params to pass
  89. * @return {boolean|Highcharts.IndicatorNullableValuesObject} Returns false if the
  90. * indicator is not valid, otherwise returns Values object.
  91. */
  92. getValues: function (series, params) {
  93. if (!this.isValid()) {
  94. return;
  95. }
  96. return this.getMoneyFlow(series.xData, series.yData, this.volumeSeries.yData, params.period);
  97. },
  98. /**
  99. * @private
  100. * @param {Array<number>} xData - x timestamp values
  101. * @param {Array<number>} seriesYData - yData of basic series
  102. * @param {Array<number>} volumeSeriesYData - yData of volume series
  103. * @param {number} period - indicator's param
  104. * @return {Highcharts.IndicatorNullableValuesObject} object containing computed money
  105. * flow data
  106. */
  107. getMoneyFlow: function (xData, seriesYData, volumeSeriesYData, period) {
  108. var len = seriesYData.length, moneyFlowVolume = [], sumVolume = 0, sumMoneyFlowVolume = 0, moneyFlowXData = [], moneyFlowYData = [], values = [], i, point, nullIndex = -1;
  109. /**
  110. * Calculates money flow volume, changes i, nullIndex vars from
  111. * upper scope!
  112. * @private
  113. * @param {Array<number>} ohlc - OHLC point
  114. * @param {number} volume - Volume point's y value
  115. * @return {number|null} - volume * moneyFlowMultiplier
  116. **/
  117. function getMoneyFlowVolume(ohlc, volume) {
  118. var high = ohlc[1], low = ohlc[2], close = ohlc[3], isValid = volume !== null &&
  119. high !== null &&
  120. low !== null &&
  121. close !== null &&
  122. high !== low;
  123. /**
  124. * @private
  125. * @param {number} h - High value
  126. * @param {number} l - Low value
  127. * @param {number} c - Close value
  128. * @return {number} calculated multiplier for the point
  129. **/
  130. function getMoneyFlowMultiplier(h, l, c) {
  131. return ((c - l) - (h - c)) / (h - l);
  132. }
  133. return isValid ?
  134. getMoneyFlowMultiplier(high, low, close) * volume :
  135. ((nullIndex = i), null);
  136. }
  137. if (period > 0 && period <= len) {
  138. for (i = 0; i < period; i++) {
  139. moneyFlowVolume[i] = getMoneyFlowVolume(seriesYData[i], volumeSeriesYData[i]);
  140. sumVolume += volumeSeriesYData[i];
  141. sumMoneyFlowVolume += moneyFlowVolume[i];
  142. }
  143. moneyFlowXData.push(xData[i - 1]);
  144. moneyFlowYData.push(i - nullIndex >= period && sumVolume !== 0 ?
  145. sumMoneyFlowVolume / sumVolume :
  146. null);
  147. values.push([moneyFlowXData[0], moneyFlowYData[0]]);
  148. for (; i < len; i++) {
  149. moneyFlowVolume[i] = getMoneyFlowVolume(seriesYData[i], volumeSeriesYData[i]);
  150. sumVolume -= volumeSeriesYData[i - period];
  151. sumVolume += volumeSeriesYData[i];
  152. sumMoneyFlowVolume -= moneyFlowVolume[i - period];
  153. sumMoneyFlowVolume += moneyFlowVolume[i];
  154. point = [
  155. xData[i],
  156. i - nullIndex >= period ?
  157. sumMoneyFlowVolume / sumVolume :
  158. null
  159. ];
  160. moneyFlowXData.push(point[0]);
  161. moneyFlowYData.push(point[1]);
  162. values.push([point[0], point[1]]);
  163. }
  164. }
  165. return {
  166. values: values,
  167. xData: moneyFlowXData,
  168. yData: moneyFlowYData
  169. };
  170. }
  171. });
  172. /**
  173. * A `CMF` series. If the [type](#series.cmf.type) option is not
  174. * specified, it is inherited from [chart.type](#chart.type).
  175. *
  176. * @extends series,plotOptions.cmf
  177. * @since 6.0.0
  178. * @product highstock
  179. * @excluding dataParser, dataURL
  180. * @requires stock/indicators/indicators
  181. * @requires stock/indicators/cmf
  182. * @apioption series.cmf
  183. */
  184. ''; // adds doclet above to the transpiled file