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

@@ -454,9 +454,9 @@ func (a *Alphapoint) CancelExistingOrder(OrderID int64, OMSID string) (int64, er
// CancelAllExistingOrders cancels all open orders by symbol
// symbol - Instrument code (ex: “BTCUSD”)
func (a *Alphapoint) CancelAllExistingOrders(symbol string) error {
func (a *Alphapoint) CancelAllExistingOrders(OMSID string) error {
request := make(map[string]interface{})
request["ins"] = symbol
request["OMSId"] = OMSID
response := Response{}
err := a.SendAuthenticatedHTTPRequest(

View File

@@ -531,7 +531,6 @@ func TestCancelExchangeOrder(t *testing.T) {
t.Skip()
}
a.Verbose = true
currencyPair := pair.NewCurrencyPair(symbol.BTC, symbol.LTC)
var orderCancellation = exchange.OrderCancellation{
@@ -548,3 +547,33 @@ func TestCancelExchangeOrder(t *testing.T) {
t.Errorf("Test Failed - ANX CancelOrder() error: %s", err)
}
}
func TestCancelAllExchangeOrders(t *testing.T) {
// Arrange
a := &Alphapoint{}
a.SetDefaults()
if !isRealOrderTestEnabled(a) {
t.Skip()
}
currencyPair := pair.NewCurrencyPair(symbol.BTC, symbol.LTC)
var orderCancellation = exchange.OrderCancellation{
OrderID: "1",
WalletAddress: "1F5zVDgNjorJ51oGebSvNCrSAHpwGkUdDB",
AccountID: "1",
CurrencyPair: currencyPair,
}
// Act
resp, err := a.CancelAllOrders(orderCancellation)
// Assert
if err != nil {
t.Errorf("Could not cancel order: %s", err)
}
if len(resp.OrderStatus) > 0 {
t.Errorf("%v orders failed to cancel", len(resp.OrderStatus))
}
}

View File

@@ -133,7 +133,6 @@ func (a *Alphapoint) ModifyOrder(orderID int64, action exchange.ModifyOrder) (in
// CancelOrder cancels an order by its corresponding ID number
func (a *Alphapoint) CancelOrder(order exchange.OrderCancellation) error {
orderIDInt, err := strconv.ParseInt(order.OrderID, 10, 64)
if err != nil {
return err
}
@@ -143,10 +142,9 @@ func (a *Alphapoint) CancelOrder(order exchange.OrderCancellation) error {
return err
}
// CancelAllOrders cancels all orders associated with a currency pair
func (a *Alphapoint) CancelAllOrders() error {
// return a.CancelAllExistingOrders(p.Pair().String())
return common.ErrNotYetImplemented
// CancelAllOrders cancels all orders for a given account
func (a *Alphapoint) CancelAllOrders(orderCancellation exchange.OrderCancellation) (exchange.CancelAllOrdersResponse, error) {
return exchange.CancelAllOrdersResponse{}, a.CancelAllExistingOrders(orderCancellation.AccountID)
}
// GetOrderInfo returns information on a current open order

View File

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

View File

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

View File

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

View File

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

View File

@@ -487,13 +487,13 @@ func (b *Binance) CancelExistingOrder(symbol string, orderID int64, origClientOr
// Get all open orders on a symbol. Careful when accessing this with no symbol.
func (b *Binance) OpenOrders(symbol string) ([]QueryOrderData, error) {
var resp []QueryOrderData
path := fmt.Sprintf("%s%s", b.APIUrl, openOrders)
params := url.Values{}
if symbol != "" {
params.Set("symbol", common.StringToUpper(symbol))
}
if err := b.SendAuthHTTPRequest("GET", path, params, &resp); err != nil {
return resp, err
}

View File

@@ -367,13 +367,10 @@ func TestCancelExchangeOrder(t *testing.T) {
b.SetDefaults()
TestSetup(t)
if b.APIKey == "" || b.APISecret == "" ||
b.APIKey == "Key" || b.APISecret == "Secret" ||
!canManipulateRealOrders {
if !isRealOrderTestEnabled() {
t.Skip()
}
b.Verbose = true
currencyPair := pair.NewCurrencyPair(symbol.LTC, symbol.BTC)
var orderCancellation = exchange.OrderCancellation{
@@ -392,6 +389,37 @@ func TestCancelExchangeOrder(t *testing.T) {
}
}
func TestCancelAllExchangeOrders(t *testing.T) {
// Arrange
b.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 := b.CancelAllOrders(orderCancellation)
// Assert
if err != nil {
t.Errorf("Could not cancel order: %s", err)
}
if len(resp.OrderStatus) > 0 {
t.Errorf("%v orders failed to cancel", len(resp.OrderStatus))
}
}
func TestGetAccountInfo(t *testing.T) {
if testAPIKey == "" || testAPISecret == "" {
t.Skip()

View File

@@ -234,8 +234,23 @@ func (b *Binance) CancelOrder(order exchange.OrderCancellation) error {
}
// CancelAllOrders cancels all orders associated with a currency pair
func (b *Binance) CancelAllOrders() error {
return common.ErrNotYetImplemented
func (b *Binance) CancelAllOrders(orderCancellation exchange.OrderCancellation) (exchange.CancelAllOrdersResponse, error) {
cancelAllOrdersResponse := exchange.CancelAllOrdersResponse{
OrderStatus: make(map[string]string),
}
openOrders, err := b.OpenOrders("")
if err != nil {
return cancelAllOrdersResponse, err
}
for _, order := range openOrders {
_, err = b.CancelExistingOrder(order.Symbol, order.OrderID, "")
if err != nil {
cancelAllOrdersResponse.OrderStatus[strconv.FormatInt(order.OrderID, 10)] = err.Error()
}
}
return cancelAllOrdersResponse, nil
}
// GetOrderInfo returns information on a current open order

View File

@@ -653,7 +653,7 @@ func (b *Bitfinex) CancelAllExistingOrders() (string, error) {
response := GenericResponse{}
return response.Result,
b.SendAuthenticatedHTTPRequest("GET", bitfinexOrderCancelAll, nil, nil)
b.SendAuthenticatedHTTPRequest("POST", bitfinexOrderCancelAll, nil, nil)
}
// ReplaceOrder replaces an older order with a new order

View File

@@ -637,7 +637,6 @@ func setFeeBuilder() exchange.FeeBuilder {
func TestGetFee(t *testing.T) {
b.SetDefaults()
b.Verbose = true
TestSetup(t)
var feeBuilder = setFeeBuilder()
@@ -759,7 +758,6 @@ func TestCancelExchangeOrder(t *testing.T) {
t.Skip()
}
b.Verbose = true
currencyPair := pair.NewCurrencyPair(symbol.LTC, symbol.BTC)
var orderCancellation = exchange.OrderCancellation{
@@ -777,3 +775,34 @@ func TestCancelExchangeOrder(t *testing.T) {
t.Errorf("Could not cancel order: %s", err)
}
}
func TestCancelAllExchangeOrdera(t *testing.T) {
// Arrange
b.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 := b.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))
}
}

View File

@@ -216,8 +216,9 @@ func (b *Bitfinex) CancelOrder(order exchange.OrderCancellation) error {
}
// CancelAllOrders cancels all orders associated with a currency pair
func (b *Bitfinex) CancelAllOrders() error {
return common.ErrNotYetImplemented
func (b *Bitfinex) CancelAllOrders(orderCancellation exchange.OrderCancellation) (exchange.CancelAllOrdersResponse, error) {
_, err := b.CancelAllExistingOrders()
return exchange.CancelAllOrdersResponse{}, err
}
// GetOrderInfo returns information on a current open order

View File

@@ -286,7 +286,6 @@ func TestCancelExchangeOrder(t *testing.T) {
t.Skip()
}
b.Verbose = true
currencyPair := pair.NewCurrencyPair(symbol.LTC, symbol.BTC)
var orderCancellation = exchange.OrderCancellation{
@@ -304,3 +303,34 @@ func TestCancelExchangeOrder(t *testing.T) {
t.Errorf("Could not cancel order: %s", err)
}
}
func TestCancelAllExchangeOrders(t *testing.T) {
// Arrange
b.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 := b.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))
}
}

View File

@@ -171,8 +171,10 @@ func (b *Bitflyer) CancelOrder(order exchange.OrderCancellation) error {
}
// CancelAllOrders cancels all orders associated with a currency pair
func (b *Bitflyer) CancelAllOrders() error {
return common.ErrNotYetImplemented
func (b *Bitflyer) CancelAllOrders(orderCancellation exchange.OrderCancellation) (exchange.CancelAllOrdersResponse, error) {
// TODO, implement BitFlyer API
b.CancelAllExistingOrders()
return exchange.CancelAllOrdersResponse{}, common.ErrNotYetImplemented
}
// GetOrderInfo returns information on a current open order

View File

@@ -326,7 +326,6 @@ func TestCancelExchangeOrder(t *testing.T) {
t.Skip()
}
b.Verbose = true
currencyPair := pair.NewCurrencyPair(symbol.LTC, symbol.BTC)
var orderCancellation = exchange.OrderCancellation{
@@ -345,6 +344,37 @@ func TestCancelExchangeOrder(t *testing.T) {
}
}
func TestCancelAllExchangeOrders(t *testing.T) {
// Arrange
b.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 := b.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) {
t.Parallel()
if testAPIKey != "" || testAPISecret != "" {

View File

@@ -115,22 +115,25 @@ type LastTransactionTicker struct {
// Orders contains information about your current orders
type Orders struct {
Status string `json:"status"`
Data []struct {
OrderID string `json:"order_id"`
OrderCurrency string `json:"order_currency"`
OrderDate int64 `json:"order_date"`
PaymentCurrency string `json:"payment_currency"`
Type string `json:"type"`
Status string `json:"status"`
Units float64 `json:"units,string"`
UnitsRemaining float64 `json:"units_remaining,string"`
Price float64 `json:"price,string"`
Fee float64 `json:"fee,string"`
Total float64 `json:"total,string"`
DateCompleted int64 `json:"date_completed"`
} `json:"data"`
Message string `json:"message"`
Status string `json:"status"`
Data []OrderData `json:"data"`
Message string `json:"message"`
}
// OrderData contains all individual order details
type OrderData struct {
OrderID string `json:"order_id"`
OrderCurrency string `json:"order_currency"`
OrderDate int64 `json:"order_date"`
PaymentCurrency string `json:"payment_currency"`
Type string `json:"type"`
Status string `json:"status"`
Units float64 `json:"units,string"`
UnitsRemaining float64 `json:"units_remaining,string"`
Price float64 `json:"price,string"`
Fee float64 `json:"fee,string"`
Total float64 `json:"total,string"`
DateCompleted int64 `json:"date_completed"`
}
// UserTransactions holds users full transaction list

View File

@@ -200,8 +200,31 @@ func (b *Bithumb) CancelOrder(order exchange.OrderCancellation) error {
}
// CancelAllOrders cancels all orders associated with a currency pair
func (b *Bithumb) CancelAllOrders() error {
return common.ErrNotYetImplemented
func (b *Bithumb) CancelAllOrders(orderCancellation exchange.OrderCancellation) (exchange.CancelAllOrdersResponse, error) {
cancelAllOrdersResponse := exchange.CancelAllOrdersResponse{
OrderStatus: make(map[string]string),
}
var allOrders []OrderData
for _, currency := range b.GetEnabledCurrencies() {
orders, err := b.GetOrders("", orderCancellation.Side.ToString(), "100", "", currency.FirstCurrency.String())
if err != nil {
return cancelAllOrdersResponse, err
}
for _, order := range orders.Data {
allOrders = append(allOrders, order)
}
}
for _, order := range allOrders {
_, err := b.CancelTrade(orderCancellation.Side.ToString(), order.OrderID, orderCancellation.CurrencyPair.FirstCurrency.String())
if err != nil {
cancelAllOrdersResponse.OrderStatus[order.OrderID] = err.Error()
}
}
return cancelAllOrdersResponse, nil
}
// GetOrderInfo returns information on a current open order

View File

@@ -242,7 +242,7 @@ func TestCancelOrders(t *testing.T) {
func TestCancelAllOrders(t *testing.T) {
_, err := b.CancelAllExistingOrders(OrderCancelAllParams{})
if err == nil {
t.Error("test failed - CancelAllOrders() error", err)
t.Error("test failed - CancelAllOrders(orderCancellation exchange.OrderCancellation) (exchange.CancelAllOrdersResponse, error)", err)
}
}
@@ -503,7 +503,6 @@ func TestCancelExchangeOrder(t *testing.T) {
t.Skip()
}
b.Verbose = true
currencyPair := pair.NewCurrencyPair(symbol.LTC, symbol.BTC)
var orderCancellation = exchange.OrderCancellation{
@@ -522,6 +521,37 @@ func TestCancelExchangeOrder(t *testing.T) {
}
}
func TestCancelAllExchangeOrders(t *testing.T) {
// Arrange
b.SetDefaults()
TestSetup(t)
if !isRealOrderTestEnabled() {
t.Skip()
}
currencyPair := pair.NewCurrencyPair(symbol.LTC, symbol.BTC)
var orderCancellation = exchange.OrderCancellation{
OrderID: "123456789012345678901234567890123456",
WalletAddress: "1F5zVDgNjorJ51oGebSvNCrSAHpwGkUdDB",
AccountID: "1",
CurrencyPair: currencyPair,
}
// Act
resp, err := b.CancelAllOrders(orderCancellation)
// Assert
if err != nil {
t.Errorf("Could not cancel order: %s", err)
}
if len(resp.OrderStatus) > 0 {
t.Errorf("%v orders failed to cancel", len(resp.OrderStatus))
}
}
func TestGetAccountInfo(t *testing.T) {
if testAPIKey != "" || testAPISecret != "" {
_, err := b.GetAccountInfo()

View File

@@ -204,8 +204,21 @@ func (b *Bitmex) CancelOrder(order exchange.OrderCancellation) error {
}
// CancelAllOrders cancels all orders associated with a currency pair
func (b *Bitmex) CancelAllOrders() error {
return common.ErrNotYetImplemented
func (b *Bitmex) CancelAllOrders(orderCancellation exchange.OrderCancellation) (exchange.CancelAllOrdersResponse, error) {
cancelAllOrdersResponse := exchange.CancelAllOrdersResponse{
OrderStatus: make(map[string]string),
}
var emptyParams OrderCancelAllParams
orders, err := b.CancelAllExistingOrders(emptyParams)
if err != nil {
return cancelAllOrdersResponse, err
}
for _, order := range orders {
cancelAllOrdersResponse.OrderStatus[order.OrderID] = order.OrdRejReason
}
return cancelAllOrdersResponse, nil
}
// GetOrderInfo returns information on a current open order

View File

@@ -54,6 +54,7 @@ func TestSetup(t *testing.T) {
bConfig.ClientID = customerID
b.Setup(bConfig)
b.ClientID = customerID
if !b.IsEnabled() || b.RESTPollingDelay != time.Duration(10) ||
b.Verbose || b.Websocket.IsEnabled() || len(b.BaseCurrencies) < 1 ||
@@ -406,7 +407,6 @@ func TestCancelExchangeOrder(t *testing.T) {
t.Skip()
}
b.Verbose = true
currencyPair := pair.NewCurrencyPair(symbol.LTC, symbol.BTC)
var orderCancellation = exchange.OrderCancellation{
@@ -424,3 +424,34 @@ func TestCancelExchangeOrder(t *testing.T) {
t.Errorf("Could not cancel order: %s", err)
}
}
func TestCancelAllExchangeOrders(t *testing.T) {
// Arrange
b.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 := b.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))
}
}

View File

@@ -1,6 +1,7 @@
package bitstamp
import (
"errors"
"fmt"
"log"
"strconv"
@@ -202,8 +203,13 @@ func (b *Bitstamp) CancelOrder(order exchange.OrderCancellation) error {
}
// CancelAllOrders cancels all orders associated with a currency pair
func (b *Bitstamp) CancelAllOrders() error {
return common.ErrNotYetImplemented
func (b *Bitstamp) CancelAllOrders(orderCancellation exchange.OrderCancellation) (exchange.CancelAllOrdersResponse, error) {
isCancelAllSuccessful, err := b.CancelAllExistingOrders()
if !isCancelAllSuccessful {
err = errors.New("Cancel all failed. Bitstamp provides no further information. Check order status to verify")
}
return exchange.CancelAllOrdersResponse{}, err
}
// GetOrderInfo returns information on a current open order

View File

@@ -372,7 +372,6 @@ func TestCancelExchangeOrder(t *testing.T) {
t.Skip()
}
b.Verbose = true
currencyPair := pair.NewCurrencyPair(symbol.LTC, symbol.BTC)
var orderCancellation = exchange.OrderCancellation{
@@ -390,3 +389,34 @@ func TestCancelExchangeOrder(t *testing.T) {
t.Errorf("Could not cancel order: %s", err)
}
}
func TestCancelAllExchangeOrders(t *testing.T) {
// Arrange
b.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 := b.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))
}
}

View File

@@ -210,8 +210,23 @@ func (b *Bittrex) CancelOrder(order exchange.OrderCancellation) error {
}
// CancelAllOrders cancels all orders associated with a currency pair
func (b *Bittrex) CancelAllOrders() error {
return common.ErrNotYetImplemented
func (b *Bittrex) CancelAllOrders(orderCancellation exchange.OrderCancellation) (exchange.CancelAllOrdersResponse, error) {
cancelAllOrdersResponse := exchange.CancelAllOrdersResponse{
OrderStatus: make(map[string]string),
}
openOrders, err := b.GetOpenOrders("")
if err != nil {
return cancelAllOrdersResponse, err
}
for _, order := range openOrders.Result {
_, err := b.CancelExistingOrder(order.OrderUUID)
if err != nil {
cancelAllOrdersResponse.OrderStatus[order.OrderUUID] = err.Error()
}
}
return cancelAllOrdersResponse, nil
}
// GetOrderInfo returns information on a current open order

View File

@@ -210,7 +210,6 @@ func TestCancelExchangeOrder(t *testing.T) {
t.Skip()
}
b.Verbose = true
currencyPair := pair.NewCurrencyPair(symbol.LTC, symbol.BTC)
var orderCancellation = exchange.OrderCancellation{
@@ -228,3 +227,34 @@ func TestCancelExchangeOrder(t *testing.T) {
t.Errorf("Could not cancel order: %s", err)
}
}
func TestCancelAllExchangeOrders(t *testing.T) {
// Arrange
b.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 := b.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))
}
}

View File

@@ -169,8 +169,8 @@ func (b *BTCC) CancelOrder(order exchange.OrderCancellation) error {
}
// CancelAllOrders cancels all orders associated with a currency pair
func (b *BTCC) CancelAllOrders() error {
return common.ErrNotYetImplemented
func (b *BTCC) CancelAllOrders(orderCancellation exchange.OrderCancellation) (exchange.CancelAllOrdersResponse, error) {
return exchange.CancelAllOrdersResponse{}, common.ErrNotYetImplemented
}
// GetOrderInfo returns information on a current open order

View File

@@ -208,7 +208,7 @@ func (b *BTCMarkets) NewOrder(currency, instrument string, price, amount float64
// CancelExistingOrder cancels an order by its ID
// orderID - id for order example "1337"
func (b *BTCMarkets) CancelExistingOrder(orderID []int64) (bool, error) {
func (b *BTCMarkets) CancelExistingOrder(orderID []int64) ([]ResponseDetails, error) {
resp := Response{}
type CancelOrder struct {
OrderIDs []int64 `json:"orderIds"`
@@ -218,28 +218,14 @@ func (b *BTCMarkets) CancelExistingOrder(orderID []int64) (bool, error) {
err := b.SendAuthenticatedRequest("POST", btcMarketsOrderCancel, orders, &resp)
if err != nil {
return false, err
return resp.Responses, err
}
if !resp.Success {
return false, fmt.Errorf("%s Unable to cancel order. Error message: %s", b.GetName(), resp.ErrorMessage)
return resp.Responses, fmt.Errorf("%s Unable to cancel order. Error message: %s", b.GetName(), resp.ErrorMessage)
}
ordersToBeCancelled := len(orderID)
ordersCancelled := 0
for _, y := range resp.Responses {
if y.Success {
ordersCancelled++
log.Printf("%s Cancelled order %d.\n", b.GetName(), y.ID)
} else {
log.Printf("%s Unable to cancel order %d. Error message: %s", b.GetName(), y.ID, y.ErrorMessage)
}
}
if ordersCancelled == ordersToBeCancelled {
return true, nil
}
return false, fmt.Errorf("%s Unable to cancel order(s)", b.GetName())
return resp.Responses, nil
}
// GetOrders returns current order information on the exchange
@@ -294,6 +280,28 @@ func (b *BTCMarkets) GetOrders(currency, instrument string, limit, since int64,
return resp.Orders, nil
}
// GetOpenOrders returns all open orders
func (b *BTCMarkets) GetOpenOrders() ([]Order, error) {
type marketsResp struct {
Response
Orders []Order `json:"orders"`
}
request := make(map[string]interface{})
var resp marketsResp
path := fmt.Sprintf("/v2/order/open")
err := b.SendAuthenticatedRequest("GET", path, request, &resp)
if err != nil {
return nil, err
}
if !resp.Success {
return nil, errors.New(resp.ErrorMessage)
}
return resp.Orders, nil
}
// GetOrderDetail returns order information an a specific order
// orderID - example "1337"
func (b *BTCMarkets) GetOrderDetail(orderID []int64) ([]Order, error) {

View File

@@ -169,13 +169,6 @@ func TestCancelOrder(t *testing.T) {
}
}
func TestCancelAllOrders(t *testing.T) {
err := b.CancelAllOrders()
if err == nil {
t.Error("Test failed - CancelAllOrders() error", err)
}
}
func TestGetOrderInfo(t *testing.T) {
_, err := b.GetOrderInfo(1337)
if err == nil {
@@ -343,7 +336,6 @@ func TestCancelExchangeOrder(t *testing.T) {
t.Skip()
}
b.Verbose = true
currencyPair := pair.NewCurrencyPair(symbol.LTC, symbol.BTC)
var orderCancellation = exchange.OrderCancellation{
@@ -361,3 +353,34 @@ func TestCancelExchangeOrder(t *testing.T) {
t.Errorf("Could not cancel order: %s", err)
}
}
func TestCancelAllExchangeOrders(t *testing.T) {
// Arrange
b.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 := b.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))
}
}

View File

@@ -4,19 +4,22 @@ import "github.com/thrasher-/gocryptotrader/currency/symbol"
// Response is the genralized response type
type Response struct {
Success bool `json:"success"`
ErrorCode int `json:"errorCode"`
ErrorMessage string `json:"errorMessage"`
ID int `json:"id"`
Responses []ResponseDetails `json:"responses"`
ClientRequestID string `json:"clientRequestId"`
Orders []Order `json:"orders"`
Status string `json:"status"`
}
// ResponseDetails holds order status details
type ResponseDetails struct {
Success bool `json:"success"`
ErrorCode int `json:"errorCode"`
ErrorMessage string `json:"errorMessage"`
ID int `json:"id"`
Responses []struct {
Success bool `json:"success"`
ErrorCode int `json:"errorCode"`
ErrorMessage string `json:"errorMessage"`
ID int64 `json:"id"`
}
ClientRequestID string `json:"clientRequestId"`
Orders []Order `json:"orders"`
Status string `json:"status"`
ID int64 `json:"id"`
}
// Market holds a tradable market instrument

View File

@@ -186,28 +186,37 @@ func (b *BTCMarkets) CancelOrder(order exchange.OrderCancellation) error {
}
// CancelAllOrders cancels all orders associated with a currency pair
func (b *BTCMarkets) CancelAllOrders() error {
orders, err := b.GetOrders("", "", 0, 0, true)
func (b *BTCMarkets) CancelAllOrders(orderCancellation exchange.OrderCancellation) (exchange.CancelAllOrdersResponse, error) {
cancelAllOrdersResponse := exchange.CancelAllOrdersResponse{
OrderStatus: make(map[string]string),
}
openOrders, err := b.GetOpenOrders()
if err != nil {
return err
return cancelAllOrdersResponse, err
}
var orderList []int64
for _, order := range orders {
orderIDInt, strconvErr := strconv.ParseInt(order.ID, 10, 64)
if strconvErr != nil {
return strconvErr
for _, order := range openOrders {
orderIDInt, err := strconv.ParseInt(order.ID, 10, 64)
if err != nil {
cancelAllOrdersResponse.OrderStatus[order.ID] = err.Error()
}
orderList = append(orderList, orderIDInt)
}
_, err = b.CancelExistingOrder(orderList)
if err != nil {
return err
if len(orderList) > 0 {
orders, err := b.CancelExistingOrder(orderList)
if err != nil {
return cancelAllOrdersResponse, err
}
for _, order := range orders {
if err != nil {
cancelAllOrdersResponse.OrderStatus[strconv.FormatInt(order.ID, 10)] = err.Error()
}
}
}
return nil
return cancelAllOrdersResponse, nil
}
// GetOrderInfo returns information on a current open order

View File

@@ -499,7 +499,7 @@ func (c *CoinbasePro) CancelAllExistingOrders(currencyPair string) ([]string, er
var resp []string
request := make(map[string]interface{})
if len(currencyPair) != 0 {
if len(currencyPair) > 0 {
request["product_id"] = currencyPair
}
return resp, c.SendAuthenticatedHTTPRequest("DELETE", coinbaseproOrders, request, &resp)

View File

@@ -446,7 +446,6 @@ func TestCancelExchangeOrder(t *testing.T) {
t.Skip()
}
c.Verbose = true
currencyPair := pair.NewCurrencyPair(symbol.LTC, symbol.BTC)
var orderCancellation = exchange.OrderCancellation{
@@ -464,3 +463,34 @@ func TestCancelExchangeOrder(t *testing.T) {
t.Errorf("Could not cancel order: %s", err)
}
}
func TestCancelAllExchangeOrders(t *testing.T) {
// Arrange
c.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 := c.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))
}
}

View File

@@ -180,8 +180,10 @@ func (c *CoinbasePro) CancelOrder(order exchange.OrderCancellation) error {
}
// CancelAllOrders cancels all orders associated with a currency pair
func (c *CoinbasePro) CancelAllOrders() error {
return common.ErrNotYetImplemented
func (c *CoinbasePro) CancelAllOrders(orderCancellation exchange.OrderCancellation) (exchange.CancelAllOrdersResponse, error) {
// CancellAllExisting orders returns a list of successful cancellations, we're only interested in failures
_, err := c.CancelAllExistingOrders("")
return exchange.CancelAllOrdersResponse{}, err
}
// GetOrderInfo returns information on a current open order

View File

@@ -204,8 +204,8 @@ func (c *COINUT) NewOrders(orders []Order) ([]OrdersBase, error) {
}
// GetOpenOrders returns a list of open order and relevant information
func (c *COINUT) GetOpenOrders(instrumentID int) ([]OrdersResponse, error) {
var result []OrdersResponse
func (c *COINUT) GetOpenOrders(instrumentID int) (GetOpenOrdersResponse, error) {
var result GetOpenOrdersResponse
params := make(map[string]interface{})
params["inst_id"] = instrumentID
@@ -240,7 +240,17 @@ func (c *COINUT) CancelExistingOrder(instrumentID, orderID int) (bool, error) {
func (c *COINUT) CancelOrders(orders []CancelOrders) (CancelOrdersResponse, error) {
var result CancelOrdersResponse
params := make(map[string]interface{})
params["entries"] = orders
type Request struct {
InstrumentID int `json:"inst_id"`
OrderID int `json:"order_id"`
}
entries := []CancelOrders{}
for _, order := range orders {
entries = append(entries, order)
}
params["entries"] = entries
return result, c.SendHTTPRequest(coinutOrdersCancel, params, true, &result)
}
@@ -348,7 +358,7 @@ func (c *COINUT) SendHTTPRequest(apiRequest string, params map[string]interface{
headers := make(map[string]string)
if authenticated {
headers["X-USER"] = c.ClientID
hmac := common.GetHMAC(common.HashSHA256, []byte(payload), []byte(c.APIKey))
hmac := common.GetHMAC(common.HashSHA256, []byte(payload), []byte(c.APISecret))
headers["X-SIGNATURE"] = common.HexEncodeToString(hmac)
}
headers["Content-Type"] = "application/json"

View File

@@ -32,9 +32,8 @@ func TestSetup(t *testing.T) {
}
bConfig.AuthenticatedAPISupport = true
bConfig.APIKey = apiKey
bConfig.ClientID = clientID
bConfig.Verbose = true
c.Setup(bConfig)
c.ClientID = clientID
if !c.IsEnabled() ||
c.RESTPollingDelay != time.Duration(10) ||
@@ -196,8 +195,9 @@ func TestFormatWithdrawPermissions(t *testing.T) {
// 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" ||
if c.APIKey == "" ||
c.APIKey == "Key" ||
!canManipulateRealOrders {
return false
}
@@ -207,7 +207,6 @@ func isRealOrderTestEnabled() bool {
func TestSubmitOrder(t *testing.T) {
c.SetDefaults()
TestSetup(t)
c.Verbose = true
if !isRealOrderTestEnabled() {
t.Skip()
@@ -233,7 +232,6 @@ func TestCancelExchangeOrder(t *testing.T) {
t.Skip()
}
c.Verbose = true
currencyPair := pair.NewCurrencyPair(symbol.LTC, symbol.BTC)
var orderCancellation = exchange.OrderCancellation{
@@ -252,6 +250,37 @@ func TestCancelExchangeOrder(t *testing.T) {
}
}
func TestCancelAllExchangeOrders(t *testing.T) {
// Arrange
c.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 := c.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 apiKey != "" || clientID != "" {
_, err := c.GetAccountInfo()

View File

@@ -137,6 +137,15 @@ type OrdersBase struct {
OrderResponse
}
// GetOpenOrdersResponse holds all order data from GetOpenOrders request
type GetOpenOrdersResponse struct {
Nonce int `json:"nonce"`
Orders []OrderResponse `json:"orders"`
Reply string `json:"reply"`
Status []string `json:"status"`
TransID int `json:"trans_id"`
}
// OrdersResponse holds the full data range on orders
type OrdersResponse struct {
Data []OrdersBase
@@ -144,7 +153,7 @@ type OrdersResponse struct {
// CancelOrders holds information about a cancelled order
type CancelOrders struct {
InstrumentID int `json:"int"`
InstrumentID int64 `json:"inst_id"`
OrderID int64 `json:"order_id"`
}

View File

@@ -286,8 +286,57 @@ func (c *COINUT) CancelOrder(order exchange.OrderCancellation) error {
}
// CancelAllOrders cancels all orders associated with a currency pair
func (c *COINUT) CancelAllOrders() error {
return common.ErrNotYetImplemented
func (c *COINUT) CancelAllOrders(orderCancellation exchange.OrderCancellation) (exchange.CancelAllOrdersResponse, error) {
// TODO, this is a terrible implementation. Requires DB to improve
// Coinut provides no way of retrieving orders without a currency
// So we need to retrieve all currencies, then retrieve orders for each currency
// Then cancel. Advisable to never use this until DB due to performance
cancelAllOrdersResponse := exchange.CancelAllOrdersResponse{
OrderStatus: make(map[string]string),
}
instruments, err := c.GetInstruments()
if err != nil {
return cancelAllOrdersResponse, err
}
var allTheOrders []OrderResponse
for _, allInstrumentData := range instruments.Instruments {
for _, instrumentData := range allInstrumentData {
openOrders, err := c.GetOpenOrders(instrumentData.InstID)
if err != nil {
return cancelAllOrdersResponse, err
}
for _, openOrder := range openOrders.Orders {
allTheOrders = append(allTheOrders, openOrder)
}
}
}
var allTheOrdersToCancel []CancelOrders
for _, orderToCancel := range allTheOrders {
cancelOrder := CancelOrders{
InstrumentID: orderToCancel.InstrumentID,
OrderID: orderToCancel.OrderID,
}
allTheOrdersToCancel = append(allTheOrdersToCancel, cancelOrder)
}
if len(allTheOrdersToCancel) > 0 {
resp, err := c.CancelOrders(allTheOrdersToCancel)
if err != nil {
return cancelAllOrdersResponse, err
}
for _, order := range resp.Results {
if order.Status != "OK" {
cancelAllOrdersResponse.OrderStatus[strconv.FormatInt(order.OrderID, 10)] = order.Status
}
}
}
return cancelAllOrdersResponse, nil
}
// GetOrderInfo returns information on a current open order

View File

@@ -264,7 +264,7 @@ type IBotExchange interface {
SubmitOrder(p pair.CurrencyPair, side OrderSide, orderType OrderType, amount, price float64, clientID string) (SubmitOrderResponse, error)
ModifyOrder(orderID int64, modify ModifyOrder) (int64, error)
CancelOrder(order OrderCancellation) error
CancelAllOrders() error
CancelAllOrders(orders OrderCancellation) (CancelAllOrdersResponse, error)
GetOrderInfo(orderID int64) (OrderDetail, error)
GetDepositAddress(cryptocurrency pair.CurrencyItem) (string, error)
@@ -741,6 +741,11 @@ type Format struct {
OrderSide map[string]string
}
// CancelAllOrdersResponse returns the status from attempting to cancel all orders on an exchagne
type CancelAllOrdersResponse struct {
OrderStatus map[string]string
}
// Formatting contain a range of exchanges formatting
type Formatting []Format

View File

@@ -262,7 +262,6 @@ func isRealOrderTestEnabled() bool {
func TestSubmitOrder(t *testing.T) {
e.SetDefaults()
TestSetup(t)
e.Verbose = true
if !isRealOrderTestEnabled() {
t.Skip()
@@ -288,7 +287,6 @@ func TestCancelExchangeOrder(t *testing.T) {
t.Skip()
}
e.Verbose = true
currencyPair := pair.NewCurrencyPair(symbol.LTC, symbol.BTC)
var orderCancellation = exchange.OrderCancellation{
@@ -306,3 +304,34 @@ func TestCancelExchangeOrder(t *testing.T) {
t.Errorf("Could not cancel order: %s", err)
}
}
func TestCancelAllExchangeOrders(t *testing.T) {
// Arrange
e.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 := e.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))
}
}

View File

@@ -223,8 +223,23 @@ func (e *EXMO) CancelOrder(order exchange.OrderCancellation) error {
}
// CancelAllOrders cancels all orders associated with a currency pair
func (e *EXMO) CancelAllOrders() error {
return common.ErrNotYetImplemented
func (e *EXMO) CancelAllOrders(orderCancellation exchange.OrderCancellation) (exchange.CancelAllOrdersResponse, error) {
cancelAllOrdersResponse := exchange.CancelAllOrdersResponse{
OrderStatus: make(map[string]string),
}
openOrders, err := e.GetOpenOrders()
if err != nil {
return cancelAllOrdersResponse, err
}
for _, order := range openOrders {
err = e.CancelExistingOrder(order.OrderID)
if err != nil {
cancelAllOrdersResponse.OrderStatus[strconv.FormatInt(order.OrderID, 10)] = err.Error()
}
}
return cancelAllOrdersResponse, nil
}
// GetOrderInfo returns information on a current open order

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

View File

@@ -338,7 +338,6 @@ func isRealOrderTestEnabled() bool {
func TestSubmitOrder(t *testing.T) {
Session[1].SetDefaults()
TestSetup(t)
Session[1].Verbose = true
if !isRealOrderTestEnabled() {
t.Skip()
@@ -364,7 +363,6 @@ func TestCancelExchangeOrder(t *testing.T) {
t.Skip()
}
Session[1].Verbose = true
currencyPair := pair.NewCurrencyPair(symbol.LTC, symbol.BTC)
var orderCancellation = exchange.OrderCancellation{
@@ -382,3 +380,34 @@ func TestCancelExchangeOrder(t *testing.T) {
t.Errorf("Could not cancel order: %s", err)
}
}
func TestCancelAllExchangeOrders(t *testing.T) {
// Arrange
Session[1].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 := Session[1].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))
}
}

View File

@@ -153,19 +153,29 @@ func (g *Gemini) ModifyOrder(orderID int64, action exchange.ModifyOrder) (int64,
// CancelOrder cancels an order by its corresponding ID number
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
func (g *Gemini) CancelAllOrders() error {
return common.ErrNotYetImplemented
func (g *Gemini) CancelAllOrders(orderCancellation exchange.OrderCancellation) (exchange.CancelAllOrdersResponse, error) {
cancelAllOrdersResponse := exchange.CancelAllOrdersResponse{
OrderStatus: make(map[string]string),
}
resp, err := g.CancelExistingOrders(false)
if err != nil {
return cancelAllOrdersResponse, err
}
for _, order := range resp.Details.CancelRejects {
cancelAllOrdersResponse.OrderStatus[order] = "Could not cancel order"
}
return cancelAllOrdersResponse, nil
}
// GetOrderInfo returns information on a current open order

View File

@@ -449,6 +449,19 @@ func (h *HitBTC) CancelExistingOrder(orderID int64) (bool, error) {
return true, nil
}
// CancelAllExistingOrders cancels all open orders
func (h *HitBTC) CancelAllExistingOrders() ([]Order, error) {
var result []Order
values := url.Values{}
err := h.SendAuthenticatedHTTPRequest("DELETE", orderBuy, values, &result)
if err != nil {
return result, err
}
return result, nil
}
// MoveOrder generates a new move order
func (h *HitBTC) MoveOrder(orderID int64, rate, amount float64) (MoveOrderResponse, error) {
result := MoveOrderResponse{}

View File

@@ -189,7 +189,6 @@ func isRealOrderTestEnabled() bool {
func TestSubmitOrder(t *testing.T) {
h.SetDefaults()
TestSetup(t)
h.Verbose = true
if !isRealOrderTestEnabled() {
t.Skip()
@@ -215,7 +214,6 @@ func TestCancelExchangeOrder(t *testing.T) {
t.Skip()
}
h.Verbose = true
currencyPair := pair.NewCurrencyPair(symbol.LTC, symbol.BTC)
var orderCancellation = exchange.OrderCancellation{
@@ -233,3 +231,34 @@ func TestCancelExchangeOrder(t *testing.T) {
t.Errorf("Could not cancel order: %s", err)
}
}
func TestCancelAllExchangeOrders(t *testing.T) {
// Arrange
h.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 := h.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))
}
}

View File

@@ -191,8 +191,20 @@ func (h *HitBTC) CancelOrder(order exchange.OrderCancellation) error {
}
// CancelAllOrders cancels all orders associated with a currency pair
func (h *HitBTC) CancelAllOrders() error {
return common.ErrNotYetImplemented
func (h *HitBTC) CancelAllOrders(orderCancellation exchange.OrderCancellation) (exchange.CancelAllOrdersResponse, error) {
cancelAllOrdersResponse := exchange.CancelAllOrdersResponse{
OrderStatus: make(map[string]string),
}
resp, err := h.CancelAllExistingOrders()
if err != nil {
return cancelAllOrdersResponse, err
}
for _, order := range resp {
cancelAllOrdersResponse.OrderStatus[strconv.FormatInt(order.ID, 10)] = fmt.Sprintf("Could not cancel order %v. Status: %v", order.ID, order.Status)
}
return cancelAllOrdersResponse, nil
}
// GetOrderInfo returns information on a current open order

View File

@@ -29,32 +29,34 @@ const (
huobiAPIURL = "https://api.huobi.pro"
huobiAPIVersion = "1"
huobiMarketHistoryKline = "market/history/kline"
huobiMarketDetail = "market/detail"
huobiMarketDetailMerged = "market/detail/merged"
huobiMarketDepth = "market/depth"
huobiMarketTrade = "market/trade"
huobiMarketTradeHistory = "market/history/trade"
huobiSymbols = "common/symbols"
huobiCurrencies = "common/currencys"
huobiTimestamp = "common/timestamp"
huobiAccounts = "account/accounts"
huobiAccountBalance = "account/accounts/%s/balance"
huobiOrderPlace = "order/orders/place"
huobiOrderCancel = "order/orders/%s/submitcancel"
huobiOrderCancelBatch = "order/orders/batchcancel"
huobiGetOrder = "order/orders/%s"
huobiGetOrderMatch = "order/orders/%s/matchresults"
huobiGetOrders = "order/orders"
huobiGetOrdersMatch = "orders/matchresults"
huobiMarginTransferIn = "dw/transfer-in/margin"
huobiMarginTransferOut = "dw/transfer-out/margin"
huobiMarginOrders = "margin/orders"
huobiMarginRepay = "margin/orders/%s/repay"
huobiMarginLoanOrders = "margin/loan-orders"
huobiMarginAccountBalance = "margin/accounts/balance"
huobiWithdrawCreate = "dw/withdraw/api/create"
huobiWithdrawCancel = "dw/withdraw-virtual/%s/cancel"
huobiMarketHistoryKline = "market/history/kline"
huobiMarketDetail = "market/detail"
huobiMarketDetailMerged = "market/detail/merged"
huobiMarketDepth = "market/depth"
huobiMarketTrade = "market/trade"
huobiMarketTradeHistory = "market/history/trade"
huobiSymbols = "common/symbols"
huobiCurrencies = "common/currencys"
huobiTimestamp = "common/timestamp"
huobiAccounts = "account/accounts"
huobiAccountBalance = "account/accounts/%s/balance"
huobiOrderPlace = "order/orders/place"
huobiOrderCancel = "order/orders/%s/submitcancel"
huobiOrderCancelBatch = "order/orders/batchcancel"
huobiBatchCancelOpenOrders = "order/orders/batchCancelOpenOrders"
huobiGetOrder = "order/orders/%s"
huobiGetOrderMatch = "order/orders/%s/matchresults"
huobiGetOrders = "order/orders"
huobiGetOpenOrders = "order/order/openOrders"
huobiGetOrdersMatch = "orders/matchresults"
huobiMarginTransferIn = "dw/transfer-in/margin"
huobiMarginTransferOut = "dw/transfer-out/margin"
huobiMarginOrders = "margin/orders"
huobiMarginRepay = "margin/orders/%s/repay"
huobiMarginLoanOrders = "margin/loan-orders"
huobiMarginAccountBalance = "margin/accounts/balance"
huobiWithdrawCreate = "dw/withdraw/api/create"
huobiWithdrawCancel = "dw/withdraw-virtual/%s/cancel"
huobiAuthRate = 100
huobiUnauthRate = 100
@@ -129,6 +131,7 @@ func (h *HUOBI) Setup(exch config.ExchangeConfig) {
if err != nil {
log.Fatal(err)
}
err = h.WebsocketSetup(h.WsConnect,
exch.Name,
exch.Websocket,
@@ -452,6 +455,29 @@ func (h *HUOBI) CancelOrderBatch(orderIDs []int64) ([]CancelOrderBatch, error) {
return result.Data, err
}
// CancelOpenOrdersBatch cancels a batch of orders -- to-do
func (h *HUOBI) CancelOpenOrdersBatch(accountID, symbol string) (CancelOpenOrdersBatch, error) {
params := url.Values{}
params.Set("account-id", accountID)
var result CancelOpenOrdersBatch
data := struct {
AccountID string `json:"account-id"`
Symbol string `json:"symbol"`
}{
AccountID: accountID,
Symbol: symbol,
}
err := h.SendAuthenticatedHTTPRequest("POST", huobiBatchCancelOpenOrders, url.Values{}, data, &result)
if result.Data.FailedCount > 0 {
return result, fmt.Errorf("There were %v failed order cancellations", result.Data.FailedCount)
}
return result, err
}
// GetOrder returns order information for the specified order
func (h *HUOBI) GetOrder(orderID int64) (OrderInfo, error) {
type response struct {
@@ -530,6 +556,29 @@ func (h *HUOBI) GetOrders(symbol, types, start, end, states, from, direct, size
return result.Orders, err
}
// GetOpenOrders returns a list of orders
func (h *HUOBI) GetOpenOrders(accountID, symbol, side string, size int) ([]OrderInfo, error) {
type response struct {
Response
Orders []OrderInfo `json:"data"`
}
vals := url.Values{}
vals.Set("symbol", symbol)
vals.Set("accountID", accountID)
vals.Set("side", side)
vals.Set("size", fmt.Sprintf("%v", size))
var result response
err := h.SendAuthenticatedHTTPRequest("GET", huobiGetOpenOrders, vals, nil, &result)
if result.ErrorMessage != "" {
return nil, errors.New(result.ErrorMessage)
}
return result.Orders, err
}
// GetOrdersMatch returns a list of matched orders
func (h *HUOBI) GetOrdersMatch(symbol, types, start, end, from, direct, size string) ([]OrderMatchInfo, error) {
type response struct {

View File

@@ -410,7 +410,6 @@ func isRealOrderTestEnabled() bool {
func TestSubmitOrder(t *testing.T) {
h.SetDefaults()
TestSetup(t)
h.Verbose = true
if !isRealOrderTestEnabled() {
t.Skip()
@@ -438,7 +437,6 @@ func TestCancelExchangeOrder(t *testing.T) {
t.Skip()
}
h.Verbose = true
currencyPair := pair.NewCurrencyPair(symbol.LTC, symbol.BTC)
var orderCancellation = exchange.OrderCancellation{
@@ -457,6 +455,37 @@ func TestCancelExchangeOrder(t *testing.T) {
}
}
func TestCancelAllExchangeOrders(t *testing.T) {
// Arrange
h.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 := h.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 apiKey == "" || apiSecret == "" {
_, err := h.GetAccountInfo()

View File

@@ -21,6 +21,16 @@ type KlineItem struct {
Count int `json:"count"`
}
// CancelOpenOrdersBatch stores open order batch response data
type CancelOpenOrdersBatch struct {
Data struct {
FailedCount int `json:"failed-count"`
NextID int `json:"next-id"`
SuccessCount int `json:"success-count"`
} `json:"data"`
Status string `json:"status"`
}
// DetailMerged stores the ticker detail merged data
type DetailMerged struct {
Detail

View File

@@ -297,8 +297,22 @@ func (h *HUOBI) CancelOrder(order exchange.OrderCancellation) error {
}
// CancelAllOrders cancels all orders associated with a currency pair
func (h *HUOBI) CancelAllOrders() error {
return common.ErrNotYetImplemented
func (h *HUOBI) CancelAllOrders(orderCancellation exchange.OrderCancellation) (exchange.CancelAllOrdersResponse, error) {
cancelAllOrdersResponse := exchange.CancelAllOrdersResponse{
OrderStatus: make(map[string]string),
}
for _, currency := range h.GetEnabledCurrencies() {
resp, err := h.CancelOpenOrdersBatch(orderCancellation.AccountID, exchange.FormatExchangeCurrency(h.Name, currency).String())
if err != nil {
return cancelAllOrdersResponse, err
}
if resp.Data.FailedCount > 0 {
return cancelAllOrdersResponse, fmt.Errorf("%v orders failed to cancel", resp.Data.FailedCount)
}
}
return cancelAllOrdersResponse, nil
}
// GetOrderInfo returns information on a current open order

View File

@@ -22,32 +22,34 @@ const (
huobihadaxAPIVersion = "1"
huobihadaxAPIName = "hadax"
huobihadaxMarketHistoryKline = "market/history/kline"
huobihadaxMarketDetail = "market/detail"
huobihadaxMarketDetailMerged = "market/detail/merged"
huobihadaxMarketDepth = "market/depth"
huobihadaxMarketTrade = "market/trade"
huobihadaxMarketTradeHistory = "market/history/trade"
huobihadaxSymbols = "common/symbols"
huobihadaxCurrencies = "common/currencys"
huobihadaxTimestamp = "common/timestamp"
huobihadaxAccounts = "account/accounts"
huobihadaxAccountBalance = "account/accounts/%s/balance"
huobihadaxOrderPlace = "order/orders/place"
huobihadaxOrderCancel = "order/orders/%s/submitcancel"
huobihadaxOrderCancelBatch = "order/orders/batchcancel"
huobihadaxGetOrder = "order/orders/%s"
huobihadaxGetOrderMatch = "order/orders/%s/matchresults"
huobihadaxGetOrders = "order/orders"
huobihadaxGetOrdersMatch = "orders/matchresults"
huobihadaxMarginTransferIn = "dw/transfer-in/margin"
huobihadaxMarginTransferOut = "dw/transfer-out/margin"
huobihadaxMarginOrders = "margin/orders"
huobihadaxMarginRepay = "margin/orders/%s/repay"
huobihadaxMarginLoanOrders = "margin/loan-orders"
huobihadaxMarginAccountBalance = "margin/accounts/balance"
huobihadaxWithdrawCreate = "dw/withdraw/api/create"
huobihadaxWithdrawCancel = "dw/withdraw-virtual/%s/cancel"
huobihadaxMarketHistoryKline = "market/history/kline"
huobihadaxMarketDetail = "market/detail"
huobihadaxMarketDetailMerged = "market/detail/merged"
huobihadaxMarketDepth = "market/depth"
huobihadaxMarketTrade = "market/trade"
huobihadaxMarketTradeHistory = "market/history/trade"
huobihadaxSymbols = "common/symbols"
huobihadaxCurrencies = "common/currencys"
huobihadaxTimestamp = "common/timestamp"
huobihadaxAccounts = "account/accounts"
huobihadaxAccountBalance = "account/accounts/%s/balance"
huobihadaxOrderPlace = "order/orders/place"
huobihadaxOrderCancel = "order/orders/%s/submitcancel"
huobihadaxGetOpenOrders = "order/order/openOrders"
huobihadaxOrderCancelBatch = "order/orders/batchcancel"
huobiHadaxBatchCancelOpenOrders = "order/orders/batchCancelOpenOrders"
huobihadaxGetOrder = "order/orders/%s"
huobihadaxGetOrderMatch = "order/orders/%s/matchresults"
huobihadaxGetOrders = "order/orders"
huobihadaxGetOrdersMatch = "orders/matchresults"
huobihadaxMarginTransferIn = "dw/transfer-in/margin"
huobihadaxMarginTransferOut = "dw/transfer-out/margin"
huobihadaxMarginOrders = "margin/orders"
huobihadaxMarginRepay = "margin/orders/%s/repay"
huobihadaxMarginLoanOrders = "margin/loan-orders"
huobihadaxMarginAccountBalance = "margin/accounts/balance"
huobihadaxWithdrawCreate = "dw/withdraw/api/create"
huobihadaxWithdrawCancel = "dw/withdraw-virtual/%s/cancel"
huobihadaxAuthRate = 100
huobihadaxUnauthRate = 100
@@ -443,6 +445,56 @@ func (h *HUOBIHADAX) CancelOrderBatch(orderIDs []int64) (CancelOrderBatch, error
return result.Data, err
}
// CancelOpenOrdersBatch cancels a batch of orders -- to-do
func (h *HUOBIHADAX) CancelOpenOrdersBatch(accountID, symbol string) (CancelOpenOrdersBatch, error) {
params := url.Values{}
params.Set("account-id", accountID)
var result CancelOpenOrdersBatch
data := struct {
AccountID string `json:"account-id"`
Symbol string `json:"symbol"`
}{
AccountID: accountID,
Symbol: symbol,
}
bytesParams, _ := common.JSONEncode(data)
postBodyParams := string(bytesParams)
err := h.SendAuthenticatedHTTPPostRequest("POST", huobiHadaxBatchCancelOpenOrders, postBodyParams, &result)
if result.Data.FailedCount > 0 {
return result, fmt.Errorf("There were %v failed order cancellations", result.Data.FailedCount)
}
return result, err
}
// GetOpenOrders returns a list of orders
func (h *HUOBIHADAX) GetOpenOrders(accountID, symbol, side string, size int) ([]OrderInfo, error) {
type response struct {
Response
Orders []OrderInfo `json:"data"`
}
vals := url.Values{}
vals.Set("symbol", symbol)
vals.Set("accountID", accountID)
vals.Set("side", side)
vals.Set("size", fmt.Sprintf("%v", size))
var result response
err := h.SendAuthenticatedHTTPRequest("GET", huobihadaxGetOpenOrders, vals, &result)
if result.ErrorMessage != "" {
return nil, errors.New(result.ErrorMessage)
}
return result.Orders, err
}
// GetOrder returns order information for the specified order
func (h *HUOBIHADAX) GetOrder(orderID int64) (OrderInfo, error) {
type response struct {

View File

@@ -389,7 +389,6 @@ func isRealOrderTestEnabled() bool {
func TestSubmitOrder(t *testing.T) {
h.SetDefaults()
TestSetup(t)
h.Verbose = true
if !isRealOrderTestEnabled() {
t.Skip()
@@ -417,7 +416,6 @@ func TestCancelExchangeOrder(t *testing.T) {
t.Skip()
}
h.Verbose = true
currencyPair := pair.NewCurrencyPair(symbol.LTC, symbol.BTC)
var orderCancellation = exchange.OrderCancellation{
@@ -436,6 +434,37 @@ func TestCancelExchangeOrder(t *testing.T) {
}
}
func TestCancelAllExchangeOrders(t *testing.T) {
// Arrange
h.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 := h.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 apiKey == "" || apiSecret == "" {
_, err := h.GetAccountInfo()

View File

@@ -46,6 +46,16 @@ type Trade struct {
Timestamp int64 `json:"ts"`
}
// CancelOpenOrdersBatch stores open order batch response data
type CancelOpenOrdersBatch struct {
Data struct {
FailedCount int `json:"failed-count"`
NextID int `json:"next-id"`
SuccessCount int `json:"success-count"`
} `json:"data"`
Status string `json:"status"`
}
// TradeHistory stores the the trade history data
type TradeHistory struct {
ID int64 `json:"id"`

View File

@@ -262,8 +262,22 @@ func (h *HUOBIHADAX) CancelOrder(order exchange.OrderCancellation) error {
}
// CancelAllOrders cancels all orders associated with a currency pair
func (h *HUOBIHADAX) CancelAllOrders() error {
return common.ErrNotYetImplemented
func (h *HUOBIHADAX) CancelAllOrders(orderCancellation exchange.OrderCancellation) (exchange.CancelAllOrdersResponse, error) {
cancelAllOrdersResponse := exchange.CancelAllOrdersResponse{
OrderStatus: make(map[string]string),
}
for _, currency := range h.GetEnabledCurrencies() {
resp, err := h.CancelOpenOrdersBatch(orderCancellation.AccountID, exchange.FormatExchangeCurrency(h.Name, currency).String())
if err != nil {
return cancelAllOrdersResponse, err
}
if resp.Data.FailedCount > 0 {
return cancelAllOrdersResponse, fmt.Errorf("%v orders failed to cancel", resp.Data.FailedCount)
}
}
return cancelAllOrdersResponse, nil
}
// GetOrderInfo returns information on a current open order

View File

@@ -195,6 +195,34 @@ func (i *ItBit) GetWalletBalance(walletID, currency string) (Balance, error) {
return resp, nil
}
// GetOrders returns active orders for itBit
// perPage defaults to & has a limit of 50
func (i *ItBit) GetOrders(walletID, symbol, status string, page, perPage int64) ([]Order, error) {
var resp []Order
params := make(map[string]interface{})
params["walletID"] = walletID
if symbol != "" {
params["instrument"] = symbol
}
if status != "" {
params["status"] = status
}
if page > 0 {
params["page"] = strconv.FormatInt(page, 10)
}
if perPage > 0 {
params["perPage"] = strconv.FormatInt(perPage, 10)
}
err := i.SendAuthenticatedHTTPRequest("GET", itbitOrders, params, &resp)
if err != nil {
return resp, err
}
return resp, nil
}
// GetWalletTrades returns all trades for a specified wallet.
func (i *ItBit) GetWalletTrades(walletID string, params url.Values) (Records, error) {
resp := Records{}

View File

@@ -258,7 +258,6 @@ func isRealOrderTestEnabled() bool {
func TestSubmitOrder(t *testing.T) {
i.SetDefaults()
TestSetup(t)
i.Verbose = true
if !isRealOrderTestEnabled() {
t.Skip()
@@ -284,7 +283,6 @@ func TestCancelExchangeOrder(t *testing.T) {
t.Skip()
}
i.Verbose = true
currencyPair := pair.NewCurrencyPair(symbol.LTC, symbol.BTC)
var orderCancellation = exchange.OrderCancellation{
@@ -303,6 +301,37 @@ func TestCancelExchangeOrder(t *testing.T) {
}
}
func TestCancelAllExchangeOrders(t *testing.T) {
// Arrange
i.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 := i.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 apiKey != "" || apiSecret != "" || clientID != "" {
_, err := i.GetAccountInfo()

View File

@@ -211,8 +211,23 @@ func (i *ItBit) CancelOrder(order exchange.OrderCancellation) error {
}
// CancelAllOrders cancels all orders associated with a currency pair
func (i *ItBit) CancelAllOrders() error {
return common.ErrNotYetImplemented
func (i *ItBit) CancelAllOrders(orderCancellation exchange.OrderCancellation) (exchange.CancelAllOrdersResponse, error) {
cancelAllOrdersResponse := exchange.CancelAllOrdersResponse{
OrderStatus: make(map[string]string),
}
openOrders, err := i.GetOrders(orderCancellation.WalletAddress, "", "open", 0, 0)
if err != nil {
return cancelAllOrdersResponse, err
}
for _, openOrder := range openOrders {
err = i.CancelExistingOrder(orderCancellation.WalletAddress, openOrder.ID)
if err != nil {
cancelAllOrdersResponse.OrderStatus[openOrder.ID] = err.Error()
}
}
return cancelAllOrdersResponse, nil
}
// GetOrderInfo returns information on a current open order

View File

@@ -344,7 +344,6 @@ func isRealOrderTestEnabled() bool {
func TestSubmitOrder(t *testing.T) {
k.SetDefaults()
TestSetup(t)
k.Verbose = true
if !isRealOrderTestEnabled() {
t.Skip()
@@ -370,7 +369,6 @@ func TestCancelExchangeOrder(t *testing.T) {
t.Skip()
}
k.Verbose = true
currencyPair := pair.NewCurrencyPair(symbol.LTC, symbol.BTC)
var orderCancellation = exchange.OrderCancellation{
@@ -389,6 +387,37 @@ func TestCancelExchangeOrder(t *testing.T) {
}
}
func TestCancelAllExchangeOrders(t *testing.T) {
// Arrange
k.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 := k.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 apiKey != "" || apiSecret != "" || clientID != "" {
_, err := k.GetAccountInfo()

View File

@@ -207,8 +207,26 @@ func (k *Kraken) CancelOrder(order exchange.OrderCancellation) error {
}
// CancelAllOrders cancels all orders associated with a currency pair
func (k *Kraken) CancelAllOrders() error {
return common.ErrNotYetImplemented
func (k *Kraken) CancelAllOrders(orderCancellation exchange.OrderCancellation) (exchange.CancelAllOrdersResponse, error) {
cancelAllOrdersResponse := exchange.CancelAllOrdersResponse{
OrderStatus: make(map[string]string),
}
var emptyOrderOptions OrderInfoOptions
openOrders, err := k.GetOpenOrders(emptyOrderOptions)
if err != nil {
return cancelAllOrdersResponse, err
}
if openOrders.Count > 0 {
for orderID := range openOrders.Open {
_, err = k.CancelExistingOrder(orderID)
if err != nil {
cancelAllOrdersResponse.OrderStatus[orderID] = err.Error()
}
}
}
return cancelAllOrdersResponse, nil
}
// GetOrderInfo returns information on a current open order

View File

@@ -278,6 +278,25 @@ func (l *LakeBTC) CancelExistingOrder(orderID int64) error {
return nil
}
// CancelExistingOrders cancels an order by ID number and returns an error
func (l *LakeBTC) CancelExistingOrders(orderIDs []string) error {
type Response struct {
Result bool `json:"Result"`
}
resp := Response{}
params := common.JoinStrings(orderIDs, ",")
err := l.SendAuthenticatedHTTPRequest(lakeBTCCancelOrder, params, &resp)
if err != nil {
return err
}
if resp.Result != true {
return fmt.Errorf("unable to cancel order(s): %v", orderIDs)
}
return nil
}
// GetTrades returns trades associated with your account by timestamp
func (l *LakeBTC) GetTrades(timestamp int64) ([]AuthenticatedTradeHistory, error) {
params := ""

View File

@@ -262,7 +262,6 @@ func isRealOrderTestEnabled() bool {
func TestSubmitOrder(t *testing.T) {
l.SetDefaults()
TestSetup(t)
l.Verbose = true
if !isRealOrderTestEnabled() {
t.Skip()
@@ -288,7 +287,6 @@ func TestCancelExchangeOrder(t *testing.T) {
t.Skip()
}
l.Verbose = true
currencyPair := pair.NewCurrencyPair(symbol.LTC, symbol.BTC)
var orderCancellation = exchange.OrderCancellation{
@@ -306,3 +304,34 @@ func TestCancelExchangeOrder(t *testing.T) {
t.Errorf("Could not cancel order: %s", err)
}
}
func TestCancelAllExchangeOrders(t *testing.T) {
// Arrange
l.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 := l.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))
}
}

View File

@@ -173,8 +173,23 @@ func (l *LakeBTC) CancelOrder(order exchange.OrderCancellation) error {
}
// CancelAllOrders cancels all orders associated with a currency pair
func (l *LakeBTC) CancelAllOrders() error {
return common.ErrNotYetImplemented
func (l *LakeBTC) CancelAllOrders(orderCancellation exchange.OrderCancellation) (exchange.CancelAllOrdersResponse, error) {
cancelAllOrdersResponse := exchange.CancelAllOrdersResponse{
OrderStatus: make(map[string]string),
}
openOrders, err := l.GetOpenOrders()
if err != nil {
return cancelAllOrdersResponse, err
}
var ordersToCancel []string
for _, order := range openOrders {
orderIDString := strconv.FormatInt(order.ID, 10)
ordersToCancel = append(ordersToCancel, orderIDString)
}
return cancelAllOrdersResponse, l.CancelExistingOrders(ordersToCancel)
}
// GetOrderInfo returns information on a current open order

View File

@@ -228,18 +228,12 @@ func (l *Liqui) GetOrderInfoByID(OrderID int64) (map[string]OrderInfo, error) {
}
// CancelExistingOrder method is used for order cancelation.
func (l *Liqui) CancelExistingOrder(OrderID int64) (bool, error) {
func (l *Liqui) CancelExistingOrder(OrderID int64) error {
req := url.Values{}
req.Add("order_id", strconv.FormatInt(OrderID, 10))
var result CancelOrder
err := l.SendAuthenticatedHTTPRequest(liquiCancelOrder, req, &result)
if err != nil {
return false, err
}
return true, nil
return l.SendAuthenticatedHTTPRequest(liquiCancelOrder, req, &result)
}
// GetTradeHistory returns trade history

View File

@@ -99,7 +99,7 @@ func TestAuthRequests(t *testing.T) {
t.Error("Test Failed - liqui GetOrderInfo() error", err)
}
_, err = l.CancelExistingOrder(1337)
err = l.CancelExistingOrder(1337)
if err == nil {
t.Error("Test Failed - liqui CancelExistingOrder() error", err)
}
@@ -247,7 +247,6 @@ func isRealOrderTestEnabled() bool {
func TestSubmitOrder(t *testing.T) {
l.SetDefaults()
TestSetup(t)
l.Verbose = true
if !isRealOrderTestEnabled() {
t.Skip()
@@ -273,7 +272,6 @@ func TestCancelExchangeOrder(t *testing.T) {
t.Skip()
}
l.Verbose = true
currencyPair := pair.NewCurrencyPair(symbol.LTC, symbol.BTC)
var orderCancellation = exchange.OrderCancellation{
@@ -291,3 +289,34 @@ func TestCancelExchangeOrder(t *testing.T) {
t.Errorf("Could not cancel order: %s", err)
}
}
func TestCancelAllExchangeOrders(t *testing.T) {
// Arrange
l.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 := l.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))
}
}

View File

@@ -178,14 +178,33 @@ func (l *Liqui) CancelOrder(order exchange.OrderCancellation) error {
return err
}
_, err = l.CancelExistingOrder(orderIDInt)
return l.CancelExistingOrder(orderIDInt)
return err
}
// CancelAllOrders cancels all orders associated with a currency pair
func (l *Liqui) CancelAllOrders() error {
return common.ErrNotYetImplemented
func (l *Liqui) CancelAllOrders(orderCancellation exchange.OrderCancellation) (exchange.CancelAllOrdersResponse, error) {
cancelAllOrdersResponse := exchange.CancelAllOrdersResponse{
OrderStatus: make(map[string]string),
}
activeOrders, err := l.GetActiveOrders("")
if err != nil {
return cancelAllOrdersResponse, err
}
for activeOrder := range activeOrders {
orderIDInt, err := strconv.ParseInt(activeOrder, 10, 64)
if err != nil {
return cancelAllOrdersResponse, err
}
err = l.CancelExistingOrder(orderIDInt)
if err != nil {
cancelAllOrdersResponse.OrderStatus[activeOrder] = err.Error()
}
}
return cancelAllOrdersResponse, nil
}
// GetOrderInfo returns information on a current open order

View File

@@ -212,7 +212,6 @@ func isRealOrderTestEnabled() bool {
func TestSubmitOrder(t *testing.T) {
l.SetDefaults()
TestSetup(t)
l.Verbose = true
if !isRealOrderTestEnabled() {
t.Skip()
@@ -228,6 +227,7 @@ func TestSubmitOrder(t *testing.T) {
t.Errorf("Order failed to be placed: %v", err)
}
}
func TestCancelExchangeOrder(t *testing.T) {
// Arrange
l.SetDefaults()
@@ -237,7 +237,6 @@ func TestCancelExchangeOrder(t *testing.T) {
t.Skip()
}
l.Verbose = true
currencyPair := pair.NewCurrencyPair(symbol.LTC, symbol.BTC)
var orderCancellation = exchange.OrderCancellation{
@@ -255,3 +254,34 @@ func TestCancelExchangeOrder(t *testing.T) {
t.Errorf("Could not cancel order: %s", err)
}
}
func TestCancelAllExchangeOrders(t *testing.T) {
// Arrange
l.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 := l.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))
}
}

View File

@@ -5,6 +5,7 @@ import (
"fmt"
"log"
"math"
"strconv"
"sync"
"github.com/thrasher-/gocryptotrader/common"
@@ -218,8 +219,24 @@ func (l *LocalBitcoins) CancelOrder(order exchange.OrderCancellation) error {
}
// CancelAllOrders cancels all orders associated with a currency pair
func (l *LocalBitcoins) CancelAllOrders() error {
return common.ErrNotYetImplemented
func (l *LocalBitcoins) CancelAllOrders(orderCancellation exchange.OrderCancellation) (exchange.CancelAllOrdersResponse, error) {
cancelAllOrdersResponse := exchange.CancelAllOrdersResponse{
OrderStatus: make(map[string]string),
}
ads, err := l.Getads()
if err != nil {
return cancelAllOrdersResponse, err
}
for _, ad := range ads.AdList {
adIDString := strconv.FormatInt(ad.Data.AdID, 10)
err = l.DeleteAd(adIDString)
if err != nil {
cancelAllOrdersResponse.OrderStatus[strconv.FormatInt(ad.Data.AdID, 10)] = err.Error()
}
}
return cancelAllOrdersResponse, nil
}
// GetOrderInfo returns information on a current open order

View File

@@ -162,7 +162,6 @@ func isRealOrderTestEnabled() bool {
func TestSubmitOrder(t *testing.T) {
o.SetDefaults()
TestSetup(t)
o.Verbose = true
if !isRealOrderTestEnabled() {
t.Skip()
@@ -188,7 +187,6 @@ func TestCancelExchangeOrder(t *testing.T) {
t.Skip()
}
o.Verbose = true
currencyPair := pair.NewCurrencyPair(symbol.LTC, symbol.BTC)
var orderCancellation = exchange.OrderCancellation{
@@ -206,3 +204,34 @@ func TestCancelExchangeOrder(t *testing.T) {
t.Errorf("Could not cancel order: %s", err)
}
}
func TestCancelAllExchangeOrders(t *testing.T) {
// Arrange
o.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 := o.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))
}
}

View File

@@ -246,8 +246,34 @@ func (o *OKCoin) CancelOrder(order exchange.OrderCancellation) error {
}
// CancelAllOrders cancels all orders associated with a currency pair
func (o *OKCoin) CancelAllOrders() error {
return common.ErrNotYetImplemented
func (o *OKCoin) CancelAllOrders(orderCancellation exchange.OrderCancellation) (exchange.CancelAllOrdersResponse, error) {
cancelAllOrdersResponse := exchange.CancelAllOrdersResponse{
OrderStatus: make(map[string]string),
}
orderInfo, err := o.GetOrderInformation(-1, exchange.FormatExchangeCurrency(o.Name, orderCancellation.CurrencyPair).String())
if err != nil {
return cancelAllOrdersResponse, err
}
var ordersToCancel []int64
for _, order := range orderInfo {
ordersToCancel = append(ordersToCancel, order.OrderID)
}
if len(ordersToCancel) > 0 {
resp, err := o.CancelExistingOrder(ordersToCancel, exchange.FormatExchangeCurrency(o.Name, orderCancellation.CurrencyPair).String())
if err != nil {
return cancelAllOrdersResponse, err
}
for _, order := range common.SplitStrings(resp.Error, ",") {
if err != nil {
cancelAllOrdersResponse.OrderStatus[order] = "Order could not be cancelled"
}
}
}
return cancelAllOrdersResponse, nil
}
// GetOrderInfo returns information on a current open order

View File

@@ -650,6 +650,20 @@ func (o *OKEX) GetContractFuturesTradeHistory(symbol, date string, since int) er
return nil
}
// GetTokenOrders returns details for a single orderID or all open orders when orderID == -1
func (o *OKEX) GetTokenOrders(symbol string, orderID int64) (TokenOrdersResponse, error) {
var resp TokenOrdersResponse
values := url.Values{}
values.Set("symbol", symbol)
values.Set("order_id", strconv.FormatInt(orderID, 10))
if err := o.SendAuthenticatedHTTPRequest(contractFutureTradeHistory, values, &resp); err != nil {
return resp, err
}
return resp, nil
}
// GetUserInfo returns the user info
func (o *OKEX) GetUserInfo() (SpotUserInfo, error) {
var resp SpotUserInfo
@@ -696,8 +710,8 @@ func (o *OKEX) SpotCancelOrder(symbol string, argOrderID int64) (int64, error) {
params := url.Values{}
params.Set("symbol", symbol)
params.Set("order_id", strconv.FormatInt(argOrderID, 10))
var returnOrderID int64
err := o.SendAuthenticatedHTTPRequest(spotCancelTrade+".do", params, &res)
if err != nil {
return returnOrderID, err

View File

@@ -454,6 +454,37 @@ func TestCancelExchangeOrder(t *testing.T) {
}
}
func TestCancelAllExchangeOrders(t *testing.T) {
// Arrange
o.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 := o.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 apiKey != "" || apiSecret != "" {
_, err := o.GetAccountInfo()

View File

@@ -40,6 +40,24 @@ type MultiStreamData struct {
Data json.RawMessage `json:"data"`
}
// TokenOrdersResponse is returned after a request for all Token Orders
type TokenOrdersResponse struct {
Result bool `json:"result"`
Orders []TokenOrder `json:"orders"`
}
// TokenOrder is the individual order details returned from TokenOrderResponse
type TokenOrder struct {
Amount float64 `json:"amount"`
AvgPrice int64 `json:"avg_price"`
DealAmount int64 `json:"deal_amount"`
OrderID int64 `json:"order_id"`
Price int64 `json:"price"`
Status int64 `json:"status"`
Symbol string `json:"symbol"`
Type string `json:"type"`
}
// TickerStreamData contains ticker stream data from okex
type TickerStreamData struct {
Buy string `json:"buy"`

View File

@@ -243,9 +243,36 @@ func (o *OKEX) CancelOrder(order exchange.OrderCancellation) error {
return err
}
// CancelAllOrders cancels all orders associated with a currency pair
func (o *OKEX) CancelAllOrders() error {
return common.ErrNotYetImplemented
// CancelAllOrders cancels all orders for all enabled currencies
func (o *OKEX) CancelAllOrders(orderCancellation exchange.OrderCancellation) (exchange.CancelAllOrdersResponse, error) {
cancelAllOrdersResponse := exchange.CancelAllOrdersResponse{
OrderStatus: make(map[string]string),
}
var allOpenOrders []TokenOrder
for _, currency := range o.GetEnabledCurrencies() {
formattedCurrency := exchange.FormatExchangeCurrency(o.Name, currency).String()
openOrders, err := o.GetTokenOrders(formattedCurrency, -1)
if err != nil {
return cancelAllOrdersResponse, err
}
if !openOrders.Result {
return cancelAllOrdersResponse, fmt.Errorf("Something went wrong for currency %s", formattedCurrency)
}
for _, openOrder := range openOrders.Orders {
allOpenOrders = append(allOpenOrders, openOrder)
}
}
for _, openOrder := range allOpenOrders {
_, err := o.SpotCancelOrder(openOrder.Symbol, openOrder.OrderID)
if err != nil {
cancelAllOrdersResponse.OrderStatus[strconv.FormatInt(openOrder.OrderID, 10)] = err.Error()
}
}
return cancelAllOrdersResponse, nil
}
// GetOrderInfo returns information on a current open order

View File

@@ -425,20 +425,23 @@ func (p *Poloniex) GetDepositsWithdrawals(start, end string) (DepositsWithdrawal
}
// GetOpenOrders returns current unfilled opened orders
func (p *Poloniex) GetOpenOrders(currency string) (interface{}, error) {
func (p *Poloniex) GetOpenOrders(currency string) (OpenOrdersResponse, error) {
values := url.Values{}
if currency != "" {
values.Set("currencyPair", currency)
result := OpenOrdersResponse{}
values.Set("currencyPair", currency)
result := OpenOrdersResponse{}
err := p.SendAuthenticatedHTTPRequest("POST", poloniexOrders, values, &result.Data)
if err != nil {
return result, err
}
return result, nil
err := p.SendAuthenticatedHTTPRequest("POST", poloniexOrders, values, &result.Data)
if err != nil {
return result, err
}
return result, nil
}
// GetOpenOrdersForAllCurrencies returns all open orders
func (p *Poloniex) GetOpenOrdersForAllCurrencies() (OpenOrdersResponseAll, error) {
values := url.Values{}
values.Set("currencyPair", "all")
result := OpenOrdersResponseAll{}

View File

@@ -207,7 +207,6 @@ func isRealOrderTestEnabled() bool {
func TestSubmitOrder(t *testing.T) {
p.SetDefaults()
TestSetup(t)
p.Verbose = true
if !isRealOrderTestEnabled() {
t.Skip()
@@ -233,7 +232,6 @@ func TestCancelExchangeOrder(t *testing.T) {
t.Skip()
}
p.Verbose = true
currencyPair := pair.NewCurrencyPair(symbol.LTC, symbol.BTC)
var orderCancellation = exchange.OrderCancellation{
@@ -251,3 +249,34 @@ func TestCancelExchangeOrder(t *testing.T) {
t.Errorf("Could not cancel order: %s", err)
}
}
func TestCancelAllExchangeOrders(t *testing.T) {
// Arrange
p.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 := p.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))
}
}

View File

@@ -193,8 +193,25 @@ func (p *Poloniex) CancelOrder(order exchange.OrderCancellation) error {
}
// CancelAllOrders cancels all orders associated with a currency pair
func (p *Poloniex) CancelAllOrders() error {
return common.ErrNotYetImplemented
func (p *Poloniex) CancelAllOrders(orderCancellation exchange.OrderCancellation) (exchange.CancelAllOrdersResponse, error) {
cancelAllOrdersResponse := exchange.CancelAllOrdersResponse{
OrderStatus: make(map[string]string),
}
openOrders, err := p.GetOpenOrdersForAllCurrencies()
if err != nil {
return cancelAllOrdersResponse, err
}
for _, openOrderPerCurrency := range openOrders.Data {
for _, openOrder := range openOrderPerCurrency {
_, err = p.CancelExistingOrder(openOrder.OrderNumber)
if err != nil {
cancelAllOrdersResponse.OrderStatus[strconv.FormatInt(openOrder.OrderNumber, 10)] = err.Error()
}
}
}
return cancelAllOrdersResponse, nil
}
// GetOrderInfo returns information on a current open order

View File

@@ -16,7 +16,7 @@ const (
apiKey = ""
apiSecret = ""
canManipulateRealOrders = false
isWexEncounteringIssues = false
isWexEncounteringIssues = true
)
func TestSetDefaults(t *testing.T) {
@@ -340,7 +340,6 @@ func TestSubmitOrder(t *testing.T) {
}
w.SetDefaults()
TestSetup(t)
w.Verbose = true
if !isRealOrderTestEnabled() {
t.Skip()
@@ -369,7 +368,6 @@ func TestCancelExchangeOrder(t *testing.T) {
t.Skip()
}
w.Verbose = true
currencyPair := pair.NewCurrencyPair(symbol.LTC, symbol.BTC)
var orderCancellation = exchange.OrderCancellation{
@@ -387,3 +385,37 @@ func TestCancelExchangeOrder(t *testing.T) {
t.Errorf("Could not cancel order: %s", err)
}
}
func TestCancelAllExchangeOrders(t *testing.T) {
if isWexEncounteringIssues {
t.Skip()
}
// Arrange
w.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 := w.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))
}
}

View File

@@ -183,7 +183,6 @@ func (w *WEX) ModifyOrder(orderID int64, action exchange.ModifyOrder) (int64, er
// CancelOrder cancels an order by its corresponding ID number
func (w *WEX) CancelOrder(order exchange.OrderCancellation) error {
orderIDInt, err := strconv.ParseInt(order.OrderID, 10, 64)
if err != nil {
return err
}
@@ -194,8 +193,36 @@ func (w *WEX) CancelOrder(order exchange.OrderCancellation) error {
}
// CancelAllOrders cancels all orders associated with a currency pair
func (w *WEX) CancelAllOrders() error {
return common.ErrNotYetImplemented
func (w *WEX) CancelAllOrders(orderCancellation exchange.OrderCancellation) (exchange.CancelAllOrdersResponse, error) {
cancelAllOrdersResponse := exchange.CancelAllOrdersResponse{
OrderStatus: make(map[string]string),
}
var allActiveOrders map[string]ActiveOrders
for _, pair := range w.EnabledPairs {
activeOrders, err := w.GetActiveOrders(pair)
if err != nil {
return cancelAllOrdersResponse, err
}
for k, v := range activeOrders {
allActiveOrders[k] = v
}
}
for k := range allActiveOrders {
orderIDInt, err := strconv.ParseInt(k, 10, 64)
if err != nil {
return cancelAllOrdersResponse, err
}
_, err = w.CancelExistingOrder(orderIDInt)
if err != nil {
cancelAllOrdersResponse.OrderStatus[k] = err.Error()
}
}
return cancelAllOrdersResponse, nil
}
// GetOrderInfo returns information on a current open order

View File

@@ -326,7 +326,6 @@ func isRealOrderTestEnabled() bool {
func TestSubmitOrder(t *testing.T) {
y.SetDefaults()
TestSetup(t)
y.Verbose = true
if !isRealOrderTestEnabled() {
t.Skip()
@@ -352,7 +351,6 @@ func TestCancelExchangeOrder(t *testing.T) {
t.Skip()
}
y.Verbose = true
currencyPair := pair.NewCurrencyPair(symbol.LTC, symbol.BTC)
var orderCancellation = exchange.OrderCancellation{
@@ -370,3 +368,34 @@ func TestCancelExchangeOrder(t *testing.T) {
t.Errorf("Could not cancel order: %s", err)
}
}
func TestCancelAllExchangeOrders(t *testing.T) {
// Arrange
y.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 := y.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))
}
}

View File

@@ -165,19 +165,45 @@ func (y *Yobit) ModifyOrder(orderID int64, action exchange.ModifyOrder) (int64,
// CancelOrder cancels an order by its corresponding ID number
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
func (y *Yobit) CancelAllOrders() error {
return common.ErrNotYetImplemented
func (y *Yobit) CancelAllOrders(orderCancellation exchange.OrderCancellation) (exchange.CancelAllOrdersResponse, error) {
cancelAllOrdersResponse := exchange.CancelAllOrdersResponse{
OrderStatus: make(map[string]string),
}
var allActiveOrders []map[string]ActiveOrders
for _, pair := range y.EnabledPairs {
activeOrdersForPair, err := y.GetActiveOrders(pair)
if err != nil {
return cancelAllOrdersResponse, err
}
allActiveOrders = append(allActiveOrders, activeOrdersForPair)
}
for _, activeOrders := range allActiveOrders {
for key := range activeOrders {
orderIDInt, err := strconv.ParseInt(key, 10, 64)
if err != nil {
return cancelAllOrdersResponse, err
}
_, err = y.CancelExistingOrder(orderIDInt)
if err != nil {
cancelAllOrdersResponse.OrderStatus[key] = err.Error()
}
}
}
return cancelAllOrdersResponse, nil
}
// GetOrderInfo returns information on a current open order

View File

@@ -22,14 +22,15 @@ const (
zbMarketURL = "https://trade.zb.com/api"
zbAPIVersion = "v1"
zbAccountInfo = "getAccountInfo"
zbMarkets = "markets"
zbKline = "kline"
zbOrder = "order"
zbCancelOrder = "cancelOrder"
zbTicker = "ticker"
zbTickers = "allTicker"
zbDepth = "depth"
zbAccountInfo = "getAccountInfo"
zbMarkets = "markets"
zbKline = "kline"
zbOrder = "order"
zbCancelOrder = "cancelOrder"
zbTicker = "ticker"
zbTickers = "allTicker"
zbDepth = "depth"
zbUnfinishedOrdersIgnoreTradeType = "getUnfinishedOrdersIgnoreTradeType"
zbAuthRate = 100
zbUnauthRate = 100
@@ -175,6 +176,24 @@ func (z *ZB) GetAccountInformation() (AccountsResponse, error) {
return result, nil
}
// GetUnfinishedOrdersIgnoreTradeType returns unfinished orders
func (z *ZB) GetUnfinishedOrdersIgnoreTradeType(currency, pageindex, pagesize string) ([]UnfinishedOpenOrder, error) {
var result []UnfinishedOpenOrder
vals := url.Values{}
vals.Set("accesskey", z.APIKey)
vals.Set("method", zbUnfinishedOrdersIgnoreTradeType)
vals.Set("currency", currency)
vals.Set("pageIndex", pageindex)
vals.Set("pageSize", pagesize)
err := z.SendAuthenticatedHTTPRequest("GET", zbUnfinishedOrdersIgnoreTradeType, vals, &result)
if err != nil {
return result, err
}
return result, nil
}
// GetMarkets returns market information including pricing, symbols and
// each symbols decimal precision
func (z *ZB) GetMarkets() (map[string]MarketResponseItem, error) {

View File

@@ -244,7 +244,6 @@ func isRealOrderTestEnabled() bool {
func TestSubmitOrder(t *testing.T) {
z.SetDefaults()
TestSetup(t)
z.Verbose = true
if !isRealOrderTestEnabled() {
t.Skip(fmt.Sprintf("ApiKey: %s. Can place orders: %v", z.APIKey, canManipulateRealOrders))
@@ -269,7 +268,6 @@ func TestCancelExchangeOrder(t *testing.T) {
t.Skip()
}
z.Verbose = true
currencyPair := pair.NewCurrencyPair(symbol.LTC, symbol.BTC)
var orderCancellation = exchange.OrderCancellation{
@@ -288,6 +286,37 @@ func TestCancelExchangeOrder(t *testing.T) {
}
}
func TestCancelAllExchangeOrders(t *testing.T) {
// Arrange
z.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 := z.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 apiKey != "" || apiSecret != "" {
_, err := z.GetAccountInfo()

View File

@@ -29,6 +29,19 @@ type AccountsBaseResponse struct {
AuthMobileEnabled bool `json:"auth_mobile_enabled"` //是否开通手机验证
}
// UnfinishedOpenOrder is the order details for retrieving all open orders
type UnfinishedOpenOrder struct {
Currency string `json:"currency"`
ID int64 `json:"id"`
Price int `json:"price"`
Status int `json:"status"`
TotalAmount float64 `json:"total_amount"`
TradeAmount int `json:"trade_amount"`
TradeDate int `json:"trade_date"`
TradeMoney int `json:"trade_money"`
Type int `json:"type"`
}
// AccountsResponse 用户基本信息
type AccountsResponse struct {
Result struct {

View File

@@ -210,8 +210,30 @@ func (z *ZB) CancelOrder(order exchange.OrderCancellation) error {
}
// CancelAllOrders cancels all orders associated with a currency pair
func (z *ZB) CancelAllOrders() error {
return common.ErrNotYetImplemented
func (z *ZB) CancelAllOrders(orderCancellation exchange.OrderCancellation) (exchange.CancelAllOrdersResponse, error) {
cancelAllOrdersResponse := exchange.CancelAllOrdersResponse{
OrderStatus: make(map[string]string),
}
var allOpenOrders []UnfinishedOpenOrder
for _, currency := range z.GetEnabledCurrencies() {
openOrders, err := z.GetUnfinishedOrdersIgnoreTradeType(exchange.FormatExchangeCurrency(z.Name, currency).String(), "1", "10")
if err != nil {
return cancelAllOrdersResponse, err
}
for _, openOrder := range openOrders {
allOpenOrders = append(allOpenOrders, openOrder)
}
}
for _, openOrder := range allOpenOrders {
err := z.CancelExistingOrder(openOrder.ID, openOrder.Currency)
if err != nil {
cancelAllOrdersResponse.OrderStatus[strconv.FormatInt(openOrder.ID, 10)] = err.Error()
}
}
return cancelAllOrdersResponse, nil
}
// GetOrderInfo returns information on a current open order

View File

@@ -1164,7 +1164,7 @@
"proxyAddress": "",
"websocketUrl": "NON_DEFAULT_HTTP_LINK_TO_WEBSOCKET_EXCHANGE_API",
"availablePairs": "DASH_BTC,CTXC_BTC,ZIL_BTC,YOU_BTC,LBA_BTC,LSK_BTC,CAI_BTC,AE_BTC,SC_BTC,KAN_BTC,WIN_BTC,DCR_BTC,WAVES_BTC,ORS_BTC,MVP_BTC,NXT_BTC,ARDR_BTC,XAS_BTC,CVT_BTC,EGT_BTC,ZCO_BTC,LET_BTC,CIT_BTC,HPB_BTC,ADA_BTC,HYC_BTC,VITE_BTC,HIT_BTC,ABL_BTC,PAX_BTC,TUSD_BTC,USDC_BTC,GUSD_BTC,BCHABC_BTC,BCHSV_BTC,XRP_BTC,LRC_BTC,NULS_BTC,MCO_BTC,ELF_BTC,ZEC_BTC,CMT_BTC,ITC_BTC,SBTC_BTC,EDO_BTC,AVT_BTC,BCX_BTC,NEO_BTC,GAS_BTC,HSR_BTC,QTUM_BTC,IOTA_BTC,XUC_BTC,EOS_BTC,STORJ_BTC,SNT_BTC,OMG_BTC,LTC_BTC,ETH_BTC,ETC_BTC,BCD_BTC,BTG_BTC,ACT_BTC,PAY_BTC,BTM_BTC,DGD_BTC,GNT_BTC,LINK_BTC,SALT_BTC,WTC_BTC,SNGLS_BTC,ZRX_BTC,BNT_BTC,CVC_BTC,MANA_BTC,RCN_BTC,TNB_BTC,KNC_BTC,DAT_BTC,GNX_BTC,ICX_BTC,XEM_BTC,ARK_BTC,YOYO_BTC,SUB_BTC,FUN_BTC,ACE_BTC,TRX_BTC,MDA_BTC,MTL_BTC,DGB_BTC,PPT_BTC,ENG_BTC,SWFTC_BTC,XMR_BTC,XLM_BTC,RDN_BTC,KCASH_BTC,MDT_BTC,NAS_BTC,RNT_BTC,UGC_BTC,DPY_BTC,SSC_BTC,AAC_BTC,LEND_BTC,SHOW_BTC,VIB_BTC,QUN_BTC,OST_BTC,INT_BTC,NGC_BTC,IOST_BTC,POE_BTC,INS_BTC,YEE_BTC,MOF_BTC,TCT_BTC,LEV_BTC,SPF_BTC,STC_BTC,THETA_BTC,HOT_BTC,PST_BTC,SNC_BTC,MKR_BTC,KEY_BTC,LIGHT_BTC,TRUE_BTC,OF_BTC,SOC_BTC,DENT_BTC,ZEN_BTC,HMC_BTC,ZIP_BTC,NANO_BTC,CIC_BTC,GTO_BTC,CHAT_BTC,INSUR_BTC,CBT_BTC,R_BTC,BEC_BTC,MITH_BTC,ABT_BTC,BKX_BTC,RFR_BTC,TRIO_BTC,REN_BTC,DADI_BTC,ENJ_BTC,ONT_BTC,OKB_BTC,CTXC_ETH,ZIL_ETH,YOU_ETH,LBA_ETH,LSK_ETH,CAI_ETH,SC_ETH,AE_ETH,KAN_ETH,WIN_ETH,DCR_ETH,WAVES_ETH,ORS_ETH,MVP_ETH,CVT_ETH,EGT_ETH,ZCO_ETH,LET_ETH,CIT_ETH,HPB_ETH,SDA_ETH,ADA_ETH,HYC_ETH,VITE_ETH,HIT_ETH,ABL_ETH,ELF_ETH,LTC_ETH,CMT_ETH,ITC_ETH,PRA_ETH,EDO_ETH,LRC_ETH,NULS_ETH,MCO_ETH,STORJ_ETH,SNT_ETH,PAY_ETH,DGD_ETH,GNT_ETH,ACT_ETH,BTM_ETH,EOS_ETH,OMG_ETH,DASH_ETH,XRP_ETH,ZEC_ETH,NEO_ETH,GAS_ETH,HSR_ETH,QTUM_ETH,IOTA_ETH,XUC_ETH,ETC_ETH,LINK_ETH,SALT_ETH,WTC_ETH,SNGLS_ETH,SNM_ETH,ZRX_ETH,BNT_ETH,CVC_ETH,MANA_ETH,VEE_ETH,TNB_ETH,KNC_ETH,DAT_ETH,GNX_ETH,ICX_ETH,XEM_ETH,ARK_ETH,YOYO_ETH,SUB_ETH,FUN_ETH,TRX_ETH,EVX_ETH,MDA_ETH,MTH_ETH,MTL_ETH,DGB_ETH,PPT_ETH,REQ_ETH,ENG_ETH,SWFTC_ETH,XMR_ETH,XLM_ETH,RDN_ETH,KCASH_ETH,MDT_ETH,NAS_ETH,RNT_ETH,UKG_ETH,UGC_ETH,DPY_ETH,SSC_ETH,AAC_ETH,FAIR_ETH,LEND_ETH,RCT_ETH,SHOW_ETH,VIB_ETH,TOPC_ETH,QUN_ETH,BRD_ETH,OST_ETH,AIDOC_ETH,INT_ETH,LA_ETH,IOST_ETH,POE_ETH,INS_ETH,YEE_ETH,MOF_ETH,TCT_ETH,ATL_ETH,LEV_ETH,REF_ETH,THETA_ETH,CAN_ETH,HOT_ETH,PST_ETH,SNC_ETH,MKR_ETH,KEY_ETH,LIGHT_ETH,TRUE_ETH,OF_ETH,SOC_ETH,DENT_ETH,ZEN_ETH,HMC_ETH,ZIP_ETH,NANO_ETH,CIC_ETH,GTO_ETH,INSUR_ETH,R_ETH,UCT_ETH,BEC_ETH,MITH_ETH,ABT_ETH,BKX_ETH,AUTO_ETH,GSC_ETH,RFR_ETH,TRIO_ETH,TRA_ETH,REN_ETH,DADI_ETH,ENJ_ETH,ONT_ETH,OKB_ETH,CTXC_USDT,ZIL_USDT,YOU_OKB,YOU_USDT,LBA_OKB,LBA_USDT,OK06ETT_USDT,CAI_OKB,LSK_USDT,CAI_USDT,AE_OKB,SC_OKB,KAN_OKB,WIN_OKB,SC_USDT,AE_USDT,KAN_USDT,WIN_USDT,ORS_OKB,MVP_OKB,DCR_OKB,DCR_USDT,WAVES_OKB,WAVES_USDT,ORS_USDT,MVP_USDT,NAS_OKB,XAS_OKB,CVT_OKB,ZCO_OKB,EGT_OKB,XAS_USDT,CVT_USDT,EGT_USDT,LET_OKB,LET_USDT,CIT_OKB,HPB_OKB,HPB_USDT,SDA_OKB,ADA_OKB,ADA_USDT,HYC_USDT,VITE_OKB,TRX_OKB,PAX_USDT,TUSD_USDT,USDC_USDT,GUSD_USDT,BCHABC_USDT,BCHSV_USDT,ELF_USDT,DASH_USDT,LRC_USDT,NULS_USDT,MCO_USDT,BTG_USDT,DASH_OKB,XRP_USDT,ZEC_USDT,NEO_USDT,GAS_USDT,HSR_USDT,QTUM_USDT,IOTA_USDT,BTC_USDT,BCD_USDT,XUC_USDT,CMT_USDT,ITC_USDT,PRA_USDT,SAN_USDT,EDO_USDT,ETH_USDT,LTC_USDT,ETC_USDT,EOS_USDT,OMG_USDT,ACT_USDT,BTM_USDT,STORJ_USDT,PAY_USDT,DGD_USDT,GNT_USDT,SNT_USDT,LINK_USDT,SALT_USDT,1ST_USDT,WTC_USDT,SNGLS_USDT,ZRX_USDT,BNT_USDT,CVC_USDT,MANA_USDT,TNB_USDT,AMM_USDT,KNC_USDT,DAT_USDT,GNX_USDT,ICX_USDT,XEM_USDT,ARK_USDT,YOYO_USDT,QVT_USDT,AST_USDT,DNT_USDT,FUN_USDT,ACE_USDT,TRX_USDT,EVX_USDT,MDA_USDT,DGB_USDT,PPT_USDT,OAX_USDT,REQ_USDT,ENG_USDT,ICN_USDT,RCN_USDT,SWFTC_USDT,XMR_USDT,XLM_USDT,RDN_USDT,KCASH_USDT,MDT_USDT,NAS_USDT,RNT_USDT,WRC_USDT,UGC_USDT,DPY_USDT,SSC_USDT,AAC_USDT,FAIR_USDT,UBTC_USDT,CAG_USDT,DNA_USDT,LEND_USDT,SHOW_USDT,VIB_USDT,MOT_USDT,UTK_USDT,MAG_USDT,TOPC_USDT,QUN_USDT,OST_USDT,AIDOC_USDT,INT_USDT,IPC_USDT,IOST_USDT,POE_USDT,INS_USDT,YEE_USDT,MOF_USDT,TCT_USDT,LEV_USDT,SPF_USDT,STC_USDT,THETA_USDT,CAN_USDT,HOT_USDT,PST_USDT,SNC_USDT,MKR_USDT,KEY_USDT,LIGHT_USDT,TRUE_USDT,OF_USDT,SOC_USDT,DENT_USDT,ZEN_USDT,HMC_USDT,ZIP_USDT,NANO_USDT,CIC_USDT,GTO_USDT,CHAT_USDT,INSUR_USDT,R_USDT,UCT_USDT,BEC_USDT,MITH_USDT,ABT_USDT,BKX_USDT,GSC_USDT,RFR_USDT,TRIO_USDT,TRA_USDT,REN_USDT,DADI_USDT,ENJ_USDT,ONT_USDT,OKB_USDT,NEO_OKB,LTC_OKB,ETC_OKB,XRP_OKB,ZEC_OKB,QTUM_OKB,IOTA_OKB,EOS_OKB",
"enabledPairs": "tct_eth",
"enabledPairs": "ltc_btc",
"baseCurrencies": "USD",
"assetTypes": "SPOT",
"supportsAutoPairUpdates": true,

View File

@@ -137,7 +137,7 @@ func ({{.Variable}} *{{.CapitalName}}) CancelOrder(order exchange.OrderCancellat
}
// CancelAllOrders cancels all orders associated with a currency pair
func ({{.Variable}} *{{.CapitalName}}) CancelAllOrders() error {
func ({{.Variable}} *{{.CapitalName}}) CancelAllOrders(orderCancellation exchange.OrderCancellation) (exchange.CancelAllOrdersResponse, error) {
return common.ErrNotYetImplemented
}