mfi.src.js 9.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260
  1. /**
  2. * @license Highstock JS v9.1.1 (2021-06-04)
  3. *
  4. * Money Flow Index indicator for Highcharts Stock
  5. *
  6. * (c) 2010-2021 Grzegorz Blachliński
  7. *
  8. * License: www.highcharts.com/license
  9. */
  10. 'use strict';
  11. (function (factory) {
  12. if (typeof module === 'object' && module.exports) {
  13. factory['default'] = factory;
  14. module.exports = factory;
  15. } else if (typeof define === 'function' && define.amd) {
  16. define('highcharts/indicators/mfi', ['highcharts', 'highcharts/modules/stock'], function (Highcharts) {
  17. factory(Highcharts);
  18. factory.Highcharts = Highcharts;
  19. return factory;
  20. });
  21. } else {
  22. factory(typeof Highcharts !== 'undefined' ? Highcharts : undefined);
  23. }
  24. }(function (Highcharts) {
  25. var _modules = Highcharts ? Highcharts._modules : {};
  26. function _registerModule(obj, path, args, fn) {
  27. if (!obj.hasOwnProperty(path)) {
  28. obj[path] = fn.apply(null, args);
  29. }
  30. }
  31. _registerModule(_modules, 'Stock/Indicators/MFI/MFIIndicator.js', [_modules['Core/Series/SeriesRegistry.js'], _modules['Core/Utilities.js']], function (SeriesRegistry, U) {
  32. /* *
  33. *
  34. * Money Flow Index indicator for Highcharts Stock
  35. *
  36. * (c) 2010-2021 Grzegorz Blachliński
  37. *
  38. * License: www.highcharts.com/license
  39. *
  40. * !!!!!!! SOURCE GETS TRANSPILED BY TYPESCRIPT. EDIT TS FILE ONLY. !!!!!!!
  41. *
  42. * */
  43. var __extends = (this && this.__extends) || (function () {
  44. var extendStatics = function (d,
  45. b) {
  46. extendStatics = Object.setPrototypeOf ||
  47. ({ __proto__: [] } instanceof Array && function (d,
  48. b) { d.__proto__ = b; }) ||
  49. function (d,
  50. b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
  51. return extendStatics(d, b);
  52. };
  53. return function (d, b) {
  54. extendStatics(d, b);
  55. function __() { this.constructor = d; }
  56. d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
  57. };
  58. })();
  59. var SMAIndicator = SeriesRegistry.seriesTypes.sma;
  60. var extend = U.extend,
  61. merge = U.merge,
  62. error = U.error,
  63. isArray = U.isArray;
  64. /* eslint-disable require-jsdoc */
  65. // Utils:
  66. function sumArray(array) {
  67. return array.reduce(function (prev, cur) {
  68. return prev + cur;
  69. });
  70. }
  71. function toFixed(a, n) {
  72. return parseFloat(a.toFixed(n));
  73. }
  74. function calculateTypicalPrice(point) {
  75. return (point[1] + point[2] + point[3]) / 3;
  76. }
  77. function calculateRawMoneyFlow(typicalPrice, volume) {
  78. return typicalPrice * volume;
  79. }
  80. /* eslint-enable require-jsdoc */
  81. /* *
  82. *
  83. * Class
  84. *
  85. * */
  86. /**
  87. * The MFI series type.
  88. *
  89. * @private
  90. * @class
  91. * @name Highcharts.seriesTypes.mfi
  92. *
  93. * @augments Highcharts.Series
  94. */
  95. var MFIIndicator = /** @class */ (function (_super) {
  96. __extends(MFIIndicator, _super);
  97. function MFIIndicator() {
  98. var _this = _super !== null && _super.apply(this,
  99. arguments) || this;
  100. /* *
  101. *
  102. * Properties
  103. *
  104. * */
  105. _this.data = void 0;
  106. _this.options = void 0;
  107. _this.points = void 0;
  108. return _this;
  109. }
  110. /* *
  111. *
  112. * Functions
  113. *
  114. * */
  115. MFIIndicator.prototype.getValues = function (series, params) {
  116. var period = params.period,
  117. xVal = series.xData,
  118. yVal = series.yData,
  119. yValLen = yVal ? yVal.length : 0,
  120. decimals = params.decimals,
  121. // MFI starts calculations from the second point
  122. // Cause we need to calculate change between two points
  123. range = 1,
  124. volumeSeries = series.chart.get(params.volumeSeriesID),
  125. yValVolume = (volumeSeries && volumeSeries.yData),
  126. MFI = [],
  127. isUp = false,
  128. xData = [],
  129. yData = [],
  130. positiveMoneyFlow = [],
  131. negativeMoneyFlow = [],
  132. newTypicalPrice,
  133. oldTypicalPrice,
  134. rawMoneyFlow,
  135. negativeMoneyFlowSum,
  136. positiveMoneyFlowSum,
  137. moneyFlowRatio,
  138. MFIPoint,
  139. i;
  140. if (!volumeSeries) {
  141. error('Series ' +
  142. params.volumeSeriesID +
  143. ' not found! Check `volumeSeriesID`.', true, series.chart);
  144. return;
  145. }
  146. // MFI requires high low and close values
  147. if ((xVal.length <= period) || !isArray(yVal[0]) ||
  148. yVal[0].length !== 4 ||
  149. !yValVolume) {
  150. return;
  151. }
  152. // Calculate first typical price
  153. newTypicalPrice = calculateTypicalPrice(yVal[range]);
  154. // Accumulate first N-points
  155. while (range < period + 1) {
  156. // Calculate if up or down
  157. oldTypicalPrice = newTypicalPrice;
  158. newTypicalPrice = calculateTypicalPrice(yVal[range]);
  159. isUp = newTypicalPrice >= oldTypicalPrice;
  160. // Calculate raw money flow
  161. rawMoneyFlow = calculateRawMoneyFlow(newTypicalPrice, yValVolume[range]);
  162. // Add to array
  163. positiveMoneyFlow.push(isUp ? rawMoneyFlow : 0);
  164. negativeMoneyFlow.push(isUp ? 0 : rawMoneyFlow);
  165. range++;
  166. }
  167. for (i = range - 1; i < yValLen; i++) {
  168. if (i > range - 1) {
  169. // Remove first point from array
  170. positiveMoneyFlow.shift();
  171. negativeMoneyFlow.shift();
  172. // Calculate if up or down
  173. oldTypicalPrice = newTypicalPrice;
  174. newTypicalPrice = calculateTypicalPrice(yVal[i]);
  175. isUp = newTypicalPrice > oldTypicalPrice;
  176. // Calculate raw money flow
  177. rawMoneyFlow = calculateRawMoneyFlow(newTypicalPrice, yValVolume[i]);
  178. // Add to array
  179. positiveMoneyFlow.push(isUp ? rawMoneyFlow : 0);
  180. negativeMoneyFlow.push(isUp ? 0 : rawMoneyFlow);
  181. }
  182. // Calculate sum of negative and positive money flow:
  183. negativeMoneyFlowSum = sumArray(negativeMoneyFlow);
  184. positiveMoneyFlowSum = sumArray(positiveMoneyFlow);
  185. moneyFlowRatio = positiveMoneyFlowSum / negativeMoneyFlowSum;
  186. MFIPoint = toFixed(100 - (100 / (1 + moneyFlowRatio)), decimals);
  187. MFI.push([xVal[i], MFIPoint]);
  188. xData.push(xVal[i]);
  189. yData.push(MFIPoint);
  190. }
  191. return {
  192. values: MFI,
  193. xData: xData,
  194. yData: yData
  195. };
  196. };
  197. /**
  198. * Money Flow Index. This series requires `linkedTo` option to be set and
  199. * should be loaded after the `stock/indicators/indicators.js` file.
  200. *
  201. * @sample stock/indicators/mfi
  202. * Money Flow Index Indicator
  203. *
  204. * @extends plotOptions.sma
  205. * @since 6.0.0
  206. * @product highstock
  207. * @requires stock/indicators/indicators
  208. * @requires stock/indicators/mfi
  209. * @optionparent plotOptions.mfi
  210. */
  211. MFIIndicator.defaultOptions = merge(SMAIndicator.defaultOptions, {
  212. /**
  213. * @excluding index
  214. */
  215. params: {
  216. index: void 0,
  217. /**
  218. * The id of volume series which is mandatory.
  219. * For example using OHLC data, volumeSeriesID='volume' means
  220. * the indicator will be calculated using OHLC and volume values.
  221. */
  222. volumeSeriesID: 'volume',
  223. /**
  224. * Number of maximum decimals that are used in MFI calculations.
  225. */
  226. decimals: 4
  227. }
  228. });
  229. return MFIIndicator;
  230. }(SMAIndicator));
  231. extend(MFIIndicator.prototype, {
  232. nameBase: 'Money Flow Index'
  233. });
  234. SeriesRegistry.registerSeriesType('mfi', MFIIndicator);
  235. /* *
  236. *
  237. * Default Export
  238. *
  239. * */
  240. /**
  241. * A `MFI` series. If the [type](#series.mfi.type) option is not specified, it
  242. * is inherited from [chart.type](#chart.type).
  243. *
  244. * @extends series,plotOptions.mfi
  245. * @since 6.0.0
  246. * @excluding dataParser, dataURL
  247. * @product highstock
  248. * @requires stock/indicators/indicators
  249. * @requires stock/indicators/mfi
  250. * @apioption series.mfi
  251. */
  252. ''; // to include the above in the js output
  253. return MFIIndicator;
  254. });
  255. _registerModule(_modules, 'masters/indicators/mfi.src.js', [], function () {
  256. });
  257. }));