diff --git a/moving_average_series.go b/moving_average_series.go index 0aa1f53..206543e 100644 --- a/moving_average_series.go +++ b/moving_average_series.go @@ -39,6 +39,9 @@ func (mas *MovingAverageSeries) Len() int { // GetValue gets a value at a given index. func (mas *MovingAverageSeries) GetValue(index int) (x float64, y float64) { + if mas.InnerSeries == nil { + return + } if mas.valueBuffer == nil { mas.valueBuffer = NewRingBufferWithCapacity(mas.GetWindowSize()) } @@ -48,7 +51,29 @@ func (mas *MovingAverageSeries) GetValue(index int) (x float64, y float64) { px, py := mas.InnerSeries.GetValue(index) mas.valueBuffer.Enqueue(py) x = px - y = mas.getAverage() + y = mas.getAverage(mas.valueBuffer) + return +} + +// GetLastValue computes the last moving average value but walking back window size samples, +// and recomputing the last moving average chunk. +func (mas MovingAverageSeries) GetLastValue() (x float64, y float64) { + if mas.InnerSeries == nil { + return + } + windowSize := mas.GetWindowSize() + seriesLength := mas.InnerSeries.Len() + startAt := seriesLength - (windowSize + 1) + if (seriesLength - startAt) < 0 { + startAt = 0 + } + vb := NewRingBufferWithCapacity(windowSize) + for index := startAt; index < seriesLength; index++ { + xn, yn := mas.InnerSeries.GetValue(index) + vb.Enqueue(yn) + x = xn + } + y = mas.getAverage(vb) return } @@ -63,9 +88,9 @@ func (mas MovingAverageSeries) GetWindowSize(defaults ...int) int { return mas.WindowSize } -func (mas MovingAverageSeries) getAverage() float64 { +func (mas MovingAverageSeries) getAverage(valueBuffer *RingBuffer) float64 { var accum float64 - mas.valueBuffer.Each(func(v interface{}) { + valueBuffer.Each(func(v interface{}) { if typed, isTyped := v.(float64); isTyped { accum += typed }