diff --git a/bollinger_band_series.go b/bollinger_band_series.go index 2894cdf..3529aa5 100644 --- a/bollinger_band_series.go +++ b/bollinger_band_series.go @@ -42,6 +42,17 @@ func (bbs BollingerBandsSeries) GetWindowSize(defaults ...int) int { return bbs.WindowSize } +// GetK returns the K value. +func (bbs BollingerBandsSeries) GetK(defaults ...float64) float64 { + if bbs.K == 0 { + if len(defaults) > 0 { + return defaults[0] + } + return 2.0 + } + return bbs.K +} + // Len returns the number of elements in the series. func (bbs *BollingerBandsSeries) Len() int { return bbs.InnerSeries.Len() @@ -65,8 +76,8 @@ func (bbs *BollingerBandsSeries) GetBoundedValue(index int) (x, y1, y2 float64) ay := bbs.getAverage(bbs.valueBuffer) std := bbs.getStdDev(bbs.valueBuffer) - y1 = ay + (bbs.K * std) - y2 = ay - (bbs.K * std) + y1 = ay + (bbs.GetK() * std) + y2 = ay - (bbs.GetK() * std) return } diff --git a/bollinger_band_series_test.go b/bollinger_band_series_test.go new file mode 100644 index 0000000..5394afd --- /dev/null +++ b/bollinger_band_series_test.go @@ -0,0 +1,32 @@ +package chart + +import ( + "testing" + + "github.com/blendlabs/go-assert" +) + +func TestBollingerBandSeries(t *testing.T) { + assert := assert.New(t) + + s1 := mockValueProvider{ + X: Seq(1.0, 100.0), + Y: SeqRand(100, 1024), + } + + bbs := &BollingerBandsSeries{ + InnerSeries: s1, + } + + xvalues := make([]float64, 100) + y1values := make([]float64, 100) + y2values := make([]float64, 100) + + for x := 0; x < 100; x++ { + xvalues[x], y1values[x], y2values[x] = bbs.GetBoundedValue(x) + } + + for x := bbs.GetWindowSize(); x < 100; x++ { + assert.True(y1values[x] > y2values[x]) + } +} diff --git a/util.go b/util.go index ac440f8..1e4e6ca 100644 --- a/util.go +++ b/util.go @@ -3,6 +3,7 @@ package chart import ( "fmt" "math" + "math/rand" "time" ) @@ -143,6 +144,18 @@ func Seq(start, end float64, steps ...float64) []float64 { return values } +// SeqRand generates a random sequence. +func SeqRand(samples int, scale float64) []float64 { + rnd := rand.New(rand.NewSource(time.Now().Unix())) + values := make([]float64, samples) + + for x := 0; x < samples; x++ { + values[x] = rnd.Float64() * scale + } + + return values +} + // PercentDifference computes the percentage difference between two values. // The formula is (v2-v1)/v1. func PercentDifference(v1, v2 float64) float64 {