diff --git a/config/pivotshort-GMTBUSD.yaml b/config/pivotshort-GMTBUSD.yaml index e99dab685..d2d62021e 100644 --- a/config/pivotshort-GMTBUSD.yaml +++ b/config/pivotshort-GMTBUSD.yaml @@ -32,7 +32,7 @@ exchangeStrategies: - roiTakeProfit: percentage: 30% - - protectionStopLoss: + - protectiveStopLoss: activationRatio: 1% stopLossRatio: 0.2% placeStopOrder: true diff --git a/config/pivotshort.yaml b/config/pivotshort.yaml index b9c9aa35e..75fcc8535 100644 --- a/config/pivotshort.yaml +++ b/config/pivotshort.yaml @@ -71,13 +71,13 @@ exchangeStrategies: percentage: 35% # (2) protective stop loss -- short term - - protectionStopLoss: + - protectiveStopLoss: activationRatio: 0.6% stopLossRatio: 0.1% placeStopOrder: false # (3) protective stop loss -- long term - - protectionStopLoss: + - protectiveStopLoss: activationRatio: 5% stopLossRatio: 1% placeStopOrder: false diff --git a/config/pivotshort_optimizer.yaml b/config/pivotshort_optimizer.yaml index 74f31ce55..207c8f5a2 100644 --- a/config/pivotshort_optimizer.yaml +++ b/config/pivotshort_optimizer.yaml @@ -44,8 +44,8 @@ matrix: step: 5% - type: range - path: '/exchangeStrategies/0/pivotshort/exits/2/protectionStopLoss/activationRatio' - label: protectionStopLoss_activationRatio + path: '/exchangeStrategies/0/pivotshort/exits/2/protectiveStopLoss/activationRatio' + label: protectiveStopLoss_activationRatio min: 0.5% max: 3% step: 0.1% @@ -60,6 +60,6 @@ matrix: - type: range path: '/exchangeStrategies/0/pivotshort/exits/5/cumulatedVolumeTakeProfit/minQuoteVolume' label: cumulatedVolumeTakeProfit_minQuoteVolume - min: 30_000_000 - max: 200_000_000 - step: 10_000_000 + min: 3_000_000 + max: 20_000_000 + step: 100_000 diff --git a/pkg/strategy/pivotshort/exit.go b/pkg/strategy/pivotshort/exit.go index 7fe7fdc9c..fd78a6603 100644 --- a/pkg/strategy/pivotshort/exit.go +++ b/pkg/strategy/pivotshort/exit.go @@ -4,15 +4,15 @@ import "github.com/c9s/bbgo/pkg/bbgo" type ExitMethod struct { RoiStopLoss *RoiStopLoss `json:"roiStopLoss"` - ProtectionStopLoss *ProtectionStopLoss `json:"protectionStopLoss"` + ProtectiveStopLoss *ProtectiveStopLoss `json:"protectiveStopLoss"` RoiTakeProfit *RoiTakeProfit `json:"roiTakeProfit"` LowerShadowTakeProfit *LowerShadowTakeProfit `json:"lowerShadowTakeProfit"` CumulatedVolumeTakeProfit *CumulatedVolumeTakeProfit `json:"cumulatedVolumeTakeProfit"` } func (m *ExitMethod) Bind(session *bbgo.ExchangeSession, orderExecutor *bbgo.GeneralOrderExecutor) { - if m.ProtectionStopLoss != nil { - m.ProtectionStopLoss.Bind(session, orderExecutor) + if m.ProtectiveStopLoss != nil { + m.ProtectiveStopLoss.Bind(session, orderExecutor) } else if m.RoiStopLoss != nil { m.RoiStopLoss.Bind(session, orderExecutor) } else if m.RoiTakeProfit != nil { diff --git a/pkg/strategy/pivotshort/protection_stop.go b/pkg/strategy/pivotshort/protection_stop.go index 8c7f5328f..5e9f0bce6 100644 --- a/pkg/strategy/pivotshort/protection_stop.go +++ b/pkg/strategy/pivotshort/protection_stop.go @@ -8,7 +8,7 @@ import ( "github.com/c9s/bbgo/pkg/types" ) -type ProtectionStopLoss struct { +type ProtectiveStopLoss struct { // ActivationRatio is the trigger condition of this ROI protection stop loss // When the price goes lower (for short position) with the ratio, the protection stop will be activated. // This number should be positive to protect the profit @@ -27,7 +27,7 @@ type ProtectionStopLoss struct { stopLossOrder *types.Order } -func (s *ProtectionStopLoss) shouldActivate(position *types.Position, closePrice fixedpoint.Value) bool { +func (s *ProtectiveStopLoss) shouldActivate(position *types.Position, closePrice fixedpoint.Value) bool { if position.IsLong() { r := one.Add(s.ActivationRatio) activationPrice := position.AverageCost.Mul(r) @@ -42,7 +42,7 @@ func (s *ProtectionStopLoss) shouldActivate(position *types.Position, closePrice return false } -func (s *ProtectionStopLoss) placeStopOrder(ctx context.Context, position *types.Position, orderExecutor bbgo.OrderExecutor) error { +func (s *ProtectiveStopLoss) placeStopOrder(ctx context.Context, position *types.Position, orderExecutor bbgo.OrderExecutor) error { if s.stopLossOrder != nil { if err := orderExecutor.CancelOrders(ctx, *s.stopLossOrder); err != nil { log.WithError(err).Errorf("failed to cancel stop limit order: %+v", s.stopLossOrder) @@ -58,7 +58,7 @@ func (s *ProtectionStopLoss) placeStopOrder(ctx context.Context, position *types Price: s.stopLossPrice.Mul(one.Add(fixedpoint.NewFromFloat(0.005))), // +0.5% from the trigger price, slippage protection StopPrice: s.stopLossPrice, Market: position.Market, - Tag: "protectionStopLoss", + Tag: "protectiveStopLoss", }) if len(createdOrders) > 0 { @@ -67,7 +67,7 @@ func (s *ProtectionStopLoss) placeStopOrder(ctx context.Context, position *types return err } -func (s *ProtectionStopLoss) shouldStop(closePrice fixedpoint.Value) bool { +func (s *ProtectiveStopLoss) shouldStop(closePrice fixedpoint.Value) bool { if s.stopLossPrice.IsZero() { return false } @@ -75,7 +75,7 @@ func (s *ProtectionStopLoss) shouldStop(closePrice fixedpoint.Value) bool { return closePrice.Compare(s.stopLossPrice) >= 0 } -func (s *ProtectionStopLoss) Bind(session *bbgo.ExchangeSession, orderExecutor *bbgo.GeneralOrderExecutor) { +func (s *ProtectiveStopLoss) Bind(session *bbgo.ExchangeSession, orderExecutor *bbgo.GeneralOrderExecutor) { s.session = session s.orderExecutor = orderExecutor @@ -127,7 +127,7 @@ func (s *ProtectionStopLoss) Bind(session *bbgo.ExchangeSession, orderExecutor * } } -func (s *ProtectionStopLoss) handleChange(ctx context.Context, position *types.Position, closePrice fixedpoint.Value, orderExecutor *bbgo.GeneralOrderExecutor) { +func (s *ProtectiveStopLoss) handleChange(ctx context.Context, position *types.Position, closePrice fixedpoint.Value, orderExecutor *bbgo.GeneralOrderExecutor) { if s.stopLossOrder != nil { // use RESTful to query the order status // orderQuery := orderExecutor.Session().Exchange.(types.ExchangeOrderQueryService) @@ -149,7 +149,7 @@ func (s *ProtectionStopLoss) handleChange(ctx context.Context, position *types.P s.stopLossPrice = position.AverageCost.Mul(one.Add(s.StopLossRatio)) } - log.Infof("[ProtectionStopLoss] %s protection stop loss activated, current price = %f, average cost = %f, stop loss price = %f", + log.Infof("[ProtectiveStopLoss] %s protection stop loss activated, current price = %f, average cost = %f, stop loss price = %f", position.Symbol, closePrice.Float64(), position.AverageCost.Float64(), s.stopLossPrice.Float64()) if s.PlaceStopOrder { @@ -168,14 +168,14 @@ func (s *ProtectionStopLoss) handleChange(ctx context.Context, position *types.P s.checkStopPrice(closePrice, position) } -func (s *ProtectionStopLoss) checkStopPrice(closePrice fixedpoint.Value, position *types.Position) { +func (s *ProtectiveStopLoss) checkStopPrice(closePrice fixedpoint.Value, position *types.Position) { if s.stopLossPrice.IsZero() { return } if s.shouldStop(closePrice) { - log.Infof("[ProtectionStopLoss] protection stop order is triggered at price %f, position = %+v", closePrice.Float64(), position) - if err := s.orderExecutor.ClosePosition(context.Background(), one, "protectionStopLoss"); err != nil { + log.Infof("[ProtectiveStopLoss] protection stop order is triggered at price %f, position = %+v", closePrice.Float64(), position) + if err := s.orderExecutor.ClosePosition(context.Background(), one, "protectiveStopLoss"); err != nil { log.WithError(err).Errorf("failed to close position") } }