cmf.src.js 9.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236
  1. /**
  2. * @license Highstock JS v8.2.0 (2020-08-20)
  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, 'Stock/Indicators/CMFIndicator.js', [_modules['Core/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,
  94. options = this.options,
  95. series = this.linkedParent,
  96. volumeSeries = (this.volumeSeries ||
  97. (this.volumeSeries =
  98. chart.get(options.params.volumeSeriesID))),
  99. isSeriesOHLC = (series &&
  100. series.yData &&
  101. series.yData[0].length === 4);
  102. /**
  103. * @private
  104. * @param {Highcharts.Series} serie to check length validity on.
  105. * @return {boolean|undefined} true if length is valid.
  106. */
  107. function isLengthValid(serie) {
  108. return serie.xData &&
  109. serie.xData.length >= options.params.period;
  110. }
  111. return !!(series &&
  112. volumeSeries &&
  113. isLengthValid(series) &&
  114. isLengthValid(volumeSeries) && isSeriesOHLC);
  115. },
  116. /**
  117. * Returns indicator's data.
  118. * @private
  119. * @param {Highcharts.CMFIndicator} this indicator to use.
  120. * @param {Highcharts.Series} series to calculate values from
  121. * @param {Highcharts.CMFIndicatorParamsOptions} params to pass
  122. * @return {boolean|Highcharts.IndicatorNullableValuesObject} Returns false if the
  123. * indicator is not valid, otherwise returns Values object.
  124. */
  125. getValues: function (series, params) {
  126. if (!this.isValid()) {
  127. return;
  128. }
  129. return this.getMoneyFlow(series.xData, series.yData, this.volumeSeries.yData, params.period);
  130. },
  131. /**
  132. * @private
  133. * @param {Array<number>} xData - x timestamp values
  134. * @param {Array<number>} seriesYData - yData of basic series
  135. * @param {Array<number>} volumeSeriesYData - yData of volume series
  136. * @param {number} period - indicator's param
  137. * @return {Highcharts.IndicatorNullableValuesObject} object containing computed money
  138. * flow data
  139. */
  140. getMoneyFlow: function (xData, seriesYData, volumeSeriesYData, period) {
  141. var len = seriesYData.length,
  142. moneyFlowVolume = [],
  143. sumVolume = 0,
  144. sumMoneyFlowVolume = 0,
  145. moneyFlowXData = [],
  146. moneyFlowYData = [],
  147. values = [],
  148. i,
  149. point,
  150. nullIndex = -1;
  151. /**
  152. * Calculates money flow volume, changes i, nullIndex vars from
  153. * upper scope!
  154. * @private
  155. * @param {Array<number>} ohlc - OHLC point
  156. * @param {number} volume - Volume point's y value
  157. * @return {number|null} - volume * moneyFlowMultiplier
  158. **/
  159. function getMoneyFlowVolume(ohlc, volume) {
  160. var high = ohlc[1],
  161. low = ohlc[2],
  162. close = ohlc[3],
  163. isValid = volume !== null &&
  164. high !== null &&
  165. low !== null &&
  166. close !== null &&
  167. high !== low;
  168. /**
  169. * @private
  170. * @param {number} h - High value
  171. * @param {number} l - Low value
  172. * @param {number} c - Close value
  173. * @return {number} calculated multiplier for the point
  174. **/
  175. function getMoneyFlowMultiplier(h, l, c) {
  176. return ((c - l) - (h - c)) / (h - l);
  177. }
  178. return isValid ?
  179. getMoneyFlowMultiplier(high, low, close) * volume :
  180. ((nullIndex = i), null);
  181. }
  182. if (period > 0 && period <= len) {
  183. for (i = 0; i < period; i++) {
  184. moneyFlowVolume[i] = getMoneyFlowVolume(seriesYData[i], volumeSeriesYData[i]);
  185. sumVolume += volumeSeriesYData[i];
  186. sumMoneyFlowVolume += moneyFlowVolume[i];
  187. }
  188. moneyFlowXData.push(xData[i - 1]);
  189. moneyFlowYData.push(i - nullIndex >= period && sumVolume !== 0 ?
  190. sumMoneyFlowVolume / sumVolume :
  191. null);
  192. values.push([moneyFlowXData[0], moneyFlowYData[0]]);
  193. for (; i < len; i++) {
  194. moneyFlowVolume[i] = getMoneyFlowVolume(seriesYData[i], volumeSeriesYData[i]);
  195. sumVolume -= volumeSeriesYData[i - period];
  196. sumVolume += volumeSeriesYData[i];
  197. sumMoneyFlowVolume -= moneyFlowVolume[i - period];
  198. sumMoneyFlowVolume += moneyFlowVolume[i];
  199. point = [
  200. xData[i],
  201. i - nullIndex >= period ?
  202. sumMoneyFlowVolume / sumVolume :
  203. null
  204. ];
  205. moneyFlowXData.push(point[0]);
  206. moneyFlowYData.push(point[1]);
  207. values.push([point[0], point[1]]);
  208. }
  209. }
  210. return {
  211. values: values,
  212. xData: moneyFlowXData,
  213. yData: moneyFlowYData
  214. };
  215. }
  216. });
  217. /**
  218. * A `CMF` series. If the [type](#series.cmf.type) option is not
  219. * specified, it is inherited from [chart.type](#chart.type).
  220. *
  221. * @extends series,plotOptions.cmf
  222. * @since 6.0.0
  223. * @product highstock
  224. * @excluding dataParser, dataURL
  225. * @requires stock/indicators/indicators
  226. * @requires stock/indicators/cmf
  227. * @apioption series.cmf
  228. */
  229. ''; // adds doclet above to the transpiled file
  230. });
  231. _registerModule(_modules, 'masters/indicators/cmf.src.js', [], function () {
  232. });
  233. }));