diff --git a/config/pivotshort-ETHUSDT.yaml b/config/pivotshort-ETHUSDT.yaml index 33d6f9723..d5bfff4e6 100644 --- a/config/pivotshort-ETHUSDT.yaml +++ b/config/pivotshort-ETHUSDT.yaml @@ -11,8 +11,12 @@ exchangeStrategies: - on: binance pivotshort: symbol: ETHUSDT + + # interval is the main pivot interval interval: 5m - pivotLength: 200 + + # window is the main pivot window + window: 200 # breakLow settings are used for shorting when the current price break the previous low breakLow: @@ -53,7 +57,7 @@ exchangeStrategies: # roiTakeProfitPercentage is used to force taking profit by percentage of the position ROI (currently the price change) # force to take the profit ROI exceeded the percentage. - roiTakeProfitPercentage: 10% + roiTakeProfitPercentage: 25% # roiMinTakeProfitPercentage applies to lowerShadowRatio and cumulatedVolume exit options roiMinTakeProfitPercentage: 10% diff --git a/config/pivotshort-GMTBUSD.yaml b/config/pivotshort-GMTBUSD.yaml index afc365ed7..0e3fa7724 100644 --- a/config/pivotshort-GMTBUSD.yaml +++ b/config/pivotshort-GMTBUSD.yaml @@ -13,8 +13,7 @@ exchangeStrategies: pivotshort: symbol: GMTBUSD interval: 5m - - pivotLength: 120 + window: 120 entry: immediate: true diff --git a/config/pivotshort.yaml b/config/pivotshort.yaml index c55c07942..ec80ca351 100644 --- a/config/pivotshort.yaml +++ b/config/pivotshort.yaml @@ -14,7 +14,7 @@ exchangeStrategies: symbol: GMTUSDT interval: 5m - pivotLength: 120 + window: 120 # breakLow settings are used for shorting when the current price break the previous low breakLow: @@ -33,13 +33,18 @@ exchangeStrategies: # force to take the profit ROI exceeded the percentage. roiTakeProfitPercentage: 25% + # roiMinTakeProfitPercentage applies to lowerShadowRatio and cumulatedVolume exit options + roiMinTakeProfitPercentage: 10% + # lowerShadowRatio is used to force taking profit when the (lower shadow height / low price) > lowerShadowRatio # you can grab a simple stats by the following SQL: # SELECT ((close - low) / close) AS shadow_ratio FROM binance_klines WHERE symbol = 'ETHUSDT' AND `interval` = '5m' AND start_time > '2022-01-01' ORDER BY shadow_ratio DESC LIMIT 20; lowerShadowRatio: 3% + # cumulatedVolume is used to take profit when the cumulated quote volume from the klines exceeded a threshold cumulatedVolume: - minVolume: 50_000 + enabled: false + minQuoteVolume: 90_000_000 window: 5 marginOrderSideEffect: repay diff --git a/pkg/strategy/pivotshort/strategy.go b/pkg/strategy/pivotshort/strategy.go index 2ace2677e..da5d3ada1 100644 --- a/pkg/strategy/pivotshort/strategy.go +++ b/pkg/strategy/pivotshort/strategy.go @@ -109,15 +109,15 @@ type Strategy struct { Environment *bbgo.Environment Symbol string `json:"symbol"` Market types.Market - Interval types.Interval `json:"interval"` + + // pivot interval and window + types.IntervalWindow // persistence fields Position *types.Position `json:"position,omitempty" persistence:"position"` ProfitStats *types.ProfitStats `json:"profitStats,omitempty" persistence:"profit_stats"` TradeStats *TradeStats `persistence:"trade_stats"` - PivotLength int `json:"pivotLength"` - BreakLow BreakLow `json:"breakLow"` Entry Entry `json:"entry"` Exit Exit `json:"exit"` @@ -279,9 +279,8 @@ func (s *Strategy) Run(ctx context.Context, orderExecutor bbgo.OrderExecutor, se }) s.tradeCollector.BindStream(session.UserDataStream) - iw := types.IntervalWindow{Window: s.PivotLength, Interval: s.Interval} store, _ := session.MarketDataStore(s.Symbol) - s.pivot = &indicator.Pivot{IntervalWindow: iw} + s.pivot = &indicator.Pivot{IntervalWindow: s.IntervalWindow} s.pivot.Bind(store) standardIndicator, _ := session.StandardIndicatorSet(s.Symbol) @@ -293,12 +292,16 @@ func (s *Strategy) Run(ctx context.Context, orderExecutor bbgo.OrderExecutor, se session.UserDataStream.OnStart(func() { if klines, ok := store.KLinesOfInterval(s.Interval); ok { - s.pivot.Update(*klines) + last := (*klines)[len(*klines)-1] + log.Debugf("updating pivot indicator: %d klines", len(*klines)) + for i := s.pivot.Window; i < len(*klines); i++ { + s.pivot.Update((*klines)[0 : i+1]) + } - log.Infof("found previous lows: %v", s.pivot.Lows) - log.Infof("found previous highs: %v", s.pivot.Highs) + log.Infof("current %s price: %f", s.Symbol, last.Close.Float64()) + log.Infof("found %s previous lows: %v", s.Symbol, s.pivot.Lows) + log.Infof("found %s previous highs: %v", s.Symbol, s.pivot.Highs) } - // s.placeBounceSellOrders(ctx, limitPrice, price, orderExecutor) })