chaikin.src.js 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376
  1. /**
  2. * @license Highstock JS v8.2.0 (2020-08-20)
  3. *
  4. * Indicator series type for Highstock
  5. *
  6. * (c) 2010-2019 Wojciech Chmiel
  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/chaikin', ['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/ADIndicator.js', [_modules['Core/Utilities.js']], function (U) {
  32. /* *
  33. *
  34. * License: www.highcharts.com/license
  35. *
  36. * !!!!!!! SOURCE GETS TRANSPILED BY TYPESCRIPT. EDIT TS FILE ONLY. !!!!!!!
  37. * */
  38. var error = U.error,
  39. seriesType = U.seriesType;
  40. /* eslint-disable valid-jsdoc */
  41. // Utils:
  42. /**
  43. * @private
  44. */
  45. function populateAverage(xVal, yVal, yValVolume, i) {
  46. var high = yVal[i][1],
  47. low = yVal[i][2],
  48. close = yVal[i][3],
  49. volume = yValVolume[i],
  50. adY = close === high && close === low || high === low ?
  51. 0 :
  52. ((2 * close - low - high) / (high - low)) * volume,
  53. adX = xVal[i];
  54. return [adX, adY];
  55. }
  56. /* eslint-enable valid-jsdoc */
  57. /**
  58. * The AD series type.
  59. *
  60. * @private
  61. * @class
  62. * @name Highcharts.seriesTypes.ad
  63. *
  64. * @augments Highcharts.Series
  65. */
  66. seriesType('ad', 'sma',
  67. /**
  68. * Accumulation Distribution (AD). This series requires `linkedTo` option to
  69. * be set.
  70. *
  71. * @sample stock/indicators/accumulation-distribution
  72. * Accumulation/Distribution indicator
  73. *
  74. * @extends plotOptions.sma
  75. * @since 6.0.0
  76. * @product highstock
  77. * @requires stock/indicators/indicators
  78. * @requires stock/indicators/accumulation-distribution
  79. * @optionparent plotOptions.ad
  80. */
  81. {
  82. params: {
  83. /**
  84. * The id of volume series which is mandatory.
  85. * For example using OHLC data, volumeSeriesID='volume' means
  86. * the indicator will be calculated using OHLC and volume values.
  87. *
  88. * @since 6.0.0
  89. */
  90. volumeSeriesID: 'volume'
  91. }
  92. },
  93. /**
  94. * @lends Highcharts.Series#
  95. */
  96. {
  97. nameComponents: false,
  98. nameBase: 'Accumulation/Distribution',
  99. getValues: function (series, params) {
  100. var period = params.period,
  101. xVal = series.xData,
  102. yVal = series.yData,
  103. volumeSeriesID = params.volumeSeriesID,
  104. volumeSeries = series.chart.get(volumeSeriesID),
  105. yValVolume = volumeSeries && volumeSeries.yData,
  106. yValLen = yVal ? yVal.length : 0,
  107. AD = [],
  108. xData = [],
  109. yData = [],
  110. len,
  111. i,
  112. ADPoint;
  113. if (xVal.length <= period &&
  114. yValLen &&
  115. yVal[0].length !== 4) {
  116. return;
  117. }
  118. if (!volumeSeries) {
  119. error('Series ' +
  120. volumeSeriesID +
  121. ' not found! Check `volumeSeriesID`.', true, series.chart);
  122. return;
  123. }
  124. // i = period <-- skip first N-points
  125. // Calculate value one-by-one for each period in visible data
  126. for (i = period; i < yValLen; i++) {
  127. len = AD.length;
  128. ADPoint = populateAverage(xVal, yVal, yValVolume, i, period);
  129. if (len > 0) {
  130. ADPoint[1] += AD[len - 1][1];
  131. }
  132. AD.push(ADPoint);
  133. xData.push(ADPoint[0]);
  134. yData.push(ADPoint[1]);
  135. }
  136. return {
  137. values: AD,
  138. xData: xData,
  139. yData: yData
  140. };
  141. }
  142. });
  143. /**
  144. * A `AD` series. If the [type](#series.ad.type) option is not
  145. * specified, it is inherited from [chart.type](#chart.type).
  146. *
  147. * @extends series,plotOptions.ad
  148. * @since 6.0.0
  149. * @excluding dataParser, dataURL
  150. * @product highstock
  151. * @requires stock/indicators/indicators
  152. * @requires stock/indicators/accumulation-distribution
  153. * @apioption series.ad
  154. */
  155. ''; // add doclet above to transpiled file
  156. });
  157. _registerModule(_modules, 'Mixins/IndicatorRequired.js', [_modules['Core/Utilities.js']], function (U) {
  158. /**
  159. *
  160. * (c) 2010-2020 Daniel Studencki
  161. *
  162. * License: www.highcharts.com/license
  163. *
  164. * !!!!!!! SOURCE GETS TRANSPILED BY TYPESCRIPT. EDIT TS FILE ONLY. !!!!!!!
  165. *
  166. * */
  167. var error = U.error;
  168. /* eslint-disable no-invalid-this, valid-jsdoc */
  169. var requiredIndicatorMixin = {
  170. /**
  171. * Check whether given indicator is loaded,
  172. else throw error.
  173. * @private
  174. * @param {Highcharts.Indicator} indicator
  175. * Indicator constructor function.
  176. * @param {string} requiredIndicator
  177. * Required indicator type.
  178. * @param {string} type
  179. * Type of indicator where function was called (parent).
  180. * @param {Highcharts.IndicatorCallbackFunction} callback
  181. * Callback which is triggered if the given indicator is loaded.
  182. * Takes indicator as an argument.
  183. * @param {string} errMessage
  184. * Error message that will be logged in console.
  185. * @return {boolean}
  186. * Returns false when there is no required indicator loaded.
  187. */
  188. isParentLoaded: function (indicator,
  189. requiredIndicator,
  190. type,
  191. callback,
  192. errMessage) {
  193. if (indicator) {
  194. return callback ? callback(indicator) : true;
  195. }
  196. error(errMessage || this.generateMessage(type, requiredIndicator));
  197. return false;
  198. },
  199. /**
  200. * @private
  201. * @param {string} indicatorType
  202. * Indicator type
  203. * @param {string} required
  204. * Required indicator
  205. * @return {string}
  206. * Error message
  207. */
  208. generateMessage: function (indicatorType, required) {
  209. return 'Error: "' + indicatorType +
  210. '" indicator type requires "' + required +
  211. '" indicator loaded before. Please read docs: ' +
  212. 'https://api.highcharts.com/highstock/plotOptions.' +
  213. indicatorType;
  214. }
  215. };
  216. return requiredIndicatorMixin;
  217. });
  218. _registerModule(_modules, 'Stock/Indicators/ChaikinIndicator.js', [_modules['Core/Globals.js'], _modules['Core/Utilities.js'], _modules['Mixins/IndicatorRequired.js']], function (H, U, requiredIndicator) {
  219. /* *
  220. *
  221. * License: www.highcharts.com/license
  222. *
  223. * !!!!!!! SOURCE GETS TRANSPILED BY TYPESCRIPT. EDIT TS FILE ONLY. !!!!!!!
  224. *
  225. * */
  226. var correctFloat = U.correctFloat,
  227. error = U.error,
  228. seriesType = U.seriesType;
  229. var EMA = H.seriesTypes.ema,
  230. AD = H.seriesTypes.ad;
  231. /**
  232. * The Chaikin series type.
  233. *
  234. * @private
  235. * @class
  236. * @name Highcharts.seriesTypes.chaikin
  237. *
  238. * @augments Highcharts.Series
  239. */
  240. seriesType('chaikin', 'ema',
  241. /**
  242. * Chaikin Oscillator. This series requires the `linkedTo` option to
  243. * be set and should be loaded after the `stock/indicators/indicators.js`
  244. * and `stock/indicators/ema.js`.
  245. *
  246. * @sample {highstock} stock/indicators/chaikin
  247. * Chaikin Oscillator
  248. *
  249. * @extends plotOptions.ema
  250. * @since 7.0.0
  251. * @product highstock
  252. * @excluding allAreas, colorAxis, joinBy, keys, navigatorOptions,
  253. * pointInterval, pointIntervalUnit, pointPlacement,
  254. * pointRange, pointStart, showInNavigator, stacking
  255. * @requires stock/indicators/indicators
  256. * @requires stock/indicators/ema
  257. * @requires stock/indicators/chaikin
  258. * @optionparent plotOptions.chaikin
  259. */
  260. {
  261. /**
  262. * Paramters used in calculation of Chaikin Oscillator
  263. * series points.
  264. *
  265. * @excluding index, period
  266. */
  267. params: {
  268. /**
  269. * The id of volume series which is mandatory.
  270. * For example using OHLC data, volumeSeriesID='volume' means
  271. * the indicator will be calculated using OHLC and volume values.
  272. */
  273. volumeSeriesID: 'volume',
  274. /**
  275. * Periods for Chaikin Oscillator calculations.
  276. *
  277. * @type {Array<number>}
  278. * @default [3, 10]
  279. */
  280. periods: [3, 10]
  281. }
  282. },
  283. /**
  284. * @lends Highcharts.Series#
  285. */
  286. {
  287. nameBase: 'Chaikin Osc',
  288. nameComponents: ['periods'],
  289. init: function () {
  290. var args = arguments,
  291. ctx = this;
  292. requiredIndicator.isParentLoaded(EMA, 'ema', ctx.type, function (indicator) {
  293. indicator.prototype.init.apply(ctx, args);
  294. return;
  295. });
  296. },
  297. getValues: function (series, params) {
  298. var periods = params.periods,
  299. period = params.period,
  300. // Accumulation Distribution Line data
  301. ADL,
  302. // 0- date, 1- Chaikin Oscillator
  303. CHA = [],
  304. xData = [],
  305. yData = [],
  306. periodsOffset,
  307. // Shorter Period EMA
  308. SPE,
  309. // Longer Period EMA
  310. LPE,
  311. oscillator,
  312. i;
  313. // Check if periods are correct
  314. if (periods.length !== 2 || periods[1] <= periods[0]) {
  315. error('Error: "Chaikin requires two periods. Notice, first ' +
  316. 'period should be lower than the second one."');
  317. return;
  318. }
  319. ADL = AD.prototype.getValues.call(this, series, {
  320. volumeSeriesID: params.volumeSeriesID,
  321. period: period
  322. });
  323. // Check if adl is calculated properly, if not skip
  324. if (!ADL) {
  325. return;
  326. }
  327. SPE = EMA.prototype.getValues.call(this, ADL, {
  328. period: periods[0]
  329. });
  330. LPE = EMA.prototype.getValues.call(this, ADL, {
  331. period: periods[1]
  332. });
  333. // Check if ema is calculated properly, if not skip
  334. if (!SPE || !LPE) {
  335. return;
  336. }
  337. periodsOffset = periods[1] - periods[0];
  338. for (i = 0; i < LPE.yData.length; i++) {
  339. oscillator = correctFloat(SPE.yData[i + periodsOffset] -
  340. LPE.yData[i]);
  341. CHA.push([LPE.xData[i], oscillator]);
  342. xData.push(LPE.xData[i]);
  343. yData.push(oscillator);
  344. }
  345. return {
  346. values: CHA,
  347. xData: xData,
  348. yData: yData
  349. };
  350. }
  351. });
  352. /**
  353. * A `Chaikin Oscillator` series. If the [type](#series.chaikin.type)
  354. * option is not specified, it is inherited from [chart.type](#chart.type).
  355. *
  356. * @extends series,plotOptions.chaikin
  357. * @since 7.0.0
  358. * @product highstock
  359. * @excluding allAreas, colorAxis, dataParser, dataURL, joinBy, keys,
  360. * navigatorOptions, pointInterval, pointIntervalUnit,
  361. * pointPlacement, pointRange, pointStart, stacking, showInNavigator
  362. * @requires stock/indicators/indicators
  363. * @requires stock/indicators/ema
  364. * @requires stock/indicators/chaikin
  365. * @apioption series.chaikin
  366. */
  367. ''; // to include the above in the js output
  368. });
  369. _registerModule(_modules, 'masters/indicators/chaikin.src.js', [], function () {
  370. });
  371. }));