diff --git a/pkg/strategy/xdepthmaker/strategy.go b/pkg/strategy/xdepthmaker/strategy.go index 972a48df7..6cd827cc0 100644 --- a/pkg/strategy/xdepthmaker/strategy.go +++ b/pkg/strategy/xdepthmaker/strategy.go @@ -1026,24 +1026,28 @@ func (s *Strategy) generateMakerOrders( depthPrice = depthPrice.Mul(fixedpoint.One.Sub(s.BidMargin)) } - depthPrice = depthPrice.Round(s.makerMarket.PricePrecision+1, fixedpoint.Down) + depthPrice = depthPrice.Round(s.makerMarket.PricePrecision, fixedpoint.Down) case types.SideTypeSell: if s.AskMargin.Sign() > 0 { depthPrice = depthPrice.Mul(fixedpoint.One.Add(s.AskMargin)) } - depthPrice = depthPrice.Round(s.makerMarket.PricePrecision+1, fixedpoint.Up) + depthPrice = depthPrice.Round(s.makerMarket.PricePrecision, fixedpoint.Up) } - depthPrice = s.makerMarket.TruncatePrice(depthPrice) - if lastMakerPrice.Sign() > 0 && depthPrice.Compare(lastMakerPrice) == 0 { - switch side { - case types.SideTypeBuy: - depthPrice = depthPrice.Sub(s.makerMarket.TickSize.Mul(s.Pips)) - case types.SideTypeSell: - depthPrice = depthPrice.Add(s.makerMarket.TickSize.Mul(s.Pips)) + tickSize := s.makerMarket.TickSize + if tickSize.IsZero() { + s.logger.Warnf("maker market tick size is zero") + } else if tickSize.Sign() > 0 { + tickSize = s.makerMarket.TickSize.Mul(s.Pips) + switch side { + case types.SideTypeBuy: + depthPrice = depthPrice.Sub(tickSize) + case types.SideTypeSell: + depthPrice = depthPrice.Add(tickSize) + } } } @@ -1058,15 +1062,15 @@ func (s *Strategy) generateMakerOrders( accumulatedBidQuantity = accumulatedBidQuantity.Add(quantity) quoteQuantity := fixedpoint.Mul(quantity, depthPrice) - quoteQuantity = quoteQuantity.Round(s.makerMarket.PricePrecision, fixedpoint.Up) + quoteQuantity = quoteQuantity.Round(s.makerMarket.PricePrecision, fixedpoint.Down) if !availableSideBalance.Eq(fixedpoint.PosInf) && availableSideBalance.Compare(quoteQuantity) <= 0 { quoteQuantity = availableSideBalance quantity = quoteQuantity.Div(depthPrice).Round(s.makerMarket.PricePrecision, fixedpoint.Down) } - if quantity.Compare(s.makerMarket.MinQuantity) <= 0 || quoteQuantity.Compare(s.makerMarket.MinNotional) <= 0 { - break layerLoop + if s.makerMarket.IsDustQuantity(quantity, depthPrice) { + continue layerLoop } availableSideBalance = availableSideBalance.Sub(quoteQuantity) @@ -1075,19 +1079,17 @@ func (s *Strategy) generateMakerOrders( case types.SideTypeSell: quantity = quantity.Sub(accumulatedAskQuantity) - quoteQuantity := quantity.Mul(depthPrice) // balance check if !availableSideBalance.Eq(fixedpoint.PosInf) && availableSideBalance.Compare(quantity) <= 0 { break layerLoop } - if quantity.Compare(s.makerMarket.MinQuantity) <= 0 || quoteQuantity.Compare(s.makerMarket.MinNotional) <= 0 { - break layerLoop + if s.makerMarket.IsDustQuantity(quantity, depthPrice) { + continue layerLoop } availableSideBalance = availableSideBalance.Sub(quantity) - accumulatedAskQuantity = accumulatedAskQuantity.Add(quantity) } diff --git a/pkg/strategy/xdepthmaker/strategy_test.go b/pkg/strategy/xdepthmaker/strategy_test.go index d81adcf2a..6eb247a2b 100644 --- a/pkg/strategy/xdepthmaker/strategy_test.go +++ b/pkg/strategy/xdepthmaker/strategy_test.go @@ -71,7 +71,7 @@ func TestStrategy_generateMakerOrders(t *testing.T) { {Side: types.SideTypeBuy, Price: Number("24866.66"), Quantity: Number("0.281715")}, // =~ $7005.3111219, accumulated amount =~ $1000.00 + $7005.3111219 = $8005.3111219 {Side: types.SideTypeBuy, Price: Number("24800"), Quantity: Number("0.283123")}, // =~ $7021.4504, accumulated amount =~ $1000.00 + $7005.3111219 + $7021.4504 = $8005.3111219 + $7021.4504 =~ $15026.7615219 {Side: types.SideTypeSell, Price: Number("25100"), Quantity: Number("0.03984")}, - {Side: types.SideTypeSell, Price: Number("25233.33"), Quantity: Number("0.2772")}, + {Side: types.SideTypeSell, Price: Number("25233.34"), Quantity: Number("0.2772")}, {Side: types.SideTypeSell, Price: Number("25300"), Quantity: Number("0.275845")}, }, orders) } diff --git a/pkg/types/price_volume_slice.go b/pkg/types/price_volume_slice.go index 08255747e..092c652a5 100644 --- a/pkg/types/price_volume_slice.go +++ b/pkg/types/price_volume_slice.go @@ -254,6 +254,8 @@ func ParsePriceVolumeSliceJSON(b []byte) (slice PriceVolumeSlice, err error) { return slice, nil } +// AverageDepthPriceByQuote calculates the average price by the required quote depth +// maxLevel is the maximum level to calculate the average price func (slice PriceVolumeSlice) AverageDepthPriceByQuote(requiredDepthInQuote fixedpoint.Value, maxLevel int) fixedpoint.Value { if len(slice) == 0 { return fixedpoint.Zero