diff --git a/pkg/exchange/bitget/convert.go b/pkg/exchange/bitget/convert.go index 2dda16d7a..460eb4942 100644 --- a/pkg/exchange/bitget/convert.go +++ b/pkg/exchange/bitget/convert.go @@ -225,6 +225,27 @@ func unfilledOrderToGlobalOrder(order v2.UnfilledOrder) (*types.Order, error) { }, nil } +func fallbackPostOnlyOrder(order types.SubmitOrder, orderId string) (*types.Order, error) { + intOrderId, err := strconv.ParseUint(orderId, 10, 64) + if err != nil { + return nil, err + } + now := time.Now() + + return &types.Order{ + SubmitOrder: order, + Exchange: types.ExchangeBitget, + OrderID: intOrderId, + UUID: orderId, + Status: types.OrderStatusNew, + OriginalStatus: "FALLBACK_STATUS", + ExecutedQuantity: fixedpoint.Zero, + IsWorking: true, + CreationTime: types.Time(now), + UpdateTime: types.Time(now), + }, nil +} + func toGlobalOrder(order v2.OrderDetail) (*types.Order, error) { side, err := toGlobalSideType(order.Side) if err != nil { diff --git a/pkg/exchange/bitget/exchange.go b/pkg/exchange/bitget/exchange.go index fde9a0999..e70b8a27f 100644 --- a/pkg/exchange/bitget/exchange.go +++ b/pkg/exchange/bitget/exchange.go @@ -378,6 +378,14 @@ func (e *Exchange) SubmitOrder(ctx context.Context, order types.SubmitOrder) (cr } if len(ordersResp) != 1 { + // 2023/03/12 If it's a maker order and there is a corresponding order to be executed, then the order will be canceled, + // you can receive the status immediately from the websocket, but the RestAPI requires at least 200ms waiting time. + // + // Therefore, We don't want to waste time waiting for him, so we choose to manually enter the order + // information and send it back. + if order.Type == types.OrderTypeLimitMaker { + return fallbackPostOnlyOrder(order, orderId) + } return nil, fmt.Errorf("unexpected length of history orders, expecting: 1, given: %d, ids: %s", len(ordersResp), orderId) } diff --git a/pkg/exchange/bitget/exchange_test.go b/pkg/exchange/bitget/exchange_test.go index 565121e18..389df54f8 100644 --- a/pkg/exchange/bitget/exchange_test.go +++ b/pkg/exchange/bitget/exchange_test.go @@ -646,6 +646,14 @@ func TestExchange_SubmitOrder(t *testing.T) { }) t.Run("Limit Maker order", func(t *testing.T) { + emptyApiResp := v2.APIResponse{ + Code: "00000", + Message: "", + Data: nil, + } + rawEmptyApiResp, err := json.Marshal(emptyApiResp) + assert.NoError(err) + transport := &httptesting.MockTransport{} ex.client.HttpClient.Transport = transport @@ -672,22 +680,36 @@ func TestExchange_SubmitOrder(t *testing.T) { return httptesting.BuildResponseString(http.StatusOK, string(placeOrderFile)), nil }) - unfilledFile, err := os.ReadFile("bitgetapi/v2/testdata/get_unfilled_orders_request_limit_order.json") - assert.NoError(err) - transport.GET(openOrderUrl, func(req *http.Request) (*http.Response, error) { query := req.URL.Query() assert.Len(query, 1) assert.Contains(query, "orderId") assert.Equal(query["orderId"], []string{strconv.FormatUint(expOrder.OrderID, 10)}) - return httptesting.BuildResponseString(http.StatusOK, string(unfilledFile)), nil + return httptesting.BuildResponseString(http.StatusOK, string(rawEmptyApiResp)), nil + }) + + transport.GET(historyOrderUrl, func(req *http.Request) (*http.Response, error) { + query := req.URL.Query() + assert.Len(query, 1) + assert.Contains(query, "orderId") + assert.Equal(query["orderId"], []string{strconv.FormatUint(expOrder.OrderID, 10)}) + return httptesting.BuildResponseString(http.StatusOK, string(rawEmptyApiResp)), nil }) reqLimitOrder2 := reqLimitOrder reqLimitOrder2.Type = types.OrderTypeLimitMaker acct, err := ex.SubmitOrder(context.Background(), reqLimitOrder2) assert.NoError(err) - assert.Equal(expOrder, acct) + + expOrder2 := *expOrder + expOrder2.OriginalStatus = "FALLBACK_STATUS" + expOrder2.Status = types.OrderStatusNew + expOrder2.IsWorking = true + expOrder2.Type = types.OrderTypeLimitMaker + expOrder2.SubmitOrder = reqLimitOrder2 + acct.CreationTime = expOrder2.CreationTime + acct.UpdateTime = expOrder2.UpdateTime + assert.Equal(&expOrder2, acct) }) t.Run("Market order", func(t *testing.T) {