bbgo_origin/pkg/indicator/v2/adx.go

73 lines
1.6 KiB
Go
Raw Normal View History

2024-03-21 11:18:55 +00:00
package indicatorv2
import (
"math"
"github.com/c9s/bbgo/pkg/fixedpoint"
"github.com/c9s/bbgo/pkg/types"
)
type ADXStream struct {
2024-03-23 08:16:05 +00:00
*RMAStream
2024-03-21 11:18:55 +00:00
Plus, Minus *types.Float64Series
window int
prevHigh, prevLow fixedpoint.Value
}
func ADX(source KLineSubscription, window int) *ADXStream {
var (
atr = ATR2(source, window)
dmp = types.NewFloat64Series()
2024-03-23 08:16:05 +00:00
dmn = types.NewFloat64Series()
2024-03-21 11:18:55 +00:00
adx = types.NewFloat64Series()
sdmp = RMA2(dmp, window, true)
2024-03-23 08:16:05 +00:00
sdmn = RMA2(dmn, window, true)
2024-03-21 11:18:55 +00:00
s = &ADXStream{
2024-03-23 08:16:05 +00:00
window: window,
Plus: types.NewFloat64Series(),
Minus: types.NewFloat64Series(),
prevHigh: fixedpoint.Zero,
prevLow: fixedpoint.Zero,
RMAStream: RMA2(adx, window, true),
2024-03-21 11:18:55 +00:00
}
)
source.AddSubscriber(func(k types.KLine) {
2024-03-23 08:16:05 +00:00
if s.prevHigh.IsZero() || s.prevLow.IsZero() {
s.prevHigh, s.prevLow = k.High, k.Low
return
}
up, dn := k.High.Sub(s.prevHigh), s.prevLow.Sub(k.Low)
if up.Compare(dn) > 0 && up > 0 {
2024-03-21 11:18:55 +00:00
dmp.PushAndEmit(up.Float64())
} else {
dmp.PushAndEmit(0.0)
}
2024-03-23 08:16:05 +00:00
if dn.Compare(up) > 0 && dn > 0 {
dmn.PushAndEmit(dn.Float64())
2024-03-21 11:18:55 +00:00
} else {
2024-03-23 08:16:05 +00:00
dmn.PushAndEmit(0.0)
2024-03-21 11:18:55 +00:00
}
2024-03-23 08:16:05 +00:00
s.Plus.PushAndEmit(sdmp.Last(0) * 100 / atr.Last(0))
s.Minus.PushAndEmit(sdmn.Last(0) * 100 / atr.Last(0))
dx := math.Abs(s.Plus.Last(0)-s.Minus.Last(0)) / (s.Plus.Last(0) + s.Minus.Last(0))
if !math.IsNaN(dx) {
adx.PushAndEmit(dx * 100.0)
} else {
adx.PushAndEmit(0.0)
2024-03-21 11:18:55 +00:00
}
s.prevHigh, s.prevLow = k.High, k.Low
s.Truncate()
})
return s
}
func (s *ADXStream) Truncate() {
s.Slice = s.Slice.Truncate(MaxNumOfRMA)
}