diff --git a/pkg/datatype/floats/pivot.go b/pkg/datatype/floats/pivot.go index b7536cbe3..00bad9427 100644 --- a/pkg/datatype/floats/pivot.go +++ b/pkg/datatype/floats/pivot.go @@ -7,10 +7,6 @@ func (s Slice) Pivot(left, right int, f func(a, pivot float64) bool) (float64, b func FindPivot(values Slice, left, right int, f func(a, pivot float64) bool) (float64, bool) { length := len(values) - if right == 0 { - right = left - } - if length == 0 || length < left+right+1 { return 0.0, false } diff --git a/pkg/datatype/floats/pivot_test.go b/pkg/datatype/floats/pivot_test.go new file mode 100644 index 000000000..5228882ca --- /dev/null +++ b/pkg/datatype/floats/pivot_test.go @@ -0,0 +1,29 @@ +package floats + +import ( + "testing" + + "github.com/stretchr/testify/assert" +) + +func TestFindPivot(t *testing.T) { + + t.Run("middle", func(t *testing.T) { + pv, ok := FindPivot(Slice{10, 20, 30, 40, 30, 20}, 2, 2, func(a, pivot float64) bool { + return a < pivot + }) + if assert.True(t, ok) { + assert.Equal(t, 40., pv) + } + }) + + t.Run("last", func(t *testing.T) { + pv, ok := FindPivot(Slice{10, 20, 30, 40, 30, 45}, 2, 0, func(a, pivot float64) bool { + return a < pivot + }) + if assert.True(t, ok) { + assert.Equal(t, 45., pv) + } + }) + +} diff --git a/pkg/indicator/pivothigh.go b/pkg/indicator/pivothigh.go index ec90f57f7..2569e31fb 100644 --- a/pkg/indicator/pivothigh.go +++ b/pkg/indicator/pivothigh.go @@ -39,7 +39,11 @@ func (inc *PivotHigh) Update(value float64) { return } - high, ok := calculatePivotHigh(inc.Highs, inc.Window, inc.RightWindow) + if inc.RightWindow == nil { + inc.RightWindow = &inc.Window + } + + high, ok := calculatePivotHigh(inc.Highs, inc.Window, *inc.RightWindow) if !ok { return } diff --git a/pkg/indicator/pivotlow.go b/pkg/indicator/pivotlow.go index 2023fc941..021a432ef 100644 --- a/pkg/indicator/pivotlow.go +++ b/pkg/indicator/pivotlow.go @@ -39,7 +39,11 @@ func (inc *PivotLow) Update(value float64) { return } - low, ok := calculatePivotLow(inc.Lows, inc.Window, inc.RightWindow) + if inc.RightWindow == nil { + inc.RightWindow = &inc.Window + } + + low, ok := calculatePivotLow(inc.Lows, inc.Window, *inc.RightWindow) if !ok { return } diff --git a/pkg/indicator/pivotlow_test.go b/pkg/indicator/pivotlow_test.go index 318df37a7..2425f530e 100644 --- a/pkg/indicator/pivotlow_test.go +++ b/pkg/indicator/pivotlow_test.go @@ -36,8 +36,8 @@ func Test_calculatePivotLow(t *testing.T) { assert.Equal(t, 0.0, low) }) - t.Run("right window 0", func(t *testing.T) { - low, ok := calculatePivotLow([]float64{15.0, 13.0, 12.0, 10.0, 14.0, 15.0}, 2, 0) + t.Run("right window same", func(t *testing.T) { + low, ok := calculatePivotLow([]float64{15.0, 13.0, 12.0, 10.0, 14.0, 15.0}, 2, 2) assert.True(t, ok) assert.Equal(t, 10.0, low) }) diff --git a/pkg/strategy/trendtrader/trend.go b/pkg/strategy/trendtrader/trend.go index 81876ef30..d562e8344 100644 --- a/pkg/strategy/trendtrader/trend.go +++ b/pkg/strategy/trendtrader/trend.go @@ -14,7 +14,7 @@ type TrendLine struct { Market types.Market `json:"-"` types.IntervalWindow - PivotRightWindow fixedpoint.Value `json:"pivotRightWindow"` + PivotRightWindow int `json:"pivotRightWindow"` // MarketOrder is the option to enable market order short. MarketOrder bool `json:"marketOrder"` @@ -35,9 +35,9 @@ func (s *TrendLine) Subscribe(session *bbgo.ExchangeSession) { session.Subscribe(types.KLineChannel, s.Symbol, types.SubscribeOptions{Interval: s.Interval}) session.Subscribe(types.KLineChannel, s.Symbol, types.SubscribeOptions{Interval: types.Interval1m}) - //if s.pivot != nil { + // if s.pivot != nil { // session.Subscribe(types.KLineChannel, s.Symbol, types.SubscribeOptions{Interval: s.Interval}) - //} + // } } func (s *TrendLine) Bind(session *bbgo.ExchangeSession, orderExecutor *bbgo.GeneralOrderExecutor) { @@ -47,8 +47,14 @@ func (s *TrendLine) Bind(session *bbgo.ExchangeSession, orderExecutor *bbgo.Gene position := orderExecutor.Position() symbol := position.Symbol standardIndicator := session.StandardIndicatorSet(s.Symbol) - s.pivotHigh = standardIndicator.PivotHigh(types.IntervalWindow{s.Interval, int(3. * s.PivotRightWindow.Float64()), int(s.PivotRightWindow.Float64())}) - s.pivotLow = standardIndicator.PivotLow(types.IntervalWindow{s.Interval, int(3. * s.PivotRightWindow.Float64()), int(s.PivotRightWindow.Float64())}) + + s.pivotHigh = standardIndicator.PivotHigh(types.IntervalWindow{ + Interval: s.Interval, + Window: int(3. * s.PivotRightWindow), RightWindow: &s.PivotRightWindow}) + + s.pivotLow = standardIndicator.PivotLow(types.IntervalWindow{ + Interval: s.Interval, + Window: int(3. * s.PivotRightWindow), RightWindow: &s.PivotRightWindow}) resistancePrices := types.NewQueue(3) pivotHighDurationCounter := 0. @@ -124,7 +130,9 @@ func (s *TrendLine) Bind(session *bbgo.ExchangeSession, orderExecutor *bbgo.Gene } } -func (s *TrendLine) placeOrder(ctx context.Context, side types.SideType, quantity fixedpoint.Value, symbol string) error { +func (s *TrendLine) placeOrder( + ctx context.Context, side types.SideType, quantity fixedpoint.Value, symbol string, +) error { market, _ := s.session.Market(symbol) _, err := s.orderExecutor.SubmitOrders(ctx, types.SubmitOrder{ Symbol: symbol, diff --git a/pkg/types/interval.go b/pkg/types/interval.go index 3410b0657..689da68e7 100644 --- a/pkg/types/interval.go +++ b/pkg/types/interval.go @@ -179,7 +179,7 @@ type IntervalWindow struct { Window int `json:"window"` // RightWindow is used by the pivot indicator - RightWindow int `json:"rightWindow"` + RightWindow *int `json:"rightWindow"` } type IntervalWindowBandWidth struct {