bbgo_origin/pkg/indicator/v2/rsi.go

63 lines
1.0 KiB
Go
Raw Permalink Normal View History

2023-07-10 08:54:22 +00:00
package indicatorv2
import (
"github.com/c9s/bbgo/pkg/types"
)
2023-05-31 05:08:40 +00:00
type RSIStream struct {
// embedded structs
2023-07-10 08:54:22 +00:00
*types.Float64Series
2023-05-31 05:08:40 +00:00
// config fields
window int
// private states
2023-07-10 08:54:22 +00:00
source types.Float64Source
2023-05-31 05:08:40 +00:00
}
2023-07-10 08:54:22 +00:00
func RSI2(source types.Float64Source, window int) *RSIStream {
2023-05-31 05:08:40 +00:00
s := &RSIStream{
2023-05-31 08:30:04 +00:00
source: source,
2023-07-10 08:54:22 +00:00
Float64Series: types.NewFloat64Series(),
2023-05-31 05:08:40 +00:00
window: window,
}
2023-06-01 00:11:30 +00:00
s.Bind(source, s)
2023-05-31 05:08:40 +00:00
return s
}
2023-06-01 00:11:30 +00:00
func (s *RSIStream) Calculate(_ float64) float64 {
2023-05-31 08:30:04 +00:00
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)
2023-05-31 08:30:04 +00:00
change := value - prev
if change >= 0 {
gainSum += change
} else {
lossSum += -change
}
}
2023-05-31 05:08:40 +00:00
2023-05-31 08:30:04 +00:00
avgGain := gainSum / float64(limit)
avgLoss := lossSum / float64(limit)
rs := avgGain / avgLoss
rsi := 100.0 - (100.0 / (1.0 + rs))
return rsi
}
2023-07-10 08:54:22 +00:00
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
}