ohlcv-indicators 3.4.7 → 3.4.9

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/index.js CHANGED
@@ -259,6 +259,27 @@ export default class OHLCV_INDICATORS {
259
259
  return this
260
260
  }
261
261
 
262
+ atr(size = 14, options = {}) {
263
+
264
+ const methodName = 'atr'
265
+
266
+ isAlreadyComputed(this)
267
+
268
+ validateNumber(size, {min: 1, max: this.len, allowDecimals: false}, 'size', methodName)
269
+ validateObject(options, 'options', methodName)
270
+
271
+ const {lag = 0, tp = null, sl = null} = options
272
+
273
+ validateNumber(lag, {min: 0, max: this.len, allowDecimals: false}, 'options.lag', methodName)
274
+
275
+ if(tp !== null) validateNumber(tp, {min: 0.01, max: 100, allowDecimals: true}, 'options.tp', methodName)
276
+ if(sl !== null) validateNumber(sl, {min: 0.01, max: 100, allowDecimals: true}, 'options.tp', methodName)
277
+
278
+ this.inputParams.push({key: methodName, params: [size, {lag, tp, sl}]})
279
+
280
+ return this
281
+ }
282
+
262
283
  ema(size = 5, options = {}) {
263
284
 
264
285
  const methodName = 'ema'
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ohlcv-indicators",
3
- "version": "3.4.7",
3
+ "version": "3.4.9",
4
4
  "description": "A JavaScript library featuring optimized trading indicators for OHLCV arrays [{open, high, low, close, value}]. This library is optimized for backtesting and trading bot development.",
5
5
  "main": "index.js",
6
6
  "type": "module",
@@ -10,6 +10,7 @@ import { lag } from "../studies/lag.js";
10
10
  import { crossPairs } from "../studies/findCrosses.js";
11
11
  import { dateTime } from "../studies/dateTime.js";
12
12
  import { scaler } from "../studies/scaler.js";
13
+ import { atr } from "../volatility/atr.js";
13
14
 
14
15
  import { buildArray } from "../utilities/assignTypes.js";
15
16
  import { numberFormater } from "../utilities/numberUtilities.js";
@@ -19,6 +20,7 @@ import { dateFormaters } from "../utilities/dateUtilities.js";
19
20
  const indicatorFunctions = {
20
21
  dateTime,
21
22
  rsi,
23
+ atr,
22
24
  ema: movingAverages,
23
25
  sma: movingAverages,
24
26
  macd,
@@ -1,7 +1,10 @@
1
1
 
2
2
  import {FasterEMA, FasterSMA} from 'trading-signals';
3
3
 
4
- const indicatorClasses = {ema: FasterEMA, sma: FasterSMA}
4
+ const indicatorClasses = {
5
+ ema: FasterEMA,
6
+ sma: FasterSMA
7
+ }
5
8
 
6
9
  export const movingAverages = (main, index, indicatorName, size, { target, lag, precomputed }) => {
7
10
  const { verticalOhlcv, instances } = main
@@ -18,13 +21,13 @@ export const movingAverages = (main, index, indicatorName, size, { target, lag,
18
21
 
19
22
  // Retrieve the current price value.
20
23
  const value = verticalOhlcv[target][index]
21
- const { maInstance } = instances[keyName]
24
+ const instance = instances[keyName]
22
25
 
23
26
  // Update the moving average instance.
24
- maInstance.update(value);
27
+ instance.update(value);
25
28
  let currMa = NaN;
26
29
  try {
27
- currMa = maInstance.getResult();
30
+ currMa = instance.getResult();
28
31
  } catch (err) {
29
32
 
30
33
  }
@@ -42,9 +45,7 @@ export const precomputeMovingAverages = ({main, size, target, lag, methodName})
42
45
  const keyName = `${methodName}_${size}${suffix}`
43
46
 
44
47
  // Create the main moving average instance.
45
- instances[keyName] = {
46
- maInstance: new indicatorClasses[methodName](size)
47
- }
48
+ instances[keyName] = new indicatorClasses[methodName](size)
48
49
 
49
50
  verticalOhlcv[keyName] = new Float64Array(len).fill(NaN)
50
51
 
@@ -0,0 +1,71 @@
1
+
2
+ import {FasterATR, FasterWSMA} from 'trading-signals';
3
+
4
+ export const atr = (main, index, size, {lag, tp, sl}) => {
5
+ const { verticalOhlcv, instances } = main
6
+ const keyName = `atr_${size}`
7
+
8
+ if (index === 0) {
9
+
10
+ const {instances, verticalOhlcv, arrayTypes, len, priceBased} = main
11
+
12
+ instances[keyName] = new FasterATR(size, FasterWSMA)
13
+
14
+ const keyNames = [keyName]
15
+
16
+ if(tp !== null)
17
+ {
18
+ keyNames.push(`${keyName}_tp`)
19
+ }
20
+
21
+ if(sl !== null)
22
+ {
23
+ keyNames.push(`${keyName}_sl`)
24
+ }
25
+
26
+ for(const k of keyNames)
27
+ {
28
+ priceBased.add(k)
29
+ verticalOhlcv[k] = new Float64Array(len).fill(NaN)
30
+ arrayTypes[k] = 'Float64Array'
31
+ }
32
+
33
+
34
+ if(lag > 0)
35
+ {
36
+ main.lag(keyNames, lag)
37
+ }
38
+ }
39
+
40
+ // Retrieve the current price value.
41
+ const curr = {
42
+ high: verticalOhlcv.high[index],
43
+ low: verticalOhlcv.low[index],
44
+ close: verticalOhlcv.close[index],
45
+ }
46
+ const instance = instances[keyName]
47
+
48
+ // Update the moving average instance.
49
+ instance.update(curr);
50
+ let currAtr = NaN;
51
+ try {
52
+ currAtr = instance.getResult();
53
+ } catch (err) {
54
+
55
+ }
56
+
57
+ if(tp !== null)
58
+ {
59
+ main.pushToMain({ index, key: `${keyName}_tp`, value: (!Number.isNaN(currAtr)) ? curr.close + (currAtr*tp) : NaN });
60
+ }
61
+
62
+ if(sl !== null)
63
+ {
64
+ main.pushToMain({ index, key: `${keyName}_sl`, value: (!Number.isNaN(currAtr)) ? curr.close - (currAtr*sl) : NaN });
65
+ }
66
+
67
+ // Always push the MA value (even if NaN).
68
+ main.pushToMain({ index, key: keyName, value: currAtr });
69
+
70
+ return true;
71
+ }