mirror of
https://github.com/c9s/bbgo.git
synced 2024-11-10 09:11:55 +00:00
grid2: round down quoteQuantity/baseQuantity after the fee reduction
This commit is contained in:
parent
b04492a5a7
commit
62eed9605d
|
@ -401,25 +401,14 @@ func (s *Strategy) processFilledOrder(o types.Order) {
|
||||||
// will be used for calculating quantity
|
// will be used for calculating quantity
|
||||||
orderExecutedQuoteAmount := o.Quantity.Mul(executedPrice)
|
orderExecutedQuoteAmount := o.Quantity.Mul(executedPrice)
|
||||||
|
|
||||||
// collect trades
|
// collect trades for fee
|
||||||
feeQuantityReduction := fixedpoint.Zero
|
// fee calculation is used to reduce the order quantity
|
||||||
feeCurrency := ""
|
|
||||||
feePrec := 2
|
|
||||||
|
|
||||||
// feeQuantityReduction calculation is used to reduce the order quantity
|
|
||||||
// because when 1.0 BTC buy order is filled without FEE token, then we will actually get 1.0 * (1 - feeRate) BTC
|
// because when 1.0 BTC buy order is filled without FEE token, then we will actually get 1.0 * (1 - feeRate) BTC
|
||||||
// if we don't reduce the sell quantity, than we might fail to place the sell order
|
// if we don't reduce the sell quantity, than we might fail to place the sell order
|
||||||
feeQuantityReduction, feeCurrency = s.aggregateOrderFee(o)
|
fee, feeCurrency := s.aggregateOrderFee(o)
|
||||||
s.logger.Infof("GRID ORDER #%d %s FEE: %s %s",
|
s.logger.Infof("GRID ORDER #%d %s FEE: %s %s",
|
||||||
o.OrderID, o.Side,
|
o.OrderID, o.Side,
|
||||||
feeQuantityReduction.String(), feeCurrency)
|
fee.String(), feeCurrency)
|
||||||
|
|
||||||
feeQuantityReduction, feePrec = roundUpMarketQuantity(s.Market, feeQuantityReduction, feeCurrency)
|
|
||||||
s.logger.Infof("GRID ORDER #%d %s FEE (rounding precision %d): %s %s",
|
|
||||||
o.OrderID, o.Side,
|
|
||||||
feePrec,
|
|
||||||
feeQuantityReduction.String(),
|
|
||||||
feeCurrency)
|
|
||||||
|
|
||||||
switch o.Side {
|
switch o.Side {
|
||||||
case types.SideTypeSell:
|
case types.SideTypeSell:
|
||||||
|
@ -437,9 +426,15 @@ func (s *Strategy) processFilledOrder(o types.Order) {
|
||||||
if s.Compound || s.EarnBase {
|
if s.Compound || s.EarnBase {
|
||||||
// if it's not using the platform fee currency, reduce the quote quantity for the buy order
|
// if it's not using the platform fee currency, reduce the quote quantity for the buy order
|
||||||
if feeCurrency == s.Market.QuoteCurrency {
|
if feeCurrency == s.Market.QuoteCurrency {
|
||||||
orderExecutedQuoteAmount = orderExecutedQuoteAmount.Sub(feeQuantityReduction)
|
orderExecutedQuoteAmount = orderExecutedQuoteAmount.Sub(fee)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// for quote amount, always round down with price precision to prevent the quote currency fund locking rounding issue
|
||||||
|
origQuoteAmount := orderExecutedQuoteAmount
|
||||||
|
orderExecutedQuoteAmount = orderExecutedQuoteAmount.Round(s.Market.PricePrecision, fixedpoint.Down)
|
||||||
|
|
||||||
|
s.logger.Infof("round down buy order quote quantity %s to %s by quote quantity precision %d", origQuoteAmount.String(), orderExecutedQuoteAmount.String(), s.Market.PricePrecision)
|
||||||
|
|
||||||
newQuantity = fixedpoint.Max(orderExecutedQuoteAmount.Div(newPrice), s.Market.MinQuantity)
|
newQuantity = fixedpoint.Max(orderExecutedQuoteAmount.Div(newPrice), s.Market.MinQuantity)
|
||||||
} else if s.QuantityOrAmount.Quantity.Sign() > 0 {
|
} else if s.QuantityOrAmount.Quantity.Sign() > 0 {
|
||||||
newQuantity = s.QuantityOrAmount.Quantity
|
newQuantity = s.QuantityOrAmount.Quantity
|
||||||
|
@ -449,10 +444,6 @@ func (s *Strategy) processFilledOrder(o types.Order) {
|
||||||
profit = s.calculateProfit(o, newPrice, newQuantity)
|
profit = s.calculateProfit(o, newPrice, newQuantity)
|
||||||
|
|
||||||
case types.SideTypeBuy:
|
case types.SideTypeBuy:
|
||||||
if feeCurrency == s.Market.BaseCurrency {
|
|
||||||
newQuantity = newQuantity.Sub(feeQuantityReduction)
|
|
||||||
}
|
|
||||||
|
|
||||||
newSide = types.SideTypeSell
|
newSide = types.SideTypeSell
|
||||||
if !s.ProfitSpread.IsZero() {
|
if !s.ProfitSpread.IsZero() {
|
||||||
newPrice = newPrice.Add(s.ProfitSpread)
|
newPrice = newPrice.Add(s.ProfitSpread)
|
||||||
|
@ -462,9 +453,19 @@ func (s *Strategy) processFilledOrder(o types.Order) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if s.EarnBase {
|
if feeCurrency == s.Market.BaseCurrency {
|
||||||
newQuantity = fixedpoint.Max(orderExecutedQuoteAmount.Div(newPrice).Sub(feeQuantityReduction), s.Market.MinQuantity)
|
newQuantity = newQuantity.Sub(fee)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// if EarnBase is enabled, we should sell less to get the same quote amount back
|
||||||
|
if s.EarnBase {
|
||||||
|
newQuantity = fixedpoint.Max(orderExecutedQuoteAmount.Div(newPrice).Sub(fee), s.Market.MinQuantity)
|
||||||
|
}
|
||||||
|
|
||||||
|
// always round down the base quantity for placing sell order to avoid the base currency fund locking issue
|
||||||
|
origQuantity := newQuantity
|
||||||
|
newQuantity = newQuantity.Round(s.Market.VolumePrecision, fixedpoint.Down)
|
||||||
|
s.logger.Infof("round down sell order quantity %s to %s by base quantity precision %d", origQuantity.String(), newQuantity.String(), s.Market.VolumePrecision)
|
||||||
}
|
}
|
||||||
|
|
||||||
orderForm := types.SubmitOrder{
|
orderForm := types.SubmitOrder{
|
||||||
|
|
|
@ -706,7 +706,7 @@ func TestStrategy_handleOrderFilled(t *testing.T) {
|
||||||
Type: types.OrderTypeLimit,
|
Type: types.OrderTypeLimit,
|
||||||
Side: types.SideTypeBuy,
|
Side: types.SideTypeBuy,
|
||||||
Price: number(11_000.0),
|
Price: number(11_000.0),
|
||||||
Quantity: number(0.09999999),
|
Quantity: number(0.09999909),
|
||||||
TimeInForce: types.TimeInForceGTC,
|
TimeInForce: types.TimeInForceGTC,
|
||||||
Market: s.Market,
|
Market: s.Market,
|
||||||
Tag: orderTag,
|
Tag: orderTag,
|
||||||
|
@ -797,7 +797,7 @@ func TestStrategy_handleOrderFilled(t *testing.T) {
|
||||||
Symbol: "BTCUSDT",
|
Symbol: "BTCUSDT",
|
||||||
Type: types.OrderTypeLimit,
|
Type: types.OrderTypeLimit,
|
||||||
Price: number(12_000.0),
|
Price: number(12_000.0),
|
||||||
Quantity: number(0.09998999),
|
Quantity: number(0.09999),
|
||||||
Side: types.SideTypeSell,
|
Side: types.SideTypeSell,
|
||||||
TimeInForce: types.TimeInForceGTC,
|
TimeInForce: types.TimeInForceGTC,
|
||||||
Market: s.Market,
|
Market: s.Market,
|
||||||
|
|
Loading…
Reference in New Issue
Block a user