pivot-points.src.js 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477
  1. /**
  2. * @license Highstock JS v9.1.1 (2021-06-04)
  3. *
  4. * Indicator series type for Highcharts Stock
  5. *
  6. * (c) 2010-2021 Paweł Fus
  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/pivot-points', ['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/PivotPoints/PivotPointsPoint.js', [_modules['Core/Series/SeriesRegistry.js']], function (SeriesRegistry) {
  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 SMAIndicator = SeriesRegistry.seriesTypes.sma;
  56. /* eslint-disable valid-jsdoc */
  57. /**
  58. * @private
  59. */
  60. function destroyExtraLabels(point, functionName) {
  61. var props = point.series.pointArrayMap,
  62. prop,
  63. i = props.length;
  64. SeriesRegistry.seriesTypes.sma.prototype.pointClass.prototype[functionName].call(point);
  65. while (i--) {
  66. prop = 'dataLabel' + props[i];
  67. // S4 dataLabel could be removed by parent method:
  68. if (point[prop] && point[prop].element) {
  69. point[prop].destroy();
  70. }
  71. point[prop] = null;
  72. }
  73. }
  74. /* eslint-enable valid-jsdoc */
  75. /* *
  76. *
  77. * Class
  78. *
  79. * */
  80. var PivotPointsPoint = /** @class */ (function (_super) {
  81. __extends(PivotPointsPoint, _super);
  82. function PivotPointsPoint() {
  83. /**
  84. *
  85. * Properties
  86. *
  87. */
  88. var _this = _super !== null && _super.apply(this,
  89. arguments) || this;
  90. _this.P = void 0;
  91. _this.pivotLine = void 0;
  92. _this.series = void 0;
  93. return _this;
  94. }
  95. /**
  96. *
  97. * Functions
  98. *
  99. */
  100. PivotPointsPoint.prototype.destroyElements = function () {
  101. destroyExtraLabels(this, 'destroyElements');
  102. };
  103. // This method is called when removing points, e.g. series.update()
  104. PivotPointsPoint.prototype.destroy = function () {
  105. destroyExtraLabels(this, 'destroyElements');
  106. };
  107. return PivotPointsPoint;
  108. }(SMAIndicator.prototype.pointClass));
  109. /* *
  110. *
  111. * Default Export
  112. *
  113. * */
  114. return PivotPointsPoint;
  115. });
  116. _registerModule(_modules, 'Stock/Indicators/PivotPoints/PivotPointsIndicator.js', [_modules['Stock/Indicators/PivotPoints/PivotPointsPoint.js'], _modules['Core/Series/SeriesRegistry.js'], _modules['Core/Utilities.js']], function (PivotPointsPoint, SeriesRegistry, U) {
  117. /* *
  118. *
  119. * License: www.highcharts.com/license
  120. *
  121. * !!!!!!! SOURCE GETS TRANSPILED BY TYPESCRIPT. EDIT TS FILE ONLY. !!!!!!!
  122. *
  123. * */
  124. var __extends = (this && this.__extends) || (function () {
  125. var extendStatics = function (d,
  126. b) {
  127. extendStatics = Object.setPrototypeOf ||
  128. ({ __proto__: [] } instanceof Array && function (d,
  129. b) { d.__proto__ = b; }) ||
  130. function (d,
  131. b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
  132. return extendStatics(d, b);
  133. };
  134. return function (d, b) {
  135. extendStatics(d, b);
  136. function __() { this.constructor = d; }
  137. d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
  138. };
  139. })();
  140. var SMAIndicator = SeriesRegistry.seriesTypes.sma;
  141. var merge = U.merge,
  142. extend = U.extend,
  143. defined = U.defined,
  144. isArray = U.isArray;
  145. /**
  146. *
  147. * Class
  148. *
  149. **/
  150. /**
  151. * The Pivot Points series type.
  152. *
  153. * @private
  154. * @class
  155. * @name Highcharts.seriesTypes.pivotpoints
  156. *
  157. * @augments Highcharts.Series
  158. */
  159. var PivotPointsIndicator = /** @class */ (function (_super) {
  160. __extends(PivotPointsIndicator, _super);
  161. function PivotPointsIndicator() {
  162. var _this = _super !== null && _super.apply(this,
  163. arguments) || this;
  164. /**
  165. *
  166. * Properties
  167. *
  168. */
  169. _this.data = void 0;
  170. _this.options = void 0;
  171. _this.points = void 0;
  172. _this.endPoint = void 0;
  173. _this.plotEndPoint = void 0;
  174. return _this;
  175. }
  176. /**
  177. *
  178. * Functions
  179. *
  180. */
  181. PivotPointsIndicator.prototype.toYData = function (point) {
  182. return [point.P]; // The rest should not affect extremes
  183. };
  184. PivotPointsIndicator.prototype.translate = function () {
  185. var indicator = this;
  186. SeriesRegistry.seriesTypes.sma.prototype.translate.apply(indicator);
  187. indicator.points.forEach(function (point) {
  188. indicator.pointArrayMap.forEach(function (value) {
  189. if (defined(point[value])) {
  190. point['plot' + value] = (indicator.yAxis.toPixels(point[value], true));
  191. }
  192. });
  193. });
  194. // Pivot points are rendered as horizontal lines
  195. // And last point start not from the next one (as it's the last one)
  196. // But from the approximated last position in a given range
  197. indicator.plotEndPoint = indicator.xAxis.toPixels(indicator.endPoint, true);
  198. };
  199. PivotPointsIndicator.prototype.getGraphPath = function (points) {
  200. var indicator = this,
  201. pointsLength = points.length,
  202. allPivotPoints = ([[],
  203. [],
  204. [],
  205. [],
  206. [],
  207. [],
  208. [],
  209. [],
  210. []]),
  211. path = [],
  212. endPoint = indicator.plotEndPoint,
  213. pointArrayMapLength = indicator.pointArrayMap.length,
  214. position,
  215. point,
  216. i;
  217. while (pointsLength--) {
  218. point = points[pointsLength];
  219. for (i = 0; i < pointArrayMapLength; i++) {
  220. position = indicator.pointArrayMap[i];
  221. if (defined(point[position])) {
  222. allPivotPoints[i].push({
  223. // Start left:
  224. plotX: point.plotX,
  225. plotY: point['plot' + position],
  226. isNull: false
  227. }, {
  228. // Go to right:
  229. plotX: endPoint,
  230. plotY: point['plot' + position],
  231. isNull: false
  232. }, {
  233. // And add null points in path to generate breaks:
  234. plotX: endPoint,
  235. plotY: null,
  236. isNull: true
  237. });
  238. }
  239. }
  240. endPoint = point.plotX;
  241. }
  242. allPivotPoints.forEach(function (pivotPoints) {
  243. path = path.concat(SeriesRegistry.seriesTypes.sma.prototype.getGraphPath.call(indicator, pivotPoints));
  244. });
  245. return path;
  246. };
  247. // TODO: Rewrite this logic to use multiple datalabels
  248. PivotPointsIndicator.prototype.drawDataLabels = function () {
  249. var indicator = this,
  250. pointMapping = indicator.pointArrayMap,
  251. currentLabel,
  252. pointsLength,
  253. point,
  254. i;
  255. if (indicator.options.dataLabels.enabled) {
  256. pointsLength = indicator.points.length;
  257. // For every Ressitance/Support group we need to render labels.
  258. // Add one more item, which will just store dataLabels from
  259. // previous iteration
  260. pointMapping.concat([false]).forEach(function (position, k) {
  261. i = pointsLength;
  262. while (i--) {
  263. point = indicator.points[i];
  264. if (!position) {
  265. // Store S4 dataLabel too:
  266. point['dataLabel' + pointMapping[k - 1]] =
  267. point.dataLabel;
  268. }
  269. else {
  270. point.y = point[position];
  271. point.pivotLine = position;
  272. point.plotY = point['plot' + position];
  273. currentLabel = point['dataLabel' + position];
  274. // Store previous label
  275. if (k) {
  276. point['dataLabel' + pointMapping[k - 1]] = point.dataLabel;
  277. }
  278. if (!point.dataLabels) {
  279. point.dataLabels = [];
  280. }
  281. point.dataLabels[0] = point.dataLabel =
  282. currentLabel =
  283. currentLabel && currentLabel.element ?
  284. currentLabel :
  285. null;
  286. }
  287. }
  288. SeriesRegistry.seriesTypes.sma.prototype.drawDataLabels.apply(indicator, arguments);
  289. });
  290. }
  291. };
  292. PivotPointsIndicator.prototype.getValues = function (series, params) {
  293. var period = params.period,
  294. xVal = series.xData,
  295. yVal = series.yData,
  296. yValLen = yVal ? yVal.length : 0,
  297. placement = this[params.algorithm + 'Placement'],
  298. // 0- from, 1- to, 2- R1, 3- R2, 4- pivot, 5- S1 etc.
  299. PP = [],
  300. endTimestamp,
  301. xData = [],
  302. yData = [],
  303. slicedXLen,
  304. slicedX,
  305. slicedY,
  306. lastPP,
  307. pivot,
  308. avg,
  309. i;
  310. // Pivot Points requires high, low and close values
  311. if (xVal.length < period ||
  312. !isArray(yVal[0]) ||
  313. yVal[0].length !== 4) {
  314. return;
  315. }
  316. for (i = period + 1; i <= yValLen + period; i += period) {
  317. slicedX = xVal.slice(i - period - 1, i);
  318. slicedY = yVal.slice(i - period - 1, i);
  319. slicedXLen = slicedX.length;
  320. endTimestamp = slicedX[slicedXLen - 1];
  321. pivot = this.getPivotAndHLC(slicedY);
  322. avg = placement(pivot);
  323. lastPP = PP.push([endTimestamp]
  324. .concat(avg));
  325. xData.push(endTimestamp);
  326. yData.push(PP[lastPP - 1].slice(1));
  327. }
  328. // We don't know exact position in ordinal axis
  329. // So we use simple logic:
  330. // Get first point in last range, calculate visible average range
  331. // and multiply by period
  332. this.endPoint = slicedX[0] + ((endTimestamp - slicedX[0]) /
  333. slicedXLen) * period;
  334. return {
  335. values: PP,
  336. xData: xData,
  337. yData: yData
  338. };
  339. };
  340. PivotPointsIndicator.prototype.getPivotAndHLC = function (values) {
  341. var high = -Infinity,
  342. low = Infinity,
  343. close = values[values.length - 1][3],
  344. pivot;
  345. values.forEach(function (p) {
  346. high = Math.max(high, p[1]);
  347. low = Math.min(low, p[2]);
  348. });
  349. pivot = (high + low + close) / 3;
  350. return [pivot, high, low, close];
  351. };
  352. PivotPointsIndicator.prototype.standardPlacement = function (values) {
  353. var diff = values[1] - values[2],
  354. avg = [
  355. null,
  356. null,
  357. values[0] + diff,
  358. values[0] * 2 - values[2],
  359. values[0],
  360. values[0] * 2 - values[1],
  361. values[0] - diff,
  362. null,
  363. null
  364. ];
  365. return avg;
  366. };
  367. PivotPointsIndicator.prototype.camarillaPlacement = function (values) {
  368. var diff = values[1] - values[2],
  369. avg = [
  370. values[3] + diff * 1.5,
  371. values[3] + diff * 1.25,
  372. values[3] + diff * 1.1666,
  373. values[3] + diff * 1.0833,
  374. values[0],
  375. values[3] - diff * 1.0833,
  376. values[3] - diff * 1.1666,
  377. values[3] - diff * 1.25,
  378. values[3] - diff * 1.5
  379. ];
  380. return avg;
  381. };
  382. PivotPointsIndicator.prototype.fibonacciPlacement = function (values) {
  383. var diff = values[1] - values[2],
  384. avg = [
  385. null,
  386. values[0] + diff,
  387. values[0] + diff * 0.618,
  388. values[0] + diff * 0.382,
  389. values[0],
  390. values[0] - diff * 0.382,
  391. values[0] - diff * 0.618,
  392. values[0] - diff,
  393. null
  394. ];
  395. return avg;
  396. };
  397. /**
  398. * Pivot points indicator. This series requires the `linkedTo` option to be
  399. * set and should be loaded after `stock/indicators/indicators.js` file.
  400. *
  401. * @sample stock/indicators/pivot-points
  402. * Pivot points
  403. *
  404. * @extends plotOptions.sma
  405. * @since 6.0.0
  406. * @product highstock
  407. * @requires stock/indicators/indicators
  408. * @requires stock/indicators/pivotpoints
  409. * @optionparent plotOptions.pivotpoints
  410. */
  411. PivotPointsIndicator.defaultOptions = merge(SMAIndicator.defaultOptions, {
  412. /**
  413. * @excluding index
  414. */
  415. params: {
  416. index: void 0,
  417. period: 28,
  418. /**
  419. * Algorithm used to calculate ressistance and support lines based
  420. * on pivot points. Implemented algorithms: `'standard'`,
  421. * `'fibonacci'` and `'camarilla'`
  422. */
  423. algorithm: 'standard'
  424. },
  425. marker: {
  426. enabled: false
  427. },
  428. enableMouseTracking: false,
  429. dataLabels: {
  430. enabled: true,
  431. format: '{point.pivotLine}'
  432. },
  433. dataGrouping: {
  434. approximation: 'averages'
  435. }
  436. });
  437. return PivotPointsIndicator;
  438. }(SMAIndicator));
  439. extend(PivotPointsIndicator.prototype, {
  440. nameBase: 'Pivot Points',
  441. pointArrayMap: ['R4', 'R3', 'R2', 'R1', 'P', 'S1', 'S2', 'S3', 'S4'],
  442. pointValKey: 'P',
  443. pointClass: PivotPointsPoint
  444. });
  445. /* *
  446. *
  447. * Registry
  448. *
  449. * */
  450. SeriesRegistry.registerSeriesType('pivotpoints', PivotPointsIndicator);
  451. /* *
  452. *
  453. * Default Export
  454. *
  455. * */
  456. /**
  457. * A pivot points indicator. If the [type](#series.pivotpoints.type) option is
  458. * not specified, it is inherited from [chart.type](#chart.type).
  459. *
  460. * @extends series,plotOptions.pivotpoints
  461. * @since 6.0.0
  462. * @product highstock
  463. * @excluding dataParser, dataURL
  464. * @requires stock/indicators/indicators
  465. * @requires stock/indicators/pivotpoints
  466. * @apioption series.pivotpoints
  467. */
  468. ''; // to include the above in the js output'
  469. return PivotPointsIndicator;
  470. });
  471. _registerModule(_modules, 'masters/indicators/pivot-points.src.js', [], function () {
  472. });
  473. }));