diff --git a/pkg/exchange/bitget/convert.go b/pkg/exchange/bitget/convert.go index f36da91655..2dda16d7a3 100644 --- a/pkg/exchange/bitget/convert.go +++ b/pkg/exchange/bitget/convert.go @@ -189,10 +189,17 @@ func unfilledOrderToGlobalOrder(order v2.UnfilledOrder) (*types.Order, error) { qty := order.Size price := order.PriceAvg - // The market order will be executed immediately, so this check is used to handle corner cases. + // 2023/11/05 The market order will be executed immediately, so this check is used to handle corner cases. + // 2024/03/06 After placing a Market Order, we can retrieve it through the unfilledOrder API, so we still need to + // handle the Market Order status. if orderType == types.OrderTypeMarket { - qty = order.BaseVolume - log.Warnf("!!! The price(%f) and quantity(%f) are not verified for market orders, because we only receive limit orders in the test environment !!!", price.Float64(), qty.Float64()) + price = order.PriceAvg + if side == types.SideTypeBuy { + qty, err = processMarketBuyQuantity(order.BaseVolume, order.QuoteVolume, order.PriceAvg, order.Size, order.Status) + if err != nil { + return nil, err + } + } } return &types.Order{ diff --git a/pkg/exchange/bitget/convert_test.go b/pkg/exchange/bitget/convert_test.go index dfab65af61..5aac971df0 100644 --- a/pkg/exchange/bitget/convert_test.go +++ b/pkg/exchange/bitget/convert_test.go @@ -227,7 +227,7 @@ func Test_unfilledOrderToGlobalOrder(t *testing.T) { } ) - t.Run("succeeds", func(t *testing.T) { + t.Run("succeeds with limit order", func(t *testing.T) { order, err := unfilledOrderToGlobalOrder(unfilledOrder) assert.NoError(err) assert.Equal(&types.Order{ @@ -251,6 +251,67 @@ func Test_unfilledOrderToGlobalOrder(t *testing.T) { }, order) }) + t.Run("succeeds with market buy order", func(t *testing.T) { + unfilledOrder2 := unfilledOrder + unfilledOrder2.OrderType = v2.OrderTypeMarket + unfilledOrder2.Side = v2.SideTypeBuy + unfilledOrder2.Size = unfilledOrder2.PriceAvg.Mul(unfilledOrder2.Size) + unfilledOrder2.PriceAvg = fixedpoint.Zero + unfilledOrder2.Status = v2.OrderStatusNew + + order, err := unfilledOrderToGlobalOrder(unfilledOrder2) + assert.NoError(err) + assert.Equal(&types.Order{ + SubmitOrder: types.SubmitOrder{ + ClientOrderID: "74b86af3-6098-479c-acac-bfb074c067f3", + Symbol: "BTCUSDT", + Side: types.SideTypeBuy, + Type: types.OrderTypeMarket, + Quantity: fixedpoint.Zero, + Price: fixedpoint.Zero, + TimeInForce: types.TimeInForceGTC, + }, + Exchange: types.ExchangeBitget, + OrderID: uint64(orderId), + UUID: strconv.FormatInt(int64(orderId), 10), + Status: types.OrderStatusNew, + ExecutedQuantity: fixedpoint.Zero, + IsWorking: true, + CreationTime: types.Time(types.NewMillisecondTimestampFromInt(1660704288118).Time()), + UpdateTime: types.Time(types.NewMillisecondTimestampFromInt(1660704288118).Time()), + }, order) + }) + + t.Run("succeeds with market sell order", func(t *testing.T) { + unfilledOrder2 := unfilledOrder + unfilledOrder2.OrderType = v2.OrderTypeMarket + unfilledOrder2.Side = v2.SideTypeSell + unfilledOrder2.PriceAvg = fixedpoint.Zero + unfilledOrder2.Status = v2.OrderStatusNew + + order, err := unfilledOrderToGlobalOrder(unfilledOrder2) + assert.NoError(err) + assert.Equal(&types.Order{ + SubmitOrder: types.SubmitOrder{ + ClientOrderID: "74b86af3-6098-479c-acac-bfb074c067f3", + Symbol: "BTCUSDT", + Side: types.SideTypeSell, + Type: types.OrderTypeMarket, + Quantity: fixedpoint.NewFromInt(5), + Price: fixedpoint.Zero, + TimeInForce: types.TimeInForceGTC, + }, + Exchange: types.ExchangeBitget, + OrderID: uint64(orderId), + UUID: strconv.FormatInt(int64(orderId), 10), + Status: types.OrderStatusNew, + ExecutedQuantity: fixedpoint.Zero, + IsWorking: true, + CreationTime: types.Time(types.NewMillisecondTimestampFromInt(1660704288118).Time()), + UpdateTime: types.Time(types.NewMillisecondTimestampFromInt(1660704288118).Time()), + }, order) + }) + t.Run("failed to convert side", func(t *testing.T) { newOrder := unfilledOrder newOrder.Side = "xxx" diff --git a/pkg/exchange/bitget/exchange.go b/pkg/exchange/bitget/exchange.go index 254cbd5197..bdda2c6561 100644 --- a/pkg/exchange/bitget/exchange.go +++ b/pkg/exchange/bitget/exchange.go @@ -362,10 +362,12 @@ func (e *Exchange) SubmitOrder(ctx context.Context, order types.SubmitOrder) (cr debugf("unfilled order response for order#%s: %+v", orderId, ordersResp) if len(ordersResp) == 1 { + // 2023/11/05 The market order will be executed immediately, so we cannot retrieve it through the NewGetUnfilledOrdersRequest API. + // Try to get the order from the NewGetHistoryOrdersRequest API. + // 2024/03/06 After placing a Market Order, we can retrieve it through the unfilledOrder API, so we still need to + // handle the Market Order status. return unfilledOrderToGlobalOrder(ordersResp[0]) } else if len(ordersResp) == 0 { - // The market order will be executed immediately, so we cannot retrieve it through the NewGetUnfilledOrdersRequest API. - // Try to get the order from the NewGetHistoryOrdersRequest API. ordersResp, err := e.v2client.NewGetHistoryOrdersRequest().OrderId(orderId).Do(ctx) if err != nil { return nil, fmt.Errorf("failed to query history order by order id: %s, err: %w", orderId, err)