cmf.src.js 8.8 KB

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