2023-06-09 10:36:54 +00:00
|
|
|
package indicator
|
|
|
|
|
2023-06-09 10:38:12 +00:00
|
|
|
type BOLLStream struct {
|
2023-06-09 10:36:54 +00:00
|
|
|
// the band series
|
|
|
|
*Float64Series
|
|
|
|
|
|
|
|
UpBand, DownBand *Float64Series
|
|
|
|
|
|
|
|
window int
|
|
|
|
k float64
|
|
|
|
|
|
|
|
SMA *SMAStream
|
|
|
|
StdDev *StdDevStream
|
|
|
|
}
|
|
|
|
|
|
|
|
// BOOL2 is bollinger indicator
|
|
|
|
// the data flow:
|
|
|
|
//
|
|
|
|
// priceSource ->
|
|
|
|
//
|
|
|
|
// -> calculate SMA
|
|
|
|
// -> calculate stdDev -> calculate bandWidth -> get latest SMA -> upBand, downBand
|
2023-06-09 10:38:12 +00:00
|
|
|
func BOLL2(source Float64Source, window int, k float64) *BOLLStream {
|
2023-06-09 10:36:54 +00:00
|
|
|
// bind these indicators before our main calculator
|
|
|
|
sma := SMA2(source, window)
|
|
|
|
stdDev := StdDev2(source, window)
|
|
|
|
|
2023-06-09 10:38:12 +00:00
|
|
|
s := &BOLLStream{
|
2023-06-09 10:36:54 +00:00
|
|
|
Float64Series: NewFloat64Series(),
|
|
|
|
UpBand: NewFloat64Series(),
|
|
|
|
DownBand: NewFloat64Series(),
|
|
|
|
window: window,
|
|
|
|
k: k,
|
|
|
|
SMA: sma,
|
|
|
|
StdDev: stdDev,
|
|
|
|
}
|
|
|
|
s.Bind(source, s)
|
|
|
|
|
|
|
|
// on band update
|
|
|
|
s.Float64Series.OnUpdate(func(band float64) {
|
|
|
|
mid := s.SMA.Last(0)
|
|
|
|
s.UpBand.PushAndEmit(mid + band)
|
|
|
|
s.DownBand.PushAndEmit(mid - band)
|
|
|
|
})
|
|
|
|
return s
|
|
|
|
}
|
|
|
|
|
2023-06-09 10:38:12 +00:00
|
|
|
func (s *BOLLStream) Calculate(v float64) float64 {
|
2023-06-09 10:36:54 +00:00
|
|
|
stdDev := s.StdDev.Last(0)
|
|
|
|
band := stdDev * s.k
|
|
|
|
return band
|
|
|
|
}
|