cmf.src.js 8.9 KB

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