Skip to content

Commit

Permalink
Merge pull request #1627 from c9s/kbearXD/grid/fee-processing
Browse files Browse the repository at this point in the history
FEATURE: [grid2] use feeProcessing field to make sure the trading fee…
  • Loading branch information
c9s authored Apr 30, 2024
2 parents 150366c + 38d8043 commit bf732ed
Show file tree
Hide file tree
Showing 5 changed files with 46 additions and 44 deletions.
14 changes: 1 addition & 13 deletions pkg/exchange/retry/order.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,6 @@ import (

"github.com/cenkalti/backoff/v4"

"github.com/c9s/bbgo/pkg/exchange/max"
maxapi "github.com/c9s/bbgo/pkg/exchange/max/maxapi"
"github.com/c9s/bbgo/pkg/types"
)

Expand Down Expand Up @@ -53,7 +51,6 @@ func QueryOrderUntilCanceled(
func QueryOrderUntilFilled(
ctx context.Context, queryOrderService types.ExchangeOrderQueryService, symbol string, orderId uint64,
) (o *types.Order, err error) {
_, isMax := queryOrderService.(*max.Exchange)
var op = func() (err2 error) {
o, err2 = queryOrderService.QueryOrder(ctx, types.OrderQuery{
Symbol: symbol,
Expand All @@ -70,16 +67,7 @@ func QueryOrderUntilFilled(

// for final status return nil error to stop the retry
switch o.Status {
case types.OrderStatusFilled:
if isMax {
// for MAX exchange, the order state done is filled but finalizing is not filled
if o.OriginalStatus == string(maxapi.OrderStateDone) {
return nil
}
} else {
return nil
}
case types.OrderStatusCanceled:
case types.OrderStatusFilled, types.OrderStatusCanceled:
return nil
}

Expand Down
42 changes: 42 additions & 0 deletions pkg/exchange/retry/trade.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
package retry

import (
"context"
"fmt"

"github.com/c9s/bbgo/pkg/types"
)

func QueryTradesUntilSuccessful(
ctx context.Context, ex types.ExchangeTradeHistoryService, symbol string, q *types.TradeQueryOptions,
) (trades []types.Trade, err error) {
var op = func() (err2 error) {
trades, err2 = ex.QueryTrades(ctx, symbol, q)
for _, trade := range trades {
if trade.FeeProcessing {
return fmt.Errorf("trade fee of #%d (order #%d) is still processing", trade.ID, trade.OrderID)
}
}
return err2
}

err = GeneralBackoff(ctx, op)
return trades, err
}

func QueryTradesUntilSuccessfulLite(
ctx context.Context, ex types.ExchangeTradeHistoryService, symbol string, q *types.TradeQueryOptions,
) (trades []types.Trade, err error) {
var op = func() (err2 error) {
trades, err2 = ex.QueryTrades(ctx, symbol, q)
for _, trade := range trades {
if trade.FeeProcessing {
return fmt.Errorf("trade fee of #%d (order #%d) is still processing", trade.ID, trade.OrderID)
}
}
return err2
}

err = GeneralLiteBackoff(ctx, op)
return trades, err
}
30 changes: 1 addition & 29 deletions pkg/strategy/grid2/grid_recover.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@ import (

"github.com/c9s/bbgo/pkg/bbgo"
"github.com/c9s/bbgo/pkg/exchange"
maxapi "github.com/c9s/bbgo/pkg/exchange/max/maxapi"
"github.com/c9s/bbgo/pkg/exchange/retry"
"github.com/c9s/bbgo/pkg/fixedpoint"
"github.com/c9s/bbgo/pkg/types"
Expand Down Expand Up @@ -72,33 +71,6 @@ func (s *Strategy) recoverByScanningTrades(ctx context.Context, session *bbgo.Ex
// add open orders into avtive maker orders
s.addOrdersToActiveOrderBook(openOrders)

// following is for MAX
if isMax {
var doneOrders []types.Order
for _, filledOrder := range filledOrders {
if filledOrder.OriginalStatus != string(maxapi.OrderStateDone) {
order, err := retry.QueryOrderUntilFilled(ctx, s.orderQueryService, filledOrder.Symbol, filledOrder.OrderID)
if err != nil {
return errors.Wrap(err, "unable to query orders until filled, please check it")
}

if order == nil {
return fmt.Errorf("after QueryOrderUntilFilled, order and error are both nil. Please check it")
}

doneOrders = append(doneOrders, *order)
} else {
doneOrders = append(doneOrders, filledOrder)
}
}

if len(filledOrders) != len(doneOrders) {
return fmt.Errorf("num of filled orders (%d) and num of done orders (%d) should be the same", len(filledOrders), len(doneOrders))
}

filledOrders = doneOrders
}

// emit the filled orders
activeOrderBook := s.orderExecutor.ActiveMakerOrders()
for _, filledOrder := range filledOrders {
Expand Down Expand Up @@ -298,7 +270,7 @@ func (s *Strategy) queryTradesToUpdateTwinOrdersMap(ctx context.Context, queryTr
var fromTradeID uint64 = 0
var limit int64 = 1000
for {
trades, err := queryTradesService.QueryTrades(ctx, s.Symbol, &types.TradeQueryOptions{
trades, err := retry.QueryTradesUntilSuccessful(ctx, queryTradesService, s.Symbol, &types.TradeQueryOptions{
StartTime: &since,
EndTime: &until,
LastTradeID: fromTradeID,
Expand Down
2 changes: 1 addition & 1 deletion pkg/strategy/grid2/recover.go
Original file line number Diff line number Diff line change
Expand Up @@ -317,7 +317,7 @@ func queryTradesToUpdateTwinOrderBook(
var fromTradeID uint64 = 0
var limit int64 = 1000
for {
trades, err := queryTradesService.QueryTrades(ctx, symbol, &types.TradeQueryOptions{
trades, err := retry.QueryTradesUntilSuccessful(ctx, queryTradesService, symbol, &types.TradeQueryOptions{
StartTime: &since,
EndTime: &until,
LastTradeID: fromTradeID,
Expand Down
2 changes: 1 addition & 1 deletion pkg/strategy/grid2/strategy.go
Original file line number Diff line number Diff line change
Expand Up @@ -417,7 +417,7 @@ func (s *Strategy) aggregateOrderQuoteAmountAndFee(o types.Order) (fixedpoint.Va
s.logger.Warnf("GRID: missing #%d order trades or missing trade fee, pulling order trades from API", o.OrderID)

// if orderQueryService is supported, use it to query the trades of the filled order
apiOrderTrades, err := s.orderQueryService.QueryOrderTrades(context.Background(), types.OrderQuery{
apiOrderTrades, err := retry.QueryOrderTradesUntilSuccessful(context.Background(), s.orderQueryService, types.OrderQuery{
Symbol: o.Symbol,
OrderID: strconv.FormatUint(o.OrderID, 10),
})
Expand Down

0 comments on commit bf732ed

Please sign in to comment.