mirror of
https://github.com/d0zingcat/gocryptotrader.git
synced 2026-05-13 23:16:45 +00:00
orders: Add method for creating cancel struct from order details (#947)
* orders: Add method for creating cancel struct from order details * orders: remove uneeded fields * glorious: nit
This commit is contained in:
@@ -116,36 +116,29 @@ func (m *OrderManager) run() {
|
||||
}
|
||||
|
||||
// CancelAllOrders iterates and cancels all orders for each exchange provided
|
||||
func (m *OrderManager) CancelAllOrders(ctx context.Context, exchangeNames []exchange.IBotExchange) {
|
||||
func (m *OrderManager) CancelAllOrders(ctx context.Context, exchanges []exchange.IBotExchange) {
|
||||
if m == nil || atomic.LoadInt32(&m.started) == 0 {
|
||||
return
|
||||
}
|
||||
|
||||
orders := m.orderStore.get()
|
||||
if orders == nil {
|
||||
allOrders := m.orderStore.get()
|
||||
if len(allOrders) == 0 {
|
||||
return
|
||||
}
|
||||
|
||||
for i := range exchangeNames {
|
||||
exchangeOrders, ok := orders[strings.ToLower(exchangeNames[i].GetName())]
|
||||
for i := range exchanges {
|
||||
orders, ok := allOrders[strings.ToLower(exchanges[i].GetName())]
|
||||
if !ok {
|
||||
continue
|
||||
}
|
||||
for j := range exchangeOrders {
|
||||
log.Debugf(log.OrderMgr,
|
||||
"Order manager: Cancelling order(s) for exchange %s.",
|
||||
exchangeNames[i].GetName())
|
||||
err := m.Cancel(ctx, &order.Cancel{
|
||||
Exchange: exchangeOrders[j].Exchange,
|
||||
ID: exchangeOrders[j].ID,
|
||||
AccountID: exchangeOrders[j].AccountID,
|
||||
ClientID: exchangeOrders[j].ClientID,
|
||||
WalletAddress: exchangeOrders[j].WalletAddress,
|
||||
Type: exchangeOrders[j].Type,
|
||||
Side: exchangeOrders[j].Side,
|
||||
Pair: exchangeOrders[j].Pair,
|
||||
AssetType: exchangeOrders[j].AssetType,
|
||||
})
|
||||
for j := range orders {
|
||||
log.Debugf(log.OrderMgr, "Order manager: Cancelling order(s) for exchange %s.", exchanges[i].GetName())
|
||||
cancel, err := orders[j].DeriveCancel()
|
||||
if err != nil {
|
||||
log.Error(log.OrderMgr, err)
|
||||
continue
|
||||
}
|
||||
err = m.Cancel(ctx, cancel)
|
||||
if err != nil {
|
||||
log.Error(log.OrderMgr, err)
|
||||
}
|
||||
|
||||
@@ -27,7 +27,6 @@ type omfExchange struct {
|
||||
// CancelOrder overrides testExchange's cancel order function
|
||||
// to do the bare minimum required with no API calls or credentials required
|
||||
func (f omfExchange) CancelOrder(ctx context.Context, o *order.Cancel) error {
|
||||
o.Status = order.Cancelled
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -414,9 +413,7 @@ func TestCancelOrder(t *testing.T) {
|
||||
Exchange: testExchange,
|
||||
ID: "1337",
|
||||
Side: order.Sell,
|
||||
Status: order.New,
|
||||
AssetType: asset.Spot,
|
||||
Date: time.Now(),
|
||||
Pair: pair,
|
||||
}
|
||||
err = m.Cancel(context.Background(), cancel)
|
||||
|
||||
@@ -782,12 +782,13 @@ func (h *HUOBI) FPlaceBatchOrder(ctx context.Context, data []fBatchOrderData) (F
|
||||
}
|
||||
|
||||
// FCancelOrder cancels a futures order
|
||||
func (h *HUOBI) FCancelOrder(ctx context.Context, symbol, orderID, clientOrderID string) (FCancelOrderData, error) {
|
||||
func (h *HUOBI) FCancelOrder(ctx context.Context, baseCurrency currency.Code, orderID, clientOrderID string) (FCancelOrderData, error) {
|
||||
var resp FCancelOrderData
|
||||
req := make(map[string]interface{})
|
||||
if symbol != "" {
|
||||
req["symbol"] = symbol
|
||||
if baseCurrency.IsEmpty() {
|
||||
return resp, fmt.Errorf("cannot cancel futures order %w", currency.ErrCurrencyCodeEmpty)
|
||||
}
|
||||
req["symbol"] = baseCurrency.String() // Upper and lower case are supported
|
||||
if orderID != "" {
|
||||
req["order_id"] = orderID
|
||||
}
|
||||
|
||||
@@ -505,11 +505,12 @@ func TestFPlaceBatchOrder(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestFCancelOrder(t *testing.T) {
|
||||
t.Parallel()
|
||||
if !areTestAPIKeysSet() || !canManipulateRealOrders {
|
||||
t.Skip("skipping test: api keys not set or canManipulateRealOrders set to false")
|
||||
}
|
||||
t.Parallel()
|
||||
_, err := h.FCancelOrder(context.Background(), "BTC", "123", "")
|
||||
|
||||
_, err := h.FCancelOrder(context.Background(), currency.BTC, "123", "")
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
|
||||
@@ -1020,7 +1020,7 @@ func (h *HUOBI) CancelOrder(ctx context.Context, o *order.Cancel) error {
|
||||
case asset.CoinMarginedFutures:
|
||||
_, err = h.CancelSwapOrder(ctx, o.ID, o.ClientID, o.Pair)
|
||||
case asset.Futures:
|
||||
_, err = h.FCancelOrder(ctx, o.Symbol, o.ClientID, o.ClientOrderID)
|
||||
_, err = h.FCancelOrder(ctx, o.Pair.Base, o.ClientID, o.ClientOrderID)
|
||||
default:
|
||||
return fmt.Errorf("%v assetType not supported", o.AssetType)
|
||||
}
|
||||
|
||||
@@ -1634,3 +1634,43 @@ func TestDetail_CopyPointerOrderSlice(t *testing.T) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestDeriveCancel(t *testing.T) {
|
||||
t.Parallel()
|
||||
var o *Detail
|
||||
if _, err := o.DeriveCancel(); !errors.Is(err, errOrderDetailIsNil) {
|
||||
t.Fatalf("received: '%v' but expected: '%v'", err, errOrderDetailIsNil)
|
||||
}
|
||||
|
||||
pair := currency.NewPair(currency.BTC, currency.AUD)
|
||||
|
||||
o = &Detail{
|
||||
Exchange: "wow",
|
||||
ID: "wow1",
|
||||
AccountID: "wow2",
|
||||
ClientID: "wow3",
|
||||
ClientOrderID: "wow4",
|
||||
WalletAddress: "wow5",
|
||||
Type: Market,
|
||||
Side: Long,
|
||||
Pair: pair,
|
||||
AssetType: asset.Futures,
|
||||
}
|
||||
cancel, err := o.DeriveCancel()
|
||||
if !errors.Is(err, nil) {
|
||||
t.Fatalf("received: '%v' but expected: '%v'", err, nil)
|
||||
}
|
||||
|
||||
if cancel.Exchange != "wow" ||
|
||||
cancel.ID != "wow1" ||
|
||||
cancel.AccountID != "wow2" ||
|
||||
cancel.ClientID != "wow3" ||
|
||||
cancel.ClientOrderID != "wow4" ||
|
||||
cancel.WalletAddress != "wow5" ||
|
||||
cancel.Type != Market ||
|
||||
cancel.Side != Long ||
|
||||
!cancel.Pair.Equal(pair) ||
|
||||
cancel.AssetType != asset.Futures {
|
||||
t.Fatal("unexpected values")
|
||||
}
|
||||
}
|
||||
|
||||
@@ -181,8 +181,6 @@ type Filter struct {
|
||||
// Each exchange has their own requirements, so not all fields
|
||||
// are required to be populated
|
||||
type Cancel struct {
|
||||
Price float64
|
||||
Amount float64
|
||||
Exchange string
|
||||
ID string
|
||||
ClientOrderID string
|
||||
@@ -191,12 +189,8 @@ type Cancel struct {
|
||||
WalletAddress string
|
||||
Type Type
|
||||
Side Side
|
||||
Status Status
|
||||
AssetType asset.Item
|
||||
Date time.Time
|
||||
Pair currency.Pair
|
||||
Symbol string
|
||||
Trades []TradeHistory
|
||||
}
|
||||
|
||||
// CancelAllResponse returns the status from attempting to
|
||||
|
||||
@@ -29,6 +29,7 @@ var (
|
||||
errUnrecognisedOrderSide = errors.New("unrecognised order side")
|
||||
errUnrecognisedOrderType = errors.New("unrecognised order type")
|
||||
errUnrecognisedOrderStatus = errors.New("unrecognised order status")
|
||||
errOrderDetailIsNil = errors.New("order detail is nil")
|
||||
)
|
||||
|
||||
// Validate checks the supplied data and returns whether or not it's valid
|
||||
@@ -493,6 +494,25 @@ func CopyPointerOrderSlice(old []*Detail) []*Detail {
|
||||
return copySlice
|
||||
}
|
||||
|
||||
// DeriveCancel populates a cancel struct by the managed order details
|
||||
func (d *Detail) DeriveCancel() (*Cancel, error) {
|
||||
if d == nil {
|
||||
return nil, errOrderDetailIsNil
|
||||
}
|
||||
return &Cancel{
|
||||
Exchange: d.Exchange,
|
||||
ID: d.ID,
|
||||
AccountID: d.AccountID,
|
||||
ClientID: d.ClientID,
|
||||
ClientOrderID: d.ClientOrderID,
|
||||
WalletAddress: d.WalletAddress,
|
||||
Type: d.Type,
|
||||
Side: d.Side,
|
||||
Pair: d.Pair,
|
||||
AssetType: d.AssetType,
|
||||
}, nil
|
||||
}
|
||||
|
||||
// String implements the stringer interface
|
||||
func (t Type) String() string {
|
||||
switch t {
|
||||
|
||||
Reference in New Issue
Block a user