ohlcv-indicators 1.8.7 → 1.8.8

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ohlcv-indicators",
3
- "version": "1.8.7",
3
+ "version": "1.8.8",
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",
@@ -0,0 +1,40 @@
1
+
2
+
3
+ export const vwap = (main) => {
4
+ const { verticalOhlcv } = main;
5
+
6
+ const vwapValues = calculateVWAP(verticalOhlcv);
7
+
8
+ return {
9
+ [`vwap`]: vwapValues,
10
+ };
11
+ };
12
+
13
+ const calculateVWAP = data => {
14
+ const { high, low, close, volume } = data;
15
+ const output = new Array(close.length).fill(null)
16
+
17
+ // Cumulative sums for VWAP calculation
18
+ let cumulativePriceVolume = 0;
19
+ let cumulativeVolume = 0;
20
+
21
+ for (let x = 0; x < close.length; x++) {
22
+
23
+ const typicalPrice = (high[x] + low[x] + close[x]) / 3;
24
+
25
+ // Calculate Price * Volume for this interval
26
+ const priceVolume = typicalPrice * volume[x];
27
+
28
+ // Update cumulative sums
29
+ cumulativePriceVolume += priceVolume;
30
+ cumulativeVolume += volume[x];
31
+
32
+ // Calculate VWAP for this interval
33
+ const vwap = cumulativePriceVolume / cumulativeVolume;
34
+
35
+ // Push the VWAP value into the array
36
+ output[x] = vwap
37
+ }
38
+
39
+ return output
40
+ }
@@ -19,8 +19,10 @@ const getCandlesStudies = (inputOhlcv, period = 20, len, classify = true, classi
19
19
  let candle_bottom_size = new Array(len).fill(null) //scaled bottom size(0, 0.5 and 1)
20
20
  let candle_gap_size = new Array(len).fill(null) //scaled gap between the current open and previous close (-1 to 1)
21
21
  let candle_shadow_size = new Array(len).fill(null) //scaled shadow size high - slow
22
- let candle_position = new Array(len).fill(null) //scaled shadow size curr.close - prev.close
23
-
22
+ let candle_close_position = new Array(len).fill(null) //scaled shadow size curr.close - prev.close
23
+ let candle_high_position = new Array(len).fill(null) //scaled shadow size curr.high - prev.high
24
+ let candle_low_position = new Array(len).fill(null) //scaled shadow size curr.low - prev.low
25
+ let candle_open_position = new Array(len).fill(null) //scaled shadow size curr.open - prev.open
24
26
 
25
27
  //instances
26
28
  let topInstance
@@ -28,7 +30,10 @@ const getCandlesStudies = (inputOhlcv, period = 20, len, classify = true, classi
28
30
  let gapInstance
29
31
  let bodySizeInstance
30
32
  let shadowSizeInstance
31
- let positionInstance
33
+ let closePositionInstance
34
+ let highPositionInstance
35
+ let lowPositionInstance
36
+ let openPositionInstance
32
37
 
33
38
  if(classify)
34
39
  {
@@ -37,7 +42,10 @@ const getCandlesStudies = (inputOhlcv, period = 20, len, classify = true, classi
37
42
  gapInstance = new FasterSMA(period)
38
43
  bodySizeInstance = new FasterSMA(period)
39
44
  shadowSizeInstance = new FasterSMA(period)
40
- positionInstance = new FasterSMA(period)
45
+ closePositionInstance = new FasterSMA(period)
46
+ highPositionInstance = new FasterSMA(period)
47
+ lowPositionInstance = new FasterSMA(period)
48
+ openPositionInstance = new FasterSMA(period)
41
49
  }
42
50
 
43
51
  for(let x = 0; x < len; x++)
@@ -45,10 +53,7 @@ const getCandlesStudies = (inputOhlcv, period = 20, len, classify = true, classi
45
53
  const curr = inputOhlcv[x]
46
54
  const prev = inputOhlcv[x-1]
47
55
 
48
- if(typeof prev === 'undefined')
49
- {
50
- continue
51
- }
56
+ if(typeof prev === 'undefined') continue
52
57
 
53
58
  const {open, high, low, close} = curr
54
59
 
@@ -59,7 +64,10 @@ const getCandlesStudies = (inputOhlcv, period = 20, len, classify = true, classi
59
64
  let topSizeMean = null
60
65
  let bodySizeMean = null
61
66
  let shadowSizeMean = null
62
- let positionMean = null
67
+ let closePositionMean = null
68
+ let highPositionMean = null
69
+ let lowPositionMean = null
70
+ let openPositionMean = null
63
71
 
64
72
  //directions
65
73
  const isUp = close > open
@@ -70,7 +78,10 @@ const getCandlesStudies = (inputOhlcv, period = 20, len, classify = true, classi
70
78
  const topSize = high - Math.max(open, close)
71
79
  const bottomSize = Math.min(open, close) - low
72
80
  const gapSize = Math.abs(prev.close - curr.open)
73
- const position = Math.abs(curr.close - prev.close)
81
+ const closePosition = Math.abs(curr.close - prev.close)
82
+ const highPosition = Math.abs(curr.high - prev.high)
83
+ const lowPosition = Math.abs(curr.low - prev.low)
84
+ const openPosition = Math.abs(curr.open - prev.open)
74
85
 
75
86
  if(classify)
76
87
  {
@@ -81,8 +92,10 @@ const getCandlesStudies = (inputOhlcv, period = 20, len, classify = true, classi
81
92
 
82
93
  gapInstance.update(gapSize)
83
94
  bodySizeInstance.update(candleBodySize)
84
- positionInstance.update(position)
85
-
95
+ closePositionInstance.update(closePosition)
96
+ highPositionInstance.update(highPosition)
97
+ lowPositionInstance.update(lowPosition)
98
+ openPositionInstance.update(openPosition)
86
99
 
87
100
  try
88
101
  {
@@ -91,7 +104,10 @@ const getCandlesStudies = (inputOhlcv, period = 20, len, classify = true, classi
91
104
  gapMean = gapInstance.getResult()
92
105
  bodySizeMean = bodySizeInstance.getResult()
93
106
  shadowSizeMean = shadowSizeInstance.getResult()
94
- positionMean = positionInstance.getResult()
107
+ closePositionMean = closePositionInstance.getResult()
108
+ highPositionMean = highPositionInstance.getResult()
109
+ lowPositionMean = lowPositionInstance.getResult()
110
+ openPositionMean = openPositionInstance.getResult()
95
111
  }
96
112
  catch(err)
97
113
  {
@@ -100,7 +116,10 @@ const getCandlesStudies = (inputOhlcv, period = 20, len, classify = true, classi
100
116
  topSizeMean = null
101
117
  bottomSizeMean = null
102
118
  shadowSizeMean = null
103
- positionMean = null
119
+ closePositionMean = null
120
+ highPositionMean = null
121
+ lowPositionMean = null
122
+ openPositionMean = null
104
123
  }
105
124
 
106
125
  //negatives and positives
@@ -112,9 +131,23 @@ const getCandlesStudies = (inputOhlcv, period = 20, len, classify = true, classi
112
131
  ? classifySize(gapSize, gapMean, 2, changeLevel)
113
132
  : -Math.abs(classifySize(gapSize, gapMean, 2, changeLevel)) || 0;
114
133
 
115
- candle_position[x] = (isUp)
116
- ? classifySize(position, positionMean, 2, changeLevel)
117
- : -Math.abs(classifySize(position, positionMean, 2, changeLevel)) || 0;
134
+ candle_close_position[x] = (isUp)
135
+ ? classifySize(closePosition, closePositionMean, 2, changeLevel)
136
+ : -Math.abs(classifySize(closePosition, closePositionMean, 2, changeLevel)) || 0;
137
+
138
+ candle_high_position[x] = (isUp)
139
+ ? classifySize(highPosition, highPositionMean, 2, changeLevel)
140
+ : -Math.abs(classifySize(highPosition, highPositionMean, 2, changeLevel)) || 0;
141
+
142
+
143
+ candle_low_position[x] = (isUp)
144
+ ? classifySize(lowPosition, lowPositionMean, 2, changeLevel)
145
+ : -Math.abs(classifySize(lowPosition, lowPositionMean, 2, changeLevel)) || 0;
146
+
147
+ candle_open_position[x] = (isUp)
148
+ ? classifySize(openPosition, openPositionMean, 2, changeLevel)
149
+ : -Math.abs(classifySize(openPosition, openPositionMean, 2, changeLevel)) || 0;
150
+
118
151
 
119
152
  //positives only
120
153
  candle_top_size[x] = classifySize(topSize, topSizeMean, 0.5, sizeLevel)
@@ -125,7 +158,9 @@ const getCandlesStudies = (inputOhlcv, period = 20, len, classify = true, classi
125
158
  //negatives and positives
126
159
  candle_body_size[x] = candleBodySize
127
160
  candle_gap_size[x] = gapSize
128
- candle_position[x] = position
161
+ candle_close_position[x] = closePosition
162
+ candle_high_position[x] = highPosition
163
+ candle_low_position[x] = lowPosition
129
164
 
130
165
  //positives only
131
166
  candle_top_size[x] = topSize
@@ -141,6 +176,9 @@ const getCandlesStudies = (inputOhlcv, period = 20, len, classify = true, classi
141
176
  candle_top_size,
142
177
  candle_bottom_size,
143
178
  candle_shadow_size,
144
- candle_position
179
+ candle_close_position,
180
+ candle_high_position,
181
+ candle_low_position,
182
+ candle_open_position
145
183
  }
146
184
  }
@@ -0,0 +1,64 @@
1
+ //change between current and prev
2
+ export const arrayChange = data => {
3
+
4
+ if(!Array.isArray(data))
5
+ {
6
+ throw Error('data param in arrayGt function must be array')
7
+ }
8
+
9
+ const output = Array(data.length).fill(0)
10
+
11
+ for (let x = 1; x < output.length; x++) {
12
+
13
+ if(data[x] === null || data[x - 1] === null)
14
+ {
15
+ output[x] === null
16
+ }
17
+ else
18
+ {
19
+ const curr = data[x]
20
+ const prev = data[x - 1]
21
+ output[x] = ((curr - prev) / prev) * 100
22
+ }
23
+ }
24
+
25
+ return output
26
+ }
27
+
28
+ //tells if array a is greater than array b
29
+
30
+ export const arrayGt = (a, b) => {
31
+
32
+ if(!Array.isArray(a) || !Array.isArray(b))
33
+ {
34
+ throw Error('a and b params in arrayGt function must be arrays')
35
+ }
36
+ if(a.length !== b.length)
37
+ {
38
+ throw Error('array a and b must be the same length in arrayGt function')
39
+ }
40
+ if(a.length < 2)
41
+ {
42
+ throw Error('arrays in arrayGt function must have at least 2 numeric items')
43
+ }
44
+
45
+ const output = Array(a.length).fill(0.5)
46
+
47
+ for (let x = 1; x < output.length; x++) {
48
+
49
+ if(a[x] === null || b[x] === null)
50
+ {
51
+ output[x] = null
52
+ }
53
+ if(a[x] > b[x])
54
+ {
55
+ output[x] = 1
56
+ }
57
+ else if(a[x] < b[x])
58
+ {
59
+ output[x] = 0
60
+ }
61
+ }
62
+
63
+ return output
64
+ }