diff --git a/pkg/indicator/pivot_low.go b/pkg/indicator/pivot_low.go index 901f9f866..62a3b21e8 100644 --- a/pkg/indicator/pivot_low.go +++ b/pkg/indicator/pivot_low.go @@ -12,7 +12,9 @@ import ( //go:generate callbackgen -type PivotLow type PivotLow struct { types.IntervalWindow + types.SeriesBase + Lows types.Float64Slice Values types.Float64Slice EndTime time.Time @@ -26,33 +28,55 @@ func (inc *PivotLow) Last() float64 { return inc.Values[len(inc.Values)-1] } -func (inc *PivotLow) CalculateAndUpdate(klines []types.KLine) { - if len(klines) < inc.Window { +func (inc *PivotLow) Update(value float64) { + if len(inc.Lows) == 0 { + inc.SeriesBase.Series = inc + } + + inc.Lows.Push(value) + + if len(inc.Lows) < inc.Window { return } - var end = len(klines) - 1 - var lastKLine = klines[end] - - // skip old data - if inc.EndTime != zeroTime && lastKLine.GetEndTime().Before(inc.EndTime) { - return - } - - recentT := klines[end-(inc.Window-1) : end+1] - - l, err := calculatePivotLow(recentT, inc.Window, KLineLowPriceMapper) + low, err := calculatePivotLow(inc.Lows, inc.Window) if err != nil { - log.WithError(err).Error("can not calculate pivots") + log.WithError(err).Errorf("can not calculate pivot low") return } - if l > 0.0 { - inc.Values.Push(l) + if low > 0.0 { + inc.Values.Push(low) + } +} + +func (inc *PivotLow) PushK(k types.KLine) { + if k.EndTime.Before(inc.EndTime) { + return } - inc.EndTime = klines[end].GetEndTime().Time() - inc.EmitUpdate(l) + inc.Update(k.Low.Float64()) + inc.EndTime = k.EndTime.Time() + inc.EmitUpdate(inc.Last()) +} + +func (inc *PivotLow) LoadK(allKLines []types.KLine) { + for _, k := range allKLines { + inc.PushK(k) + } +} + +func (inc *PivotLow) CalculateAndUpdate(allKLines []types.KLine) { + if len(inc.Values) == 0 { + for _, k := range allKLines { + inc.PushK(k) + } + inc.EmitUpdate(inc.Last()) + } else { + k := allKLines[len(allKLines)-1] + inc.PushK(k) + inc.EmitUpdate(inc.Last()) + } } func (inc *PivotLow) handleKLineWindowUpdate(interval types.Interval, window types.KLineWindow) { @@ -67,15 +91,15 @@ func (inc *PivotLow) Bind(updater KLineWindowUpdater) { updater.OnKLineWindowUpdate(inc.handleKLineWindowUpdate) } -func calculatePivotLow(klines []types.KLine, window int, valLow KLineValueMapper) (float64, error) { - length := len(klines) +func calculatePivotLow(lows types.Float64Slice, window int) (float64, error) { + length := len(lows) if length == 0 || length < window { return 0., fmt.Errorf("insufficient elements for calculating with window = %d", window) } - var lows types.Float64Slice - for _, k := range klines { - lows.Push(valLow(k)) + var pv types.Float64Slice + for _, low := range lows { + pv.Push(low) } pl := 0. diff --git a/pkg/indicator/pivotlow_callbacks.go b/pkg/indicator/pivotlow_callbacks.go new file mode 100644 index 000000000..5ea139caf --- /dev/null +++ b/pkg/indicator/pivotlow_callbacks.go @@ -0,0 +1,15 @@ +// Code generated by "callbackgen -type PivotLow"; DO NOT EDIT. + +package indicator + +import () + +func (inc *PivotLow) OnUpdate(cb func(value float64)) { + inc.updateCallbacks = append(inc.updateCallbacks, cb) +} + +func (inc *PivotLow) EmitUpdate(value float64) { + for _, cb := range inc.updateCallbacks { + cb(value) + } +}