ohlcv-indicators 3.2.6 → 3.2.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/dist/ohlcv-indicators.min.js +273 -263
- package/index.js +3 -3
- package/package.json +1 -1
- package/src/studies/candleVectors.js +46 -36
- package/src/utilities/pushToMain.js +8 -6
package/index.js
CHANGED
|
@@ -431,7 +431,7 @@ export default class OHLCV_INDICATORS {
|
|
|
431
431
|
throw new Error('"size" must be a positive number greater than 0 in candleVectors.');
|
|
432
432
|
}
|
|
433
433
|
|
|
434
|
-
const { stdDev = 1, lag = 0, scale = 0.
|
|
434
|
+
const { stdDev = 1, lag = 0, scale = 0.001, patternSize = 0, autoMinMax = false } = options;
|
|
435
435
|
|
|
436
436
|
|
|
437
437
|
if (typeof stdDev !== 'number' || stdDev <= 0) {
|
|
@@ -443,9 +443,9 @@ export default class OHLCV_INDICATORS {
|
|
|
443
443
|
throw new Error(`"scale" value in candleVectors must be any of the following numbers: ${validMagnitudeValues.join(', ')}`);
|
|
444
444
|
}
|
|
445
445
|
|
|
446
|
-
if (typeof patternSize !== 'number' || !Number.isInteger(patternSize) || patternSize <
|
|
446
|
+
if (typeof patternSize !== 'number' || !Number.isInteger(patternSize) || patternSize < 0 ) {
|
|
447
447
|
|
|
448
|
-
throw new Error(`"patternSize" value in candleVectors must be
|
|
448
|
+
throw new Error(`"patternSize" value in candleVectors must be a positive integer.`);
|
|
449
449
|
}
|
|
450
450
|
if (typeof autoMinMax !== 'boolean') {
|
|
451
451
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "ohlcv-indicators",
|
|
3
|
-
"version": "3.2.
|
|
3
|
+
"version": "3.2.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",
|
|
@@ -1,16 +1,8 @@
|
|
|
1
|
-
|
|
2
|
-
import { classifyBoll } from '../utilities/classification.js'
|
|
1
|
+
const diff = (a, b) => (a - b)
|
|
3
2
|
|
|
4
|
-
const
|
|
5
|
-
|
|
6
|
-
// crear una nueva instancia con la altura porcentual utilizando Bollinger Bands con una desviación estándar de 1.5
|
|
7
|
-
// Las diferencias estarán basadas en (objetivo - lower) / (upper - lower). Esto arrojará un valor entre -1 y 1
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
export const candleVectors = (main, index, size, {stdDev, patternSize, lag, scale, autoMinMax}) => {
|
|
3
|
+
export const candleVectors = (main, index, size, {patternSize, lag, autoMinMax}) => {
|
|
11
4
|
|
|
12
5
|
const { verticalOhlcv, instances, lastIndexReplace } = main
|
|
13
|
-
const calcSize = (di, bo) => classifyBoll(di, bo, scale, autoMinMax)
|
|
14
6
|
|
|
15
7
|
if(index === 0)
|
|
16
8
|
{
|
|
@@ -74,7 +66,7 @@ export const candleVectors = (main, index, size, {stdDev, patternSize, lag, scal
|
|
|
74
66
|
bodyVectors,
|
|
75
67
|
lookBackVectors,
|
|
76
68
|
keyNames,
|
|
77
|
-
|
|
69
|
+
arrayChunk: {...Object.fromEntries(keyNames.map(v => [v, []]))}
|
|
78
70
|
}
|
|
79
71
|
})
|
|
80
72
|
|
|
@@ -85,33 +77,19 @@ export const candleVectors = (main, index, size, {stdDev, patternSize, lag, scal
|
|
|
85
77
|
|
|
86
78
|
}
|
|
87
79
|
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
const {bodyVectors, lookBackVectors, bodyInstance} = instances.candleVectors
|
|
92
|
-
|
|
93
|
-
let bodyBoll = null
|
|
94
|
-
const currOpen = verticalOhlcv.open[index]
|
|
95
|
-
const currClose = verticalOhlcv.close[index]
|
|
96
|
-
const bodySize = diff(currClose, currOpen)
|
|
97
|
-
|
|
98
|
-
// Update instances with current absolute values
|
|
99
|
-
bodyInstance.update(Math.abs(bodySize), lastIndexReplace)
|
|
100
|
-
|
|
101
|
-
try {
|
|
102
|
-
bodyBoll = bodyInstance.getResult()
|
|
103
|
-
} catch (err) {
|
|
104
|
-
// If there's not enough data, means remain null
|
|
105
|
-
}
|
|
106
|
-
|
|
80
|
+
const {bodyVectors, lookBackVectors, arrayChunk} = instances.candleVectors
|
|
107
81
|
|
|
108
82
|
for(let x = 0; x < bodyVectors.length; x++)
|
|
109
83
|
{
|
|
110
84
|
const [k2, k1] = bodyVectors[x]
|
|
111
85
|
const v2 = verticalOhlcv[k2][index]
|
|
112
86
|
const v1 = verticalOhlcv[k1][index]
|
|
87
|
+
const key = `candle_body_${k2}_${k1}`
|
|
88
|
+
const difference = diff(v2, v1)
|
|
113
89
|
|
|
114
|
-
|
|
90
|
+
const zScore = calcZScore(arrayChunk, key, size, difference, lastIndexReplace)
|
|
91
|
+
|
|
92
|
+
main.pushToMain({index, key, value: zScore})
|
|
115
93
|
}
|
|
116
94
|
|
|
117
95
|
for(let x = 0; x < patternSize; x++)
|
|
@@ -120,12 +98,18 @@ export const candleVectors = (main, index, size, {stdDev, patternSize, lag, scal
|
|
|
120
98
|
{
|
|
121
99
|
const currV = verticalOhlcv[currK][index]
|
|
122
100
|
const prevV = verticalOhlcv[prevK][index-(x+1)]
|
|
101
|
+
const key = `candle_change_${x+1}_${currK}_${prevK}`
|
|
102
|
+
|
|
103
|
+
if(typeof prevV === 'undefined')
|
|
104
|
+
{
|
|
105
|
+
main.pushToMain({index, key, value: null})
|
|
106
|
+
continue
|
|
107
|
+
}
|
|
123
108
|
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
})
|
|
109
|
+
const difference = diff(currV, prevV)
|
|
110
|
+
const zScore = calcZScore(arrayChunk, key, size, difference, lastIndexReplace)
|
|
111
|
+
|
|
112
|
+
main.pushToMain({index, key, value: zScore})
|
|
129
113
|
}
|
|
130
114
|
}
|
|
131
115
|
|
|
@@ -133,3 +117,29 @@ export const candleVectors = (main, index, size, {stdDev, patternSize, lag, scal
|
|
|
133
117
|
}
|
|
134
118
|
|
|
135
119
|
|
|
120
|
+
const calcZScore = (arrayChunk, key, size, difference, lastIndexReplace) => {
|
|
121
|
+
|
|
122
|
+
if(lastIndexReplace)
|
|
123
|
+
{
|
|
124
|
+
arrayChunk[key][arrayChunk[key].length - 1] = difference
|
|
125
|
+
}
|
|
126
|
+
else
|
|
127
|
+
{
|
|
128
|
+
arrayChunk[key].push(difference)
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
|
|
132
|
+
if (arrayChunk[key].length > size) {
|
|
133
|
+
arrayChunk[key].shift(); // Removes the first element to maintain array size
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
if(arrayChunk.length < size) return null
|
|
137
|
+
|
|
138
|
+
const mean = arrayChunk[key].reduce((sum, value) => sum + value, 0) / size
|
|
139
|
+
|
|
140
|
+
const stdDev = Math.sqrt(
|
|
141
|
+
arrayChunk[key].reduce((sum, value) => sum + (value - mean) ** 2, 0) / size
|
|
142
|
+
)
|
|
143
|
+
|
|
144
|
+
return (difference - mean) / stdDev
|
|
145
|
+
}
|
|
@@ -1,19 +1,21 @@
|
|
|
1
1
|
export const pushToMain = ({main, index, key, value}) => {
|
|
2
2
|
|
|
3
3
|
const {precision, priceBased, minMaxRanges, verticalOhlcv, autoMinMaxKeys, precisionMultiplier} = main
|
|
4
|
-
let {invalidValueIndex } = main
|
|
5
4
|
|
|
6
5
|
if(value === null || typeof value === 'undefined')
|
|
7
6
|
{
|
|
8
|
-
invalidValueIndex = index
|
|
7
|
+
main.invalidValueIndex = index //do not use let for main.invalidValueIndex
|
|
9
8
|
|
|
10
|
-
for(
|
|
9
|
+
for(const k of Object.keys(minMaxRanges))
|
|
11
10
|
{
|
|
12
11
|
minMaxRanges[k] = {min: Infinity, max: -Infinity}
|
|
13
12
|
}
|
|
13
|
+
|
|
14
|
+
verticalOhlcv[key][index] = null
|
|
15
|
+
return false
|
|
14
16
|
}
|
|
15
|
-
|
|
16
|
-
verticalOhlcv[key][index] = value
|
|
17
|
+
|
|
18
|
+
verticalOhlcv[key][index] = value
|
|
17
19
|
|
|
18
20
|
if(typeof value === 'number' && !key.includes('_x_'))
|
|
19
21
|
{
|
|
@@ -28,7 +30,7 @@ export const pushToMain = ({main, index, key, value}) => {
|
|
|
28
30
|
}
|
|
29
31
|
else if(key.startsWith('candle_') && keyInAutoMinMax)
|
|
30
32
|
{
|
|
31
|
-
minMaxRanges[key] = { min: -
|
|
33
|
+
minMaxRanges[key] = { min: -3, max: 3}
|
|
32
34
|
}
|
|
33
35
|
else if(key.includes('_range_') && keyInAutoMinMax)
|
|
34
36
|
{
|