Cancel all orders wrapper implementation (#217)

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

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

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

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

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

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

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

* Adds tests to all exchanges to test wrapper function CancelAllOrders

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

* Fixes coinut, hitbtc and okex api for authenticated requests

* Fixes comment and spacing

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

* Fixes OKEX delimiter

* Removes spacing and test verbosity

* Removes more spacing

* Removes space

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

View File

@@ -21,15 +21,17 @@ const (
gateioMarketURL = "https://data.gateio.io"
gateioAPIVersion = "api2/1"
gateioSymbol = "pairs"
gateioMarketInfo = "marketinfo"
gateioKline = "candlestick2"
gateioOrder = "private"
gateioBalances = "private/balances"
gateioCancelOrder = "private/cancelOrder"
gateioTicker = "ticker"
gateioTickers = "tickers"
gateioOrderbook = "orderBook"
gateioSymbol = "pairs"
gateioMarketInfo = "marketinfo"
gateioKline = "candlestick2"
gateioOrder = "private"
gateioBalances = "private/balances"
gateioCancelOrder = "private/cancelOrder"
gateioCancelAllOrders = "private/cancelAllOrders"
gateioOpenOrders = "private/openOrders"
gateioTicker = "ticker"
gateioTickers = "tickers"
gateioOrderbook = "orderBook"
gateioAuthRate = 100
gateioUnauthRate = 100
@@ -381,6 +383,54 @@ func (g *Gateio) SendHTTPRequest(path string, result interface{}) error {
return g.SendPayload("GET", path, nil, nil, result, false, g.Verbose)
}
// CancelAllExistingOrders all orders for a given symbol and side
// orderType (0: sell,1: buy,-1: unlimited)
func (g *Gateio) CancelAllExistingOrders(orderType int64, symbol string) error {
type response struct {
Result bool `json:"result"`
Code int `json:"code"`
Message string `json:"message"`
}
var result response
params := fmt.Sprintf("type=%d&currencyPair=%s",
orderType,
symbol,
)
err := g.SendAuthenticatedHTTPRequest("POST", gateioCancelAllOrders, params, &result)
if err != nil {
return err
}
if !result.Result {
return fmt.Errorf("code:%d message:%s", result.Code, result.Message)
}
return nil
}
//
// GetOpenOrders retrieves all orders with an optional symbol filter
func (g *Gateio) GetOpenOrders(symbol string) (OpenOrdersResponse, error) {
var params string
var result OpenOrdersResponse
if symbol != "" {
params = fmt.Sprintf("currencyPair=%s", symbol)
}
err := g.SendAuthenticatedHTTPRequest("POST", gateioOpenOrders, params, &result)
if err != nil {
return result, err
}
if result.Code > 0 {
return result, fmt.Errorf("code:%d message:%s", result.Code, result.Message)
}
return result, nil
}
// SendAuthenticatedHTTPRequest sends authenticated requests to the Gateio API
// To use this you must setup an APIKey and APISecret from the exchange
func (g *Gateio) SendAuthenticatedHTTPRequest(method, endpoint, param string, result interface{}) error {

View File

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

View File

@@ -130,6 +130,31 @@ type SpotNewOrderResponse struct {
Filledrate float64 `json:"filledRate,string"` // FilledPrice
}
// OpenOrdersResponse the main response from GetOpenOrders
type OpenOrdersResponse struct {
Code int `json:"code"`
Elapsed string `json:"elapsed"`
Message string `json:"message"`
Orders []OpenOrder `json:"orders"`
Result string `json:"result"`
}
// OpenOrder details each open order
type OpenOrder struct {
Amount string `json:"amount"`
CurrencyPair string `json:"currencyPair"`
FilledAmount int `json:"filledAmount"`
FilledRate int `json:"filledRate"`
InitialAmount string `json:"initialAmount"`
InitialRate float64 `json:"initialRate"`
OrderNumber string `json:"orderNumber"`
Rate float64 `json:"rate"`
Status string `json:"status"`
Timestamp string `json:"timestamp"`
Total string `json:"total"`
Type string `json:"type"`
}
// WithdrawalFees the large list of predefined withdrawal fees
// Prone to change
var WithdrawalFees = map[string]float64{

View File

@@ -231,8 +231,28 @@ func (g *Gateio) CancelOrder(order exchange.OrderCancellation) error {
}
// CancelAllOrders cancels all orders associated with a currency pair
func (g *Gateio) CancelAllOrders() error {
return common.ErrNotYetImplemented
func (g *Gateio) CancelAllOrders(orderCancellation exchange.OrderCancellation) (exchange.CancelAllOrdersResponse, error) {
cancelAllOrdersResponse := exchange.CancelAllOrdersResponse{
OrderStatus: make(map[string]string),
}
openOrders, err := g.GetOpenOrders("")
if err != nil {
return cancelAllOrdersResponse, err
}
var uniqueSymbols map[string]string
for _, openOrder := range openOrders.Orders {
uniqueSymbols[openOrder.CurrencyPair] = openOrder.CurrencyPair
}
for _, uniqueSymbol := range uniqueSymbols {
err = g.CancelAllExistingOrders(-1, uniqueSymbol)
if err != nil {
return cancelAllOrdersResponse, err
}
}
return cancelAllOrdersResponse, nil
}
// GetOrderInfo returns information on a current open order