psar.src.js 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343
  1. /**
  2. * @license Highstock JS v9.1.1 (2021-06-04)
  3. *
  4. * Parabolic SAR 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/psar', ['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/PSAR/PSARIndicator.js', [_modules['Core/Series/SeriesRegistry.js'], _modules['Core/Utilities.js']], function (SeriesRegistry, U) {
  32. /* *
  33. *
  34. * Parabolic SAR 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 merge = U.merge,
  61. extend = U.extend;
  62. /* eslint-disable require-jsdoc */
  63. // Utils:
  64. function toFixed(a, n) {
  65. return parseFloat(a.toFixed(n));
  66. }
  67. function calculateDirection(previousDirection, low, high, PSAR) {
  68. if ((previousDirection === 1 && low > PSAR) ||
  69. (previousDirection === -1 && high > PSAR)) {
  70. return 1;
  71. }
  72. return -1;
  73. }
  74. /* *
  75. * Method for calculating acceleration factor
  76. * dir - direction
  77. * pDir - previous Direction
  78. * eP - extreme point
  79. * pEP - previous extreme point
  80. * inc - increment for acceleration factor
  81. * maxAcc - maximum acceleration factor
  82. * initAcc - initial acceleration factor
  83. */
  84. function getAccelerationFactor(dir, pDir, eP, pEP, pAcc, inc, maxAcc, initAcc) {
  85. if (dir === pDir) {
  86. if (dir === 1 && (eP > pEP)) {
  87. return (pAcc === maxAcc) ? maxAcc : toFixed(pAcc + inc, 2);
  88. }
  89. if (dir === -1 && (eP < pEP)) {
  90. return (pAcc === maxAcc) ? maxAcc : toFixed(pAcc + inc, 2);
  91. }
  92. return pAcc;
  93. }
  94. return initAcc;
  95. }
  96. function getExtremePoint(high, low, previousDirection, previousExtremePoint) {
  97. if (previousDirection === 1) {
  98. return (high > previousExtremePoint) ? high : previousExtremePoint;
  99. }
  100. return (low < previousExtremePoint) ? low : previousExtremePoint;
  101. }
  102. function getEPMinusPSAR(EP, PSAR) {
  103. return EP - PSAR;
  104. }
  105. function getAccelerationFactorMultiply(accelerationFactor, EPMinusSAR) {
  106. return accelerationFactor * EPMinusSAR;
  107. }
  108. /* *
  109. * Method for calculating PSAR
  110. * pdir - previous direction
  111. * sDir - second previous Direction
  112. * PSAR - previous PSAR
  113. * pACCMultiply - previous acceleration factor multiply
  114. * sLow - second previous low
  115. * pLow - previous low
  116. * sHigh - second previous high
  117. * pHigh - previous high
  118. * pEP - previous extreme point
  119. */
  120. function getPSAR(pdir, sDir, PSAR, pACCMulti, sLow, pLow, pHigh, sHigh, pEP) {
  121. if (pdir === sDir) {
  122. if (pdir === 1) {
  123. return (PSAR + pACCMulti < Math.min(sLow, pLow)) ?
  124. PSAR + pACCMulti :
  125. Math.min(sLow, pLow);
  126. }
  127. return (PSAR + pACCMulti > Math.max(sHigh, pHigh)) ?
  128. PSAR + pACCMulti :
  129. Math.max(sHigh, pHigh);
  130. }
  131. return pEP;
  132. }
  133. /* eslint-enable require-jsdoc */
  134. /* *
  135. *
  136. * Class
  137. *
  138. * */
  139. /**
  140. * The Parabolic SAR series type.
  141. *
  142. * @private
  143. * @class
  144. * @name Highcharts.seriesTypes.psar
  145. *
  146. * @augments Highcharts.Series
  147. */
  148. var PSARIndicator = /** @class */ (function (_super) {
  149. __extends(PSARIndicator, _super);
  150. function PSARIndicator() {
  151. var _this = _super !== null && _super.apply(this,
  152. arguments) || this;
  153. /* *
  154. *
  155. * Properties
  156. *
  157. * */
  158. _this.data = void 0;
  159. _this.points = void 0;
  160. _this.options = void 0;
  161. return _this;
  162. }
  163. /* *
  164. *
  165. * Functions
  166. *
  167. * */
  168. PSARIndicator.prototype.getValues = function (series, params) {
  169. var xVal = series.xData,
  170. yVal = series.yData,
  171. // Extreme point is the lowest low for falling and highest high
  172. // for rising psar - and we are starting with falling
  173. extremePoint = yVal[0][1],
  174. accelerationFactor = params.initialAccelerationFactor,
  175. maxAccelerationFactor = params.maxAccelerationFactor,
  176. increment = params.increment,
  177. // Set initial acc factor (for every new trend!)
  178. initialAccelerationFactor = params.initialAccelerationFactor,
  179. PSAR = yVal[0][2],
  180. decimals = params.decimals,
  181. index = params.index,
  182. PSARArr = [],
  183. xData = [],
  184. yData = [],
  185. previousDirection = 1,
  186. direction,
  187. EPMinusPSAR,
  188. accelerationFactorMultiply,
  189. newDirection,
  190. prevLow,
  191. prevPrevLow,
  192. prevHigh,
  193. prevPrevHigh,
  194. newExtremePoint,
  195. high,
  196. low,
  197. ind;
  198. if (index >= yVal.length) {
  199. return;
  200. }
  201. for (ind = 0; ind < index; ind++) {
  202. extremePoint = Math.max(yVal[ind][1], extremePoint);
  203. PSAR = Math.min(yVal[ind][2], toFixed(PSAR, decimals));
  204. }
  205. direction = (yVal[ind][1] > PSAR) ? 1 : -1;
  206. EPMinusPSAR = getEPMinusPSAR(extremePoint, PSAR);
  207. accelerationFactor = params.initialAccelerationFactor;
  208. accelerationFactorMultiply = getAccelerationFactorMultiply(accelerationFactor, EPMinusPSAR);
  209. PSARArr.push([xVal[index], PSAR]);
  210. xData.push(xVal[index]);
  211. yData.push(toFixed(PSAR, decimals));
  212. for (ind = index + 1; ind < yVal.length; ind++) {
  213. prevLow = yVal[ind - 1][2];
  214. prevPrevLow = yVal[ind - 2][2];
  215. prevHigh = yVal[ind - 1][1];
  216. prevPrevHigh = yVal[ind - 2][1];
  217. high = yVal[ind][1];
  218. low = yVal[ind][2];
  219. // Null points break PSAR
  220. if (prevPrevLow !== null &&
  221. prevPrevHigh !== null &&
  222. prevLow !== null &&
  223. prevHigh !== null &&
  224. high !== null &&
  225. low !== null) {
  226. PSAR = getPSAR(direction, previousDirection, PSAR, accelerationFactorMultiply, prevPrevLow, prevLow, prevHigh, prevPrevHigh, extremePoint);
  227. newExtremePoint = getExtremePoint(high, low, direction, extremePoint);
  228. newDirection = calculateDirection(previousDirection, low, high, PSAR);
  229. accelerationFactor = getAccelerationFactor(newDirection, direction, newExtremePoint, extremePoint, accelerationFactor, increment, maxAccelerationFactor, initialAccelerationFactor);
  230. EPMinusPSAR = getEPMinusPSAR(newExtremePoint, PSAR);
  231. accelerationFactorMultiply = getAccelerationFactorMultiply(accelerationFactor, EPMinusPSAR);
  232. PSARArr.push([xVal[ind], toFixed(PSAR, decimals)]);
  233. xData.push(xVal[ind]);
  234. yData.push(toFixed(PSAR, decimals));
  235. previousDirection = direction;
  236. direction = newDirection;
  237. extremePoint = newExtremePoint;
  238. }
  239. }
  240. return {
  241. values: PSARArr,
  242. xData: xData,
  243. yData: yData
  244. };
  245. };
  246. /**
  247. * Parabolic SAR. This series requires `linkedTo`
  248. * option to be set and should be loaded
  249. * after `stock/indicators/indicators.js` file.
  250. *
  251. * @sample stock/indicators/psar
  252. * Parabolic SAR Indicator
  253. *
  254. * @extends plotOptions.sma
  255. * @since 6.0.0
  256. * @product highstock
  257. * @requires stock/indicators/indicators
  258. * @requires stock/indicators/psar
  259. * @optionparent plotOptions.psar
  260. */
  261. PSARIndicator.defaultOptions = merge(SMAIndicator.defaultOptions, {
  262. lineWidth: 0,
  263. marker: {
  264. enabled: true
  265. },
  266. states: {
  267. hover: {
  268. lineWidthPlus: 0
  269. }
  270. },
  271. /**
  272. * @excluding period
  273. */
  274. params: {
  275. period: void 0,
  276. /**
  277. * The initial value for acceleration factor.
  278. * Acceleration factor is starting with this value
  279. * and increases by specified increment each time
  280. * the extreme point makes a new high.
  281. * AF can reach a maximum of maxAccelerationFactor,
  282. * no matter how long the uptrend extends.
  283. */
  284. initialAccelerationFactor: 0.02,
  285. /**
  286. * The Maximum value for acceleration factor.
  287. * AF can reach a maximum of maxAccelerationFactor,
  288. * no matter how long the uptrend extends.
  289. */
  290. maxAccelerationFactor: 0.2,
  291. /**
  292. * Acceleration factor increases by increment each time
  293. * the extreme point makes a new high.
  294. *
  295. * @since 6.0.0
  296. */
  297. increment: 0.02,
  298. /**
  299. * Index from which PSAR is starting calculation
  300. *
  301. * @since 6.0.0
  302. */
  303. index: 2,
  304. /**
  305. * Number of maximum decimals that are used in PSAR calculations.
  306. *
  307. * @since 6.0.0
  308. */
  309. decimals: 4
  310. }
  311. });
  312. return PSARIndicator;
  313. }(SMAIndicator));
  314. extend(PSARIndicator.prototype, {
  315. nameComponents: void 0
  316. });
  317. SeriesRegistry.registerSeriesType('psar', PSARIndicator);
  318. /* *
  319. *
  320. * Default Export
  321. *
  322. * */
  323. /**
  324. * A `PSAR` series. If the [type](#series.psar.type) option is not specified, it
  325. * is inherited from [chart.type](#chart.type).
  326. *
  327. * @extends series,plotOptions.psar
  328. * @since 6.0.0
  329. * @product highstock
  330. * @excluding dataParser, dataURL
  331. * @requires stock/indicators/indicators
  332. * @requires stock/indicators/psar
  333. * @apioption series.psar
  334. */
  335. ''; // to include the above in the js output
  336. return PSARIndicator;
  337. });
  338. _registerModule(_modules, 'masters/indicators/psar.src.js', [], function () {
  339. });
  340. }));