Skip to content

Commit

Permalink
Merge pull request #930 from andycheng123/fix/pivotshort-trendema
Browse files Browse the repository at this point in the history
Fix: Pivotshort
  • Loading branch information
c9s committed Sep 11, 2022
2 parents e0d3a5e + df7d768 commit 3c4bad6
Show file tree
Hide file tree
Showing 6 changed files with 85 additions and 6 deletions.
8 changes: 2 additions & 6 deletions pkg/bbgo/trend_ema.go
Expand Up @@ -44,7 +44,7 @@ func (s *TrendEMA) Bind(session *ExchangeSession, orderExecutor *GeneralOrderExe

func (s *TrendEMA) Gradient() float64 {
if s.last > 0.0 && s.current > 0.0 {
return s.last / s.current
return s.current / s.last
}
return 0.0
}
Expand All @@ -58,11 +58,7 @@ func (s *TrendEMA) GradientAllowed() bool {
return false
}

if s.MaxGradient > 0.0 && gradient < s.MaxGradient {
return true
}

if s.MinGradient > 0.0 && gradient > s.MinGradient {
if s.MaxGradient > 0.0 && gradient < s.MaxGradient && gradient > s.MinGradient {
return true
}

Expand Down
21 changes: 21 additions & 0 deletions pkg/bbgo/trend_ema_test.go
@@ -0,0 +1,21 @@
package bbgo

import (
"testing"

"github.com/c9s/bbgo/pkg/types"
)

func Test_TrendEMA(t *testing.T) {
t.Run("Test Trend EMA", func(t *testing.T) {
trendEMA_test := TrendEMA{
IntervalWindow: types.IntervalWindow{Window: 1},
}
trendEMA_test.last = 1000.0
trendEMA_test.current = 1200.0

if trendEMA_test.Gradient() != 1.2 {
t.Errorf("Gradient() = %v, want %v", trendEMA_test.Gradient(), 1.2)
}
})
}
11 changes: 11 additions & 0 deletions pkg/strategy/pivotshort/breaklow.go
Expand Up @@ -50,6 +50,9 @@ type BreakLow struct {

orderExecutor *bbgo.GeneralOrderExecutor
session *bbgo.ExchangeSession

// StrategyController
bbgo.StrategyController
}

func (s *BreakLow) Subscribe(session *bbgo.ExchangeSession) {
Expand All @@ -73,6 +76,9 @@ func (s *BreakLow) Bind(session *bbgo.ExchangeSession, orderExecutor *bbgo.Gener
s.session = session
s.orderExecutor = orderExecutor

// StrategyController
s.Status = types.StrategyStatusRunning

position := orderExecutor.Position()
symbol := position.Symbol
standardIndicator := session.StandardIndicatorSet(s.Symbol)
Expand Down Expand Up @@ -146,6 +152,11 @@ func (s *BreakLow) Bind(session *bbgo.ExchangeSession, orderExecutor *bbgo.Gener
ratio := fixedpoint.One.Add(s.Ratio)
breakPrice := previousLow.Mul(ratio)

// StrategyController
if s.Status != types.StrategyStatusRunning {
return
}

openPrice := kline.Open
closePrice := kline.Close

Expand Down
16 changes: 16 additions & 0 deletions pkg/strategy/pivotshort/failedbreakhigh.go
Expand Up @@ -45,6 +45,9 @@ type FailedBreakHigh struct {

orderExecutor *bbgo.GeneralOrderExecutor
session *bbgo.ExchangeSession

// StrategyController
bbgo.StrategyController
}

func (s *FailedBreakHigh) Subscribe(session *bbgo.ExchangeSession) {
Expand Down Expand Up @@ -80,6 +83,9 @@ func (s *FailedBreakHigh) Bind(session *bbgo.ExchangeSession, orderExecutor *bbg
s.lastHigh = fixedpoint.Zero
s.pivotHigh = standardIndicator.PivotHigh(s.IntervalWindow)

// StrategyController
s.Status = types.StrategyStatusRunning

if s.VWMA != nil {
s.vwma = standardIndicator.VWMA(types.IntervalWindow{
Interval: s.BreakInterval,
Expand Down Expand Up @@ -122,6 +128,11 @@ func (s *FailedBreakHigh) Bind(session *bbgo.ExchangeSession, orderExecutor *bbg
return
}

// StrategyController
if s.Status != types.StrategyStatusRunning {
return
}

// make sure the position is opened, and it's a short position
if !position.IsOpened(k.Close) || !position.IsShort() {
return
Expand Down Expand Up @@ -150,6 +161,11 @@ func (s *FailedBreakHigh) Bind(session *bbgo.ExchangeSession, orderExecutor *bbg
return
}

// StrategyController
if s.Status != types.StrategyStatusRunning {
return
}

previousHigh := s.lastHigh
ratio := fixedpoint.One.Add(s.Ratio)
breakPrice := previousHigh.Mul(ratio)
Expand Down
11 changes: 11 additions & 0 deletions pkg/strategy/pivotshort/resistance.go
Expand Up @@ -35,6 +35,9 @@ type ResistanceShort struct {
currentResistancePrice fixedpoint.Value

activeOrders *bbgo.ActiveOrderBook

// StrategyController
bbgo.StrategyController
}

func (s *ResistanceShort) Subscribe(session *bbgo.ExchangeSession) {
Expand All @@ -59,6 +62,9 @@ func (s *ResistanceShort) Bind(session *bbgo.ExchangeSession, orderExecutor *bbg
})
s.activeOrders.BindStream(session.UserDataStream)

// StrategyController
s.Status = types.StrategyStatusRunning

if s.TrendEMA != nil {
s.TrendEMA.Bind(session, orderExecutor)
}
Expand All @@ -69,6 +75,11 @@ func (s *ResistanceShort) Bind(session *bbgo.ExchangeSession, orderExecutor *bbg
s.updateResistanceOrders(fixedpoint.NewFromFloat(s.resistancePivot.Last()))

session.MarketDataStream.OnKLineClosed(types.KLineWith(s.Symbol, s.Interval, func(kline types.KLine) {
// StrategyController
if s.Status != types.StrategyStatusRunning {
return
}

// trend EMA protection
if s.TrendEMA != nil && !s.TrendEMA.GradientAllowed() {
return
Expand Down
24 changes: 24 additions & 0 deletions pkg/strategy/pivotshort/strategy.go
Expand Up @@ -125,13 +125,37 @@ func (s *Strategy) Run(ctx context.Context, orderExecutor bbgo.OrderExecutor, se
s.OnSuspend(func() {
// Cancel active orders
_ = s.orderExecutor.GracefulCancel(ctx)

if s.BreakLow != nil {
s.BreakLow.Suspend()
}

if s.ResistanceShort != nil {
s.ResistanceShort.Suspend()
}

if s.FailedBreakHigh != nil {
s.FailedBreakHigh.Suspend()
}
})

s.OnEmergencyStop(func() {
// Cancel active orders
_ = s.orderExecutor.GracefulCancel(ctx)
// Close 100% position
_ = s.ClosePosition(ctx, fixedpoint.One)

if s.BreakLow != nil {
s.BreakLow.EmergencyStop()
}

if s.ResistanceShort != nil {
s.ResistanceShort.EmergencyStop()
}

if s.FailedBreakHigh != nil {
s.FailedBreakHigh.EmergencyStop()
}
})

// initial required information
Expand Down

0 comments on commit 3c4bad6

Please sign in to comment.