-
-
Notifications
You must be signed in to change notification settings - Fork 278
/
rsi.go
62 lines (53 loc) · 1.03 KB
/
rsi.go
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
package indicatorv2
import (
"github.com/c9s/bbgo/pkg/types"
)
type RSIStream struct {
// embedded structs
*types.Float64Series
// config fields
window int
// private states
source types.Float64Source
}
func RSI2(source types.Float64Source, window int) *RSIStream {
s := &RSIStream{
source: source,
Float64Series: types.NewFloat64Series(),
window: window,
}
s.Bind(source, s)
return s
}
func (s *RSIStream) Calculate(_ float64) float64 {
var gainSum, lossSum float64
var sourceLen = s.source.Length()
var limit = min(s.window, sourceLen)
for i := 0; i < limit; i++ {
value := s.source.Last(i)
prev := s.source.Last(i + 1)
change := value - prev
if change >= 0 {
gainSum += change
} else {
lossSum += -change
}
}
avgGain := gainSum / float64(limit)
avgLoss := lossSum / float64(limit)
rs := avgGain / avgLoss
rsi := 100.0 - (100.0 / (1.0 + rs))
return rsi
}
func max(x, y int) int {
if x > y {
return x
}
return y
}
func min(x, y int) int {
if x < y {
return x
}
return y
}