diff --git a/pkg/strategy/rebalance/strategy.go b/pkg/strategy/rebalance/strategy.go index 22896d24b..40c0fa821 100644 --- a/pkg/strategy/rebalance/strategy.go +++ b/pkg/strategy/rebalance/strategy.go @@ -40,7 +40,6 @@ type Strategy struct { DryRun bool `json:"dryRun"` OnStart bool `json:"onStart"` // rebalance on start - session *bbgo.ExchangeSession symbols []string markets map[string]types.Market activeOrderBook *bbgo.ActiveOrderBook @@ -97,11 +96,9 @@ func (s *Strategy) Validate() error { func (s *Strategy) Subscribe(session *bbgo.ExchangeSession) {} func (s *Strategy) Run(ctx context.Context, _ bbgo.OrderExecutor, session *bbgo.ExchangeSession) error { - s.session = session - s.markets = make(map[string]types.Market) for _, symbol := range s.symbols { - market, ok := s.session.Market(symbol) + market, ok := session.Market(symbol) if !ok { return fmt.Errorf("market %s not found", symbol) } @@ -112,7 +109,7 @@ func (s *Strategy) Run(ctx context.Context, _ bbgo.OrderExecutor, session *bbgo. s.MultiMarketStrategy.Initialize(ctx, s.Environment, session, s.markets, ID) s.activeOrderBook = bbgo.NewActiveOrderBook("") - s.activeOrderBook.BindStream(s.session.UserDataStream) + s.activeOrderBook.BindStream(session.UserDataStream) session.UserDataStream.OnStart(func() { if s.OnStart { @@ -137,7 +134,7 @@ func (s *Strategy) Run(ctx context.Context, _ bbgo.OrderExecutor, session *bbgo. func (s *Strategy) rebalance(ctx context.Context) { // cancel active orders before rebalance - if err := s.session.Exchange.CancelOrders(ctx, s.activeOrderBook.Orders()...); err != nil { + if err := s.Session.Exchange.CancelOrders(ctx, s.activeOrderBook.Orders()...); err != nil { log.WithError(err).Errorf("failed to cancel orders") } @@ -174,7 +171,7 @@ func (s *Strategy) queryMidPrices(ctx context.Context) (types.ValueMap, error) { continue } - ticker, err := s.session.Exchange.QueryTicker(ctx, currency+s.QuoteCurrency) + ticker, err := s.Session.Exchange.QueryTicker(ctx, currency+s.QuoteCurrency) if err != nil { return nil, err } @@ -186,7 +183,7 @@ func (s *Strategy) queryMidPrices(ctx context.Context) (types.ValueMap, error) { func (s *Strategy) selectBalances() (types.BalanceMap, error) { m := make(types.BalanceMap) - balances := s.session.GetAccount().Balances() + balances := s.Session.GetAccount().Balances() for currency := range s.TargetWeights { balance, ok := balances[currency] if !ok { @@ -235,28 +232,36 @@ func (s *Strategy) generateOrder(ctx context.Context) (*types.SubmitOrder, error quantity = quantity.Abs() } - if s.MaxAmount.Float64() > 0 { - quantity = bbgo.AdjustQuantityByMaxAmount(quantity, midPrice, s.MaxAmount) - log.Infof("adjust quantity %s (%s %s @ %s) by max amount %s", - quantity.String(), - symbol, - side.String(), - midPrice.String(), - s.MaxAmount.String()) + ticker, err := s.Session.Exchange.QueryTicker(ctx, symbol) + if err != nil { + return nil, err } + var price fixedpoint.Value if side == types.SideTypeBuy { - quantity = fixedpoint.Min(quantity, balances[s.QuoteCurrency].Available.Div(midPrice)) + price = ticker.Buy + quantity = fixedpoint.Min(quantity, balances[s.QuoteCurrency].Available.Div(ticker.Sell)) } else if side == types.SideTypeSell { + price = ticker.Sell quantity = fixedpoint.Min(quantity, balances[market.BaseCurrency].Available) } - if market.IsDustQuantity(quantity, midPrice) { + if s.MaxAmount.Float64() > 0 { + quantity = bbgo.AdjustQuantityByMaxAmount(quantity, price, s.MaxAmount) + log.Infof("adjusted quantity %s (%s %s @ %s) by max amount %s", + quantity.String(), + symbol, + side.String(), + price.String(), + s.MaxAmount.String()) + } + + if market.IsDustQuantity(quantity, price) { log.Infof("quantity %s (%s %s @ %s) is dust quantity, skip", quantity.String(), symbol, side.String(), - midPrice.String()) + price.String()) continue } @@ -265,7 +270,7 @@ func (s *Strategy) generateOrder(ctx context.Context) (*types.SubmitOrder, error Side: side, Type: s.OrderType, Quantity: quantity, - Price: midPrice, + Price: price, }, nil } return nil, nil