Merge pull request #1830 from c9s/c9s/xdepthmaker/fix-book-pricing
Some checks are pending
Go / build (1.21, 6.2) (push) Waiting to run
golang-lint / lint (push) Waiting to run

FIX: [xdepthmaker] fix book pricing
This commit is contained in:
c9s 2024-11-17 18:01:27 +08:00 committed by GitHub
commit 0399cd1379
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 21 additions and 17 deletions

View File

@ -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)
}

View File

@ -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)
}

View File

@ -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