ohlcv-indicators 1.8.3 → 1.8.5

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
@@ -192,10 +192,10 @@ export default class OHLCV_INDICATORS {
192
192
  return this
193
193
 
194
194
  }
195
- bollingerBands(size, times)
195
+ bollingerBands(size, times, bollingerBandsStudies)
196
196
  {
197
197
 
198
- const result = bollingerBands(this, size, times)
198
+ const result = bollingerBands(this, size, times, bollingerBandsStudies)
199
199
  Object.assign(this.indicators, result)
200
200
 
201
201
  this.priceBased.push('bollinger_bands_middle', 'bollinger_bands_upper', 'bollinger_bands_lower')
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ohlcv-indicators",
3
- "version": "1.8.3",
3
+ "version": "1.8.5",
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",
@@ -2,30 +2,36 @@
2
2
  import {FasterBollingerBands, FasterSMA} from 'trading-signals';
3
3
  import { classifySize } from '../utilities/classification.js';
4
4
 
5
- export const bollingerBands = (main, size, times) => {
5
+ export const bollingerBands = (main, size, times, bollingerBandsStudies) => {
6
6
 
7
7
  const {verticalOhlcv} = main
8
8
  const {close} = verticalOhlcv
9
9
 
10
- const col = getBollingerBands(close, size, times)
10
+ const col = getBollingerBands(close, size, times, bollingerBandsStudies)
11
11
  return col
12
12
  }
13
13
 
14
- export const getBollingerBands = (data, size = 20, times = 2) => {
14
+ export const getBollingerBands = (data, size = 20, times = 2, bollingerBandsStudies = false) => {
15
15
 
16
16
  const dataLength = data.length
17
17
  const bollinger_bands_upper = Array(dataLength).fill(null)
18
18
  const bollinger_bands_middle = Array(dataLength).fill(null)
19
19
  const bollinger_bands_lower = Array(dataLength).fill(null)
20
- const bollinger_bands_range = Array(dataLength).fill(null)
21
- const bollinger_bands_height = Array(dataLength).fill(null)
22
20
 
23
21
 
24
- const heightInstance = new FasterSMA(size)
25
-
22
+ let bollinger_bands_range
23
+ let bollinger_bands_height
24
+ let heightInstance
26
25
  let range = null
27
26
  let height = null
28
27
 
28
+ if(bollingerBandsStudies)
29
+ {
30
+ bollinger_bands_range = Array(dataLength).fill(null)
31
+ bollinger_bands_height = Array(dataLength).fill(null)
32
+ heightInstance = new FasterSMA(size)
33
+ }
34
+
29
35
  let getRange = (value, upper, lower) => ({
30
36
  range: ((value - lower) / (upper - lower)),
31
37
  height: upper-lower
@@ -52,6 +58,8 @@ export const getBollingerBands = (data, size = 20, times = 2) => {
52
58
  bollinger_bands_middle[x] = obj.middle;
53
59
  bollinger_bands_lower[x] = obj.lower;
54
60
 
61
+ if(bollingerBandsStudies === false) continue
62
+
55
63
  if(hasNull)
56
64
  {
57
65
  bollinger_bands_range[x] = null
@@ -79,6 +87,13 @@ export const getBollingerBands = (data, size = 20, times = 2) => {
79
87
  bollinger_bands_height[x] = classifySize(height, heightMean, 1.5)
80
88
  }
81
89
 
82
- return { bollinger_bands_upper, bollinger_bands_middle, bollinger_bands_lower, bollinger_bands_range, bollinger_bands_height }
90
+ let output = { bollinger_bands_upper, bollinger_bands_middle, bollinger_bands_lower }
91
+
92
+ if(bollingerBandsStudies)
93
+ {
94
+ output = {...output, bollinger_bands_range, bollinger_bands_height}
95
+ }
96
+
97
+ return output
83
98
  }
84
99
 
@@ -1,16 +1,18 @@
1
1
  import {FasterSMA} from 'trading-signals'
2
2
  import { classifyChange, classifySize } from '../utilities/classification.js'
3
3
 
4
- export const candlesStudies = (main, period, classify) => {
4
+ export const candlesStudies = (main, period, classify, classificationLevels) => {
5
5
 
6
6
  const {inputOhlcv, len} = main
7
7
 
8
- const cols = getCandlesStudies(inputOhlcv, period, len, classify)
8
+ const cols = getCandlesStudies(inputOhlcv, period, len, classify, classificationLevels)
9
9
  return cols
10
10
  }
11
11
 
12
- const getCandlesStudies = (inputOhlcv, period = 20, len, classify = true) => {
12
+ const getCandlesStudies = (inputOhlcv, period = 20, len, classify = true, classificationLevels = {}) => {
13
13
 
14
+ const {changeLevel = 7, sizeLevel = 5} = classificationLevels
15
+
14
16
  //close > open
15
17
  let candle_body_size = new Array(len).fill(null) //scaled candle direction close - open
16
18
  let candle_top_size = new Array(len).fill(null) //scaled top size (0, 0.5 and 1)
@@ -64,8 +66,8 @@ const getCandlesStudies = (inputOhlcv, period = 20, len, classify = true) => {
64
66
  const shadowSize = curr.high - curr.low
65
67
 
66
68
  //sizes
67
- const topSize = (candleBodySize > 0) ? high - close : high - open
68
- const bottomSize = (candleBodySize > 0) ? open - low : close - low
69
+ const topSize = high - Math.max(open, close)
70
+ const bottomSize = Math.min(open, close) - low
69
71
  const gapSize = prev.close - curr.open
70
72
  const position = curr.close - prev.close
71
73
 
@@ -101,14 +103,14 @@ const getCandlesStudies = (inputOhlcv, period = 20, len, classify = true) => {
101
103
  }
102
104
 
103
105
  //negatives and positives
104
- candle_body_size[x] = classifyChange(candleBodySize, bodySizeMean, 0.5)
105
- candle_gap_size[x] = classifyChange(gapSize, gapMean, 0.5)
106
- candle_position[x] = classifyChange(position, positionMean, 0.5)
106
+ candle_body_size[x] = classifyChange(candleBodySize, bodySizeMean, 0.5, changeLevel)
107
+ candle_gap_size[x] = classifyChange(gapSize, gapMean, 0.5, changeLevel)
108
+ candle_position[x] = classifyChange(position, positionMean, 0.5, changeLevel)
107
109
 
108
110
  //positives only
109
- candle_top_size[x] = classifySize(topSize, topSizeMean, 0.5)
110
- candle_bottom_size[x] = classifySize(bottomSize, bottomSizeMean, 0.5)
111
- candle_shadow_size[x] = classifySize(shadowSize, shadowSizeMean, 0.5)
111
+ candle_top_size[x] = classifySize(topSize, topSizeMean, 0.5, sizeLevel)
112
+ candle_bottom_size[x] = classifySize(bottomSize, bottomSizeMean, 0.5, sizeLevel)
113
+ candle_shadow_size[x] = classifySize(shadowSize, shadowSizeMean, 0.5, sizeLevel)
112
114
  }
113
115
  else{
114
116
  //negatives and positives
@@ -202,7 +202,7 @@ export const crossPairs = (main, arr) => {
202
202
  }
203
203
 
204
204
  } else {
205
- console.log(`Missing ohlcv properties for ${fast} or ${slow}`);
205
+ throw Error(`Missing ohlcv properties for ${fast} or ${slow}`);
206
206
  }
207
207
  }
208
208
 
@@ -1,49 +1,44 @@
1
+ export const classifySize = (value, mean, standardDeviation = 1.5, numLevels = 5) => {
2
+ if (value === null || mean === null || standardDeviation === null) return null
3
+ if (numLevels < 2) throw new Error("numLevels must be at least 2")
1
4
 
2
- export const classifySize = (value, mean, standardDeviation = 1.5) => {
5
+ // Calculate the range for each level
6
+ const step = (4 * standardDeviation) / (numLevels - 1)
7
+ const thresholds = []
8
+
9
+ for (let i = 0; i < numLevels - 1; i++) {
10
+ thresholds.push(mean - (2 * standardDeviation) + (i * step))
11
+ }
12
+
13
+ // Classify the value based on calculated thresholds
14
+ for (let i = thresholds.length - 1; i >= 0; i--) {
15
+ if (value > thresholds[i]) {
16
+ return (i + 1) / (numLevels - 1)
17
+ }
18
+ }
19
+
20
+ return 0
21
+ }
22
+
23
+
24
+ export const classifyChange = (value, mean, standardDeviation = 0.5, numLevels = 7) => {
3
25
  if (value === null || mean === null || standardDeviation === null) return null;
26
+ if (numLevels < 2) throw new Error("numLevels must be at least 2");
4
27
 
5
- const largeThreshold = mean + (2 * standardDeviation); // Large (2σ above mean)
6
- const mediumThreshold = mean + (1 * standardDeviation); // Medium (1σ above mean)
7
- const smallThreshold = mean - (1 * standardDeviation); // Small (1σ below mean)
8
- const verySmallThreshold = mean - (1.5 * standardDeviation); // Very small (1.5σ below mean)
28
+ // Calculate the range for each level
29
+ const step = (4 * standardDeviation) / (numLevels - 1);
30
+ const thresholds = [];
9
31
 
10
- if (value > largeThreshold) {
11
- return 1; // Large
12
- } else if (value > mediumThreshold) {
13
- return 0.75; // Medium
14
- } else if (value > smallThreshold) {
15
- return 0.5; // Small
16
- } else if (value > verySmallThreshold) {
17
- return 0.25; // Very small
18
- } else {
19
- return 0; // Insignificant
32
+ for (let i = 0; i < numLevels - 1; i++) {
33
+ thresholds.push(mean - (2 * standardDeviation) + (i * step));
20
34
  }
21
- };
22
35
 
23
-
24
- export const classifyChange = (value, mean, standardDeviation = 0.5) => {
25
- if (value === null || mean === null || standardDeviation === null) return null;
26
-
27
- const largePositiveThreshold = mean + (2 * standardDeviation); // Large positive
28
- const mediumPositiveThreshold = mean + (1.5 * standardDeviation); // Medium positive (1.5σ)
29
- const smallPositiveThreshold = mean + (0.5 * standardDeviation); // Small positive (0.5σ)
30
- const smallNegativeThreshold = mean - (0.5 * standardDeviation); // Small negative (-0.5σ)
31
- const mediumNegativeThreshold = mean - (1.5 * standardDeviation); // Medium negative (-1.5σ)
32
- const largeNegativeThreshold = mean - (2 * standardDeviation); // Large negative
33
-
34
- if (value >= largePositiveThreshold) {
35
- return 1; // Large positive
36
- } else if (value >= mediumPositiveThreshold) {
37
- return 0.5; // Medium positive
38
- } else if (value >= smallPositiveThreshold) {
39
- return 0.25; // Small positive
40
- } else if (value <= largeNegativeThreshold) {
41
- return -1; // Large negative
42
- } else if (value <= mediumNegativeThreshold) {
43
- return -0.5; // Medium negative
44
- } else if (value <= smallNegativeThreshold) {
45
- return -0.25; // Small negative
46
- } else {
47
- return 0; // No significant change
36
+ // Classify the value based on calculated thresholds
37
+ for (let i = thresholds.length - 1; i >= 0; i--) {
38
+ if (value > thresholds[i]) {
39
+ return (i - Math.floor((numLevels - 1) / 2)) / Math.floor((numLevels - 1) / 2);
40
+ }
48
41
  }
42
+
43
+ return -1;
49
44
  };