mirror of
https://github.com/d0zingcat/gocryptotrader.git
synced 2026-05-16 23:16:48 +00:00
FTX: order cancellation improvement (#727)
* exchanges/request: Requester.doRequest() now always parses returned response body into JSON even in the case of an artificial error after the request itself * exchanges/ftx: consider order cancellation successful under two new conditions, reported by the exchange: (1) order is already closed or (2) order is already queued for cancellation * exchanges/ftx: fix a typo in a comment * exchanges/request: keep the same behavior of doRequest() when there is an unmarshaling error * exchanges/ftx: FTX.DeleteOrderByClientID now also reports no errors when requesting the cancellation of orders that are already canceled on the exchange * exchanges/ftx: order deletion methods are now unified * exchanges/ftx: DeleteOrder* methods now check if the given ID is not empty
This commit is contained in:
@@ -129,6 +129,7 @@ const (
|
||||
)
|
||||
|
||||
var (
|
||||
errInvalidOrderID = errors.New("invalid order ID")
|
||||
errStartTimeCannotBeAfterEndTime = errors.New("start timestamp cannot be after end timestamp")
|
||||
errSubaccountNameMustBeSpecified = errors.New("a subaccount name must be specified")
|
||||
errSubaccountUpdateNameInvalid = errors.New("invalid subaccount old/new name")
|
||||
@@ -776,51 +777,43 @@ func (f *FTX) GetOrderStatusByClientID(clientOrderID string) (OrderData, error)
|
||||
return resp.Data, f.SendAuthHTTPRequest(exchange.RestSpot, http.MethodGet, getOrderStatusByClientID+clientOrderID, nil, &resp)
|
||||
}
|
||||
|
||||
// DeleteOrder deletes an order
|
||||
func (f *FTX) DeleteOrder(orderID string) (string, error) {
|
||||
func (f *FTX) deleteOrderByPath(path string) (string, error) {
|
||||
resp := struct {
|
||||
Result string `json:"result"`
|
||||
Success bool `json:"success"`
|
||||
Error string `json:"error"`
|
||||
}{}
|
||||
if err := f.SendAuthHTTPRequest(exchange.RestSpot, http.MethodDelete, deleteOrder+orderID, nil, &resp); err != nil {
|
||||
return "", err
|
||||
err := f.SendAuthHTTPRequest(exchange.RestSpot, http.MethodDelete, path, nil, &resp)
|
||||
// If there is an error reported, but the resp struct reports one of a very few
|
||||
// specific error causes, we still consider this a successful cancellation.
|
||||
if err != nil && !resp.Success && (resp.Error == "Order already closed" || resp.Error == "Order already queued for cancellation") {
|
||||
return resp.Error, nil
|
||||
}
|
||||
if !resp.Success {
|
||||
return resp.Result, errors.New("delete order request by ID unsuccessful")
|
||||
return resp.Result, err
|
||||
}
|
||||
|
||||
// DeleteOrder deletes an order
|
||||
func (f *FTX) DeleteOrder(orderID string) (string, error) {
|
||||
if orderID == "" {
|
||||
return "", errInvalidOrderID
|
||||
}
|
||||
return resp.Result, nil
|
||||
return f.deleteOrderByPath(deleteOrder + orderID)
|
||||
}
|
||||
|
||||
// DeleteOrderByClientID deletes an order
|
||||
func (f *FTX) DeleteOrderByClientID(clientID string) (string, error) {
|
||||
resp := struct {
|
||||
Result string `json:"result"`
|
||||
Success bool `json:"success"`
|
||||
}{}
|
||||
|
||||
if err := f.SendAuthHTTPRequest(exchange.RestSpot, http.MethodDelete, deleteOrderByClientID+clientID, nil, &resp); err != nil {
|
||||
return "", err
|
||||
if clientID == "" {
|
||||
return "", errInvalidOrderID
|
||||
}
|
||||
if !resp.Success {
|
||||
return resp.Result, errors.New("delete order request by client ID unsuccessful")
|
||||
}
|
||||
return resp.Result, nil
|
||||
return f.deleteOrderByPath(deleteOrderByClientID + clientID)
|
||||
}
|
||||
|
||||
// DeleteTriggerOrder deletes an order
|
||||
func (f *FTX) DeleteTriggerOrder(orderID string) (string, error) {
|
||||
resp := struct {
|
||||
Result string `json:"result"`
|
||||
Success bool `json:"success"`
|
||||
}{}
|
||||
|
||||
if err := f.SendAuthHTTPRequest(exchange.RestSpot, http.MethodDelete, cancelTriggerOrder+orderID, nil, &resp); err != nil {
|
||||
return "", err
|
||||
if orderID == "" {
|
||||
return "", errInvalidOrderID
|
||||
}
|
||||
if !resp.Success {
|
||||
return resp.Result, errors.New("delete trigger order request unsuccessful")
|
||||
}
|
||||
return resp.Result, nil
|
||||
return f.deleteOrderByPath(cancelTriggerOrder + orderID)
|
||||
}
|
||||
|
||||
// GetFills gets fills' data
|
||||
|
||||
@@ -197,6 +197,12 @@ func (r *Requester) doRequest(req *http.Request, p *Item) error {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
// Even in the case of an erroneous condition below, yield the parsed
|
||||
// response to caller.
|
||||
var unmarshallError error
|
||||
if p.Result != nil {
|
||||
unmarshallError = json.Unmarshal(contents, p.Result)
|
||||
}
|
||||
|
||||
if p.HTTPRecording {
|
||||
// This dumps http responses for future mocking implementations
|
||||
@@ -242,10 +248,7 @@ func (r *Requester) doRequest(req *http.Request, p *Item) error {
|
||||
string(contents))
|
||||
}
|
||||
}
|
||||
if p.Result != nil {
|
||||
return json.Unmarshal(contents, p.Result)
|
||||
}
|
||||
return nil
|
||||
return unmarshallError
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user