Cancel all orders wrapper implementation (#217)

* Changes method signature for cancelling all orders (experitmental). Implements cancelAllOrders wrapper for alphapoint, anx, binance

* Implements cancel all wrapper for bitfinex, bitmex, bitstamp, bittrex, btcmarkets, coinbasepro and hilariously coinut

* Changes method signature to only use one OrderCancellation type. Adds support for Exmo, gateio, gemini, itbit, lakebtc

* Adds/updates support for hitbtc, huobi, hadax, itbit and kraken

* Adds support for liqui, localbitcoins, okcoin, poloniex, wex and yobit. Splits up open order methods for poloniex

* Adds bithumb, okex and zb support. BTCC for another PR

* Updates bitflyer, bithumb, bitmex, coinut, okex and zb cancelAllOrders method to cancel via enabled currency pairs rather than a singular currency

* Adds tests to all exchanges to test wrapper function CancelAllOrders

* Fixes OKEX and huobi, btcmarkets, kraken, okCoin cancel order implementations

* Fixes coinut, hitbtc and okex api for authenticated requests

* Fixes comment and spacing

* Changes the CancelAllOrders signature to return orderids and errors along with a generic error.

* Fixes OKEX delimiter

* Removes spacing and test verbosity

* Removes more spacing

* Removes space

* Fixes okex rebasing issue. Also makes the maps instead of assuming they just work
This commit is contained in:
Scott
2018-12-14 15:53:26 +11:00
committed by Adrian Gallagher
parent 4ca3fd5b00
commit ff6a84f0f1
89 changed files with 2050 additions and 304 deletions

View File

@@ -24,7 +24,8 @@ const (
anxCurrencies = "currencyStatic"
anxDataToken = "dataToken"
anxOrderNew = "order/new"
anxCancel = "order/cancel"
anxOrderCancel = "order/cancel"
anxOrderList = "order/list"
anxOrderInfo = "order/info"
anxSend = "send"
anxSubaccountNew = "subaccount/new"
@@ -242,22 +243,42 @@ func (a *ANX) NewOrder(orderType string, buy bool, tradedCurrency string, traded
// CancelOrderByIDs cancels orders, requires already knowing order IDs
// There is no existing API call to retrieve orderIds
func (a *ANX) CancelOrderByIDs(orderIds []string) (err error) {
func (a *ANX) CancelOrderByIDs(orderIds []string) (OrderCancelResponse, error) {
request := make(map[string]interface{})
request["orderIds"] = orderIds
type OrderCancelResponse struct {
Order OrderResponse `json:"order"`
ResultCode string `json:"resultCode"`
UUID int64 `json:"uuid"`
ErrorCode int64 `json:"errorCode"`
}
var response OrderCancelResponse
err = a.SendAuthenticatedHTTPRequest(anxCancel, request, &response)
err := a.SendAuthenticatedHTTPRequest(anxOrderCancel, request, &response)
if response.ResultCode != "OK" {
return response, errors.New(response.ResultCode)
}
return response, err
}
// GetOrderList retrieves orders from the exchange
func (a *ANX) GetOrderList(isActiveOrdersOnly bool) ([]OrderResponse, error) {
request := make(map[string]interface{})
request["activeOnly"] = isActiveOrdersOnly
type OrderListResponse struct {
Timestamp int64 `json:"timestamp"`
ResultCode string `json:"resultCode"`
Count int64 `json:"count"`
OrderResponses []OrderResponse `json:"orders"`
}
var response OrderListResponse
err := a.SendAuthenticatedHTTPRequest(anxOrderList, request, &response)
if err != nil {
return nil, err
}
if response.ResultCode != "OK" {
log.Printf("Response code is not OK: %s\n", response.ResultCode)
return errors.New(response.ResultCode)
return nil, errors.New(response.ResultCode)
}
return err
return response.OrderResponses, err
}
// OrderInfo returns information about a specific order

View File

@@ -266,7 +266,6 @@ func TestCancelExchangeOrder(t *testing.T) {
t.Skip()
}
a.Verbose = true
currencyPair := pair.NewCurrencyPair(symbol.BTC, symbol.LTC)
var orderCancellation = exchange.OrderCancellation{
@@ -284,6 +283,36 @@ func TestCancelExchangeOrder(t *testing.T) {
}
}
func TestCancelAllExchangeOrders(t *testing.T) {
// Arrange
a.SetDefaults()
TestSetup(t)
if !isRealOrderTestEnabled() {
t.Skip()
}
currencyPair := pair.NewCurrencyPair(symbol.BTC, symbol.LTC)
var orderCancellation = exchange.OrderCancellation{
OrderID: "1",
WalletAddress: "1F5zVDgNjorJ51oGebSvNCrSAHpwGkUdDB",
AccountID: "1",
CurrencyPair: currencyPair,
}
// Act
resp, err := a.CancelAllOrders(orderCancellation)
// Assert
if err != nil {
t.Errorf("Could not cancel order: %s", err)
}
if len(resp.OrderStatus) > 0 {
t.Errorf("%v orders failed to cancel", len(resp.OrderStatus))
}
}
func TestGetAccountInfo(t *testing.T) {
if testAPIKey != "" || testAPISecret != "" {
_, err := a.GetAccountInfo()

View File

@@ -2,6 +2,13 @@ package anx
import "github.com/thrasher-/gocryptotrader/currency/symbol"
// List of strings
const (
CancelOrderNotFound string = "ORDER_NOT_FOUND"
CancelRequestSubmitted string = "CANCEL_REQUEST_SUBMITTED"
CancelOrderWrongState string = "ORDER_CANCEL_WRONG_STATE"
)
// Currency holds the currency information
type Currency struct {
Decimals int `json:"decimals"`
@@ -128,6 +135,20 @@ type OrderResponse struct {
TradedCurrencyOutstanding string `json:"tradedCurrencyOutstanding"`
}
// OrderCancelResponse returned when cancelling multiple orders
type OrderCancelResponse struct {
OrderCancellationResponses []OrderCancellationResponse `json:"orderIds"`
ResultCode string `json:"resultCode"`
UUID int64 `json:"uuid"`
ErrorCode int64 `json:"errorCode"`
}
// OrderCancellationResponse contians the orderID and error when cancelling multiple orders
type OrderCancellationResponse struct {
UUID string `json:"uuid"`
Error string `json:"errorCode"`
}
// TickerComponent is a sub-type for ticker
type TickerComponent struct {
Currency string `json:"currency"`

View File

@@ -264,12 +264,37 @@ func (a *ANX) ModifyOrder(orderID int64, action exchange.ModifyOrder) (int64, er
// CancelOrder cancels an order by its corresponding ID number
func (a *ANX) CancelOrder(order exchange.OrderCancellation) error {
orderIDs := []string{order.OrderID}
return a.CancelOrderByIDs(orderIDs)
_, err := a.CancelOrderByIDs(orderIDs)
return err
}
// CancelAllOrders cancels all orders associated with a currency pair
func (a *ANX) CancelAllOrders() error {
return common.ErrNotYetImplemented
func (a *ANX) CancelAllOrders(orderCancellation exchange.OrderCancellation) (exchange.CancelAllOrdersResponse, error) {
cancelAllOrdersResponse := exchange.CancelAllOrdersResponse{
OrderStatus: make(map[string]string),
}
placedOrders, err := a.GetOrderList(true)
if err != nil {
return cancelAllOrdersResponse, err
}
var orderIDs []string
for _, order := range placedOrders {
orderIDs = append(orderIDs, order.OrderID)
}
resp, err := a.CancelOrderByIDs(orderIDs)
if err != nil {
return cancelAllOrdersResponse, err
}
for _, order := range resp.OrderCancellationResponses {
if order.Error != CancelRequestSubmitted {
cancelAllOrdersResponse.OrderStatus[order.UUID] = order.Error
}
}
return cancelAllOrdersResponse, err
}
// GetOrderInfo returns information on a current open order