From 458aab301eea0567efacf848ca3cbad8a0db5c91 Mon Sep 17 00:00:00 2001 From: Scott Date: Fri, 30 Nov 2018 16:20:34 +1100 Subject: [PATCH] Cancel order wrapper wrapup (#214) * Reimplements order cancellation for alphapoint, anx, binance, bitfinex, bithumb, bitmex, bitstamp, bittrex, btcmarkets, coinbasepro, coinut, exmo, gateio, gemini, gitbtc, huobi, hadax, itbit, kraken, lakebtc, liqui, okcoin, okex, poloniex, wex, yobit and zb wrappers. Adds new order cancellation struct type. Updates old tests that pointed to the wrong unrenamed methods * Sets up tests for all supported exchanges. request.DoRequest errors when response status is not 200 * Updates alphapoint, coinut, hitbtc, lakebtc cancel order implementations. Finishes testing * Adds localbitcoin cancel order wrapper support * Fixes tests and build issues. Adds WexIssue flag for tests * Changes CancelOrder signature to only return error. Allows exchange to format currency pairs with delimiters --- exchanges/alphapoint/alphapoint.go | 6 +- exchanges/alphapoint/alphapoint_test.go | 82 ++++++++++--- exchanges/alphapoint/alphapoint_wrapper.go | 14 ++- exchanges/anx/anx.go | 21 ++++ exchanges/anx/anx_test.go | 54 ++++++-- exchanges/anx/anx_wrapper.go | 5 +- exchanges/binance/binance.go | 15 --- exchanges/binance/binance_test.go | 63 +++++++--- exchanges/binance/binance_wrapper.go | 13 +- exchanges/bitfinex/bitfinex.go | 1 + exchanges/bitfinex/bitfinex_test.go | 51 ++++++-- exchanges/bitfinex/bitfinex_wrapper.go | 13 +- exchanges/bitflyer/bitflyer_test.go | 55 +++++++-- exchanges/bitflyer/bitflyer_wrapper.go | 2 +- exchanges/bithumb/bithumb_test.go | 52 ++++++-- exchanges/bithumb/bithumb_wrapper.go | 5 +- exchanges/bitmex/bitmex_test.go | 52 ++++++-- exchanges/bitmex/bitmex_wrapper.go | 9 +- exchanges/bitstamp/bitstamp_test.go | 56 +++++++-- exchanges/bitstamp/bitstamp_wrapper.go | 12 +- exchanges/bittrex/bittrex_test.go | 52 ++++++-- exchanges/bittrex/bittrex_wrapper.go | 6 +- exchanges/btcc/btcc_test.go | 64 +++++++++- exchanges/btcc/btcc_wrapper.go | 2 +- exchanges/btcmarkets/btcmarkets_test.go | 56 +++++++-- exchanges/btcmarkets/btcmarkets_types.go | 2 +- exchanges/btcmarkets/btcmarkets_wrapper.go | 21 ++-- exchanges/coinbasepro/coinbasepro_test.go | 57 +++++++-- exchanges/coinbasepro/coinbasepro_wrapper.go | 4 +- exchanges/coinut/coinut.go | 14 ++- exchanges/coinut/coinut_test.go | 55 +++++++-- exchanges/coinut/coinut_wrapper.go | 21 +++- exchanges/exchange.go | 13 +- exchanges/exmo/exmo_test.go | 55 +++++++-- exchanges/exmo/exmo_wrapper.go | 10 +- exchanges/gateio/gateio_test.go | 55 +++++++-- exchanges/gateio/gateio_wrapper.go | 12 +- exchanges/gemini/gemini_test.go | 51 ++++++-- exchanges/gemini/gemini_wrapper.go | 13 +- exchanges/hitbtc/hitbtc.go | 4 +- exchanges/hitbtc/hitbtc_test.go | 55 +++++++-- exchanges/hitbtc/hitbtc_wrapper.go | 13 +- exchanges/huobi/huobi_test.go | 55 +++++++-- exchanges/huobi/huobi_wrapper.go | 12 +- exchanges/huobihadax/huobihadax_test.go | 54 ++++++-- exchanges/huobihadax/huobihadax_wrapper.go | 12 +- exchanges/itbit/itbit_test.go | 57 +++++++-- exchanges/itbit/itbit_wrapper.go | 4 +- exchanges/kraken/kraken_test.go | 57 +++++++-- exchanges/kraken/kraken_wrapper.go | 6 +- exchanges/lakebtc/lakebtc.go | 2 +- exchanges/lakebtc/lakebtc_test.go | 59 +++++++-- exchanges/lakebtc/lakebtc_wrapper.go | 10 +- exchanges/liqui/liqui_test.go | 55 +++++++-- exchanges/liqui/liqui_wrapper.go | 13 +- exchanges/localbitcoins/localbitcoins_test.go | 64 +++++++++- .../localbitcoins/localbitcoins_wrapper.go | 4 +- exchanges/okcoin/okcoin_test.go | 55 +++++++-- exchanges/okcoin/okcoin_wrapper.go | 14 ++- exchanges/okex/okex_test.go | 55 +++++++-- exchanges/okex/okex_wrapper.go | 13 +- exchanges/poloniex/poloniex_test.go | 55 +++++++-- exchanges/poloniex/poloniex_wrapper.go | 13 +- exchanges/request/request.go | 5 + exchanges/request/request_test.go | 2 +- exchanges/wex/wex_test.go | 116 ++++++++++++++++-- exchanges/wex/wex_wrapper.go | 13 +- exchanges/yobit/yobit_test.go | 55 +++++++-- exchanges/yobit/yobit_wrapper.go | 13 +- exchanges/zb/zb_test.go | 53 ++++++-- exchanges/zb/zb_wrapper.go | 11 +- tools/exchange_template/wrapper_file.tmpl | 2 +- 72 files changed, 1771 insertions(+), 384 deletions(-) diff --git a/exchanges/alphapoint/alphapoint.go b/exchanges/alphapoint/alphapoint.go index 2b0a42ea..759cfae6 100644 --- a/exchanges/alphapoint/alphapoint.go +++ b/exchanges/alphapoint/alphapoint.go @@ -431,10 +431,10 @@ func (a *Alphapoint) ModifyExistingOrder(symbol string, OrderID, action int64) ( // CancelExistingOrder cancels an order that has not been executed. // symbol - Instrument code (ex: “BTCUSD”) // OrderId - Order id (ex: 1000) -func (a *Alphapoint) CancelExistingOrder(symbol string, OrderID int64) (int64, error) { +func (a *Alphapoint) CancelExistingOrder(OrderID int64, OMSID string) (int64, error) { request := make(map[string]interface{}) - request["ins"] = symbol - request["serverOrderId"] = OrderID + request["OrderId"] = OrderID + request["OMSId"] = OMSID response := Response{} err := a.SendAuthenticatedHTTPRequest( diff --git a/exchanges/alphapoint/alphapoint_test.go b/exchanges/alphapoint/alphapoint_test.go index f4d4f476..617e40b6 100644 --- a/exchanges/alphapoint/alphapoint_test.go +++ b/exchanges/alphapoint/alphapoint_test.go @@ -4,14 +4,16 @@ import ( "testing" "github.com/thrasher-/gocryptotrader/common" + "github.com/thrasher-/gocryptotrader/currency/pair" + "github.com/thrasher-/gocryptotrader/currency/symbol" exchange "github.com/thrasher-/gocryptotrader/exchanges" ) const ( - onlineTest = false - - testAPIKey = "" - testAPISecret = "" + onlineTest = false + testAPIKey = "" + testAPISecret = "" + canManipulateRealOrders = false ) func TestSetDefaults(t *testing.T) { @@ -432,21 +434,6 @@ func TestModifyExistingOrder(t *testing.T) { } } -func TestCancelExistingOrder(t *testing.T) { - a := &Alphapoint{} - a.SetDefaults() - testSetAPIKey(a) - - if !testIsAPIKeysSet(a) { - return - } - - _, err := a.CancelExistingOrder("", 1) - if err == nil { - t.Error("Test Failed - GetUserInfo() error") - } -} - func TestCancelAllExistingOrders(t *testing.T) { a := &Alphapoint{} a.SetDefaults() @@ -504,3 +491,60 @@ func TestFormatWithdrawPermissions(t *testing.T) { t.Errorf("Expected: %s, Recieved: %s", expectedResult, withdrawPermissions) } } + +// Any tests below this line have the ability to impact your orders on the exchange. Enable canManipulateRealOrders to run them +// ---------------------------------------------------------------------------------------------------------------------------- + +func isRealOrderTestEnabled(a *Alphapoint) bool { + if a.APIKey == "" || a.APISecret == "" || + a.APIKey == "Key" || a.APISecret == "Secret" || + !canManipulateRealOrders { + return false + } + return true +} + +func TestSubmitOrder(t *testing.T) { + a := &Alphapoint{} + a.SetDefaults() + + if !isRealOrderTestEnabled(a) { + t.Skip() + } + var p = pair.CurrencyPair{ + Delimiter: "_", + FirstCurrency: symbol.BTC, + SecondCurrency: symbol.USD, + } + response, err := a.SubmitOrder(p, exchange.Buy, exchange.Market, 1, 1, "clientId") + if err != nil || !response.IsOrderPlaced { + t.Errorf("Order failed to be placed: %v", err) + } +} + +func TestCancelExchangeOrder(t *testing.T) { + // Arrange + a := &Alphapoint{} + a.SetDefaults() + + if !isRealOrderTestEnabled(a) { + t.Skip() + } + + a.Verbose = true + currencyPair := pair.NewCurrencyPair(symbol.BTC, symbol.LTC) + + var orderCancellation = exchange.OrderCancellation{ + OrderID: "1", + WalletAddress: "1F5zVDgNjorJ51oGebSvNCrSAHpwGkUdDB", + AccountID: "1", + CurrencyPair: currencyPair, + } + // Act + err := a.CancelOrder(orderCancellation) + + // Assert + if err != nil { + t.Errorf("Test Failed - ANX CancelOrder() error: %s", err) + } +} diff --git a/exchanges/alphapoint/alphapoint_wrapper.go b/exchanges/alphapoint/alphapoint_wrapper.go index dc877815..c9549c60 100644 --- a/exchanges/alphapoint/alphapoint_wrapper.go +++ b/exchanges/alphapoint/alphapoint_wrapper.go @@ -3,6 +3,7 @@ package alphapoint import ( "errors" "fmt" + "strconv" "github.com/thrasher-/gocryptotrader/common" "github.com/thrasher-/gocryptotrader/currency/pair" @@ -129,9 +130,16 @@ func (a *Alphapoint) ModifyOrder(orderID int64, action exchange.ModifyOrder) (in } // CancelOrder cancels an order by its corresponding ID number -func (a *Alphapoint) CancelOrder(orderID int64) error { - // return a.CancelExistingOrder(p.Pair().String(), orderID) - return common.ErrNotYetImplemented +func (a *Alphapoint) CancelOrder(order exchange.OrderCancellation) error { + orderIDInt, err := strconv.ParseInt(order.OrderID, 10, 64) + + if err != nil { + return err + } + + _, err = a.CancelExistingOrder(orderIDInt, order.AccountID) + + return err } // CancelAllOrders cancels all orders associated with a currency pair diff --git a/exchanges/anx/anx.go b/exchanges/anx/anx.go index 276ffafe..1425b66a 100644 --- a/exchanges/anx/anx.go +++ b/exchanges/anx/anx.go @@ -24,6 +24,7 @@ const ( anxCurrencies = "currencyStatic" anxDataToken = "dataToken" anxOrderNew = "order/new" + anxCancel = "order/cancel" anxOrderInfo = "order/info" anxSend = "send" anxSubaccountNew = "subaccount/new" @@ -239,6 +240,26 @@ func (a *ANX) NewOrder(orderType string, buy bool, tradedCurrency string, traded return response.OrderID, nil } +// 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) { + 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) + if response.ResultCode != "OK" { + log.Printf("Response code is not OK: %s\n", response.ResultCode) + return errors.New(response.ResultCode) + } + return err +} + // OrderInfo returns information about a specific order func (a *ANX) OrderInfo(orderID string) (OrderResponse, error) { request := make(map[string]interface{}) diff --git a/exchanges/anx/anx_test.go b/exchanges/anx/anx_test.go index f49ca9cc..f420d71c 100644 --- a/exchanges/anx/anx_test.go +++ b/exchanges/anx/anx_test.go @@ -11,16 +11,13 @@ import ( // Please supply your own keys here for due diligence testing const ( - testAPIKey = "" - testAPISecret = "" + testAPIKey = "" + testAPISecret = "" + canManipulateRealOrders = false ) var a ANX -const ( - canPlaceOrders = false -) - func TestSetDefaults(t *testing.T) { a.SetDefaults() @@ -230,15 +227,23 @@ func TestFormatWithdrawPermissions(t *testing.T) { } } -// This will really really use the API to place an order -// If you're going to test this, make sure you're willing to place real orders on the exchange +// Any tests below this line have the ability to impact your orders on the exchange. Enable canManipulateRealOrders to run them +// ---------------------------------------------------------------------------------------------------------------------------- + +func isRealOrderTestEnabled() bool { + if a.APIKey == "" || a.APISecret == "" || + a.APIKey == "Key" || a.APISecret == "Secret" || + !canManipulateRealOrders { + return false + } + return true +} + func TestSubmitOrder(t *testing.T) { a.SetDefaults() TestSetup(t) - if a.APIKey == "" || a.APISecret == "" || - a.APIKey == "Key" || a.APISecret == "Secret" || - !canPlaceOrders { + if !isRealOrderTestEnabled() { t.Skip() } var p = pair.CurrencyPair{ @@ -251,3 +256,30 @@ func TestSubmitOrder(t *testing.T) { t.Errorf("Order failed to be placed: %v", err) } } + +func TestCancelExchangeOrder(t *testing.T) { + // Arrange + a.SetDefaults() + TestSetup(t) + + if !isRealOrderTestEnabled() { + t.Skip() + } + + a.Verbose = true + currencyPair := pair.NewCurrencyPair(symbol.BTC, symbol.LTC) + + var orderCancellation = exchange.OrderCancellation{ + OrderID: "1", + WalletAddress: "1F5zVDgNjorJ51oGebSvNCrSAHpwGkUdDB", + AccountID: "1", + CurrencyPair: currencyPair, + } + // Act + err := a.CancelOrder(orderCancellation) + + // Assert + if err != nil { + t.Errorf("Test Failed - ANX CancelOrder() error: %s", err) + } +} diff --git a/exchanges/anx/anx_wrapper.go b/exchanges/anx/anx_wrapper.go index bf407468..ff03065e 100644 --- a/exchanges/anx/anx_wrapper.go +++ b/exchanges/anx/anx_wrapper.go @@ -228,8 +228,9 @@ func (a *ANX) ModifyOrder(orderID int64, action exchange.ModifyOrder) (int64, er } // CancelOrder cancels an order by its corresponding ID number -func (a *ANX) CancelOrder(orderID int64) error { - return common.ErrNotYetImplemented +func (a *ANX) CancelOrder(order exchange.OrderCancellation) error { + orderIDs := []string{order.OrderID} + return a.CancelOrderByIDs(orderIDs) } // CancelAllOrders cancels all orders associated with a currency pair diff --git a/exchanges/binance/binance.go b/exchanges/binance/binance.go index bda24ff9..6d0c2b27 100644 --- a/exchanges/binance/binance.go +++ b/exchanges/binance/binance.go @@ -419,21 +419,6 @@ func (b *Binance) GetBestPrice(symbol string) (BestPrice, error) { return resp, b.SendHTTPRequest(path, &resp) } -// NewOrderTest sends a new order -func (b *Binance) NewOrderTest() (interface{}, error) { - var resp interface{} - - path := fmt.Sprintf("%s%s", b.APIUrl, newOrderTest) - - params := url.Values{} - params.Set("symbol", "BTCUSDT") - params.Set("side", "BUY") - params.Set("type", "MARKET") - params.Set("quantity", "0.1") - - return resp, b.SendAuthHTTPRequest("POST", path, params, &resp) -} - // NewOrder sends a new order to Binance func (b *Binance) NewOrder(o NewOrderRequest) (NewOrderResponse, error) { var resp NewOrderResponse diff --git a/exchanges/binance/binance_test.go b/exchanges/binance/binance_test.go index de79b353..9cc7e264 100644 --- a/exchanges/binance/binance_test.go +++ b/exchanges/binance/binance_test.go @@ -12,9 +12,9 @@ import ( // Please supply your own keys here for due diligence testing const ( - testAPIKey = "" - testAPISecret = "" - canPlaceOrders = false + testAPIKey = "" + testAPISecret = "" + canManipulateRealOrders = false ) var b Binance @@ -138,14 +138,6 @@ func TestGetBestPrice(t *testing.T) { } } -func TestNewOrderTest(t *testing.T) { - t.Parallel() - _, err := b.NewOrderTest() - if err != nil { - t.Error("Test Failed - Binance NewOrderTest() error", err) - } -} - func TestNewOrder(t *testing.T) { t.Parallel() @@ -339,17 +331,26 @@ func TestFormatWithdrawPermissions(t *testing.T) { } } -// This will really really use the API to place an order -// If you're going to test this, make sure you're willing to place real orders on the exchange +// Any tests below this line have the ability to impact your orders on the exchange. Enable canManipulateRealOrders to run them +// ----------------------------------------------------------------------------------------------------------------------------- + +func isRealOrderTestEnabled() bool { + if b.APIKey == "" || b.APISecret == "" || + b.APIKey == "Key" || b.APISecret == "Secret" || + !canManipulateRealOrders { + return false + } + return true +} + func TestSubmitOrder(t *testing.T) { b.SetDefaults() TestSetup(t) - if b.APIKey == "" || b.APISecret == "" || - b.APIKey == "Key" || b.APISecret == "Secret" || - !canPlaceOrders { + if !isRealOrderTestEnabled() { t.Skip() } + var p = pair.CurrencyPair{ Delimiter: "", FirstCurrency: symbol.LTC, @@ -360,3 +361,33 @@ func TestSubmitOrder(t *testing.T) { t.Errorf("Order failed to be placed: %v", err) } } + +func TestCancelExchangeOrder(t *testing.T) { + // Arrange + b.SetDefaults() + TestSetup(t) + + if b.APIKey == "" || b.APISecret == "" || + b.APIKey == "Key" || b.APISecret == "Secret" || + !canManipulateRealOrders { + t.Skip() + } + + b.Verbose = true + currencyPair := pair.NewCurrencyPair(symbol.LTC, symbol.BTC) + + var orderCancellation = exchange.OrderCancellation{ + OrderID: "1", + WalletAddress: "1F5zVDgNjorJ51oGebSvNCrSAHpwGkUdDB", + AccountID: "1", + CurrencyPair: currencyPair, + } + + // Act + err := b.CancelOrder(orderCancellation) + + // Assert + if err != nil { + t.Errorf("Could not cancel order: %s", err) + } +} diff --git a/exchanges/binance/binance_wrapper.go b/exchanges/binance/binance_wrapper.go index f625bbc3..cab9e370 100644 --- a/exchanges/binance/binance_wrapper.go +++ b/exchanges/binance/binance_wrapper.go @@ -4,6 +4,7 @@ import ( "errors" "fmt" "log" + "strconv" "sync" "github.com/thrasher-/gocryptotrader/common" @@ -190,8 +191,16 @@ func (b *Binance) ModifyOrder(orderID int64, action exchange.ModifyOrder) (int64 } // CancelOrder cancels an order by its corresponding ID number -func (b *Binance) CancelOrder(orderID int64) error { - return common.ErrNotYetImplemented +func (b *Binance) CancelOrder(order exchange.OrderCancellation) error { + orderIDInt, err := strconv.ParseInt(order.OrderID, 10, 64) + + if err != nil { + return err + } + + _, err = b.CancelExistingOrder(exchange.FormatExchangeCurrency(b.Name, order.CurrencyPair).String(), orderIDInt, order.AccountID) + + return err } // CancelAllOrders cancels all orders associated with a currency pair diff --git a/exchanges/bitfinex/bitfinex.go b/exchanges/bitfinex/bitfinex.go index 7e5bd42d..761740a6 100644 --- a/exchanges/bitfinex/bitfinex.go +++ b/exchanges/bitfinex/bitfinex.go @@ -916,6 +916,7 @@ func (b *Bitfinex) SendAuthenticatedHTTPRequest(method, path string, params map[ if err != nil { return err } + return nil } diff --git a/exchanges/bitfinex/bitfinex_test.go b/exchanges/bitfinex/bitfinex_test.go index aa24bcf1..67e15ced 100644 --- a/exchanges/bitfinex/bitfinex_test.go +++ b/exchanges/bitfinex/bitfinex_test.go @@ -15,9 +15,9 @@ import ( // Please supply your own keys here to do better tests const ( - testAPIKey = "" - testAPISecret = "" - canPlaceOrders = false + testAPIKey = "" + testAPISecret = "" + canManipulateRealOrders = false ) var b Bitfinex @@ -721,15 +721,22 @@ func TestFormatWithdrawPermissions(t *testing.T) { } } -// This will really really use the API to place an order -// If you're going to test this, make sure you're willing to place real orders on the exchange +// Any tests below this line have the ability to impact your orders on the exchange. Enable canManipulateRealOrders to run them +// ---------------------------------------------------------------------------------------------------------------------------- +func isRealOrderTestEnabled() bool { + if b.APIKey == "" || b.APISecret == "" || + b.APIKey == "Key" || b.APISecret == "Secret" || + !canManipulateRealOrders { + return false + } + return true +} + func TestSubmitOrder(t *testing.T) { b.SetDefaults() TestSetup(t) - if b.APIKey == "" || b.APISecret == "" || - b.APIKey == "Key" || b.APISecret == "Secret" || - !canPlaceOrders { + if !isRealOrderTestEnabled() { t.Skip() } var p = pair.CurrencyPair{ @@ -742,3 +749,31 @@ func TestSubmitOrder(t *testing.T) { t.Errorf("Order failed to be placed: %v", err) } } + +func TestCancelExchangeOrder(t *testing.T) { + // Arrange + b.SetDefaults() + TestSetup(t) + + if !isRealOrderTestEnabled() { + t.Skip() + } + + b.Verbose = true + currencyPair := pair.NewCurrencyPair(symbol.LTC, symbol.BTC) + + var orderCancellation = exchange.OrderCancellation{ + OrderID: "1", + WalletAddress: "1F5zVDgNjorJ51oGebSvNCrSAHpwGkUdDB", + AccountID: "1", + CurrencyPair: currencyPair, + } + + // Act + err := b.CancelOrder(orderCancellation) + + // Assert + if err != nil { + t.Errorf("Could not cancel order: %s", err) + } +} diff --git a/exchanges/bitfinex/bitfinex_wrapper.go b/exchanges/bitfinex/bitfinex_wrapper.go index c6a366fb..94232b8b 100644 --- a/exchanges/bitfinex/bitfinex_wrapper.go +++ b/exchanges/bitfinex/bitfinex_wrapper.go @@ -4,6 +4,7 @@ import ( "fmt" "log" "net/url" + "strconv" "sync" "github.com/thrasher-/gocryptotrader/common" @@ -202,8 +203,16 @@ func (b *Bitfinex) ModifyOrder(orderID int64, action exchange.ModifyOrder) (int6 } // CancelOrder cancels an order by its corresponding ID number -func (b *Bitfinex) CancelOrder(orderID int64) error { - return common.ErrNotYetImplemented +func (b *Bitfinex) CancelOrder(order exchange.OrderCancellation) error { + orderIDInt, err := strconv.ParseInt(order.OrderID, 10, 64) + + if err != nil { + return err + } + + _, err = b.CancelExistingOrder(orderIDInt) + + return err } // CancelAllOrders cancels all orders associated with a currency pair diff --git a/exchanges/bitflyer/bitflyer_test.go b/exchanges/bitflyer/bitflyer_test.go index d19dc787..43e82acc 100644 --- a/exchanges/bitflyer/bitflyer_test.go +++ b/exchanges/bitflyer/bitflyer_test.go @@ -13,9 +13,9 @@ import ( // Please supply your own keys here for due diligence testing const ( - testAPIKey = "" - testAPISecret = "" - canPlaceOrders = false + testAPIKey = "" + testAPISecret = "" + canManipulateRealOrders = false ) var b Bitflyer @@ -248,24 +248,59 @@ func TestFormatWithdrawPermissions(t *testing.T) { } } -// This will really really use the API to place an order -// If you're going to test this, make sure you're willing to place real orders on the exchange +// Any tests below this line have the ability to impact your orders on the exchange. Enable canManipulateRealOrders to run them +// ---------------------------------------------------------------------------------------------------------------------------- +func isRealOrderTestEnabled() bool { + if b.APIKey == "" || b.APISecret == "" || + b.APIKey == "Key" || b.APISecret == "Secret" || + !canManipulateRealOrders { + return false + } + return true +} + func TestSubmitOrder(t *testing.T) { b.SetDefaults() TestSetup(t) - if b.APIKey == "" || b.APISecret == "" || - b.APIKey == "Key" || b.APISecret == "Secret" || - !canPlaceOrders { + if !isRealOrderTestEnabled() { t.Skip() } var p = pair.CurrencyPair{ Delimiter: "", - FirstCurrency: symbol.BTC, - SecondCurrency: symbol.LTC, + FirstCurrency: symbol.LTC, + SecondCurrency: symbol.BTC, } response, err := b.SubmitOrder(p, exchange.Buy, exchange.Market, 1, 1, "clientId") if err != nil || !response.IsOrderPlaced { t.Errorf("Order failed to be placed: %v", err) } } + +func TestCancelExchangeOrder(t *testing.T) { + // Arrange + b.SetDefaults() + TestSetup(t) + + if !isRealOrderTestEnabled() { + t.Skip() + } + + b.Verbose = true + currencyPair := pair.NewCurrencyPair(symbol.LTC, symbol.BTC) + + var orderCancellation = exchange.OrderCancellation{ + OrderID: "1", + WalletAddress: "1F5zVDgNjorJ51oGebSvNCrSAHpwGkUdDB", + AccountID: "1", + CurrencyPair: currencyPair, + } + + // Act + err := b.CancelOrder(orderCancellation) + + // Assert + if err != nil { + t.Errorf("Could not cancel order: %s", err) + } +} diff --git a/exchanges/bitflyer/bitflyer_wrapper.go b/exchanges/bitflyer/bitflyer_wrapper.go index 43ca45e6..513a36c2 100644 --- a/exchanges/bitflyer/bitflyer_wrapper.go +++ b/exchanges/bitflyer/bitflyer_wrapper.go @@ -166,7 +166,7 @@ func (b *Bitflyer) ModifyOrder(orderID int64, action exchange.ModifyOrder) (int6 } // CancelOrder cancels an order by its corresponding ID number -func (b *Bitflyer) CancelOrder(orderID int64) error { +func (b *Bitflyer) CancelOrder(order exchange.OrderCancellation) error { return common.ErrNotYetImplemented } diff --git a/exchanges/bithumb/bithumb_test.go b/exchanges/bithumb/bithumb_test.go index 421590b1..9c10d6ce 100644 --- a/exchanges/bithumb/bithumb_test.go +++ b/exchanges/bithumb/bithumb_test.go @@ -11,9 +11,9 @@ import ( // Please supply your own keys here for due diligence testing const ( - testAPIKey = "" - testAPISecret = "" - canPlaceOrders = false + testAPIKey = "" + testAPISecret = "" + canManipulateRealOrders = false ) var b Bithumb @@ -284,17 +284,25 @@ func TestFormatWithdrawPermissions(t *testing.T) { } } -// This will really really use the API to place an order -// If you're going to test this, make sure you're willing to place real orders on the exchange +// Any tests below this line have the ability to impact your orders on the exchange. Enable canManipulateRealOrders to run them +// ---------------------------------------------------------------------------------------------------------------------------- +func isRealOrderTestEnabled() bool { + if b.APIKey == "" || b.APISecret == "" || + b.APIKey == "Key" || b.APISecret == "Secret" || + !canManipulateRealOrders { + return false + } + return true +} + func TestSubmitOrder(t *testing.T) { b.SetDefaults() TestSetup(t) - if b.APIKey == "" || b.APISecret == "" || - b.APIKey == "Key" || b.APISecret == "Secret" || - !canPlaceOrders { + if !isRealOrderTestEnabled() { t.Skip() } + var p = pair.CurrencyPair{ Delimiter: "", FirstCurrency: symbol.BTC, @@ -305,3 +313,31 @@ func TestSubmitOrder(t *testing.T) { t.Errorf("Order failed to be placed: %v", err) } } + +func TestCancelExchangeOrder(t *testing.T) { + // Arrange + b.SetDefaults() + TestSetup(t) + + if !isRealOrderTestEnabled() { + t.Skip() + } + + b.Verbose = true + currencyPair := pair.NewCurrencyPair(symbol.LTC, symbol.BTC) + + var orderCancellation = exchange.OrderCancellation{ + OrderID: "1", + WalletAddress: "1F5zVDgNjorJ51oGebSvNCrSAHpwGkUdDB", + AccountID: "1", + CurrencyPair: currencyPair, + } + + // Act + err := b.CancelOrder(orderCancellation) + + // Assert + if err != nil { + t.Errorf("Could not cancel order: %s", err) + } +} diff --git a/exchanges/bithumb/bithumb_wrapper.go b/exchanges/bithumb/bithumb_wrapper.go index b91b4bfd..7eda7a44 100644 --- a/exchanges/bithumb/bithumb_wrapper.go +++ b/exchanges/bithumb/bithumb_wrapper.go @@ -173,8 +173,9 @@ func (b *Bithumb) ModifyOrder(orderID int64, action exchange.ModifyOrder) (int64 } // CancelOrder cancels an order by its corresponding ID number -func (b *Bithumb) CancelOrder(orderID int64) error { - return common.ErrNotYetImplemented +func (b *Bithumb) CancelOrder(order exchange.OrderCancellation) error { + _, err := b.CancelTrade(order.Side.ToString(), order.OrderID, order.CurrencyPair.FirstCurrency.String()) + return err } // CancelAllOrders cancels all orders associated with a currency pair diff --git a/exchanges/bitmex/bitmex_test.go b/exchanges/bitmex/bitmex_test.go index c142a24f..f55cbec9 100644 --- a/exchanges/bitmex/bitmex_test.go +++ b/exchanges/bitmex/bitmex_test.go @@ -13,9 +13,9 @@ import ( // Please supply your own keys here for due diligence testing const ( - testAPIKey = "" - testAPISecret = "" - canPlaceOrders = false + testAPIKey = "" + testAPISecret = "" + canManipulateRealOrders = false ) var b Bitmex @@ -464,17 +464,25 @@ func TestFormatWithdrawPermissions(t *testing.T) { } } -// This will really really use the API to place an order -// If you're going to test this, make sure you're willing to place real orders on the exchange +// Any tests below this line have the ability to impact your orders on the exchange. Enable canManipulateRealOrders to run them +// ---------------------------------------------------------------------------------------------------------------------------- +func isRealOrderTestEnabled() bool { + if b.APIKey == "" || b.APISecret == "" || + b.APIKey == "Key" || b.APISecret == "Secret" || + !canManipulateRealOrders { + return false + } + return true +} + func TestSubmitOrder(t *testing.T) { b.SetDefaults() TestSetup(t) - if b.APIKey == "" || b.APISecret == "" || - b.APIKey == "Key" || b.APISecret == "Secret" || - !canPlaceOrders { + if !isRealOrderTestEnabled() { t.Skip() } + var p = pair.CurrencyPair{ Delimiter: "", FirstCurrency: symbol.XBT, @@ -485,3 +493,31 @@ func TestSubmitOrder(t *testing.T) { t.Errorf("Order failed to be placed: %v", err) } } + +func TestCancelExchangeOrder(t *testing.T) { + // Arrange + b.SetDefaults() + TestSetup(t) + + if !isRealOrderTestEnabled() { + t.Skip() + } + + b.Verbose = true + currencyPair := pair.NewCurrencyPair(symbol.LTC, symbol.BTC) + + var orderCancellation = exchange.OrderCancellation{ + OrderID: "123456789012345678901234567890123456", + WalletAddress: "1F5zVDgNjorJ51oGebSvNCrSAHpwGkUdDB", + AccountID: "1", + CurrencyPair: currencyPair, + } + + // Act + err := b.CancelOrder(orderCancellation) + + // Assert + if err != nil { + t.Errorf("Could not cancel order: %s", err) + } +} diff --git a/exchanges/bitmex/bitmex_wrapper.go b/exchanges/bitmex/bitmex_wrapper.go index 8cd23019..14e228f7 100644 --- a/exchanges/bitmex/bitmex_wrapper.go +++ b/exchanges/bitmex/bitmex_wrapper.go @@ -177,8 +177,13 @@ func (b *Bitmex) ModifyOrder(orderID int64, action exchange.ModifyOrder) (int64, } // CancelOrder cancels an order by its corresponding ID number -func (b *Bitmex) CancelOrder(orderID int64) error { - return common.ErrNotYetImplemented +func (b *Bitmex) CancelOrder(order exchange.OrderCancellation) error { + var params = OrderCancelParams{ + OrderID: order.OrderID, + } + _, err := b.CancelOrders(params) + + return err } // CancelAllOrders cancels all orders associated with a currency pair diff --git a/exchanges/bitstamp/bitstamp_test.go b/exchanges/bitstamp/bitstamp_test.go index fe95bccc..eeb1e9b6 100644 --- a/exchanges/bitstamp/bitstamp_test.go +++ b/exchanges/bitstamp/bitstamp_test.go @@ -14,10 +14,10 @@ import ( // Please add your private keys and customerID for better tests const ( - apiKey = "" - apiSecret = "" - customerID = "" - canPlaceOrders = false + apiKey = "" + apiSecret = "" + customerID = "" + canManipulateRealOrders = false ) var b Bitstamp @@ -51,6 +51,8 @@ func TestSetup(t *testing.T) { } bConfig.APIKey = apiKey bConfig.APISecret = apiSecret + bConfig.ClientID = customerID + b.Setup(bConfig) if !b.IsEnabled() || b.RESTPollingDelay != time.Duration(10) || @@ -365,17 +367,25 @@ func TestFormatWithdrawPermissions(t *testing.T) { } } -// This will really really use the API to place an order -// If you're going to test this, make sure you're willing to place real orders on the exchange +// Any tests below this line have the ability to impact your orders on the exchange. Enable canManipulateRealOrders to run them +// ---------------------------------------------------------------------------------------------------------------------------- +func isRealOrderTestEnabled() bool { + if b.APIKey == "" || b.APISecret == "" || + b.APIKey == "Key" || b.APISecret == "Secret" || + !canManipulateRealOrders { + return false + } + return true +} + func TestSubmitOrder(t *testing.T) { b.SetDefaults() TestSetup(t) - if b.APIKey == "" || b.APISecret == "" || - b.APIKey == "Key" || b.APISecret == "Secret" || - !canPlaceOrders { + if !isRealOrderTestEnabled() { t.Skip() } + var p = pair.CurrencyPair{ Delimiter: "", FirstCurrency: symbol.BTC, @@ -386,3 +396,31 @@ func TestSubmitOrder(t *testing.T) { t.Errorf("Order failed to be placed: %v", err) } } + +func TestCancelExchangeOrder(t *testing.T) { + // Arrange + b.SetDefaults() + TestSetup(t) + + if !isRealOrderTestEnabled() { + t.Skip() + } + + b.Verbose = true + currencyPair := pair.NewCurrencyPair(symbol.LTC, symbol.BTC) + + var orderCancellation = exchange.OrderCancellation{ + OrderID: "1", + WalletAddress: "1F5zVDgNjorJ51oGebSvNCrSAHpwGkUdDB", + AccountID: "1", + CurrencyPair: currencyPair, + } + + // Act + err := b.CancelOrder(orderCancellation) + + // Assert + if err != nil { + t.Errorf("Could not cancel order: %s", err) + } +} diff --git a/exchanges/bitstamp/bitstamp_wrapper.go b/exchanges/bitstamp/bitstamp_wrapper.go index 11adf00e..9e50aca7 100644 --- a/exchanges/bitstamp/bitstamp_wrapper.go +++ b/exchanges/bitstamp/bitstamp_wrapper.go @@ -3,6 +3,7 @@ package bitstamp import ( "fmt" "log" + "strconv" "strings" "sync" @@ -189,8 +190,15 @@ func (b *Bitstamp) ModifyOrder(orderID int64, action exchange.ModifyOrder) (int6 } // CancelOrder cancels an order by its corresponding ID number -func (b *Bitstamp) CancelOrder(orderID int64) error { - return common.ErrNotYetImplemented +func (b *Bitstamp) CancelOrder(order exchange.OrderCancellation) error { + orderIDInt, err := strconv.ParseInt(order.OrderID, 10, 64) + + if err != nil { + return err + } + _, err = b.CancelExistingOrder(orderIDInt) + + return err } // CancelAllOrders cancels all orders associated with a currency pair diff --git a/exchanges/bittrex/bittrex_test.go b/exchanges/bittrex/bittrex_test.go index db38610b..9abf0162 100644 --- a/exchanges/bittrex/bittrex_test.go +++ b/exchanges/bittrex/bittrex_test.go @@ -12,9 +12,9 @@ import ( // Please supply you own test keys here to run better tests. const ( - apiKey = "" - apiSecret = "" - canPlaceOrders = false + apiKey = "" + apiSecret = "" + canManipulateRealOrders = false ) var b Bittrex @@ -333,17 +333,25 @@ func TestFormatWithdrawPermissions(t *testing.T) { } } -// This will really really use the API to place an order -// If you're going to test this, make sure you're willing to place real orders on the exchange +// Any tests below this line have the ability to impact your orders on the exchange. Enable canManipulateRealOrders to run them +// ---------------------------------------------------------------------------------------------------------------------------- +func isRealOrderTestEnabled() bool { + if b.APIKey == "" || b.APISecret == "" || + b.APIKey == "Key" || b.APISecret == "Secret" || + !canManipulateRealOrders { + return false + } + return true +} + func TestSubmitOrder(t *testing.T) { b.SetDefaults() TestSetup(t) - if b.APIKey == "" || b.APISecret == "" || - b.APIKey == "Key" || b.APISecret == "Secret" || - !canPlaceOrders { + if !isRealOrderTestEnabled() { t.Skip() } + var p = pair.CurrencyPair{ Delimiter: "-", FirstCurrency: symbol.BTC, @@ -354,3 +362,31 @@ func TestSubmitOrder(t *testing.T) { t.Errorf("Order failed to be placed: %v", err) } } + +func TestCancelExchangeOrder(t *testing.T) { + // Arrange + b.SetDefaults() + TestSetup(t) + + if !isRealOrderTestEnabled() { + t.Skip() + } + + b.Verbose = true + currencyPair := pair.NewCurrencyPair(symbol.LTC, symbol.BTC) + + var orderCancellation = exchange.OrderCancellation{ + OrderID: "1", + WalletAddress: "1F5zVDgNjorJ51oGebSvNCrSAHpwGkUdDB", + AccountID: "1", + CurrencyPair: currencyPair, + } + + // Act + err := b.CancelOrder(orderCancellation) + + // Assert + if err != nil { + t.Errorf("Could not cancel order: %s", err) + } +} diff --git a/exchanges/bittrex/bittrex_wrapper.go b/exchanges/bittrex/bittrex_wrapper.go index e9c4e9b6..20c9b20d 100644 --- a/exchanges/bittrex/bittrex_wrapper.go +++ b/exchanges/bittrex/bittrex_wrapper.go @@ -203,8 +203,10 @@ func (b *Bittrex) ModifyOrder(orderID int64, action exchange.ModifyOrder) (int64 } // CancelOrder cancels an order by its corresponding ID number -func (b *Bittrex) CancelOrder(orderID int64) error { - return common.ErrNotYetImplemented +func (b *Bittrex) CancelOrder(order exchange.OrderCancellation) error { + _, err := b.CancelExistingOrder(order.OrderID) + + return err } // CancelAllOrders cancels all orders associated with a currency pair diff --git a/exchanges/btcc/btcc_test.go b/exchanges/btcc/btcc_test.go index 32c4b947..cac2391a 100644 --- a/exchanges/btcc/btcc_test.go +++ b/exchanges/btcc/btcc_test.go @@ -5,14 +5,16 @@ import ( "time" "github.com/thrasher-/gocryptotrader/config" + "github.com/thrasher-/gocryptotrader/currency/pair" "github.com/thrasher-/gocryptotrader/currency/symbol" exchange "github.com/thrasher-/gocryptotrader/exchanges" ) // Please supply your own APIkeys here to do better tests const ( - apiKey = "" - apiSecret = "" + apiKey = "" + apiSecret = "" + canManipulateRealOrders = false ) var b BTCC @@ -168,3 +170,61 @@ func TestFormatWithdrawPermissions(t *testing.T) { t.Errorf("Expected: %s, Recieved: %s", expectedResult, withdrawPermissions) } } + +// Any tests below this line have the ability to impact your orders on the exchange. Enable canManipulateRealOrders to run them +// ---------------------------------------------------------------------------------------------------------------------------- +func isRealOrderTestEnabled() bool { + if b.APIKey == "" || b.APISecret == "" || + b.APIKey == "Key" || b.APISecret == "Secret" || + !canManipulateRealOrders { + return false + } + return true +} + +func TestSubmitOrder(t *testing.T) { + b.SetDefaults() + TestSetup(t) + + if !isRealOrderTestEnabled() { + t.Skip() + } + + var p = pair.CurrencyPair{ + Delimiter: "-", + FirstCurrency: symbol.BTC, + SecondCurrency: symbol.LTC, + } + response, err := b.SubmitOrder(p, exchange.Buy, exchange.Limit, 1, 1, "clientId") + if err != nil || !response.IsOrderPlaced { + t.Errorf("Order failed to be placed: %v", err) + } +} + +func TestCancelExchangeOrder(t *testing.T) { + // Arrange + b.SetDefaults() + TestSetup(t) + + if !isRealOrderTestEnabled() { + t.Skip() + } + + b.Verbose = true + currencyPair := pair.NewCurrencyPair(symbol.LTC, symbol.BTC) + + var orderCancellation = exchange.OrderCancellation{ + OrderID: "1", + WalletAddress: "1F5zVDgNjorJ51oGebSvNCrSAHpwGkUdDB", + AccountID: "1", + CurrencyPair: currencyPair, + } + + // Act + err := b.CancelOrder(orderCancellation) + + // Assert + if err != nil { + t.Errorf("Could not cancel order: %s", err) + } +} diff --git a/exchanges/btcc/btcc_wrapper.go b/exchanges/btcc/btcc_wrapper.go index 54d1d53c..8648e600 100644 --- a/exchanges/btcc/btcc_wrapper.go +++ b/exchanges/btcc/btcc_wrapper.go @@ -164,7 +164,7 @@ func (b *BTCC) ModifyOrder(orderID int64, action exchange.ModifyOrder) (int64, e } // CancelOrder cancels an order by its corresponding ID number -func (b *BTCC) CancelOrder(orderID int64) error { +func (b *BTCC) CancelOrder(order exchange.OrderCancellation) error { return common.ErrNotYetImplemented } diff --git a/exchanges/btcmarkets/btcmarkets_test.go b/exchanges/btcmarkets/btcmarkets_test.go index be0c077b..acbec6f0 100644 --- a/exchanges/btcmarkets/btcmarkets_test.go +++ b/exchanges/btcmarkets/btcmarkets_test.go @@ -14,9 +14,9 @@ var b BTCMarkets // Please supply your own keys here to do better tests const ( - apiKey = "" - apiSecret = "" - canPlaceOrders = false + apiKey = "" + apiSecret = "" + canManipulateRealOrders = false ) func TestSetDefaults(t *testing.T) { @@ -161,7 +161,9 @@ func TestModifyOrder(t *testing.T) { } func TestCancelOrder(t *testing.T) { - err := b.CancelOrder(1337) + + _, err := b.CancelExistingOrder([]int64{1337}) + if err == nil { t.Error("Test failed - CancelgOrder() error", err) } @@ -302,17 +304,25 @@ func TestFormatWithdrawPermissions(t *testing.T) { } } -// This will really really use the API to place an order -// If you're going to test this, make sure you're willing to place real orders on the exchange +// Any tests below this line have the ability to impact your orders on the exchange. Enable canManipulateRealOrders to run them +// ---------------------------------------------------------------------------------------------------------------------------- +func isRealOrderTestEnabled() bool { + if b.APIKey == "" || b.APISecret == "" || + b.APIKey == "Key" || b.APISecret == "Secret" || + !canManipulateRealOrders { + return false + } + return true +} + func TestSubmitOrder(t *testing.T) { b.SetDefaults() TestSetup(t) - if b.APIKey == "" || b.APISecret == "" || - b.APIKey == "Key" || b.APISecret == "Secret" || - !canPlaceOrders { + if !isRealOrderTestEnabled() { t.Skip() } + var p = pair.CurrencyPair{ Delimiter: "-", FirstCurrency: symbol.BTC, @@ -323,3 +333,31 @@ func TestSubmitOrder(t *testing.T) { t.Errorf("Order failed to be placed: %v", err) } } + +func TestCancelExchangeOrder(t *testing.T) { + // Arrange + b.SetDefaults() + TestSetup(t) + + if !isRealOrderTestEnabled() { + t.Skip() + } + + b.Verbose = true + currencyPair := pair.NewCurrencyPair(symbol.LTC, symbol.BTC) + + var orderCancellation = exchange.OrderCancellation{ + OrderID: "1", + WalletAddress: "1F5zVDgNjorJ51oGebSvNCrSAHpwGkUdDB", + AccountID: "1", + CurrencyPair: currencyPair, + } + + // Act + err := b.CancelOrder(orderCancellation) + + // Assert + if err != nil { + t.Errorf("Could not cancel order: %s", err) + } +} diff --git a/exchanges/btcmarkets/btcmarkets_types.go b/exchanges/btcmarkets/btcmarkets_types.go index 97fec971..bd43b364 100644 --- a/exchanges/btcmarkets/btcmarkets_types.go +++ b/exchanges/btcmarkets/btcmarkets_types.go @@ -75,7 +75,7 @@ type OrderToGo struct { // Order holds order information type Order struct { - ID int64 `json:"id"` + ID string `json:"id"` Currency string `json:"currency"` Instrument string `json:"instrument"` OrderSide string `json:"orderSide"` diff --git a/exchanges/btcmarkets/btcmarkets_wrapper.go b/exchanges/btcmarkets/btcmarkets_wrapper.go index b95f4fab..2fb7a54d 100644 --- a/exchanges/btcmarkets/btcmarkets_wrapper.go +++ b/exchanges/btcmarkets/btcmarkets_wrapper.go @@ -4,6 +4,7 @@ import ( "errors" "fmt" "log" + "strconv" "sync" "github.com/thrasher-/gocryptotrader/common" @@ -176,12 +177,12 @@ func (b *BTCMarkets) ModifyOrder(orderID int64, action exchange.ModifyOrder) (in } // CancelOrder cancels an order by its corresponding ID number -func (b *BTCMarkets) CancelOrder(orderID int64) error { - _, err := b.CancelExistingOrder([]int64{orderID}) - if err != nil { - return err - } - return nil +func (b *BTCMarkets) CancelOrder(order exchange.OrderCancellation) error { + orderIDInt, err := strconv.ParseInt(order.OrderID, 10, 64) + + _, err = b.CancelExistingOrder([]int64{orderIDInt}) + + return err } // CancelAllOrders cancels all orders associated with a currency pair @@ -193,7 +194,13 @@ func (b *BTCMarkets) CancelAllOrders() error { var orderList []int64 for _, order := range orders { - orderList = append(orderList, order.ID) + orderIDInt, strconvErr := strconv.ParseInt(order.ID, 10, 64) + + if strconvErr != nil { + return strconvErr + } + + orderList = append(orderList, orderIDInt) } _, err = b.CancelExistingOrder(orderList) diff --git a/exchanges/coinbasepro/coinbasepro_test.go b/exchanges/coinbasepro/coinbasepro_test.go index c80843ad..1cc728cb 100644 --- a/exchanges/coinbasepro/coinbasepro_test.go +++ b/exchanges/coinbasepro/coinbasepro_test.go @@ -1,7 +1,6 @@ package coinbasepro import ( - "fmt" "testing" "time" @@ -15,10 +14,10 @@ var c CoinbasePro // Please supply your APIKeys here for better testing const ( - apiKey = "" - apiSecret = "" - clientID = "" //passphrase you made at API CREATION - canPlaceOrders = false + apiKey = "" + apiSecret = "" + clientID = "" //passphrase you made at API CREATION + canManipulateRealOrders = false ) func TestSetDefaults(t *testing.T) { @@ -408,17 +407,25 @@ func TestFormatWithdrawPermissions(t *testing.T) { } } -// This will really really use the API to place an order -// If you're going to test this, make sure you're willing to place real orders on the exchange +// Any tests below this line have the ability to impact your orders on the exchange. Enable canManipulateRealOrders to run them +// ---------------------------------------------------------------------------------------------------------------------------- +func isRealOrderTestEnabled() bool { + if c.APIKey == "" || c.APISecret == "" || + c.APIKey == "Key" || c.APISecret == "Secret" || + !canManipulateRealOrders { + return false + } + return true +} + func TestSubmitOrder(t *testing.T) { c.SetDefaults() TestSetup(t) - if c.APIKey == "" || c.APISecret == "" || - c.APIKey == "Key" || c.APISecret == "Secret" || - !canPlaceOrders { - t.Skip(fmt.Sprintf("ApiKey: %s. Can Place others: %v", c.APIKey, canPlaceOrders)) + if !isRealOrderTestEnabled() { + t.Skip() } + var p = pair.CurrencyPair{ Delimiter: "-", FirstCurrency: symbol.BTC, @@ -429,3 +436,31 @@ func TestSubmitOrder(t *testing.T) { t.Errorf("Order failed to be placed: %v", err) } } + +func TestCancelExchangeOrder(t *testing.T) { + // Arrange + c.SetDefaults() + TestSetup(t) + + if !isRealOrderTestEnabled() { + t.Skip() + } + + c.Verbose = true + currencyPair := pair.NewCurrencyPair(symbol.LTC, symbol.BTC) + + var orderCancellation = exchange.OrderCancellation{ + OrderID: "1", + WalletAddress: "1F5zVDgNjorJ51oGebSvNCrSAHpwGkUdDB", + AccountID: "1", + CurrencyPair: currencyPair, + } + + // Act + err := c.CancelOrder(orderCancellation) + + // Assert + if err != nil { + t.Errorf("Could not cancel order: %s", err) + } +} diff --git a/exchanges/coinbasepro/coinbasepro_wrapper.go b/exchanges/coinbasepro/coinbasepro_wrapper.go index cb2d5ac1..76a11507 100644 --- a/exchanges/coinbasepro/coinbasepro_wrapper.go +++ b/exchanges/coinbasepro/coinbasepro_wrapper.go @@ -175,8 +175,8 @@ func (c *CoinbasePro) ModifyOrder(orderID int64, action exchange.ModifyOrder) (i } // CancelOrder cancels an order by its corresponding ID number -func (c *CoinbasePro) CancelOrder(orderID int64) error { - return common.ErrNotYetImplemented +func (c *CoinbasePro) CancelOrder(order exchange.OrderCancellation) error { + return c.CancelExistingOrder(order.OrderID) } // CancelAllOrders cancels all orders associated with a currency pair diff --git a/exchanges/coinut/coinut.go b/exchanges/coinut/coinut.go index 6f1af74c..24a0c2d6 100644 --- a/exchanges/coinut/coinut.go +++ b/exchanges/coinut/coinut.go @@ -216,8 +216,18 @@ func (c *COINUT) GetOpenOrders(instrumentID int) ([]OrdersResponse, error) { func (c *COINUT) CancelExistingOrder(instrumentID, orderID int) (bool, error) { var result GenericResponse params := make(map[string]interface{}) - params["inst_id"] = instrumentID - params["order_id"] = orderID + type Request struct { + InstrumentID int `json:"inst_id"` + OrderID int `json:"order_id"` + } + + var entry = Request{ + InstrumentID: instrumentID, + OrderID: orderID, + } + + entries := []Request{entry} + params["entries"] = entries err := c.SendHTTPRequest(coinutOrdersCancel, params, true, &result) if err != nil { diff --git a/exchanges/coinut/coinut_test.go b/exchanges/coinut/coinut_test.go index 7a5038fe..39417034 100644 --- a/exchanges/coinut/coinut_test.go +++ b/exchanges/coinut/coinut_test.go @@ -1,7 +1,6 @@ package coinut import ( - "fmt" "testing" "time" @@ -15,9 +14,9 @@ var c COINUT // Please supply your own keys here to do better tests const ( - apiKey = "" - apiSecret = "" - canPlaceOrders = false + apiKey = "" + apiSecret = "" + canManipulateRealOrders = false ) func TestSetDefaults(t *testing.T) { @@ -193,18 +192,26 @@ func TestFormatWithdrawPermissions(t *testing.T) { } } -// This will really really use the API to place an order -// If you're going to test this, make sure you're willing to place real orders on the exchange +// Any tests below this line have the ability to impact your orders on the exchange. Enable canManipulateRealOrders to run them +// ---------------------------------------------------------------------------------------------------------------------------- +func isRealOrderTestEnabled() bool { + if c.APISecret == "" || + c.APISecret == "Secret" || + !canManipulateRealOrders { + return false + } + return true +} + func TestSubmitOrder(t *testing.T) { c.SetDefaults() TestSetup(t) c.Verbose = true - if c.APISecret == "" || - c.APISecret == "Secret" || - !canPlaceOrders { - t.Skip(fmt.Sprintf("ApiKey: %s. Can place orders: %v", c.APIKey, canPlaceOrders)) + if !isRealOrderTestEnabled() { + t.Skip() } + var p = pair.CurrencyPair{ Delimiter: "", FirstCurrency: symbol.BTC, @@ -215,3 +222,31 @@ func TestSubmitOrder(t *testing.T) { t.Errorf("Order failed to be placed: %v", err) } } + +func TestCancelExchangeOrder(t *testing.T) { + // Arrange + c.SetDefaults() + TestSetup(t) + + if !isRealOrderTestEnabled() { + t.Skip() + } + + c.Verbose = true + currencyPair := pair.NewCurrencyPair(symbol.LTC, symbol.BTC) + + var orderCancellation = exchange.OrderCancellation{ + OrderID: "1", + WalletAddress: "1F5zVDgNjorJ51oGebSvNCrSAHpwGkUdDB", + AccountID: "1", + CurrencyPair: currencyPair, + } + + // Act + err := c.CancelOrder(orderCancellation) + + // Assert + if err != nil { + t.Errorf("Could not cancel order: %s", err) + } +} diff --git a/exchanges/coinut/coinut_wrapper.go b/exchanges/coinut/coinut_wrapper.go index 2391710a..5c085514 100644 --- a/exchanges/coinut/coinut_wrapper.go +++ b/exchanges/coinut/coinut_wrapper.go @@ -199,8 +199,25 @@ func (c *COINUT) ModifyOrder(orderID int64, action exchange.ModifyOrder) (int64, } // CancelOrder cancels an order by its corresponding ID number -func (c *COINUT) CancelOrder(orderID int64) error { - return common.ErrNotYetImplemented +func (c *COINUT) CancelOrder(order exchange.OrderCancellation) error { + orderIDInt, err := strconv.ParseInt(order.OrderID, 10, 64) + + if err != nil { + return err + } + + // Need to get the ID of the currency sent + instruments, err := c.GetInstruments() + + if err != nil { + return err + } + + currencyArray := instruments.Instruments[exchange.FormatExchangeCurrency(c.Name, order.CurrencyPair).String()] + currencyID := currencyArray[0].InstID + _, err = c.CancelExistingOrder(currencyID, int(orderIDInt)) + + return err } // CancelAllOrders cancels all orders associated with a currency pair diff --git a/exchanges/exchange.go b/exchanges/exchange.go index 4765350b..5d968c77 100644 --- a/exchanges/exchange.go +++ b/exchanges/exchange.go @@ -89,6 +89,15 @@ type FeeBuilder struct { Amount float64 } +// OrderCancellation type requred when requesting to cancel an order +type OrderCancellation struct { + AccountID string + OrderID string + CurrencyPair pair.CurrencyPair + WalletAddress string + Side OrderSide +} + // Definitions for each type of withdrawal method for a given exchange const ( // No withdraw @@ -161,7 +170,7 @@ type TradeHistory struct { // OrderDetail holds order detail data type OrderDetail struct { Exchange string - ID int64 + ID string BaseCurrency string QuoteCurrency string OrderSide string @@ -254,7 +263,7 @@ type IBotExchange interface { GetFundingHistory() ([]FundHistory, error) SubmitOrder(p pair.CurrencyPair, side OrderSide, orderType OrderType, amount, price float64, clientID string) (SubmitOrderResponse, error) ModifyOrder(orderID int64, modify ModifyOrder) (int64, error) - CancelOrder(orderID int64) error + CancelOrder(order OrderCancellation) error CancelAllOrders() error GetOrderInfo(orderID int64) (OrderDetail, error) GetDepositAddress(cryptocurrency pair.CurrencyItem) (string, error) diff --git a/exchanges/exmo/exmo_test.go b/exchanges/exmo/exmo_test.go index 7383f2d7..d94aeb7e 100644 --- a/exchanges/exmo/exmo_test.go +++ b/exchanges/exmo/exmo_test.go @@ -1,7 +1,6 @@ package exmo import ( - "fmt" "testing" "github.com/thrasher-/gocryptotrader/currency/pair" @@ -10,9 +9,9 @@ import ( ) const ( - APIKey = "" - APISecret = "" - canPlaceOrders = false + APIKey = "" + APISecret = "" + canManipulateRealOrders = false ) var ( @@ -249,18 +248,26 @@ func TestFormatWithdrawPermissions(t *testing.T) { } } -// This will really really use the API to place an order -// If you're going to test this, make sure you're willing to place real orders on the exchange +// Any tests below this line have the ability to impact your orders on the exchange. Enable canManipulateRealOrders to run them +// ---------------------------------------------------------------------------------------------------------------------------- +func isRealOrderTestEnabled() bool { + if e.APIKey == "" || e.APISecret == "" || + e.APIKey == "Key" || e.APISecret == "Secret" || + !canManipulateRealOrders { + return false + } + return true +} + func TestSubmitOrder(t *testing.T) { e.SetDefaults() TestSetup(t) e.Verbose = true - if e.APISecret == "" || - e.APISecret == "Secret" || - !canPlaceOrders { - t.Skip(fmt.Sprintf("ApiKey: %s. Can place orders: %v", e.APIKey, canPlaceOrders)) + if !isRealOrderTestEnabled() { + t.Skip() } + var p = pair.CurrencyPair{ Delimiter: "_", FirstCurrency: symbol.BTC, @@ -271,3 +278,31 @@ func TestSubmitOrder(t *testing.T) { t.Errorf("Order failed to be placed: %v", err) } } + +func TestCancelExchangeOrder(t *testing.T) { + // Arrange + e.SetDefaults() + TestSetup(t) + + if !isRealOrderTestEnabled() { + t.Skip() + } + + e.Verbose = true + currencyPair := pair.NewCurrencyPair(symbol.LTC, symbol.BTC) + + var orderCancellation = exchange.OrderCancellation{ + OrderID: "1", + WalletAddress: "1F5zVDgNjorJ51oGebSvNCrSAHpwGkUdDB", + AccountID: "1", + CurrencyPair: currencyPair, + } + + // Act + err := e.CancelOrder(orderCancellation) + + // Assert + if err != nil { + t.Errorf("Could not cancel order: %s", err) + } +} diff --git a/exchanges/exmo/exmo_wrapper.go b/exchanges/exmo/exmo_wrapper.go index 550aec1f..9e329785 100644 --- a/exchanges/exmo/exmo_wrapper.go +++ b/exchanges/exmo/exmo_wrapper.go @@ -212,8 +212,14 @@ func (e *EXMO) ModifyOrder(orderID int64, action exchange.ModifyOrder) (int64, e } // CancelOrder cancels an order by its corresponding ID number -func (e *EXMO) CancelOrder(orderID int64) error { - return common.ErrNotYetImplemented +func (e *EXMO) CancelOrder(order exchange.OrderCancellation) error { + orderIDInt, err := strconv.ParseInt(order.OrderID, 10, 64) + + if err != nil { + return err + } + + return e.CancelExistingOrder(orderIDInt) } // CancelAllOrders cancels all orders associated with a currency pair diff --git a/exchanges/gateio/gateio_test.go b/exchanges/gateio/gateio_test.go index 357eb523..0134bd7e 100644 --- a/exchanges/gateio/gateio_test.go +++ b/exchanges/gateio/gateio_test.go @@ -1,7 +1,6 @@ package gateio import ( - "fmt" "testing" "github.com/thrasher-/gocryptotrader/config" @@ -13,9 +12,9 @@ import ( // Please supply your own APIKEYS here for due diligence testing const ( - apiKey = "" - apiSecret = "" - canPlaceOrders = false + apiKey = "" + apiSecret = "" + canManipulateRealOrders = false ) var g Gateio @@ -251,18 +250,26 @@ func TestFormatWithdrawPermissions(t *testing.T) { } } -// This will really really use the API to place an order -// If you're going to test this, make sure you're willing to place real orders on the exchange +// Any tests below this line have the ability to impact your orders on the exchange. Enable canManipulateRealOrders to run them +// ---------------------------------------------------------------------------------------------------------------------------- +func isRealOrderTestEnabled() bool { + if g.APIKey == "" || g.APISecret == "" || + g.APIKey == "Key" || g.APISecret == "Secret" || + !canManipulateRealOrders { + return false + } + return true +} + func TestSubmitOrder(t *testing.T) { g.SetDefaults() TestSetup(t) g.Verbose = true - if g.APIKey == "" || g.APISecret == "" || - g.APIKey == "Key" || g.APISecret == "Secret" || - !canPlaceOrders { - t.Skip(fmt.Sprintf("ApiKey: %s. Can place orders: %v", g.APIKey, canPlaceOrders)) + if !isRealOrderTestEnabled() { + t.Skip() } + var p = pair.CurrencyPair{ Delimiter: "_", FirstCurrency: symbol.LTC, @@ -273,3 +280,31 @@ func TestSubmitOrder(t *testing.T) { t.Errorf("Order failed to be placed: %v", err) } } + +func TestCancelExchangeOrder(t *testing.T) { + // Arrange + g.SetDefaults() + TestSetup(t) + + if !isRealOrderTestEnabled() { + t.Skip() + } + + g.Verbose = true + currencyPair := pair.NewCurrencyPair(symbol.LTC, symbol.BTC) + + var orderCancellation = exchange.OrderCancellation{ + OrderID: "1", + WalletAddress: "1F5zVDgNjorJ51oGebSvNCrSAHpwGkUdDB", + AccountID: "1", + CurrencyPair: currencyPair, + } + + // Act + err := g.CancelOrder(orderCancellation) + + // Assert + if err != nil { + t.Errorf("Could not cancel order: %s", err) + } +} diff --git a/exchanges/gateio/gateio_wrapper.go b/exchanges/gateio/gateio_wrapper.go index a30f72c8..01bbcfd0 100644 --- a/exchanges/gateio/gateio_wrapper.go +++ b/exchanges/gateio/gateio_wrapper.go @@ -4,6 +4,7 @@ import ( "errors" "fmt" "log" + "strconv" "sync" "github.com/thrasher-/gocryptotrader/common" @@ -165,8 +166,15 @@ func (g *Gateio) ModifyOrder(orderID int64, action exchange.ModifyOrder) (int64, } // CancelOrder cancels an order by its corresponding ID number -func (g *Gateio) CancelOrder(orderID int64) error { - return common.ErrNotYetImplemented +func (g *Gateio) CancelOrder(order exchange.OrderCancellation) error { + orderIDInt, err := strconv.ParseInt(order.OrderID, 10, 64) + + if err != nil { + return err + } + _, err = g.CancelExistingOrder(orderIDInt, exchange.FormatExchangeCurrency(g.Name, order.CurrencyPair).String()) + + return err } // CancelAllOrders cancels all orders associated with a currency pair diff --git a/exchanges/gemini/gemini_test.go b/exchanges/gemini/gemini_test.go index a0f60dfa..f4f90161 100644 --- a/exchanges/gemini/gemini_test.go +++ b/exchanges/gemini/gemini_test.go @@ -1,7 +1,6 @@ package gemini import ( - "fmt" "net/url" "testing" @@ -24,7 +23,7 @@ const ( apiKeyRole2 = "" sessionHeartBeat2 = false - canPlaceOrders = false + canManipulateRealOrders = false ) func TestAddSession(t *testing.T) { @@ -325,18 +324,26 @@ func TestFormatWithdrawPermissions(t *testing.T) { } } -// This will really really use the API to place an order -// If you're going to test this, make sure you're willing to place real orders on the exchange +// Any tests below this line have the ability to impact your orders on the exchange. Enable canManipulateRealOrders to run them +// ---------------------------------------------------------------------------------------------------------------------------- +func isRealOrderTestEnabled() bool { + if Session[1].APIKey == "" || Session[1].APISecret == "" || + Session[1].APIKey == "Key" || Session[1].APISecret == "Secret" || + !canManipulateRealOrders { + return false + } + return true +} + func TestSubmitOrder(t *testing.T) { Session[1].SetDefaults() TestSetup(t) Session[1].Verbose = true - if Session[1].APIKey == "" || Session[1].APISecret == "" || - Session[1].APIKey == "Key" || Session[1].APISecret == "Secret" || - !canPlaceOrders { - t.Skip(fmt.Sprintf("ApiKey: %s. Can place orders: %v", Session[1].APIKey, canPlaceOrders)) + if !isRealOrderTestEnabled() { + t.Skip() } + var p = pair.CurrencyPair{ Delimiter: "_", FirstCurrency: symbol.LTC, @@ -347,3 +354,31 @@ func TestSubmitOrder(t *testing.T) { t.Errorf("Order failed to be placed: %v", err) } } + +func TestCancelExchangeOrder(t *testing.T) { + // Arrange + Session[1].SetDefaults() + TestSetup(t) + + if !isRealOrderTestEnabled() { + t.Skip() + } + + Session[1].Verbose = true + currencyPair := pair.NewCurrencyPair(symbol.LTC, symbol.BTC) + + var orderCancellation = exchange.OrderCancellation{ + OrderID: "1", + WalletAddress: "1F5zVDgNjorJ51oGebSvNCrSAHpwGkUdDB", + AccountID: "1", + CurrencyPair: currencyPair, + } + + // Act + err := Session[1].CancelOrder(orderCancellation) + + // Assert + if err != nil { + t.Errorf("Could not cancel order: %s", err) + } +} diff --git a/exchanges/gemini/gemini_wrapper.go b/exchanges/gemini/gemini_wrapper.go index adef578e..48ae004e 100644 --- a/exchanges/gemini/gemini_wrapper.go +++ b/exchanges/gemini/gemini_wrapper.go @@ -4,6 +4,7 @@ import ( "fmt" "log" "net/url" + "strconv" "sync" "github.com/thrasher-/gocryptotrader/common" @@ -150,8 +151,16 @@ func (g *Gemini) ModifyOrder(orderID int64, action exchange.ModifyOrder) (int64, } // CancelOrder cancels an order by its corresponding ID number -func (g *Gemini) CancelOrder(orderID int64) error { - return common.ErrNotYetImplemented +func (g *Gemini) CancelOrder(order exchange.OrderCancellation) error { + orderIDInt, err := strconv.ParseInt(order.OrderID, 10, 64) + + if err != nil { + return err + } + + _, err = g.CancelExistingOrder(orderIDInt) + + return err } // CancelAllOrders cancels all orders associated with a currency pair diff --git a/exchanges/hitbtc/hitbtc.go b/exchanges/hitbtc/hitbtc.go index e8bfae4d..0174fed4 100644 --- a/exchanges/hitbtc/hitbtc.go +++ b/exchanges/hitbtc/hitbtc.go @@ -39,7 +39,6 @@ const ( orders = "order" orderBuy = "api/2/order" orderSell = "sell" - orderCancel = "cancelOrder" orderMove = "moveOrder" tradableBalances = "returnTradableBalances" transferBalance = "transferBalance" @@ -436,9 +435,8 @@ func (h *HitBTC) PlaceOrder(currency string, rate, amount float64, orderType, si func (h *HitBTC) CancelExistingOrder(orderID int64) (bool, error) { result := GenericResponse{} values := url.Values{} - values.Set("orderNumber", strconv.FormatInt(orderID, 10)) - err := h.SendAuthenticatedHTTPRequest("POST", orderCancel, values, &result) + err := h.SendAuthenticatedHTTPRequest("DELETE", orderBuy+"/"+strconv.FormatInt(orderID, 10), values, &result) if err != nil { return false, err diff --git a/exchanges/hitbtc/hitbtc_test.go b/exchanges/hitbtc/hitbtc_test.go index 3f470181..eb80a064 100644 --- a/exchanges/hitbtc/hitbtc_test.go +++ b/exchanges/hitbtc/hitbtc_test.go @@ -1,7 +1,6 @@ package hitbtc import ( - "fmt" "testing" "github.com/thrasher-/gocryptotrader/config" @@ -15,9 +14,9 @@ var h HitBTC // Please supply your own APIKEYS here for due diligence testing const ( - apiKey = "" - apiSecret = "" - canPlaceOrders = false + apiKey = "" + apiSecret = "" + canManipulateRealOrders = false ) func TestSetDefaults(t *testing.T) { @@ -176,18 +175,26 @@ func TestFormatWithdrawPermissions(t *testing.T) { } } -// This will really really use the API to place an order -// If you're going to test this, make sure you're willing to place real orders on the exchange +// Any tests below this line have the ability to impact your orders on the exchange. Enable canManipulateRealOrders to run them +// ---------------------------------------------------------------------------------------------------------------------------- +func isRealOrderTestEnabled() bool { + if h.APIKey == "" || h.APISecret == "" || + h.APIKey == "Key" || h.APISecret == "Secret" || + !canManipulateRealOrders { + return false + } + return true +} + func TestSubmitOrder(t *testing.T) { h.SetDefaults() TestSetup(t) h.Verbose = true - if h.APIKey == "" || h.APISecret == "" || - h.APIKey == "Key" || h.APISecret == "Secret" || - !canPlaceOrders { - t.Skip(fmt.Sprintf("ApiKey: %s. Can place orders: %v", h.APIKey, canPlaceOrders)) + if !isRealOrderTestEnabled() { + t.Skip() } + var p = pair.CurrencyPair{ Delimiter: "", FirstCurrency: symbol.DGD, @@ -198,3 +205,31 @@ func TestSubmitOrder(t *testing.T) { t.Errorf("Order failed to be placed: %v", err) } } + +func TestCancelExchangeOrder(t *testing.T) { + // Arrange + h.SetDefaults() + TestSetup(t) + + if !isRealOrderTestEnabled() { + t.Skip() + } + + h.Verbose = true + currencyPair := pair.NewCurrencyPair(symbol.LTC, symbol.BTC) + + var orderCancellation = exchange.OrderCancellation{ + OrderID: "1", + WalletAddress: "1F5zVDgNjorJ51oGebSvNCrSAHpwGkUdDB", + AccountID: "1", + CurrencyPair: currencyPair, + } + + // Act + err := h.CancelOrder(orderCancellation) + + // Assert + if err != nil { + t.Errorf("Could not cancel order: %s", err) + } +} diff --git a/exchanges/hitbtc/hitbtc_wrapper.go b/exchanges/hitbtc/hitbtc_wrapper.go index 0a2272d1..1ed0fc5d 100644 --- a/exchanges/hitbtc/hitbtc_wrapper.go +++ b/exchanges/hitbtc/hitbtc_wrapper.go @@ -3,6 +3,7 @@ package hitbtc import ( "fmt" "log" + "strconv" "sync" "github.com/thrasher-/gocryptotrader/common" @@ -177,8 +178,16 @@ func (h *HitBTC) ModifyOrder(orderID int64, action exchange.ModifyOrder) (int64, } // CancelOrder cancels an order by its corresponding ID number -func (h *HitBTC) CancelOrder(orderID int64) error { - return common.ErrNotYetImplemented +func (h *HitBTC) CancelOrder(order exchange.OrderCancellation) error { + orderIDInt, err := strconv.ParseInt(order.OrderID, 10, 64) + + if err != nil { + return err + } + + _, err = h.CancelExistingOrder(orderIDInt) + + return err } // CancelAllOrders cancels all orders associated with a currency pair diff --git a/exchanges/huobi/huobi_test.go b/exchanges/huobi/huobi_test.go index e2ac2ed2..043309fa 100644 --- a/exchanges/huobi/huobi_test.go +++ b/exchanges/huobi/huobi_test.go @@ -5,7 +5,6 @@ import ( "crypto/rand" "crypto/x509" "encoding/pem" - "fmt" "io/ioutil" "strconv" "strings" @@ -20,9 +19,9 @@ import ( // Please supply you own test keys here for due diligence testing. const ( - apiKey = "" - apiSecret = "" - canPlaceOrders = false + apiKey = "" + apiSecret = "" + canManipulateRealOrders = false ) var h HUOBI @@ -397,18 +396,26 @@ func TestFormatWithdrawPermissions(t *testing.T) { } } -// This will really really use the API to place an order -// If you're going to test this, make sure you're willing to place real orders on the exchange +// Any tests below this line have the ability to impact your orders on the exchange. Enable canManipulateRealOrders to run them +// ---------------------------------------------------------------------------------------------------------------------------- +func isRealOrderTestEnabled() bool { + if h.APIKey == "" || h.APISecret == "" || + h.APIKey == "Key" || h.APISecret == "Secret" || + !canManipulateRealOrders { + return false + } + return true +} + func TestSubmitOrder(t *testing.T) { h.SetDefaults() TestSetup(t) h.Verbose = true - if h.APIKey == "" || h.APISecret == "" || - h.APIKey == "Key" || h.APISecret == "Secret" || - !canPlaceOrders { - t.Skip(fmt.Sprintf("ApiKey: %s. Can place orders: %v", h.APIKey, canPlaceOrders)) + if !isRealOrderTestEnabled() { + t.Skip() } + var p = pair.CurrencyPair{ Delimiter: "", FirstCurrency: symbol.BTC, @@ -421,3 +428,31 @@ func TestSubmitOrder(t *testing.T) { t.Errorf("Order failed to be placed: %v", err) } } + +func TestCancelExchangeOrder(t *testing.T) { + // Arrange + h.SetDefaults() + TestSetup(t) + + if !isRealOrderTestEnabled() { + t.Skip() + } + + h.Verbose = true + currencyPair := pair.NewCurrencyPair(symbol.LTC, symbol.BTC) + + var orderCancellation = exchange.OrderCancellation{ + OrderID: "1", + WalletAddress: "1F5zVDgNjorJ51oGebSvNCrSAHpwGkUdDB", + AccountID: "1", + CurrencyPair: currencyPair, + } + + // Act + err := h.CancelOrder(orderCancellation) + + // Assert + if err != nil { + t.Errorf("Could not cancel order: %s", err) + } +} diff --git a/exchanges/huobi/huobi_wrapper.go b/exchanges/huobi/huobi_wrapper.go index 5c80fb83..63c34a47 100644 --- a/exchanges/huobi/huobi_wrapper.go +++ b/exchanges/huobi/huobi_wrapper.go @@ -219,8 +219,16 @@ func (h *HUOBI) ModifyOrder(orderID int64, action exchange.ModifyOrder) (int64, } // CancelOrder cancels an order by its corresponding ID number -func (h *HUOBI) CancelOrder(orderID int64) error { - return common.ErrNotYetImplemented +func (h *HUOBI) CancelOrder(order exchange.OrderCancellation) error { + orderIDInt, err := strconv.ParseInt(order.OrderID, 10, 64) + + if err != nil { + return err + } + + _, err = h.CancelExistingOrder(orderIDInt) + + return err } // CancelAllOrders cancels all orders associated with a currency pair diff --git a/exchanges/huobihadax/huobihadax_test.go b/exchanges/huobihadax/huobihadax_test.go index e60afc8e..17eebe8f 100644 --- a/exchanges/huobihadax/huobihadax_test.go +++ b/exchanges/huobihadax/huobihadax_test.go @@ -14,9 +14,9 @@ import ( // Please supply your own APIKEYS here for due diligence testing const ( - apiKey = "" - apiSecret = "" - canPlaceOrders = false + apiKey = "" + apiSecret = "" + canManipulateRealOrders = false ) var h HUOBIHADAX @@ -375,18 +375,26 @@ func TestFormatWithdrawPermissions(t *testing.T) { } } -// This will really really use the API to place an order -// If you're going to test this, make sure you're willing to place real orders on the exchange +// Any tests below this line have the ability to impact your orders on the exchange. Enable canManipulateRealOrders to run them +// ---------------------------------------------------------------------------------------------------------------------------- +func isRealOrderTestEnabled() bool { + if h.APIKey == "" || h.APISecret == "" || + h.APIKey == "Key" || h.APISecret == "Secret" || + !canManipulateRealOrders { + return false + } + return true +} + func TestSubmitOrder(t *testing.T) { h.SetDefaults() TestSetup(t) h.Verbose = true - if h.APIKey == "" || h.APISecret == "" || - h.APIKey == "Key" || h.APISecret == "Secret" || - !canPlaceOrders { - t.Skip(fmt.Sprintf("ApiKey: %s. Can place orders: %v", h.APIKey, canPlaceOrders)) + if !isRealOrderTestEnabled() { + t.Skip() } + var p = pair.CurrencyPair{ Delimiter: "", FirstCurrency: symbol.BTC, @@ -399,3 +407,31 @@ func TestSubmitOrder(t *testing.T) { t.Errorf("Order failed to be placed: %v", err) } } + +func TestCancelExchangeOrder(t *testing.T) { + // Arrange + h.SetDefaults() + TestSetup(t) + + if !isRealOrderTestEnabled() { + t.Skip() + } + + h.Verbose = true + currencyPair := pair.NewCurrencyPair(symbol.LTC, symbol.BTC) + + var orderCancellation = exchange.OrderCancellation{ + OrderID: "1", + WalletAddress: "1F5zVDgNjorJ51oGebSvNCrSAHpwGkUdDB", + AccountID: "1", + CurrencyPair: currencyPair, + } + + // Act + err := h.CancelOrder(orderCancellation) + + // Assert + if err != nil { + t.Errorf("Could not cancel order: %s", err) + } +} diff --git a/exchanges/huobihadax/huobihadax_wrapper.go b/exchanges/huobihadax/huobihadax_wrapper.go index c7b95b58..d13c2418 100644 --- a/exchanges/huobihadax/huobihadax_wrapper.go +++ b/exchanges/huobihadax/huobihadax_wrapper.go @@ -184,8 +184,16 @@ func (h *HUOBIHADAX) ModifyOrder(orderID int64, action exchange.ModifyOrder) (in } // CancelOrder cancels an order by its corresponding ID number -func (h *HUOBIHADAX) CancelOrder(orderID int64) error { - return common.ErrNotYetImplemented +func (h *HUOBIHADAX) CancelOrder(order exchange.OrderCancellation) error { + orderIDInt, err := strconv.ParseInt(order.OrderID, 10, 64) + + if err != nil { + return err + } + + _, err = h.CancelExistingOrder(orderIDInt) + + return err } // CancelAllOrders cancels all orders associated with a currency pair diff --git a/exchanges/itbit/itbit_test.go b/exchanges/itbit/itbit_test.go index 954468ba..b1a4b13b 100644 --- a/exchanges/itbit/itbit_test.go +++ b/exchanges/itbit/itbit_test.go @@ -1,7 +1,6 @@ package itbit import ( - "fmt" "net/url" "testing" @@ -15,10 +14,10 @@ var i ItBit // Please provide your own keys to do proper testing const ( - apiKey = "" - apiSecret = "" - clientID = "" - canPlaceOrders = false + apiKey = "" + apiSecret = "" + clientID = "" + canManipulateRealOrders = false ) func TestSetDefaults(t *testing.T) { @@ -245,18 +244,26 @@ func TestFormatWithdrawPermissions(t *testing.T) { } } -// This will really really use the API to place an order -// If you're going to test this, make sure you're willing to place real orders on the exchange +// Any tests below this line have the ability to impact your orders on the exchange. Enable canManipulateRealOrders to run them +// ---------------------------------------------------------------------------------------------------------------------------- +func isRealOrderTestEnabled() bool { + if i.APIKey == "" || i.APISecret == "" || + i.APIKey == "Key" || i.APISecret == "Secret" || + !canManipulateRealOrders { + return false + } + return true +} + func TestSubmitOrder(t *testing.T) { i.SetDefaults() TestSetup(t) i.Verbose = true - if i.APIKey == "" || i.APISecret == "" || - i.APIKey == "Key" || i.APISecret == "Secret" || - !canPlaceOrders { - t.Skip(fmt.Sprintf("ApiKey: %s. Can place orders: %v", i.APIKey, canPlaceOrders)) + if !isRealOrderTestEnabled() { + t.Skip() } + var p = pair.CurrencyPair{ Delimiter: "", FirstCurrency: symbol.BTC, @@ -267,3 +274,31 @@ func TestSubmitOrder(t *testing.T) { t.Errorf("Order failed to be placed: %v", err) } } + +func TestCancelExchangeOrder(t *testing.T) { + // Arrange + i.SetDefaults() + TestSetup(t) + + if !isRealOrderTestEnabled() { + t.Skip() + } + + i.Verbose = true + currencyPair := pair.NewCurrencyPair(symbol.LTC, symbol.BTC) + + var orderCancellation = exchange.OrderCancellation{ + OrderID: "1", + WalletAddress: "1F5zVDgNjorJ51oGebSvNCrSAHpwGkUdDB", + AccountID: "1", + CurrencyPair: currencyPair, + } + + // Act + err := i.CancelOrder(orderCancellation) + + // Assert + if err != nil { + t.Errorf("Could not cancel order: %s", err) + } +} diff --git a/exchanges/itbit/itbit_wrapper.go b/exchanges/itbit/itbit_wrapper.go index 2a52a3e2..a5144afe 100644 --- a/exchanges/itbit/itbit_wrapper.go +++ b/exchanges/itbit/itbit_wrapper.go @@ -172,8 +172,8 @@ func (i *ItBit) ModifyOrder(orderID int64, action exchange.ModifyOrder) (int64, } // CancelOrder cancels an order by its corresponding ID number -func (i *ItBit) CancelOrder(orderID int64) error { - return common.ErrNotYetImplemented +func (i *ItBit) CancelOrder(order exchange.OrderCancellation) error { + return i.CancelExistingOrder(order.WalletAddress, order.OrderID) } // CancelAllOrders cancels all orders associated with a currency pair diff --git a/exchanges/kraken/kraken_test.go b/exchanges/kraken/kraken_test.go index 4ce9c061..77a58bab 100644 --- a/exchanges/kraken/kraken_test.go +++ b/exchanges/kraken/kraken_test.go @@ -1,7 +1,6 @@ package kraken import ( - "fmt" "testing" "github.com/thrasher-/gocryptotrader/config" @@ -14,10 +13,10 @@ var k Kraken // Please add your own APIkeys to do correct due diligence testing. const ( - apiKey = "" - apiSecret = "" - clientID = "" - canPlaceOrders = false + apiKey = "" + apiSecret = "" + clientID = "" + canManipulateRealOrders = false ) func TestSetDefaults(t *testing.T) { @@ -331,18 +330,26 @@ func TestFormatWithdrawPermissions(t *testing.T) { } } -// This will really really use the API to place an order -// If you're going to test this, make sure you're willing to place real orders on the exchange +// Any tests below this line have the ability to impact your orders on the exchange. Enable canManipulateRealOrders to run them +// ---------------------------------------------------------------------------------------------------------------------------- +func isRealOrderTestEnabled() bool { + if k.APIKey == "" || k.APISecret == "" || + k.APIKey == "Key" || k.APISecret == "Secret" || + !canManipulateRealOrders { + return false + } + return true +} + func TestSubmitOrder(t *testing.T) { k.SetDefaults() TestSetup(t) k.Verbose = true - if k.APIKey == "" || k.APISecret == "" || - k.APIKey == "Key" || k.APISecret == "Secret" || - !canPlaceOrders { - t.Skip(fmt.Sprintf("ApiKey: %s. Can place orders: %v", k.APIKey, canPlaceOrders)) + if !isRealOrderTestEnabled() { + t.Skip() } + var p = pair.CurrencyPair{ Delimiter: "", FirstCurrency: symbol.XBT, @@ -353,3 +360,31 @@ func TestSubmitOrder(t *testing.T) { t.Errorf("Order failed to be placed: %v", err) } } + +func TestCancelExchangeOrder(t *testing.T) { + // Arrange + k.SetDefaults() + TestSetup(t) + + if !isRealOrderTestEnabled() { + t.Skip() + } + + k.Verbose = true + currencyPair := pair.NewCurrencyPair(symbol.LTC, symbol.BTC) + + var orderCancellation = exchange.OrderCancellation{ + OrderID: "1", + WalletAddress: "1F5zVDgNjorJ51oGebSvNCrSAHpwGkUdDB", + AccountID: "1", + CurrencyPair: currencyPair, + } + + // Act + err := k.CancelOrder(orderCancellation) + + // Assert + if err != nil { + t.Errorf("Could not cancel order: %s", err) + } +} diff --git a/exchanges/kraken/kraken_wrapper.go b/exchanges/kraken/kraken_wrapper.go index d9de3e60..b1a68430 100644 --- a/exchanges/kraken/kraken_wrapper.go +++ b/exchanges/kraken/kraken_wrapper.go @@ -185,8 +185,10 @@ func (k *Kraken) ModifyOrder(orderID int64, action exchange.ModifyOrder) (int64, } // CancelOrder cancels an order by its corresponding ID number -func (k *Kraken) CancelOrder(orderID int64) error { - return common.ErrNotYetImplemented +func (k *Kraken) CancelOrder(order exchange.OrderCancellation) error { + _, err := k.CancelExistingOrder(order.OrderID) + + return err } // CancelAllOrders cancels all orders associated with a currency pair diff --git a/exchanges/lakebtc/lakebtc.go b/exchanges/lakebtc/lakebtc.go index 5771502f..c5577f55 100644 --- a/exchanges/lakebtc/lakebtc.go +++ b/exchanges/lakebtc/lakebtc.go @@ -27,7 +27,7 @@ const ( lakeBTCSellOrder = "sellOrder" lakeBTCOpenOrders = "openOrders" lakeBTCGetOrders = "getOrders" - lakeBTCCancelOrder = "cancelOrder" + lakeBTCCancelOrder = "cancelOrders" lakeBTCGetTrades = "getTrades" lakeBTCGetExternalAccounts = "getExternalAccounts" lakeBTCCreateWithdraw = "createWithdraw" diff --git a/exchanges/lakebtc/lakebtc_test.go b/exchanges/lakebtc/lakebtc_test.go index 2b8a3504..64eae0a3 100644 --- a/exchanges/lakebtc/lakebtc_test.go +++ b/exchanges/lakebtc/lakebtc_test.go @@ -1,7 +1,6 @@ package lakebtc import ( - "fmt" "testing" "github.com/thrasher-/gocryptotrader/config" @@ -14,9 +13,9 @@ var l LakeBTC // Please add your own APIkeys to do correct due diligence testing. const ( - apiKey = "" - apiSecret = "" - canPlaceOrders = false + apiKey = "" + apiSecret = "" + canManipulateRealOrders = false ) func TestSetDefaults(t *testing.T) { @@ -108,9 +107,9 @@ func TestCancelOrder(t *testing.T) { if l.APIKey == "" || l.APISecret == "" { t.Skip() } - err := l.CancelOrder(1337) + err := l.CancelExistingOrder(1337) if err == nil { - t.Error("Test Failed - CancelOrder() error", err) + t.Error("Test Failed - CancelExistingOrder() error", err) } } @@ -249,18 +248,26 @@ func TestFormatWithdrawPermissions(t *testing.T) { } } -// This will really really use the API to place an order -// If you're going to test this, make sure you're willing to place real orders on the exchange +// Any tests below this line have the ability to impact your orders on the exchange. Enable canManipulateRealOrders to run them +// ---------------------------------------------------------------------------------------------------------------------------- +func isRealOrderTestEnabled() bool { + if l.APIKey == "" || l.APISecret == "" || + l.APIKey == "Key" || l.APISecret == "Secret" || + !canManipulateRealOrders { + return false + } + return true +} + func TestSubmitOrder(t *testing.T) { l.SetDefaults() TestSetup(t) l.Verbose = true - if l.APIKey == "" || l.APISecret == "" || - l.APIKey == "Key" || l.APISecret == "Secret" || - !canPlaceOrders { - t.Skip(fmt.Sprintf("ApiKey: %s. Can place orders: %v", l.APIKey, canPlaceOrders)) + if !isRealOrderTestEnabled() { + t.Skip() } + var p = pair.CurrencyPair{ Delimiter: "", FirstCurrency: symbol.BTC, @@ -271,3 +278,31 @@ func TestSubmitOrder(t *testing.T) { t.Errorf("Order failed to be placed: %v", err) } } + +func TestCancelExchangeOrder(t *testing.T) { + // Arrange + l.SetDefaults() + TestSetup(t) + + if !isRealOrderTestEnabled() { + t.Skip() + } + + l.Verbose = true + currencyPair := pair.NewCurrencyPair(symbol.LTC, symbol.BTC) + + var orderCancellation = exchange.OrderCancellation{ + OrderID: "1", + WalletAddress: "1F5zVDgNjorJ51oGebSvNCrSAHpwGkUdDB", + AccountID: "1", + CurrencyPair: currencyPair, + } + + // Act + err := l.CancelOrder(orderCancellation) + + // Assert + if err != nil { + t.Errorf("Could not cancel order: %s", err) + } +} diff --git a/exchanges/lakebtc/lakebtc_wrapper.go b/exchanges/lakebtc/lakebtc_wrapper.go index ff62d498..dd6b5708 100644 --- a/exchanges/lakebtc/lakebtc_wrapper.go +++ b/exchanges/lakebtc/lakebtc_wrapper.go @@ -162,8 +162,14 @@ func (l *LakeBTC) ModifyOrder(orderID int64, action exchange.ModifyOrder) (int64 } // CancelOrder cancels an order by its corresponding ID number -func (l *LakeBTC) CancelOrder(orderID int64) error { - return common.ErrNotYetImplemented +func (l *LakeBTC) CancelOrder(order exchange.OrderCancellation) error { + orderIDInt, err := strconv.ParseInt(order.OrderID, 10, 64) + + if err != nil { + return err + } + + return l.CancelExistingOrder(orderIDInt) } // CancelAllOrders cancels all orders associated with a currency pair diff --git a/exchanges/liqui/liqui_test.go b/exchanges/liqui/liqui_test.go index 9b92a25a..c0f80999 100644 --- a/exchanges/liqui/liqui_test.go +++ b/exchanges/liqui/liqui_test.go @@ -1,7 +1,6 @@ package liqui import ( - "fmt" "net/url" "testing" @@ -14,9 +13,9 @@ import ( var l Liqui const ( - apiKey = "" - apiSecret = "" - canPlaceOrders = false + apiKey = "" + apiSecret = "" + canManipulateRealOrders = false ) func TestSetDefaults(t *testing.T) { @@ -234,18 +233,26 @@ func TestFormatWithdrawPermissions(t *testing.T) { } } -// This will really really use the API to place an order -// If you're going to test this, make sure you're willing to place real orders on the exchange +// Any tests below this line have the ability to impact your orders on the exchange. Enable canManipulateRealOrders to run them +// ---------------------------------------------------------------------------------------------------------------------------- +func isRealOrderTestEnabled() bool { + if l.APIKey == "" || l.APISecret == "" || + l.APIKey == "Key" || l.APISecret == "Secret" || + !canManipulateRealOrders { + return false + } + return true +} + func TestSubmitOrder(t *testing.T) { l.SetDefaults() TestSetup(t) l.Verbose = true - if l.APIKey == "" || l.APISecret == "" || - l.APIKey == "Key" || l.APISecret == "Secret" || - !canPlaceOrders { - t.Skip(fmt.Sprintf("ApiKey: %s. Can place orders: %v", l.APIKey, canPlaceOrders)) + if !isRealOrderTestEnabled() { + t.Skip() } + var p = pair.CurrencyPair{ Delimiter: "", FirstCurrency: symbol.BTC, @@ -256,3 +263,31 @@ func TestSubmitOrder(t *testing.T) { t.Errorf("Order failed to be placed: %v", err) } } + +func TestCancelExchangeOrder(t *testing.T) { + // Arrange + l.SetDefaults() + TestSetup(t) + + if !isRealOrderTestEnabled() { + t.Skip() + } + + l.Verbose = true + currencyPair := pair.NewCurrencyPair(symbol.LTC, symbol.BTC) + + var orderCancellation = exchange.OrderCancellation{ + OrderID: "1", + WalletAddress: "1F5zVDgNjorJ51oGebSvNCrSAHpwGkUdDB", + AccountID: "1", + CurrencyPair: currencyPair, + } + + // Act + err := l.CancelOrder(orderCancellation) + + // Assert + if err != nil { + t.Errorf("Could not cancel order: %s", err) + } +} diff --git a/exchanges/liqui/liqui_wrapper.go b/exchanges/liqui/liqui_wrapper.go index 5d4b94b6..78fef956 100644 --- a/exchanges/liqui/liqui_wrapper.go +++ b/exchanges/liqui/liqui_wrapper.go @@ -3,6 +3,7 @@ package liqui import ( "fmt" "log" + "strconv" "sync" "github.com/thrasher-/gocryptotrader/common" @@ -170,8 +171,16 @@ func (l *Liqui) ModifyOrder(orderID int64, action exchange.ModifyOrder) (int64, } // CancelOrder cancels an order by its corresponding ID number -func (l *Liqui) CancelOrder(orderID int64) error { - return common.ErrNotYetImplemented +func (l *Liqui) CancelOrder(order exchange.OrderCancellation) error { + orderIDInt, err := strconv.ParseInt(order.OrderID, 10, 64) + + if err != nil { + return err + } + + _, err = l.CancelExistingOrder(orderIDInt) + + return err } // CancelAllOrders cancels all orders associated with a currency pair diff --git a/exchanges/localbitcoins/localbitcoins_test.go b/exchanges/localbitcoins/localbitcoins_test.go index 1121c9bc..7a62d6e7 100644 --- a/exchanges/localbitcoins/localbitcoins_test.go +++ b/exchanges/localbitcoins/localbitcoins_test.go @@ -4,6 +4,7 @@ import ( "testing" "github.com/thrasher-/gocryptotrader/config" + "github.com/thrasher-/gocryptotrader/currency/pair" "github.com/thrasher-/gocryptotrader/currency/symbol" exchange "github.com/thrasher-/gocryptotrader/exchanges" ) @@ -13,8 +14,9 @@ var l LocalBitcoins // Please supply your own APIKEYS here for due diligence testing const ( - apiKey = "" - apiSecret = "" + apiKey = "" + apiSecret = "" + canManipulateRealOrders = false ) func TestSetDefaults(t *testing.T) { @@ -195,3 +197,61 @@ func TestFormatWithdrawPermissions(t *testing.T) { t.Errorf("Expected: %s, Recieved: %s", expectedResult, withdrawPermissions) } } + +// Any tests below this line have the ability to impact your orders on the exchange. Enable canManipulateRealOrders to run them +// ---------------------------------------------------------------------------------------------------------------------------- +func isRealOrderTestEnabled() bool { + if l.APIKey == "" || l.APISecret == "" || + l.APIKey == "Key" || l.APISecret == "Secret" || + !canManipulateRealOrders { + return false + } + return true +} + +func TestSubmitOrder(t *testing.T) { + l.SetDefaults() + TestSetup(t) + l.Verbose = true + + if !isRealOrderTestEnabled() { + t.Skip() + } + + var p = pair.CurrencyPair{ + Delimiter: "", + FirstCurrency: symbol.BTC, + SecondCurrency: symbol.EUR, + } + response, err := l.SubmitOrder(p, exchange.Buy, exchange.Market, 1, 10, "hi") + if err != nil || !response.IsOrderPlaced { + t.Errorf("Order failed to be placed: %v", err) + } +} +func TestCancelExchangeOrder(t *testing.T) { + // Arrange + l.SetDefaults() + TestSetup(t) + + if !isRealOrderTestEnabled() { + t.Skip() + } + + l.Verbose = true + currencyPair := pair.NewCurrencyPair(symbol.LTC, symbol.BTC) + + var orderCancellation = exchange.OrderCancellation{ + OrderID: "1", + WalletAddress: "1F5zVDgNjorJ51oGebSvNCrSAHpwGkUdDB", + AccountID: "1", + CurrencyPair: currencyPair, + } + + // Act + err := l.CancelOrder(orderCancellation) + + // Assert + if err != nil { + t.Errorf("Could not cancel order: %s", err) + } +} diff --git a/exchanges/localbitcoins/localbitcoins_wrapper.go b/exchanges/localbitcoins/localbitcoins_wrapper.go index 8b55f328..74cce3ab 100644 --- a/exchanges/localbitcoins/localbitcoins_wrapper.go +++ b/exchanges/localbitcoins/localbitcoins_wrapper.go @@ -213,8 +213,8 @@ func (l *LocalBitcoins) ModifyOrder(orderID int64, action exchange.ModifyOrder) } // CancelOrder cancels an order by its corresponding ID number -func (l *LocalBitcoins) CancelOrder(orderID int64) error { - return common.ErrNotYetImplemented +func (l *LocalBitcoins) CancelOrder(order exchange.OrderCancellation) error { + return l.DeleteAd(order.OrderID) } // CancelAllOrders cancels all orders associated with a currency pair diff --git a/exchanges/okcoin/okcoin_test.go b/exchanges/okcoin/okcoin_test.go index 942c1234..942e9341 100644 --- a/exchanges/okcoin/okcoin_test.go +++ b/exchanges/okcoin/okcoin_test.go @@ -1,7 +1,6 @@ package okcoin import ( - "fmt" "testing" "github.com/thrasher-/gocryptotrader/config" @@ -15,9 +14,9 @@ var o OKCoin // Please supply your own APIKEYS here for due diligence testing const ( - apiKey = "" - apiSecret = "" - canPlaceOrders = false + apiKey = "" + apiSecret = "" + canManipulateRealOrders = false ) func TestSetDefaults(t *testing.T) { @@ -149,18 +148,26 @@ func TestFormatWithdrawPermissions(t *testing.T) { } } -// This will really really use the API to place an order -// If you're going to test this, make sure you're willing to place real orders on the exchange +// Any tests below this line have the ability to impact your orders on the exchange. Enable canManipulateRealOrders to run them +// ---------------------------------------------------------------------------------------------------------------------------- +func isRealOrderTestEnabled() bool { + if o.APIKey == "" || o.APISecret == "" || + o.APIKey == "Key" || o.APISecret == "Secret" || + !canManipulateRealOrders { + return false + } + return true +} + func TestSubmitOrder(t *testing.T) { o.SetDefaults() TestSetup(t) o.Verbose = true - if o.APIKey == "" || o.APISecret == "" || - o.APIKey == "Key" || o.APISecret == "Secret" || - !canPlaceOrders { - t.Skip(fmt.Sprintf("ApiKey: %s. Can place orders: %v", o.APIKey, canPlaceOrders)) + if !isRealOrderTestEnabled() { + t.Skip() } + var p = pair.CurrencyPair{ Delimiter: "", FirstCurrency: symbol.BTC, @@ -171,3 +178,31 @@ func TestSubmitOrder(t *testing.T) { t.Errorf("Order failed to be placed: %v", err) } } + +func TestCancelExchangeOrder(t *testing.T) { + // Arrange + o.SetDefaults() + TestSetup(t) + + if !isRealOrderTestEnabled() { + t.Skip() + } + + o.Verbose = true + currencyPair := pair.NewCurrencyPair(symbol.LTC, symbol.BTC) + + var orderCancellation = exchange.OrderCancellation{ + OrderID: "1", + WalletAddress: "1F5zVDgNjorJ51oGebSvNCrSAHpwGkUdDB", + AccountID: "1", + CurrencyPair: currencyPair, + } + + // Act + err := o.CancelOrder(orderCancellation) + + // Assert + if err != nil { + t.Errorf("Could not cancel order: %s", err) + } +} diff --git a/exchanges/okcoin/okcoin_wrapper.go b/exchanges/okcoin/okcoin_wrapper.go index e516d8c5..7d4deb09 100644 --- a/exchanges/okcoin/okcoin_wrapper.go +++ b/exchanges/okcoin/okcoin_wrapper.go @@ -4,6 +4,7 @@ import ( "errors" "fmt" "log" + "strconv" "sync" "github.com/thrasher-/gocryptotrader/common" @@ -231,8 +232,17 @@ func (o *OKCoin) ModifyOrder(orderID int64, action exchange.ModifyOrder) (int64, } // CancelOrder cancels an order by its corresponding ID number -func (o *OKCoin) CancelOrder(orderID int64) error { - return common.ErrNotYetImplemented +func (o *OKCoin) CancelOrder(order exchange.OrderCancellation) error { + orderIDInt, err := strconv.ParseInt(order.OrderID, 10, 64) + orders := []int64{orderIDInt} + + if err != nil { + return err + } + + _, err = o.CancelExistingOrder(orders, exchange.FormatExchangeCurrency(o.Name, order.CurrencyPair).String()) + + return err } // CancelAllOrders cancels all orders associated with a currency pair diff --git a/exchanges/okex/okex_test.go b/exchanges/okex/okex_test.go index 4d78e9b1..d600b40a 100644 --- a/exchanges/okex/okex_test.go +++ b/exchanges/okex/okex_test.go @@ -1,7 +1,6 @@ package okex import ( - "fmt" "testing" "github.com/thrasher-/gocryptotrader/config" @@ -14,9 +13,9 @@ var o OKEX // Please supply you own test keys here for due diligence testing. const ( - apiKey = "" - apiSecret = "" - canPlaceOrders = false + apiKey = "" + apiSecret = "" + canManipulateRealOrders = false ) func TestSetDefaults(t *testing.T) { @@ -398,18 +397,26 @@ func TestFormatWithdrawPermissions(t *testing.T) { } } -// This will really really use the API to place an order -// If you're going to test this, make sure you're willing to place real orders on the exchange +// Any tests below this line have the ability to impact your orders on the exchange. Enable canManipulateRealOrders to run them +// ---------------------------------------------------------------------------------------------------------------------------- +func isRealOrderTestEnabled() bool { + if o.APIKey == "" || o.APISecret == "" || + o.APIKey == "Key" || o.APISecret == "Secret" || + !canManipulateRealOrders { + return false + } + return true +} + func TestSubmitOrder(t *testing.T) { o.SetDefaults() TestSetup(t) o.Verbose = true - if o.APIKey == "" || o.APISecret == "" || - o.APIKey == "Key" || o.APISecret == "Secret" || - !canPlaceOrders { - t.Skip(fmt.Sprintf("ApiKey: %s. Can place orders: %v", o.APIKey, canPlaceOrders)) + if !isRealOrderTestEnabled() { + t.Skip() } + var p = pair.CurrencyPair{ Delimiter: "", FirstCurrency: symbol.BTC, @@ -420,3 +427,31 @@ func TestSubmitOrder(t *testing.T) { t.Errorf("Order failed to be placed: %v", err) } } + +func TestCancelExchangeOrder(t *testing.T) { + // Arrange + o.SetDefaults() + TestSetup(t) + + if !isRealOrderTestEnabled() { + t.Skip() + } + + o.Verbose = true + currencyPair := pair.NewCurrencyPair(symbol.LTC, symbol.BTC) + + var orderCancellation = exchange.OrderCancellation{ + OrderID: "1", + WalletAddress: "1F5zVDgNjorJ51oGebSvNCrSAHpwGkUdDB", + AccountID: "1", + CurrencyPair: currencyPair, + } + + // Act + err := o.CancelOrder(orderCancellation) + + // Assert + if err != nil { + t.Errorf("Could not cancel order: %s", err) + } +} diff --git a/exchanges/okex/okex_wrapper.go b/exchanges/okex/okex_wrapper.go index eb5f9765..cf3848a4 100644 --- a/exchanges/okex/okex_wrapper.go +++ b/exchanges/okex/okex_wrapper.go @@ -4,6 +4,7 @@ import ( "errors" "fmt" "log" + "strconv" "sync" "github.com/thrasher-/gocryptotrader/common" @@ -216,8 +217,16 @@ func (o *OKEX) ModifyOrder(orderID int64, action exchange.ModifyOrder) (int64, e } // CancelOrder cancels an order by its corresponding ID number -func (o *OKEX) CancelOrder(orderID int64) error { - return common.ErrNotYetImplemented +func (o *OKEX) CancelOrder(order exchange.OrderCancellation) error { + orderIDInt, err := strconv.ParseInt(order.OrderID, 10, 64) + + if err != nil { + return err + } + + _, err = o.SpotCancelOrder(exchange.FormatExchangeCurrency(o.Name, order.CurrencyPair).String(), orderIDInt) + + return err } // CancelAllOrders cancels all orders associated with a currency pair diff --git a/exchanges/poloniex/poloniex_test.go b/exchanges/poloniex/poloniex_test.go index 35b7d7be..00ccceb7 100644 --- a/exchanges/poloniex/poloniex_test.go +++ b/exchanges/poloniex/poloniex_test.go @@ -1,7 +1,6 @@ package poloniex import ( - "fmt" "testing" "github.com/thrasher-/gocryptotrader/config" @@ -15,9 +14,9 @@ var p Poloniex // Please supply your own APIKEYS here for due diligence testing const ( - apiKey = "" - apiSecret = "" - canPlaceOrders = false + apiKey = "" + apiSecret = "" + canManipulateRealOrders = false ) func TestSetDefaults(t *testing.T) { @@ -194,18 +193,26 @@ func TestFormatWithdrawPermissions(t *testing.T) { } } -// This will really really use the API to place an order -// If you're going to test this, make sure you're willing to place real orders on the exchange +// Any tests below this line have the ability to impact your orders on the exchange. Enable canManipulateRealOrders to run them +// ---------------------------------------------------------------------------------------------------------------------------- +func isRealOrderTestEnabled() bool { + if p.APIKey == "" || p.APISecret == "" || + p.APIKey == "Key" || p.APISecret == "Secret" || + !canManipulateRealOrders { + return false + } + return true +} + func TestSubmitOrder(t *testing.T) { p.SetDefaults() TestSetup(t) p.Verbose = true - if p.APIKey == "" || p.APISecret == "" || - p.APIKey == "Key" || p.APISecret == "Secret" || - !canPlaceOrders { - t.Skip(fmt.Sprintf("ApiKey: %s. Can place orders: %v", p.APIKey, canPlaceOrders)) + if !isRealOrderTestEnabled() { + t.Skip() } + var pair = pair.CurrencyPair{ Delimiter: "_", FirstCurrency: symbol.BTC, @@ -216,3 +223,31 @@ func TestSubmitOrder(t *testing.T) { t.Errorf("Order failed to be placed: %v", err) } } + +func TestCancelExchangeOrder(t *testing.T) { + // Arrange + p.SetDefaults() + TestSetup(t) + + if !isRealOrderTestEnabled() { + t.Skip() + } + + p.Verbose = true + currencyPair := pair.NewCurrencyPair(symbol.LTC, symbol.BTC) + + var orderCancellation = exchange.OrderCancellation{ + OrderID: "1", + WalletAddress: "1F5zVDgNjorJ51oGebSvNCrSAHpwGkUdDB", + AccountID: "1", + CurrencyPair: currencyPair, + } + + // Act + err := p.CancelOrder(orderCancellation) + + // Assert + if err != nil { + t.Errorf("Could not cancel order: %s", err) + } +} diff --git a/exchanges/poloniex/poloniex_wrapper.go b/exchanges/poloniex/poloniex_wrapper.go index 76d41e1b..e43c5e17 100644 --- a/exchanges/poloniex/poloniex_wrapper.go +++ b/exchanges/poloniex/poloniex_wrapper.go @@ -3,6 +3,7 @@ package poloniex import ( "fmt" "log" + "strconv" "sync" "github.com/thrasher-/gocryptotrader/common" @@ -179,8 +180,16 @@ func (p *Poloniex) ModifyOrder(orderID int64, action exchange.ModifyOrder) (int6 } // CancelOrder cancels an order by its corresponding ID number -func (p *Poloniex) CancelOrder(orderID int64) error { - return common.ErrNotYetImplemented +func (p *Poloniex) CancelOrder(order exchange.OrderCancellation) error { + orderIDInt, err := strconv.ParseInt(order.OrderID, 10, 64) + + if err != nil { + return err + } + + _, err = p.CancelExistingOrder(orderIDInt) + + return err } // CancelAllOrders cancels all orders associated with a currency pair diff --git a/exchanges/request/request.go b/exchanges/request/request.go index 5f0825be..c63bd6e2 100644 --- a/exchanges/request/request.go +++ b/exchanges/request/request.go @@ -291,8 +291,13 @@ func (r *Requester) DoRequest(req *http.Request, method, path string, headers ma return err } + if resp.StatusCode != 200 && resp.StatusCode != 201 && resp.StatusCode != 202 { + return fmt.Errorf("Error: HTTP Status code %s. Body: %s", resp.Status, contents) + } + resp.Body.Close() if verbose { + log.Printf("HTTP status: %s, Code: %v", resp.Status, resp.StatusCode) log.Printf("%s exchange raw response: %s", r.Name, string(contents[:])) } diff --git a/exchanges/request/request_test.go b/exchanges/request/request_test.go index f2f0996a..b3088bea 100644 --- a/exchanges/request/request_test.go +++ b/exchanges/request/request_test.go @@ -274,7 +274,7 @@ func TestDoRequest(t *testing.T) { headers := make(map[string]string) headers["content-type"] = "content/text" - err = r.SendPayload("POST", "https://api.bitfinex.com", headers, nil, result, false, true) + err = r.SendPayload("POST", "https://bitfinex.com", headers, nil, result, false, true) if err != nil { t.Fatal(err) } diff --git a/exchanges/wex/wex_test.go b/exchanges/wex/wex_test.go index ccf3d075..8629d64f 100644 --- a/exchanges/wex/wex_test.go +++ b/exchanges/wex/wex_test.go @@ -1,7 +1,6 @@ package wex import ( - "fmt" "testing" "github.com/thrasher-/gocryptotrader/config" @@ -14,9 +13,10 @@ var w WEX // Please supply your own keys for better unit testing const ( - apiKey = "" - apiSecret = "" - canPlaceOrders = false + apiKey = "" + apiSecret = "" + canManipulateRealOrders = false + isWexEncounteringIssues = true ) func TestSetDefaults(t *testing.T) { @@ -38,6 +38,9 @@ func TestSetup(t *testing.T) { } func TestGetTradablePairs(t *testing.T) { + if isWexEncounteringIssues { + t.Skip() + } t.Parallel() _, err := w.GetTradablePairs() if err != nil { @@ -46,6 +49,9 @@ func TestGetTradablePairs(t *testing.T) { } func TestGetInfo(t *testing.T) { + if isWexEncounteringIssues { + t.Skip() + } t.Parallel() _, err := w.GetInfo() if err != nil { @@ -54,6 +60,9 @@ func TestGetInfo(t *testing.T) { } func TestGetTicker(t *testing.T) { + if isWexEncounteringIssues { + t.Skip() + } t.Parallel() _, err := w.GetTicker("btc_usd") if err != nil { @@ -62,6 +71,9 @@ func TestGetTicker(t *testing.T) { } func TestGetDepth(t *testing.T) { + if isWexEncounteringIssues { + t.Skip() + } t.Parallel() _, err := w.GetDepth("btc_usd") if err != nil { @@ -70,6 +82,9 @@ func TestGetDepth(t *testing.T) { } func TestGetTrades(t *testing.T) { + if isWexEncounteringIssues { + t.Skip() + } t.Parallel() _, err := w.GetTrades("btc_usd") if err != nil { @@ -78,6 +93,9 @@ func TestGetTrades(t *testing.T) { } func TestGetAccountInfo(t *testing.T) { + if isWexEncounteringIssues { + t.Skip() + } t.Parallel() _, err := w.GetAccountInfo() if err == nil { @@ -86,6 +104,9 @@ func TestGetAccountInfo(t *testing.T) { } func TestGetActiveOrders(t *testing.T) { + if isWexEncounteringIssues { + t.Skip() + } t.Parallel() _, err := w.GetActiveOrders("") if err == nil { @@ -94,6 +115,9 @@ func TestGetActiveOrders(t *testing.T) { } func TestGetOrderInfo(t *testing.T) { + if isWexEncounteringIssues { + t.Skip() + } t.Parallel() _, err := w.GetOrderInfo(6196974) if err == nil { @@ -102,6 +126,9 @@ func TestGetOrderInfo(t *testing.T) { } func TestCancelExistingOrder(t *testing.T) { + if isWexEncounteringIssues { + t.Skip() + } t.Parallel() _, err := w.CancelExistingOrder(1337) if err == nil { @@ -110,6 +137,9 @@ func TestCancelExistingOrder(t *testing.T) { } func TestTrade(t *testing.T) { + if isWexEncounteringIssues { + t.Skip() + } t.Parallel() _, err := w.Trade("", "buy", 0, 0) if err == nil { @@ -118,6 +148,9 @@ func TestTrade(t *testing.T) { } func TestGetTransactionHistory(t *testing.T) { + if isWexEncounteringIssues { + t.Skip() + } t.Parallel() _, err := w.GetTransactionHistory(0, 0, 0, "", "", "") if err == nil { @@ -126,6 +159,9 @@ func TestGetTransactionHistory(t *testing.T) { } func TestGetTradeHistory(t *testing.T) { + if isWexEncounteringIssues { + t.Skip() + } t.Parallel() _, err := w.GetTradeHistory(0, 0, 0, "", "", "", "") if err == nil { @@ -134,6 +170,9 @@ func TestGetTradeHistory(t *testing.T) { } func TestWithdrawCoins(t *testing.T) { + if isWexEncounteringIssues { + t.Skip() + } t.Parallel() _, err := w.WithdrawCoins("", 0, "") if err == nil { @@ -142,6 +181,9 @@ func TestWithdrawCoins(t *testing.T) { } func TestCoinDepositAddress(t *testing.T) { + if isWexEncounteringIssues { + t.Skip() + } t.Parallel() _, err := w.CoinDepositAddress("btc") if err == nil { @@ -150,6 +192,9 @@ func TestCoinDepositAddress(t *testing.T) { } func TestCreateCoupon(t *testing.T) { + if isWexEncounteringIssues { + t.Skip() + } t.Parallel() _, err := w.CreateCoupon("bla", 0) if err == nil { @@ -158,6 +203,9 @@ func TestCreateCoupon(t *testing.T) { } func TestRedeemCoupon(t *testing.T) { + if isWexEncounteringIssues { + t.Skip() + } t.Parallel() _, err := w.RedeemCoupon("bla") if err == nil { @@ -180,6 +228,9 @@ func setFeeBuilder() exchange.FeeBuilder { } func TestGetFee(t *testing.T) { + if isWexEncounteringIssues { + t.Skip() + } w.SetDefaults() TestSetup(t) var feeBuilder = setFeeBuilder() @@ -258,6 +309,9 @@ func TestGetFee(t *testing.T) { } func TestFormatWithdrawPermissions(t *testing.T) { + if isWexEncounteringIssues { + t.Skip() + } // Arrange w.SetDefaults() expectedResult := exchange.AutoWithdrawCryptoWithAPIPermissionText @@ -269,18 +323,29 @@ func TestFormatWithdrawPermissions(t *testing.T) { } } -// This will really really use the API to place an order -// If you're going to test this, make sure you're willing to place real orders on the exchange +// Any tests below this line have the ability to impact your orders on the exchange. Enable canManipulateRealOrders to run them +// ---------------------------------------------------------------------------------------------------------------------------- +func isRealOrderTestEnabled() bool { + if w.APIKey == "" || w.APISecret == "" || + w.APIKey == "Key" || w.APISecret == "Secret" || + !canManipulateRealOrders { + return false + } + return true +} + func TestSubmitOrder(t *testing.T) { + if isWexEncounteringIssues { + t.Skip() + } w.SetDefaults() TestSetup(t) w.Verbose = true - if w.APIKey == "" || w.APISecret == "" || - w.APIKey == "Key" || w.APISecret == "Secret" || - !canPlaceOrders { - t.Skip(fmt.Sprintf("ApiKey: %s. Can place orders: %v", w.APIKey, canPlaceOrders)) + if !isRealOrderTestEnabled() { + t.Skip() } + var pair = pair.CurrencyPair{ Delimiter: "_", FirstCurrency: symbol.BTC, @@ -291,3 +356,34 @@ func TestSubmitOrder(t *testing.T) { t.Errorf("Order failed to be placed: %v", err) } } + +func TestCancelExchangeOrder(t *testing.T) { + if isWexEncounteringIssues { + t.Skip() + } + // Arrange + w.SetDefaults() + TestSetup(t) + + if !isRealOrderTestEnabled() { + t.Skip() + } + + w.Verbose = true + currencyPair := pair.NewCurrencyPair(symbol.LTC, symbol.BTC) + + var orderCancellation = exchange.OrderCancellation{ + OrderID: "1", + WalletAddress: "1F5zVDgNjorJ51oGebSvNCrSAHpwGkUdDB", + AccountID: "1", + CurrencyPair: currencyPair, + } + + // Act + err := w.CancelOrder(orderCancellation) + + // Assert + if err != nil { + t.Errorf("Could not cancel order: %s", err) + } +} diff --git a/exchanges/wex/wex_wrapper.go b/exchanges/wex/wex_wrapper.go index df8cf470..3c8ef1dd 100644 --- a/exchanges/wex/wex_wrapper.go +++ b/exchanges/wex/wex_wrapper.go @@ -3,6 +3,7 @@ package wex import ( "fmt" "log" + "strconv" "sync" "github.com/thrasher-/gocryptotrader/common" @@ -180,8 +181,16 @@ func (w *WEX) ModifyOrder(orderID int64, action exchange.ModifyOrder) (int64, er } // CancelOrder cancels an order by its corresponding ID number -func (w *WEX) CancelOrder(orderID int64) error { - return common.ErrNotYetImplemented +func (w *WEX) CancelOrder(order exchange.OrderCancellation) error { + orderIDInt, err := strconv.ParseInt(order.OrderID, 10, 64) + + if err != nil { + return err + } + + _, err = w.CancelExistingOrder(orderIDInt) + + return err } // CancelAllOrders cancels all orders associated with a currency pair diff --git a/exchanges/yobit/yobit_test.go b/exchanges/yobit/yobit_test.go index c064847f..501a0c09 100644 --- a/exchanges/yobit/yobit_test.go +++ b/exchanges/yobit/yobit_test.go @@ -1,7 +1,6 @@ package yobit import ( - "fmt" "testing" "github.com/thrasher-/gocryptotrader/config" @@ -14,9 +13,9 @@ var y Yobit // Please supply your own keys for better unit testing const ( - apiKey = "" - apiSecret = "" - canPlaceOrders = false + apiKey = "" + apiSecret = "" + canManipulateRealOrders = false ) func TestSetDefaults(t *testing.T) { @@ -313,18 +312,26 @@ func TestFormatWithdrawPermissions(t *testing.T) { } } -// This will really really use the API to place an order -// If you're going to test this, make sure you're willing to place real orders on the exchange +// Any tests below this line have the ability to impact your orders on the exchange. Enable canManipulateRealOrders to run them +// ---------------------------------------------------------------------------------------------------------------------------- +func isRealOrderTestEnabled() bool { + if y.APIKey == "" || y.APISecret == "" || + y.APIKey == "Key" || y.APISecret == "Secret" || + !canManipulateRealOrders { + return false + } + return true +} + func TestSubmitOrder(t *testing.T) { y.SetDefaults() TestSetup(t) y.Verbose = true - if y.APIKey == "" || y.APISecret == "" || - y.APIKey == "Key" || y.APISecret == "Secret" || - !canPlaceOrders { - t.Skip(fmt.Sprintf("ApiKey: %s. Can place orders: %v", y.APIKey, canPlaceOrders)) + if !isRealOrderTestEnabled() { + t.Skip() } + var pair = pair.CurrencyPair{ Delimiter: "_", FirstCurrency: symbol.BTC, @@ -335,3 +342,31 @@ func TestSubmitOrder(t *testing.T) { t.Errorf("Order failed to be placed: %v", err) } } + +func TestCancelExchangeOrder(t *testing.T) { + // Arrange + y.SetDefaults() + TestSetup(t) + + if !isRealOrderTestEnabled() { + t.Skip() + } + + y.Verbose = true + currencyPair := pair.NewCurrencyPair(symbol.LTC, symbol.BTC) + + var orderCancellation = exchange.OrderCancellation{ + OrderID: "1", + WalletAddress: "1F5zVDgNjorJ51oGebSvNCrSAHpwGkUdDB", + AccountID: "1", + CurrencyPair: currencyPair, + } + + // Act + err := y.CancelOrder(orderCancellation) + + // Assert + if err != nil { + t.Errorf("Could not cancel order: %s", err) + } +} diff --git a/exchanges/yobit/yobit_wrapper.go b/exchanges/yobit/yobit_wrapper.go index 2a5768b7..2ba65341 100644 --- a/exchanges/yobit/yobit_wrapper.go +++ b/exchanges/yobit/yobit_wrapper.go @@ -3,6 +3,7 @@ package yobit import ( "fmt" "log" + "strconv" "sync" "github.com/thrasher-/gocryptotrader/common" @@ -162,8 +163,16 @@ func (y *Yobit) ModifyOrder(orderID int64, action exchange.ModifyOrder) (int64, } // CancelOrder cancels an order by its corresponding ID number -func (y *Yobit) CancelOrder(orderID int64) error { - return common.ErrNotYetImplemented +func (y *Yobit) CancelOrder(order exchange.OrderCancellation) error { + orderIDInt, err := strconv.ParseInt(order.OrderID, 10, 64) + + if err != nil { + return err + } + + _, err = y.CancelExistingOrder(orderIDInt) + + return err } // CancelAllOrders cancels all orders associated with a currency pair diff --git a/exchanges/zb/zb_test.go b/exchanges/zb/zb_test.go index 25fae4a4..db55a06c 100644 --- a/exchanges/zb/zb_test.go +++ b/exchanges/zb/zb_test.go @@ -12,9 +12,9 @@ import ( // Please supply you own test keys here for due diligence testing. const ( - apiKey = "" - apiSecret = "" - canPlaceOrders = false + apiKey = "" + apiSecret = "" + canManipulateRealOrders = false ) var z ZB @@ -243,17 +243,24 @@ func TestFormatWithdrawPermissions(t *testing.T) { } } -// This will really really use the API to place an order -// If you're going to test this, make sure you're willing to place real orders on the exchange +// Any tests below this line have the ability to impact your orders on the exchange. Enable canManipulateRealOrders to run them +// ---------------------------------------------------------------------------------------------------------------------------- +func isRealOrderTestEnabled() bool { + if z.APIKey == "" || z.APISecret == "" || + z.APIKey == "Key" || z.APISecret == "Secret" || + !canManipulateRealOrders { + return false + } + return true +} + func TestSubmitOrder(t *testing.T) { z.SetDefaults() TestSetup(t) z.Verbose = true - if z.APIKey == "" || z.APISecret == "" || - z.APIKey == "Key" || z.APISecret == "Secret" || - !canPlaceOrders { - t.Skip(fmt.Sprintf("ApiKey: %s. Can place orders: %v", z.APIKey, canPlaceOrders)) + if !isRealOrderTestEnabled() { + t.Skip(fmt.Sprintf("ApiKey: %s. Can place orders: %v", z.APIKey, canManipulateRealOrders)) } var pair = pair.CurrencyPair{ Delimiter: "_", @@ -265,3 +272,31 @@ func TestSubmitOrder(t *testing.T) { t.Errorf("Order failed to be placed: %v", err) } } + +func TestCancelExchangeOrder(t *testing.T) { + // Arrange + z.SetDefaults() + TestSetup(t) + + if !isRealOrderTestEnabled() { + t.Skip() + } + + z.Verbose = true + currencyPair := pair.NewCurrencyPair(symbol.LTC, symbol.BTC) + + var orderCancellation = exchange.OrderCancellation{ + OrderID: "1", + WalletAddress: "1F5zVDgNjorJ51oGebSvNCrSAHpwGkUdDB", + AccountID: "1", + CurrencyPair: currencyPair, + } + + // Act + err := z.CancelOrder(orderCancellation) + + // Assert + if err != nil { + t.Errorf("Could not cancel order: %s", err) + } +} diff --git a/exchanges/zb/zb_wrapper.go b/exchanges/zb/zb_wrapper.go index d6c23356..0255fd8d 100644 --- a/exchanges/zb/zb_wrapper.go +++ b/exchanges/zb/zb_wrapper.go @@ -4,6 +4,7 @@ import ( "errors" "fmt" "log" + "strconv" "sync" "github.com/thrasher-/gocryptotrader/common" @@ -173,8 +174,14 @@ func (z *ZB) ModifyOrder(orderID int64, action exchange.ModifyOrder) (int64, err } // CancelOrder cancels an order by its corresponding ID number -func (z *ZB) CancelOrder(orderID int64) error { - return common.ErrNotYetImplemented +func (z *ZB) CancelOrder(order exchange.OrderCancellation) error { + orderIDInt, err := strconv.ParseInt(order.OrderID, 10, 64) + + if err != nil { + return err + } + + return z.CancelExistingOrder(orderIDInt, exchange.FormatExchangeCurrency(z.Name, order.CurrencyPair).String()) } // CancelAllOrders cancels all orders associated with a currency pair diff --git a/tools/exchange_template/wrapper_file.tmpl b/tools/exchange_template/wrapper_file.tmpl index 2fdc965e..2f8d0e47 100644 --- a/tools/exchange_template/wrapper_file.tmpl +++ b/tools/exchange_template/wrapper_file.tmpl @@ -132,7 +132,7 @@ func ({{.Variable}} *{{.CapitalName}}) ModifyOrder(orderID int64, action exchang } // CancelOrder cancels an order by its corresponding ID number -func ({{.Variable}} *{{.CapitalName}}) CancelOrder(orderID int64) error { +func ({{.Variable}} *{{.CapitalName}}) CancelOrder(order exchange.OrderCancellation) error { return common.ErrNotYetImplemented }