macd.src.js 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463
  1. /**
  2. * @license Highstock JS v9.0.1 (2021-02-16)
  3. *
  4. * Indicator series type for Highstock
  5. *
  6. * (c) 2010-2021 Sebastian Bochan
  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/macd', ['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/MACD/MACDIndicator.js', [_modules['Core/Globals.js'], _modules['Core/Series/SeriesRegistry.js'], _modules['Core/Utilities.js']], function (H, SeriesRegistry, U) {
  32. /* *
  33. *
  34. * License: www.highcharts.com/license
  35. *
  36. * !!!!!!! SOURCE GETS TRANSPILED BY TYPESCRIPT. EDIT TS FILE ONLY. !!!!!!!
  37. *
  38. * */
  39. var __extends = (this && this.__extends) || (function () {
  40. var extendStatics = function (d,
  41. b) {
  42. extendStatics = Object.setPrototypeOf ||
  43. ({ __proto__: [] } instanceof Array && function (d,
  44. b) { d.__proto__ = b; }) ||
  45. function (d,
  46. b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
  47. return extendStatics(d, b);
  48. };
  49. return function (d, b) {
  50. extendStatics(d, b);
  51. function __() { this.constructor = d; }
  52. d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
  53. };
  54. })();
  55. var noop = H.noop;
  56. var _a = SeriesRegistry.seriesTypes,
  57. SMAIndicator = _a.sma,
  58. EMAIndicator = _a.ema,
  59. ColumnSeries = _a.column;
  60. var extend = U.extend,
  61. correctFloat = U.correctFloat,
  62. defined = U.defined,
  63. merge = U.merge;
  64. /**
  65. *
  66. * Class
  67. *
  68. */
  69. /**
  70. * The MACD series type.
  71. *
  72. * @private
  73. * @class
  74. * @name Highcharts.seriesTypes.macd
  75. *
  76. * @augments Highcharts.Series
  77. */
  78. var MACDIndicator = /** @class */ (function (_super) {
  79. __extends(MACDIndicator, _super);
  80. function MACDIndicator() {
  81. var _this = _super !== null && _super.apply(this,
  82. arguments) || this;
  83. /**
  84. *
  85. * Properties
  86. *
  87. */
  88. _this.data = void 0;
  89. _this.options = void 0;
  90. _this.points = void 0;
  91. _this.currentLineZone = void 0;
  92. _this.graphmacd = void 0;
  93. _this.graphsignal = void 0;
  94. _this.macdZones = void 0;
  95. _this.signalZones = void 0;
  96. return _this;
  97. }
  98. /**
  99. *
  100. * Functions
  101. *
  102. */
  103. MACDIndicator.prototype.init = function () {
  104. SeriesRegistry.seriesTypes.sma.prototype.init.apply(this, arguments);
  105. // Check whether series is initialized. It may be not initialized,
  106. // when any of required indicators is missing.
  107. if (this.options) {
  108. // Set default color for a signal line and the histogram:
  109. this.options = merge({
  110. signalLine: {
  111. styles: {
  112. lineColor: this.color
  113. }
  114. },
  115. macdLine: {
  116. styles: {
  117. color: this.color
  118. }
  119. }
  120. }, this.options);
  121. // Zones have indexes automatically calculated, we need to
  122. // translate them to support multiple lines within one indicator
  123. this.macdZones = {
  124. zones: this.options.macdLine.zones,
  125. startIndex: 0
  126. };
  127. this.signalZones = {
  128. zones: this.macdZones.zones.concat(this.options.signalLine.zones),
  129. startIndex: this.macdZones.zones.length
  130. };
  131. this.resetZones = true;
  132. }
  133. };
  134. MACDIndicator.prototype.toYData = function (point) {
  135. return [point.y, point.signal, point.MACD];
  136. };
  137. MACDIndicator.prototype.translate = function () {
  138. var indicator = this, plotNames = ['plotSignal', 'plotMACD'];
  139. H.seriesTypes.column.prototype.translate.apply(indicator);
  140. indicator.points.forEach(function (point) {
  141. [point.signal, point.MACD].forEach(function (value, i) {
  142. if (value !== null) {
  143. point[plotNames[i]] =
  144. indicator.yAxis.toPixels(value, true);
  145. }
  146. });
  147. });
  148. };
  149. MACDIndicator.prototype.destroy = function () {
  150. // this.graph is null due to removing two times the same SVG element
  151. this.graph = null;
  152. this.graphmacd = this.graphmacd && this.graphmacd.destroy();
  153. this.graphsignal = this.graphsignal && this.graphsignal.destroy();
  154. SeriesRegistry.seriesTypes.sma.prototype.destroy.apply(this, arguments);
  155. };
  156. MACDIndicator.prototype.drawGraph = function () {
  157. var indicator = this,
  158. mainLinePoints = indicator.points,
  159. pointsLength = mainLinePoints.length,
  160. mainLineOptions = indicator.options,
  161. histogramZones = indicator.zones,
  162. gappedExtend = {
  163. options: {
  164. gapSize: mainLineOptions.gapSize
  165. }
  166. },
  167. otherSignals = [[],
  168. []],
  169. point;
  170. // Generate points for top and bottom lines:
  171. while (pointsLength--) {
  172. point = mainLinePoints[pointsLength];
  173. if (defined(point.plotMACD)) {
  174. otherSignals[0].push({
  175. plotX: point.plotX,
  176. plotY: point.plotMACD,
  177. isNull: !defined(point.plotMACD)
  178. });
  179. }
  180. if (defined(point.plotSignal)) {
  181. otherSignals[1].push({
  182. plotX: point.plotX,
  183. plotY: point.plotSignal,
  184. isNull: !defined(point.plotMACD)
  185. });
  186. }
  187. }
  188. // Modify options and generate smoothing line:
  189. ['macd', 'signal'].forEach(function (lineName, i) {
  190. indicator.points = otherSignals[i];
  191. indicator.options = merge(mainLineOptions[lineName + 'Line'].styles, gappedExtend);
  192. indicator.graph = indicator['graph' + lineName];
  193. // Zones extension:
  194. indicator.currentLineZone = lineName + 'Zones';
  195. indicator.zones =
  196. indicator[indicator.currentLineZone].zones;
  197. SeriesRegistry.seriesTypes.sma.prototype.drawGraph.call(indicator);
  198. indicator['graph' + lineName] = indicator.graph;
  199. });
  200. // Restore options:
  201. indicator.points = mainLinePoints;
  202. indicator.options = mainLineOptions;
  203. indicator.zones = histogramZones;
  204. indicator.currentLineZone = null;
  205. // indicator.graph = null;
  206. };
  207. MACDIndicator.prototype.getZonesGraphs = function (props) {
  208. var allZones = _super.prototype.getZonesGraphs.call(this,
  209. props),
  210. currentZones = allZones;
  211. if (this.currentLineZone) {
  212. currentZones = allZones.splice(this[this.currentLineZone].startIndex + 1);
  213. if (!currentZones.length) {
  214. // Line has no zones, return basic graph "zone"
  215. currentZones = [props[0]];
  216. }
  217. else {
  218. // Add back basic prop:
  219. currentZones.splice(0, 0, props[0]);
  220. }
  221. }
  222. return currentZones;
  223. };
  224. MACDIndicator.prototype.applyZones = function () {
  225. // Histogram zones are handled by drawPoints method
  226. // Here we need to apply zones for all lines
  227. var histogramZones = this.zones;
  228. // signalZones.zones contains all zones:
  229. this.zones = this.signalZones.zones;
  230. SeriesRegistry.seriesTypes.sma.prototype.applyZones.call(this);
  231. // applyZones hides only main series.graph, hide macd line manually
  232. if (this.graphmacd && this.options.macdLine.zones.length) {
  233. this.graphmacd.hide();
  234. }
  235. this.zones = histogramZones;
  236. };
  237. MACDIndicator.prototype.getValues = function (series, params) {
  238. var j = 0,
  239. MACD = [],
  240. xMACD = [],
  241. yMACD = [],
  242. signalLine = [],
  243. shortEMA,
  244. longEMA,
  245. i;
  246. if (series.xData.length <
  247. params.longPeriod + params.signalPeriod) {
  248. return;
  249. }
  250. // Calculating the short and long EMA used when calculating the MACD
  251. shortEMA = SeriesRegistry.seriesTypes.ema.prototype.getValues(series, {
  252. period: params.shortPeriod,
  253. index: params.index
  254. });
  255. longEMA = SeriesRegistry.seriesTypes.ema.prototype.getValues(series, {
  256. period: params.longPeriod,
  257. index: params.index
  258. });
  259. shortEMA = shortEMA.values;
  260. longEMA = longEMA.values;
  261. // Subtract each Y value from the EMA's and create the new dataset
  262. // (MACD)
  263. for (i = 1; i <= shortEMA.length; i++) {
  264. if (defined(longEMA[i - 1]) &&
  265. defined(longEMA[i - 1][1]) &&
  266. defined(shortEMA[i + params.shortPeriod + 1]) &&
  267. defined(shortEMA[i + params.shortPeriod + 1][0])) {
  268. MACD.push([
  269. shortEMA[i + params.shortPeriod + 1][0],
  270. 0,
  271. null,
  272. shortEMA[i + params.shortPeriod + 1][1] -
  273. longEMA[i - 1][1]
  274. ]);
  275. }
  276. }
  277. // Set the Y and X data of the MACD. This is used in calculating the
  278. // signal line.
  279. for (i = 0; i < MACD.length; i++) {
  280. xMACD.push(MACD[i][0]);
  281. yMACD.push([0, null, MACD[i][3]]);
  282. }
  283. // Setting the signalline (Signal Line: X-day EMA of MACD line).
  284. signalLine = SeriesRegistry.seriesTypes.ema.prototype.getValues({
  285. xData: xMACD,
  286. yData: yMACD
  287. }, {
  288. period: params.signalPeriod,
  289. index: 2
  290. });
  291. signalLine = signalLine.values;
  292. // Setting the MACD Histogram. In comparison to the loop with pure
  293. // MACD this loop uses MACD x value not xData.
  294. for (i = 0; i < MACD.length; i++) {
  295. // detect the first point
  296. if (MACD[i][0] >= signalLine[0][0]) {
  297. MACD[i][2] = signalLine[j][1];
  298. yMACD[i] = [0, signalLine[j][1], MACD[i][3]];
  299. if (MACD[i][3] === null) {
  300. MACD[i][1] = 0;
  301. yMACD[i][0] = 0;
  302. }
  303. else {
  304. MACD[i][1] = correctFloat(MACD[i][3] -
  305. signalLine[j][1]);
  306. yMACD[i][0] = correctFloat(MACD[i][3] -
  307. signalLine[j][1]);
  308. }
  309. j++;
  310. }
  311. }
  312. return {
  313. values: MACD,
  314. xData: xMACD,
  315. yData: yMACD
  316. };
  317. };
  318. /**
  319. * Moving Average Convergence Divergence (MACD). This series requires
  320. * `linkedTo` option to be set and should be loaded after the
  321. * `stock/indicators/indicators.js` and `stock/indicators/ema.js`.
  322. *
  323. * @sample stock/indicators/macd
  324. * MACD indicator
  325. *
  326. * @extends plotOptions.sma
  327. * @since 6.0.0
  328. * @product highstock
  329. * @requires stock/indicators/indicators
  330. * @requires stock/indicators/macd
  331. * @optionparent plotOptions.macd
  332. */
  333. MACDIndicator.defaultOptions = merge(SMAIndicator.defaultOptions, {
  334. params: {
  335. /**
  336. * The short period for indicator calculations.
  337. */
  338. shortPeriod: 12,
  339. /**
  340. * The long period for indicator calculations.
  341. */
  342. longPeriod: 26,
  343. /**
  344. * The base period for signal calculations.
  345. */
  346. signalPeriod: 9,
  347. period: 26
  348. },
  349. /**
  350. * The styles for signal line
  351. */
  352. signalLine: {
  353. /**
  354. * @sample stock/indicators/macd-zones
  355. * Zones in MACD
  356. *
  357. * @extends plotOptions.macd.zones
  358. */
  359. zones: [],
  360. styles: {
  361. /**
  362. * Pixel width of the line.
  363. */
  364. lineWidth: 1,
  365. /**
  366. * Color of the line.
  367. *
  368. * @type {Highcharts.ColorString}
  369. */
  370. lineColor: void 0
  371. }
  372. },
  373. /**
  374. * The styles for macd line
  375. */
  376. macdLine: {
  377. /**
  378. * @sample stock/indicators/macd-zones
  379. * Zones in MACD
  380. *
  381. * @extends plotOptions.macd.zones
  382. */
  383. zones: [],
  384. styles: {
  385. /**
  386. * Pixel width of the line.
  387. */
  388. lineWidth: 1,
  389. /**
  390. * Color of the line.
  391. *
  392. * @type {Highcharts.ColorString}
  393. */
  394. lineColor: void 0
  395. }
  396. },
  397. /**
  398. * @type {number|null}
  399. */
  400. threshold: 0,
  401. groupPadding: 0.1,
  402. pointPadding: 0.1,
  403. crisp: false,
  404. states: {
  405. hover: {
  406. halo: {
  407. size: 0
  408. }
  409. }
  410. },
  411. tooltip: {
  412. pointFormat: '<span style="color:{point.color}">\u25CF</span> <b> {series.name}</b><br/>' +
  413. 'Value: {point.MACD}<br/>' +
  414. 'Signal: {point.signal}<br/>' +
  415. 'Histogram: {point.y}<br/>'
  416. },
  417. dataGrouping: {
  418. approximation: 'averages'
  419. },
  420. minPointLength: 0
  421. });
  422. return MACDIndicator;
  423. }(SMAIndicator));
  424. extend(MACDIndicator.prototype, {
  425. nameComponents: ['longPeriod', 'shortPeriod', 'signalPeriod'],
  426. requiredIndicators: ['ema'],
  427. // "y" value is treated as Histogram data
  428. pointArrayMap: ['y', 'signal', 'MACD'],
  429. parallelArrays: ['x', 'y', 'signal', 'MACD'],
  430. pointValKey: 'y',
  431. // Columns support:
  432. markerAttribs: noop,
  433. getColumnMetrics: H.seriesTypes.column.prototype.getColumnMetrics,
  434. crispCol: H.seriesTypes.column.prototype.crispCol,
  435. drawPoints: H.seriesTypes.column.prototype.drawPoints
  436. });
  437. SeriesRegistry.registerSeriesType('macd', MACDIndicator);
  438. /* *
  439. *
  440. * Default Export
  441. *
  442. * */
  443. /**
  444. * A `MACD` series. If the [type](#series.macd.type) option is not
  445. * specified, it is inherited from [chart.type](#chart.type).
  446. *
  447. * @extends series,plotOptions.macd
  448. * @since 6.0.0
  449. * @product highstock
  450. * @excluding dataParser, dataURL
  451. * @requires stock/indicators/indicators
  452. * @requires stock/indicators/macd
  453. * @apioption series.macd
  454. */
  455. ''; // to include the above in the js output
  456. return MACDIndicator;
  457. });
  458. _registerModule(_modules, 'masters/indicators/macd.src.js', [], function () {
  459. });
  460. }));