mirror of
https://github.com/d0zingcat/gocryptotrader.git
synced 2026-05-13 15:09:42 +00:00
exchanges/order, GateIO: Update USDT margined futures pathway for cancel all orders (#2021)
* order/gateio: update USDT margined futures pathway for cancel all orders and drop count field * gateio: add and expand tests for CancelAllOrders and getExchangeSide * Add test for load * linter: fix * Update exchanges/kraken/kraken_wrapper.go Co-authored-by: Scott <gloriousCode@users.noreply.github.com> * glorious: nits * Update exchanges/order/orders.go Co-authored-by: Gareth Kirwan <gbjkirwan@gmail.com> * gk: nits * glorious: nits * reverted change for options * Update exchanges/gateio/gateio_wrapper_test.go Co-authored-by: Scott <gloriousCode@users.noreply.github.com> * Update exchanges/gateio/gateio_wrapper.go Co-authored-by: Gareth Kirwan <gbjkirwan@gmail.com> * Update exchanges/deribit/deribit_wrapper.go Co-authored-by: Gareth Kirwan <gbjkirwan@gmail.com> * Update exchanges/gateio/gateio_wrapper_test.go Co-authored-by: Gareth Kirwan <gbjkirwan@gmail.com> * Update exchanges/gateio/gateio_wrapper_test.go Co-authored-by: Gareth Kirwan <gbjkirwan@gmail.com> * Add consts for cancel side references * Update exchanges/gateio/gateio_wrapper.go Co-authored-by: Adrian Gallagher <adrian.gallagher@thrasher.io> * Update exchanges/gateio/gateio_wrapper.go Co-authored-by: Adrian Gallagher <adrian.gallagher@thrasher.io> * Update exchanges/gateio/gateio_websocket_request_futures.go Co-authored-by: Adrian Gallagher <adrian.gallagher@thrasher.io> * thrasher-: nits --------- Co-authored-by: Ryan O'Hara-Reid <ryan.oharareid@thrasher.io> Co-authored-by: Scott <gloriousCode@users.noreply.github.com> Co-authored-by: Gareth Kirwan <gbjkirwan@gmail.com> Co-authored-by: Adrian Gallagher <adrian.gallagher@thrasher.io>
This commit is contained in:
@@ -693,17 +693,18 @@ func (e *Exchange) CancelBatchOrders(_ context.Context, _ []order.Cancel) (*orde
|
||||
}
|
||||
|
||||
// CancelAllOrders cancels all orders associated with a currency pair
|
||||
func (e *Exchange) CancelAllOrders(ctx context.Context, orderCancellation *order.Cancel) (order.CancelAllResponse, error) {
|
||||
if err := orderCancellation.Validate(); err != nil {
|
||||
return order.CancelAllResponse{}, err
|
||||
func (e *Exchange) CancelAllOrders(ctx context.Context, cancel *order.Cancel) (order.CancelAllResponse, error) {
|
||||
var resp order.CancelAllResponse
|
||||
if err := cancel.Validate(); err != nil {
|
||||
return resp, err
|
||||
}
|
||||
var cancelData *MultipleCancelResponse
|
||||
pairFmt, err := e.GetPairFormat(orderCancellation.AssetType, true)
|
||||
|
||||
fPair, err := e.FormatExchangeCurrency(cancel.Pair, cancel.AssetType)
|
||||
if err != nil {
|
||||
return order.CancelAllResponse{}, err
|
||||
return resp, err
|
||||
}
|
||||
var orderTypeStr string
|
||||
switch orderCancellation.Type {
|
||||
switch cancel.Type {
|
||||
case order.Limit:
|
||||
orderTypeStr = order.Limit.String()
|
||||
case order.Market:
|
||||
@@ -711,26 +712,24 @@ func (e *Exchange) CancelAllOrders(ctx context.Context, orderCancellation *order
|
||||
case order.AnyType, order.UnknownType:
|
||||
orderTypeStr = "all"
|
||||
default:
|
||||
return order.CancelAllResponse{}, fmt.Errorf("%s: orderType %v is not valid", e.Name, orderCancellation.Type)
|
||||
return resp, fmt.Errorf("%s %w: %v", e.Name, order.ErrTypeIsInvalid, cancel.Type)
|
||||
}
|
||||
|
||||
var cancelData *MultipleCancelResponse
|
||||
if e.Websocket.IsConnected() && e.Websocket.CanUseAuthenticatedWebsocketForWrapper() {
|
||||
cancelData, err = e.WSSubmitCancelAllByInstrument(ctx, pairFmt.Format(orderCancellation.Pair), orderTypeStr, true, true)
|
||||
cancelData, err = e.WSSubmitCancelAllByInstrument(ctx, fPair.String(), orderTypeStr, true, true)
|
||||
} else {
|
||||
cancelData, err = e.SubmitCancelAllByInstrument(ctx, pairFmt.Format(orderCancellation.Pair), orderTypeStr, true, true)
|
||||
cancelData, err = e.SubmitCancelAllByInstrument(ctx, fPair.String(), orderTypeStr, true, true)
|
||||
}
|
||||
if err != nil {
|
||||
return order.CancelAllResponse{}, err
|
||||
return resp, err
|
||||
}
|
||||
response := order.CancelAllResponse{Count: cancelData.CancelCount}
|
||||
if len(cancelData.CancelDetails) > 0 {
|
||||
response.Status = make(map[string]string)
|
||||
for a := range cancelData.CancelDetails {
|
||||
for b := range cancelData.CancelDetails[a].Result {
|
||||
response.Status[cancelData.CancelDetails[a].Result[b].OrderID] = cancelData.CancelDetails[a].Result[b].OrderState
|
||||
}
|
||||
for a := range cancelData.CancelDetails {
|
||||
for b := range cancelData.CancelDetails[a].Result {
|
||||
resp.Add(cancelData.CancelDetails[a].Result[b].OrderID, cancelData.CancelDetails[a].Result[b].OrderState)
|
||||
}
|
||||
}
|
||||
return response, nil
|
||||
return resp, nil
|
||||
}
|
||||
|
||||
// GetOrderInfo returns order information based on order ID
|
||||
|
||||
@@ -2820,7 +2820,7 @@ func (e *Exchange) CancelMultipleDeliveryOrders(ctx context.Context, contract cu
|
||||
return nil, fmt.Errorf("%w, currency pair for contract must not be empty", errInvalidOrMissingContractParam)
|
||||
}
|
||||
params := url.Values{}
|
||||
if side == "ask" || side == "bid" {
|
||||
if side == order.Ask.Lower() || side == order.Bid.Lower() {
|
||||
params.Set("side", side)
|
||||
}
|
||||
params.Set("contract", contract.String())
|
||||
|
||||
@@ -66,29 +66,6 @@ func TestUpdateTradablePairs(t *testing.T) {
|
||||
testexch.UpdatePairsOnce(t, e)
|
||||
}
|
||||
|
||||
func TestCancelAllExchangeOrders(t *testing.T) {
|
||||
t.Parallel()
|
||||
sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders)
|
||||
_, err := e.CancelAllOrders(t.Context(), nil)
|
||||
require.ErrorIs(t, err, order.ErrCancelOrderIsNil)
|
||||
|
||||
r := &order.Cancel{
|
||||
OrderID: "1",
|
||||
AccountID: "1",
|
||||
}
|
||||
|
||||
for _, a := range e.GetAssetTypes(false) {
|
||||
r.AssetType = a
|
||||
r.Pair = currency.EMPTYPAIR
|
||||
_, err = e.CancelAllOrders(t.Context(), r)
|
||||
assert.ErrorIs(t, err, currency.ErrCurrencyPairEmpty)
|
||||
|
||||
r.Pair = getPair(t, a)
|
||||
_, err = e.CancelAllOrders(t.Context(), r)
|
||||
require.NoError(t, err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestGetAccountInfo(t *testing.T) {
|
||||
t.Parallel()
|
||||
sharedtestvalues.SkipTestIfCredentialsUnset(t, e)
|
||||
|
||||
@@ -80,7 +80,7 @@ func (e *Exchange) WebsocketFuturesCancelAllOpenFuturesOrders(ctx context.Contex
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if side != "" && side != "ask" && side != "bid" {
|
||||
if side != "" && side != order.Ask.Lower() && side != order.Bid.Lower() {
|
||||
return nil, fmt.Errorf("%w: %s", order.ErrSideIsInvalid, side)
|
||||
}
|
||||
|
||||
|
||||
@@ -31,10 +31,10 @@ func TestWebsocketFuturesSubmitOrder(t *testing.T) {
|
||||
|
||||
sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders)
|
||||
|
||||
g := newExchangeWithWebsocket(t, asset.Futures)
|
||||
e := newExchangeWithWebsocket(t, asset.USDTMarginedFutures) //nolint:govet // Intentional shadow
|
||||
out.AutoSize = ""
|
||||
|
||||
got, err := g.WebsocketFuturesSubmitOrder(t.Context(), asset.USDTMarginedFutures, out)
|
||||
got, err := e.WebsocketFuturesSubmitOrder(t.Context(), asset.USDTMarginedFutures, out)
|
||||
require.NoError(t, err)
|
||||
require.NotEmpty(t, got)
|
||||
}
|
||||
@@ -73,15 +73,15 @@ func TestWebsocketFuturesSubmitOrders(t *testing.T) {
|
||||
|
||||
sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders)
|
||||
|
||||
g := newExchangeWithWebsocket(t, asset.Futures)
|
||||
e := newExchangeWithWebsocket(t, asset.USDTMarginedFutures) //nolint:govet // Intentional shadow
|
||||
|
||||
// test single order
|
||||
got, err := g.WebsocketFuturesSubmitOrders(t.Context(), asset.CoinMarginedFutures, out)
|
||||
got, err := e.WebsocketFuturesSubmitOrders(t.Context(), asset.CoinMarginedFutures, out)
|
||||
require.NoError(t, err)
|
||||
require.NotEmpty(t, got)
|
||||
|
||||
// test batch orders
|
||||
got, err = g.WebsocketFuturesSubmitOrders(t.Context(), asset.CoinMarginedFutures, out, out)
|
||||
got, err = e.WebsocketFuturesSubmitOrders(t.Context(), asset.CoinMarginedFutures, out, out)
|
||||
require.NoError(t, err)
|
||||
require.NotEmpty(t, got)
|
||||
}
|
||||
@@ -99,9 +99,9 @@ func TestWebsocketFuturesCancelOrder(t *testing.T) {
|
||||
|
||||
sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders)
|
||||
|
||||
g := newExchangeWithWebsocket(t, asset.Futures)
|
||||
e := newExchangeWithWebsocket(t, asset.USDTMarginedFutures) //nolint:govet // Intentional shadow
|
||||
|
||||
got, err := g.WebsocketFuturesCancelOrder(t.Context(), "513160761072", BTCUSDT, asset.USDTMarginedFutures)
|
||||
got, err := e.WebsocketFuturesCancelOrder(t.Context(), "513160761072", BTCUSDT, asset.USDTMarginedFutures)
|
||||
require.NoError(t, err)
|
||||
require.NotEmpty(t, got)
|
||||
}
|
||||
@@ -119,9 +119,9 @@ func TestWebsocketFuturesCancelAllOpenFuturesOrders(t *testing.T) {
|
||||
|
||||
sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders)
|
||||
|
||||
g := newExchangeWithWebsocket(t, asset.Futures)
|
||||
e := newExchangeWithWebsocket(t, asset.USDTMarginedFutures) //nolint:govet // Intentional shadow
|
||||
|
||||
got, err := g.WebsocketFuturesCancelAllOpenFuturesOrders(t.Context(), BTCUSDT, asset.USDTMarginedFutures, "bid")
|
||||
got, err := e.WebsocketFuturesCancelAllOpenFuturesOrders(t.Context(), BTCUSDT, asset.USDTMarginedFutures, order.Bid.Lower())
|
||||
require.NoError(t, err)
|
||||
require.NotEmpty(t, got)
|
||||
}
|
||||
@@ -151,10 +151,10 @@ func TestWebsocketFuturesAmendOrder(t *testing.T) {
|
||||
|
||||
sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders)
|
||||
|
||||
g := newExchangeWithWebsocket(t, asset.Futures)
|
||||
e := newExchangeWithWebsocket(t, asset.USDTMarginedFutures) //nolint:govet // Intentional shadow
|
||||
|
||||
amend.OrderID = "513170215869"
|
||||
got, err := g.WebsocketFuturesAmendOrder(t.Context(), amend)
|
||||
got, err := e.WebsocketFuturesAmendOrder(t.Context(), amend)
|
||||
require.NoError(t, err)
|
||||
require.NotEmpty(t, got)
|
||||
}
|
||||
@@ -178,10 +178,10 @@ func TestWebsocketFuturesOrderList(t *testing.T) {
|
||||
|
||||
sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders)
|
||||
|
||||
g := newExchangeWithWebsocket(t, asset.Futures)
|
||||
e := newExchangeWithWebsocket(t, asset.USDTMarginedFutures) //nolint:govet // Intentional shadow
|
||||
|
||||
list.Status = statusOpen
|
||||
got, err := g.WebsocketFuturesOrderList(t.Context(), list)
|
||||
got, err := e.WebsocketFuturesOrderList(t.Context(), list)
|
||||
require.NoError(t, err)
|
||||
require.NotEmpty(t, got)
|
||||
}
|
||||
@@ -199,9 +199,9 @@ func TestWebsocketFuturesGetOrderStatus(t *testing.T) {
|
||||
|
||||
sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders)
|
||||
|
||||
g := newExchangeWithWebsocket(t, asset.Futures)
|
||||
e := newExchangeWithWebsocket(t, asset.USDTMarginedFutures) //nolint:govet // Intentional shadow
|
||||
|
||||
got, err := g.WebsocketFuturesGetOrderStatus(t.Context(), BTCUSDT, asset.USDTMarginedFutures, "513170215869")
|
||||
got, err := e.WebsocketFuturesGetOrderStatus(t.Context(), BTCUSDT, asset.USDTMarginedFutures, "513170215869")
|
||||
require.NoError(t, err)
|
||||
require.NotEmpty(t, got)
|
||||
}
|
||||
|
||||
@@ -20,15 +20,15 @@ func TestWebsocketLogin(t *testing.T) {
|
||||
|
||||
sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders)
|
||||
|
||||
g := newExchangeWithWebsocket(t, asset.Spot)
|
||||
e := newExchangeWithWebsocket(t, asset.Spot) //nolint:govet // Intentional shadow
|
||||
|
||||
c, err := g.Websocket.GetConnection(asset.Spot)
|
||||
c, err := e.Websocket.GetConnection(asset.Spot)
|
||||
require.NoError(t, err)
|
||||
|
||||
err = g.websocketLogin(t.Context(), c, "")
|
||||
err = e.websocketLogin(t.Context(), c, "")
|
||||
require.ErrorIs(t, err, errChannelEmpty)
|
||||
|
||||
err = g.websocketLogin(t.Context(), c, "spot.login")
|
||||
err = e.websocketLogin(t.Context(), c, "spot.login")
|
||||
require.NoError(t, err)
|
||||
}
|
||||
|
||||
@@ -50,9 +50,9 @@ func TestWebsocketSpotSubmitOrder(t *testing.T) {
|
||||
|
||||
sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders)
|
||||
|
||||
g := newExchangeWithWebsocket(t, asset.Spot)
|
||||
e := newExchangeWithWebsocket(t, asset.Spot) //nolint:govet // Intentional shadow
|
||||
|
||||
got, err := g.WebsocketSpotSubmitOrder(t.Context(), out)
|
||||
got, err := e.WebsocketSpotSubmitOrder(t.Context(), out)
|
||||
require.NoError(t, err)
|
||||
require.NotEmpty(t, got)
|
||||
}
|
||||
@@ -78,15 +78,15 @@ func TestWebsocketSpotSubmitOrders(t *testing.T) {
|
||||
|
||||
sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders)
|
||||
|
||||
g := newExchangeWithWebsocket(t, asset.Spot)
|
||||
e := newExchangeWithWebsocket(t, asset.Spot) //nolint:govet // Intentional shadow
|
||||
|
||||
// test single order
|
||||
got, err := g.WebsocketSpotSubmitOrders(t.Context(), out)
|
||||
got, err := e.WebsocketSpotSubmitOrders(t.Context(), out)
|
||||
require.NoError(t, err)
|
||||
require.NotEmpty(t, got)
|
||||
|
||||
// test batch orders
|
||||
got, err = g.WebsocketSpotSubmitOrders(t.Context(), out, out)
|
||||
got, err = e.WebsocketSpotSubmitOrders(t.Context(), out, out)
|
||||
require.NoError(t, err)
|
||||
require.NotEmpty(t, got)
|
||||
}
|
||||
@@ -100,9 +100,9 @@ func TestWebsocketSpotCancelOrder(t *testing.T) {
|
||||
|
||||
sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders)
|
||||
|
||||
g := newExchangeWithWebsocket(t, asset.Spot)
|
||||
e := newExchangeWithWebsocket(t, asset.Spot) //nolint:govet // Intentional shadow
|
||||
|
||||
got, err := g.WebsocketSpotCancelOrder(t.Context(), "644913098758", BTCUSDT, "")
|
||||
got, err := e.WebsocketSpotCancelOrder(t.Context(), "644913098758", BTCUSDT, "")
|
||||
require.NoError(t, err)
|
||||
require.NotEmpty(t, got)
|
||||
}
|
||||
@@ -122,10 +122,10 @@ func TestWebsocketSpotCancelAllOrdersByIDs(t *testing.T) {
|
||||
|
||||
sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders)
|
||||
|
||||
g := newExchangeWithWebsocket(t, asset.Spot)
|
||||
e := newExchangeWithWebsocket(t, asset.Spot) //nolint:govet // Intentional shadow
|
||||
|
||||
out.OrderID = "644913101755"
|
||||
got, err := g.WebsocketSpotCancelAllOrdersByIDs(t.Context(), []WebsocketOrderBatchRequest{out})
|
||||
got, err := e.WebsocketSpotCancelAllOrdersByIDs(t.Context(), []WebsocketOrderBatchRequest{out})
|
||||
require.NoError(t, err)
|
||||
require.NotEmpty(t, got)
|
||||
}
|
||||
@@ -137,9 +137,9 @@ func TestWebsocketSpotCancelAllOrdersByPair(t *testing.T) {
|
||||
|
||||
sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders)
|
||||
|
||||
g := newExchangeWithWebsocket(t, asset.Spot)
|
||||
e := newExchangeWithWebsocket(t, asset.Spot) //nolint:govet // Intentional shadow
|
||||
|
||||
got, err := g.WebsocketSpotCancelAllOrdersByPair(t.Context(), currency.EMPTYPAIR, order.Buy, "")
|
||||
got, err := e.WebsocketSpotCancelAllOrdersByPair(t.Context(), currency.EMPTYPAIR, order.Buy, "")
|
||||
require.NoError(t, err)
|
||||
require.NotEmpty(t, got)
|
||||
}
|
||||
@@ -166,10 +166,10 @@ func TestWebsocketSpotAmendOrder(t *testing.T) {
|
||||
|
||||
sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders)
|
||||
|
||||
g := newExchangeWithWebsocket(t, asset.Spot)
|
||||
e := newExchangeWithWebsocket(t, asset.Spot) //nolint:govet // Intentional shadow
|
||||
|
||||
amend.OrderID = "645029162673"
|
||||
got, err := g.WebsocketSpotAmendOrder(t.Context(), amend)
|
||||
got, err := e.WebsocketSpotAmendOrder(t.Context(), amend)
|
||||
require.NoError(t, err)
|
||||
require.NotEmpty(t, got)
|
||||
}
|
||||
@@ -185,9 +185,9 @@ func TestWebsocketSpotGetOrderStatus(t *testing.T) {
|
||||
sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders)
|
||||
|
||||
testexch.UpdatePairsOnce(t, e)
|
||||
g := newExchangeWithWebsocket(t, asset.Spot)
|
||||
e := newExchangeWithWebsocket(t, asset.Spot) //nolint:govet // Intentional shadow
|
||||
|
||||
got, err := g.WebsocketSpotGetOrderStatus(t.Context(), "644999650452", BTCUSDT, "")
|
||||
got, err := e.WebsocketSpotGetOrderStatus(t.Context(), "644999650452", BTCUSDT, "")
|
||||
require.NoError(t, err)
|
||||
require.NotEmpty(t, got)
|
||||
}
|
||||
@@ -206,30 +206,6 @@ func newExchangeWithWebsocket(t *testing.T, a asset.Item) *Exchange {
|
||||
e.API.AuthenticatedWebsocketSupport = true
|
||||
e.SetCredentials(apiKey, apiSecret, "", "", "", "")
|
||||
e.Websocket.SetCanUseAuthenticatedEndpoints(true)
|
||||
switch a {
|
||||
case asset.Spot:
|
||||
avail, err := e.GetAvailablePairs(a)
|
||||
require.NoError(t, err)
|
||||
if len(avail) > 1 { // reduce pairs to 1 to speed up tests
|
||||
avail = avail[:1]
|
||||
}
|
||||
require.NoError(t, e.SetPairs(avail, a, true))
|
||||
case asset.Futures:
|
||||
avail, err := e.GetAvailablePairs(a)
|
||||
require.NoError(t, err)
|
||||
usdtPairs, err := avail.GetPairsByQuote(currency.USDT) // Get USDT margin pairs
|
||||
require.NoError(t, err)
|
||||
btcPairs, err := avail.GetPairsByQuote(currency.USD) // Get BTC margin pairs
|
||||
require.NoError(t, err)
|
||||
// below makes sure there is both a USDT and BTC pair available
|
||||
// so that allows two connections to be made.
|
||||
avail[0] = usdtPairs[0]
|
||||
avail[1] = btcPairs[0]
|
||||
avail = avail[:2]
|
||||
require.NoError(t, e.SetPairs(avail, a, true))
|
||||
default:
|
||||
require.NoError(t, e.CurrencyPairs.SetAssetEnabled(a, false))
|
||||
}
|
||||
|
||||
// Disable all other asset types to ensure only the specified asset type is used for websocket tests.
|
||||
for _, enabled := range e.GetAssetTypes(true) {
|
||||
|
||||
@@ -1124,65 +1124,73 @@ func (e *Exchange) CancelBatchOrders(ctx context.Context, o []order.Cancel) (*or
|
||||
|
||||
// CancelAllOrders cancels all orders associated with a currency pair
|
||||
func (e *Exchange) CancelAllOrders(ctx context.Context, o *order.Cancel) (order.CancelAllResponse, error) {
|
||||
err := o.Validate()
|
||||
if err != nil {
|
||||
return order.CancelAllResponse{}, err
|
||||
var resp order.CancelAllResponse
|
||||
if err := o.Validate(); err != nil {
|
||||
return resp, err
|
||||
}
|
||||
var cancelAllOrdersResponse order.CancelAllResponse
|
||||
cancelAllOrdersResponse.Status = map[string]string{}
|
||||
|
||||
fmtPair, err := e.FormatExchangeCurrency(o.Pair, o.AssetType)
|
||||
if err != nil {
|
||||
return resp, err
|
||||
}
|
||||
|
||||
var side string
|
||||
switch {
|
||||
case o.Side.IsLong():
|
||||
side = order.Bid.Lower()
|
||||
case o.Side.IsShort():
|
||||
side = order.Ask.Lower()
|
||||
case o.Side == order.UnknownSide, o.Side == order.AnySide:
|
||||
default:
|
||||
return resp, fmt.Errorf("%w: %q", order.ErrSideIsInvalid, o.Side)
|
||||
}
|
||||
|
||||
switch o.AssetType {
|
||||
case asset.Spot, asset.Margin, asset.CrossMargin:
|
||||
if o.Pair.IsEmpty() {
|
||||
return order.CancelAllResponse{}, currency.ErrCurrencyPairEmpty
|
||||
}
|
||||
var cancel []SpotPriceTriggeredOrder
|
||||
cancel, err = e.CancelMultipleSpotOpenOrders(ctx, o.Pair, o.AssetType)
|
||||
cancel, err := e.CancelMultipleSpotOpenOrders(ctx, fmtPair, o.AssetType)
|
||||
if err != nil {
|
||||
return cancelAllOrdersResponse, err
|
||||
return resp, err
|
||||
}
|
||||
for x := range cancel {
|
||||
cancelAllOrdersResponse.Status[strconv.FormatInt(cancel[x].AutoOrderID, 10)] = cancel[x].Status
|
||||
resp.Add(strconv.FormatInt(cancel[x].AutoOrderID, 10), cancel[x].Status)
|
||||
}
|
||||
case asset.CoinMarginedFutures, asset.USDTMarginedFutures, asset.DeliveryFutures:
|
||||
if o.Pair.IsEmpty() {
|
||||
return cancelAllOrdersResponse, currency.ErrCurrencyPairEmpty
|
||||
}
|
||||
settle, err := getSettlementCurrency(o.Pair, o.AssetType)
|
||||
settle, err := getSettlementCurrency(fmtPair, o.AssetType)
|
||||
if err != nil {
|
||||
return cancelAllOrdersResponse, err
|
||||
return resp, err
|
||||
}
|
||||
var cancel []Order
|
||||
if o.AssetType == asset.DeliveryFutures {
|
||||
cancel, err = e.CancelMultipleDeliveryOrders(ctx, o.Pair, o.Side.Lower(), settle)
|
||||
cancel, err = e.CancelMultipleDeliveryOrders(ctx, fmtPair, side, settle)
|
||||
} else {
|
||||
cancel, err = e.CancelMultipleFuturesOpenOrders(ctx, o.Pair, o.Side.Lower(), settle)
|
||||
cancel, err = e.CancelMultipleFuturesOpenOrders(ctx, fmtPair, side, settle)
|
||||
}
|
||||
if err != nil {
|
||||
return cancelAllOrdersResponse, err
|
||||
return resp, err
|
||||
}
|
||||
for f := range cancel {
|
||||
cancelAllOrdersResponse.Status[strconv.FormatInt(cancel[f].ID, 10)] = cancel[f].Status
|
||||
resp.Add(strconv.FormatInt(cancel[f].ID, 10), cancel[f].FinishAs)
|
||||
}
|
||||
case asset.Options:
|
||||
var underlying currency.Pair
|
||||
if !o.Pair.IsEmpty() {
|
||||
underlying, err = e.GetUnderlyingFromCurrencyPair(o.Pair)
|
||||
if err != nil {
|
||||
return cancelAllOrdersResponse, err
|
||||
return resp, err
|
||||
}
|
||||
}
|
||||
cancel, err := e.CancelMultipleOptionOpenOrders(ctx, o.Pair, underlying.String(), o.Side.Lower())
|
||||
cancel, err := e.CancelMultipleOptionOpenOrders(ctx, fmtPair, underlying.String(), side)
|
||||
if err != nil {
|
||||
return cancelAllOrdersResponse, err
|
||||
return resp, err
|
||||
}
|
||||
for x := range cancel {
|
||||
cancelAllOrdersResponse.Status[strconv.FormatInt(cancel[x].OptionOrderID, 10)] = cancel[x].Status
|
||||
resp.Add(strconv.FormatInt(cancel[x].OptionOrderID, 10), cancel[x].FinishAs)
|
||||
}
|
||||
default:
|
||||
return cancelAllOrdersResponse, fmt.Errorf("%w asset type: %v", asset.ErrNotSupported, o.AssetType)
|
||||
return resp, fmt.Errorf("%w asset type: %v", asset.ErrNotSupported, o.AssetType)
|
||||
}
|
||||
|
||||
return cancelAllOrdersResponse, nil
|
||||
return resp, nil
|
||||
}
|
||||
|
||||
// GetOrderInfo returns order information based on order ID
|
||||
@@ -2573,13 +2581,14 @@ func (e *Exchange) deriveFuturesWebsocketOrderResponses(responses []*WebsocketFu
|
||||
}
|
||||
|
||||
func (e *Exchange) getSpotOrderRequest(s *order.Submit) (*CreateOrderRequest, error) {
|
||||
var side string
|
||||
switch {
|
||||
case s.Side.IsLong():
|
||||
s.Side = order.Buy
|
||||
side = order.Buy.Lower()
|
||||
case s.Side.IsShort():
|
||||
s.Side = order.Sell
|
||||
side = order.Sell.Lower()
|
||||
default:
|
||||
return nil, order.ErrSideIsInvalid
|
||||
return nil, fmt.Errorf("%w: %q", order.ErrSideIsInvalid, s.Side)
|
||||
}
|
||||
|
||||
tif, err := toExchangeTIF(s.TimeInForce, s.Price)
|
||||
@@ -2588,7 +2597,7 @@ func (e *Exchange) getSpotOrderRequest(s *order.Submit) (*CreateOrderRequest, er
|
||||
}
|
||||
|
||||
return &CreateOrderRequest{
|
||||
Side: s.Side.Lower(),
|
||||
Side: side,
|
||||
Type: s.Type.Lower(),
|
||||
Account: e.assetTypeToString(s.AssetType),
|
||||
Amount: types.Number(s.GetTradeAmount(e.GetTradingRequirements())),
|
||||
|
||||
73
exchanges/gateio/gateio_wrapper_test.go
Normal file
73
exchanges/gateio/gateio_wrapper_test.go
Normal file
@@ -0,0 +1,73 @@
|
||||
package gateio
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
"github.com/thrasher-corp/gocryptotrader/currency"
|
||||
"github.com/thrasher-corp/gocryptotrader/exchanges/asset"
|
||||
"github.com/thrasher-corp/gocryptotrader/exchanges/order"
|
||||
"github.com/thrasher-corp/gocryptotrader/exchanges/sharedtestvalues"
|
||||
)
|
||||
|
||||
func TestCancelAllOrders(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
_, err := e.CancelAllOrders(t.Context(), nil)
|
||||
require.ErrorIs(t, err, order.ErrCancelOrderIsNil)
|
||||
|
||||
_, err = e.CancelAllOrders(t.Context(), &order.Cancel{Pair: currency.EMPTYPAIR, AssetType: 1336})
|
||||
require.ErrorIs(t, err, currency.ErrCurrencyPairEmpty)
|
||||
|
||||
_, err = e.CancelAllOrders(t.Context(), &order.Cancel{Pair: currency.NewBTCUSDT(), AssetType: 1336})
|
||||
require.ErrorIs(t, err, asset.ErrNotSupported)
|
||||
|
||||
_, err = e.CancelAllOrders(t.Context(), &order.Cancel{
|
||||
Pair: currency.NewBTCUSDT(),
|
||||
AssetType: asset.Options,
|
||||
Side: order.ClosePosition,
|
||||
})
|
||||
require.ErrorIs(t, err, order.ErrSideIsInvalid)
|
||||
|
||||
_, err = e.CancelAllOrders(t.Context(), &order.Cancel{
|
||||
Pair: currency.NewPair(currency.BTC, currency.EMPTYCODE),
|
||||
AssetType: asset.USDTMarginedFutures,
|
||||
Side: order.Long,
|
||||
})
|
||||
require.ErrorIs(t, err, errInvalidSettlementQuote)
|
||||
|
||||
_, err = e.CancelAllOrders(t.Context(), &order.Cancel{
|
||||
Pair: currency.NewPair(currency.BTC, currency.EMPTYCODE),
|
||||
AssetType: asset.USDTMarginedFutures,
|
||||
Side: order.Short,
|
||||
})
|
||||
require.ErrorIs(t, err, errInvalidSettlementQuote)
|
||||
|
||||
_, err = e.CancelAllOrders(t.Context(), &order.Cancel{
|
||||
Pair: currency.NewPair(currency.BTC, currency.EMPTYCODE),
|
||||
AssetType: asset.USDTMarginedFutures,
|
||||
Side: order.AnySide,
|
||||
})
|
||||
require.ErrorIs(t, err, errInvalidSettlementQuote)
|
||||
|
||||
sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders)
|
||||
|
||||
for _, a := range e.GetAssetTypes(false) {
|
||||
t.Run(a.String(), func(t *testing.T) {
|
||||
t.Parallel()
|
||||
r := &order.Cancel{
|
||||
OrderID: "1",
|
||||
AccountID: "1",
|
||||
AssetType: a,
|
||||
Pair: currency.EMPTYPAIR,
|
||||
}
|
||||
_, err := e.CancelAllOrders(t.Context(), r)
|
||||
assert.ErrorIs(t, err, currency.ErrCurrencyPairEmpty)
|
||||
|
||||
r.Pair = getPair(t, a)
|
||||
_, err = e.CancelAllOrders(t.Context(), r)
|
||||
assert.NoError(t, err)
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -815,50 +815,48 @@ func (e *Exchange) CancelBatchOrders(ctx context.Context, o []order.Cancel) (*or
|
||||
|
||||
// CancelAllOrders cancels all orders associated with a currency pair
|
||||
func (e *Exchange) CancelAllOrders(ctx context.Context, req *order.Cancel) (order.CancelAllResponse, error) {
|
||||
var resp order.CancelAllResponse
|
||||
if err := req.Validate(); err != nil {
|
||||
return order.CancelAllResponse{}, err
|
||||
}
|
||||
cancelAllOrdersResponse := order.CancelAllResponse{
|
||||
Status: make(map[string]string),
|
||||
return resp, err
|
||||
}
|
||||
switch req.AssetType {
|
||||
case asset.Spot:
|
||||
if e.Websocket.CanUseAuthenticatedWebsocketForWrapper() {
|
||||
resp, err := e.wsCancelAllOrders(ctx)
|
||||
cancel, err := e.wsCancelAllOrders(ctx)
|
||||
if err != nil {
|
||||
return cancelAllOrdersResponse, err
|
||||
return resp, err
|
||||
}
|
||||
|
||||
cancelAllOrdersResponse.Count = resp.Count
|
||||
return cancelAllOrdersResponse, err
|
||||
for i := range cancel.Count {
|
||||
resp.Add(fmt.Sprintf("Unknown:%d", i+1), "cancelled")
|
||||
}
|
||||
return resp, err
|
||||
}
|
||||
|
||||
var emptyOrderOptions OrderInfoOptions
|
||||
openOrders, err := e.GetOpenOrders(ctx, emptyOrderOptions)
|
||||
openOrders, err := e.GetOpenOrders(ctx, OrderInfoOptions{})
|
||||
if err != nil {
|
||||
return cancelAllOrdersResponse, err
|
||||
return resp, err
|
||||
}
|
||||
for orderID := range openOrders.Open {
|
||||
var err error
|
||||
if e.Websocket.CanUseAuthenticatedWebsocketForWrapper() {
|
||||
err = e.wsCancelOrders(ctx, []string{orderID})
|
||||
} else {
|
||||
_, err = e.CancelExistingOrder(ctx, orderID)
|
||||
}
|
||||
if err != nil {
|
||||
cancelAllOrdersResponse.Status[orderID] = err.Error()
|
||||
resp.Add(orderID, err.Error())
|
||||
continue
|
||||
}
|
||||
resp.Add(orderID, "cancelled")
|
||||
}
|
||||
case asset.Futures:
|
||||
cancelData, err := e.FuturesCancelAllOrders(ctx, req.Pair)
|
||||
if err != nil {
|
||||
return cancelAllOrdersResponse, err
|
||||
return resp, err
|
||||
}
|
||||
for x := range cancelData.CancelStatus.CancelledOrders {
|
||||
cancelAllOrdersResponse.Status[cancelData.CancelStatus.CancelledOrders[x].OrderID] = "cancelled"
|
||||
resp.Add(cancelData.CancelStatus.CancelledOrders[x].OrderID, "cancelled")
|
||||
}
|
||||
}
|
||||
return cancelAllOrdersResponse, nil
|
||||
return resp, nil
|
||||
}
|
||||
|
||||
// GetOrderInfo returns information on a current open order
|
||||
|
||||
@@ -1748,3 +1748,10 @@ func TestMarshalOrder(t *testing.T) {
|
||||
exp := []byte(`{"Exchange":"test","Type":4,"Side":"BUY","Pair":"BTC-USDT","AssetType":"spot","TimeInForce":"","ReduceOnly":false,"Leverage":0,"Price":1000,"Amount":1,"QuoteAmount":0,"TriggerPrice":0,"TriggerPriceType":0,"ClientID":"","ClientOrderID":"","AutoBorrow":false,"MarginType":"multi","RetrieveFees":false,"RetrieveFeeDelay":0,"RiskManagementModes":{"Mode":"","TakeProfit":{"Enabled":false,"TriggerPriceType":0,"Price":0,"LimitPrice":0,"OrderType":0},"StopLoss":{"Enabled":false,"TriggerPriceType":0,"Price":0,"LimitPrice":0,"OrderType":0},"StopEntry":{"Enabled":false,"TriggerPriceType":0,"Price":0,"LimitPrice":0,"OrderType":0}},"Hidden":false,"Iceberg":false,"EndTime":"0001-01-01T00:00:00Z","StopDirection":false,"TrackingMode":0,"TrackingValue":0,"RFQDisabled":false}`)
|
||||
assert.Equal(t, exp, j)
|
||||
}
|
||||
|
||||
func TestAdd(t *testing.T) {
|
||||
t.Parallel()
|
||||
var c CancelAllResponse
|
||||
c.Add("order1", "cancelled")
|
||||
assert.Equal(t, "cancelled", c.Status["order1"])
|
||||
}
|
||||
|
||||
@@ -281,7 +281,6 @@ type Cancel struct {
|
||||
// cancel all orders on an exchange
|
||||
type CancelAllResponse struct {
|
||||
Status map[string]string
|
||||
Count int64
|
||||
}
|
||||
|
||||
// CancelBatchResponse returns the status of orders
|
||||
|
||||
@@ -1377,3 +1377,11 @@ func StringToTrackingMode(mode string) TrackingMode {
|
||||
return UnknownTrackingMode
|
||||
}
|
||||
}
|
||||
|
||||
// Add adds a new orderID and status to the CancelAllResponse
|
||||
func (c *CancelAllResponse) Add(orderID, status string) {
|
||||
if c.Status == nil {
|
||||
c.Status = make(map[string]string)
|
||||
}
|
||||
c.Status[orderID] = status
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user