@@ -401,25 +401,14 @@ func (s *Strategy) processFilledOrder(o types.Order) {
401
401
// will be used for calculating quantity
402
402
orderExecutedQuoteAmount := o .Quantity .Mul (executedPrice )
403
403
404
- // collect trades
405
- feeQuantityReduction := fixedpoint .Zero
406
- feeCurrency := ""
407
- feePrec := 2
408
-
409
- // feeQuantityReduction calculation is used to reduce the order quantity
404
+ // collect trades for fee
405
+ // fee calculation is used to reduce the order quantity
410
406
// because when 1.0 BTC buy order is filled without FEE token, then we will actually get 1.0 * (1 - feeRate) BTC
411
407
// if we don't reduce the sell quantity, than we might fail to place the sell order
412
- feeQuantityReduction , feeCurrency = s .aggregateOrderFee (o )
408
+ fee , feeCurrency : = s .aggregateOrderFee (o )
413
409
s .logger .Infof ("GRID ORDER #%d %s FEE: %s %s" ,
414
410
o .OrderID , o .Side ,
415
- feeQuantityReduction .String (), feeCurrency )
416
-
417
- feeQuantityReduction , feePrec = roundUpMarketQuantity (s .Market , feeQuantityReduction , feeCurrency )
418
- s .logger .Infof ("GRID ORDER #%d %s FEE (rounding precision %d): %s %s" ,
419
- o .OrderID , o .Side ,
420
- feePrec ,
421
- feeQuantityReduction .String (),
422
- feeCurrency )
411
+ fee .String (), feeCurrency )
423
412
424
413
switch o .Side {
425
414
case types .SideTypeSell :
@@ -437,9 +426,15 @@ func (s *Strategy) processFilledOrder(o types.Order) {
437
426
if s .Compound || s .EarnBase {
438
427
// if it's not using the platform fee currency, reduce the quote quantity for the buy order
439
428
if feeCurrency == s .Market .QuoteCurrency {
440
- orderExecutedQuoteAmount = orderExecutedQuoteAmount .Sub (feeQuantityReduction )
429
+ orderExecutedQuoteAmount = orderExecutedQuoteAmount .Sub (fee )
441
430
}
442
431
432
+ // for quote amount, always round down with price precision to prevent the quote currency fund locking rounding issue
433
+ origQuoteAmount := orderExecutedQuoteAmount
434
+ orderExecutedQuoteAmount = orderExecutedQuoteAmount .Round (s .Market .PricePrecision , fixedpoint .Down )
435
+
436
+ s .logger .Infof ("round down buy order quote quantity %s to %s by quote quantity precision %d" , origQuoteAmount .String (), orderExecutedQuoteAmount .String (), s .Market .PricePrecision )
437
+
443
438
newQuantity = fixedpoint .Max (orderExecutedQuoteAmount .Div (newPrice ), s .Market .MinQuantity )
444
439
} else if s .QuantityOrAmount .Quantity .Sign () > 0 {
445
440
newQuantity = s .QuantityOrAmount .Quantity
@@ -449,10 +444,6 @@ func (s *Strategy) processFilledOrder(o types.Order) {
449
444
profit = s .calculateProfit (o , newPrice , newQuantity )
450
445
451
446
case types .SideTypeBuy :
452
- if feeCurrency == s .Market .BaseCurrency {
453
- newQuantity = newQuantity .Sub (feeQuantityReduction )
454
- }
455
-
456
447
newSide = types .SideTypeSell
457
448
if ! s .ProfitSpread .IsZero () {
458
449
newPrice = newPrice .Add (s .ProfitSpread )
@@ -462,9 +453,19 @@ func (s *Strategy) processFilledOrder(o types.Order) {
462
453
}
463
454
}
464
455
456
+ if feeCurrency == s .Market .BaseCurrency {
457
+ newQuantity = newQuantity .Sub (fee )
458
+ }
459
+
460
+ // if EarnBase is enabled, we should sell less to get the same quote amount back
465
461
if s .EarnBase {
466
- newQuantity = fixedpoint .Max (orderExecutedQuoteAmount .Div (newPrice ).Sub (feeQuantityReduction ), s .Market .MinQuantity )
462
+ newQuantity = fixedpoint .Max (orderExecutedQuoteAmount .Div (newPrice ).Sub (fee ), s .Market .MinQuantity )
467
463
}
464
+
465
+ // always round down the base quantity for placing sell order to avoid the base currency fund locking issue
466
+ origQuantity := newQuantity
467
+ newQuantity = newQuantity .Round (s .Market .VolumePrecision , fixedpoint .Down )
468
+ s .logger .Infof ("round down sell order quantity %s to %s by base quantity precision %d" , origQuantity .String (), newQuantity .String (), s .Market .VolumePrecision )
468
469
}
469
470
470
471
orderForm := types.SubmitOrder {
@@ -1869,4 +1870,4 @@ func roundUpMarketQuantity(market types.Market, v fixedpoint.Value, c string) (f
1869
1870
}
1870
1871
1871
1872
return v .Round (prec , fixedpoint .Up ), prec
1872
- }
1873
+ }
0 commit comments