@@ -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,10 +426,21 @@ 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
443
- newQuantity = fixedpoint .Max (orderExecutedQuoteAmount .Div (newPrice ), s .Market .MinQuantity )
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
+ s .logger .Infof ("round down %s %s order quote quantity %s to %s by quote precision %d" , s .Symbol , newSide , origQuoteAmount .String (), orderExecutedQuoteAmount .String (), s .Market .PricePrecision )
436
+
437
+ newQuantity = orderExecutedQuoteAmount .Div (newPrice )
438
+
439
+ origQuantity := newQuantity
440
+ newQuantity = newQuantity .Round (s .Market .VolumePrecision , fixedpoint .Down )
441
+ s .logger .Infof ("round down %s %s order base quantity %s to %s by base precision %d" , s .Symbol , newSide , origQuantity .String (), newQuantity .String (), s .Market .VolumePrecision )
442
+
443
+ newQuantity = fixedpoint .Max (newQuantity , s .Market .MinQuantity )
444
444
} else if s .QuantityOrAmount .Quantity .Sign () > 0 {
445
445
newQuantity = s .QuantityOrAmount .Quantity
446
446
}
@@ -449,10 +449,6 @@ func (s *Strategy) processFilledOrder(o types.Order) {
449
449
profit = s .calculateProfit (o , newPrice , newQuantity )
450
450
451
451
case types .SideTypeBuy :
452
- if feeCurrency == s .Market .BaseCurrency {
453
- newQuantity = newQuantity .Sub (feeQuantityReduction )
454
- }
455
-
456
452
newSide = types .SideTypeSell
457
453
if ! s .ProfitSpread .IsZero () {
458
454
newPrice = newPrice .Add (s .ProfitSpread )
@@ -462,9 +458,19 @@ func (s *Strategy) processFilledOrder(o types.Order) {
462
458
}
463
459
}
464
460
461
+ if feeCurrency == s .Market .BaseCurrency {
462
+ newQuantity = newQuantity .Sub (fee )
463
+ }
464
+
465
+ // if EarnBase is enabled, we should sell less to get the same quote amount back
465
466
if s .EarnBase {
466
- newQuantity = fixedpoint .Max (orderExecutedQuoteAmount .Div (newPrice ).Sub (feeQuantityReduction ), s .Market .MinQuantity )
467
+ newQuantity = fixedpoint .Max (orderExecutedQuoteAmount .Div (newPrice ).Sub (fee ), s .Market .MinQuantity )
467
468
}
469
+
470
+ // always round down the base quantity for placing sell order to avoid the base currency fund locking issue
471
+ origQuantity := newQuantity
472
+ newQuantity = newQuantity .Round (s .Market .VolumePrecision , fixedpoint .Down )
473
+ s .logger .Infof ("round down sell order quantity %s to %s by base quantity precision %d" , origQuantity .String (), newQuantity .String (), s .Market .VolumePrecision )
468
474
}
469
475
470
476
orderForm := types.SubmitOrder {
@@ -1869,4 +1875,4 @@ func roundUpMarketQuantity(market types.Market, v fixedpoint.Value, c string) (f
1869
1875
}
1870
1876
1871
1877
return v .Round (prec , fixedpoint .Up ), prec
1872
- }
1878
+ }
0 commit comments