ohlcv-indicators 1.0.3 → 1.0.7

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.0.3",
3
+ "version": "1.0.7",
4
4
  "description": "A JavaScript library featuring optimized trading indicators for OHLCV arrays [{open, high, low, close, value}], utilizing BigNumber precision for enhanced accuracy.",
5
5
  "main": "index.js",
6
6
  "type": "module",
@@ -1,45 +1,84 @@
1
- //volume profile can not be concatenated to the main class
2
-
3
- export const VolumeProfile = (BigNumber, ohlcv, numBins = 10) => {
4
-
1
+ export const VolumeProfile = (BigNumber, ohlcv, numBins = 10, position) => {
5
2
  const { open, high, low, close, volume } = ohlcv;
6
3
 
7
4
  // Determine the range of prices
8
5
  const lowPrice = BigNumber.min(...low);
9
6
  const highPrice = BigNumber.max(...high);
10
7
  const binSize = highPrice.minus(lowPrice).dividedBy(numBins);
8
+ const zero = BigNumber(0);
9
+
10
+ // Initialize totals
11
+ const totals = {
12
+ upVolume: zero,
13
+ downVolume: zero,
14
+ grossVolume: zero,
15
+ };
11
16
 
12
17
  // Initialize bins
13
18
  const bins = Array.from({ length: numBins }, (_, i) => ({
14
19
  price: lowPrice.plus(binSize.multipliedBy(i)),
15
- upVolume: new BigNumber(0),
16
- downVolume: new BigNumber(0)
20
+ upVolume: zero,
21
+ downVolume: zero,
22
+ grossVolume: zero,
17
23
  }));
18
24
 
19
25
  // Precompute binSize inversely to use multiplication instead of division in the loop
20
- const inverseBinSize = new BigNumber(1).dividedBy(binSize);
26
+ const inverseBinSize = BigNumber(1).dividedBy(binSize);
21
27
 
22
28
  // Distribute volume into bins
23
- const numDataPoints = close.length;
24
- for (let i = 0; i < numDataPoints; i++) {
29
+ for (let i = 0; i < close.length; i++) {
30
+ const currentClose = close[i];
25
31
  const currentOpen = open[i];
26
32
  const currentHigh = high[i];
27
33
  const currentLow = low[i];
28
- const currentClose = close[i];
29
34
  const currentVolume = volume[i];
30
35
 
31
- const upVolume = currentClose.isGreaterThanOrEqualTo(currentOpen) ? currentVolume : new BigNumber(0);
32
- const downVolume = currentClose.isLessThan(currentOpen) ? currentVolume : new BigNumber(0);
36
+ const upVolume = currentClose.isGreaterThanOrEqualTo(currentOpen) ? currentVolume : zero;
37
+ const downVolume = currentClose.isLessThan(currentOpen) ? currentVolume : zero;
33
38
 
34
- const lowIndex = currentLow.minus(lowPrice).multipliedBy(inverseBinSize).integerValue(BigNumber.ROUND_FLOOR).toNumber();
35
- const highIndex = currentHigh.minus(lowPrice).multipliedBy(inverseBinSize).integerValue(BigNumber.ROUND_CEIL).toNumber();
39
+ const lowIndex = Math.max(0, currentLow.minus(lowPrice).multipliedBy(inverseBinSize).integerValue(BigNumber.ROUND_FLOOR).toNumber());
40
+ const highIndex = Math.min(numBins, currentHigh.minus(lowPrice).multipliedBy(inverseBinSize).integerValue(BigNumber.ROUND_CEIL).toNumber());
36
41
 
37
- for (let j = Math.max(lowIndex, 0); j < Math.min(highIndex, numBins); j++) {
42
+ for (let j = lowIndex; j < highIndex; j++) {
38
43
  bins[j].upVolume = bins[j].upVolume.plus(upVolume);
39
44
  bins[j].downVolume = bins[j].downVolume.plus(downVolume);
45
+ bins[j].grossVolume = bins[j].grossVolume.plus(upVolume.plus(downVolume));
40
46
  }
41
47
  }
42
48
 
43
- return bins
49
+ // Sum totals outside the loop
50
+ for (const { upVolume, downVolume, grossVolume } of bins) {
51
+ totals.upVolume = totals.upVolume.plus(upVolume);
52
+ totals.downVolume = totals.downVolume.plus(downVolume);
53
+ totals.grossVolume = totals.grossVolume.plus(grossVolume);
54
+ }
55
+
56
+
57
+ const nodes = findVolumeNodes(bins)
58
+ return {bins, nodes};
59
+ }
60
+
44
61
 
62
+ const findVolumeNodes = bins => {
63
+ if (!bins || bins.length === 0) {
64
+ throw new Error('Bins array is empty or not provided');
65
+ }
66
+
67
+ let highestVolumeNode = bins[0];
68
+ let lowestVolumeNode = bins[0];
69
+
70
+ bins.forEach(bin => {
71
+ if (bin.grossVolume.isGreaterThan(highestVolumeNode.grossVolume)) {
72
+ highestVolumeNode = bin;
73
+ }
74
+
75
+ if (bin.grossVolume.isLessThan(lowestVolumeNode.grossVolume)) {
76
+ lowestVolumeNode = bin;
77
+ }
78
+ });
79
+
80
+ return {
81
+ highestVolumeNode,
82
+ lowestVolumeNode
83
+ }
45
84
  }
package/test/test.js CHANGED
@@ -24,7 +24,7 @@ const TEST = async () => {
24
24
  //.crossPairs([{fast: 'ema_9', slow: 'ema_21'}, {fast: 'close', slow: 'sma_200'}, {fast: 'rsi_14', slow: 30}])
25
25
 
26
26
  const dataSet = indicators.getData()
27
- const vp = VolumeProfile(BigNumber, dataSet)
27
+ const vp = VolumeProfile(BigNumber, dataSet, 5)
28
28
 
29
29
  console.log(vp)
30
30