mirror of
https://github.com/d0zingcat/gocryptotrader.git
synced 2026-05-13 23:16:45 +00:00
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:
@@ -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(
|
||||
|
||||
@@ -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))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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"`
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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 != "" {
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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"`
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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¤cyPair=%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 {
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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{
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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{}
|
||||
|
||||
@@ -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))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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"`
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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{}
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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 := ""
|
||||
|
||||
@@ -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))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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"`
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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{}
|
||||
|
||||
|
||||
@@ -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))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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
|
||||
|
||||
2
testdata/configtest.json
vendored
2
testdata/configtest.json
vendored
@@ -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,
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user