From 69b45e90e9a4dc4a75b86ee4a36d58332d063417 Mon Sep 17 00:00:00 2001 From: zenix Date: Tue, 5 Jul 2022 20:43:05 +0900 Subject: [PATCH] add drift exit condition --- config/drift.yaml | 26 ++++++++++++++++++++++++-- pkg/strategy/drift/strategy.go | 19 +++++++++++++++---- 2 files changed, 39 insertions(+), 6 deletions(-) diff --git a/config/drift.yaml b/config/drift.yaml index 2b5c8b8c4..aa4e4785f 100644 --- a/config/drift.yaml +++ b/config/drift.yaml @@ -13,6 +13,28 @@ exchangeStrategies: symbol: ETHUSDT # kline interval for indicators interval: 15m + window: 3 + exits: + - roiStopLoss: + percentage: 0.8% + - roiTakeProfit: + percentage: 35% + - protectiveStopLoss: + activationRatio: 0.6% + stopLossRatio: 0.1% + placeStopOrder: false + - protectiveStopLoss: + activationRatio: 5% + stopLossRatio: 1% + placeStopOrder: false + - cumulatedVolumeTakeProfit: + interval: 5m + window: 2 + minQuoteVolume: 200_000_000 + #- protectiveStopLoss: + # activationRatio: 2% + # stopLossRatio: 1% + # placeStopOrder: false sync: userDataStream: @@ -32,7 +54,7 @@ backtest: accounts: binance: #makerFeeRate: 0 - #takerFeeRate: 15 + #takerFeeRate: 0 balances: - ETH: 10.0 + ETH: 0.0 USDT: 5000.0 diff --git a/pkg/strategy/drift/strategy.go b/pkg/strategy/drift/strategy.go index b3a9496dc..aab805b42 100644 --- a/pkg/strategy/drift/strategy.go +++ b/pkg/strategy/drift/strategy.go @@ -40,7 +40,8 @@ type Strategy struct { midPrice fixedpoint.Value lock sync.RWMutex - Session *bbgo.ExchangeSession + ExitMethods bbgo.ExitMethodSet `json:"exits"` + Session *bbgo.ExchangeSession *bbgo.GeneralOrderExecutor *bbgo.ActiveOrderBook } @@ -64,6 +65,7 @@ func (s *Strategy) Subscribe(session *bbgo.ExchangeSession) { if !bbgo.IsBackTesting { session.Subscribe(types.MarketTradeChannel, s.Symbol, types.SubscribeOptions{}) } + s.ExitMethods.SetAndSubscribe(session, s) } var Three fixedpoint.Value = fixedpoint.NewFromInt(3) @@ -155,12 +157,15 @@ func (s *Strategy) Run(ctx context.Context, orderExecutor bbgo.OrderExecutor, se bbgo.Sync(s) }) s.GeneralOrderExecutor.Bind() + for _, method := range s.ExitMethods { + method.Bind(session, s.GeneralOrderExecutor) + } s.ActiveOrderBook = bbgo.NewActiveOrderBook(s.Symbol) s.ActiveOrderBook.BindStream(session.UserDataStream) store, _ := session.MarketDataStore(s.Symbol) - s.drift = &indicator.Drift{IntervalWindow: types.IntervalWindow{Interval: s.Interval, Window: 5}} + s.drift = &indicator.Drift{IntervalWindow: types.IntervalWindow{Interval: s.Interval, Window: s.Window}} s.atr = &indicator.ATR{IntervalWindow: types.IntervalWindow{Interval: s.Interval, Window: 34}} s.atr.Bind(store) @@ -203,7 +208,7 @@ func (s *Strategy) Run(ctx context.Context, orderExecutor bbgo.OrderExecutor, se hlc3 := kline.High.Add(kline.Low).Add(kline.Close).Div(Three) s.drift.Update(hlc3.Float64()) price := s.GetLastPrice() - if s.drift.Last() < 0 && s.drift.Index(1) >= 0 { + if s.drift.Last() < 0 && s.drift.Index(1) > 0 { if s.ActiveOrderBook.NumOfOrders() > 0 { if err := s.GeneralOrderExecutor.GracefulCancelActiveOrderBook(ctx, s.ActiveOrderBook); err != nil { log.WithError(err).Errorf("cannot cancel orders") @@ -222,6 +227,9 @@ func (s *Strategy) Run(ctx context.Context, orderExecutor bbgo.OrderExecutor, se if s.Market.IsDustQuantity(baseBalance.Available, hlc3) { return } + if !s.Position.IsClosed() && !s.Position.IsDust(hlc3) { + return + } _, err := s.GeneralOrderExecutor.SubmitOrders(ctx, types.SubmitOrder{ Symbol: s.Symbol, Side: types.SideTypeSell, @@ -235,7 +243,7 @@ func (s *Strategy) Run(ctx context.Context, orderExecutor bbgo.OrderExecutor, se return } } - if s.drift.Last() > 0 && s.drift.Index(1) <= 0 { + if s.drift.Last() > 0 && s.drift.Index(1) < 0 { if s.ActiveOrderBook.NumOfOrders() > 0 { if err := s.GeneralOrderExecutor.GracefulCancelActiveOrderBook(ctx, s.ActiveOrderBook); err != nil { log.WithError(err).Errorf("cannot cancel orders") @@ -254,6 +262,9 @@ func (s *Strategy) Run(ctx context.Context, orderExecutor bbgo.OrderExecutor, se quoteBalance.Available.Div(hlc3), hlc3) { return } + if !s.Position.IsClosed() && !s.Position.IsDust(hlc3) { + return + } _, err := s.GeneralOrderExecutor.SubmitOrders(ctx, types.SubmitOrder{ Symbol: s.Symbol, Side: types.SideTypeBuy,