forked from DeviaVir/zenbot
-
Notifications
You must be signed in to change notification settings - Fork 0
/
helpers.js
111 lines (108 loc) · 4.1 KB
/
helpers.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
//Basic Usage
// let crossover = require('../../../lib/helpers').crossover,
// or
// const tv = require('../../../lib/helpers')
// ...
// s.period.hl2 = tv.hl2(s.period)
module.exports = {
crossover: function(s, key1, key2) {
return s.period[key1] > s.period[key2] && s.lookback[0][key1] <= s.lookback[0][key2]
},
crossunder: function(s, key1, key2) {
return s.period[key1] < s.period[key2] && s.lookback[0][key1] >= s.lookback[0][key2]
},
crossoverVal: function(p1val1, p1val2, p2val1, p2val2) {
return p1val1 > p1val2 && p2val1 <= p2val2
},
crossunderVal: function(p1val1, p1val2, p2val1, p2val2) {
return p1val1 < p1val2 && p2val1 >= p2val2
},
nz: function(src, val = 0) {
return typeof src != 'number' || isNaN(src) ? val : src
},
iff: function(v, r, r2) {
return v != undefined && v ? r : r2
},
hl2: function(period) {
return (period.high + period.low) / 2
},
hlc3: function(period) {
return (period.high + period.low + period.close) / 3
},
ohlc4: function(period) {
return (period.open + period.high + period.low + period.close) / 4
},
HAhlc3: function(period, lookback) {
/*
xClose = (Open+High+Low+Close)/4
xOpen = [xOpen(Previous Bar) + xClose(Previous Bar)]/2
xHigh = Max(High, xOpen, xClose)
xLow = Min(Low, xOpen, xClose)
*/
let haClose = (period.open + period.high + period.low + period.close) / 4,
haClosePeriod = lookback != undefined ? lookback : period,
haClosePrev = (haClosePeriod.open + haClosePeriod.high + haClosePeriod.low + haClosePeriod.close) / 4,
haOpen = (period.haOpen ? period.haOpen : period.open + haClosePrev) / 2,
haHigh = Math.max(period.high, haOpen, haClose),
haLow = Math.min(period.low, haOpen, haClose)
// save haOpen
period.haOpen = haOpen
return (haClose + haHigh + haLow) / 3
},
HAohlc4: function(period, lookback) {
/*
xClose = (Open+High+Low+Close)/4
xOpen = [xOpen(Previous Bar) + xClose(Previous Bar)]/2
xHigh = Max(High, xOpen, xClose)
xLow = Min(Low, xOpen, xClose)
*/
let haClose = (period.open + period.high + period.low + period.close) / 4,
haClosePeriod = lookback != undefined ? lookback : period,
haClosePrev = (haClosePeriod.open + haClosePeriod.high + haClosePeriod.low + haClosePeriod.close) / 4,
haOpen = (period.haOpen ? period.haOpen : period.open + haClosePrev) / 2,
haHigh = Math.max(period.high, haOpen, haClose),
haLow = Math.min(period.low, haOpen, haClose)
// save haOpen
period.haOpen = haOpen
return (haClose + haOpen + haHigh + haLow) / 4
},
// sample usage: let adjusted_lbks = s.lookback.map((period, i) => tv.src(period, s.options.src, s.lookback[i+1]))
src: function(src, period, lookback) {
if (!period)
throw 'helpers src(). period undefined'
if (!src || src === 'close') {
return period.close
} else if (src === 'hl2') {
return module.exports.hl2(period)
} else if (src === 'hlc3') {
return module.exports.hlc3(period)
} else if (src === 'ohlc4') {
return module.exports.ohlc4(period)
} else if (src === 'HAhlc3') {
return module.exports.HAhlc3(period, lookback)
} else if (src === 'HAohlc4') {
return module.exports.HAohlc4(period, lookback)
} else
throw src + ' not supported'
},
adjust_by_pct: function(pct, n) {
return n * (pct / 100 + 1)
},
pivot: function(s, leftBars, rightBars) {
let totalBars = leftBars + rightBars + 1,
periods = [s.period, ...s.lookback.slice(0, totalBars - 1)].reverse(),
lPeriods = periods.slice(0, leftBars),
rPeriods = periods.slice(leftBars + 1),
oPeriods = lPeriods.concat(rPeriods),
countH = oPeriods.reduce((p, c) => {
return p + (typeof c.high !== 'undefined' && periods[leftBars].high > c.high ? 1 : 0)
}, 0),
countL = oPeriods.reduce((p, c) => {
return p + (typeof c.low !== 'undefined' && periods[leftBars].low < c.low ? 1 : 0)
}, 0)
return {
high: countH == oPeriods.length ? periods[leftBars].high : null,
low: countL == oPeriods.length ? periods[leftBars].low : null
}
}
}