GetActiveOrders/GetOrderHistory wrapper implementation (#239)

* Adds signature to all exchange wrappers

* Adds funky new OrderHistoryRequest type. Updates signature for GetOrderHistory to use funky new type. Adds tests for GetOrderHistory on all exchanges. Implements GetOrderHistory for ANX

* Fixes alphapoint, bitstamp, itbit, zb tests. Adds exchange functions FilterOrdersByStatusAndType, FilterOrdersByTickRange, FilterOrdersByCurrencies to easily filter returned orders. Adds tests for filters. Implements GetOrderHistory wrapper for Binance, bitfinex, bithumb, bitmex. Adds new filter funcs to implementations.

* Adds bitstamp wrapper support

* Splits up GetOrderHistory into GetOpenOrders and GetOrderHistory wraapper functions to distinguish between active and past. Renames exchange.GetOrderHistoryRequest to exchange.GetOrdersRequest. Renames any API exchange method named GetOpenOrders to GetActiveOrders. Adds test function TestGetOpenOrders for each exchange

* Reimplements the split GetOrders and GetOrderHistory for alphapoint, anx, binance, bitfinex, bithumb, bitmex, bitstamp and bittrex. Renames orderType, orderStatus constants. Adds new exchange.FilterOrdersBySide and exchange.FilterOrdersByType and removes old exchange.FilterOrdersByStatusAndType.

* Changes orderHistoryRequest to use currencypair array instead of strings, also adds fees and trade breakdown. Removes if statement preventing ANX/BTCMarkets testing. Implements Active order + Order history retrieval for Bittrex and BTCMarkets.

* Adds support for coinut and coinbasepro

* Adds Exmo support

* Adds GateIO support

* Adds Gemini support

* Adds hitbtc, huobi, hadax,  itbit, kraken support for open orders & order history. Fixes switch case break and fallthroughs. Adds filtering to gateio and gemini results

* Adds support for LakeBTC, Liqui, Localbitcoin, OKCoin, OKEX

* Adds poloniex support

* Adds Wex support

* Adds Yobit support. Updates Wex support

* Adds ZB support. Removes ArrangeActAssert from tests

* Changes baseCurrency + quoteCurrency exchange.OrderDetail properties to a pair.CurrencyPair. Adds exchange name to all implementations. Fixes EXMO TestSetup

* Removes verbose setting from tests as verbosity increases the amount of noise return when testing. Noise is only helpful when debugging tests to get more helpful information to resolve the issue and so it is unnecessary to have such lengthy output when testing in bulk or via Travis CI. This commit therefore improves readability when there are no issues

* Fixes issue where gemini test sandbox api url was overridden. Handles blank response from Gemini

* Fixes verbose typo

* Removes spacing for old act assert test comments. Limits previous infinite loop to 10

* Fixes issue with filtering where orderside is never specified

* Uses proper capitalisation for ServerOrderID and OpenOrders. Reverts commenting out orde_id param for bithumb.GetOrderDetails. Removes unnecessary int logic

* Removes JSON ID fields. Uses map where appropriate for exchange order side/type. Updates OrderDetail/GetOrdersRequest type to use time fields. Remvoes comments. Removes inappropriate variable name. Adds AccountID field for alphapoint. Fixes log message formatting. Lowers errorfs to warnfs for time conversion

* Adds missed files

* Removes blank line

* Adds sorting options for orders. Adds concurrency warnings in comments. Adds test for NewCurrencyPairWithDelimiter. Removes (e *Base) from filter funcs. Updates references to filter funcs

* Fixes rebase issues. Condenses append loops.

* Fixes more receive typos. Removes some inline strings. Adds AskOrderSide and BidOrderSide. Removes hypothetical infinite loop

* Fixes issue where allTrades wasn't used in loop. Fixes assignment/typing issues

* Fixes formatting
This commit is contained in:
Scott
2019-02-05 10:44:05 +11:00
committed by Adrian Gallagher
parent 82a622294c
commit 978b91a692
105 changed files with 4797 additions and 765 deletions

View File

@@ -71,7 +71,6 @@ func TestBuildURL(t *testing.T) {
}
func TestGetChannelsString(t *testing.T) {
s.Details.Channels = append(s.Details.Channels, struct {
Created int `json:"created"`
Creator string `json:"creator"`
@@ -315,7 +314,6 @@ func TestHandleHelloResponse(t *testing.T) {
}
func TestHandleReconnectResponse(t *testing.T) {
err := s.handleReconnectResponse([]byte(`{"malformedjson}`))
if err == nil {
t.Error("test failed - slack handleReconnectResponse(), unmarshalled malformed json")

View File

@@ -108,6 +108,15 @@ func NewCurrencyPair(firstCurrency, secondCurrency string) CurrencyPair {
}
}
// NewCurrencyPairWithDelimiter returns a CurrencyPair with a delimiter
func NewCurrencyPairWithDelimiter(firstCurrency, secondCurrency, delimiter string) CurrencyPair {
return CurrencyPair{
FirstCurrency: CurrencyItem(firstCurrency),
SecondCurrency: CurrencyItem(secondCurrency),
Delimiter: delimiter,
}
}
// NewCurrencyPairFromIndex returns a CurrencyPair via a currency string and
// specific index
func NewCurrencyPairFromIndex(currency, index string) CurrencyPair {

View File

@@ -180,6 +180,29 @@ func TestNewCurrencyPair(t *testing.T) {
}
}
func TestNewCurrencyPairWithDelimiter(t *testing.T) {
t.Parallel()
pair := NewCurrencyPairWithDelimiter("BTC", "USD", "-test-")
actual := pair.Pair()
expected := CurrencyItem("BTC-test-USD")
if actual != expected {
t.Errorf(
"Test failed. Pair(): %s was not equal to expected value: %s",
actual, expected,
)
}
pair = NewCurrencyPairWithDelimiter("BTC", "USD", "")
actual = pair.Pair()
expected = CurrencyItem("BTCUSD")
if actual != expected {
t.Errorf(
"Test failed. Pair(): %s was not equal to expected value: %s",
actual, expected,
)
}
}
func TestNewCurrencyPairDelimiter(t *testing.T) {
t.Parallel()
pair := NewCurrencyPairDelimiter("BTC-USD", "-")

View File

@@ -361,7 +361,7 @@ func (a *Alphapoint) WithdrawCoins(symbol, product, address string, amount float
}
func (a *Alphapoint) convertOrderTypeToOrderTypeNumber(orderType string) (orderTypeNumber int64) {
if orderType == exchange.Market.ToString() {
if orderType == exchange.MarketOrderType.ToString() {
orderTypeNumber = 1
}

View File

@@ -413,7 +413,7 @@ func TestCreateOrder(t *testing.T) {
return
}
_, err := a.CreateOrder("", "", exchange.Market.ToString(), 0.01, 0)
_, err := a.CreateOrder("", "", exchange.MarketOrderType.ToString(), 0.01, 0)
if err == nil {
t.Error("Test Failed - GetUserInfo() error")
}
@@ -480,18 +480,49 @@ func TestGetOrderFee(t *testing.T) {
}
func TestFormatWithdrawPermissions(t *testing.T) {
// Arrange
a := &Alphapoint{}
a.SetDefaults()
expectedResult := exchange.AutoWithdrawCryptoWithAPIPermissionText + " & " + exchange.WithdrawCryptoWith2FAText + " & " + exchange.NoFiatWithdrawalsText
// Act
withdrawPermissions := a.FormatWithdrawPermissions()
// Assert
if withdrawPermissions != expectedResult {
t.Errorf("Expected: %s, Received: %s", expectedResult, withdrawPermissions)
}
}
func TestGetActiveOrders(t *testing.T) {
a := &Alphapoint{}
a.SetDefaults()
var getOrdersRequest = exchange.GetOrdersRequest{
OrderType: exchange.AnyOrderType,
}
_, err := a.GetActiveOrders(getOrdersRequest)
if areTestAPIKeysSet(a) && err != nil {
t.Errorf("Could not get open orders: %s", err)
} else if !areTestAPIKeysSet(a) && err == nil {
t.Error("Expecting an error when no keys are set")
}
}
func TestGetOrderHistory(t *testing.T) {
a := &Alphapoint{}
a.SetDefaults()
var getOrdersRequest = exchange.GetOrdersRequest{
OrderType: exchange.AnyOrderType,
}
_, err := a.GetOrderHistory(getOrdersRequest)
if areTestAPIKeysSet(a) && err != nil {
t.Errorf("Could not get order history: %s", err)
} else if !areTestAPIKeysSet(a) && err == nil {
t.Error("Expecting an error when no keys are set")
}
}
// Any tests below this line have the ability to impact your orders on the exchange. Enable canManipulateRealOrders to run them
// ----------------------------------------------------------------------------------------------------------------------------
@@ -515,9 +546,9 @@ func TestSubmitOrder(t *testing.T) {
FirstCurrency: symbol.BTC,
SecondCurrency: symbol.USD,
}
response, err := a.SubmitOrder(p, exchange.Buy, exchange.Market, 1, 1, "clientId")
response, err := a.SubmitOrder(p, exchange.BuyOrderSide, exchange.MarketOrderType, 1, 1, "clientId")
if !areTestAPIKeysSet(a) && err == nil {
t.Errorf("Expecting an error when no keys are set: %v", err)
t.Error("Expecting an error when no keys are set")
}
if areTestAPIKeysSet(a) && err != nil {
t.Errorf("Withdraw failed to be placed: %v", err)
@@ -529,7 +560,6 @@ func TestSubmitOrder(t *testing.T) {
}
func TestCancelExchangeOrder(t *testing.T) {
// Arrange
a := &Alphapoint{}
a.SetDefaults()
@@ -545,12 +575,10 @@ func TestCancelExchangeOrder(t *testing.T) {
AccountID: "1",
CurrencyPair: currencyPair,
}
// Act
err := a.CancelOrder(orderCancellation)
// Assert
err := a.CancelOrder(orderCancellation)
if !areTestAPIKeysSet(a) && err == nil {
t.Errorf("Expecting an error when no keys are set: %v", err)
t.Error("Expecting an error when no keys are set")
}
if areTestAPIKeysSet(a) && err != nil {
t.Errorf("Withdraw failed to be placed: %v", err)
@@ -558,7 +586,6 @@ func TestCancelExchangeOrder(t *testing.T) {
}
func TestCancelAllExchangeOrders(t *testing.T) {
// Arrange
a := &Alphapoint{}
a.SetDefaults()
@@ -574,12 +601,11 @@ func TestCancelAllExchangeOrders(t *testing.T) {
AccountID: "1",
CurrencyPair: currencyPair,
}
// Act
resp, err := a.CancelAllOrders(orderCancellation)
// Assert
if !areTestAPIKeysSet(a) && err == nil {
t.Errorf("Expecting an error when no keys are set: %v", err)
t.Error("Expecting an error when no keys are set")
}
if areTestAPIKeysSet(a) && err != nil {
t.Errorf("Withdraw failed to be placed: %v", err)

View File

@@ -1,5 +1,7 @@
package alphapoint
import exchange "github.com/thrasher-/gocryptotrader/exchanges"
// Response contains general responses from the exchange
type Response struct {
IsAccepted bool `json:"isAccepted"`
@@ -144,19 +146,21 @@ type AccountInfo struct {
// Order is a generalised order type
type Order struct {
Serverorderid int `json:"ServerOrderId"`
AccountID int `json:"AccountId"`
Price int `json:"Price"`
QtyTotal int `json:"QtyTotal"`
QtyRemaining int `json:"QtyRemaining"`
ReceiveTime int64 `json:"ReceiveTime"`
Side int `json:"Side"`
ServerOrderID int `json:"ServerOrderId"`
AccountID int `json:"AccountId"`
Price float64 `json:"Price"`
QtyTotal float64 `json:"QtyTotal"`
QtyRemaining float64 `json:"QtyRemaining"`
ReceiveTime int64 `json:"ReceiveTime"`
Side int64 `json:"Side"`
State int `json:"orderState"`
OrderType int `json:"orderType"`
}
// OpenOrders holds the full range of orders by instrument
type OpenOrders struct {
Instrument string `json:"ins"`
Openorders []Order `json:"openOrders"`
OpenOrders []Order `json:"openOrders"`
}
// OrderInfo holds all open orders across the entire range of all instruments
@@ -192,3 +196,17 @@ type WebsocketTicker struct {
BuyOrderCount int `json:"buyOrderCount"`
SellOrderCount int `json:"sellOrderCount"`
}
// orderSideMap holds order type info based on Alphapoint data
var orderSideMap = map[int64]exchange.OrderSide{
1: exchange.BuyOrderSide,
2: exchange.SellOrderSide,
}
// orderTypeMap holds order type info based on Alphapoint data
var orderTypeMap = map[int]exchange.OrderType{
1: exchange.MarketOrderType,
2: exchange.LimitOrderType,
3: exchange.StopOrderType,
6: exchange.TrailingStopOrderType,
}

View File

@@ -4,6 +4,7 @@ import (
"errors"
"fmt"
"strconv"
"time"
"github.com/thrasher-/gocryptotrader/common"
"github.com/thrasher-/gocryptotrader/currency/pair"
@@ -161,9 +162,9 @@ func (a *Alphapoint) GetOrderInfo(orderID int64) (float64, error) {
}
for x := range orders {
for y := range orders[x].Openorders {
if int64(orders[x].Openorders[y].Serverorderid) == orderID {
return float64(orders[x].Openorders[y].QtyRemaining), nil
for y := range orders[x].OpenOrders {
if int64(orders[x].OpenOrders[y].ServerOrderID) == orderID {
return float64(orders[x].OpenOrders[y].QtyRemaining), nil
}
}
}
@@ -216,3 +217,88 @@ func (a *Alphapoint) GetFeeByType(feeBuilder exchange.FeeBuilder) (float64, erro
func (a *Alphapoint) GetWithdrawCapabilities() uint32 {
return a.GetWithdrawPermissions()
}
// GetActiveOrders retrieves any orders that are active/open
// This function is not concurrency safe due to orderSide/orderType maps
func (a *Alphapoint) GetActiveOrders(getOrdersRequest exchange.GetOrdersRequest) ([]exchange.OrderDetail, error) {
resp, err := a.GetOrders()
if err != nil {
return nil, err
}
var orders []exchange.OrderDetail
for x := range resp {
for _, order := range resp[x].OpenOrders {
if order.State != 1 {
continue
}
orderDetail := exchange.OrderDetail{
Amount: float64(order.QtyTotal),
Exchange: a.Name,
AccountID: fmt.Sprintf("%v", order.AccountID),
ID: fmt.Sprintf("%v", order.ServerOrderID),
Price: float64(order.Price),
RemainingAmount: float64(order.QtyRemaining),
}
orderDetail.OrderSide = orderSideMap[order.Side]
orderDetail.OrderDate = time.Unix(order.ReceiveTime, 0)
orderDetail.OrderType = orderTypeMap[order.OrderType]
if orderDetail.OrderType == "" {
orderDetail.OrderType = exchange.UnknownOrderType
}
orders = append(orders, orderDetail)
}
}
exchange.FilterOrdersByType(&orders, getOrdersRequest.OrderType)
exchange.FilterOrdersBySide(&orders, getOrdersRequest.OrderSide)
exchange.FilterOrdersByTickRange(&orders, getOrdersRequest.StartTicks, getOrdersRequest.EndTicks)
return orders, nil
}
// GetOrderHistory retrieves account order information
// Can Limit response to specific order status
// This function is not concurrency safe due to orderSide/orderType maps
func (a *Alphapoint) GetOrderHistory(getOrdersRequest exchange.GetOrdersRequest) ([]exchange.OrderDetail, error) {
resp, err := a.GetOrders()
if err != nil {
return nil, err
}
var orders []exchange.OrderDetail
for x := range resp {
for _, order := range resp[x].OpenOrders {
if order.State == 1 {
continue
}
orderDetail := exchange.OrderDetail{
Amount: float64(order.QtyTotal),
AccountID: fmt.Sprintf("%v", order.AccountID),
Exchange: a.Name,
ID: fmt.Sprintf("%v", order.ServerOrderID),
Price: float64(order.Price),
RemainingAmount: float64(order.QtyRemaining),
}
orderDetail.OrderSide = orderSideMap[order.Side]
orderDetail.OrderDate = time.Unix(order.ReceiveTime, 0)
orderDetail.OrderType = orderTypeMap[order.OrderType]
if orderDetail.OrderType == "" {
orderDetail.OrderType = exchange.UnknownOrderType
}
orders = append(orders, orderDetail)
}
}
exchange.FilterOrdersByType(&orders, getOrdersRequest.OrderType)
exchange.FilterOrdersBySide(&orders, getOrdersRequest.OrderSide)
exchange.FilterOrdersByTickRange(&orders, getOrdersRequest.StartTicks, getOrdersRequest.EndTicks)
return orders, nil
}

View File

@@ -55,11 +55,9 @@ func TestSetup(t *testing.T) {
t.Error("Test Failed - ANX Setup() init error")
}
a.Setup(anxConfig)
if testAPIKey != "" && testAPISecret != "" {
a.APIKey = testAPIKey
a.APISecret = testAPISecret
a.AuthenticatedAPISupport = true
}
a.APIKey = testAPIKey
a.APISecret = testAPISecret
a.AuthenticatedAPISupport = true
if a.Enabled != true {
t.Error("Test Failed - ANX Setup() incorrect values set")
@@ -216,18 +214,49 @@ func TestGetFee(t *testing.T) {
}
func TestFormatWithdrawPermissions(t *testing.T) {
// Arrange
a.SetDefaults()
expectedResult := exchange.AutoWithdrawCryptoWithSetupText + " & " + exchange.WithdrawCryptoWith2FAText + " & " +
exchange.WithdrawCryptoWithEmailText + " & " + exchange.WithdrawFiatViaWebsiteOnlyText
// Act
withdrawPermissions := a.FormatWithdrawPermissions()
// Assert
if withdrawPermissions != expectedResult {
t.Errorf("Expected: %s, Received: %s", expectedResult, withdrawPermissions)
}
}
func TestGetActiveOrders(t *testing.T) {
a.SetDefaults()
TestSetup(t)
var getOrdersRequest = exchange.GetOrdersRequest{
OrderType: exchange.AnyOrderType,
}
_, err := a.GetActiveOrders(getOrdersRequest)
if areTestAPIKeysSet() && err != nil {
t.Errorf("Could not get open orders: %s", err)
} else if !areTestAPIKeysSet() && err == nil {
t.Error("Expecting an error when no keys are set")
}
}
func TestGetOrderHistory(t *testing.T) {
a.SetDefaults()
TestSetup(t)
var getOrdersRequest = exchange.GetOrdersRequest{
OrderType: exchange.AnyOrderType,
}
_, err := a.GetOrderHistory(getOrdersRequest)
if areTestAPIKeysSet() && err != nil {
t.Errorf("Could not get order history: %s", err)
} else if !areTestAPIKeysSet() && err == nil {
t.Error("Expecting an error when no keys are set")
}
}
// Any tests below this line have the ability to impact your orders on the exchange. Enable canManipulateRealOrders to run them
// ----------------------------------------------------------------------------------------------------------------------------
@@ -251,7 +280,7 @@ func TestSubmitOrder(t *testing.T) {
FirstCurrency: symbol.BTC,
SecondCurrency: symbol.USD,
}
response, err := a.SubmitOrder(p, exchange.Buy, exchange.Market, 1, 1, "clientId")
response, err := a.SubmitOrder(p, exchange.BuyOrderSide, exchange.MarketOrderType, 1, 1, "clientId")
if areTestAPIKeysSet() && (err != nil || !response.IsOrderPlaced) {
t.Errorf("Order failed to be placed: %v", err)
} else if !areTestAPIKeysSet() && err == nil {
@@ -260,7 +289,6 @@ func TestSubmitOrder(t *testing.T) {
}
func TestCancelExchangeOrder(t *testing.T) {
// Arrange
a.SetDefaults()
TestSetup(t)
@@ -276,19 +304,16 @@ func TestCancelExchangeOrder(t *testing.T) {
AccountID: "1",
CurrencyPair: currencyPair,
}
// Act
err := a.CancelOrder(orderCancellation)
// Assert
err := a.CancelOrder(orderCancellation)
if areTestAPIKeysSet() && err != nil {
t.Errorf("Could not cancel order: %s", err)
} else if !areTestAPIKeysSet() && err == nil {
t.Errorf("Expecting an error when no keys are set: %v", err)
t.Error("Expecting an error when no keys are set")
}
}
func TestCancelAllExchangeOrders(t *testing.T) {
// Arrange
a.SetDefaults()
TestSetup(t)
@@ -304,14 +329,13 @@ func TestCancelAllExchangeOrders(t *testing.T) {
AccountID: "1",
CurrencyPair: currencyPair,
}
// Act
resp, err := a.CancelAllOrders(orderCancellation)
// Assert
if areTestAPIKeysSet() && err != nil {
t.Errorf("Could not cancel order: %s", err)
} else if !areTestAPIKeysSet() && err == nil {
t.Errorf("Expecting an error when no keys are set: %v", err)
t.Error("Expecting an error when no keys are set")
}
if len(resp.OrderStatus) > 0 {

View File

@@ -119,20 +119,20 @@ type Order struct {
// OrderResponse holds order response data
type OrderResponse struct {
BuyTradedCurrency bool `json:"buyTradedCurrency"`
ExecutedAverageRate string `json:"executedAverageRate"`
LimitPriceInSettlementCurrency string `json:"limitPriceInSettlementCurrency"`
OrderID string `json:"orderId"`
OrderStatus string `json:"orderStatus"`
OrderType string `json:"orderType"`
ReplaceExistingOrderUUID string `json:"replaceExistingOrderId"`
SettlementCurrency string `json:"settlementCurrency"`
SettlementCurrencyAmount string `json:"settlementCurrencyAmount"`
SettlementCurrencyOutstanding string `json:"settlementCurrencyOutstanding"`
Timestamp int64 `json:"timestamp"`
TradedCurrency string `json:"tradedCurrency"`
TradedCurrencyAmount string `json:"tradedCurrencyAmount"`
TradedCurrencyOutstanding string `json:"tradedCurrencyOutstanding"`
BuyTradedCurrency bool `json:"buyTradedCurrency"`
ExecutedAverageRate string `json:"executedAverageRate"`
LimitPriceInSettlementCurrency string `json:"limitPriceInSettlementCurrency"`
OrderID string `json:"orderId"`
OrderStatus string `json:"orderStatus"`
OrderType string `json:"orderType"`
ReplaceExistingOrderUUID string `json:"replaceExistingOrderId"`
SettlementCurrency string `json:"settlementCurrency"`
SettlementCurrencyAmount float64 `json:"settlementCurrencyAmount,string"`
SettlementCurrencyOutstanding string `json:"settlementCurrencyOutstanding"`
Timestamp int64 `json:"timestamp"`
TradedCurrency string `json:"tradedCurrency"`
TradedCurrencyAmount float64 `json:"tradedCurrencyAmount,string"`
TradedCurrencyOutstanding string `json:"tradedCurrencyOutstanding"`
}
// OrderCancelResponse returned when cancelling multiple orders

View File

@@ -3,7 +3,9 @@ package anx
import (
"fmt"
"strconv"
"strings"
"sync"
"time"
"github.com/thrasher-/gocryptotrader/common"
"github.com/thrasher-/gocryptotrader/currency/pair"
@@ -228,11 +230,11 @@ func (a *ANX) SubmitOrder(p pair.CurrencyPair, side exchange.OrderSide, orderTyp
var isBuying bool
var limitPriceInSettlementCurrency float64
if side == exchange.Buy {
if side == exchange.BuyOrderSide {
isBuying = true
}
if orderType == exchange.Limit {
if orderType == exchange.LimitOrderType {
limitPriceInSettlementCurrency = price
}
@@ -345,3 +347,70 @@ func (a *ANX) GetFeeByType(feeBuilder exchange.FeeBuilder) (float64, error) {
func (a *ANX) GetWithdrawCapabilities() uint32 {
return a.GetWithdrawPermissions()
}
// GetActiveOrders retrieves any orders that are active/open
func (a *ANX) GetActiveOrders(getOrdersRequest exchange.GetOrdersRequest) ([]exchange.OrderDetail, error) {
resp, err := a.GetOrderList(true)
if err != nil {
return nil, err
}
var orders []exchange.OrderDetail
for _, order := range resp {
orderDate := time.Unix(order.Timestamp, 0)
orderType := exchange.OrderType(strings.ToUpper(order.OrderType))
orderDetail := exchange.OrderDetail{
Amount: order.TradedCurrencyAmount,
CurrencyPair: pair.NewCurrencyPairWithDelimiter(order.TradedCurrency, order.SettlementCurrency, a.ConfigCurrencyPairFormat.Delimiter),
OrderDate: orderDate,
Exchange: a.Name,
ID: order.OrderID,
OrderType: orderType,
Price: order.SettlementCurrencyAmount,
Status: order.OrderStatus,
}
orders = append(orders, orderDetail)
}
exchange.FilterOrdersByType(&orders, getOrdersRequest.OrderType)
exchange.FilterOrdersByTickRange(&orders, getOrdersRequest.StartTicks, getOrdersRequest.EndTicks)
exchange.FilterOrdersByCurrencies(&orders, getOrdersRequest.Currencies)
return orders, nil
}
// GetOrderHistory retrieves account order information
// Can Limit response to specific order status
func (a *ANX) GetOrderHistory(getOrdersRequest exchange.GetOrdersRequest) ([]exchange.OrderDetail, error) {
resp, err := a.GetOrderList(false)
if err != nil {
return nil, err
}
var orders []exchange.OrderDetail
for _, order := range resp {
orderDate := time.Unix(order.Timestamp, 0)
orderType := exchange.OrderType(strings.ToUpper(order.OrderType))
orderDetail := exchange.OrderDetail{
Amount: order.TradedCurrencyAmount,
OrderDate: orderDate,
Exchange: a.Name,
ID: order.OrderID,
OrderType: orderType,
Price: order.SettlementCurrencyAmount,
Status: order.OrderStatus,
CurrencyPair: pair.NewCurrencyPairWithDelimiter(order.TradedCurrency, order.SettlementCurrency, a.ConfigCurrencyPairFormat.Delimiter),
}
orders = append(orders, orderDetail)
}
exchange.FilterOrdersByType(&orders, getOrdersRequest.OrderType)
exchange.FilterOrdersByTickRange(&orders, getOrdersRequest.StartTicks, getOrdersRequest.EndTicks)
exchange.FilterOrdersByCurrencies(&orders, getOrdersRequest.Currencies)
return orders, nil
}

View File

@@ -498,8 +498,9 @@ func (b *Binance) CancelExistingOrder(symbol string, orderID int64, origClientOr
return resp, b.SendAuthHTTPRequest("DELETE", path, params, &resp)
}
// OpenOrders Current open orders
// Get all open orders on a symbol. Careful when accessing this with no symbol.
// OpenOrders Current open orders. Get all open orders on a symbol.
// Careful when accessing this with no symbol: The number of requests counted against the rate limiter
// is equal to the number of symbols currently trading on the exchange.
func (b *Binance) OpenOrders(symbol string) ([]QueryOrderData, error) {
var resp []QueryOrderData
path := fmt.Sprintf("%s%s", b.APIUrl, openOrders)

View File

@@ -320,17 +320,61 @@ func TestGetFee(t *testing.T) {
}
func TestFormatWithdrawPermissions(t *testing.T) {
// Arrange
b.SetDefaults()
expectedResult := exchange.AutoWithdrawCryptoText + " & " + exchange.NoFiatWithdrawalsText
// Act
withdrawPermissions := b.FormatWithdrawPermissions()
// Assert
if withdrawPermissions != expectedResult {
t.Errorf("Expected: %s, Received: %s", expectedResult, withdrawPermissions)
}
}
func TestGetActiveOrders(t *testing.T) {
b.SetDefaults()
TestSetup(t)
var getOrdersRequest = exchange.GetOrdersRequest{
OrderType: exchange.AnyOrderType,
}
_, err := b.GetActiveOrders(getOrdersRequest)
if err == nil {
t.Error("Expected: 'At least one currency is required to fetch order history'. received nil")
}
getOrdersRequest.Currencies = []pair.CurrencyPair{pair.NewCurrencyPair(symbol.LTC, symbol.BTC)}
_, err = b.GetActiveOrders(getOrdersRequest)
if areTestAPIKeysSet() && err != nil {
t.Errorf("Could not get open orders: %s", err)
} else if !areTestAPIKeysSet() && err == nil {
t.Error("Expecting an error when no keys are set")
}
}
func TestGetOrderHistory(t *testing.T) {
b.SetDefaults()
TestSetup(t)
var getOrdersRequest = exchange.GetOrdersRequest{
OrderType: exchange.AnyOrderType,
}
_, err := b.GetOrderHistory(getOrdersRequest)
if err == nil {
t.Error("Expected: 'At least one currency is required to fetch order history'. received nil")
}
getOrdersRequest.Currencies = []pair.CurrencyPair{pair.NewCurrencyPair(symbol.LTC, symbol.BTC)}
_, err = b.GetOrderHistory(getOrdersRequest)
if areTestAPIKeysSet() && err != nil {
t.Errorf("Could not get order history: %s", err)
} else if !areTestAPIKeysSet() && err == nil {
t.Error("Expecting an error when no keys are set")
}
}
// Any tests below this line have the ability to impact your orders on the exchange. Enable canManipulateRealOrders to run them
// -----------------------------------------------------------------------------------------------------------------------------
@@ -351,7 +395,7 @@ func TestSubmitOrder(t *testing.T) {
FirstCurrency: symbol.LTC,
SecondCurrency: symbol.BTC,
}
response, err := b.SubmitOrder(p, exchange.Buy, exchange.Market, 1, 1, "clientId")
response, err := b.SubmitOrder(p, exchange.BuyOrderSide, exchange.MarketOrderType, 1, 1, "clientId")
if areTestAPIKeysSet() && (err != nil || !response.IsOrderPlaced) {
t.Errorf("Order failed to be placed: %v", err)
} else if !areTestAPIKeysSet() && err == nil {
@@ -360,7 +404,6 @@ func TestSubmitOrder(t *testing.T) {
}
func TestCancelExchangeOrder(t *testing.T) {
// Arrange
b.SetDefaults()
TestSetup(t)
@@ -373,12 +416,9 @@ func TestCancelExchangeOrder(t *testing.T) {
CurrencyPair: currencyPair,
}
// Act
err := b.CancelOrder(orderCancellation)
// Assert
if !areTestAPIKeysSet() && err == nil {
t.Errorf("Expecting an error when no keys are set: %v", err)
t.Error("Expecting an error when no keys are set")
}
if areTestAPIKeysSet() && err != nil {
t.Errorf("Could not cancel orders: %v", err)
@@ -386,7 +426,6 @@ func TestCancelExchangeOrder(t *testing.T) {
}
func TestCancelAllExchangeOrders(t *testing.T) {
// Arrange
b.SetDefaults()
TestSetup(t)
@@ -399,12 +438,10 @@ func TestCancelAllExchangeOrders(t *testing.T) {
CurrencyPair: currencyPair,
}
// Act
resp, err := b.CancelAllOrders(orderCancellation)
// Assert
if !areTestAPIKeysSet() && err == nil {
t.Errorf("Expecting an error when no keys are set: %v", err)
t.Error("Expecting an error when no keys are set")
}
if areTestAPIKeysSet() && err != nil {
t.Errorf("Could not cancel order: %v", err)
@@ -452,7 +489,7 @@ func TestWithdraw(t *testing.T) {
_, err := b.WithdrawCryptocurrencyFunds(withdrawCryptoRequest)
if !areTestAPIKeysSet() && err == nil {
t.Errorf("Expecting an error when no keys are set: %v", err)
t.Error("Expecting an error when no keys are set")
}
if areTestAPIKeysSet() && err != nil {
t.Errorf("Withdraw failed to be placed: %v", err)

View File

@@ -4,7 +4,9 @@ import (
"errors"
"fmt"
"strconv"
"strings"
"sync"
"time"
"github.com/thrasher-/gocryptotrader/common"
"github.com/thrasher-/gocryptotrader/currency/pair"
@@ -183,16 +185,16 @@ func (b *Binance) SubmitOrder(p pair.CurrencyPair, side exchange.OrderSide, orde
var submitOrderResponse exchange.SubmitOrderResponse
var sideType RequestParamsSideType
if side == exchange.Buy {
if side == exchange.BuyOrderSide {
sideType = BinanceRequestParamsSideBuy
} else {
sideType = BinanceRequestParamsSideSell
}
var requestParamsOrderType RequestParamsOrderType
if orderType == exchange.Market {
if orderType == exchange.MarketOrderType {
requestParamsOrderType = BinanceRequestParamsOrderMarket
} else if orderType == exchange.Limit {
} else if orderType == exchange.LimitOrderType {
requestParamsOrderType = BinanceRequestParamsOrderLimit
} else {
submitOrderResponse.IsOrderPlaced = false
@@ -306,3 +308,86 @@ func (b *Binance) GetFeeByType(feeBuilder exchange.FeeBuilder) (float64, error)
func (b *Binance) GetWithdrawCapabilities() uint32 {
return b.GetWithdrawPermissions()
}
// GetActiveOrders retrieves any orders that are active/open
func (b *Binance) GetActiveOrders(getOrdersRequest exchange.GetOrdersRequest) ([]exchange.OrderDetail, error) {
if len(getOrdersRequest.Currencies) <= 0 {
return nil, errors.New("At least one currency is required to fetch order history")
}
var orders []exchange.OrderDetail
for _, currency := range getOrdersRequest.Currencies {
resp, err := b.OpenOrders(exchange.FormatExchangeCurrency(b.Name, currency).String())
if err != nil {
return nil, err
}
for _, order := range resp {
orderSide := exchange.OrderSide(strings.ToUpper(order.Side))
orderType := exchange.OrderType(strings.ToUpper(order.Type))
orderDate := time.Unix(int64(order.Time), 0)
orders = append(orders, exchange.OrderDetail{
Amount: order.OrigQty,
OrderDate: orderDate,
Exchange: b.Name,
ID: fmt.Sprintf("%v", order.OrderID),
OrderSide: orderSide,
OrderType: orderType,
Price: order.Price,
Status: order.Status,
CurrencyPair: pair.NewCurrencyPairFromString(order.Symbol),
})
}
}
exchange.FilterOrdersByType(&orders, getOrdersRequest.OrderType)
exchange.FilterOrdersBySide(&orders, getOrdersRequest.OrderSide)
exchange.FilterOrdersByTickRange(&orders, getOrdersRequest.StartTicks, getOrdersRequest.EndTicks)
return orders, nil
}
// GetOrderHistory retrieves account order information
// Can Limit response to specific order status
func (b *Binance) GetOrderHistory(getOrdersRequest exchange.GetOrdersRequest) ([]exchange.OrderDetail, error) {
if len(getOrdersRequest.Currencies) <= 0 {
return nil, errors.New("At least one currency is required to fetch order history")
}
var orders []exchange.OrderDetail
for _, currency := range getOrdersRequest.Currencies {
resp, err := b.AllOrders(exchange.FormatExchangeCurrency(b.Name, currency).String(), "", "1000")
if err != nil {
return nil, err
}
for _, order := range resp {
orderSide := exchange.OrderSide(strings.ToUpper(order.Side))
orderType := exchange.OrderType(strings.ToUpper(order.Type))
orderDate := time.Unix(int64(order.Time), 0)
// New orders are covered in GetOpenOrders
if order.Status == "NEW" {
continue
}
orders = append(orders, exchange.OrderDetail{
Amount: order.OrigQty,
OrderDate: orderDate,
Exchange: b.Name,
ID: fmt.Sprintf("%v", order.OrderID),
OrderSide: orderSide,
OrderType: orderType,
Price: order.Price,
CurrencyPair: pair.NewCurrencyPairFromString(order.Symbol),
Status: order.Status,
})
}
}
exchange.FilterOrdersByType(&orders, getOrdersRequest.OrderType)
exchange.FilterOrdersBySide(&orders, getOrdersRequest.OrderSide)
exchange.FilterOrdersByTickRange(&orders, getOrdersRequest.StartTicks, getOrdersRequest.EndTicks)
return orders, nil
}

View File

@@ -46,6 +46,7 @@ const (
bitfinexOrderCancelReplace = "order/cancel/replace"
bitfinexOrderStatus = "order/status"
bitfinexOrders = "orders"
bitfinexInactiveOrders = "orders/hist"
bitfinexPositions = "positions"
bitfinexClaimPosition = "position/claim"
bitfinexHistory = "history"
@@ -732,9 +733,19 @@ func (b *Bitfinex) GetOrderStatus(OrderID int64) (Order, error) {
b.SendAuthenticatedHTTPRequest("POST", bitfinexOrderStatus, request, &orderStatus)
}
// GetActiveOrders returns all active orders and statuses
func (b *Bitfinex) GetActiveOrders() ([]Order, error) {
response := []Order{}
// GetInactiveOrders returns order status information
func (b *Bitfinex) GetInactiveOrders() ([]Order, error) {
var response []Order
request := make(map[string]interface{})
request["limit"] = "100"
return response,
b.SendAuthenticatedHTTPRequest("POST", bitfinexInactiveOrders, request, &response)
}
// GetOpenOrders returns all active orders and statuses
func (b *Bitfinex) GetOpenOrders() ([]Order, error) {
var response []Order
return response,
b.SendAuthenticatedHTTPRequest("POST", bitfinexOrders, nil, &response)

View File

@@ -431,15 +431,15 @@ func TestGetOrderStatus(t *testing.T) {
}
}
func TestGetActiveOrders(t *testing.T) {
func TestGetOpenOrders(t *testing.T) {
if b.APIKey == "" || b.APISecret == "" {
t.SkipNow()
}
t.Parallel()
_, err := b.GetActiveOrders()
_, err := b.GetOpenOrders()
if err == nil {
t.Error("Test Failed - GetActiveOrders() error")
t.Error("Test Failed - GetOpenOrders() error")
}
}
@@ -697,17 +697,48 @@ func TestGetFee(t *testing.T) {
}
func TestFormatWithdrawPermissions(t *testing.T) {
// Arrange
b.SetDefaults()
expectedResult := exchange.AutoWithdrawCryptoWithAPIPermissionText + " & " + exchange.AutoWithdrawFiatWithAPIPermissionText
// Act
withdrawPermissions := b.FormatWithdrawPermissions()
// Assert
if withdrawPermissions != expectedResult {
t.Errorf("Expected: %s, Received: %s", expectedResult, withdrawPermissions)
}
}
func TestGetActiveOrders(t *testing.T) {
b.SetDefaults()
TestSetup(t)
var getOrdersRequest = exchange.GetOrdersRequest{
OrderType: exchange.AnyOrderType,
}
_, err := b.GetActiveOrders(getOrdersRequest)
if areTestAPIKeysSet() && err != nil {
t.Errorf("Could not get open orders: %s", err)
} else if !areTestAPIKeysSet() && err == nil {
t.Error("Expecting an error when no keys are set")
}
}
func TestGetOrderHistory(t *testing.T) {
b.SetDefaults()
TestSetup(t)
var getOrdersRequest = exchange.GetOrdersRequest{
OrderType: exchange.AnyOrderType,
}
_, err := b.GetOrderHistory(getOrdersRequest)
if areTestAPIKeysSet() && err != nil {
t.Errorf("Could not get order history: %s", err)
} else if !areTestAPIKeysSet() && err == nil {
t.Error("Expecting an error when no keys are set")
}
}
// Any tests below this line have the ability to impact your orders on the exchange. Enable canManipulateRealOrders to run them
// ----------------------------------------------------------------------------------------------------------------------------
func areTestAPIKeysSet() bool {
@@ -730,7 +761,7 @@ func TestSubmitOrder(t *testing.T) {
FirstCurrency: symbol.LTC,
SecondCurrency: symbol.BTC,
}
response, err := b.SubmitOrder(p, exchange.Buy, exchange.Market, 1, 1, "clientId")
response, err := b.SubmitOrder(p, exchange.BuyOrderSide, exchange.MarketOrderType, 1, 1, "clientId")
if areTestAPIKeysSet() && (err != nil || !response.IsOrderPlaced) {
t.Errorf("Order failed to be placed: %v", err)
} else if !areTestAPIKeysSet() && err == nil {
@@ -739,7 +770,6 @@ func TestSubmitOrder(t *testing.T) {
}
func TestCancelExchangeOrder(t *testing.T) {
// Arrange
b.SetDefaults()
TestSetup(t)
@@ -756,12 +786,9 @@ func TestCancelExchangeOrder(t *testing.T) {
CurrencyPair: currencyPair,
}
// Act
err := b.CancelOrder(orderCancellation)
// Assert
if !areTestAPIKeysSet() && err == nil {
t.Errorf("Expecting an error when no keys are set: %v", err)
t.Error("Expecting an error when no keys are set")
}
if areTestAPIKeysSet() && err != nil {
t.Errorf("Could not cancel orders: %v", err)
@@ -769,7 +796,6 @@ func TestCancelExchangeOrder(t *testing.T) {
}
func TestCancelAllExchangeOrdera(t *testing.T) {
// Arrange
b.SetDefaults()
TestSetup(t)
@@ -786,12 +812,10 @@ func TestCancelAllExchangeOrdera(t *testing.T) {
CurrencyPair: currencyPair,
}
// Act
resp, err := b.CancelAllOrders(orderCancellation)
// Assert
if !areTestAPIKeysSet() && err == nil {
t.Errorf("Expecting an error when no keys are set: %v", err)
t.Error("Expecting an error when no keys are set")
}
if areTestAPIKeysSet() && err != nil {
t.Errorf("Could not cancel orders: %v", err)
@@ -825,7 +849,7 @@ func TestWithdraw(t *testing.T) {
_, err := b.WithdrawCryptocurrencyFunds(withdrawCryptoRequest)
if !areTestAPIKeysSet() && err == nil {
t.Errorf("Expecting an error when no keys are set: %v", err)
t.Error("Expecting an error when no keys are set")
}
if areTestAPIKeysSet() && err != nil {
t.Errorf("Withdraw failed to be placed: %v", err)
@@ -858,7 +882,7 @@ func TestWithdrawFiat(t *testing.T) {
_, err := b.WithdrawFiatFunds(withdrawFiatRequest)
if !areTestAPIKeysSet() && err == nil {
t.Errorf("Expecting an error when no keys are set: %v", err)
t.Error("Expecting an error when no keys are set")
}
if areTestAPIKeysSet() && err != nil {
t.Errorf("Withdraw failed to be placed: %v", err)
@@ -897,7 +921,7 @@ func TestWithdrawInternationalBank(t *testing.T) {
_, err := b.WithdrawFiatFundsToInternationalBank(withdrawFiatRequest)
if !areTestAPIKeysSet() && err == nil {
t.Errorf("Expecting an error when no keys are set: %v", err)
t.Error("Expecting an error when no keys are set")
}
if areTestAPIKeysSet() && err != nil {
t.Errorf("Withdraw failed to be placed: %v", err)

View File

@@ -257,7 +257,7 @@ type Order struct {
OriginalAmount float64 `json:"original_amount,string"`
RemainingAmount float64 `json:"remaining_amount,string"`
ExecutedAmount float64 `json:"executed_amount,string"`
OrderID int64 `json:"order_id"`
OrderID int64 `json:"order_id,omitempty"`
}
// OrderMultiResponse holds order information on the executed orders

View File

@@ -5,7 +5,9 @@ import (
"fmt"
"net/url"
"strconv"
"strings"
"sync"
"time"
"github.com/thrasher-/gocryptotrader/common"
"github.com/thrasher-/gocryptotrader/currency/pair"
@@ -166,7 +168,7 @@ func (b *Bitfinex) SubmitOrder(p pair.CurrencyPair, side exchange.OrderSide, ord
var submitOrderResponse exchange.SubmitOrderResponse
var isBuying bool
if side == exchange.Buy {
if side == exchange.BuyOrderSide {
isBuying = true
}
@@ -306,3 +308,120 @@ func (b *Bitfinex) GetFeeByType(feeBuilder exchange.FeeBuilder) (float64, error)
func (b *Bitfinex) GetWithdrawCapabilities() uint32 {
return b.GetWithdrawPermissions()
}
// GetActiveOrders retrieves any orders that are active/open
func (b *Bitfinex) GetActiveOrders(getOrdersRequest exchange.GetOrdersRequest) ([]exchange.OrderDetail, error) {
var orders []exchange.OrderDetail
resp, err := b.GetOpenOrders()
if err != nil {
return nil, err
}
for _, order := range resp {
orderSide := exchange.OrderSide(strings.ToUpper(order.Side))
timestamp, err := strconv.ParseInt(order.Timestamp, 10, 64)
if err != nil {
log.Warnf("Unable to convert timestamp '%v', leaving blank", order.Timestamp)
}
orderDate := time.Unix(timestamp, 0)
orderDetail := exchange.OrderDetail{
Amount: order.OriginalAmount,
OrderDate: orderDate,
Exchange: b.Name,
ID: fmt.Sprintf("%v", order.OrderID),
OrderSide: orderSide,
Price: order.Price,
RemainingAmount: order.RemainingAmount,
CurrencyPair: pair.NewCurrencyPairFromString(order.Symbol),
ExecutedAmount: order.ExecutedAmount,
}
if order.IsLive {
orderDetail.Status = string(exchange.ActiveOrderStatus)
} else if order.IsCancelled {
orderDetail.Status = string(exchange.CancelledOrderStatus)
} else if order.IsHidden {
orderDetail.Status = string(exchange.HiddenOrderStatus)
} else {
orderDetail.Status = string(exchange.UnknownOrderStatus)
}
// API docs discrepency. Example contains prefixed "exchange "
// Return type suggests “market” / “limit” / “stop” / “trailing-stop”
orderType := strings.Replace(order.Type, "exchange ", "", 1)
if orderType == "trailing-stop" {
orderDetail.OrderType = exchange.TrailingStopOrderType
} else {
orderDetail.OrderType = exchange.OrderType(strings.ToUpper(orderType))
}
orders = append(orders, orderDetail)
}
exchange.FilterOrdersBySide(&orders, getOrdersRequest.OrderSide)
exchange.FilterOrdersByType(&orders, getOrdersRequest.OrderType)
exchange.FilterOrdersByTickRange(&orders, getOrdersRequest.StartTicks, getOrdersRequest.EndTicks)
exchange.FilterOrdersByCurrencies(&orders, getOrdersRequest.Currencies)
return orders, nil
}
// GetOrderHistory retrieves account order information
// Can Limit response to specific order status
func (b *Bitfinex) GetOrderHistory(getOrdersRequest exchange.GetOrdersRequest) ([]exchange.OrderDetail, error) {
var orders []exchange.OrderDetail
resp, err := b.GetInactiveOrders()
if err != nil {
return nil, err
}
for _, order := range resp {
orderSide := exchange.OrderSide(strings.ToUpper(order.Side))
timestamp, err := strconv.ParseInt(order.Timestamp, 10, 64)
if err != nil {
log.Warnf("Unable to convert timestamp '%v', leaving blank", order.Timestamp)
}
orderDate := time.Unix(timestamp, 0)
orderDetail := exchange.OrderDetail{
Amount: order.OriginalAmount,
OrderDate: orderDate,
Exchange: b.Name,
ID: fmt.Sprintf("%v", order.OrderID),
OrderSide: orderSide,
Price: order.Price,
RemainingAmount: order.RemainingAmount,
ExecutedAmount: order.ExecutedAmount,
CurrencyPair: pair.NewCurrencyPairFromString(order.Symbol),
}
if order.IsLive {
orderDetail.Status = string(exchange.ActiveOrderStatus)
} else if order.IsCancelled {
orderDetail.Status = string(exchange.CancelledOrderStatus)
} else if order.IsHidden {
orderDetail.Status = string(exchange.HiddenOrderStatus)
} else {
orderDetail.Status = string(exchange.UnknownOrderStatus)
}
// API docs discrepency. Example contains prefixed "exchange "
// Return type suggests “market” / “limit” / “stop” / “trailing-stop”
orderType := strings.Replace(order.Type, "exchange ", "", 1)
if orderType == "trailing-stop" {
orderDetail.OrderType = exchange.TrailingStopOrderType
} else {
orderDetail.OrderType = exchange.OrderType(strings.ToUpper(orderType))
}
orders = append(orders, orderDetail)
}
exchange.FilterOrdersBySide(&orders, getOrdersRequest.OrderSide)
exchange.FilterOrdersByType(&orders, getOrdersRequest.OrderType)
exchange.FilterOrdersByTickRange(&orders, getOrdersRequest.StartTicks, getOrdersRequest.EndTicks)
exchange.FilterOrdersByCurrencies(&orders, getOrdersRequest.Currencies)
return orders, nil
}

View File

@@ -238,17 +238,46 @@ func TestGetFee(t *testing.T) {
}
func TestFormatWithdrawPermissions(t *testing.T) {
// Arrange
b.SetDefaults()
expectedResult := exchange.AutoWithdrawFiatText + " & " + exchange.WithdrawCryptoViaWebsiteOnlyText
// Act
withdrawPermissions := b.FormatWithdrawPermissions()
// Assert
if withdrawPermissions != expectedResult {
t.Errorf("Expected: %s, Received: %s", expectedResult, withdrawPermissions)
}
}
func TestGetActiveOrders(t *testing.T) {
b.SetDefaults()
TestSetup(t)
var getOrdersRequest = exchange.GetOrdersRequest{
OrderType: exchange.AnyOrderType,
}
_, err := b.GetActiveOrders(getOrdersRequest)
if areTestAPIKeysSet() && err != nil {
t.Errorf("Could not get open orders: %s", err)
} else if !areTestAPIKeysSet() && err == nil {
t.Error("Expecting an error when no keys are set")
}
}
func TestGetOrderHistory(t *testing.T) {
b.SetDefaults()
TestSetup(t)
var getOrdersRequest = exchange.GetOrdersRequest{
OrderType: exchange.AnyOrderType,
}
_, err := b.GetOrderHistory(getOrdersRequest)
if err != common.ErrNotYetImplemented {
t.Errorf("Expected '%v', received '%v'", common.ErrNotYetImplemented, err)
}
}
// Any tests below this line have the ability to impact your orders on the exchange. Enable canManipulateRealOrders to run them
// ----------------------------------------------------------------------------------------------------------------------------
func areTestAPIKeysSet() bool {
@@ -272,14 +301,13 @@ func TestSubmitOrder(t *testing.T) {
FirstCurrency: symbol.LTC,
SecondCurrency: symbol.BTC,
}
_, err := b.SubmitOrder(p, exchange.Buy, exchange.Market, 1, 1, "clientId")
_, err := b.SubmitOrder(p, exchange.BuyOrderSide, exchange.MarketOrderType, 1, 1, "clientId")
if err != common.ErrNotYetImplemented {
t.Errorf("Expected 'Not Yet Implemented', received %v", err)
}
}
func TestCancelExchangeOrder(t *testing.T) {
// Arrange
b.SetDefaults()
TestSetup(t)
@@ -295,16 +323,14 @@ func TestCancelExchangeOrder(t *testing.T) {
CurrencyPair: currencyPair,
}
// Act
err := b.CancelOrder(orderCancellation)
// Assert
if err != common.ErrNotYetImplemented {
t.Errorf("Expected 'Not Yet Implemented', received %v", err)
}
}
func TestCancelAllExchangeOrders(t *testing.T) {
// Arrange
b.SetDefaults()
TestSetup(t)
@@ -320,9 +346,8 @@ func TestCancelAllExchangeOrders(t *testing.T) {
CurrencyPair: currencyPair,
}
// Act
_, err := b.CancelAllOrders(orderCancellation)
// Assert
if err != common.ErrNotYetImplemented {
t.Errorf("Expected 'Not Yet Implemented', received %v", err)
}

View File

@@ -215,3 +215,14 @@ func (b *Bitflyer) GetWebsocket() (*exchange.Websocket, error) {
func (b *Bitflyer) GetWithdrawCapabilities() uint32 {
return b.GetWithdrawPermissions()
}
// GetActiveOrders retrieves any orders that are active/open
func (b *Bitflyer) GetActiveOrders(getOrdersRequest exchange.GetOrdersRequest) ([]exchange.OrderDetail, error) {
return nil, common.ErrNotYetImplemented
}
// GetOrderHistory retrieves account order information
// Can Limit response to specific order status
func (b *Bitflyer) GetOrderHistory(getOrdersRequest exchange.GetOrdersRequest) ([]exchange.OrderDetail, error) {
return nil, common.ErrNotYetImplemented
}

View File

@@ -355,11 +355,25 @@ func (b *Bithumb) GetOrders(orderID, transactionType, count, after, currency str
response := Orders{}
params := url.Values{}
params.Set("order_id", orderID)
params.Set("type", transactionType)
params.Set("count", count)
params.Set("after", after)
params.Set("currency", common.StringToUpper(currency))
if len(orderID) > 0 {
params.Set("order_id", orderID)
}
if len(transactionType) > 0 {
params.Set("type", transactionType)
}
if len(count) > 0 {
params.Set("count", count)
}
if len(after) > 0 {
params.Set("after", after)
}
if len(currency) > 0 {
params.Set("currency", common.StringToUpper(currency))
}
return response,
b.SendAuthenticatedHTTPRequest(privateOrders, params, &response)
@@ -421,7 +435,7 @@ func (b *Bithumb) GetOrderDetails(orderID, transactionType, currency string) (Or
params := url.Values{}
params.Set("order_id", common.StringToUpper(orderID))
params.Set("type", common.StringToUpper(transactionType))
params.Set("type", transactionType)
params.Set("currency", common.StringToUpper(currency))
return response,

View File

@@ -277,17 +277,49 @@ func TestGetFee(t *testing.T) {
}
func TestFormatWithdrawPermissions(t *testing.T) {
// Arrange
b.SetDefaults()
expectedResult := exchange.AutoWithdrawCryptoText + " & " + exchange.AutoWithdrawFiatText
// Act
withdrawPermissions := b.FormatWithdrawPermissions()
// Assert
if withdrawPermissions != expectedResult {
t.Errorf("Expected: %s, Received: %s", expectedResult, withdrawPermissions)
}
}
func TestGetActiveOrders(t *testing.T) {
b.SetDefaults()
TestSetup(t)
var getOrdersRequest = exchange.GetOrdersRequest{
OrderType: exchange.AnyOrderType,
OrderSide: exchange.SellOrderSide,
}
_, err := b.GetActiveOrders(getOrdersRequest)
if areTestAPIKeysSet() && err != nil {
t.Errorf("Could not get open orders: %s", err)
} else if !areTestAPIKeysSet() && err == nil {
t.Error("Expecting an error when no keys are set")
}
}
func TestGetOrderHistory(t *testing.T) {
b.SetDefaults()
TestSetup(t)
var getOrdersRequest = exchange.GetOrdersRequest{
OrderType: exchange.AnyOrderType,
}
_, err := b.GetOrderHistory(getOrdersRequest)
if areTestAPIKeysSet() && err != nil {
t.Errorf("Could not get order history: %s", err)
} else if !areTestAPIKeysSet() && err == nil {
t.Error("Expecting an error when no keys are set")
}
}
// Any tests below this line have the ability to impact your orders on the exchange. Enable canManipulateRealOrders to run them
// ----------------------------------------------------------------------------------------------------------------------------
func areTestAPIKeysSet() bool {
@@ -311,7 +343,7 @@ func TestSubmitOrder(t *testing.T) {
FirstCurrency: symbol.BTC,
SecondCurrency: symbol.LTC,
}
response, err := b.SubmitOrder(p, exchange.Buy, exchange.Market, 1, 1, "clientId")
response, err := b.SubmitOrder(p, exchange.BuyOrderSide, exchange.MarketOrderType, 1, 1, "clientId")
if areTestAPIKeysSet() && (err != nil || !response.IsOrderPlaced) {
t.Errorf("Order failed to be placed: %v", err)
} else if !areTestAPIKeysSet() && err == nil {
@@ -320,7 +352,6 @@ func TestSubmitOrder(t *testing.T) {
}
func TestCancelExchangeOrder(t *testing.T) {
// Arrange
b.SetDefaults()
TestSetup(t)
@@ -337,12 +368,9 @@ func TestCancelExchangeOrder(t *testing.T) {
CurrencyPair: currencyPair,
}
// Act
err := b.CancelOrder(orderCancellation)
// Assert
if !areTestAPIKeysSet() && err == nil {
t.Errorf("Expecting an error when no keys are set: %v", err)
t.Error("Expecting an error when no keys are set")
}
if areTestAPIKeysSet() && err != nil {
t.Errorf("Could not cancel order: %v", err)
@@ -350,7 +378,6 @@ func TestCancelExchangeOrder(t *testing.T) {
}
func TestCancelAllExchangeOrders(t *testing.T) {
// Arrange
b.SetDefaults()
TestSetup(t)
@@ -367,12 +394,10 @@ func TestCancelAllExchangeOrders(t *testing.T) {
CurrencyPair: currencyPair,
}
// Act
resp, err := b.CancelAllOrders(orderCancellation)
// Assert
if !areTestAPIKeysSet() && err == nil {
t.Errorf("Expecting an error when no keys are set: %v", err)
t.Error("Expecting an error when no keys are set")
}
if areTestAPIKeysSet() && err != nil {
t.Errorf("Could not cancel order: %v", err)
@@ -403,7 +428,7 @@ func TestModifyOrder(t *testing.T) {
_, err := b.ModifyOrder(exchange.ModifyOrder{OrderID: "1337",
Price: 100,
Amount: 1000,
OrderSide: exchange.Sell,
OrderSide: exchange.SellOrderSide,
Currency: curr})
if err == nil {
t.Error("Test Failed - ModifyOrder() error")
@@ -426,7 +451,7 @@ func TestWithdraw(t *testing.T) {
_, err := b.WithdrawCryptocurrencyFunds(withdrawCryptoRequest)
if !areTestAPIKeysSet() && err == nil {
t.Errorf("Expecting an error when no keys are set: %v", err)
t.Error("Expecting an error when no keys are set")
}
if areTestAPIKeysSet() && err != nil {
t.Errorf("Withdraw failed to be placed: %v", err)
@@ -460,7 +485,7 @@ func TestWithdrawFiat(t *testing.T) {
_, err := b.WithdrawFiatFunds(withdrawFiatRequest)
if !areTestAPIKeysSet() && err == nil {
t.Errorf("Expecting an error when no keys are set: %v", err)
t.Error("Expecting an error when no keys are set")
}
if areTestAPIKeysSet() && err != nil {
t.Errorf("Withdraw failed to be placed: %v", err)

View File

@@ -6,6 +6,7 @@ import (
"math"
"strconv"
"sync"
"time"
"github.com/thrasher-/gocryptotrader/common"
"github.com/thrasher-/gocryptotrader/currency/pair"
@@ -173,11 +174,11 @@ func (b *Bithumb) SubmitOrder(p pair.CurrencyPair, side exchange.OrderSide, orde
var submitOrderResponse exchange.SubmitOrderResponse
var err error
var orderID string
if side == exchange.Buy {
if side == exchange.BuyOrderSide {
var result MarketBuy
result, err = b.MarketBuyOrder(p.FirstCurrency.String(), amount)
orderID = result.OrderID
} else if side == exchange.Sell {
} else if side == exchange.SellOrderSide {
var result MarketSell
result, err = b.MarketSellOrder(p.FirstCurrency.String(), amount)
orderID = result.OrderID
@@ -306,3 +307,85 @@ func (b *Bithumb) GetFeeByType(feeBuilder exchange.FeeBuilder) (float64, error)
func (b *Bithumb) GetWithdrawCapabilities() uint32 {
return b.GetWithdrawPermissions()
}
// GetActiveOrders retrieves any orders that are active/open
func (b *Bithumb) GetActiveOrders(getOrdersRequest exchange.GetOrdersRequest) ([]exchange.OrderDetail, error) {
var orders []exchange.OrderDetail
resp, err := b.GetOrders("", "", "1000", "", "")
if err != nil {
return nil, err
}
for _, order := range resp.Data {
if order.Status != "placed" {
continue
}
orderDate := time.Unix(order.OrderDate, 0)
orderDetail := exchange.OrderDetail{
Amount: order.Units,
Exchange: b.Name,
ID: order.OrderID,
OrderDate: orderDate,
Price: order.Price,
RemainingAmount: order.UnitsRemaining,
Status: string(exchange.ActiveOrderStatus),
CurrencyPair: pair.NewCurrencyPairWithDelimiter(order.OrderCurrency, order.PaymentCurrency, b.ConfigCurrencyPairFormat.Delimiter),
}
if order.Type == "bid" {
orderDetail.OrderSide = exchange.BuyOrderSide
} else if order.Type == "ask" {
orderDetail.OrderSide = exchange.SellOrderSide
}
orders = append(orders, orderDetail)
}
exchange.FilterOrdersBySide(&orders, getOrdersRequest.OrderSide)
exchange.FilterOrdersByTickRange(&orders, getOrdersRequest.StartTicks, getOrdersRequest.EndTicks)
exchange.FilterOrdersByCurrencies(&orders, getOrdersRequest.Currencies)
return orders, nil
}
// GetOrderHistory retrieves account order information
// Can Limit response to specific order status
func (b *Bithumb) GetOrderHistory(getOrdersRequest exchange.GetOrdersRequest) ([]exchange.OrderDetail, error) {
var orders []exchange.OrderDetail
resp, err := b.GetOrders("", "", "1000", "", "")
if err != nil {
return nil, err
}
for _, order := range resp.Data {
if order.Status == "placed" {
continue
}
orderDate := time.Unix(order.OrderDate, 0)
orderDetail := exchange.OrderDetail{
Amount: order.Units,
Exchange: b.Name,
ID: order.OrderID,
OrderDate: orderDate,
Price: order.Price,
RemainingAmount: order.UnitsRemaining,
CurrencyPair: pair.NewCurrencyPairWithDelimiter(order.OrderCurrency, order.PaymentCurrency, b.ConfigCurrencyPairFormat.Delimiter),
}
if order.Type == "bid" {
orderDetail.OrderSide = exchange.BuyOrderSide
} else if order.Type == "ask" {
orderDetail.OrderSide = exchange.SellOrderSide
}
orders = append(orders, orderDetail)
}
exchange.FilterOrdersBySide(&orders, getOrdersRequest.OrderSide)
exchange.FilterOrdersByTickRange(&orders, getOrdersRequest.StartTicks, getOrdersRequest.EndTicks)
exchange.FilterOrdersByCurrencies(&orders, getOrdersRequest.Currencies)
return orders, nil
}

View File

@@ -400,11 +400,11 @@ func (b *Bitmex) GetCurrentNotifications() ([]Notification, error) {
}
// GetOrders returns all the orders, open and closed
func (b *Bitmex) GetOrders(params GenericRequestParams) ([]Order, error) {
func (b *Bitmex) GetOrders(params OrdersRequest) ([]Order, error) {
var orders []Order
return orders, b.SendAuthenticatedHTTPRequest("GET",
bitmexEndpointOrder,
fmt.Sprintf("%v%v", bitmexEndpointOrder, ""),
params,
&orders)
}

View File

@@ -1037,3 +1037,31 @@ func (p UserRequestWithdrawalParams) ToURLVals(path string) (string, error) {
func (p UserRequestWithdrawalParams) IsNil() bool {
return p == (UserRequestWithdrawalParams{})
}
// OrdersRequest used for GetOrderHistory
type OrdersRequest struct {
Symbol string `json:"symbol,omitempty"`
Filter string `json:"filter,omitempty"`
Columns string `json:"columns,omitempty"`
Count float64 `json:"count,omitempty"`
Start float64 `json:"start,omitempty"`
Reverse bool `json:"reverse,omitempty"`
StartTime string `json:"startTime,omitempty"`
EndTime string `json:"endTime,omitempty"`
}
// VerifyData verifies parameter data during SendAuthenticatedHTTPRequest
func (p OrdersRequest) VerifyData() error {
return nil
}
// ToURLVals converts struct values to url.values and encodes it on the supplied
// path
func (p OrdersRequest) ToURLVals(path string) (string, error) {
return "", nil
}
// IsNil checks to see if any values has been set for the paramater
func (p OrdersRequest) IsNil() bool {
return p == (OrdersRequest{})
}

View File

@@ -32,7 +32,6 @@ func TestSetup(t *testing.T) {
if err != nil {
t.Error("Test Failed - Bitmex Setup() init error")
}
bitmexConfig.AuthenticatedAPISupport = true
bitmexConfig.APIKey = testAPIKey
bitmexConfig.APISecret = testAPISecret
@@ -209,13 +208,6 @@ func TestGetCurrentNotifications(t *testing.T) {
}
}
func TestGetOrders(t *testing.T) {
_, err := b.GetOrders(GenericRequestParams{})
if err == nil {
t.Error("test failed - GetOrders() error", err)
}
}
func TestAmendOrder(t *testing.T) {
_, err := b.AmendOrder(OrderAmendParams{})
if err == nil {
@@ -454,18 +446,50 @@ func TestGetFee(t *testing.T) {
}
func TestFormatWithdrawPermissions(t *testing.T) {
// Arrange
b.SetDefaults()
expectedResult := exchange.AutoWithdrawCryptoWithAPIPermissionText + " & " + exchange.WithdrawCryptoWith2FAText +
" & " + exchange.WithdrawCryptoWithEmailText + " & " + exchange.NoFiatWithdrawalsText
// Act
withdrawPermissions := b.FormatWithdrawPermissions()
// Assert
if withdrawPermissions != expectedResult {
t.Errorf("Expected: %s, Received: %s", expectedResult, withdrawPermissions)
}
}
func TestGetActiveOrders(t *testing.T) {
b.SetDefaults()
TestSetup(t)
var getOrdersRequest = exchange.GetOrdersRequest{
OrderType: exchange.AnyOrderType,
}
_, err := b.GetActiveOrders(getOrdersRequest)
if areTestAPIKeysSet() && err != nil {
t.Errorf("Could not get open orders: %s", err)
} else if !areTestAPIKeysSet() && err == nil {
t.Error("Expecting an error when no keys are set")
}
}
func TestGetOrderHistory(t *testing.T) {
b.SetDefaults()
TestSetup(t)
var getOrdersRequest = exchange.GetOrdersRequest{
OrderType: exchange.AnyOrderType,
Currencies: []pair.CurrencyPair{pair.NewCurrencyPair(symbol.LTC, symbol.BTC)},
}
_, err := b.GetOrderHistory(getOrdersRequest)
if areTestAPIKeysSet() && err != nil {
t.Errorf("Could not get order history: %s", err)
} else if !areTestAPIKeysSet() && err == nil {
t.Error("Expecting an error when no keys are set")
}
}
// Any tests below this line have the ability to impact your orders on the exchange. Enable canManipulateRealOrders to run them
// ----------------------------------------------------------------------------------------------------------------------------
func areTestAPIKeysSet() bool {
@@ -489,7 +513,7 @@ func TestSubmitOrder(t *testing.T) {
FirstCurrency: symbol.XBT,
SecondCurrency: symbol.USD,
}
response, err := b.SubmitOrder(p, exchange.Buy, exchange.Market, 1, 1, "clientId")
response, err := b.SubmitOrder(p, exchange.BuyOrderSide, exchange.MarketOrderType, 1, 1, "clientId")
if areTestAPIKeysSet() && (err != nil || !response.IsOrderPlaced) {
t.Errorf("Order failed to be placed: %v", err)
} else if !areTestAPIKeysSet() && err == nil {
@@ -498,7 +522,6 @@ func TestSubmitOrder(t *testing.T) {
}
func TestCancelExchangeOrder(t *testing.T) {
// Arrange
b.SetDefaults()
TestSetup(t)
@@ -515,12 +538,9 @@ func TestCancelExchangeOrder(t *testing.T) {
CurrencyPair: currencyPair,
}
// Act
err := b.CancelOrder(orderCancellation)
// Assert
if !areTestAPIKeysSet() && err == nil {
t.Errorf("Expecting an error when no keys are set: %v", err)
t.Error("Expecting an error when no keys are set")
}
if areTestAPIKeysSet() && err != nil {
t.Errorf("Could not cancel orders: %v", err)
@@ -528,7 +548,6 @@ func TestCancelExchangeOrder(t *testing.T) {
}
func TestCancelAllExchangeOrders(t *testing.T) {
// Arrange
b.SetDefaults()
TestSetup(t)
@@ -545,12 +564,10 @@ func TestCancelAllExchangeOrders(t *testing.T) {
CurrencyPair: currencyPair,
}
// Act
resp, err := b.CancelAllOrders(orderCancellation)
// Assert
if !areTestAPIKeysSet() && err == nil {
t.Errorf("Expecting an error when no keys are set: %v", err)
t.Error("Expecting an error when no keys are set")
}
if areTestAPIKeysSet() && err != nil {
t.Errorf("Could not cancel orders: %v", err)
@@ -599,7 +616,7 @@ func TestWithdraw(t *testing.T) {
_, err := b.WithdrawCryptocurrencyFunds(withdrawCryptoRequest)
if !areTestAPIKeysSet() && err == nil {
t.Errorf("Expecting an error when no keys are set: %v", err)
t.Error("Expecting an error when no keys are set")
}
if areTestAPIKeysSet() && err != nil {
t.Errorf("Withdraw failed to be placed: %v", err)

View File

@@ -1,5 +1,7 @@
package bitmex
import exchange "github.com/thrasher-/gocryptotrader/exchanges"
// RequestError allows for a general error capture from requests
type RequestError struct {
Error struct {
@@ -293,14 +295,14 @@ type Order struct {
MultiLegReportingType string `json:"multiLegReportingType"`
OrdRejReason string `json:"ordRejReason"`
OrdStatus string `json:"ordStatus"`
OrdType string `json:"ordType"`
OrdType int64 `json:"ordType,string"`
OrderID string `json:"orderID"`
OrderQty int64 `json:"orderQty"`
PegOffsetValue float64 `json:"pegOffsetValue"`
PegPriceType string `json:"pegPriceType"`
Price float64 `json:"price"`
SettlCurrency string `json:"settlCurrency"`
Side string `json:"side"`
Side int64 `json:"side,string"`
SimpleCumQty float64 `json:"simpleCumQty"`
SimpleLeavesQty float64 `json:"simpleLeavesQty"`
SimpleOrderQty float64 `json:"simpleOrderQty"`
@@ -666,3 +668,17 @@ type WalletInfo struct {
WithdrawalLock []string `json:"withdrawalLock"`
Withdrawn int64 `json:"withdrawn"`
}
// orderTypeMap holds order type info based on Bitmex data
var orderTypeMap = map[int64]exchange.OrderType{
1: exchange.MarketOrderType,
2: exchange.LimitOrderType,
3: exchange.StopOrderType,
7: exchange.TrailingStopOrderType,
}
// orderSideMap holds order type info based on Bitmex data
var orderSideMap = map[int64]exchange.OrderSide{
1: exchange.BuyOrderSide,
2: exchange.SellOrderSide,
}

View File

@@ -322,7 +322,7 @@ func (b *Bitmex) processOrderbook(data []OrderBookL2, action string, currencyPai
var bids, asks []orderbook.Item
for _, orderbookItem := range data {
if orderbookItem.Side == exchange.Sell.ToString() {
if orderbookItem.Side == exchange.SellOrderSide.ToString() {
asks = append(asks, orderbook.Item{
Price: orderbookItem.Price,
Amount: float64(orderbookItem.Size),

View File

@@ -107,12 +107,12 @@ func (b *Bitmex) UpdateOrderbook(p pair.CurrencyPair, assetType string) (orderbo
}
for _, ob := range orderbookNew {
if ob.Side == exchange.Sell.ToString() {
if ob.Side == exchange.SellOrderSide.ToString() {
orderBook.Asks = append(orderBook.Asks,
orderbook.Item{Amount: float64(ob.Size), Price: ob.Price})
continue
}
if ob.Side == exchange.Buy.ToString() {
if ob.Side == exchange.BuyOrderSide.ToString() {
orderBook.Bids = append(orderBook.Bids,
orderbook.Item{Amount: float64(ob.Size), Price: ob.Price})
continue
@@ -181,7 +181,7 @@ func (b *Bitmex) SubmitOrder(p pair.CurrencyPair, side exchange.OrderSide, order
Side: side.ToString(),
}
if orderType == exchange.Limit {
if orderType == exchange.LimitOrderType {
orderNewParams.Price = price
}
@@ -304,3 +304,84 @@ func (b *Bitmex) GetFeeByType(feeBuilder exchange.FeeBuilder) (float64, error) {
func (b *Bitmex) GetWithdrawCapabilities() uint32 {
return b.GetWithdrawPermissions()
}
// GetActiveOrders retrieves any orders that are active/open
// This function is not concurrency safe due to orderSide/orderType maps
func (b *Bitmex) GetActiveOrders(getOrdersRequest exchange.GetOrdersRequest) ([]exchange.OrderDetail, error) {
var orders []exchange.OrderDetail
params := OrdersRequest{}
params.Filter = "{\"open\":true}"
resp, err := b.GetOrders(params)
if err != nil {
return nil, err
}
for _, order := range resp {
orderSide := orderSideMap[order.Side]
orderType := orderTypeMap[order.OrdType]
if orderType == "" {
orderType = exchange.UnknownOrderType
}
orderDetail := exchange.OrderDetail{
Price: order.Price,
Amount: float64(order.OrderQty),
Exchange: b.Name,
ID: order.OrderID,
OrderSide: orderSide,
OrderType: orderType,
Status: order.OrdStatus,
CurrencyPair: pair.NewCurrencyPairWithDelimiter(order.Symbol, order.SettlCurrency, b.ConfigCurrencyPairFormat.Delimiter),
}
orders = append(orders, orderDetail)
}
exchange.FilterOrdersBySide(&orders, getOrdersRequest.OrderSide)
exchange.FilterOrdersByType(&orders, getOrdersRequest.OrderType)
exchange.FilterOrdersByTickRange(&orders, getOrdersRequest.StartTicks, getOrdersRequest.EndTicks)
exchange.FilterOrdersByCurrencies(&orders, getOrdersRequest.Currencies)
return orders, nil
}
// GetOrderHistory retrieves account order information
// Can Limit response to specific order status
// This function is not concurrency safe due to orderSide/orderType maps
func (b *Bitmex) GetOrderHistory(getOrdersRequest exchange.GetOrdersRequest) ([]exchange.OrderDetail, error) {
var orders []exchange.OrderDetail
params := OrdersRequest{}
resp, err := b.GetOrders(params)
if err != nil {
return nil, err
}
for _, order := range resp {
orderSide := orderSideMap[order.Side]
orderType := orderTypeMap[order.OrdType]
if orderType == "" {
orderType = exchange.UnknownOrderType
}
orderDetail := exchange.OrderDetail{
Price: order.Price,
Amount: float64(order.OrderQty),
Exchange: b.Name,
ID: order.OrderID,
OrderSide: orderSide,
OrderType: orderType,
Status: order.OrdStatus,
CurrencyPair: pair.NewCurrencyPairWithDelimiter(order.Symbol, order.SettlCurrency, b.ConfigCurrencyPairFormat.Delimiter),
}
orders = append(orders, orderDetail)
}
exchange.FilterOrdersBySide(&orders, getOrdersRequest.OrderSide)
exchange.FilterOrdersByType(&orders, getOrdersRequest.OrderType)
exchange.FilterOrdersByTickRange(&orders, getOrdersRequest.StartTicks, getOrdersRequest.EndTicks)
exchange.FilterOrdersByCurrencies(&orders, getOrdersRequest.Currencies)
return orders, nil
}

View File

@@ -339,7 +339,7 @@ func (b *Bitstamp) GetBalance() (Balances, error) {
// GetUserTransactions returns an array of transactions
func (b *Bitstamp) GetUserTransactions(currencyPair string) ([]UserTransactions, error) {
type Response struct {
Date string `json:"datetime"`
Date int64 `json:"datetime"`
TransID int64 `json:"id"`
Type int `json:"type,string"`
USD interface{} `json:"usd"`

View File

@@ -339,7 +339,6 @@ func TestGetUnconfirmedBitcoinDeposits(t *testing.T) {
}
func TestTransferAccountBalance(t *testing.T) {
t.Parallel()
if b.APIKey == "" || b.APISecret == "" ||
b.APIKey == "Key" || b.APISecret == "Secret" {
@@ -356,17 +355,48 @@ func TestTransferAccountBalance(t *testing.T) {
}
func TestFormatWithdrawPermissions(t *testing.T) {
// Arrange
b.SetDefaults()
expectedResult := exchange.AutoWithdrawCryptoText + " & " + exchange.AutoWithdrawFiatText
// Act
withdrawPermissions := b.FormatWithdrawPermissions()
// Assert
if withdrawPermissions != expectedResult {
t.Errorf("Expected: %s, Received: %s", expectedResult, withdrawPermissions)
}
}
func TestGetActiveOrders(t *testing.T) {
b.SetDefaults()
TestSetup(t)
var getOrdersRequest = exchange.GetOrdersRequest{
OrderType: exchange.AnyOrderType,
}
_, err := b.GetActiveOrders(getOrdersRequest)
if areTestAPIKeysSet() && err != nil {
t.Errorf("Could not get open orders: %s", err)
} else if !areTestAPIKeysSet() && err == nil {
t.Error("Expecting an error when no keys are set")
}
}
func TestGetOrderHistory(t *testing.T) {
b.SetDefaults()
TestSetup(t)
var getOrdersRequest = exchange.GetOrdersRequest{
OrderType: exchange.AnyOrderType,
}
_, err := b.GetOrderHistory(getOrdersRequest)
if areTestAPIKeysSet() && err != nil {
t.Errorf("Could not get order history: %s", err)
} else if !areTestAPIKeysSet() && err == nil {
t.Error("Expecting an error when no keys are set")
}
}
// Any tests below this line have the ability to impact your orders on the exchange. Enable canManipulateRealOrders to run them
// ----------------------------------------------------------------------------------------------------------------------------
func areTestAPIKeysSet() bool {
@@ -389,7 +419,7 @@ func TestSubmitOrder(t *testing.T) {
FirstCurrency: symbol.BTC,
SecondCurrency: symbol.USD,
}
response, err := b.SubmitOrder(p, exchange.Buy, exchange.Market, 1, 1, "clientId")
response, err := b.SubmitOrder(p, exchange.BuyOrderSide, exchange.MarketOrderType, 1, 1, "clientId")
if areTestAPIKeysSet() && (err != nil || !response.IsOrderPlaced) {
t.Errorf("Order failed to be placed: %v", err)
} else if !areTestAPIKeysSet() && err == nil {
@@ -398,7 +428,6 @@ func TestSubmitOrder(t *testing.T) {
}
func TestCancelExchangeOrder(t *testing.T) {
// Arrange
b.SetDefaults()
TestSetup(t)
@@ -415,12 +444,9 @@ func TestCancelExchangeOrder(t *testing.T) {
CurrencyPair: currencyPair,
}
// Act
err := b.CancelOrder(orderCancellation)
// Assert
if !areTestAPIKeysSet() && err == nil {
t.Errorf("Expecting an error when no keys are set: %v", err)
t.Error("Expecting an error when no keys are set")
}
if areTestAPIKeysSet() && err != nil {
t.Errorf("Could not cancel orders: %v", err)
@@ -428,7 +454,6 @@ func TestCancelExchangeOrder(t *testing.T) {
}
func TestCancelAllExchangeOrders(t *testing.T) {
// Arrange
b.SetDefaults()
TestSetup(t)
@@ -445,12 +470,10 @@ func TestCancelAllExchangeOrders(t *testing.T) {
CurrencyPair: currencyPair,
}
// Act
resp, err := b.CancelAllOrders(orderCancellation)
// Assert
if !areTestAPIKeysSet() && err == nil {
t.Errorf("Expecting an error when no keys are set: %v", err)
t.Error("Expecting an error when no keys are set")
}
if areTestAPIKeysSet() && err != nil {
t.Errorf("Could not cancel orders: %v", err)
@@ -484,7 +507,7 @@ func TestWithdraw(t *testing.T) {
_, err := b.WithdrawCryptocurrencyFunds(withdrawCryptoRequest)
if !areTestAPIKeysSet() && err == nil {
t.Errorf("Expecting an error when no keys are set: %v", err)
t.Error("Expecting an error when no keys are set")
}
if areTestAPIKeysSet() && err != nil {
t.Errorf("Withdraw failed to be placed: %v", err)
@@ -519,7 +542,7 @@ func TestWithdrawFiat(t *testing.T) {
_, err := b.WithdrawFiatFunds(withdrawFiatRequest)
if !areTestAPIKeysSet() && err == nil {
t.Errorf("Expecting an error when no keys are set: %v", err)
t.Error("Expecting an error when no keys are set")
}
if areTestAPIKeysSet() && err != nil {
t.Errorf("Withdraw failed to be placed: %v", err)
@@ -560,7 +583,7 @@ func TestWithdrawInternationalBank(t *testing.T) {
_, err := b.WithdrawFiatFundsToInternationalBank(withdrawFiatRequest)
if !areTestAPIKeysSet() && err == nil {
t.Errorf("Expecting an error when no keys are set: %v", err)
t.Error("Expecting an error when no keys are set")
}
if areTestAPIKeysSet() && err != nil {
t.Errorf("Withdraw failed to be placed: %v", err)

View File

@@ -77,7 +77,7 @@ type Balances struct {
// UserTransactions holds user transaction information
type UserTransactions struct {
Date string `json:"datetime"`
Date int64 `json:"datetime"`
TransID int64 `json:"id"`
Type int `json:"type,string"`
USD float64 `json:"usd"`
@@ -91,11 +91,12 @@ type UserTransactions struct {
// Order holds current open order data
type Order struct {
ID int64 `json:"id"`
Date string `json:"datetime"`
Type int `json:"type"`
Price float64 `json:"price"`
Amount float64 `json:"amount"`
ID int64 `json:"id"`
Date int64 `json:"datetime"`
Type int `json:"type"`
Price float64 `json:"price"`
Amount float64 `json:"amount"`
Currency string `json:"currency_pair"`
}
// OrderStatus holds order status information

View File

@@ -6,9 +6,11 @@ import (
"strconv"
"strings"
"sync"
"time"
"github.com/thrasher-/gocryptotrader/common"
"github.com/thrasher-/gocryptotrader/currency/pair"
"github.com/thrasher-/gocryptotrader/currency/symbol"
exchange "github.com/thrasher-/gocryptotrader/exchanges"
"github.com/thrasher-/gocryptotrader/exchanges/orderbook"
"github.com/thrasher-/gocryptotrader/exchanges/ticker"
@@ -176,8 +178,8 @@ func (b *Bitstamp) GetExchangeHistory(p pair.CurrencyPair, assetType string) ([]
// SubmitOrder submits a new order
func (b *Bitstamp) SubmitOrder(p pair.CurrencyPair, side exchange.OrderSide, orderType exchange.OrderType, amount, price float64, clientID string) (exchange.SubmitOrderResponse, error) {
var submitOrderResponse exchange.SubmitOrderResponse
buy := side == exchange.Buy
market := orderType == exchange.Market
buy := side == exchange.BuyOrderSide
market := orderType == exchange.MarketOrderType
response, err := b.PlaceOrder(p.Pair().String(), price, amount, buy, market)
if response.ID > 0 {
@@ -289,3 +291,94 @@ func (b *Bitstamp) GetWebsocket() (*exchange.Websocket, error) {
func (b *Bitstamp) GetWithdrawCapabilities() uint32 {
return b.GetWithdrawPermissions()
}
// GetActiveOrders retrieves any orders that are active/open
func (b *Bitstamp) GetActiveOrders(getOrdersRequest exchange.GetOrdersRequest) ([]exchange.OrderDetail, error) {
var orders []exchange.OrderDetail
var currPair string
if len(getOrdersRequest.Currencies) != 1 {
currPair = "all"
} else {
currPair = getOrdersRequest.Currencies[0].Pair().String()
}
resp, err := b.GetOpenOrders(currPair)
if err != nil {
return nil, err
}
for _, order := range resp {
symbolOne := order.Currency[0:3]
symbolTwo := order.Currency[len(order.Currency)-3:]
orderDate := time.Unix(order.Date, 0)
orders = append(orders, exchange.OrderDetail{
Amount: order.Amount,
ID: fmt.Sprintf("%v", order.ID),
Price: order.Price,
OrderDate: orderDate,
CurrencyPair: pair.NewCurrencyPair(symbolOne, symbolTwo),
Exchange: b.Name,
})
}
exchange.FilterOrdersByTickRange(&orders, getOrdersRequest.StartTicks, getOrdersRequest.EndTicks)
exchange.FilterOrdersByCurrencies(&orders, getOrdersRequest.Currencies)
return orders, nil
}
// GetOrderHistory retrieves account order information
// Can Limit response to specific order status
func (b *Bitstamp) GetOrderHistory(getOrdersRequest exchange.GetOrdersRequest) ([]exchange.OrderDetail, error) {
var currPair string
if len(getOrdersRequest.Currencies) == 1 {
currPair = getOrdersRequest.Currencies[0].Pair().String()
}
resp, err := b.GetUserTransactions(currPair)
if err != nil {
return nil, err
}
var orders []exchange.OrderDetail
for _, order := range resp {
if order.Type == 2 {
quoteCurrency := ""
baseCurrency := ""
if order.BTC > 0 {
baseCurrency = symbol.BTC
} else if order.XRP > 0 {
baseCurrency = symbol.XRP
} else {
log.Warnf("No quote currency found for OrderID '%v'", order.OrderID)
}
if order.USD > 0 {
quoteCurrency = symbol.USD
} else if order.EUR > 0 {
quoteCurrency = symbol.EUR
} else {
log.Warnf("No quote currency found for OrderID '%v'", order.OrderID)
}
var currPair pair.CurrencyPair
if quoteCurrency != "" && baseCurrency != "" {
currPair = pair.NewCurrencyPairWithDelimiter(baseCurrency, quoteCurrency, b.ConfigCurrencyPairFormat.Delimiter)
}
orderDate := time.Unix(order.Date, 0)
orders = append(orders, exchange.OrderDetail{
ID: fmt.Sprintf("%v", order.OrderID),
OrderDate: orderDate,
Exchange: b.Name,
CurrencyPair: currPair,
})
}
}
exchange.FilterOrdersByTickRange(&orders, getOrdersRequest.StartTicks, getOrdersRequest.EndTicks)
exchange.FilterOrdersByCurrencies(&orders, getOrdersRequest.Currencies)
return orders, nil
}

View File

@@ -422,9 +422,9 @@ func (b *Bittrex) GetOrder(uuid string) (Order, error) {
return order, nil
}
// GetOrderHistory is used to retrieve your order history. If currencyPair
// GetOrderHistoryForCurrency is used to retrieve your order history. If currencyPair
// omitted it will return the entire order History.
func (b *Bittrex) GetOrderHistory(currencyPair string) (Order, error) {
func (b *Bittrex) GetOrderHistoryForCurrency(currencyPair string) (Order, error) {
var orders Order
values := url.Values{}

View File

@@ -181,14 +181,14 @@ func TestGetOrder(t *testing.T) {
}
}
func TestGetOrderHistory(t *testing.T) {
func TestGetOrderHistoryForCurrency(t *testing.T) {
t.Parallel()
_, err := b.GetOrderHistory("")
_, err := b.GetOrderHistoryForCurrency("")
if err == nil {
t.Error("Test Failed - Bittrex - GetOrderHistory() error")
}
_, err = b.GetOrderHistory("btc-ltc")
_, err = b.GetOrderHistoryForCurrency("btc-ltc")
if err == nil {
t.Error("Test Failed - Bittrex - GetOrderHistory() error")
}
@@ -305,17 +305,51 @@ func TestGetFee(t *testing.T) {
}
func TestFormatWithdrawPermissions(t *testing.T) {
// Arrange
b.SetDefaults()
expectedResult := exchange.AutoWithdrawCryptoWithAPIPermissionText + " & " + exchange.NoFiatWithdrawalsText
// Act
withdrawPermissions := b.FormatWithdrawPermissions()
// Assert
if withdrawPermissions != expectedResult {
t.Errorf("Expected: %s, Received: %s", expectedResult, withdrawPermissions)
}
}
func TestGetActiveOrders(t *testing.T) {
b.SetDefaults()
TestSetup(t)
var getOrdersRequest = exchange.GetOrdersRequest{
OrderType: exchange.AnyOrderType,
Currencies: []pair.CurrencyPair{pair.NewCurrencyPair(symbol.BTC, symbol.LTC)},
}
getOrdersRequest.Currencies[0].Delimiter = "-"
_, err := b.GetActiveOrders(getOrdersRequest)
if areTestAPIKeysSet() && err != nil {
t.Errorf("Could not get open orders: %s", err)
} else if !areTestAPIKeysSet() && err == nil {
t.Error("Expecting an error when no keys are set")
}
}
func TestGetOrderHistory(t *testing.T) {
b.SetDefaults()
TestSetup(t)
var getOrdersRequest = exchange.GetOrdersRequest{
OrderType: exchange.AnyOrderType,
}
_, err := b.GetOrderHistory(getOrdersRequest)
if areTestAPIKeysSet() && err != nil {
t.Errorf("Could not get order history: %s", err)
} else if !areTestAPIKeysSet() && err == nil {
t.Error("Expecting an error when no keys are set")
}
}
// Any tests below this line have the ability to impact your orders on the exchange. Enable canManipulateRealOrders to run them
// ----------------------------------------------------------------------------------------------------------------------------
func areTestAPIKeysSet() bool {
@@ -339,7 +373,7 @@ func TestSubmitOrder(t *testing.T) {
FirstCurrency: symbol.BTC,
SecondCurrency: symbol.LTC,
}
response, err := b.SubmitOrder(p, exchange.Buy, exchange.Limit, 1, 1, "clientId")
response, err := b.SubmitOrder(p, exchange.BuyOrderSide, exchange.LimitOrderType, 1, 1, "clientId")
if areTestAPIKeysSet() && (err != nil || !response.IsOrderPlaced) {
t.Errorf("Order failed to be placed: %v", err)
} else if !areTestAPIKeysSet() && err == nil {
@@ -348,7 +382,6 @@ func TestSubmitOrder(t *testing.T) {
}
func TestCancelExchangeOrder(t *testing.T) {
// Arrange
b.SetDefaults()
TestSetup(t)
@@ -365,12 +398,9 @@ func TestCancelExchangeOrder(t *testing.T) {
CurrencyPair: currencyPair,
}
// Act
err := b.CancelOrder(orderCancellation)
// Assert
if !areTestAPIKeysSet() && err == nil {
t.Errorf("Expecting an error when no keys are set: %v", err)
t.Error("Expecting an error when no keys are set")
}
if areTestAPIKeysSet() && err != nil {
t.Errorf("Could not cancel orders: %v", err)
@@ -378,7 +408,6 @@ func TestCancelExchangeOrder(t *testing.T) {
}
func TestCancelAllExchangeOrders(t *testing.T) {
// Arrange
b.SetDefaults()
TestSetup(t)
@@ -395,12 +424,10 @@ func TestCancelAllExchangeOrders(t *testing.T) {
CurrencyPair: currencyPair,
}
// Act
resp, err := b.CancelAllOrders(orderCancellation)
// Assert
if !areTestAPIKeysSet() && err == nil {
t.Errorf("Expecting an error when no keys are set: %v", err)
t.Error("Expecting an error when no keys are set")
}
if areTestAPIKeysSet() && err != nil {
t.Errorf("Could not cancel orders: %v", err)
@@ -434,7 +461,7 @@ func TestWithdraw(t *testing.T) {
_, err := b.WithdrawCryptocurrencyFunds(withdrawCryptoRequest)
if !areTestAPIKeysSet() && err == nil {
t.Errorf("Expecting an error when no keys are set: %v", err)
t.Error("Expecting an error when no keys are set")
}
if areTestAPIKeysSet() && err != nil {
t.Errorf("Withdraw failed to be placed: %v", err)

View File

@@ -183,6 +183,9 @@ type Order struct {
IsConditional bool `json:"IsConditional"`
Condition string `json:"Condition"`
ConditionTarget string `json:"ConditionTarget"`
// Below Used in OrderHistory
TimeStamp string `json:"TimeStamp"`
Commission float64 `json:"Commission"`
} `json:"result"`
}

View File

@@ -3,7 +3,9 @@ package bittrex
import (
"errors"
"fmt"
"strings"
"sync"
"time"
"github.com/thrasher-/gocryptotrader/common"
"github.com/thrasher-/gocryptotrader/currency/pair"
@@ -178,11 +180,11 @@ func (b *Bittrex) GetExchangeHistory(p pair.CurrencyPair, assetType string) ([]e
// SubmitOrder submits a new order
func (b *Bittrex) SubmitOrder(p pair.CurrencyPair, side exchange.OrderSide, orderType exchange.OrderType, amount, price float64, clientID string) (exchange.SubmitOrderResponse, error) {
var submitOrderResponse exchange.SubmitOrderResponse
buy := side == exchange.Buy
buy := side == exchange.BuyOrderSide
var response UUID
var err error
if orderType != exchange.Limit {
if orderType != exchange.LimitOrderType {
return submitOrderResponse, errors.New("not supported on exchange")
}
@@ -286,3 +288,89 @@ func (b *Bittrex) GetFeeByType(feeBuilder exchange.FeeBuilder) (float64, error)
func (b *Bittrex) GetWithdrawCapabilities() uint32 {
return b.GetWithdrawPermissions()
}
// GetActiveOrders retrieves any orders that are active/open
func (b *Bittrex) GetActiveOrders(getOrdersRequest exchange.GetOrdersRequest) ([]exchange.OrderDetail, error) {
var currPair string
if len(getOrdersRequest.Currencies) == 1 {
currPair = getOrdersRequest.Currencies[0].Pair().String()
}
resp, err := b.GetOpenOrders(currPair)
if err != nil {
return nil, err
}
var orders []exchange.OrderDetail
for _, order := range resp.Result {
orderDate, err := time.Parse(time.RFC3339, order.Opened)
if err != nil {
log.Warnf("Exchange %v Func %v Order %v Could not parse date to unix with value of %v",
b.Name, "GetActiveOrders", order.OrderUUID, order.Opened)
}
currency := pair.NewCurrencyPairDelimiter(order.Exchange, b.ConfigCurrencyPairFormat.Delimiter)
orderType := exchange.OrderType(strings.ToUpper(order.Type))
orders = append(orders, exchange.OrderDetail{
Amount: order.Quantity,
RemainingAmount: order.QuantityRemaining,
Price: order.Price,
OrderDate: orderDate,
ID: order.OrderUUID,
Exchange: b.Name,
OrderType: orderType,
CurrencyPair: currency,
})
}
exchange.FilterOrdersByType(&orders, getOrdersRequest.OrderType)
exchange.FilterOrdersByTickRange(&orders, getOrdersRequest.StartTicks, getOrdersRequest.EndTicks)
exchange.FilterOrdersByCurrencies(&orders, getOrdersRequest.Currencies)
return orders, nil
}
// GetOrderHistory retrieves account order information
// Can Limit response to specific order status
func (b *Bittrex) GetOrderHistory(getOrdersRequest exchange.GetOrdersRequest) ([]exchange.OrderDetail, error) {
var currPair string
if len(getOrdersRequest.Currencies) == 1 {
currPair = getOrdersRequest.Currencies[0].Pair().String()
}
resp, err := b.GetOrderHistoryForCurrency(currPair)
if err != nil {
return nil, err
}
var orders []exchange.OrderDetail
for _, order := range resp.Result {
orderDate, err := time.Parse(time.RFC3339, order.TimeStamp)
if err != nil {
log.Warnf("Exchange %v Func %v Order %v Could not parse date to unix with value of %v",
b.Name, "GetActiveOrders", order.OrderUUID, order.Opened)
}
currency := pair.NewCurrencyPairDelimiter(order.Exchange, b.ConfigCurrencyPairFormat.Delimiter)
orderType := exchange.OrderType(strings.ToUpper(order.Type))
orders = append(orders, exchange.OrderDetail{
Amount: order.Quantity,
RemainingAmount: order.QuantityRemaining,
Price: order.Price,
OrderDate: orderDate,
ID: order.OrderUUID,
Exchange: b.Name,
OrderType: orderType,
Fee: order.Commission,
CurrencyPair: currency,
})
}
exchange.FilterOrdersByType(&orders, getOrdersRequest.OrderType)
exchange.FilterOrdersByTickRange(&orders, getOrdersRequest.StartTicks, getOrdersRequest.EndTicks)
exchange.FilterOrdersByCurrencies(&orders, getOrdersRequest.Currencies)
return orders, nil
}

View File

@@ -161,17 +161,48 @@ func TestGetFee(t *testing.T) {
}
func TestFormatWithdrawPermissions(t *testing.T) {
// Arrange
b.SetDefaults()
expectedResult := exchange.NoAPIWithdrawalMethodsText
// Act
withdrawPermissions := b.FormatWithdrawPermissions()
// Assert
if withdrawPermissions != expectedResult {
t.Errorf("Expected: %s, Received: %s", expectedResult, withdrawPermissions)
}
}
func TestGetActiveOrders(t *testing.T) {
b.SetDefaults()
TestSetup(t)
var getOrdersRequest = exchange.GetOrdersRequest{
OrderType: exchange.AnyOrderType,
}
_, err := b.GetActiveOrders(getOrdersRequest)
if areTestAPIKeysSet() && err != nil {
t.Errorf("Could not get open orders: %s", err)
} else if !areTestAPIKeysSet() && err == nil {
t.Error("Expecting an error when no keys are set")
}
}
func TestGetOrderHistory(t *testing.T) {
b.SetDefaults()
TestSetup(t)
var getOrdersRequest = exchange.GetOrdersRequest{
OrderType: exchange.AnyOrderType,
}
_, err := b.GetOrderHistory(getOrdersRequest)
if areTestAPIKeysSet() && err != nil {
t.Errorf("Could not get order history: %s", err)
} else if !areTestAPIKeysSet() && err == nil {
t.Error("Expecting an error when no keys are set")
}
}
// Any tests below this line have the ability to impact your orders on the exchange. Enable canManipulateRealOrders to run them
// ----------------------------------------------------------------------------------------------------------------------------
func areTestAPIKeysSet() bool {
@@ -195,14 +226,13 @@ func TestSubmitOrder(t *testing.T) {
FirstCurrency: symbol.BTC,
SecondCurrency: symbol.LTC,
}
_, err := b.SubmitOrder(p, exchange.Buy, exchange.Limit, 1, 1, "clientId")
_, err := b.SubmitOrder(p, exchange.BuyOrderSide, exchange.LimitOrderType, 1, 1, "clientId")
if err != common.ErrNotYetImplemented {
t.Errorf("Expected 'Not Yet Implemented', received %v", err)
}
}
func TestCancelExchangeOrder(t *testing.T) {
// Arrange
b.SetDefaults()
TestSetup(t)
@@ -219,17 +249,13 @@ func TestCancelExchangeOrder(t *testing.T) {
CurrencyPair: currencyPair,
}
// Act
err := b.CancelOrder(orderCancellation)
// Assert
if err != common.ErrNotYetImplemented {
t.Errorf("Expected 'Not Yet Implemented', received %v", err)
}
}
func TestCancelAllExchangeOrders(t *testing.T) {
// Arrange
b.SetDefaults()
TestSetup(t)
@@ -246,10 +272,8 @@ func TestCancelAllExchangeOrders(t *testing.T) {
CurrencyPair: currencyPair,
}
// Act
_, err := b.CancelAllOrders(orderCancellation)
// Assert
if err != common.ErrNotYetImplemented {
t.Errorf("Expected 'Not Yet Implemented', received %v", err)
}

View File

@@ -216,3 +216,14 @@ func (b *BTCC) GetFeeByType(feeBuilder exchange.FeeBuilder) (float64, error) {
func (b *BTCC) GetWithdrawCapabilities() uint32 {
return b.GetWithdrawPermissions()
}
// GetActiveOrders retrieves any orders that are active/open
func (b *BTCC) GetActiveOrders(getOrdersRequest exchange.GetOrdersRequest) ([]exchange.OrderDetail, error) {
return nil, common.ErrNotYetImplemented
}
// GetOrderHistory retrieves account order information
// Can Limit response to specific order status
func (b *BTCC) GetOrderHistory(getOrdersRequest exchange.GetOrdersRequest) ([]exchange.OrderDetail, error) {
return nil, common.ErrNotYetImplemented
}

View File

@@ -267,17 +267,18 @@ func (b *BTCMarkets) GetOrders(currency, instrument string, limit, since int64,
return nil, errors.New(resp.ErrorMessage)
}
for i := range resp.Orders {
resp.Orders[i].Price = resp.Orders[i].Price / common.SatoshisPerBTC
resp.Orders[i].OpenVolume = resp.Orders[i].OpenVolume / common.SatoshisPerBTC
resp.Orders[i].Volume = resp.Orders[i].Volume / common.SatoshisPerBTC
for _, order := range resp.Orders {
order.Price = order.Price / common.SatoshisPerBTC
order.OpenVolume = order.OpenVolume / common.SatoshisPerBTC
order.Volume = order.Volume / common.SatoshisPerBTC
for x := range resp.Orders[i].Trades {
resp.Orders[i].Trades[x].Fee = resp.Orders[i].Trades[x].Fee / common.SatoshisPerBTC
resp.Orders[i].Trades[x].Price = resp.Orders[i].Trades[x].Price / common.SatoshisPerBTC
resp.Orders[i].Trades[x].Volume = resp.Orders[i].Trades[x].Volume / common.SatoshisPerBTC
for _, trade := range order.Trades {
trade.Fee = trade.Fee / common.SatoshisPerBTC
trade.Price = trade.Price / common.SatoshisPerBTC
trade.Volume = trade.Volume / common.SatoshisPerBTC
}
}
return resp.Orders, nil
}
@@ -300,6 +301,18 @@ func (b *BTCMarkets) GetOpenOrders() ([]Order, error) {
return nil, errors.New(resp.ErrorMessage)
}
for _, order := range resp.Orders {
order.Price = order.Price / common.SatoshisPerBTC
order.OpenVolume = order.OpenVolume / common.SatoshisPerBTC
order.Volume = order.Volume / common.SatoshisPerBTC
for _, trade := range order.Trades {
trade.Fee = trade.Fee / common.SatoshisPerBTC
trade.Price = trade.Price / common.SatoshisPerBTC
trade.Volume = trade.Volume / common.SatoshisPerBTC
}
}
return resp.Orders, nil
}

View File

@@ -31,12 +31,9 @@ func TestSetup(t *testing.T) {
if err != nil {
t.Error("Test Failed - BTC Markets Setup() init error")
}
if areTestAPIKeysSet() {
bConfig.APIKey = apiKey
bConfig.APISecret = apiSecret
bConfig.AuthenticatedAPISupport = true
}
bConfig.APIKey = apiKey
bConfig.APISecret = apiSecret
bConfig.AuthenticatedAPISupport = true
b.Setup(bConfig)
}
@@ -155,7 +152,6 @@ func TestGetFundingHistory(t *testing.T) {
}
func TestCancelOrder(t *testing.T) {
_, err := b.CancelExistingOrder([]int64{1337})
if err == nil {
@@ -266,17 +262,49 @@ func TestGetFee(t *testing.T) {
}
func TestFormatWithdrawPermissions(t *testing.T) {
// Arrange
b.SetDefaults()
expectedResult := exchange.AutoWithdrawCryptoText + " & " + exchange.AutoWithdrawFiatText
// Act
withdrawPermissions := b.FormatWithdrawPermissions()
// Assert
if withdrawPermissions != expectedResult {
t.Errorf("Expected: %s, Received: %s", expectedResult, withdrawPermissions)
}
}
func TestGetActiveOrders(t *testing.T) {
b.SetDefaults()
TestSetup(t)
var getOrdersRequest = exchange.GetOrdersRequest{
OrderType: exchange.AnyOrderType,
}
_, err := b.GetActiveOrders(getOrdersRequest)
if areTestAPIKeysSet() && err != nil {
t.Errorf("Could not get open orders: %s", err)
} else if !areTestAPIKeysSet() && err == nil {
t.Error("Expecting an error when no keys are set")
}
}
func TestGetOrderHistory(t *testing.T) {
b.SetDefaults()
TestSetup(t)
var getOrdersRequest = exchange.GetOrdersRequest{
OrderType: exchange.AnyOrderType,
Currencies: []pair.CurrencyPair{pair.NewCurrencyPair(symbol.BTC, symbol.LTC)},
}
_, err := b.GetOrderHistory(getOrdersRequest)
if areTestAPIKeysSet() && err != nil {
t.Errorf("Could not get order history: %s", err)
} else if !areTestAPIKeysSet() && err == nil {
t.Error("Expecting an error when no keys are set")
}
}
// Any tests below this line have the ability to impact your orders on the exchange. Enable canManipulateRealOrders to run them
// ----------------------------------------------------------------------------------------------------------------------------
func areTestAPIKeysSet() bool {
@@ -300,7 +328,7 @@ func TestSubmitOrder(t *testing.T) {
FirstCurrency: symbol.BTC,
SecondCurrency: symbol.LTC,
}
response, err := b.SubmitOrder(p, exchange.Buy, exchange.Limit, 1, 1, "clientId")
response, err := b.SubmitOrder(p, exchange.BuyOrderSide, exchange.LimitOrderType, 1, 1, "clientId")
if areTestAPIKeysSet() && (err != nil || !response.IsOrderPlaced) {
t.Errorf("Order failed to be placed: %v", err)
} else if !areTestAPIKeysSet() && err == nil {
@@ -309,7 +337,6 @@ func TestSubmitOrder(t *testing.T) {
}
func TestCancelExchangeOrder(t *testing.T) {
// Arrange
b.SetDefaults()
TestSetup(t)
@@ -326,12 +353,9 @@ func TestCancelExchangeOrder(t *testing.T) {
CurrencyPair: currencyPair,
}
// Act
err := b.CancelOrder(orderCancellation)
// Assert
if !areTestAPIKeysSet() && err == nil {
t.Errorf("Expecting an error when no keys are set: %v", err)
t.Error("Expecting an error when no keys are set")
}
if areTestAPIKeysSet() && err != nil {
t.Errorf("Could not cancel orders: %v", err)
@@ -339,7 +363,6 @@ func TestCancelExchangeOrder(t *testing.T) {
}
func TestCancelAllExchangeOrders(t *testing.T) {
// Arrange
b.SetDefaults()
TestSetup(t)
@@ -356,12 +379,10 @@ func TestCancelAllExchangeOrders(t *testing.T) {
CurrencyPair: currencyPair,
}
// Act
resp, err := b.CancelAllOrders(orderCancellation)
// Assert
if !areTestAPIKeysSet() && err == nil {
t.Errorf("Expecting an error when no keys are set: %v", err)
t.Error("Expecting an error when no keys are set")
}
if areTestAPIKeysSet() && err != nil {
t.Errorf("Could not cancel orders: %v", err)
@@ -395,7 +416,7 @@ func TestWithdraw(t *testing.T) {
_, err := b.WithdrawCryptocurrencyFunds(withdrawCryptoRequest)
if !areTestAPIKeysSet() && err == nil {
t.Errorf("Expecting an error when no keys are set: %v", err)
t.Error("Expecting an error when no keys are set")
}
if areTestAPIKeysSet() && err != nil {
t.Errorf("Withdraw failed to be placed: %v", err)
@@ -428,7 +449,7 @@ func TestWithdrawFiat(t *testing.T) {
_, err := b.WithdrawFiatFunds(withdrawFiatRequest)
if !areTestAPIKeysSet() && err == nil {
t.Errorf("Expecting an error when no keys are set: %v", err)
t.Error("Expecting an error when no keys are set")
}
if areTestAPIKeysSet() && err != nil {
t.Errorf("Withdraw failed to be placed: %v", err)

View File

@@ -4,7 +4,9 @@ import (
"errors"
"fmt"
"strconv"
"strings"
"sync"
"time"
"github.com/thrasher-/gocryptotrader/common"
"github.com/thrasher-/gocryptotrader/currency/pair"
@@ -245,17 +247,25 @@ func (b *BTCMarkets) GetOrderInfo(orderID int64) (exchange.OrderDetail, error) {
}
for _, order := range orders {
var side exchange.OrderSide
if strings.EqualFold(order.OrderSide, exchange.AskOrderSide.ToString()) {
side = exchange.SellOrderSide
} else if strings.EqualFold(order.OrderSide, exchange.BidOrderSide.ToString()) {
side = exchange.BuyOrderSide
}
orderDate := time.Unix(int64(order.CreationTime), 0)
orderType := exchange.OrderType(strings.ToUpper(order.OrderType))
OrderDetail.Amount = order.Volume
OrderDetail.BaseCurrency = order.Currency
OrderDetail.CreationTime = int64(order.CreationTime)
OrderDetail.OrderDate = orderDate
OrderDetail.Exchange = b.GetName()
OrderDetail.ID = order.ID
OrderDetail.OpenVolume = order.OpenVolume
OrderDetail.OrderSide = order.OrderSide
OrderDetail.OrderType = order.OrderType
OrderDetail.RemainingAmount = order.OpenVolume
OrderDetail.OrderSide = side
OrderDetail.OrderType = orderType
OrderDetail.Price = order.Price
OrderDetail.QuoteCurrency = order.Instrument
OrderDetail.Status = order.Status
OrderDetail.CurrencyPair = pair.NewCurrencyPairWithDelimiter(order.Instrument, order.Currency, b.ConfigCurrencyPairFormat.Delimiter)
}
return OrderDetail, nil
@@ -300,3 +310,120 @@ func (b *BTCMarkets) GetFeeByType(feeBuilder exchange.FeeBuilder) (float64, erro
func (b *BTCMarkets) GetWithdrawCapabilities() uint32 {
return b.GetWithdrawPermissions()
}
// GetActiveOrders retrieves any orders that are active/open
func (b *BTCMarkets) GetActiveOrders(getOrdersRequest exchange.GetOrdersRequest) ([]exchange.OrderDetail, error) {
resp, err := b.GetOpenOrders()
if err != nil {
return nil, err
}
var orders []exchange.OrderDetail
for _, order := range resp {
var side exchange.OrderSide
if strings.EqualFold(order.OrderSide, exchange.AskOrderSide.ToString()) {
side = exchange.SellOrderSide
} else if strings.EqualFold(order.OrderSide, exchange.BidOrderSide.ToString()) {
side = exchange.BuyOrderSide
}
orderDate := time.Unix(int64(order.CreationTime), 0)
orderType := exchange.OrderType(strings.ToUpper(order.OrderType))
openOrder := exchange.OrderDetail{
ID: order.ID,
Amount: order.Volume,
Exchange: b.Name,
RemainingAmount: order.OpenVolume,
OrderDate: orderDate,
OrderSide: side,
OrderType: orderType,
Price: order.Price,
Status: order.Status,
CurrencyPair: pair.NewCurrencyPairWithDelimiter(order.Instrument, order.Currency, b.ConfigCurrencyPairFormat.Delimiter),
}
for _, trade := range order.Trades {
tradeDate := time.Unix(int64(trade.CreationTime), 0)
openOrder.Trades = append(openOrder.Trades, exchange.TradeHistory{
Amount: trade.Volume,
Exchange: b.Name,
Price: trade.Price,
TID: trade.ID,
Timestamp: tradeDate,
Fee: trade.Fee,
Description: trade.Description,
})
}
orders = append(orders, openOrder)
}
exchange.FilterOrdersByType(&orders, getOrdersRequest.OrderType)
exchange.FilterOrdersByTickRange(&orders, getOrdersRequest.StartTicks, getOrdersRequest.EndTicks)
exchange.FilterOrdersBySide(&orders, getOrdersRequest.OrderSide)
return orders, nil
}
// GetOrderHistory retrieves account order information
// Can Limit response to specific order status
func (b *BTCMarkets) GetOrderHistory(getOrdersRequest exchange.GetOrdersRequest) ([]exchange.OrderDetail, error) {
if len(getOrdersRequest.Currencies) <= 0 {
return nil, errors.New("Requires at least one currency pair to retrieve history")
}
var respOrders []Order
for _, currency := range getOrdersRequest.Currencies {
resp, err := b.GetOrders(currency.FirstCurrency.String(), currency.SecondCurrency.String(), 200, 0, true)
if err != nil {
return nil, err
}
respOrders = append(respOrders, resp...)
}
var orders []exchange.OrderDetail
for _, order := range respOrders {
var side exchange.OrderSide
if strings.EqualFold(order.OrderSide, exchange.AskOrderSide.ToString()) {
side = exchange.SellOrderSide
} else if strings.EqualFold(order.OrderSide, exchange.BidOrderSide.ToString()) {
side = exchange.BuyOrderSide
}
orderDate := time.Unix(int64(order.CreationTime), 0)
orderType := exchange.OrderType(strings.ToUpper(order.OrderType))
openOrder := exchange.OrderDetail{
ID: order.ID,
Amount: order.Volume,
Exchange: b.Name,
RemainingAmount: order.OpenVolume,
OrderDate: orderDate,
OrderSide: side,
OrderType: orderType,
Price: order.Price,
Status: order.Status,
CurrencyPair: pair.NewCurrencyPairWithDelimiter(order.Instrument, order.Currency, b.ConfigCurrencyPairFormat.Delimiter),
}
for _, trade := range order.Trades {
tradeDate := time.Unix(int64(trade.CreationTime), 0)
openOrder.Trades = append(openOrder.Trades, exchange.TradeHistory{
Amount: trade.Volume,
Exchange: b.Name,
Price: trade.Price,
TID: trade.ID,
Timestamp: tradeDate,
Fee: trade.Fee,
Description: trade.Description,
})
}
orders = append(orders, openOrder)
}
exchange.FilterOrdersByType(&orders, getOrdersRequest.OrderType)
exchange.FilterOrdersByTickRange(&orders, getOrdersRequest.StartTicks, getOrdersRequest.EndTicks)
exchange.FilterOrdersBySide(&orders, getOrdersRequest.OrderSide)
return orders, nil
}

View File

@@ -396,17 +396,51 @@ func TestCalculateTradingFee(t *testing.T) {
}
func TestFormatWithdrawPermissions(t *testing.T) {
// Arrange
c.SetDefaults()
expectedResult := exchange.AutoWithdrawCryptoWithAPIPermissionText + " & " + exchange.AutoWithdrawFiatWithAPIPermissionText
// Act
withdrawPermissions := c.FormatWithdrawPermissions()
// Assert
if withdrawPermissions != expectedResult {
t.Errorf("Expected: %s, Received: %s", expectedResult, withdrawPermissions)
}
}
func TestGetActiveOrders(t *testing.T) {
c.SetDefaults()
TestSetup(t)
var getOrdersRequest = exchange.GetOrdersRequest{
OrderType: exchange.AnyOrderType,
Currencies: []pair.CurrencyPair{pair.NewCurrencyPair(symbol.BTC, symbol.LTC)},
}
_, err := c.GetActiveOrders(getOrdersRequest)
if areTestAPIKeysSet() && err != nil {
t.Errorf("Could not get open orders: %s", err)
} else if !areTestAPIKeysSet() && err == nil {
t.Error("Expecting an error when no keys are set")
}
}
func TestGetOrderHistory(t *testing.T) {
c.SetDefaults()
TestSetup(t)
var getOrdersRequest = exchange.GetOrdersRequest{
OrderType: exchange.AnyOrderType,
Currencies: []pair.CurrencyPair{pair.NewCurrencyPair(symbol.BTC, symbol.LTC)},
}
_, err := c.GetOrderHistory(getOrdersRequest)
if areTestAPIKeysSet() && err != nil {
t.Errorf("Could not get order history: %s", err)
} else if !areTestAPIKeysSet() && err == nil {
t.Error("Expecting an error when no keys are set")
}
}
// Any tests below this line have the ability to impact your orders on the exchange. Enable canManipulateRealOrders to run them
// ----------------------------------------------------------------------------------------------------------------------------
func areTestAPIKeysSet() bool {
@@ -430,7 +464,7 @@ func TestSubmitOrder(t *testing.T) {
FirstCurrency: symbol.BTC,
SecondCurrency: symbol.LTC,
}
response, err := c.SubmitOrder(p, exchange.Buy, exchange.Limit, 1, 1, "clientId")
response, err := c.SubmitOrder(p, exchange.BuyOrderSide, exchange.LimitOrderType, 1, 1, "clientId")
if areTestAPIKeysSet() && (err != nil || !response.IsOrderPlaced) {
t.Errorf("Order failed to be placed: %v", err)
} else if !areTestAPIKeysSet() && err == nil {
@@ -439,7 +473,7 @@ func TestSubmitOrder(t *testing.T) {
}
func TestCancelExchangeOrder(t *testing.T) {
// Arrange
c.SetDefaults()
TestSetup(t)
@@ -456,12 +490,9 @@ func TestCancelExchangeOrder(t *testing.T) {
CurrencyPair: currencyPair,
}
// Act
err := c.CancelOrder(orderCancellation)
// Assert
if !areTestAPIKeysSet() && err == nil {
t.Errorf("Expecting an error when no keys are set: %v", err)
t.Error("Expecting an error when no keys are set")
}
if areTestAPIKeysSet() && err != nil {
t.Errorf("Could not cancel orders: %v", err)
@@ -469,7 +500,7 @@ func TestCancelExchangeOrder(t *testing.T) {
}
func TestCancelAllExchangeOrders(t *testing.T) {
// Arrange
c.SetDefaults()
TestSetup(t)
@@ -486,12 +517,10 @@ func TestCancelAllExchangeOrders(t *testing.T) {
CurrencyPair: currencyPair,
}
// Act
resp, err := c.CancelAllOrders(orderCancellation)
// Assert
if !areTestAPIKeysSet() && err == nil {
t.Errorf("Expecting an error when no keys are set: %v", err)
t.Error("Expecting an error when no keys are set")
}
if areTestAPIKeysSet() && err != nil {
t.Errorf("Could not cancel orders: %v", err)
@@ -525,7 +554,7 @@ func TestWithdraw(t *testing.T) {
_, err := c.WithdrawCryptocurrencyFunds(withdrawCryptoRequest)
if !areTestAPIKeysSet() && err == nil {
t.Errorf("Expecting an error when no keys are set: %v", err)
t.Error("Expecting an error when no keys are set")
}
if areTestAPIKeysSet() && err != nil {
t.Errorf("Withdraw failed to be placed: %v", err)
@@ -548,7 +577,7 @@ func TestWithdrawFiat(t *testing.T) {
_, err := c.WithdrawFiatFunds(withdrawFiatRequest)
if !areTestAPIKeysSet() && err == nil {
t.Errorf("Expecting an error when no keys are set: %v", err)
t.Error("Expecting an error when no keys are set")
}
if areTestAPIKeysSet() && err != nil {
t.Errorf("Withdraw failed to be placed: %v", err)
@@ -571,7 +600,7 @@ func TestWithdrawInternationalBank(t *testing.T) {
_, err := c.WithdrawFiatFundsToInternationalBank(withdrawFiatRequest)
if !areTestAPIKeysSet() && err == nil {
t.Errorf("Expecting an error when no keys are set: %v", err)
t.Error("Expecting an error when no keys are set")
}
if areTestAPIKeysSet() && err != nil {
t.Errorf("Withdraw failed to be placed: %v", err)

View File

@@ -3,7 +3,9 @@ package coinbasepro
import (
"errors"
"fmt"
"strings"
"sync"
"time"
"github.com/thrasher-/gocryptotrader/common"
"github.com/thrasher-/gocryptotrader/currency/pair"
@@ -156,10 +158,10 @@ func (c *CoinbasePro) SubmitOrder(p pair.CurrencyPair, side exchange.OrderSide,
var submitOrderResponse exchange.SubmitOrderResponse
var response string
var err error
if orderType == exchange.Market {
if orderType == exchange.MarketOrderType {
response, err = c.PlaceMarginOrder("", amount, amount, side.ToString(), p.Pair().String(), "")
} else if orderType == exchange.Limit {
} else if orderType == exchange.LimitOrderType {
response, err = c.PlaceLimitOrder("", price, amount, side.ToString(), "", "", p.Pair().String(), "", false)
} else {
err = errors.New("not supported")
@@ -259,3 +261,86 @@ func (c *CoinbasePro) GetFeeByType(feeBuilder exchange.FeeBuilder) (float64, err
func (c *CoinbasePro) GetWithdrawCapabilities() uint32 {
return c.GetWithdrawPermissions()
}
// GetActiveOrders retrieves any orders that are active/open
func (c *CoinbasePro) GetActiveOrders(getOrdersRequest exchange.GetOrdersRequest) ([]exchange.OrderDetail, error) {
var respOrders []GeneralizedOrderResponse
for _, currency := range getOrdersRequest.Currencies {
resp, err := c.GetOrders([]string{"open", "pending", "active"}, exchange.FormatExchangeCurrency(c.Name, currency).String())
if err != nil {
return nil, err
}
respOrders = append(respOrders, resp...)
}
var orders []exchange.OrderDetail
for _, order := range respOrders {
currency := pair.NewCurrencyPairDelimiter(order.ProductID, c.ConfigCurrencyPairFormat.Delimiter)
orderSide := exchange.OrderSide(strings.ToUpper(order.Side))
orderType := exchange.OrderType(strings.ToUpper(order.Type))
orderDate, err := time.Parse(time.RFC3339, order.CreatedAt)
if err != nil {
log.Warnf("Exchange %v Func %v Order %v Could not parse date to unix with value of %v",
c.Name, "GetActiveOrders", order.ID, order.CreatedAt)
}
orders = append(orders, exchange.OrderDetail{
ID: order.ID,
Amount: order.Size,
ExecutedAmount: order.FilledSize,
OrderType: orderType,
OrderDate: orderDate,
OrderSide: orderSide,
CurrencyPair: currency,
Exchange: c.Name,
})
}
exchange.FilterOrdersByType(&orders, getOrdersRequest.OrderType)
exchange.FilterOrdersByTickRange(&orders, getOrdersRequest.StartTicks, getOrdersRequest.EndTicks)
exchange.FilterOrdersBySide(&orders, getOrdersRequest.OrderSide)
return orders, nil
}
// GetOrderHistory retrieves account order information
// Can Limit response to specific order status
func (c *CoinbasePro) GetOrderHistory(getOrdersRequest exchange.GetOrdersRequest) ([]exchange.OrderDetail, error) {
var respOrders []GeneralizedOrderResponse
for _, currency := range getOrdersRequest.Currencies {
resp, err := c.GetOrders([]string{"done", "settled"}, exchange.FormatExchangeCurrency(c.Name, currency).String())
if err != nil {
return nil, err
}
respOrders = append(respOrders, resp...)
}
var orders []exchange.OrderDetail
for _, order := range respOrders {
currency := pair.NewCurrencyPairDelimiter(order.ProductID, c.ConfigCurrencyPairFormat.Delimiter)
orderSide := exchange.OrderSide(strings.ToUpper(order.Side))
orderType := exchange.OrderType(strings.ToUpper(order.Type))
orderDate, err := time.Parse(time.RFC3339, order.CreatedAt)
if err != nil {
log.Warnf("Exchange %v Func %v Order %v Could not parse date to unix with value of %v",
c.Name, "GetActiveOrders", order.ID, order.CreatedAt)
}
orders = append(orders, exchange.OrderDetail{
ID: order.ID,
Amount: order.Size,
ExecutedAmount: order.FilledSize,
OrderType: orderType,
OrderDate: orderDate,
OrderSide: orderSide,
CurrencyPair: currency,
Exchange: c.Name,
})
}
exchange.FilterOrdersByType(&orders, getOrdersRequest.OrderType)
exchange.FilterOrdersByTickRange(&orders, getOrdersRequest.StartTicks, getOrdersRequest.EndTicks)
exchange.FilterOrdersBySide(&orders, getOrdersRequest.OrderSide)
return orders, nil
}

View File

@@ -182,22 +182,50 @@ func TestGetFee(t *testing.T) {
}
func TestFormatWithdrawPermissions(t *testing.T) {
// Arrange
c.SetDefaults()
expectedResult := exchange.WithdrawCryptoViaWebsiteOnlyText + " & " + exchange.WithdrawFiatViaWebsiteOnlyText
// Act
withdrawPermissions := c.FormatWithdrawPermissions()
// Assert
if withdrawPermissions != expectedResult {
t.Errorf("Expected: %s, Received: %s", expectedResult, withdrawPermissions)
}
}
func TestGetActiveOrders(t *testing.T) {
c.SetDefaults()
TestSetup(t)
var getOrdersRequest = exchange.GetOrdersRequest{
OrderType: exchange.AnyOrderType,
}
_, err := c.GetActiveOrders(getOrdersRequest)
if areTestAPIKeysSet() && err != nil {
t.Errorf("Could not get open orders: %s", err)
}
}
func TestGetOrderHistory(t *testing.T) {
c.SetDefaults()
TestSetup(t)
var getOrdersRequest = exchange.GetOrdersRequest{
OrderType: exchange.AnyOrderType,
Currencies: []pair.CurrencyPair{pair.NewCurrencyPair(symbol.BTC, symbol.LTC)},
}
_, err := c.GetOrderHistory(getOrdersRequest)
if areTestAPIKeysSet() && err != nil {
t.Errorf("Could not get order history: %s", err)
}
}
// Any tests below this line have the ability to impact your orders on the exchange. Enable canManipulateRealOrders to run them
// ----------------------------------------------------------------------------------------------------------------------------
func areTestAPIKeysSet() bool {
if c.APIKey != "" && c.APIKey != "Key" &&
c.APISecret != "" && c.APISecret != "Secret" {
if c.APIKey != "" && c.APIKey != "Key" {
return true
}
return false
@@ -216,7 +244,7 @@ func TestSubmitOrder(t *testing.T) {
FirstCurrency: symbol.BTC,
SecondCurrency: symbol.USD,
}
response, err := c.SubmitOrder(p, exchange.Buy, exchange.Limit, 1, 10, "1234234")
response, err := c.SubmitOrder(p, exchange.BuyOrderSide, exchange.LimitOrderType, 1, 10, "1234234")
if areTestAPIKeysSet() && (err != nil || !response.IsOrderPlaced) {
t.Errorf("Order failed to be placed: %v", err)
} else if !areTestAPIKeysSet() && err == nil {
@@ -225,7 +253,7 @@ func TestSubmitOrder(t *testing.T) {
}
func TestCancelExchangeOrder(t *testing.T) {
// Arrange
c.SetDefaults()
TestSetup(t)
@@ -242,12 +270,9 @@ func TestCancelExchangeOrder(t *testing.T) {
CurrencyPair: currencyPair,
}
// Act
err := c.CancelOrder(orderCancellation)
// Assert
if !areTestAPIKeysSet() && err == nil {
t.Errorf("Expecting an error when no keys are set: %v", err)
t.Error("Expecting an error when no keys are set")
}
if areTestAPIKeysSet() && err != nil {
t.Errorf("Could not cancel orders: %v", err)
@@ -255,7 +280,7 @@ func TestCancelExchangeOrder(t *testing.T) {
}
func TestCancelAllExchangeOrders(t *testing.T) {
// Arrange
c.SetDefaults()
TestSetup(t)
@@ -272,12 +297,10 @@ func TestCancelAllExchangeOrders(t *testing.T) {
CurrencyPair: currencyPair,
}
// Act
resp, err := c.CancelAllOrders(orderCancellation)
// Assert
if !areTestAPIKeysSet() && err == nil {
t.Errorf("Expecting an error when no keys are set: %v", err)
t.Error("Expecting an error when no keys are set")
}
if areTestAPIKeysSet() && err != nil {
t.Errorf("Could not cancel orders: %v", err)

View File

@@ -4,7 +4,9 @@ import (
"errors"
"fmt"
"strconv"
"strings"
"sync"
"time"
"github.com/thrasher-/gocryptotrader/common"
"github.com/thrasher-/gocryptotrader/currency/pair"
@@ -215,7 +217,7 @@ func (c *COINUT) SubmitOrder(p pair.CurrencyPair, side exchange.OrderSide, order
var submitOrderResponse exchange.SubmitOrderResponse
var err error
var APIresponse interface{}
isBuyOrder := side == exchange.Buy
isBuyOrder := side == exchange.BuyOrderSide
clientIDInt, err := strconv.ParseUint(clientID, 0, 32)
clientIDUint := uint32(clientIDInt)
@@ -231,9 +233,9 @@ func (c *COINUT) SubmitOrder(p pair.CurrencyPair, side exchange.OrderSide, order
currencyArray := instruments.Instruments[p.Pair().String()]
currencyID := currencyArray[0].InstID
if orderType == exchange.Limit {
if orderType == exchange.LimitOrderType {
APIresponse, err = c.NewOrder(currencyID, amount, price, isBuyOrder, clientIDUint)
} else if orderType == exchange.Market {
} else if orderType == exchange.MarketOrderType {
APIresponse, err = c.NewOrder(currencyID, amount, 0, isBuyOrder, clientIDUint)
} else {
return submitOrderResponse, errors.New("unsupported order type")
@@ -382,3 +384,110 @@ func (c *COINUT) GetFeeByType(feeBuilder exchange.FeeBuilder) (float64, error) {
func (c *COINUT) GetWithdrawCapabilities() uint32 {
return c.GetWithdrawPermissions()
}
// GetActiveOrders retrieves any orders that are active/open
func (c *COINUT) GetActiveOrders(getOrdersRequest exchange.GetOrdersRequest) ([]exchange.OrderDetail, error) {
instruments, err := c.GetInstruments()
if err != nil {
return nil, err
}
var allTheOrders []OrderResponse
for instrument, allInstrumentData := range instruments.Instruments {
for _, instrumentData := range allInstrumentData {
for _, currency := range getOrdersRequest.Currencies {
currStr := fmt.Sprintf("%v%v%v", currency.FirstCurrency.String(), c.ConfigCurrencyPairFormat.Delimiter, currency.SecondCurrency.String())
if strings.EqualFold(currStr, instrument) {
openOrders, err := c.GetOpenOrders(instrumentData.InstID)
if err != nil {
return nil, err
}
allTheOrders = append(allTheOrders, openOrders.Orders...)
continue
}
}
}
}
var orders []exchange.OrderDetail
for _, order := range allTheOrders {
for instrument, allInstrumentData := range instruments.Instruments {
for _, instrumentData := range allInstrumentData {
if instrumentData.InstID == int(order.InstrumentID) {
currPair := pair.NewCurrencyPairDelimiter(instrument, "")
orderSide := exchange.OrderSide(strings.ToUpper(order.Side))
orderDate := time.Unix(order.Timestamp, 0)
orders = append(orders, exchange.OrderDetail{
ID: strconv.FormatInt(order.OrderID, 10),
Amount: order.Quantity,
Price: order.Price,
Exchange: c.Name,
OrderSide: orderSide,
OrderDate: orderDate,
CurrencyPair: currPair,
})
}
}
}
}
exchange.FilterOrdersByTickRange(&orders, getOrdersRequest.StartTicks, getOrdersRequest.EndTicks)
exchange.FilterOrdersBySide(&orders, getOrdersRequest.OrderSide)
return orders, nil
}
// GetOrderHistory retrieves account order information
// Can Limit response to specific order status
func (c *COINUT) GetOrderHistory(getOrdersRequest exchange.GetOrdersRequest) ([]exchange.OrderDetail, error) {
instruments, err := c.GetInstruments()
if err != nil {
return nil, err
}
var allTheOrders []OrderFilledResponse
for instrument, allInstrumentData := range instruments.Instruments {
for _, instrumentData := range allInstrumentData {
for _, currency := range getOrdersRequest.Currencies {
currStr := fmt.Sprintf("%v%v%v", currency.FirstCurrency.String(), c.ConfigCurrencyPairFormat.Delimiter, currency.SecondCurrency.String())
if strings.EqualFold(currStr, instrument) {
orders, err := c.GetTradeHistory(instrumentData.InstID, -1, -1)
if err != nil {
return nil, err
}
allTheOrders = append(allTheOrders, orders.Trades...)
continue
}
}
}
}
var orders []exchange.OrderDetail
for _, order := range allTheOrders {
for instrument, allInstrumentData := range instruments.Instruments {
for _, instrumentData := range allInstrumentData {
if instrumentData.InstID == int(order.Order.InstrumentID) {
currPair := pair.NewCurrencyPairDelimiter(instrument, "")
orderSide := exchange.OrderSide(strings.ToUpper(order.Order.Side))
orderDate := time.Unix(order.Order.Timestamp, 0)
orders = append(orders, exchange.OrderDetail{
ID: strconv.FormatInt(order.Order.OrderID, 10),
Amount: order.Order.Quantity,
Price: order.Order.Price,
Exchange: c.Name,
OrderSide: orderSide,
OrderDate: orderDate,
CurrencyPair: currPair,
})
}
}
}
}
exchange.FilterOrdersByTickRange(&orders, getOrdersRequest.StartTicks, getOrdersRequest.EndTicks)
exchange.FilterOrdersBySide(&orders, getOrdersRequest.OrderSide)
return orders, nil
}

View File

@@ -5,6 +5,7 @@ import (
"fmt"
"net/http"
"net/url"
"sort"
"strings"
"sync"
"time"
@@ -207,27 +208,32 @@ type AccountCurrencyInfo struct {
// TradeHistory holds exchange history data
type TradeHistory struct {
Timestamp int64
TID int64
Price float64
Amount float64
Exchange string
Type string
Timestamp time.Time
TID int64
Price float64
Amount float64
Exchange string
Type string
Fee float64
Description string
}
// OrderDetail holds order detail data
type OrderDetail struct {
Exchange string
ID string
BaseCurrency string
QuoteCurrency string
OrderSide string
OrderType string
CreationTime int64
Status string
Price float64
Amount float64
OpenVolume float64
Exchange string
AccountID string
ID string
CurrencyPair pair.CurrencyPair
OrderSide OrderSide
OrderType OrderType
OrderDate time.Time
Status string
Price float64
Amount float64
ExecutedAmount float64
RemainingAmount float64
Fee float64
Trades []TradeHistory
}
// FundHistory holds exchange funding history data
@@ -316,6 +322,9 @@ type IBotExchange interface {
GetOrderInfo(orderID int64) (OrderDetail, error)
GetDepositAddress(cryptocurrency pair.CurrencyItem, accountID string) (string, error)
GetOrderHistory(GetOrdersRequest GetOrdersRequest) ([]OrderDetail, error)
GetActiveOrders(getOrdersRequest GetOrdersRequest) ([]OrderDetail, error)
WithdrawCryptocurrencyFunds(wtihdrawRequest WithdrawRequest) (string, error)
WithdrawFiatFunds(wtihdrawRequest WithdrawRequest) (string, error)
WithdrawFiatFundsToInternationalBank(wtihdrawRequest WithdrawRequest) (string, error)
@@ -817,9 +826,13 @@ type OrderType string
// OrderType ...types
const (
Limit OrderType = "Limit"
Market OrderType = "Market"
ImmediateOrCancel OrderType = "IMMEDIATE_OR_CANCEL"
AnyOrderType OrderType = "ANY"
LimitOrderType OrderType = "LIMIT"
MarketOrderType OrderType = "MARKET"
ImmediateOrCancelOrderType OrderType = "IMMEDIATE_OR_CANCEL"
StopOrderType OrderType = "STOP"
TrailingStopOrderType OrderType = "TRAILINGSTOP"
UnknownOrderType OrderType = "UNKNOWN"
)
// ToString changes the ordertype to the exchange standard and returns a string
@@ -832,8 +845,11 @@ type OrderSide string
// OrderSide types
const (
Buy OrderSide = "Buy"
Sell OrderSide = "Sell"
AnyOrderSide OrderSide = "ANY"
BuyOrderSide OrderSide = "BUY"
SellOrderSide OrderSide = "SELL"
BidOrderSide OrderSide = "BID"
AskOrderSide OrderSide = "ASK"
)
// ToString changes the ordertype to the exchange standard and returns a string
@@ -942,3 +958,224 @@ func (e *Base) FormatWithdrawPermissions() string {
return NoAPIWithdrawalMethodsText
}
// GetOrdersRequest used for GetOrderHistory and GetOpenOrders wrapper functions
type GetOrdersRequest struct {
OrderType OrderType
OrderSide OrderSide
StartTicks time.Time
EndTicks time.Time
// Currencies Empty array = all currencies. Some endpoints only support singular currency enquiries
Currencies []pair.CurrencyPair
}
// OrderStatus defines order status types
type OrderStatus string
// All OrderStatus types
const (
AnyOrderStatus OrderStatus = "ANY"
NewOrderStatus OrderStatus = "NEW"
ActiveOrderStatus OrderStatus = "ACTIVE"
PartiallyFilledOrderStatus OrderStatus = "PARTIALLY_FILLED"
FilledOrderStatus OrderStatus = "FILLED"
CancelledOrderStatus OrderStatus = "CANCELED"
PendingCancelOrderStatus OrderStatus = "PENDING_CANCEL"
RejectedOrderStatus OrderStatus = "REJECTED"
ExpiredOrderStatus OrderStatus = "EXPIRED"
HiddenOrderStatus OrderStatus = "HIDDEN"
UnknownOrderStatus OrderStatus = "UNKNOWN"
)
// FilterOrdersBySide removes any OrderDetails that don't match the orderStatus provided
func FilterOrdersBySide(orders *[]OrderDetail, orderSide OrderSide) {
if orderSide == "" || orderSide == AnyOrderSide {
return
}
var filteredOrders []OrderDetail
for _, orderDetail := range *orders {
if strings.EqualFold(string(orderDetail.OrderSide), string(orderSide)) {
filteredOrders = append(filteredOrders, orderDetail)
}
}
*orders = filteredOrders
}
// FilterOrdersByType removes any OrderDetails that don't match the orderType provided
func FilterOrdersByType(orders *[]OrderDetail, orderType OrderType) {
if orderType == "" || orderType == AnyOrderType {
return
}
var filteredOrders []OrderDetail
for _, orderDetail := range *orders {
if strings.EqualFold(string(orderDetail.OrderType), string(orderType)) {
filteredOrders = append(filteredOrders, orderDetail)
}
}
*orders = filteredOrders
}
// FilterOrdersByTickRange removes any OrderDetails outside of the tick range
func FilterOrdersByTickRange(orders *[]OrderDetail, startTicks, endTicks time.Time) {
if startTicks.IsZero() || endTicks.IsZero() ||
startTicks.Unix() == 0 || endTicks.Unix() == 0 || endTicks.Before(startTicks) {
return
}
var filteredOrders []OrderDetail
for _, orderDetail := range *orders {
if orderDetail.OrderDate.Unix() >= startTicks.Unix() && orderDetail.OrderDate.Unix() <= endTicks.Unix() {
filteredOrders = append(filteredOrders, orderDetail)
}
}
*orders = filteredOrders
}
// FilterOrdersByCurrencies removes any OrderDetails that do not match the provided currency list
// It is forgiving in that the provided currencies can match quote or base currencies
func FilterOrdersByCurrencies(orders *[]OrderDetail, currencies []pair.CurrencyPair) {
if len(currencies) <= 0 {
return
}
var filteredOrders []OrderDetail
for _, orderDetail := range *orders {
matchFound := false
for _, currency := range currencies {
if !matchFound && orderDetail.CurrencyPair.Equal(currency, false) {
matchFound = true
}
}
if matchFound {
filteredOrders = append(filteredOrders, orderDetail)
}
}
*orders = filteredOrders
}
// ByPrice used for sorting orders by price
type ByPrice []OrderDetail
func (b ByPrice) Len() int {
return len(b)
}
func (b ByPrice) Less(i, j int) bool {
return b[i].Price < b[j].Price
}
func (b ByPrice) Swap(i, j int) {
b[i], b[j] = b[j], b[i]
}
// SortOrdersByPrice the caller function to sort orders
func SortOrdersByPrice(orders *[]OrderDetail, reverse bool) {
if reverse {
sort.Sort(sort.Reverse(ByPrice(*orders)))
} else {
sort.Sort(ByPrice(*orders))
}
}
// ByOrderType used for sorting orders by order type
type ByOrderType []OrderDetail
func (b ByOrderType) Len() int {
return len(b)
}
func (b ByOrderType) Less(i, j int) bool {
return b[i].OrderType.ToString() < b[j].OrderType.ToString()
}
func (b ByOrderType) Swap(i, j int) {
b[i], b[j] = b[j], b[i]
}
// SortOrdersByType the caller function to sort orders
func SortOrdersByType(orders *[]OrderDetail, reverse bool) {
if reverse {
sort.Sort(sort.Reverse(ByOrderType(*orders)))
} else {
sort.Sort(ByOrderType(*orders))
}
}
// ByCurrency used for sorting orders by order currency
type ByCurrency []OrderDetail
func (b ByCurrency) Len() int {
return len(b)
}
func (b ByCurrency) Less(i, j int) bool {
return b[i].CurrencyPair.Pair().String() < b[j].CurrencyPair.Pair().String()
}
func (b ByCurrency) Swap(i, j int) {
b[i], b[j] = b[j], b[i]
}
// SortOrdersByCurrency the caller function to sort orders
func SortOrdersByCurrency(orders *[]OrderDetail, reverse bool) {
if reverse {
sort.Sort(sort.Reverse(ByCurrency(*orders)))
} else {
sort.Sort(ByCurrency(*orders))
}
}
// ByDate used for sorting orders by order date
type ByDate []OrderDetail
func (b ByDate) Len() int {
return len(b)
}
func (b ByDate) Less(i, j int) bool {
return b[i].OrderDate.Unix() < b[j].OrderDate.Unix()
}
func (b ByDate) Swap(i, j int) {
b[i], b[j] = b[j], b[i]
}
// SortOrdersByDate the caller function to sort orders
func SortOrdersByDate(orders *[]OrderDetail, reverse bool) {
if reverse {
sort.Sort(sort.Reverse(ByDate(*orders)))
} else {
sort.Sort(ByDate(*orders))
}
}
// ByOrderSide used for sorting orders by order side (buy sell)
type ByOrderSide []OrderDetail
func (b ByOrderSide) Len() int {
return len(b)
}
func (b ByOrderSide) Less(i, j int) bool {
return b[i].OrderSide.ToString() < b[j].OrderSide.ToString()
}
func (b ByOrderSide) Swap(i, j int) {
b[i], b[j] = b[j], b[i]
}
// SortOrdersBySide the caller function to sort orders
func SortOrdersBySide(orders *[]OrderDetail, reverse bool) {
if reverse {
sort.Sort(sort.Reverse(ByOrderSide(*orders)))
} else {
sort.Sort(ByOrderSide(*orders))
}
}

View File

@@ -2,12 +2,14 @@ package exchange
import (
"net/http"
"strings"
"testing"
"time"
"github.com/thrasher-/gocryptotrader/common"
"github.com/thrasher-/gocryptotrader/config"
"github.com/thrasher-/gocryptotrader/currency/pair"
"github.com/thrasher-/gocryptotrader/currency/symbol"
"github.com/thrasher-/gocryptotrader/exchanges/request"
"github.com/thrasher-/gocryptotrader/exchanges/ticker"
)
@@ -929,3 +931,248 @@ func TestOrderTypes(t *testing.T) {
t.Errorf("test failed - unexpected string %s", os.ToString())
}
}
func TestFilterOrdersByType(t *testing.T) {
var orders []OrderDetail
orders = append(orders, OrderDetail{
OrderType: ImmediateOrCancelOrderType,
})
orders = append(orders, OrderDetail{
OrderType: LimitOrderType,
})
FilterOrdersByType(&orders, AnyOrderType)
if len(orders) != 2 {
t.Errorf("Orders failed to be filtered. Expected %v, received %v", 2, len(orders))
}
FilterOrdersByType(&orders, LimitOrderType)
if len(orders) != 1 {
t.Errorf("Orders failed to be filtered. Expected %v, received %v", 1, len(orders))
}
FilterOrdersByType(&orders, StopOrderType)
if len(orders) != 0 {
t.Errorf("Orders failed to be filtered. Expected %v, received %v", 0, len(orders))
}
}
func TestFilterOrdersBySide(t *testing.T) {
var orders []OrderDetail
orders = append(orders, OrderDetail{
OrderSide: BuyOrderSide,
})
orders = append(orders, OrderDetail{
OrderSide: SellOrderSide,
})
orders = append(orders, OrderDetail{})
FilterOrdersBySide(&orders, AnyOrderSide)
if len(orders) != 3 {
t.Errorf("Orders failed to be filtered. Expected %v, received %v", 3, len(orders))
}
FilterOrdersBySide(&orders, BuyOrderSide)
if len(orders) != 1 {
t.Errorf("Orders failed to be filtered. Expected %v, received %v", 1, len(orders))
}
FilterOrdersBySide(&orders, SellOrderSide)
if len(orders) != 0 {
t.Errorf("Orders failed to be filtered. Expected %v, received %v", 0, len(orders))
}
}
func TestFilterOrdersByTickRange(t *testing.T) {
var orders []OrderDetail
orders = append(orders, OrderDetail{
OrderDate: time.Unix(100, 0),
})
orders = append(orders, OrderDetail{
OrderDate: time.Unix(110, 0),
})
orders = append(orders, OrderDetail{
OrderDate: time.Unix(111, 0),
})
FilterOrdersByTickRange(&orders, time.Unix(0, 0), time.Unix(0, 0))
if len(orders) != 3 {
t.Errorf("Orders failed to be filtered. Expected %v, received %v", 3, len(orders))
}
FilterOrdersByTickRange(&orders, time.Unix(100, 0), time.Unix(111, 0))
if len(orders) != 3 {
t.Errorf("Orders failed to be filtered. Expected %v, received %v", 3, len(orders))
}
FilterOrdersByTickRange(&orders, time.Unix(101, 0), time.Unix(111, 0))
if len(orders) != 2 {
t.Errorf("Orders failed to be filtered. Expected %v, received %v", 2, len(orders))
}
FilterOrdersByTickRange(&orders, time.Unix(200, 0), time.Unix(300, 0))
if len(orders) != 0 {
t.Errorf("Orders failed to be filtered. Expected %v, received %v", 0, len(orders))
}
}
func TestFilterOrdersByCurrencies(t *testing.T) {
var orders []OrderDetail
orders = append(orders, OrderDetail{
CurrencyPair: pair.NewCurrencyPair(symbol.BTC, symbol.USD),
})
orders = append(orders, OrderDetail{
CurrencyPair: pair.NewCurrencyPair(symbol.LTC, symbol.EUR),
})
orders = append(orders, OrderDetail{
CurrencyPair: pair.NewCurrencyPair(symbol.DOGE, symbol.RUB),
})
currencies := []pair.CurrencyPair{pair.NewCurrencyPair(symbol.BTC, symbol.USD), pair.NewCurrencyPair(symbol.LTC, symbol.EUR), pair.NewCurrencyPair(symbol.DOGE, symbol.RUB)}
FilterOrdersByCurrencies(&orders, currencies)
if len(orders) != 3 {
t.Errorf("Orders failed to be filtered. Expected %v, received %v", 3, len(orders))
}
currencies = []pair.CurrencyPair{pair.NewCurrencyPair(symbol.BTC, symbol.USD), pair.NewCurrencyPair(symbol.LTC, symbol.EUR)}
FilterOrdersByCurrencies(&orders, currencies)
if len(orders) != 2 {
t.Errorf("Orders failed to be filtered. Expected %v, received %v", 2, len(orders))
}
currencies = []pair.CurrencyPair{pair.NewCurrencyPair(symbol.BTC, symbol.USD)}
FilterOrdersByCurrencies(&orders, currencies)
if len(orders) != 1 {
t.Errorf("Orders failed to be filtered. Expected %v, received %v", 1, len(orders))
}
currencies = []pair.CurrencyPair{}
FilterOrdersByCurrencies(&orders, currencies)
if len(orders) != 1 {
t.Errorf("Orders failed to be filtered. Expected %v, received %v", 1, len(orders))
}
}
func TestSortOrdersByPrice(t *testing.T) {
orders := []OrderDetail{
{
Price: 100,
}, {
Price: 0,
}, {
Price: 50,
},
}
SortOrdersByPrice(&orders, false)
if orders[0].Price != 0 {
t.Errorf("Test failed. Expected: '%v', received: '%v'", 0, orders[0].Price)
}
SortOrdersByPrice(&orders, true)
if orders[0].Price != 100 {
t.Errorf("Test failed. Expected: '%v', received: '%v'", 100, orders[0].Price)
}
}
func TestSortOrdersByDate(t *testing.T) {
orders := []OrderDetail{
{
OrderDate: time.Unix(0, 0),
}, {
OrderDate: time.Unix(1, 0),
}, {
OrderDate: time.Unix(2, 0),
},
}
SortOrdersByDate(&orders, false)
if orders[0].OrderDate.Unix() != time.Unix(0, 0).Unix() {
t.Errorf("Test failed. Expected: '%v', received: '%v'", time.Unix(0, 0).Unix(), orders[0].OrderDate.Unix())
}
SortOrdersByDate(&orders, true)
if orders[0].OrderDate.Unix() != time.Unix(2, 0).Unix() {
t.Errorf("Test failed. Expected: '%v', received: '%v'", time.Unix(2, 0).Unix(), orders[0].OrderDate.Unix())
}
}
func TestSortOrdersByCurrency(t *testing.T) {
orders := []OrderDetail{
{
CurrencyPair: pair.NewCurrencyPairWithDelimiter(symbol.BTC, symbol.USD, "-"),
}, {
CurrencyPair: pair.NewCurrencyPairWithDelimiter(symbol.DOGE, symbol.USD, "-"),
}, {
CurrencyPair: pair.NewCurrencyPairWithDelimiter(symbol.BTC, symbol.RUB, "-"),
}, {
CurrencyPair: pair.NewCurrencyPairWithDelimiter(symbol.LTC, symbol.EUR, "-"),
}, {
CurrencyPair: pair.NewCurrencyPairWithDelimiter(symbol.LTC, symbol.AUD, "-"),
},
}
SortOrdersByCurrency(&orders, false)
if orders[0].CurrencyPair.Pair().String() != symbol.BTC+"-"+symbol.RUB {
t.Errorf("Test failed. Expected: '%v', received: '%v'", symbol.BTC+"-"+symbol.RUB, orders[0].CurrencyPair.Pair().String())
}
SortOrdersByCurrency(&orders, true)
if orders[0].CurrencyPair.Pair().String() != symbol.LTC+"-"+symbol.EUR {
t.Errorf("Test failed. Expected: '%v', received: '%v'", symbol.LTC+"-"+symbol.EUR, orders[0].CurrencyPair.Pair().String())
}
}
func TestSortOrdersByOrderSide(t *testing.T) {
orders := []OrderDetail{
{
OrderSide: BuyOrderSide,
}, {
OrderSide: SellOrderSide,
}, {
OrderSide: SellOrderSide,
}, {
OrderSide: BuyOrderSide,
},
}
SortOrdersBySide(&orders, false)
if !strings.EqualFold(orders[0].OrderSide.ToString(), BuyOrderSide.ToString()) {
t.Errorf("Test failed. Expected: '%v', received: '%v'", BuyOrderSide, orders[0].OrderSide)
}
t.Log(orders)
SortOrdersBySide(&orders, true)
if !strings.EqualFold(orders[0].OrderSide.ToString(), SellOrderSide.ToString()) {
t.Errorf("Test failed. Expected: '%v', received: '%v'", SellOrderSide, orders[0].OrderSide)
}
}
func TestSortOrdersByOrderType(t *testing.T) {
orders := []OrderDetail{
{
OrderType: MarketOrderType,
}, {
OrderType: LimitOrderType,
}, {
OrderType: ImmediateOrCancelOrderType,
}, {
OrderType: TrailingStopOrderType,
},
}
SortOrdersByType(&orders, false)
if !strings.EqualFold(orders[0].OrderType.ToString(), ImmediateOrCancelOrderType.ToString()) {
t.Errorf("Test failed. Expected: '%v', received: '%v'", ImmediateOrCancelOrderType, orders[0].OrderType)
}
SortOrdersByType(&orders, true)
if !strings.EqualFold(orders[0].OrderType.ToString(), TrailingStopOrderType.ToString()) {
t.Errorf("Test failed. Expected: '%v', received: '%v'", TrailingStopOrderType, orders[0].OrderType)
}
}

View File

@@ -4,6 +4,7 @@ import (
"testing"
"github.com/thrasher-/gocryptotrader/common"
"github.com/thrasher-/gocryptotrader/config"
"github.com/thrasher-/gocryptotrader/currency/pair"
"github.com/thrasher-/gocryptotrader/currency/symbol"
exchange "github.com/thrasher-/gocryptotrader/exchanges"
@@ -24,6 +25,18 @@ func TestDefault(t *testing.T) {
}
func TestSetup(t *testing.T) {
cfg := config.GetConfig()
cfg.LoadConfig("../../testdata/configtest.json")
exmoConf, err := cfg.GetExchangeConfig("EXMO")
if err != nil {
t.Error("Test Failed - OKCoin Setup() init error")
}
exmoConf.AuthenticatedAPISupport = true
exmoConf.APIKey = APIKey
exmoConf.APISecret = APISecret
e.Setup(exmoConf)
e.AuthenticatedAPISupport = true
e.APIKey = APIKey
e.APISecret = APISecret
@@ -226,17 +239,52 @@ func TestGetFee(t *testing.T) {
}
func TestFormatWithdrawPermissions(t *testing.T) {
// Arrange
e.SetDefaults()
expectedResult := exchange.AutoWithdrawCryptoWithSetupText + " & " + exchange.NoFiatWithdrawalsText
// Act
withdrawPermissions := e.FormatWithdrawPermissions()
// Assert
if withdrawPermissions != expectedResult {
t.Errorf("Expected: %s, Received: %s", expectedResult, withdrawPermissions)
}
}
func TestGetActiveOrders(t *testing.T) {
e.SetDefaults()
TestSetup(t)
var getOrdersRequest = exchange.GetOrdersRequest{
OrderType: exchange.AnyOrderType,
}
_, err := e.GetActiveOrders(getOrdersRequest)
if areTestAPIKeysSet() && err != nil {
t.Errorf("Could not get open orders: %s", err)
} else if !areTestAPIKeysSet() && err == nil {
t.Error("Expecting an error when no keys are set")
}
}
func TestGetOrderHistory(t *testing.T) {
e.SetDefaults()
TestSetup(t)
var getOrdersRequest = exchange.GetOrdersRequest{
OrderType: exchange.AnyOrderType,
}
currPair := pair.NewCurrencyPair(symbol.BTC, symbol.USD)
currPair.Delimiter = "_"
getOrdersRequest.Currencies = []pair.CurrencyPair{currPair}
_, err := e.GetOrderHistory(getOrdersRequest)
if areTestAPIKeysSet() && err != nil {
t.Errorf("Could not get order history: %s", err)
} else if !areTestAPIKeysSet() && err == nil {
t.Error("Expecting an error when no keys are set")
}
}
// Any tests below this line have the ability to impact your orders on the exchange. Enable canManipulateRealOrders to run them
// ----------------------------------------------------------------------------------------------------------------------------
func areTestAPIKeysSet() bool {
@@ -259,7 +307,7 @@ func TestSubmitOrder(t *testing.T) {
FirstCurrency: symbol.BTC,
SecondCurrency: symbol.USD,
}
response, err := e.SubmitOrder(p, exchange.Buy, exchange.Market, 1, 10, "1234234")
response, err := e.SubmitOrder(p, exchange.BuyOrderSide, exchange.MarketOrderType, 1, 10, "1234234")
if areTestAPIKeysSet() && (err != nil || !response.IsOrderPlaced) {
t.Errorf("Order failed to be placed: %v", err)
} else if !areTestAPIKeysSet() && err == nil {
@@ -268,7 +316,7 @@ func TestSubmitOrder(t *testing.T) {
}
func TestCancelExchangeOrder(t *testing.T) {
// Arrange
e.SetDefaults()
TestSetup(t)
if areTestAPIKeysSet() && !canManipulateRealOrders {
@@ -284,11 +332,9 @@ func TestCancelExchangeOrder(t *testing.T) {
CurrencyPair: currencyPair,
}
// Act
err := e.CancelOrder(orderCancellation)
// Assert
if !areTestAPIKeysSet() && err == nil {
t.Errorf("Expecting an error when no keys are set: %v", err)
t.Error("Expecting an error when no keys are set")
}
if areTestAPIKeysSet() && err != nil {
t.Errorf("Could not cancel orders: %v", err)
@@ -296,7 +342,7 @@ func TestCancelExchangeOrder(t *testing.T) {
}
func TestCancelAllExchangeOrders(t *testing.T) {
// Arrange
e.SetDefaults()
TestSetup(t)
@@ -312,11 +358,10 @@ func TestCancelAllExchangeOrders(t *testing.T) {
CurrencyPair: currencyPair,
}
// Act
resp, err := e.CancelAllOrders(orderCancellation)
// Assert
if !areTestAPIKeysSet() && err == nil {
t.Errorf("Expecting an error when no keys are set: %v", err)
t.Error("Expecting an error when no keys are set")
}
if areTestAPIKeysSet() && err != nil {
t.Errorf("Could not cancel orders: %v", err)
@@ -350,7 +395,7 @@ func TestWithdraw(t *testing.T) {
_, err := e.WithdrawCryptocurrencyFunds(withdrawCryptoRequest)
if !areTestAPIKeysSet() && err == nil {
t.Errorf("Expecting an error when no keys are set: %v", err)
t.Error("Expecting an error when no keys are set")
}
if areTestAPIKeysSet() && err != nil {
t.Errorf("Withdraw failed to be placed: %v", err)

View File

@@ -10,6 +10,7 @@ type Trades struct {
Price float64 `json:"price,string"`
Amount float64 `json:"amount,string"`
Date int64 `json:"date"`
Pair string `json:"pair"`
}
// Orderbook holds the orderbook data

View File

@@ -4,7 +4,9 @@ import (
"errors"
"fmt"
"strconv"
"strings"
"sync"
"time"
"github.com/thrasher-/gocryptotrader/common"
"github.com/thrasher-/gocryptotrader/currency/pair"
@@ -186,10 +188,10 @@ func (e *EXMO) GetExchangeHistory(p pair.CurrencyPair, assetType string) ([]exch
func (e *EXMO) SubmitOrder(p pair.CurrencyPair, side exchange.OrderSide, orderType exchange.OrderType, amount, price float64, clientID string) (exchange.SubmitOrderResponse, error) {
var submitOrderResponse exchange.SubmitOrderResponse
var oT string
if orderType == exchange.Limit {
if orderType == exchange.LimitOrderType {
return submitOrderResponse, errors.New("Unsupported order type")
} else if orderType == exchange.Market {
if side == exchange.Buy {
} else if orderType == exchange.MarketOrderType {
if side == exchange.BuyOrderSide {
oT = "market_buy"
} else {
oT = "market_sell"
@@ -303,3 +305,71 @@ func (e *EXMO) GetFeeByType(feeBuilder exchange.FeeBuilder) (float64, error) {
func (e *EXMO) GetWithdrawCapabilities() uint32 {
return e.GetWithdrawPermissions()
}
// GetActiveOrders retrieves any orders that are active/open
func (e *EXMO) GetActiveOrders(getOrdersRequest exchange.GetOrdersRequest) ([]exchange.OrderDetail, error) {
resp, err := e.GetOpenOrders()
if err != nil {
return nil, err
}
var orders []exchange.OrderDetail
for _, order := range resp {
symbol := pair.NewCurrencyPairDelimiter(order.Pair, "_")
orderDate := time.Unix(order.Created, 0)
orderSide := exchange.OrderSide(strings.ToUpper(order.Type))
orders = append(orders, exchange.OrderDetail{
ID: fmt.Sprintf("%v", order.OrderID),
Amount: order.Quantity,
OrderDate: orderDate,
Price: order.Price,
OrderSide: orderSide,
Exchange: e.Name,
CurrencyPair: symbol,
})
}
exchange.FilterOrdersByTickRange(&orders, getOrdersRequest.StartTicks, getOrdersRequest.EndTicks)
exchange.FilterOrdersBySide(&orders, getOrdersRequest.OrderSide)
return orders, nil
}
// GetOrderHistory retrieves account order information
// Can Limit response to specific order status
func (e *EXMO) GetOrderHistory(getOrdersRequest exchange.GetOrdersRequest) ([]exchange.OrderDetail, error) {
if len(getOrdersRequest.Currencies) <= 0 {
return nil, errors.New("Currency must be supplied")
}
var allTrades []UserTrades
for _, currency := range getOrdersRequest.Currencies {
resp, err := e.GetUserTrades(exchange.FormatExchangeCurrency(e.Name, currency).String(), "", "10000")
if err != nil {
return nil, err
}
for _, order := range resp {
allTrades = append(allTrades, order...)
}
}
var orders []exchange.OrderDetail
for _, order := range allTrades {
symbol := pair.NewCurrencyPairDelimiter(order.Pair, "_")
orderDate := time.Unix(order.Date, 0)
orderSide := exchange.OrderSide(strings.ToUpper(order.Type))
orders = append(orders, exchange.OrderDetail{
ID: fmt.Sprintf("%v", order.TradeID),
Amount: order.Quantity,
OrderDate: orderDate,
Price: order.Price,
OrderSide: orderSide,
Exchange: e.Name,
CurrencyPair: symbol,
})
}
exchange.FilterOrdersByTickRange(&orders, getOrdersRequest.StartTicks, getOrdersRequest.EndTicks)
exchange.FilterOrdersBySide(&orders, getOrdersRequest.OrderSide)
return orders, nil
}

View File

@@ -31,6 +31,7 @@ const (
gateioCancelAllOrders = "private/cancelAllOrders"
gateioWithdraw = "private/withdraw"
gateioOpenOrders = "private/openOrders"
gateioTradeHistory = "private/tradeHistory"
gateioDepositAddress = "private/depositAddress"
gateioTicker = "ticker"
gateioTickers = "tickers"
@@ -428,8 +429,7 @@ func (g *Gateio) CancelAllExistingOrders(orderType int64, symbol string) error {
return nil
}
//
// GetOpenOrders retrieves all orders with an optional symbol filter
// GetOpenOrders retrieves all open orders with an optional symbol filter
func (g *Gateio) GetOpenOrders(symbol string) (OpenOrdersResponse, error) {
var params string
var result OpenOrdersResponse
@@ -450,6 +450,24 @@ func (g *Gateio) GetOpenOrders(symbol string) (OpenOrdersResponse, error) {
return result, nil
}
// GetTradeHistory retrieves all orders with an optional symbol filter
func (g *Gateio) GetTradeHistory(symbol string) (TradHistoryResponse, error) {
var params string
var result TradHistoryResponse
params = fmt.Sprintf("currencyPair=%s", symbol)
err := g.SendAuthenticatedHTTPRequest("POST", gateioTradeHistory, params, &result)
if err != nil {
return result, err
}
if result.Code > 0 {
return result, fmt.Errorf("code:%d message:%s", result.Code, result.Message)
}
return result, nil
}
// SendAuthenticatedHTTPRequest sends authenticated requests to the Gateio API
// To use this you must setup an APIKey and APISecret from the exchange
func (g *Gateio) SendAuthenticatedHTTPRequest(method, endpoint, param string, result interface{}) error {

View File

@@ -31,7 +31,6 @@ func TestSetup(t *testing.T) {
if err != nil {
t.Error("Test Failed - GateIO Setup() init error")
}
gateioConfig.AuthenticatedAPISupport = true
gateioConfig.APIKey = apiKey
gateioConfig.APISecret = apiSecret
@@ -240,17 +239,52 @@ func TestGetFee(t *testing.T) {
}
func TestFormatWithdrawPermissions(t *testing.T) {
// Arrange
g.SetDefaults()
expectedResult := exchange.AutoWithdrawCryptoText + " & " + exchange.NoFiatWithdrawalsText
// Act
withdrawPermissions := g.FormatWithdrawPermissions()
// Assert
if withdrawPermissions != expectedResult {
t.Errorf("Expected: %s, Received: %s", expectedResult, withdrawPermissions)
}
}
func TestGetActiveOrders(t *testing.T) {
g.SetDefaults()
TestSetup(t)
var getOrdersRequest = exchange.GetOrdersRequest{
OrderType: exchange.AnyOrderType,
}
_, err := g.GetActiveOrders(getOrdersRequest)
if areTestAPIKeysSet() && err != nil {
t.Errorf("Could not get open orders: %s", err)
} else if !areTestAPIKeysSet() && err == nil {
t.Error("Expecting an error when no keys are set")
}
}
func TestGetOrderHistory(t *testing.T) {
g.SetDefaults()
TestSetup(t)
var getOrdersRequest = exchange.GetOrdersRequest{
OrderType: exchange.AnyOrderType,
}
currPair := pair.NewCurrencyPair(symbol.LTC, symbol.BTC)
currPair.Delimiter = "_"
getOrdersRequest.Currencies = []pair.CurrencyPair{currPair}
_, err := g.GetOrderHistory(getOrdersRequest)
if areTestAPIKeysSet() && err != nil {
t.Errorf("Could not get order history: %s", err)
} else if !areTestAPIKeysSet() && err == nil {
t.Error("Expecting an error when no keys are set")
}
}
// Any tests below this line have the ability to impact your orders on the exchange. Enable canManipulateRealOrders to run them
// ----------------------------------------------------------------------------------------------------------------------------
func areTestAPIKeysSet() bool {
@@ -274,7 +308,7 @@ func TestSubmitOrder(t *testing.T) {
FirstCurrency: symbol.LTC,
SecondCurrency: symbol.BTC,
}
response, err := g.SubmitOrder(p, exchange.Buy, exchange.Market, 1, 10, "1234234")
response, err := g.SubmitOrder(p, exchange.BuyOrderSide, exchange.MarketOrderType, 1, 10, "1234234")
if areTestAPIKeysSet() && (err != nil || !response.IsOrderPlaced) {
t.Errorf("Order failed to be placed: %v", err)
} else if !areTestAPIKeysSet() && err == nil {
@@ -283,7 +317,6 @@ func TestSubmitOrder(t *testing.T) {
}
func TestCancelExchangeOrder(t *testing.T) {
// Arrange
g.SetDefaults()
TestSetup(t)
@@ -300,12 +333,9 @@ func TestCancelExchangeOrder(t *testing.T) {
CurrencyPair: currencyPair,
}
// Act
err := g.CancelOrder(orderCancellation)
// Assert
if !areTestAPIKeysSet() && err == nil {
t.Errorf("Expecting an error when no keys are set: %v", err)
t.Error("Expecting an error when no keys are set")
}
if areTestAPIKeysSet() && err != nil {
t.Errorf("Could not cancel orders: %v", err)
@@ -313,7 +343,6 @@ func TestCancelExchangeOrder(t *testing.T) {
}
func TestCancelAllExchangeOrders(t *testing.T) {
// Arrange
g.SetDefaults()
TestSetup(t)
@@ -330,12 +359,10 @@ func TestCancelAllExchangeOrders(t *testing.T) {
CurrencyPair: currencyPair,
}
// Act
resp, err := g.CancelAllOrders(orderCancellation)
// Assert
if !areTestAPIKeysSet() && err == nil {
t.Errorf("Expecting an error when no keys are set: %v", err)
t.Error("Expecting an error when no keys are set")
}
if areTestAPIKeysSet() && err != nil {
t.Errorf("Could not cancel orders: %v", err)
@@ -383,7 +410,7 @@ func TestWithdraw(t *testing.T) {
_, err := g.WithdrawCryptocurrencyFunds(withdrawCryptoRequest)
if !areTestAPIKeysSet() && err == nil {
t.Errorf("Expecting an error when no keys are set: %v", err)
t.Error("Expecting an error when no keys are set")
}
if areTestAPIKeysSet() && err != nil {
t.Errorf("Withdraw failed to be placed: %v", err)

View File

@@ -142,20 +142,41 @@ type OpenOrdersResponse struct {
// OpenOrder details each open order
type OpenOrder struct {
Amount string `json:"amount"`
Amount float64 `json:"amount,string"`
CurrencyPair string `json:"currencyPair"`
FilledAmount int `json:"filledAmount"`
FilledRate int `json:"filledRate"`
InitialAmount string `json:"initialAmount"`
FilledAmount float64 `json:"filledAmount,string"`
FilledRate float64 `json:"filledRate"`
InitialAmount float64 `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"`
Timestamp int64 `json:"timestamp"`
Total float64 `json:"total,string"`
Type string `json:"type"`
}
// TradHistoryResponse The full response for retrieving all user trade history
type TradHistoryResponse struct {
Code int `json:"code,omitempty"`
Elapsed string `json:"elapsed,omitempty"`
Message string `json:"message"`
Trades []TradesResponse `json:"trades"`
Result string `json:"result"`
}
// TradesResponse details trade history
type TradesResponse struct {
ID string `json:"id"`
OrderID string `json:"orderid"`
Pair string `json:"pair"`
Type string `json:"type"`
Rate float64 `json:"rate,string"`
Amount float64 `json:"amount,string"`
Time string `json:"time"`
TimeUnix int64 `json:"time_unix,string"`
}
// WithdrawalFees the large list of predefined withdrawal fees
// Prone to change
var WithdrawalFees = map[string]float64{

View File

@@ -4,6 +4,7 @@ import (
"errors"
"fmt"
"strconv"
"strings"
"sync"
"time"
@@ -191,7 +192,7 @@ func (g *Gateio) SubmitOrder(p pair.CurrencyPair, side exchange.OrderSide, order
var submitOrderResponse exchange.SubmitOrderResponse
var orderTypeFormat SpotNewOrderRequestParamsType
if side == exchange.Buy {
if side == exchange.BuyOrderSide {
orderTypeFormat = SpotNewOrderRequestParamsTypeBuy
} else {
orderTypeFormat = SpotNewOrderRequestParamsTypeSell
@@ -319,3 +320,77 @@ func (g *Gateio) GetFeeByType(feeBuilder exchange.FeeBuilder) (float64, error) {
func (g *Gateio) GetWithdrawCapabilities() uint32 {
return g.GetWithdrawPermissions()
}
// GetActiveOrders retrieves any orders that are active/open
func (g *Gateio) GetActiveOrders(getOrdersRequest exchange.GetOrdersRequest) ([]exchange.OrderDetail, error) {
var currPair string
if len(getOrdersRequest.Currencies) == 1 {
currPair = getOrdersRequest.Currencies[0].Pair().String()
}
resp, err := g.GetOpenOrders(currPair)
if err != nil {
return nil, err
}
var orders []exchange.OrderDetail
for _, order := range resp.Orders {
if order.Status != "open" {
continue
}
symbol := pair.NewCurrencyPairDelimiter(order.CurrencyPair, g.ConfigCurrencyPairFormat.Delimiter)
side := exchange.OrderSide(strings.ToUpper(order.Type))
orderDate := time.Unix(order.Timestamp, 0)
orders = append(orders, exchange.OrderDetail{
ID: order.OrderNumber,
Amount: order.Amount,
Price: order.Rate,
RemainingAmount: order.FilledAmount,
OrderDate: orderDate,
OrderSide: side,
Exchange: g.Name,
CurrencyPair: symbol,
})
}
exchange.FilterOrdersByTickRange(&orders, getOrdersRequest.StartTicks, getOrdersRequest.EndTicks)
exchange.FilterOrdersBySide(&orders, getOrdersRequest.OrderSide)
return orders, nil
}
// GetOrderHistory retrieves account order information
// Can Limit response to specific order status
func (g *Gateio) GetOrderHistory(getOrdersRequest exchange.GetOrdersRequest) ([]exchange.OrderDetail, error) {
var trades []TradesResponse
for _, currency := range getOrdersRequest.Currencies {
resp, err := g.GetTradeHistory(currency.Pair().String())
if err != nil {
return nil, err
}
trades = append(trades, resp.Trades...)
}
var orders []exchange.OrderDetail
for _, trade := range trades {
symbol := pair.NewCurrencyPairDelimiter(trade.Pair, g.ConfigCurrencyPairFormat.Delimiter)
side := exchange.OrderSide(strings.ToUpper(trade.Type))
orderDate := time.Unix(trade.TimeUnix, 0)
orders = append(orders, exchange.OrderDetail{
ID: trade.OrderID,
Amount: trade.Amount,
Price: trade.Rate,
OrderDate: orderDate,
OrderSide: side,
Exchange: g.Name,
CurrencyPair: symbol,
})
}
exchange.FilterOrdersByTickRange(&orders, getOrdersRequest.StartTicks, getOrdersRequest.EndTicks)
exchange.FilterOrdersBySide(&orders, getOrdersRequest.OrderSide)
return orders, nil
}

View File

@@ -373,19 +373,22 @@ func (g *Gemini) GetOrderStatus(orderID int64) (Order, error) {
// GetOrders returns active orders in the market
func (g *Gemini) GetOrders() ([]Order, error) {
var response struct {
orders []Order
Message string `json:"message"`
var response interface{}
type orders struct {
orders []Order
}
err := g.SendAuthenticatedHTTPRequest("POST", geminiOrders, nil, &response)
if err != nil {
return response.orders, err
return nil, err
}
if response.Message != "" {
return response.orders, errors.New(response.Message)
switch r := response.(type) {
case orders:
return r.orders, nil
default:
return []Order{}, nil
}
return response.orders, nil
}
// GetTradeHistory returns an array of trades that have been on the exchange
@@ -512,9 +515,12 @@ func (g *Gemini) SendAuthenticatedHTTPRequest(method, path string, params map[st
PayloadBase64 := common.Base64Encode(PayloadJSON)
hmac := common.GetHMAC(common.HashSHA512_384, []byte(PayloadBase64), []byte(g.APISecret))
headers["Content-Length"] = "0"
headers["Content-Type"] = "text/plain"
headers["X-GEMINI-APIKEY"] = g.APIKey
headers["X-GEMINI-PAYLOAD"] = PayloadBase64
headers["X-GEMINI-SIGNATURE"] = common.HexEncodeToString(hmac)
headers["Cache-Control"] = "no-cache"
return g.SendPayload(method, g.APIUrl+"/v1/"+path, headers, strings.NewReader(""), result, true, g.Verbose)
}

View File

@@ -24,17 +24,17 @@ const (
apiKeyRole2 = ""
sessionHeartBeat2 = false
canManipulateRealOrders = !false
canManipulateRealOrders = false
)
func TestAddSession(t *testing.T) {
var g1 Gemini
if Session[1] == nil {
err := AddSession(&g1, 1, apiKey1, apiSecret1, apiKeyRole1, true, false)
err := AddSession(&g1, 1, apiKey1, apiSecret1, apiKeyRole1, true, true)
if err != nil {
t.Error("Test failed - AddSession() error", err)
}
err = AddSession(&g1, 1, apiKey1, apiSecret1, apiKeyRole1, true, false)
err = AddSession(&g1, 1, apiKey1, apiSecret1, apiKeyRole1, true, true)
if err == nil {
t.Error("Test failed - AddSession() error", err)
}
@@ -55,7 +55,6 @@ func TestSetDefaults(t *testing.T) {
}
func TestSetup(t *testing.T) {
cfg := config.GetConfig()
cfg.LoadConfig("../../testdata/configtest.json")
geminiConfig, err := cfg.GetExchangeConfig("Gemini")
@@ -74,6 +73,8 @@ func TestSetup(t *testing.T) {
Session[2].APIKey = apiKey2
Session[2].APISecret = apiSecret2
Session[1].APIUrl = geminiSandboxAPIURL
Session[2].APIUrl = geminiSandboxAPIURL
}
func TestGetSymbols(t *testing.T) {
@@ -249,7 +250,6 @@ func setFeeBuilder() exchange.FeeBuilder {
}
func TestGetFee(t *testing.T) {
var feeBuilder = setFeeBuilder()
if apiKey1 != "" && apiSecret1 != "" {
// CryptocurrencyTradeFee Basic
@@ -330,16 +330,54 @@ func TestFormatWithdrawPermissions(t *testing.T) {
TestAddSession(t)
TestSetDefaults(t)
TestSetup(t)
// Arrange
expectedResult := exchange.AutoWithdrawCryptoWithAPIPermissionText + " & " + exchange.AutoWithdrawCryptoWithSetupText + " & " + exchange.WithdrawFiatViaWebsiteOnlyText
// Act
withdrawPermissions := Session[1].FormatWithdrawPermissions()
// Assert
if withdrawPermissions != expectedResult {
t.Errorf("Expected: %s, Received: %s", expectedResult, withdrawPermissions)
}
}
func TestGetActiveOrders(t *testing.T) {
TestAddSession(t)
TestSetDefaults(t)
TestSetup(t)
Session[1].Verbose = true
var getOrdersRequest = exchange.GetOrdersRequest{
OrderType: exchange.AnyOrderType,
Currencies: []pair.CurrencyPair{pair.NewCurrencyPair(symbol.LTC, symbol.BTC)},
}
_, err := Session[1].GetActiveOrders(getOrdersRequest)
if areTestAPIKeysSet() && err != nil {
t.Errorf("Could not get open orders: %s", err)
} else if !areTestAPIKeysSet() && err == nil {
t.Error("Expecting an error when no keys are set")
}
}
func TestGetOrderHistory(t *testing.T) {
TestAddSession(t)
TestSetDefaults(t)
TestSetup(t)
Session[1].Verbose = true
var getOrdersRequest = exchange.GetOrdersRequest{
OrderType: exchange.AnyOrderType,
Currencies: []pair.CurrencyPair{pair.NewCurrencyPair(symbol.LTC, symbol.BTC)},
}
_, err := Session[1].GetOrderHistory(getOrdersRequest)
if areTestAPIKeysSet() && err != nil {
t.Errorf("Could not get order history: %s", err)
} else if !areTestAPIKeysSet() && err == nil {
t.Error("Expecting an error when no keys are set")
}
}
// Any tests below this line have the ability to impact your orders on the exchange. Enable canManipulateRealOrders to run them
// ----------------------------------------------------------------------------------------------------------------------------
func areTestAPIKeysSet() bool {
@@ -364,7 +402,7 @@ func TestSubmitOrder(t *testing.T) {
FirstCurrency: symbol.LTC,
SecondCurrency: symbol.BTC,
}
response, err := Session[1].SubmitOrder(p, exchange.Buy, exchange.Market, 1, 10, "1234234")
response, err := Session[1].SubmitOrder(p, exchange.BuyOrderSide, exchange.MarketOrderType, 1, 10, "1234234")
if areTestAPIKeysSet() && (err != nil || !response.IsOrderPlaced) {
t.Errorf("Order failed to be placed: %v", err)
} else if !areTestAPIKeysSet() && err == nil {
@@ -373,7 +411,6 @@ func TestSubmitOrder(t *testing.T) {
}
func TestCancelExchangeOrder(t *testing.T) {
// Arrange
TestAddSession(t)
TestSetDefaults(t)
TestSetup(t)
@@ -391,12 +428,9 @@ func TestCancelExchangeOrder(t *testing.T) {
CurrencyPair: currencyPair,
}
// Act
err := Session[1].CancelOrder(orderCancellation)
// Assert
if !areTestAPIKeysSet() && err == nil {
t.Errorf("Expecting an error when no keys are set: %v", err)
t.Error("Expecting an error when no keys are set")
}
if areTestAPIKeysSet() && err != nil {
t.Errorf("Could not cancel orders: %v", err)
@@ -404,7 +438,6 @@ func TestCancelExchangeOrder(t *testing.T) {
}
func TestCancelAllExchangeOrders(t *testing.T) {
// Arrange
TestAddSession(t)
TestSetDefaults(t)
TestSetup(t)
@@ -422,12 +455,10 @@ func TestCancelAllExchangeOrders(t *testing.T) {
CurrencyPair: currencyPair,
}
// Act
resp, err := Session[1].CancelAllOrders(orderCancellation)
// Assert
if !areTestAPIKeysSet() && err == nil {
t.Errorf("Expecting an error when no keys are set: %v", err)
t.Error("Expecting an error when no keys are set")
}
if areTestAPIKeysSet() && err != nil {
t.Errorf("Could not cancel orders: %v", err)
@@ -462,7 +493,7 @@ func TestWithdraw(t *testing.T) {
_, err := Session[1].WithdrawCryptocurrencyFunds(withdrawCryptoRequest)
if !areTestAPIKeysSet() && err == nil {
t.Errorf("Expecting an error when no keys are set: %v", err)
t.Error("Expecting an error when no keys are set")
}
if areTestAPIKeysSet() && err != nil {
t.Errorf("Withdraw failed to be placed: %v", err)

View File

@@ -117,6 +117,9 @@ type TradeHistory struct {
Exchange string `json:"exchange"`
IsAuctionFilled bool `json:"is_auction_fill"`
ClientOrderID string `json:"client_order_id"`
// Used to store values
BaseCurrency string
QuoteCurrency string
}
// TradeVolume holds Volume information

View File

@@ -5,7 +5,9 @@ import (
"fmt"
"net/url"
"strconv"
"strings"
"sync"
"time"
"github.com/thrasher-/gocryptotrader/common"
"github.com/thrasher-/gocryptotrader/currency/pair"
@@ -241,3 +243,89 @@ func (g *Gemini) GetFeeByType(feeBuilder exchange.FeeBuilder) (float64, error) {
func (g *Gemini) GetWithdrawCapabilities() uint32 {
return g.GetWithdrawPermissions()
}
// GetActiveOrders retrieves any orders that are active/open
func (g *Gemini) GetActiveOrders(getOrdersRequest exchange.GetOrdersRequest) ([]exchange.OrderDetail, error) {
resp, err := g.GetOrders()
if err != nil {
return nil, err
}
var orders []exchange.OrderDetail
for _, order := range resp {
symbol := pair.NewCurrencyPairDelimiter(order.Symbol, g.ConfigCurrencyPairFormat.Delimiter)
var orderType exchange.OrderType
if order.Type == "exchange limit" {
orderType = exchange.LimitOrderType
} else if order.Type == "market buy" || order.Type == "market sell" {
orderType = exchange.MarketOrderType
}
side := exchange.OrderSide(strings.ToUpper(order.Type))
orderDate := time.Unix(order.Timestamp, 0)
orders = append(orders, exchange.OrderDetail{
Amount: order.OriginalAmount,
RemainingAmount: order.RemainingAmount,
ID: fmt.Sprintf("%v", order.OrderID),
ExecutedAmount: order.ExecutedAmount,
Exchange: g.Name,
OrderType: orderType,
OrderSide: side,
Price: order.Price,
CurrencyPair: symbol,
OrderDate: orderDate,
})
}
exchange.FilterOrdersByTickRange(&orders, getOrdersRequest.StartTicks, getOrdersRequest.EndTicks)
exchange.FilterOrdersBySide(&orders, getOrdersRequest.OrderSide)
exchange.FilterOrdersByType(&orders, getOrdersRequest.OrderType)
exchange.FilterOrdersByCurrencies(&orders, getOrdersRequest.Currencies)
return orders, nil
}
// GetOrderHistory retrieves account order information
// Can Limit response to specific order status
func (g *Gemini) GetOrderHistory(getOrdersRequest exchange.GetOrdersRequest) ([]exchange.OrderDetail, error) {
if len(getOrdersRequest.Currencies) <= 0 {
return nil, errors.New("Currency must be supplied")
}
var trades []TradeHistory
for _, currency := range getOrdersRequest.Currencies {
resp, err := g.GetTradeHistory(exchange.FormatExchangeCurrency(g.Name, currency).String(), getOrdersRequest.StartTicks.Unix())
if err != nil {
return nil, err
}
for _, trade := range resp {
trade.BaseCurrency = currency.FirstCurrency.String()
trade.QuoteCurrency = currency.SecondCurrency.String()
trades = append(trades, trade)
}
}
var orders []exchange.OrderDetail
for _, trade := range trades {
side := exchange.OrderSide(strings.ToUpper(trade.Type))
orderDate := time.Unix(trade.Timestamp, 0)
orders = append(orders, exchange.OrderDetail{
Amount: trade.Amount,
ID: fmt.Sprintf("%v", trade.OrderID),
Exchange: g.Name,
OrderDate: orderDate,
OrderSide: side,
Fee: trade.FeeAmount,
Price: trade.Price,
CurrencyPair: pair.NewCurrencyPairWithDelimiter(trade.BaseCurrency, trade.QuoteCurrency, g.ConfigCurrencyPairFormat.Delimiter),
})
}
exchange.FilterOrdersByTickRange(&orders, getOrdersRequest.StartTicks, getOrdersRequest.EndTicks)
exchange.FilterOrdersBySide(&orders, getOrdersRequest.OrderSide)
return orders, nil
}

View File

@@ -35,6 +35,8 @@ const (
apiV2CryptoAddress = "api/2/account/crypto/address"
apiV2CryptoWithdraw = "api/2/account/crypto/withdraw"
apiV2TradeHistory = "api/2/history/trades"
apiV2OrderHistory = "api/2/history/order"
apiv2OpenOrders = "api/2/order"
apiV2FeeInfo = "api/2/trading/fee"
orders = "order"
orderBuy = "api/2/order"
@@ -387,8 +389,8 @@ func (h *HitBTC) GetActiveorders(currency string) ([]Order, error) {
return resp, err
}
// GetAuthenticatedTradeHistory returns your trade history
func (h *HitBTC) GetAuthenticatedTradeHistory(currency, start, end string) (interface{}, error) {
// GetTradeHistoryForCurrency returns your trade history
func (h *HitBTC) GetTradeHistoryForCurrency(currency, start, end string) (AuthenticatedTradeHistoryResponse, error) {
values := url.Values{}
if start != "" {
@@ -399,11 +401,22 @@ func (h *HitBTC) GetAuthenticatedTradeHistory(currency, start, end string) (inte
values.Set("end", end)
}
if currency != "" && currency != "all" {
values.Set("currencyPair", currency)
result := AuthenticatedTradeHistoryResponse{}
values.Set("currencyPair", currency)
result := AuthenticatedTradeHistoryResponse{}
return result, h.SendAuthenticatedHTTPRequest("POST", apiV2TradeHistory, values, &result.Data)
return result, h.SendAuthenticatedHTTPRequest("POST", apiV2TradeHistory, values, &result.Data)
}
// GetTradeHistoryForAllCurrencies returns your trade history
func (h *HitBTC) GetTradeHistoryForAllCurrencies(currency, start, end string) (AuthenticatedTradeHistoryAll, error) {
values := url.Values{}
if start != "" {
values.Set("start", start)
}
if end != "" {
values.Set("end", end)
}
values.Set("currencyPair", "all")
@@ -412,6 +425,24 @@ func (h *HitBTC) GetAuthenticatedTradeHistory(currency, start, end string) (inte
return result, h.SendAuthenticatedHTTPRequest("POST", apiV2TradeHistory, values, &result.Data)
}
// GetOrders List of your order history.
func (h *HitBTC) GetOrders(currency string) ([]OrderHistoryResponse, error) {
values := url.Values{}
values.Set("symbol", currency)
var result []OrderHistoryResponse
return result, h.SendAuthenticatedHTTPRequest("GET", apiV2OrderHistory, values, &result)
}
// GetOpenOrders List of your currently open orders.
func (h *HitBTC) GetOpenOrders(currency string) ([]OrderHistoryResponse, error) {
values := url.Values{}
values.Set("symbol", currency)
var result []OrderHistoryResponse
return result, h.SendAuthenticatedHTTPRequest("GET", apiv2OpenOrders, values, &result)
}
// PlaceOrder places an order on the exchange
func (h *HitBTC) PlaceOrder(currency string, rate, amount float64, orderType, side string) (OrderResponse, error) {
result := OrderResponse{}

View File

@@ -30,7 +30,6 @@ func TestSetup(t *testing.T) {
if err != nil {
t.Error("Test Failed - HitBTC Setup() init error")
}
hitbtcConfig.AuthenticatedAPISupport = true
hitbtcConfig.APIKey = apiKey
hitbtcConfig.APISecret = apiSecret
@@ -164,17 +163,50 @@ func TestGetFee(t *testing.T) {
}
func TestFormatWithdrawPermissions(t *testing.T) {
// Arrange
h.SetDefaults()
expectedResult := exchange.AutoWithdrawCryptoText + " & " + exchange.NoFiatWithdrawalsText
// Act
withdrawPermissions := h.FormatWithdrawPermissions()
// Assert
if withdrawPermissions != expectedResult {
t.Errorf("Expected: %s, Received: %s", expectedResult, withdrawPermissions)
}
}
func TestGetActiveOrders(t *testing.T) {
h.SetDefaults()
TestSetup(t)
var getOrdersRequest = exchange.GetOrdersRequest{
OrderType: exchange.AnyOrderType,
Currencies: []pair.CurrencyPair{pair.NewCurrencyPair(symbol.ETH, symbol.BTC)},
}
_, err := h.GetActiveOrders(getOrdersRequest)
if areTestAPIKeysSet() && err != nil {
t.Errorf("Could not get open orders: %s", err)
} else if !areTestAPIKeysSet() && err == nil {
t.Error("Expecting an error when no keys are set")
}
}
func TestGetOrderHistory(t *testing.T) {
h.SetDefaults()
TestSetup(t)
var getOrdersRequest = exchange.GetOrdersRequest{
OrderType: exchange.AnyOrderType,
Currencies: []pair.CurrencyPair{pair.NewCurrencyPair(symbol.ETH, symbol.BTC)},
}
_, err := h.GetOrderHistory(getOrdersRequest)
if areTestAPIKeysSet() && err != nil {
t.Errorf("Could not get order history: %s", err)
} else if !areTestAPIKeysSet() && err == nil {
t.Error("Expecting an error when no keys are set")
}
}
// Any tests below this line have the ability to impact your orders on the exchange. Enable canManipulateRealOrders to run them
// ----------------------------------------------------------------------------------------------------------------------------
func areTestAPIKeysSet() bool {
@@ -198,7 +230,7 @@ func TestSubmitOrder(t *testing.T) {
FirstCurrency: symbol.DGD,
SecondCurrency: symbol.BTC,
}
response, err := h.SubmitOrder(p, exchange.Buy, exchange.Market, 1, 10, "1234234")
response, err := h.SubmitOrder(p, exchange.BuyOrderSide, exchange.MarketOrderType, 1, 10, "1234234")
if areTestAPIKeysSet() && (err != nil || !response.IsOrderPlaced) {
t.Errorf("Order failed to be placed: %v", err)
} else if !areTestAPIKeysSet() && err == nil {
@@ -207,7 +239,6 @@ func TestSubmitOrder(t *testing.T) {
}
func TestCancelExchangeOrder(t *testing.T) {
// Arrange
h.SetDefaults()
TestSetup(t)
@@ -224,12 +255,9 @@ func TestCancelExchangeOrder(t *testing.T) {
CurrencyPair: currencyPair,
}
// Act
err := h.CancelOrder(orderCancellation)
// Assert
if !areTestAPIKeysSet() && err == nil {
t.Errorf("Expecting an error when no keys are set: %v", err)
t.Error("Expecting an error when no keys are set")
}
if areTestAPIKeysSet() && err != nil {
t.Errorf("Could not cancel orders: %v", err)
@@ -237,7 +265,6 @@ func TestCancelExchangeOrder(t *testing.T) {
}
func TestCancelAllExchangeOrders(t *testing.T) {
// Arrange
h.SetDefaults()
TestSetup(t)
@@ -254,12 +281,10 @@ func TestCancelAllExchangeOrders(t *testing.T) {
CurrencyPair: currencyPair,
}
// Act
resp, err := h.CancelAllOrders(orderCancellation)
// Assert
if !areTestAPIKeysSet() && err == nil {
t.Errorf("Expecting an error when no keys are set: %v", err)
t.Error("Expecting an error when no keys are set")
}
if areTestAPIKeysSet() && err != nil {
t.Errorf("Could not cancel orders: %v", err)
@@ -293,7 +318,7 @@ func TestWithdraw(t *testing.T) {
_, err := h.WithdrawCryptocurrencyFunds(withdrawCryptoRequest)
if !areTestAPIKeysSet() && err == nil {
t.Errorf("Expecting an error when no keys are set: %v", err)
t.Error("Expecting an error when no keys are set")
}
if areTestAPIKeysSet() && err != nil {
t.Errorf("Withdraw failed to be placed: %v", err)

View File

@@ -184,6 +184,23 @@ type AuthenticatedTradeHistoryResponse struct {
Data []AuthentictedTradeHistory
}
// OrderHistoryResponse used for GetOrderHistory
type OrderHistoryResponse struct {
ID string `json:"id"`
ClientOrderID string `json:"clientOrderId"`
Symbol string `json:"symbol"`
Side string `json:"side"`
Status string `json:"status"`
Type string `json:"type"`
TimeInForce string `json:"timeInForce"`
Price float64 `json:"price,string"`
Quantity float64 `json:"quantity,string"`
PostOnly bool `json:"postOnly"`
CumQuantity float64 `json:"cumQuantity,string"`
CreatedAt string `json:"createdAt"`
UpdatedAt string `json:"updatedAt"`
}
// ResultingTrades holds resulting trade information
type ResultingTrades struct {
Amount float64 `json:"amount,string"`

View File

@@ -1,9 +1,12 @@
package hitbtc
import (
"errors"
"fmt"
"strconv"
"strings"
"sync"
"time"
"github.com/thrasher-/gocryptotrader/common"
"github.com/thrasher-/gocryptotrader/currency/pair"
@@ -264,3 +267,88 @@ func (h *HitBTC) GetFeeByType(feeBuilder exchange.FeeBuilder) (float64, error) {
func (h *HitBTC) GetWithdrawCapabilities() uint32 {
return h.GetWithdrawPermissions()
}
// GetActiveOrders retrieves any orders that are active/open
func (h *HitBTC) GetActiveOrders(getOrdersRequest exchange.GetOrdersRequest) ([]exchange.OrderDetail, error) {
if len(getOrdersRequest.Currencies) <= 0 {
return nil, errors.New("Currency must be supplied")
}
var allOrders []OrderHistoryResponse
for _, currency := range getOrdersRequest.Currencies {
resp, err := h.GetOpenOrders(currency.Pair().String())
if err != nil {
return nil, err
}
allOrders = append(allOrders, resp...)
}
var orders []exchange.OrderDetail
for _, order := range allOrders {
symbol := pair.NewCurrencyPairDelimiter(order.Symbol, h.ConfigCurrencyPairFormat.Delimiter)
side := exchange.OrderSide(strings.ToUpper(order.Side))
orderDate, err := time.Parse(time.RFC3339, order.CreatedAt)
if err != nil {
log.Warnf("Exchange %v Func %v Order %v Could not parse date to unix with value of %v",
h.Name, "GetActiveOrders", order.ID, order.CreatedAt)
}
orders = append(orders, exchange.OrderDetail{
ID: order.ID,
Amount: order.Quantity,
Exchange: h.Name,
Price: order.Price,
OrderDate: orderDate,
OrderSide: side,
CurrencyPair: symbol,
})
}
exchange.FilterOrdersByTickRange(&orders, getOrdersRequest.StartTicks, getOrdersRequest.EndTicks)
exchange.FilterOrdersBySide(&orders, getOrdersRequest.OrderSide)
return orders, nil
}
// GetOrderHistory retrieves account order information
// Can Limit response to specific order status
func (h *HitBTC) GetOrderHistory(getOrdersRequest exchange.GetOrdersRequest) ([]exchange.OrderDetail, error) {
if len(getOrdersRequest.Currencies) <= 0 {
return nil, errors.New("Currency must be supplied")
}
var allOrders []OrderHistoryResponse
for _, currency := range getOrdersRequest.Currencies {
resp, err := h.GetOrders(currency.Pair().String())
if err != nil {
return nil, err
}
allOrders = append(allOrders, resp...)
}
var orders []exchange.OrderDetail
for _, order := range allOrders {
symbol := pair.NewCurrencyPairDelimiter(order.Symbol, h.ConfigCurrencyPairFormat.Delimiter)
side := exchange.OrderSide(strings.ToUpper(order.Side))
orderDate, err := time.Parse(time.RFC3339, order.CreatedAt)
if err != nil {
log.Warnf("Exchange %v Func %v Order %v Could not parse date to unix with value of %v",
h.Name, "GetOrderHistory", order.ID, order.CreatedAt)
}
orders = append(orders, exchange.OrderDetail{
ID: order.ID,
Amount: order.Quantity,
Exchange: h.Name,
Price: order.Price,
OrderDate: orderDate,
OrderSide: side,
CurrencyPair: symbol,
})
}
exchange.FilterOrdersByTickRange(&orders, getOrdersRequest.StartTicks, getOrdersRequest.EndTicks)
exchange.FilterOrdersBySide(&orders, getOrdersRequest.OrderSide)
return orders, nil
}

View File

@@ -48,7 +48,7 @@ const (
huobiGetOrder = "order/orders/%s"
huobiGetOrderMatch = "order/orders/%s/matchresults"
huobiGetOrders = "order/orders"
huobiGetOpenOrders = "order/order/openOrders"
huobiGetOpenOrders = "order/openOrders"
huobiGetOrdersMatch = "orders/matchresults"
huobiMarginTransferIn = "dw/transfer-in/margin"
huobiMarginTransferOut = "dw/transfer-out/margin"
@@ -570,7 +570,9 @@ func (h *HUOBI) GetOpenOrders(accountID, symbol, side string, size int) ([]Order
vals := url.Values{}
vals.Set("symbol", symbol)
vals.Set("accountID", accountID)
vals.Set("side", side)
if len(side) > 0 {
vals.Set("side", side)
}
vals.Set("size", fmt.Sprintf("%v", size))
var result response

View File

@@ -66,7 +66,6 @@ func TestSetup(t *testing.T) {
if err != nil {
t.Error("Test Failed - Huobi Setup() init error")
}
hConfig.AuthenticatedAPISupport = true
hConfig.APIKey = apiKey
hConfig.APISecret = apiSecret
@@ -385,17 +384,50 @@ func TestGetFee(t *testing.T) {
}
func TestFormatWithdrawPermissions(t *testing.T) {
// Arrange
h.SetDefaults()
expectedResult := exchange.AutoWithdrawCryptoWithSetupText + " & " + exchange.NoFiatWithdrawalsText
// Act
withdrawPermissions := h.FormatWithdrawPermissions()
// Assert
if withdrawPermissions != expectedResult {
t.Errorf("Expected: %s, Received: %s", expectedResult, withdrawPermissions)
}
}
func TestGetActiveOrders(t *testing.T) {
h.SetDefaults()
TestSetup(t)
var getOrdersRequest = exchange.GetOrdersRequest{
OrderType: exchange.AnyOrderType,
Currencies: []pair.CurrencyPair{pair.NewCurrencyPair(symbol.BTC, symbol.USDT)},
}
_, err := h.GetActiveOrders(getOrdersRequest)
if areTestAPIKeysSet() && err != nil {
t.Errorf("Could not get open orders: %s", err)
} else if !areTestAPIKeysSet() && err == nil {
t.Error("Expecting an error when no keys are set")
}
}
func TestGetOrderHistory(t *testing.T) {
h.SetDefaults()
TestSetup(t)
var getOrdersRequest = exchange.GetOrdersRequest{
OrderType: exchange.AnyOrderType,
Currencies: []pair.CurrencyPair{pair.NewCurrencyPair(symbol.BTC, symbol.USDT)},
}
_, err := h.GetOrderHistory(getOrdersRequest)
if areTestAPIKeysSet() && err != nil {
t.Errorf("Could not get order history: %s", err)
} else if !areTestAPIKeysSet() && err == nil {
t.Error("Expecting an error when no keys are set")
}
}
// Any tests below this line have the ability to impact your orders on the exchange. Enable canManipulateRealOrders to run them
// ----------------------------------------------------------------------------------------------------------------------------
func areTestAPIKeysSet() bool {
@@ -430,7 +462,7 @@ func TestSubmitOrder(t *testing.T) {
t.Errorf("Failed to get accounts. Err: %s", err)
}
response, err := h.SubmitOrder(p, exchange.Buy, exchange.Limit, 1, 10, strconv.FormatInt(accounts[0].ID, 10))
response, err := h.SubmitOrder(p, exchange.BuyOrderSide, exchange.LimitOrderType, 1, 10, strconv.FormatInt(accounts[0].ID, 10))
if areTestAPIKeysSet() && (err != nil || !response.IsOrderPlaced) {
t.Errorf("Order failed to be placed: %v", err)
} else if !areTestAPIKeysSet() && err == nil {
@@ -439,7 +471,6 @@ func TestSubmitOrder(t *testing.T) {
}
func TestCancelExchangeOrder(t *testing.T) {
// Arrange
h.SetDefaults()
TestSetup(t)
@@ -456,12 +487,10 @@ func TestCancelExchangeOrder(t *testing.T) {
CurrencyPair: currencyPair,
}
// Act
err := h.CancelOrder(orderCancellation)
// Assert
if !areTestAPIKeysSet() && err == nil {
t.Errorf("Expecting an error when no keys are set: %v", err)
t.Error("Expecting an error when no keys are set")
}
if areTestAPIKeysSet() && err != nil {
t.Errorf("Could not cancel orders: %v", err)
@@ -469,7 +498,6 @@ func TestCancelExchangeOrder(t *testing.T) {
}
func TestCancelAllExchangeOrders(t *testing.T) {
// Arrange
h.SetDefaults()
TestSetup(t)
if areTestAPIKeysSet() && !canManipulateRealOrders {
@@ -484,11 +512,10 @@ func TestCancelAllExchangeOrders(t *testing.T) {
CurrencyPair: currencyPair,
}
// Act
resp, err := h.CancelAllOrders(orderCancellation)
// Assert
if !areTestAPIKeysSet() && err == nil {
t.Errorf("Expecting an error when no keys are set: %v", err)
t.Error("Expecting an error when no keys are set")
}
if areTestAPIKeysSet() && err != nil {
t.Errorf("Could not cancel orders: %v", err)
@@ -536,7 +563,7 @@ func TestWithdraw(t *testing.T) {
_, err := h.WithdrawCryptocurrencyFunds(withdrawCryptoRequest)
if !areTestAPIKeysSet() && err == nil {
t.Errorf("Expecting an error when no keys are set: %v", err)
t.Error("Expecting an error when no keys are set")
}
if areTestAPIKeysSet() && err != nil {
t.Errorf("Withdraw failed to be placed: %v", err)

View File

@@ -141,23 +141,26 @@ type CancelOrderBatch struct {
// OrderInfo stores the order info
type OrderInfo struct {
ID int `json:"id"`
Symbol string `json:"symbol"`
AccountID int `json:"account-id"`
Amount string `json:"amount"`
Price string `json:"price"`
CreatedAt int64 `json:"created-at"`
Type string `json:"type"`
FieldAmount string `json:"field-amount"`
FieldCashAmount string `json:"field-cash-amount"`
FieldFees string `json:"field-fees"`
FinishedAt int64 `json:"finished-at"`
UserID int `json:"user-id"`
Source string `json:"source"`
State string `json:"state"`
CanceledAt int `json:"canceled-at"`
Exchange string `json:"exchange"`
Batch string `json:"batch"`
ID int `json:"id"`
Symbol string `json:"symbol"`
AccountID float64 `json:"account-id"`
Amount float64 `json:"amount,string"`
Price float64 `json:"price,string"`
CreatedAt int64 `json:"created-at"`
Type string `json:"type"`
FieldAmount float64 `json:"field-amount,string"`
FieldCashAmount float64 `json:"field-cash-amount,string"`
Fieldees float64 `json:"field-fees,string"`
FilledAmount float64 `json:"filled-amount,string"`
FilledCashAmount float64 `json:"filled-cash-amount,string"`
FilledFees float64 `json:"filled-fees,string"`
FinishedAt int64 `json:"finished-at"`
UserID int `json:"user-id"`
Source string `json:"source"`
State string `json:"state"`
CanceledAt int `json:"canceled-at"`
Exchange string `json:"exchange"`
Batch string `json:"batch"`
}
// OrderMatchInfo stores the order match info

View File

@@ -4,7 +4,9 @@ import (
"errors"
"fmt"
"strconv"
"strings"
"sync"
"time"
"github.com/thrasher-/gocryptotrader/common"
"github.com/thrasher-/gocryptotrader/config"
@@ -259,14 +261,14 @@ func (h *HUOBI) SubmitOrder(p pair.CurrencyPair, side exchange.OrderSide, orderT
AccountID: int(accountID),
}
if side == exchange.Buy && orderType == exchange.Market {
if side == exchange.BuyOrderSide && orderType == exchange.MarketOrderType {
formattedType = SpotNewOrderRequestTypeBuyMarket
} else if side == exchange.Sell && orderType == exchange.Market {
} else if side == exchange.SellOrderSide && orderType == exchange.MarketOrderType {
formattedType = SpotNewOrderRequestTypeSellMarket
} else if side == exchange.Buy && orderType == exchange.Limit {
} else if side == exchange.BuyOrderSide && orderType == exchange.LimitOrderType {
formattedType = SpotNewOrderRequestTypeBuyLimit
params.Price = price
} else if side == exchange.Sell && orderType == exchange.Limit {
} else if side == exchange.SellOrderSide && orderType == exchange.LimitOrderType {
formattedType = SpotNewOrderRequestTypeSellLimit
params.Price = price
} else {
@@ -374,3 +376,84 @@ func (h *HUOBI) GetFeeByType(feeBuilder exchange.FeeBuilder) (float64, error) {
func (h *HUOBI) GetWithdrawCapabilities() uint32 {
return h.GetWithdrawPermissions()
}
// GetActiveOrders retrieves any orders that are active/open
func (h *HUOBI) GetActiveOrders(getOrdersRequest exchange.GetOrdersRequest) ([]exchange.OrderDetail, error) {
if len(getOrdersRequest.Currencies) <= 0 {
return nil, errors.New("Currency must be supplied")
}
side := ""
if getOrdersRequest.OrderSide == exchange.AnyOrderSide || getOrdersRequest.OrderSide == "" {
side = ""
} else if getOrdersRequest.OrderSide == exchange.SellOrderSide {
side = strings.ToLower(string(getOrdersRequest.OrderSide))
}
var allOrders []OrderInfo
for _, currency := range getOrdersRequest.Currencies {
resp, err := h.GetOpenOrders(h.ClientID, currency.Pair().Lower().String(), side, 500)
if err != nil {
return nil, err
}
allOrders = append(allOrders, resp...)
}
var orders []exchange.OrderDetail
for _, order := range allOrders {
symbol := pair.NewCurrencyPairDelimiter(order.Symbol, h.ConfigCurrencyPairFormat.Delimiter)
orderDate := time.Unix(order.CreatedAt, 0)
orders = append(orders, exchange.OrderDetail{
ID: fmt.Sprintf("%v", order.ID),
Exchange: h.Name,
Amount: order.Amount,
Price: order.Price,
OrderDate: orderDate,
ExecutedAmount: order.FilledAmount,
RemainingAmount: (order.Amount - order.FilledAmount),
CurrencyPair: symbol,
})
}
exchange.FilterOrdersByTickRange(&orders, getOrdersRequest.StartTicks, getOrdersRequest.EndTicks)
return orders, nil
}
// GetOrderHistory retrieves account order information
// Can Limit response to specific order status
func (h *HUOBI) GetOrderHistory(getOrdersRequest exchange.GetOrdersRequest) ([]exchange.OrderDetail, error) {
if len(getOrdersRequest.Currencies) <= 0 {
return nil, errors.New("Currency must be supplied")
}
states := "partial-canceled,filled,canceled"
var allOrders []OrderInfo
for _, currency := range getOrdersRequest.Currencies {
resp, err := h.GetOrders(currency.Pair().Lower().String(), "", "", "", states, "", "", "")
if err != nil {
return nil, err
}
allOrders = append(allOrders, resp...)
}
var orders []exchange.OrderDetail
for _, order := range allOrders {
symbol := pair.NewCurrencyPairDelimiter(order.Symbol, h.ConfigCurrencyPairFormat.Delimiter)
orderDate := time.Unix(order.CreatedAt, 0)
orders = append(orders, exchange.OrderDetail{
ID: fmt.Sprintf("%v", order.ID),
Exchange: h.Name,
Amount: order.Amount,
Price: order.Price,
OrderDate: orderDate,
CurrencyPair: symbol,
})
}
exchange.FilterOrdersByTickRange(&orders, getOrdersRequest.StartTicks, getOrdersRequest.EndTicks)
return orders, nil
}

View File

@@ -37,7 +37,7 @@ const (
huobihadaxAccountBalance = "account/accounts/%s/balance"
huobihadaxOrderPlace = "order/orders/place"
huobihadaxOrderCancel = "order/orders/%s/submitcancel"
huobihadaxGetOpenOrders = "order/order/openOrders"
huobihadaxGetOpenOrders = "order/openOrders"
huobihadaxOrderCancelBatch = "order/orders/batchcancel"
huobiHadaxBatchCancelOpenOrders = "order/orders/batchCancelOpenOrders"
huobihadaxGetOrder = "order/orders/%s"
@@ -497,7 +497,9 @@ func (h *HUOBIHADAX) GetOpenOrders(accountID, symbol, side string, size int) ([]
vals := url.Values{}
vals.Set("symbol", symbol)
vals.Set("accountID", accountID)
vals.Set("side", side)
if len(side) > 0 {
vals.Set("side", side)
}
vals.Set("size", fmt.Sprintf("%v", size))
var result response

View File

@@ -62,7 +62,6 @@ func TestSetup(t *testing.T) {
if err != nil {
t.Error("Test Failed - HuobiHadax Setup() init error")
}
hadaxConfig.AuthenticatedAPISupport = true
hadaxConfig.APIKey = apiKey
hadaxConfig.APISecret = apiSecret
@@ -365,17 +364,50 @@ func TestGetFee(t *testing.T) {
}
func TestFormatWithdrawPermissions(t *testing.T) {
// Arrange
h.SetDefaults()
expectedResult := exchange.AutoWithdrawCryptoWithSetupText + " & " + exchange.NoFiatWithdrawalsText
// Act
withdrawPermissions := h.FormatWithdrawPermissions()
// Assert
if withdrawPermissions != expectedResult {
t.Errorf("Expected: %s, Received: %s", expectedResult, withdrawPermissions)
}
}
func TestGetActiveOrders(t *testing.T) {
h.SetDefaults()
TestSetup(t)
var getOrdersRequest = exchange.GetOrdersRequest{
OrderType: exchange.AnyOrderType,
Currencies: []pair.CurrencyPair{pair.NewCurrencyPair(symbol.BTC, symbol.USDT)},
}
_, err := h.GetActiveOrders(getOrdersRequest)
if areTestAPIKeysSet() && err != nil {
t.Errorf("Could not get open orders: %s", err)
} else if !areTestAPIKeysSet() && err == nil {
t.Error("Expecting an error when no keys are set")
}
}
func TestGetOrderHistory(t *testing.T) {
h.SetDefaults()
TestSetup(t)
var getOrdersRequest = exchange.GetOrdersRequest{
OrderType: exchange.AnyOrderType,
Currencies: []pair.CurrencyPair{pair.NewCurrencyPair(symbol.BTC, symbol.USDT)},
}
_, err := h.GetOrderHistory(getOrdersRequest)
if areTestAPIKeysSet() && err != nil {
t.Errorf("Could not get order history: %s", err)
} else if !areTestAPIKeysSet() && err == nil {
t.Error("Expecting an error when no keys are set")
}
}
// Any tests below this line have the ability to impact your orders on the exchange. Enable canManipulateRealOrders to run them
// ----------------------------------------------------------------------------------------------------------------------------
func areTestAPIKeysSet() bool {
@@ -410,7 +442,7 @@ func TestSubmitOrder(t *testing.T) {
t.Errorf("Failed to get accounts. Err: %s", err)
}
response, err := h.SubmitOrder(p, exchange.Buy, exchange.Limit, 1, 10, strconv.FormatInt(accounts[0].ID, 10))
response, err := h.SubmitOrder(p, exchange.BuyOrderSide, exchange.LimitOrderType, 1, 10, strconv.FormatInt(accounts[0].ID, 10))
if areTestAPIKeysSet() && (err != nil || !response.IsOrderPlaced) {
t.Errorf("Order failed to be placed: %v", err)
} else if !areTestAPIKeysSet() && err == nil {
@@ -419,8 +451,6 @@ func TestSubmitOrder(t *testing.T) {
}
func TestCancelExchangeOrder(t *testing.T) {
// Arrange
h.SetDefaults()
TestSetup(t)
@@ -437,12 +467,9 @@ func TestCancelExchangeOrder(t *testing.T) {
CurrencyPair: currencyPair,
}
// Act
err := h.CancelOrder(orderCancellation)
// Assert
if !areTestAPIKeysSet() && err == nil {
t.Errorf("Expecting an error when no keys are set: %v", err)
t.Error("Expecting an error when no keys are set")
}
if areTestAPIKeysSet() && err != nil {
t.Errorf("Could not cancel orders: %v", err)
@@ -450,7 +477,6 @@ func TestCancelExchangeOrder(t *testing.T) {
}
func TestCancelAllExchangeOrders(t *testing.T) {
// Arrange
h.SetDefaults()
TestSetup(t)
@@ -467,12 +493,10 @@ func TestCancelAllExchangeOrders(t *testing.T) {
CurrencyPair: currencyPair,
}
// Act
resp, err := h.CancelAllOrders(orderCancellation)
// Assert
if !areTestAPIKeysSet() && err == nil {
t.Errorf("Expecting an error when no keys are set: %v", err)
t.Error("Expecting an error when no keys are set")
}
if areTestAPIKeysSet() && err != nil {
t.Errorf("Could not cancel orders: %v", err)
@@ -520,7 +544,7 @@ func TestWithdraw(t *testing.T) {
_, err := h.WithdrawCryptocurrencyFunds(withdrawCryptoRequest)
if !areTestAPIKeysSet() && err == nil {
t.Errorf("Expecting an error when no keys are set: %v", err)
t.Error("Expecting an error when no keys are set")
}
if areTestAPIKeysSet() && err != nil {
t.Errorf("Withdraw failed to be placed: %v", err)

View File

@@ -123,23 +123,26 @@ type CancelOrderBatch struct {
// OrderInfo stores the order info
type OrderInfo struct {
ID int `json:"id"`
Symbol string `json:"symbol"`
AccountID int `json:"account-id"`
Amount string `json:"amount"`
Price string `json:"price"`
CreatedAt int64 `json:"created-at"`
Type string `json:"type"`
FieldAmount string `json:"field-amount"`
FieldCashAmount string `json:"field-cash-amount"`
FieldFees string `json:"field-fees"`
FinishedAt int64 `json:"finished-at"`
UserID int `json:"user-id"`
Source string `json:"source"`
State string `json:"state"`
CanceledAt int `json:"canceled-at"`
Exchange string `json:"exchange"`
Batch string `json:"batch"`
ID int `json:"id"`
Symbol string `json:"symbol"`
AccountID float64 `json:"account-id"`
Amount float64 `json:"amount,string"`
Price float64 `json:"price,string"`
CreatedAt int64 `json:"created-at"`
Type string `json:"type"`
FieldAmount float64 `json:"field-amount,string"`
FieldCashAmount float64 `json:"field-cash-amount,string"`
Fieldees float64 `json:"field-fees,string"`
FilledAmount float64 `json:"filled-amount,string"`
FilledCashAmount float64 `json:"filled-cash-amount,string"`
FilledFees float64 `json:"filled-fees,string"`
FinishedAt int64 `json:"finished-at"`
UserID int `json:"user-id"`
Source string `json:"source"`
State string `json:"state"`
CanceledAt int `json:"canceled-at"`
Exchange string `json:"exchange"`
Batch string `json:"batch"`
}
// OrderMatchInfo stores the order match info

View File

@@ -4,7 +4,9 @@ import (
"errors"
"fmt"
"strconv"
"strings"
"sync"
"time"
"github.com/thrasher-/gocryptotrader/common"
"github.com/thrasher-/gocryptotrader/currency/pair"
@@ -224,14 +226,14 @@ func (h *HUOBIHADAX) SubmitOrder(p pair.CurrencyPair, side exchange.OrderSide, o
AccountID: int(accountID),
}
if side == exchange.Buy && orderType == exchange.Market {
if side == exchange.BuyOrderSide && orderType == exchange.MarketOrderType {
formattedType = SpotNewOrderRequestTypeBuyMarket
} else if side == exchange.Sell && orderType == exchange.Market {
} else if side == exchange.SellOrderSide && orderType == exchange.MarketOrderType {
formattedType = SpotNewOrderRequestTypeSellMarket
} else if side == exchange.Buy && orderType == exchange.Limit {
} else if side == exchange.BuyOrderSide && orderType == exchange.LimitOrderType {
formattedType = SpotNewOrderRequestTypeBuyLimit
params.Price = price
} else if side == exchange.Sell && orderType == exchange.Limit {
} else if side == exchange.SellOrderSide && orderType == exchange.LimitOrderType {
formattedType = SpotNewOrderRequestTypeSellLimit
params.Price = price
} else {
@@ -339,3 +341,84 @@ func (h *HUOBIHADAX) GetFeeByType(feeBuilder exchange.FeeBuilder) (float64, erro
func (h *HUOBIHADAX) GetWithdrawCapabilities() uint32 {
return h.GetWithdrawPermissions()
}
// GetActiveOrders retrieves any orders that are active/open
func (h *HUOBIHADAX) GetActiveOrders(getOrdersRequest exchange.GetOrdersRequest) ([]exchange.OrderDetail, error) {
if len(getOrdersRequest.Currencies) <= 0 {
return nil, errors.New("Currency must be supplied")
}
side := ""
if getOrdersRequest.OrderSide == exchange.AnyOrderSide || getOrdersRequest.OrderSide == "" {
side = ""
} else if getOrdersRequest.OrderSide == exchange.SellOrderSide {
side = strings.ToLower(string(getOrdersRequest.OrderSide))
}
var allOrders []OrderInfo
for _, currency := range getOrdersRequest.Currencies {
resp, err := h.GetOpenOrders(h.ClientID, currency.Pair().Lower().String(), side, 500)
if err != nil {
return nil, err
}
allOrders = append(allOrders, resp...)
}
var orders []exchange.OrderDetail
for _, order := range allOrders {
symbol := pair.NewCurrencyPairDelimiter(order.Symbol, h.ConfigCurrencyPairFormat.Delimiter)
orderDate := time.Unix(order.CreatedAt, 0)
orders = append(orders, exchange.OrderDetail{
ID: fmt.Sprintf("%v", order.ID),
Exchange: h.Name,
Amount: order.Amount,
Price: order.Price,
OrderDate: orderDate,
ExecutedAmount: order.FilledAmount,
RemainingAmount: (order.Amount - order.FilledAmount),
CurrencyPair: symbol,
})
}
exchange.FilterOrdersByTickRange(&orders, getOrdersRequest.StartTicks, getOrdersRequest.EndTicks)
return orders, nil
}
// GetOrderHistory retrieves account order information
// Can Limit response to specific order status
func (h *HUOBIHADAX) GetOrderHistory(getOrdersRequest exchange.GetOrdersRequest) ([]exchange.OrderDetail, error) {
if len(getOrdersRequest.Currencies) <= 0 {
return nil, errors.New("Currency must be supplied")
}
states := "partial-canceled,filled,canceled"
var allOrders []OrderInfo
for _, currency := range getOrdersRequest.Currencies {
resp, err := h.GetOrders(currency.Pair().Lower().String(), "", "", "", states, "", "", "")
if err != nil {
return nil, err
}
allOrders = append(allOrders, resp...)
}
var orders []exchange.OrderDetail
for _, order := range allOrders {
symbol := pair.NewCurrencyPairDelimiter(order.Symbol, h.ConfigCurrencyPairFormat.Delimiter)
orderDate := time.Unix(order.CreatedAt, 0)
orders = append(orders, exchange.OrderDetail{
ID: fmt.Sprintf("%v", order.ID),
Exchange: h.Name,
Amount: order.Amount,
Price: order.Price,
OrderDate: orderDate,
CurrencyPair: symbol,
})
}
exchange.FilterOrdersByTickRange(&orders, getOrdersRequest.StartTicks, getOrdersRequest.EndTicks)
return orders, nil
}

View File

@@ -32,7 +32,6 @@ func TestSetup(t *testing.T) {
if err != nil {
t.Error("Test Failed - Gemini Setup() init error")
}
itbitConfig.AuthenticatedAPISupport = true
itbitConfig.APIKey = apiKey
itbitConfig.APISecret = apiSecret
@@ -234,17 +233,48 @@ func TestGetFee(t *testing.T) {
}
func TestFormatWithdrawPermissions(t *testing.T) {
// Arrange
i.SetDefaults()
expectedResult := exchange.WithdrawCryptoViaWebsiteOnlyText + " & " + exchange.WithdrawFiatViaWebsiteOnlyText
// Act
withdrawPermissions := i.FormatWithdrawPermissions()
// Assert
if withdrawPermissions != expectedResult {
t.Errorf("Expected: %s, Received: %s", expectedResult, withdrawPermissions)
}
}
func TestGetActiveOrders(t *testing.T) {
i.SetDefaults()
TestSetup(t)
var getOrdersRequest = exchange.GetOrdersRequest{
OrderType: exchange.AnyOrderType,
}
_, err := i.GetActiveOrders(getOrdersRequest)
if areTestAPIKeysSet() && err != nil {
t.Errorf("Could not get open orders: %s", err)
} else if !areTestAPIKeysSet() && err == nil {
t.Error("Expecting an error when no keys are set")
}
}
func TestGetOrderHistory(t *testing.T) {
i.SetDefaults()
TestSetup(t)
var getOrdersRequest = exchange.GetOrdersRequest{
OrderType: exchange.AnyOrderType,
}
_, err := i.GetOrderHistory(getOrdersRequest)
if areTestAPIKeysSet() && err != nil {
t.Errorf("Could not get order history: %s", err)
} else if !areTestAPIKeysSet() && err == nil {
t.Error("Expecting an error when no keys are set")
}
}
// Any tests below this line have the ability to impact your orders on the exchange. Enable canManipulateRealOrders to run them
// ----------------------------------------------------------------------------------------------------------------------------
func areTestAPIKeysSet() bool {
@@ -267,7 +297,7 @@ func TestSubmitOrder(t *testing.T) {
FirstCurrency: symbol.BTC,
SecondCurrency: symbol.USDT,
}
response, err := i.SubmitOrder(p, exchange.Buy, exchange.Limit, 1, 10, "hi")
response, err := i.SubmitOrder(p, exchange.BuyOrderSide, exchange.LimitOrderType, 1, 10, "hi")
if areTestAPIKeysSet() && (err != nil || !response.IsOrderPlaced) {
t.Errorf("Order failed to be placed: %v", err)
} else if !areTestAPIKeysSet() && err == nil {
@@ -276,7 +306,6 @@ func TestSubmitOrder(t *testing.T) {
}
func TestCancelExchangeOrder(t *testing.T) {
// Arrange
i.SetDefaults()
TestSetup(t)
@@ -293,12 +322,10 @@ func TestCancelExchangeOrder(t *testing.T) {
CurrencyPair: currencyPair,
}
// Act
err := i.CancelOrder(orderCancellation)
// Assert
if !areTestAPIKeysSet() && err == nil {
t.Errorf("Expecting an error when no keys are set: %v", err)
t.Error("Expecting an error when no keys are set")
}
if areTestAPIKeysSet() && err != nil {
t.Errorf("Could not cancel orders: %v", err)
@@ -306,7 +333,6 @@ func TestCancelExchangeOrder(t *testing.T) {
}
func TestCancelAllExchangeOrders(t *testing.T) {
// Arrange
i.SetDefaults()
TestSetup(t)
@@ -323,12 +349,10 @@ func TestCancelAllExchangeOrders(t *testing.T) {
CurrencyPair: currencyPair,
}
// Act
resp, err := i.CancelAllOrders(orderCancellation)
// Assert
if !areTestAPIKeysSet() && err == nil {
t.Errorf("Expecting an error when no keys are set: %v", err)
t.Error("Expecting an error when no keys are set")
}
if areTestAPIKeysSet() && err != nil {
t.Errorf("Could not cancel orders: %v", err)

View File

@@ -4,7 +4,9 @@ import (
"fmt"
"net/url"
"strconv"
"strings"
"sync"
"time"
"github.com/thrasher-/gocryptotrader/common"
"github.com/thrasher-/gocryptotrader/currency/pair"
@@ -280,3 +282,98 @@ func (i *ItBit) GetFeeByType(feeBuilder exchange.FeeBuilder) (float64, error) {
func (i *ItBit) GetWithdrawCapabilities() uint32 {
return i.GetWithdrawPermissions()
}
// GetActiveOrders retrieves any orders that are active/open
func (i *ItBit) GetActiveOrders(getOrdersRequest exchange.GetOrdersRequest) ([]exchange.OrderDetail, error) {
wallets, err := i.GetWallets(url.Values{})
if err != nil {
return nil, err
}
var allOrders []Order
for _, wallet := range wallets {
resp, err := i.GetOrders(wallet.ID, "", "open", 0, 0)
if err != nil {
return nil, err
}
allOrders = append(allOrders, resp...)
}
var orders []exchange.OrderDetail
for _, order := range allOrders {
symbol := pair.NewCurrencyPairDelimiter(order.Instrument, i.ConfigCurrencyPairFormat.Delimiter)
side := exchange.OrderSide(strings.ToUpper(order.Side))
orderDate, err := time.Parse(time.RFC3339, order.CreatedTime)
if err != nil {
log.Warnf("Exchange %v Func %v Order %v Could not parse date to unix with value of %v",
i.Name, "GetActiveOrders", order.ID, order.CreatedTime)
}
orders = append(orders, exchange.OrderDetail{
ID: order.ID,
OrderSide: side,
Amount: order.Amount,
ExecutedAmount: order.AmountFilled,
RemainingAmount: (order.Amount - order.AmountFilled),
Exchange: i.Name,
OrderDate: orderDate,
CurrencyPair: symbol,
})
}
exchange.FilterOrdersByTickRange(&orders, getOrdersRequest.StartTicks, getOrdersRequest.EndTicks)
exchange.FilterOrdersBySide(&orders, getOrdersRequest.OrderSide)
exchange.FilterOrdersByCurrencies(&orders, getOrdersRequest.Currencies)
return orders, nil
}
// GetOrderHistory retrieves account order information
// Can Limit response to specific order status
func (i *ItBit) GetOrderHistory(getOrdersRequest exchange.GetOrdersRequest) ([]exchange.OrderDetail, error) {
wallets, err := i.GetWallets(url.Values{})
if err != nil {
return nil, err
}
var allOrders []Order
for _, wallet := range wallets {
resp, err := i.GetOrders(wallet.ID, "", "", 0, 0)
if err != nil {
return nil, err
}
allOrders = append(allOrders, resp...)
}
var orders []exchange.OrderDetail
for _, order := range allOrders {
if order.Type == "open" {
continue
}
symbol := pair.NewCurrencyPairDelimiter(order.Instrument, i.ConfigCurrencyPairFormat.Delimiter)
side := exchange.OrderSide(strings.ToUpper(order.Side))
orderDate, err := time.Parse(time.RFC3339, order.CreatedTime)
if err != nil {
log.Warnf("Exchange %v Func %v Order %v Could not parse date to unix with value of %v",
i.Name, "GetActiveOrders", order.ID, order.CreatedTime)
}
orders = append(orders, exchange.OrderDetail{
ID: order.ID,
OrderSide: side,
Amount: order.Amount,
ExecutedAmount: order.AmountFilled,
RemainingAmount: (order.Amount - order.AmountFilled),
Exchange: i.Name,
OrderDate: orderDate,
CurrencyPair: symbol,
})
}
exchange.FilterOrdersByTickRange(&orders, getOrdersRequest.StartTicks, getOrdersRequest.EndTicks)
exchange.FilterOrdersBySide(&orders, getOrdersRequest.OrderSide)
exchange.FilterOrdersByCurrencies(&orders, getOrdersRequest.Currencies)
return orders, nil
}

View File

@@ -540,15 +540,15 @@ func (k *Kraken) GetTradeBalance(args ...TradeBalanceOptions) (TradeBalanceInfo,
}
// GetOpenOrders returns all current open orders
func (k *Kraken) GetOpenOrders(args ...OrderInfoOptions) (OpenOrders, error) {
func (k *Kraken) GetOpenOrders(args OrderInfoOptions) (OpenOrders, error) {
params := url.Values{}
if args[0].Trades {
if args.Trades {
params.Set("trades", "true")
}
if args[0].UserRef != 0 {
params.Set("userref", strconv.FormatInt(int64(args[0].UserRef), 10))
if args.UserRef != 0 {
params.Set("userref", strconv.FormatInt(int64(args.UserRef), 10))
}
var response struct {
@@ -564,33 +564,31 @@ func (k *Kraken) GetOpenOrders(args ...OrderInfoOptions) (OpenOrders, error) {
}
// GetClosedOrders returns a list of closed orders
func (k *Kraken) GetClosedOrders(args ...GetClosedOrdersOptions) (ClosedOrders, error) {
func (k *Kraken) GetClosedOrders(args GetClosedOrdersOptions) (ClosedOrders, error) {
params := url.Values{}
if args != nil {
if args[0].Trades {
params.Set("trades", "true")
}
if args.Trades {
params.Set("trades", "true")
}
if args[0].UserRef != 0 {
params.Set("userref", strconv.FormatInt(int64(args[0].UserRef), 10))
}
if args.UserRef != 0 {
params.Set("userref", strconv.FormatInt(int64(args.UserRef), 10))
}
if len(args[0].Start) != 0 {
params.Set("start", args[0].Start)
}
if len(args.Start) != 0 {
params.Set("start", args.Start)
}
if len(args[0].End) != 0 {
params.Set("end", args[0].End)
}
if len(args.End) != 0 {
params.Set("end", args.End)
}
if args[0].Ofs != 0 {
params.Set("ofs", strconv.FormatInt(args[0].Ofs, 10))
}
if args.Ofs != 0 {
params.Set("ofs", strconv.FormatInt(args.Ofs, 10))
}
if len(args[0].CloseTime) != 0 {
params.Set("closetime", args[0].CloseTime)
}
if len(args.CloseTime) != 0 {
params.Set("closetime", args.CloseTime)
}
var response struct {

View File

@@ -30,7 +30,6 @@ func TestSetup(t *testing.T) {
if err != nil {
t.Error("Test Failed - kraken Setup() init error", err)
}
krakenConfig.AuthenticatedAPISupport = true
krakenConfig.APIKey = apiKey
krakenConfig.APISecret = apiSecret
@@ -319,17 +318,48 @@ func TestGetFee(t *testing.T) {
}
func TestFormatWithdrawPermissions(t *testing.T) {
// Arrange
k.SetDefaults()
expectedResult := exchange.AutoWithdrawCryptoWithSetupText + " & " + exchange.WithdrawCryptoWith2FAText + " & " + exchange.AutoWithdrawFiatWithSetupText + " & " + exchange.WithdrawFiatWith2FAText
// Act
withdrawPermissions := k.FormatWithdrawPermissions()
// Assert
if withdrawPermissions != expectedResult {
t.Errorf("Expected: %s, Received: %s", expectedResult, withdrawPermissions)
}
}
func TestGetActiveOrders(t *testing.T) {
k.SetDefaults()
TestSetup(t)
var getOrdersRequest = exchange.GetOrdersRequest{
OrderType: exchange.AnyOrderType,
}
_, err := k.GetActiveOrders(getOrdersRequest)
if areTestAPIKeysSet() && err != nil {
t.Errorf("Could not get open orders: %s", err)
} else if !areTestAPIKeysSet() && err == nil {
t.Error("Expecting an error when no keys are set")
}
}
func TestGetOrderHistory(t *testing.T) {
k.SetDefaults()
TestSetup(t)
var getOrdersRequest = exchange.GetOrdersRequest{
OrderType: exchange.AnyOrderType,
}
_, err := k.GetOrderHistory(getOrdersRequest)
if areTestAPIKeysSet() && err != nil {
t.Errorf("Could not get order history: %s", err)
} else if !areTestAPIKeysSet() && err == nil {
t.Error("Expecting an error when no keys are set")
}
}
// Any tests below this line have the ability to impact your orders on the exchange. Enable canManipulateRealOrders to run them
// ----------------------------------------------------------------------------------------------------------------------------
func areTestAPIKeysSet() bool {
@@ -353,7 +383,7 @@ func TestSubmitOrder(t *testing.T) {
FirstCurrency: symbol.XBT,
SecondCurrency: symbol.CAD,
}
response, err := k.SubmitOrder(p, exchange.Buy, exchange.Market, 1, 10, "hi")
response, err := k.SubmitOrder(p, exchange.BuyOrderSide, exchange.MarketOrderType, 1, 10, "hi")
if areTestAPIKeysSet() && (err != nil || !response.IsOrderPlaced) {
t.Errorf("Order failed to be placed: %v", err)
} else if !areTestAPIKeysSet() && err == nil {
@@ -362,7 +392,6 @@ func TestSubmitOrder(t *testing.T) {
}
func TestCancelExchangeOrder(t *testing.T) {
// Arrange
k.SetDefaults()
TestSetup(t)
@@ -379,12 +408,9 @@ func TestCancelExchangeOrder(t *testing.T) {
CurrencyPair: currencyPair,
}
// Act
err := k.CancelOrder(orderCancellation)
// Assert
if !areTestAPIKeysSet() && err == nil {
t.Errorf("Expecting an error when no keys are set: %v", err)
t.Error("Expecting an error when no keys are set")
}
if areTestAPIKeysSet() && err != nil {
t.Errorf("Could not cancel orders: %v", err)
@@ -392,7 +418,6 @@ func TestCancelExchangeOrder(t *testing.T) {
}
func TestCancelAllExchangeOrders(t *testing.T) {
// Arrange
k.SetDefaults()
TestSetup(t)
@@ -409,12 +434,10 @@ func TestCancelAllExchangeOrders(t *testing.T) {
CurrencyPair: currencyPair,
}
// Act
resp, err := k.CancelAllOrders(orderCancellation)
// Assert
if !areTestAPIKeysSet() && err == nil {
t.Errorf("Expecting an error when no keys are set: %v", err)
t.Error("Expecting an error when no keys are set")
}
if areTestAPIKeysSet() && err != nil {
t.Errorf("Could not cancel orders: %v", err)
@@ -463,7 +486,7 @@ func TestWithdraw(t *testing.T) {
_, err := k.WithdrawCryptocurrencyFunds(withdrawCryptoRequest)
if !areTestAPIKeysSet() && err == nil {
t.Errorf("Expecting an error when no keys are set: %v", err)
t.Error("Expecting an error when no keys are set")
}
if areTestAPIKeysSet() && err != nil {
t.Errorf("Withdraw failed to be placed: %v", err)
@@ -488,7 +511,7 @@ func TestWithdrawFiat(t *testing.T) {
_, err := k.WithdrawFiatFunds(withdrawFiatRequest)
if !areTestAPIKeysSet() && err == nil {
t.Errorf("Expecting an error when no keys are set: %v", err)
t.Error("Expecting an error when no keys are set")
}
if areTestAPIKeysSet() && err != nil {
t.Errorf("Withdraw failed to be placed: %v", err)
@@ -513,7 +536,7 @@ func TestWithdrawInternationalBank(t *testing.T) {
_, err := k.WithdrawFiatFundsToInternationalBank(withdrawFiatRequest)
if !areTestAPIKeysSet() && err == nil {
t.Errorf("Expecting an error when no keys are set: %v", err)
t.Error("Expecting an error when no keys are set")
}
if areTestAPIKeysSet() && err != nil {
t.Errorf("Withdraw failed to be placed: %v", err)

View File

@@ -2,8 +2,10 @@ package kraken
import (
"errors"
"fmt"
"strings"
"sync"
"time"
"github.com/thrasher-/gocryptotrader/common"
"github.com/thrasher-/gocryptotrader/currency/pair"
@@ -290,3 +292,77 @@ func (k *Kraken) GetFeeByType(feeBuilder exchange.FeeBuilder) (float64, error) {
func (k *Kraken) GetWithdrawCapabilities() uint32 {
return k.GetWithdrawPermissions()
}
// GetActiveOrders retrieves any orders that are active/open
func (k *Kraken) GetActiveOrders(getOrdersRequest exchange.GetOrdersRequest) ([]exchange.OrderDetail, error) {
resp, err := k.GetOpenOrders(OrderInfoOptions{})
if err != nil {
return nil, err
}
var orders []exchange.OrderDetail
for ID, order := range resp.Open {
symbol := pair.NewCurrencyPairDelimiter(order.Descr.Pair, k.ConfigCurrencyPairFormat.Delimiter)
orderDate := time.Unix(int64(order.StartTm), 0)
side := exchange.OrderSide(strings.ToUpper(order.Descr.Type))
orders = append(orders, exchange.OrderDetail{
ID: ID,
Amount: order.Vol,
RemainingAmount: (order.Vol - order.VolExec),
ExecutedAmount: order.VolExec,
Exchange: k.Name,
OrderDate: orderDate,
Price: order.Price,
OrderSide: side,
CurrencyPair: symbol,
})
}
exchange.FilterOrdersByTickRange(&orders, getOrdersRequest.StartTicks, getOrdersRequest.EndTicks)
exchange.FilterOrdersBySide(&orders, getOrdersRequest.OrderSide)
exchange.FilterOrdersByCurrencies(&orders, getOrdersRequest.Currencies)
return orders, nil
}
// GetOrderHistory retrieves account order information
// Can Limit response to specific order status
func (k *Kraken) GetOrderHistory(getOrdersRequest exchange.GetOrdersRequest) ([]exchange.OrderDetail, error) {
request := GetClosedOrdersOptions{}
if getOrdersRequest.StartTicks.Unix() > 0 {
request.Start = fmt.Sprintf("%v", getOrdersRequest.StartTicks.Unix())
}
if getOrdersRequest.EndTicks.Unix() > 0 {
request.End = fmt.Sprintf("%v", getOrdersRequest.EndTicks.Unix())
}
resp, err := k.GetClosedOrders(request)
if err != nil {
return nil, err
}
var orders []exchange.OrderDetail
for ID, order := range resp.Closed {
symbol := pair.NewCurrencyPairDelimiter(order.Descr.Pair, k.ConfigCurrencyPairFormat.Delimiter)
orderDate := time.Unix(int64(order.StartTm), 0)
side := exchange.OrderSide(strings.ToUpper(order.Descr.Type))
orders = append(orders, exchange.OrderDetail{
ID: ID,
Amount: order.Vol,
RemainingAmount: (order.Vol - order.VolExec),
ExecutedAmount: order.VolExec,
Exchange: k.Name,
OrderDate: orderDate,
Price: order.Price,
OrderSide: side,
CurrencyPair: symbol,
})
}
exchange.FilterOrdersBySide(&orders, getOrdersRequest.OrderSide)
exchange.FilterOrdersByCurrencies(&orders, getOrdersRequest.Currencies)
return orders, nil
}

View File

@@ -30,7 +30,6 @@ func TestSetup(t *testing.T) {
if err != nil {
t.Error("Test Failed - LakeBTC Setup() init error")
}
lakebtcConfig.AuthenticatedAPISupport = true
lakebtcConfig.APIKey = apiKey
lakebtcConfig.APISecret = apiSecret
@@ -227,17 +226,48 @@ func TestGetFee(t *testing.T) {
}
func TestFormatWithdrawPermissions(t *testing.T) {
// Arrange
l.SetDefaults()
expectedResult := exchange.AutoWithdrawCryptoText + " & " + exchange.WithdrawFiatViaWebsiteOnlyText
// Act
withdrawPermissions := l.FormatWithdrawPermissions()
// Assert
if withdrawPermissions != expectedResult {
t.Errorf("Expected: %s, Received: %s", expectedResult, withdrawPermissions)
}
}
func TestGetActiveOrders(t *testing.T) {
l.SetDefaults()
TestSetup(t)
var getOrdersRequest = exchange.GetOrdersRequest{
OrderType: exchange.AnyOrderType,
}
_, err := l.GetActiveOrders(getOrdersRequest)
if areTestAPIKeysSet() && err != nil {
t.Errorf("Could not get open orders: %s", err)
} else if !areTestAPIKeysSet() && err == nil {
t.Error("Expecting an error when no keys are set")
}
}
func TestGetOrderHistory(t *testing.T) {
l.SetDefaults()
TestSetup(t)
var getOrdersRequest = exchange.GetOrdersRequest{
OrderType: exchange.AnyOrderType,
}
_, err := l.GetOrderHistory(getOrdersRequest)
if areTestAPIKeysSet() && err != nil {
t.Errorf("Could not get order history: %s", err)
} else if !areTestAPIKeysSet() && err == nil {
t.Error("Expecting an error when no keys are set")
}
}
// Any tests below this line have the ability to impact your orders on the exchange. Enable canManipulateRealOrders to run them
// ----------------------------------------------------------------------------------------------------------------------------
func areTestAPIKeysSet() bool {
@@ -261,7 +291,7 @@ func TestSubmitOrder(t *testing.T) {
FirstCurrency: symbol.BTC,
SecondCurrency: symbol.EUR,
}
response, err := l.SubmitOrder(p, exchange.Buy, exchange.Market, 1, 10, "hi")
response, err := l.SubmitOrder(p, exchange.BuyOrderSide, exchange.MarketOrderType, 1, 10, "hi")
if areTestAPIKeysSet() && (err != nil || !response.IsOrderPlaced) {
t.Errorf("Order failed to be placed: %v", err)
} else if !areTestAPIKeysSet() && err == nil {
@@ -270,7 +300,6 @@ func TestSubmitOrder(t *testing.T) {
}
func TestCancelExchangeOrder(t *testing.T) {
// Arrange
l.SetDefaults()
TestSetup(t)
@@ -287,12 +316,9 @@ func TestCancelExchangeOrder(t *testing.T) {
CurrencyPair: currencyPair,
}
// Act
err := l.CancelOrder(orderCancellation)
// Assert
if !areTestAPIKeysSet() && err == nil {
t.Errorf("Expecting an error when no keys are set: %v", err)
t.Error("Expecting an error when no keys are set")
}
if areTestAPIKeysSet() && err != nil {
t.Errorf("Could not cancel orders: %v", err)
@@ -300,7 +326,6 @@ func TestCancelExchangeOrder(t *testing.T) {
}
func TestCancelAllExchangeOrders(t *testing.T) {
// Arrange
l.SetDefaults()
TestSetup(t)
@@ -317,12 +342,10 @@ func TestCancelAllExchangeOrders(t *testing.T) {
CurrencyPair: currencyPair,
}
// Act
resp, err := l.CancelAllOrders(orderCancellation)
// Assert
if !areTestAPIKeysSet() && err == nil {
t.Errorf("Expecting an error when no keys are set: %v", err)
t.Error("Expecting an error when no keys are set")
}
if areTestAPIKeysSet() && err != nil {
t.Errorf("Could not cancel orders: %v", err)
@@ -356,7 +379,7 @@ func TestWithdraw(t *testing.T) {
_, err := l.WithdrawCryptocurrencyFunds(withdrawCryptoRequest)
if !areTestAPIKeysSet() && err == nil {
t.Errorf("Expecting an error when no keys are set: %v", err)
t.Error("Expecting an error when no keys are set")
}
if areTestAPIKeysSet() && err != nil {
t.Errorf("Withdraw failed to be placed: %v", err)

View File

@@ -6,6 +6,7 @@ import (
"strconv"
"strings"
"sync"
"time"
"github.com/thrasher-/gocryptotrader/common"
"github.com/thrasher-/gocryptotrader/currency/pair"
@@ -150,7 +151,7 @@ func (l *LakeBTC) GetExchangeHistory(p pair.CurrencyPair, assetType string) ([]e
// SubmitOrder submits a new order
func (l *LakeBTC) SubmitOrder(p pair.CurrencyPair, side exchange.OrderSide, orderType exchange.OrderType, amount, price float64, clientID string) (exchange.SubmitOrderResponse, error) {
var submitOrderResponse exchange.SubmitOrderResponse
isBuyOrder := side == exchange.Buy
isBuyOrder := side == exchange.BuyOrderSide
response, err := l.Trade(isBuyOrder, amount, price, common.StringToLower(p.Pair().String()))
if response.ID > 0 {
@@ -264,3 +265,70 @@ func (l *LakeBTC) GetFeeByType(feeBuilder exchange.FeeBuilder) (float64, error)
func (l *LakeBTC) GetWithdrawCapabilities() uint32 {
return l.GetWithdrawPermissions()
}
// GetActiveOrders retrieves any orders that are active/open
func (l *LakeBTC) GetActiveOrders(getOrdersRequest exchange.GetOrdersRequest) ([]exchange.OrderDetail, error) {
resp, err := l.GetOpenOrders()
if err != nil {
return nil, err
}
var orders []exchange.OrderDetail
for _, order := range resp {
symbol := pair.NewCurrencyPairDelimiter(order.Symbol, l.ConfigCurrencyPairFormat.Delimiter)
orderDate := time.Unix(order.At, 0)
side := exchange.OrderSide(strings.ToUpper(order.Type))
orders = append(orders, exchange.OrderDetail{
Amount: order.Amount,
ID: fmt.Sprintf("%v", order.ID),
Price: order.Price,
OrderSide: side,
OrderDate: orderDate,
CurrencyPair: symbol,
Exchange: l.Name,
})
}
exchange.FilterOrdersByTickRange(&orders, getOrdersRequest.StartTicks, getOrdersRequest.EndTicks)
exchange.FilterOrdersBySide(&orders, getOrdersRequest.OrderSide)
exchange.FilterOrdersByCurrencies(&orders, getOrdersRequest.Currencies)
return orders, nil
}
// GetOrderHistory retrieves account order information
// Can Limit response to specific order status
func (l *LakeBTC) GetOrderHistory(getOrdersRequest exchange.GetOrdersRequest) ([]exchange.OrderDetail, error) {
resp, err := l.GetOrders([]int64{})
if err != nil {
return nil, err
}
var orders []exchange.OrderDetail
for _, order := range resp {
if order.State == "active" {
continue
}
symbol := pair.NewCurrencyPairDelimiter(order.Symbol, l.ConfigCurrencyPairFormat.Delimiter)
orderDate := time.Unix(order.At, 0)
side := exchange.OrderSide(strings.ToUpper(order.Type))
orders = append(orders, exchange.OrderDetail{
Amount: order.Amount,
ID: fmt.Sprintf("%v", order.ID),
Price: order.Price,
OrderSide: side,
OrderDate: orderDate,
CurrencyPair: symbol,
Exchange: l.Name,
})
}
exchange.FilterOrdersByTickRange(&orders, getOrdersRequest.StartTicks, getOrdersRequest.EndTicks)
exchange.FilterOrdersBySide(&orders, getOrdersRequest.OrderSide)
exchange.FilterOrdersByCurrencies(&orders, getOrdersRequest.Currencies)
return orders, nil
}

View File

@@ -212,8 +212,8 @@ func (l *Liqui) Trade(pair, orderType string, amount, price float64) (float64, e
return result.OrderID, err
}
// GetActiveOrders returns the list of your active orders.
func (l *Liqui) GetActiveOrders(pair string) (map[string]ActiveOrders, error) {
// GetOpenOrders returns the list of your active orders.
func (l *Liqui) GetOpenOrders(pair string) (map[string]ActiveOrders, error) {
result := make(map[string]ActiveOrders)
req := url.Values{}

View File

@@ -30,7 +30,6 @@ func TestSetup(t *testing.T) {
if err != nil {
t.Error("Test Failed - liqui Setup() init error")
}
liquiConfig.AuthenticatedAPISupport = true
liquiConfig.APIKey = apiKey
liquiConfig.APISecret = apiSecret
@@ -90,7 +89,7 @@ func TestAuthRequests(t *testing.T) {
t.Error("Test Failed - liqui Trade() error", err)
}
_, err = l.GetActiveOrders("eth_btc")
_, err = l.GetOpenOrders("eth_btc")
if err == nil {
t.Error("Test Failed - liqui GetActiveOrders() error", err)
}
@@ -223,17 +222,47 @@ func TestGetFee(t *testing.T) {
}
func TestFormatWithdrawPermissions(t *testing.T) {
// Arrange
l.SetDefaults()
expectedResult := exchange.WithdrawCryptoWithAPIPermissionText + " & " + exchange.NoFiatWithdrawalsText
// Act
withdrawPermissions := l.FormatWithdrawPermissions()
// Assert
if withdrawPermissions != expectedResult {
t.Errorf("Expected: %s, Received: %s", expectedResult, withdrawPermissions)
}
}
func TestGetActiveOrders(t *testing.T) {
l.SetDefaults()
TestSetup(t)
var getOrdersRequest = exchange.GetOrdersRequest{
OrderType: exchange.AnyOrderType,
Currencies: []pair.CurrencyPair{pair.NewCurrencyPair(symbol.BTC, symbol.USDT)},
}
_, err := l.GetActiveOrders(getOrdersRequest)
if areTestAPIKeysSet() && err != nil {
t.Errorf("Could not get open orders: %s", err)
} else if !areTestAPIKeysSet() && err == nil {
t.Error("Expecting an error when no keys are set")
}
}
func TestGetOrderHistory(t *testing.T) {
l.SetDefaults()
TestSetup(t)
var getOrdersRequest = exchange.GetOrdersRequest{
OrderType: exchange.AnyOrderType,
}
_, err := l.GetOrderHistory(getOrdersRequest)
if err != common.ErrFunctionNotSupported {
t.Errorf("Expected '%v', received: '%v'", common.ErrFunctionNotSupported, err)
}
}
// Any tests below this line have the ability to impact your orders on the exchange. Enable canManipulateRealOrders to run them
// ----------------------------------------------------------------------------------------------------------------------------
func areTestAPIKeysSet() bool {
@@ -256,7 +285,7 @@ func TestSubmitOrder(t *testing.T) {
FirstCurrency: symbol.BTC,
SecondCurrency: symbol.EUR,
}
response, err := l.SubmitOrder(p, exchange.Buy, exchange.Market, 1, 10, "hi")
response, err := l.SubmitOrder(p, exchange.BuyOrderSide, exchange.MarketOrderType, 1, 10, "hi")
if areTestAPIKeysSet() && (err != nil || !response.IsOrderPlaced) {
t.Errorf("Order failed to be placed: %v", err)
} else if !areTestAPIKeysSet() && err == nil {
@@ -265,7 +294,6 @@ func TestSubmitOrder(t *testing.T) {
}
func TestCancelExchangeOrder(t *testing.T) {
// Arrange
l.SetDefaults()
TestSetup(t)
@@ -281,11 +309,9 @@ func TestCancelExchangeOrder(t *testing.T) {
CurrencyPair: currencyPair,
}
// Act
err := l.CancelOrder(orderCancellation)
// Assert
if !areTestAPIKeysSet() && err == nil {
t.Errorf("Expecting an error when no keys are set: %v", err)
t.Error("Expecting an error when no keys are set")
}
if areTestAPIKeysSet() && err != nil {
t.Errorf("Could not cancel orders: %v", err)
@@ -293,7 +319,6 @@ func TestCancelExchangeOrder(t *testing.T) {
}
func TestCancelAllExchangeOrders(t *testing.T) {
// Arrange
l.SetDefaults()
TestSetup(t)
@@ -309,11 +334,10 @@ func TestCancelAllExchangeOrders(t *testing.T) {
CurrencyPair: currencyPair,
}
// Act
resp, err := l.CancelAllOrders(orderCancellation)
// Assert
if !areTestAPIKeysSet() && err == nil {
t.Errorf("Expecting an error when no keys are set: %v", err)
t.Error("Expecting an error when no keys are set")
}
if areTestAPIKeysSet() && err != nil {
t.Errorf("Could not cancel orders: %v", err)
@@ -347,7 +371,7 @@ func TestWithdraw(t *testing.T) {
_, err := l.WithdrawCryptocurrencyFunds(withdrawCryptoRequest)
if !areTestAPIKeysSet() && err == nil {
t.Errorf("Expecting an error when no keys are set: %v", err)
t.Error("Expecting an error when no keys are set")
}
if areTestAPIKeysSet() && err != nil {
t.Errorf("Withdraw failed to be placed: %v", err)

View File

@@ -1,9 +1,12 @@
package liqui
import (
"errors"
"fmt"
"strconv"
"strings"
"sync"
"time"
"github.com/thrasher-/gocryptotrader/common"
"github.com/thrasher-/gocryptotrader/currency/pair"
@@ -192,7 +195,7 @@ func (l *Liqui) CancelAllOrders(orderCancellation exchange.OrderCancellation) (e
cancelAllOrdersResponse := exchange.CancelAllOrdersResponse{
OrderStatus: make(map[string]string),
}
activeOrders, err := l.GetActiveOrders("")
activeOrders, err := l.GetOpenOrders("")
if err != nil {
return cancelAllOrdersResponse, err
}
@@ -260,3 +263,45 @@ func (l *Liqui) GetFeeByType(feeBuilder exchange.FeeBuilder) (float64, error) {
func (l *Liqui) GetWithdrawCapabilities() uint32 {
return l.GetWithdrawPermissions()
}
// GetActiveOrders retrieves any orders that are active/open
func (l *Liqui) GetActiveOrders(getOrdersRequest exchange.GetOrdersRequest) ([]exchange.OrderDetail, error) {
if len(getOrdersRequest.Currencies) <= 0 {
return nil, errors.New("Currency must be supplied")
}
var orders []exchange.OrderDetail
for _, currency := range getOrdersRequest.Currencies {
resp, err := l.GetOpenOrders(exchange.FormatExchangeCurrency(l.Name, currency).String())
if err != nil {
return nil, err
}
for ID, order := range resp {
symbol := pair.NewCurrencyPairDelimiter(order.Pair, l.ConfigCurrencyPairFormat.Delimiter)
orderDate := time.Unix(int64(order.TimestampCreated), 0)
side := exchange.OrderSide(strings.ToUpper(order.Type))
orders = append(orders, exchange.OrderDetail{
Amount: order.Amount,
ID: ID,
Price: order.Rate,
OrderSide: side,
OrderDate: orderDate,
Exchange: l.Name,
CurrencyPair: symbol,
})
}
}
exchange.FilterOrdersByTickRange(&orders, getOrdersRequest.StartTicks, getOrdersRequest.EndTicks)
exchange.FilterOrdersBySide(&orders, getOrdersRequest.OrderSide)
return orders, nil
}
// GetOrderHistory retrieves account order information
// Can Limit response to specific order status
func (l *Liqui) GetOrderHistory(getOrdersRequest exchange.GetOrdersRequest) ([]exchange.OrderDetail, error) {
return nil, common.ErrFunctionNotSupported
}

View File

@@ -98,6 +98,8 @@ const (
localbitcoinsAuthRate = 0
localbitcoinsUnauthRate = 1
// String response used with order status
null = "null"
)
var (

View File

@@ -31,7 +31,6 @@ func TestSetup(t *testing.T) {
if err != nil {
t.Error("Test Failed - LakeBTC Setup() init error")
}
localbitcoinsConfig.AuthenticatedAPISupport = true
localbitcoinsConfig.APIKey = apiKey
localbitcoinsConfig.APISecret = apiSecret
@@ -188,17 +187,48 @@ func TestGetFee(t *testing.T) {
}
func TestFormatWithdrawPermissions(t *testing.T) {
// Arrange
l.SetDefaults()
expectedResult := exchange.AutoWithdrawCryptoText + " & " + exchange.WithdrawFiatViaWebsiteOnlyText
// Act
withdrawPermissions := l.FormatWithdrawPermissions()
// Assert
if withdrawPermissions != expectedResult {
t.Errorf("Expected: %s, Received: %s", expectedResult, withdrawPermissions)
}
}
func TestGetActiveOrders(t *testing.T) {
l.SetDefaults()
TestSetup(t)
var getOrdersRequest = exchange.GetOrdersRequest{
OrderType: exchange.AnyOrderType,
}
_, err := l.GetActiveOrders(getOrdersRequest)
if areTestAPIKeysSet() && err != nil {
t.Errorf("Could not get open orders: %s", err)
} else if !areTestAPIKeysSet() && err == nil {
t.Error("Expecting an error when no keys are set")
}
}
func TestGetOrderHistory(t *testing.T) {
l.SetDefaults()
TestSetup(t)
var getOrdersRequest = exchange.GetOrdersRequest{
OrderType: exchange.AnyOrderType,
}
_, err := l.GetOrderHistory(getOrdersRequest)
if areTestAPIKeysSet() && err != nil {
t.Errorf("Could not get order history: %s", err)
} else if !areTestAPIKeysSet() && err == nil {
t.Error("Expecting an error when no keys are set")
}
}
// Any tests below this line have the ability to impact your orders on the exchange. Enable canManipulateRealOrders to run them
// ----------------------------------------------------------------------------------------------------------------------------
func areTestAPIKeysSet() bool {
@@ -222,7 +252,7 @@ func TestSubmitOrder(t *testing.T) {
FirstCurrency: symbol.BTC,
SecondCurrency: symbol.EUR,
}
response, err := l.SubmitOrder(p, exchange.Buy, exchange.Market, 1, 10, "hi")
response, err := l.SubmitOrder(p, exchange.BuyOrderSide, exchange.MarketOrderType, 1, 10, "hi")
if areTestAPIKeysSet() && (err != nil || !response.IsOrderPlaced) {
t.Errorf("Order failed to be placed: %v", err)
} else if !areTestAPIKeysSet() && err == nil {
@@ -231,7 +261,6 @@ func TestSubmitOrder(t *testing.T) {
}
func TestCancelExchangeOrder(t *testing.T) {
// Arrange
l.SetDefaults()
TestSetup(t)
@@ -248,12 +277,9 @@ func TestCancelExchangeOrder(t *testing.T) {
CurrencyPair: currencyPair,
}
// Act
err := l.CancelOrder(orderCancellation)
// Assert
if !areTestAPIKeysSet() && err == nil {
t.Errorf("Expecting an error when no keys are set: %v", err)
t.Error("Expecting an error when no keys are set")
}
if areTestAPIKeysSet() && err != nil {
t.Errorf("Could not cancel orders: %v", err)
@@ -261,7 +287,6 @@ func TestCancelExchangeOrder(t *testing.T) {
}
func TestCancelAllExchangeOrders(t *testing.T) {
// Arrange
l.SetDefaults()
TestSetup(t)
@@ -278,12 +303,10 @@ func TestCancelAllExchangeOrders(t *testing.T) {
CurrencyPair: currencyPair,
}
// Act
resp, err := l.CancelAllOrders(orderCancellation)
// Assert
if !areTestAPIKeysSet() && err == nil {
t.Errorf("Expecting an error when no keys are set: %v", err)
t.Error("Expecting an error when no keys are set")
}
if areTestAPIKeysSet() && err != nil {
t.Errorf("Could not cancel orders: %v", err)
@@ -317,7 +340,7 @@ func TestWithdraw(t *testing.T) {
_, err := l.WithdrawCryptocurrencyFunds(withdrawCryptoRequest)
if !areTestAPIKeysSet() && err == nil {
t.Errorf("Expecting an error when no keys are set: %v", err)
t.Error("Expecting an error when no keys are set")
}
if areTestAPIKeysSet() && err != nil {
t.Errorf("Withdraw failed to be placed: %v", err)

View File

@@ -7,6 +7,7 @@ import (
"strconv"
"strings"
"sync"
"time"
"github.com/thrasher-/gocryptotrader/currency/symbol"
@@ -293,3 +294,108 @@ func (l *LocalBitcoins) GetFeeByType(feeBuilder exchange.FeeBuilder) (float64, e
func (l *LocalBitcoins) GetWithdrawCapabilities() uint32 {
return l.GetWithdrawPermissions()
}
// GetActiveOrders retrieves any orders that are active/open
func (l *LocalBitcoins) GetActiveOrders(getOrdersRequest exchange.GetOrdersRequest) ([]exchange.OrderDetail, error) {
resp, err := l.GetDashboardInfo()
if err != nil {
return nil, err
}
var orders []exchange.OrderDetail
for _, trade := range resp {
orderDate, err := time.Parse(time.RFC3339, trade.Data.CreatedAt)
if err != nil {
log.Warnf("Exchange %v Func %v Order %v Could not parse date to unix with value of %v",
l.Name, "GetActiveOrders", trade.Data.Advertisement.ID, trade.Data.CreatedAt)
}
var side exchange.OrderSide
if trade.Data.IsBuying {
side = exchange.BuyOrderSide
} else if trade.Data.IsSelling {
side = exchange.SellOrderSide
}
orders = append(orders, exchange.OrderDetail{
Amount: trade.Data.AmountBTC,
Price: trade.Data.Amount,
ID: fmt.Sprintf("%v", trade.Data.Advertisement.ID),
OrderDate: orderDate,
Fee: trade.Data.FeeBTC,
OrderSide: side,
CurrencyPair: pair.NewCurrencyPairWithDelimiter(symbol.BTC, trade.Data.Currency, l.ConfigCurrencyPairFormat.Delimiter),
Exchange: l.Name,
})
}
exchange.FilterOrdersByTickRange(&orders, getOrdersRequest.StartTicks, getOrdersRequest.EndTicks)
exchange.FilterOrdersBySide(&orders, getOrdersRequest.OrderSide)
return orders, nil
}
// GetOrderHistory retrieves account order information
// Can Limit response to specific order status
func (l *LocalBitcoins) GetOrderHistory(getOrdersRequest exchange.GetOrdersRequest) ([]exchange.OrderDetail, error) {
var allTrades []DashBoardInfo
resp, err := l.GetDashboardCancelledTrades()
if err != nil {
return nil, err
}
allTrades = append(allTrades, resp...)
resp, err = l.GetDashboardClosedTrades()
if err != nil {
return nil, err
}
allTrades = append(allTrades, resp...)
resp, err = l.GetDashboardReleasedTrades()
if err != nil {
return nil, err
}
allTrades = append(allTrades, resp...)
var orders []exchange.OrderDetail
for _, trade := range allTrades {
orderDate, err := time.Parse(time.RFC3339, trade.Data.CreatedAt)
if err != nil {
log.Warnf("Exchange %v Func %v Order %v Could not parse date to unix with value of %v",
l.Name, "GetActiveOrders", trade.Data.Advertisement.ID, trade.Data.CreatedAt)
}
var side exchange.OrderSide
if trade.Data.IsBuying {
side = exchange.BuyOrderSide
} else if trade.Data.IsSelling {
side = exchange.SellOrderSide
}
status := ""
if trade.Data.ReleasedAt != "" && trade.Data.ReleasedAt != null {
status = "Released"
} else if trade.Data.CanceledAt != "" && trade.Data.CanceledAt != null {
status = "Cancelled"
} else if trade.Data.ClosedAt != "" && trade.Data.ClosedAt != null {
status = "Closed"
}
orders = append(orders, exchange.OrderDetail{
Amount: trade.Data.AmountBTC,
Price: trade.Data.Amount,
ID: fmt.Sprintf("%v", trade.Data.Advertisement.ID),
OrderDate: orderDate,
Fee: trade.Data.FeeBTC,
OrderSide: side,
Status: status,
CurrencyPair: pair.NewCurrencyPairWithDelimiter(symbol.BTC, trade.Data.Currency, l.ConfigCurrencyPairFormat.Delimiter),
Exchange: l.Name,
})
}
exchange.FilterOrdersByTickRange(&orders, getOrdersRequest.StartTicks, getOrdersRequest.EndTicks)
exchange.FilterOrdersBySide(&orders, getOrdersRequest.OrderSide)
return orders, nil
}

View File

@@ -533,11 +533,11 @@ func (o *OKCoin) GetOrderInfoBatch(orderID []int64, symbol string) ([]OrderInfo,
return result.Orders, nil
}
// GetOrderHistory returns a history of orders
func (o *OKCoin) GetOrderHistory(pageLength, currentPage int64, status, symbol string) (OrderHistory, error) {
// GetOrderHistoryForCurrency returns a history of orders
func (o *OKCoin) GetOrderHistoryForCurrency(pageLength, currentPage, status int64, symbol string) (OrderHistory, error) {
v := url.Values{}
v.Set("symbol", symbol)
v.Set("status", status)
v.Set("status", strconv.FormatInt(status, 10))
v.Set("current_page", strconv.FormatInt(currentPage, 10))
v.Set("page_length", strconv.FormatInt(pageLength, 10))
result := OrderHistory{}

View File

@@ -31,7 +31,6 @@ func TestSetup(t *testing.T) {
if err != nil {
t.Error("Test Failed - OKCoin Setup() init error")
}
okcoinConfig.AuthenticatedAPISupport = true
okcoinConfig.APIKey = apiKey
okcoinConfig.APISecret = apiSecret
@@ -138,17 +137,50 @@ func TestGetFee(t *testing.T) {
}
func TestFormatWithdrawPermissions(t *testing.T) {
// Arrange
o.SetDefaults()
expectedResult := exchange.AutoWithdrawCryptoText + " & " + exchange.WithdrawFiatViaWebsiteOnlyText
// Act
withdrawPermissions := o.FormatWithdrawPermissions()
// Assert
if withdrawPermissions != expectedResult {
t.Errorf("Expected: %s, Received: %s", expectedResult, withdrawPermissions)
}
}
func TestGetActiveOrders(t *testing.T) {
o.SetDefaults()
TestSetup(t)
var getOrdersRequest = exchange.GetOrdersRequest{
OrderType: exchange.AnyOrderType,
Currencies: []pair.CurrencyPair{pair.NewCurrencyPair(symbol.LTC, symbol.BTC)},
}
_, err := o.GetActiveOrders(getOrdersRequest)
if areTestAPIKeysSet() && err != nil {
t.Errorf("Could not get open orders: %s", err)
} else if !areTestAPIKeysSet() && err == nil {
t.Error("Expecting an error when no keys are set")
}
}
func TestGetOrderHistory(t *testing.T) {
o.SetDefaults()
TestSetup(t)
var getOrdersRequest = exchange.GetOrdersRequest{
OrderType: exchange.AnyOrderType,
Currencies: []pair.CurrencyPair{pair.NewCurrencyPair(symbol.LTC, symbol.BTC)},
}
_, err := o.GetOrderHistory(getOrdersRequest)
if areTestAPIKeysSet() && err != nil {
t.Errorf("Could not get order history: %s", err)
} else if !areTestAPIKeysSet() && err == nil {
t.Error("Expecting an error when no keys are set")
}
}
// Any tests below this line have the ability to impact your orders on the exchange. Enable canManipulateRealOrders to run them
// ----------------------------------------------------------------------------------------------------------------------------
func areTestAPIKeysSet() bool {
@@ -172,7 +204,7 @@ func TestSubmitOrder(t *testing.T) {
FirstCurrency: symbol.BTC,
SecondCurrency: symbol.EUR,
}
response, err := o.SubmitOrder(p, exchange.Buy, exchange.Market, 1, 10, "hi")
response, err := o.SubmitOrder(p, exchange.BuyOrderSide, exchange.MarketOrderType, 1, 10, "hi")
if areTestAPIKeysSet() && (err != nil || !response.IsOrderPlaced) {
t.Errorf("Order failed to be placed: %v", err)
} else if !areTestAPIKeysSet() && err == nil {
@@ -181,7 +213,6 @@ func TestSubmitOrder(t *testing.T) {
}
func TestCancelExchangeOrder(t *testing.T) {
// Arrange
o.SetDefaults()
TestSetup(t)
if areTestAPIKeysSet() && !canManipulateRealOrders {
@@ -197,11 +228,9 @@ func TestCancelExchangeOrder(t *testing.T) {
CurrencyPair: currencyPair,
}
// Act
err := o.CancelOrder(orderCancellation)
// Assert
if !areTestAPIKeysSet() && err == nil {
t.Errorf("Expecting an error when no keys are set: %v", err)
t.Error("Expecting an error when no keys are set")
}
if areTestAPIKeysSet() && err != nil {
t.Errorf("Could not cancel orders: %v", err)
@@ -209,7 +238,6 @@ func TestCancelExchangeOrder(t *testing.T) {
}
func TestCancelAllExchangeOrders(t *testing.T) {
// Arrange
o.SetDefaults()
TestSetup(t)
@@ -226,12 +254,10 @@ func TestCancelAllExchangeOrders(t *testing.T) {
CurrencyPair: currencyPair,
}
// Act
resp, err := o.CancelAllOrders(orderCancellation)
// Assert
if !areTestAPIKeysSet() && err == nil {
t.Errorf("Expecting an error when no keys are set: %v", err)
t.Error("Expecting an error when no keys are set")
}
if areTestAPIKeysSet() && err != nil {
t.Errorf("Could not cancel orders: %v", err)
@@ -267,7 +293,7 @@ func TestWithdraw(t *testing.T) {
_, err := o.WithdrawCryptocurrencyFunds(withdrawCryptoRequest)
if !areTestAPIKeysSet() && err == nil {
t.Errorf("Expecting an error when no keys are set: %v", err)
t.Error("Expecting an error when no keys are set")
}
if areTestAPIKeysSet() && err != nil {
t.Errorf("Withdraw failed to be placed: %v", err)

View File

@@ -4,7 +4,9 @@ import (
"errors"
"fmt"
"strconv"
"strings"
"sync"
"time"
"github.com/thrasher-/gocryptotrader/common"
"github.com/thrasher-/gocryptotrader/currency/pair"
@@ -202,14 +204,14 @@ func (o *OKCoin) GetExchangeHistory(p pair.CurrencyPair, assetType string) ([]ex
func (o *OKCoin) SubmitOrder(p pair.CurrencyPair, side exchange.OrderSide, orderType exchange.OrderType, amount, price float64, clientID string) (exchange.SubmitOrderResponse, error) {
var submitOrderResponse exchange.SubmitOrderResponse
var oT string
if orderType == exchange.Limit {
if side == exchange.Buy {
if orderType == exchange.LimitOrderType {
if side == exchange.BuyOrderSide {
oT = "buy"
} else {
oT = "sell"
}
} else if orderType == exchange.Market {
if side == exchange.Buy {
} else if orderType == exchange.MarketOrderType {
if side == exchange.BuyOrderSide {
oT = "buy_market"
} else {
oT = "sell_market"
@@ -329,3 +331,75 @@ func (o *OKCoin) GetFeeByType(feeBuilder exchange.FeeBuilder) (float64, error) {
func (o *OKCoin) GetWithdrawCapabilities() uint32 {
return o.GetWithdrawPermissions()
}
// GetActiveOrders retrieves any orders that are active/open
func (o *OKCoin) GetActiveOrders(getOrdersRequest exchange.GetOrdersRequest) ([]exchange.OrderDetail, error) {
var allOrders []OrderInfo
for _, currency := range getOrdersRequest.Currencies {
resp, err := o.GetOrderHistoryForCurrency(200, 0, 0, exchange.FormatExchangeCurrency(o.Name, currency).String())
if err != nil {
return nil, err
}
allOrders = append(allOrders, resp.Orders...)
}
var orders []exchange.OrderDetail
for _, order := range allOrders {
// Status 2 == Filled, -1 == Cancelled.
if order.Status == 2 || order.Status == -1 {
continue
}
symbol := pair.NewCurrencyPairDelimiter(order.Symbol, o.ConfigCurrencyPairFormat.Delimiter)
orderDate := time.Unix(order.Created, 0)
side := exchange.OrderSide(strings.ToUpper(order.Type))
orders = append(orders, exchange.OrderDetail{
ID: fmt.Sprintf("%v", order.OrderID),
Amount: order.Amount,
OrderDate: orderDate,
Price: order.Price,
OrderSide: side,
CurrencyPair: symbol,
Exchange: o.Name,
})
}
exchange.FilterOrdersByTickRange(&orders, getOrdersRequest.StartTicks, getOrdersRequest.EndTicks)
exchange.FilterOrdersBySide(&orders, getOrdersRequest.OrderSide)
return orders, nil
}
// GetOrderHistory retrieves account order information
// Can Limit response to specific order status
func (o *OKCoin) GetOrderHistory(getOrdersRequest exchange.GetOrdersRequest) ([]exchange.OrderDetail, error) {
var allOrders []OrderInfo
for _, currency := range getOrdersRequest.Currencies {
resp, err := o.GetOrderInformation(-1, exchange.FormatExchangeCurrency(o.Name, currency).String())
if err != nil {
return nil, err
}
allOrders = append(allOrders, resp...)
}
var orders []exchange.OrderDetail
for _, order := range allOrders {
symbol := pair.NewCurrencyPairDelimiter(order.Symbol, o.ConfigCurrencyPairFormat.Delimiter)
orderDate := time.Unix(order.Created, 0)
side := exchange.OrderSide(strings.ToUpper(order.Type))
orders = append(orders, exchange.OrderDetail{
ID: fmt.Sprintf("%v", order.OrderID),
Amount: order.Amount,
OrderDate: orderDate,
Price: order.Price,
OrderSide: side,
CurrencyPair: symbol,
Exchange: o.Name,
})
}
exchange.FilterOrdersByTickRange(&orders, getOrdersRequest.StartTicks, getOrdersRequest.EndTicks)
exchange.FilterOrdersBySide(&orders, getOrdersRequest.OrderSide)
return orders, nil
}

View File

@@ -64,7 +64,8 @@ const (
spotTrade = "trade"
spotBatchTrade = "batch_trade"
spotCancelTrade = "cancel_order"
spotOrderInfo = "order_info"
spotOrderInfo = "order_info.do"
spotOrderHistory = "order_history.do"
spotMultiOrderInfo = "orders_info"
spotWithdraw = "withdraw.do"
spotCancelWithdraw = "cancel_withdraw"
@@ -1256,3 +1257,44 @@ func (o *OKEX) Withdrawal(symbol string, fee float64, tradePWD, address string,
return resp.WithdrawID, nil
}
// GetOrderInformation withdraws a cryptocurrency to a supplied address
func (o *OKEX) GetOrderInformation(orderID int64, symbol string) ([]OrderInfo, error) {
type Response struct {
Result bool `json:"result"`
Orders []OrderInfo `json:"orders"`
}
v := url.Values{}
v.Set("symbol", symbol)
v.Set("order_id", strconv.FormatInt(orderID, 10))
result := Response{}
err := o.SendAuthenticatedHTTPRequest(spotOrderInfo, v, &result)
if err != nil {
return nil, err
}
if !result.Result {
return nil, errors.New("unable to retrieve order info")
}
return result.Orders, nil
}
// GetOrderHistoryForCurrency returns a history of orders
func (o *OKEX) GetOrderHistoryForCurrency(pageLength, currentPage, status int64, symbol string) (OrderHistory, error) {
v := url.Values{}
v.Set("symbol", symbol)
v.Set("status", strconv.FormatInt(status, 10))
v.Set("current_page", strconv.FormatInt(currentPage, 10))
v.Set("page_length", strconv.FormatInt(pageLength, 10))
result := OrderHistory{}
err := o.SendAuthenticatedHTTPRequest(spotOrderHistory, v, &result)
if err != nil {
return result, err
}
return result, nil
}

View File

@@ -33,7 +33,6 @@ func TestSetup(t *testing.T) {
if err != nil {
t.Error("Test Failed - Okex Setup() init error")
}
okexConfig.AuthenticatedAPISupport = true
okexConfig.APIKey = apiKey
okexConfig.APISecret = apiSecret
@@ -387,17 +386,50 @@ func TestGetFee(t *testing.T) {
}
func TestFormatWithdrawPermissions(t *testing.T) {
// Arrange
o.SetDefaults()
expectedResult := exchange.AutoWithdrawCryptoText + " & " + exchange.NoFiatWithdrawalsText
// Act
withdrawPermissions := o.FormatWithdrawPermissions()
// Assert
if withdrawPermissions != expectedResult {
t.Errorf("Expected: %s, Received: %s", expectedResult, withdrawPermissions)
}
}
func TestGetActiveOrders(t *testing.T) {
o.SetDefaults()
TestSetup(t)
var getOrdersRequest = exchange.GetOrdersRequest{
OrderType: exchange.AnyOrderType,
Currencies: []pair.CurrencyPair{pair.NewCurrencyPair(symbol.LTC, symbol.BTC)},
}
_, err := o.GetActiveOrders(getOrdersRequest)
if areTestAPIKeysSet() && err != nil {
t.Errorf("Could not get open orders: %s", err)
} else if !areTestAPIKeysSet() && err == nil {
t.Error("Expecting an error when no keys are set")
}
}
func TestGetOrderHistory(t *testing.T) {
o.SetDefaults()
TestSetup(t)
var getOrdersRequest = exchange.GetOrdersRequest{
OrderType: exchange.AnyOrderType,
Currencies: []pair.CurrencyPair{pair.NewCurrencyPair(symbol.LTC, symbol.BTC)},
}
_, err := o.GetOrderHistory(getOrdersRequest)
if areTestAPIKeysSet() && err != nil {
t.Errorf("Could not get order history: %s", err)
} else if !areTestAPIKeysSet() && err == nil {
t.Error("Expecting an error when no keys are set")
}
}
// Any tests below this line have the ability to impact your orders on the exchange. Enable canManipulateRealOrders to run them
// ----------------------------------------------------------------------------------------------------------------------------
func areTestAPIKeysSet() bool {
@@ -421,7 +453,7 @@ func TestSubmitOrder(t *testing.T) {
FirstCurrency: symbol.BTC,
SecondCurrency: symbol.EUR,
}
response, err := o.SubmitOrder(p, exchange.Buy, exchange.Market, 1, 10, "hi")
response, err := o.SubmitOrder(p, exchange.BuyOrderSide, exchange.MarketOrderType, 1, 10, "hi")
if areTestAPIKeysSet() && (err != nil || !response.IsOrderPlaced) {
t.Errorf("Order failed to be placed: %v", err)
} else if !areTestAPIKeysSet() && err == nil {
@@ -430,7 +462,6 @@ func TestSubmitOrder(t *testing.T) {
}
func TestCancelExchangeOrder(t *testing.T) {
// Arrange
o.SetDefaults()
TestSetup(t)
@@ -447,12 +478,9 @@ func TestCancelExchangeOrder(t *testing.T) {
CurrencyPair: currencyPair,
}
// Act
err := o.CancelOrder(orderCancellation)
// Assert
if !areTestAPIKeysSet() && err == nil {
t.Errorf("Expecting an error when no keys are set: %v", err)
t.Error("Expecting an error when no keys are set")
}
if areTestAPIKeysSet() && err != nil {
t.Errorf("Could not cancel orders: %v", err)
@@ -460,7 +488,6 @@ func TestCancelExchangeOrder(t *testing.T) {
}
func TestCancelAllExchangeOrders(t *testing.T) {
// Arrange
o.SetDefaults()
TestSetup(t)
@@ -477,12 +504,10 @@ func TestCancelAllExchangeOrders(t *testing.T) {
CurrencyPair: currencyPair,
}
// Act
resp, err := o.CancelAllOrders(orderCancellation)
// Assert
if !areTestAPIKeysSet() && err == nil {
t.Errorf("Expecting an error when no keys are set: %v", err)
t.Error("Expecting an error when no keys are set")
}
if areTestAPIKeysSet() && err != nil {
t.Errorf("Could not cancel orders: %v", err)
@@ -532,7 +557,7 @@ func TestWithdraw(t *testing.T) {
_, err := o.WithdrawCryptocurrencyFunds(withdrawCryptoRequest)
if !areTestAPIKeysSet() && err == nil {
t.Errorf("Expecting an error when no keys are set: %v", err)
t.Error("Expecting an error when no keys are set")
}
if areTestAPIKeysSet() && err != nil {
t.Errorf("Withdraw failed to be placed: %v", err)

View File

@@ -469,3 +469,26 @@ type WithdrawalResponse struct {
WithdrawID int `json:"withdraw_id"`
Result bool `json:"result"`
}
// OrderInfo holds data on an order
type OrderInfo struct {
Amount float64 `json:"amount"`
AvgPrice float64 `json:"avg_price"`
Created int64 `json:"create_date"`
DealAmount float64 `json:"deal_amount"`
OrderID int64 `json:"order_id"`
OrdersID int64 `json:"orders_id"`
Price float64 `json:"price"`
Status int `json:"status"`
Symbol string `json:"symbol"`
Type string `json:"type"`
}
// OrderHistory holds information on order history
type OrderHistory struct {
CurrentPage int `json:"current_page"`
Orders []OrderInfo `json:"orders"`
PageLength int `json:"page_length"`
Result bool `json:"result"`
Total int `json:"total"`
}

View File

@@ -4,7 +4,9 @@ import (
"errors"
"fmt"
"strconv"
"strings"
"sync"
"time"
"github.com/thrasher-/gocryptotrader/common"
"github.com/thrasher-/gocryptotrader/currency/pair"
@@ -194,14 +196,14 @@ func (o *OKEX) SubmitOrder(p pair.CurrencyPair, side exchange.OrderSide, orderTy
var submitOrderResponse exchange.SubmitOrderResponse
var oT SpotNewOrderRequestType
if orderType == exchange.Limit {
if side == exchange.Buy {
if orderType == exchange.LimitOrderType {
if side == exchange.BuyOrderSide {
oT = SpotNewOrderRequestTypeBuy
} else {
oT = SpotNewOrderRequestTypeSell
}
} else if orderType == exchange.Market {
if side == exchange.Buy {
} else if orderType == exchange.MarketOrderType {
if side == exchange.BuyOrderSide {
oT = SpotNewOrderRequestTypeBuyMarket
} else {
oT = SpotNewOrderRequestTypeSellMarket
@@ -322,3 +324,77 @@ func (o *OKEX) GetFeeByType(feeBuilder exchange.FeeBuilder) (float64, error) {
func (o *OKEX) GetWithdrawCapabilities() uint32 {
return o.GetWithdrawPermissions()
}
// GetActiveOrders retrieves any orders that are active/open
func (o *OKEX) GetActiveOrders(getOrdersRequest exchange.GetOrdersRequest) ([]exchange.OrderDetail, error) {
var allOrders []OrderInfo
for _, currency := range getOrdersRequest.Currencies {
resp, err := o.GetOrderHistoryForCurrency(200, 0, 0, exchange.FormatExchangeCurrency(o.Name, currency).String())
if err != nil {
return nil, err
}
allOrders = append(allOrders, resp.Orders...)
}
var orders []exchange.OrderDetail
for _, order := range allOrders {
// Status 2 == Filled, -1 == Cancelled.
if order.Status == 2 || order.Status == -1 {
continue
}
symbol := pair.NewCurrencyPairDelimiter(order.Symbol, o.ConfigCurrencyPairFormat.Delimiter)
orderDate := time.Unix(order.Created, 0)
side := exchange.OrderSide(strings.ToUpper(order.Type))
orders = append(orders, exchange.OrderDetail{
ID: fmt.Sprintf("%v", order.OrderID),
Amount: order.Amount,
OrderDate: orderDate,
Price: order.Price,
OrderSide: side,
CurrencyPair: symbol,
Exchange: o.Name,
})
}
exchange.FilterOrdersByTickRange(&orders, getOrdersRequest.StartTicks, getOrdersRequest.EndTicks)
exchange.FilterOrdersBySide(&orders, getOrdersRequest.OrderSide)
return orders, nil
}
// GetOrderHistory retrieves account order information
// Can Limit response to specific order status
func (o *OKEX) GetOrderHistory(getOrdersRequest exchange.GetOrdersRequest) ([]exchange.OrderDetail, error) {
var allOrders []OrderInfo
for _, currency := range getOrdersRequest.Currencies {
resp, err := o.GetOrderInformation(-1, exchange.FormatExchangeCurrency(o.Name, currency).String())
if err != nil {
return nil, err
}
allOrders = append(allOrders, resp...)
}
var orders []exchange.OrderDetail
for _, order := range allOrders {
symbol := pair.NewCurrencyPairDelimiter(order.Symbol, o.ConfigCurrencyPairFormat.Delimiter)
orderDate := time.Unix(order.Created, 0)
side := exchange.OrderSide(strings.ToUpper(order.Type))
orders = append(orders, exchange.OrderDetail{
ID: fmt.Sprintf("%v", order.OrderID),
Amount: order.Amount,
OrderDate: orderDate,
Price: order.Price,
OrderSide: side,
CurrencyPair: symbol,
Exchange: o.Name,
})
}
exchange.FilterOrdersByTickRange(&orders, getOrdersRequest.StartTicks, getOrdersRequest.EndTicks)
exchange.FilterOrdersBySide(&orders, getOrdersRequest.OrderSide)
return orders, nil
}

View File

@@ -456,35 +456,24 @@ func (p *Poloniex) GetOpenOrdersForAllCurrencies() (OpenOrdersResponseAll, error
return result, nil
}
// GetAuthenticatedTradeHistory returns account trade history
func (p *Poloniex) GetAuthenticatedTradeHistory(currency, start, end, limit string) (interface{}, error) {
// GetAuthenticatedTradeHistoryForCurrency returns account trade history
func (p *Poloniex) GetAuthenticatedTradeHistoryForCurrency(currency string, start, end, limit int64) (AuthenticatedTradeHistoryResponse, error) {
values := url.Values{}
if start != "" {
values.Set("start", start)
if start > 0 {
values.Set("start", strconv.FormatInt(start, 10))
}
if limit != "" {
values.Set("limit", limit)
if limit > 0 {
values.Set("limit", strconv.FormatInt(limit, 10))
}
if end != "" {
values.Set("end", end)
if end > 0 {
values.Set("end", strconv.FormatInt(end, 10))
}
if currency != "" && currency != "all" {
values.Set("currencyPair", currency)
result := AuthenticatedTradeHistoryResponse{}
err := p.SendAuthenticatedHTTPRequest("POST", poloniexTradeHistory, values, &result.Data)
if err != nil {
return result, err
}
return result, nil
}
values.Set("currencyPair", "all")
result := AuthenticatedTradeHistoryAll{}
values.Set("currencyPair", currency)
result := AuthenticatedTradeHistoryResponse{}
err := p.SendAuthenticatedHTTPRequest("POST", poloniexTradeHistory, values, &result.Data)
if err != nil {
@@ -494,6 +483,39 @@ func (p *Poloniex) GetAuthenticatedTradeHistory(currency, start, end, limit stri
return result, nil
}
// GetAuthenticatedTradeHistory returns account trade history
func (p *Poloniex) GetAuthenticatedTradeHistory(start, end, limit int64) (AuthenticatedTradeHistoryAll, error) {
values := url.Values{}
if start > 0 {
values.Set("start", strconv.FormatInt(start, 10))
}
if limit > 0 {
values.Set("limit", strconv.FormatInt(limit, 10))
}
if end > 0 {
values.Set("end", strconv.FormatInt(end, 10))
}
values.Set("currencyPair", "all")
var result interface{}
err := p.SendAuthenticatedHTTPRequest("POST", poloniexTradeHistory, values, &result)
if err != nil {
return AuthenticatedTradeHistoryAll{}, err
}
// If there are no orders, Poloniex returns an empty array
switch r := result.(type) {
case AuthenticatedTradeHistoryAll:
return r, nil
default:
return AuthenticatedTradeHistoryAll{}, nil
}
}
// PlaceOrder places a new order on the exchange
func (p *Poloniex) PlaceOrder(currency string, rate, amount float64, immediate, fillOrKill, buy bool) (OrderResponse, error) {
result := OrderResponse{}

View File

@@ -31,7 +31,6 @@ func TestSetup(t *testing.T) {
if err != nil {
t.Error("Test Failed - Poloniex Setup() init error")
}
poloniexConfig.AuthenticatedAPISupport = true
poloniexConfig.APIKey = apiKey
poloniexConfig.APISecret = apiSecret
@@ -183,17 +182,48 @@ func TestGetFee(t *testing.T) {
}
func TestFormatWithdrawPermissions(t *testing.T) {
// Arrange
p.SetDefaults()
expectedResult := exchange.AutoWithdrawCryptoWithAPIPermissionText + " & " + exchange.NoFiatWithdrawalsText
// Act
withdrawPermissions := p.FormatWithdrawPermissions()
// Assert
if withdrawPermissions != expectedResult {
t.Errorf("Expected: %s, Received: %s", expectedResult, withdrawPermissions)
}
}
func TestGetActiveOrders(t *testing.T) {
p.SetDefaults()
TestSetup(t)
var getOrdersRequest = exchange.GetOrdersRequest{
OrderType: exchange.AnyOrderType,
}
_, err := p.GetActiveOrders(getOrdersRequest)
if areTestAPIKeysSet() && err != nil {
t.Errorf("Could not get open orders: %s", err)
} else if !areTestAPIKeysSet() && err == nil {
t.Error("Expecting an error when no keys are set")
}
}
func TestGetOrderHistory(t *testing.T) {
p.SetDefaults()
TestSetup(t)
var getOrdersRequest = exchange.GetOrdersRequest{
OrderType: exchange.AnyOrderType,
}
_, err := p.GetOrderHistory(getOrdersRequest)
if areTestAPIKeysSet() && err != nil {
t.Errorf("Could not get order history: %s", err)
} else if !areTestAPIKeysSet() && err == nil {
t.Error("Expecting an error when no keys are set")
}
}
// Any tests below this line have the ability to impact your orders on the exchange. Enable canManipulateRealOrders to run them
// ----------------------------------------------------------------------------------------------------------------------------
func areTestAPIKeysSet() bool {
@@ -217,7 +247,7 @@ func TestSubmitOrder(t *testing.T) {
FirstCurrency: symbol.BTC,
SecondCurrency: symbol.LTC,
}
response, err := p.SubmitOrder(pair, exchange.Buy, exchange.Market, 1, 10, "hi")
response, err := p.SubmitOrder(pair, exchange.BuyOrderSide, exchange.MarketOrderType, 1, 10, "hi")
if areTestAPIKeysSet() && (err != nil || !response.IsOrderPlaced) {
t.Errorf("Order failed to be placed: %v", err)
} else if !areTestAPIKeysSet() && err == nil {
@@ -226,7 +256,6 @@ func TestSubmitOrder(t *testing.T) {
}
func TestCancelExchangeOrder(t *testing.T) {
// Arrange
p.SetDefaults()
TestSetup(t)
@@ -243,12 +272,10 @@ func TestCancelExchangeOrder(t *testing.T) {
CurrencyPair: currencyPair,
}
// Act
err := p.CancelOrder(orderCancellation)
// Assert
if !areTestAPIKeysSet() && err == nil {
t.Errorf("Expecting an error when no keys are set: %v", err)
t.Error("Expecting an error when no keys are set")
}
if areTestAPIKeysSet() && err != nil {
t.Errorf("Could not cancel orders: %v", err)
@@ -256,7 +283,6 @@ func TestCancelExchangeOrder(t *testing.T) {
}
func TestCancelAllExchangeOrders(t *testing.T) {
// Arrange
p.SetDefaults()
TestSetup(t)
@@ -273,12 +299,10 @@ func TestCancelAllExchangeOrders(t *testing.T) {
CurrencyPair: currencyPair,
}
// Act
resp, err := p.CancelAllOrders(orderCancellation)
// Assert
if !areTestAPIKeysSet() && err == nil {
t.Errorf("Expecting an error when no keys are set: %v", err)
t.Error("Expecting an error when no keys are set")
}
if areTestAPIKeysSet() && err != nil {
t.Errorf("Could not cancel orders: %v", err)
@@ -312,7 +336,7 @@ func TestWithdraw(t *testing.T) {
_, err := p.WithdrawCryptocurrencyFunds(withdrawCryptoRequest)
if !areTestAPIKeysSet() && err == nil {
t.Errorf("Expecting an error when no keys are set: %v", err)
t.Error("Expecting an error when no keys are set")
}
if areTestAPIKeysSet() && err != nil {
t.Errorf("Withdraw failed to be placed: %v", err)

View File

@@ -3,7 +3,9 @@ package poloniex
import (
"fmt"
"strconv"
"strings"
"sync"
"time"
"github.com/thrasher-/gocryptotrader/common"
"github.com/thrasher-/gocryptotrader/currency/pair"
@@ -164,8 +166,8 @@ func (p *Poloniex) GetExchangeHistory(currencyPair pair.CurrencyPair, assetType
// SubmitOrder submits a new order
func (p *Poloniex) SubmitOrder(currencyPair pair.CurrencyPair, side exchange.OrderSide, orderType exchange.OrderType, amount, price float64, clientID string) (exchange.SubmitOrderResponse, error) {
var submitOrderResponse exchange.SubmitOrderResponse
fillOrKill := orderType == exchange.Market
isBuyOrder := side == exchange.Buy
fillOrKill := orderType == exchange.MarketOrderType
isBuyOrder := side == exchange.BuyOrderSide
response, err := p.PlaceOrder(currencyPair.Pair().String(), price, amount, false, fillOrKill, isBuyOrder)
if response.OrderNumber > 0 {
@@ -289,3 +291,79 @@ func (p *Poloniex) GetFeeByType(feeBuilder exchange.FeeBuilder) (float64, error)
func (p *Poloniex) GetWithdrawCapabilities() uint32 {
return p.GetWithdrawPermissions()
}
// GetActiveOrders retrieves any orders that are active/open
func (p *Poloniex) GetActiveOrders(getOrdersRequest exchange.GetOrdersRequest) ([]exchange.OrderDetail, error) {
resp, err := p.GetOpenOrdersForAllCurrencies()
if err != nil {
return nil, err
}
var orders []exchange.OrderDetail
for currencyPair, openOrders := range resp.Data {
symbol := pair.NewCurrencyPairDelimiter(currencyPair, p.ConfigCurrencyPairFormat.Delimiter)
for _, order := range openOrders {
orderSide := exchange.OrderSide(strings.ToUpper(order.Type))
orderDate, err := time.Parse(time.RFC3339, order.Date)
if err != nil {
log.Warnf("Exchange %v Func %v Order %v Could not parse date to unix with value of %v",
p.Name, "GetActiveOrders", order.OrderNumber, order.Date)
}
orders = append(orders, exchange.OrderDetail{
ID: fmt.Sprintf("%v", order.OrderNumber),
OrderSide: orderSide,
Amount: order.Amount,
OrderDate: orderDate,
Price: order.Rate,
CurrencyPair: symbol,
Exchange: p.Name,
})
}
}
exchange.FilterOrdersByTickRange(&orders, getOrdersRequest.StartTicks, getOrdersRequest.EndTicks)
exchange.FilterOrdersByCurrencies(&orders, getOrdersRequest.Currencies)
exchange.FilterOrdersBySide(&orders, getOrdersRequest.OrderSide)
return orders, nil
}
// GetOrderHistory retrieves account order information
// Can Limit response to specific order status
func (p *Poloniex) GetOrderHistory(getOrdersRequest exchange.GetOrdersRequest) ([]exchange.OrderDetail, error) {
resp, err := p.GetAuthenticatedTradeHistory(getOrdersRequest.StartTicks.Unix(), getOrdersRequest.EndTicks.Unix(), 10000)
if err != nil {
return nil, err
}
var orders []exchange.OrderDetail
for currencyPair, historicOrders := range resp.Data {
symbol := pair.NewCurrencyPairDelimiter(currencyPair, p.ConfigCurrencyPairFormat.Delimiter)
for _, order := range historicOrders {
orderSide := exchange.OrderSide(strings.ToUpper(order.Type))
orderDate, err := time.Parse(time.RFC3339, order.Date)
if err != nil {
log.Warnf("Exchange %v Func %v Order %v Could not parse date to unix with value of %v",
p.Name, "GetActiveOrders", order.OrderNumber, order.Date)
}
orders = append(orders, exchange.OrderDetail{
ID: fmt.Sprintf("%v", order.GlobalTradeID),
OrderSide: orderSide,
Amount: order.Amount,
OrderDate: orderDate,
Price: order.Rate,
CurrencyPair: symbol,
Exchange: p.Name,
})
}
}
exchange.FilterOrdersByCurrencies(&orders, getOrdersRequest.Currencies)
exchange.FilterOrdersBySide(&orders, getOrdersRequest.OrderSide)
return orders, nil
}

View File

@@ -189,8 +189,8 @@ func (w *WEX) GetAccountInformation() (AccountInfo, error) {
return result, nil
}
// GetActiveOrders returns the active orders for a specific currency
func (w *WEX) GetActiveOrders(pair string) (map[string]ActiveOrders, error) {
// GetOpenOrders returns the active orders for a specific currency
func (w *WEX) GetOpenOrders(pair string) (map[string]ActiveOrders, error) {
req := url.Values{}
req.Add("pair", pair)
@@ -266,20 +266,20 @@ func (w *WEX) GetTransactionHistory(TIDFrom, Count, TIDEnd int64, order, since,
}
// GetTradeHistory returns the trade history
func (w *WEX) GetTradeHistory(TIDFrom, Count, TIDEnd int64, order, since, end, pair string) (map[string]TradeHistory, error) {
func (w *WEX) GetTradeHistory(TIDFrom, Count, TIDEnd, since, end int64, order, pair string) (map[string]TradeHistory, error) {
req := url.Values{}
req.Add("from", strconv.FormatInt(TIDFrom, 10))
req.Add("count", strconv.FormatInt(Count, 10))
req.Add("from_id", strconv.FormatInt(TIDFrom, 10))
req.Add("end_id", strconv.FormatInt(TIDEnd, 10))
req.Add("order", order)
req.Add("since", since)
req.Add("end", end)
req.Add("since", strconv.FormatInt(since, 10))
req.Add("end", strconv.FormatInt(end, 10))
req.Add("pair", pair)
var result map[string]TradeHistory
result := TradeHistoryResponse{}
return result, w.SendAuthenticatedHTTPRequest(wexTradeHistory, req, &result)
return result.Data, w.SendAuthenticatedHTTPRequest(wexTradeHistory, req, &result)
}
// WithdrawCoins withdraws coins for a specific coin

View File

@@ -1,7 +1,9 @@
package wex
import (
"math"
"testing"
"time"
"github.com/thrasher-/gocryptotrader/common"
"github.com/thrasher-/gocryptotrader/config"
@@ -104,14 +106,14 @@ func TestGetAccountInfo(t *testing.T) {
}
}
func TestGetActiveOrders(t *testing.T) {
func GetOpenOrders(t *testing.T) {
if isWexEncounteringIssues {
t.Skip()
}
t.Parallel()
_, err := w.GetActiveOrders("")
_, err := w.GetOpenOrders("")
if err == nil {
t.Error("Test Failed - GetActiveOrders() error", err)
t.Error("Test Failed - GetOpenOrders() error", err)
}
}
@@ -159,17 +161,6 @@ func TestGetTransactionHistory(t *testing.T) {
}
}
func TestGetTradeHistory(t *testing.T) {
if isWexEncounteringIssues {
t.Skip()
}
t.Parallel()
_, err := w.GetTradeHistory(0, 0, 0, "", "", "", "")
if err == nil {
t.Error("Test Failed - GetTradeHistory() error", err)
}
}
func TestWithdrawCoins(t *testing.T) {
if isWexEncounteringIssues {
t.Skip()
@@ -313,17 +304,53 @@ func TestFormatWithdrawPermissions(t *testing.T) {
if isWexEncounteringIssues {
t.Skip()
}
// Arrange
w.SetDefaults()
expectedResult := exchange.AutoWithdrawCryptoWithAPIPermissionText + " & " + exchange.NoFiatWithdrawalsText
// Act
withdrawPermissions := w.FormatWithdrawPermissions()
// Assert
if withdrawPermissions != expectedResult {
t.Errorf("Expected: %s, Received: %s", expectedResult, withdrawPermissions)
}
}
func TestGetActiveOrders(t *testing.T) {
w.SetDefaults()
TestSetup(t)
var getOrdersRequest = exchange.GetOrdersRequest{
OrderType: exchange.AnyOrderType,
Currencies: []pair.CurrencyPair{pair.NewCurrencyPair(symbol.LTC, symbol.BTC)},
}
_, err := w.GetActiveOrders(getOrdersRequest)
if areTestAPIKeysSet() && err != nil {
t.Errorf("Could not get open orders: %s", err)
} else if !areTestAPIKeysSet() && err == nil {
t.Error("Expecting an error when no keys are set")
}
}
func TestGetOrderHistory(t *testing.T) {
w.SetDefaults()
TestSetup(t)
var getOrdersRequest = exchange.GetOrdersRequest{
OrderType: exchange.AnyOrderType,
Currencies: []pair.CurrencyPair{pair.NewCurrencyPair(symbol.LTC, symbol.BTC)},
StartTicks: time.Unix(0, 0),
EndTicks: time.Unix(math.MaxInt64, 0),
}
_, err := w.GetOrderHistory(getOrdersRequest)
if areTestAPIKeysSet() && err != nil {
t.Errorf("Could not get order history: %s", err)
} else if !areTestAPIKeysSet() && err == nil {
t.Error("Expecting an error when no keys are set")
}
}
// Any tests below this line have the ability to impact your orders on the exchange. Enable canManipulateRealOrders to run them
// ----------------------------------------------------------------------------------------------------------------------------
func areTestAPIKeysSet() bool {
@@ -350,7 +377,7 @@ func TestSubmitOrder(t *testing.T) {
FirstCurrency: symbol.BTC,
SecondCurrency: symbol.USD,
}
response, err := w.SubmitOrder(pair, exchange.Buy, exchange.Market, 1, 10, "hi")
response, err := w.SubmitOrder(pair, exchange.BuyOrderSide, exchange.MarketOrderType, 1, 10, "hi")
if areTestAPIKeysSet() && (err != nil || !response.IsOrderPlaced) {
t.Errorf("Order failed to be placed: %v", err)
} else if !areTestAPIKeysSet() && err == nil {
@@ -362,7 +389,7 @@ func TestCancelExchangeOrder(t *testing.T) {
if isWexEncounteringIssues {
t.Skip()
}
// Arrange
w.SetDefaults()
TestSetup(t)
@@ -379,12 +406,10 @@ func TestCancelExchangeOrder(t *testing.T) {
CurrencyPair: currencyPair,
}
// Act
err := w.CancelOrder(orderCancellation)
// Assert
if !areTestAPIKeysSet() && err == nil {
t.Errorf("Expecting an error when no keys are set: %v", err)
t.Error("Expecting an error when no keys are set")
}
if areTestAPIKeysSet() && err != nil {
t.Errorf("Could not cancel orders: %v", err)
@@ -395,7 +420,7 @@ func TestCancelAllExchangeOrders(t *testing.T) {
if isWexEncounteringIssues {
t.Skip()
}
// Arrange
w.SetDefaults()
TestSetup(t)
@@ -412,12 +437,10 @@ func TestCancelAllExchangeOrders(t *testing.T) {
CurrencyPair: currencyPair,
}
// Act
resp, err := w.CancelAllOrders(orderCancellation)
// Assert
if !areTestAPIKeysSet() && err == nil {
t.Errorf("Expecting an error when no keys are set: %v", err)
t.Error("Expecting an error when no keys are set")
}
if areTestAPIKeysSet() && err != nil {
t.Errorf("Could not cancel orders: %v", err)
@@ -451,7 +474,7 @@ func TestWithdraw(t *testing.T) {
_, err := w.WithdrawCryptocurrencyFunds(withdrawCryptoRequest)
if !areTestAPIKeysSet() && err == nil {
t.Errorf("Expecting an error when no keys are set: %v", err)
t.Error("Expecting an error when no keys are set")
}
if areTestAPIKeysSet() && err != nil {
t.Errorf("Withdraw failed to be placed: %v", err)

View File

@@ -114,6 +114,12 @@ type TransHistory struct {
Timestamp float64 `json:"timestamp"`
}
//TradeHistoryResponse returns all your trade history
type TradeHistoryResponse struct {
Success int64 `json:"success"`
Data map[string]TradeHistory `json:"return,omitempty"`
}
// TradeHistory stores trade history
type TradeHistory struct {
Pair string `json:"pair"`

View File

@@ -2,8 +2,11 @@ package wex
import (
"fmt"
"math"
"strconv"
"strings"
"sync"
"time"
"github.com/thrasher-/gocryptotrader/common"
"github.com/thrasher-/gocryptotrader/currency/pair"
@@ -205,7 +208,7 @@ func (w *WEX) CancelAllOrders(orderCancellation exchange.OrderCancellation) (exc
var allActiveOrders map[string]ActiveOrders
for _, pair := range w.EnabledPairs {
activeOrders, err := w.GetActiveOrders(pair)
activeOrders, err := w.GetOpenOrders(pair)
if err != nil {
return cancelAllOrdersResponse, err
}
@@ -274,3 +277,70 @@ func (w *WEX) GetFeeByType(feeBuilder exchange.FeeBuilder) (float64, error) {
func (w *WEX) GetWithdrawCapabilities() uint32 {
return w.GetWithdrawPermissions()
}
// GetActiveOrders retrieves any orders that are active/open
func (w *WEX) GetActiveOrders(getOrdersRequest exchange.GetOrdersRequest) ([]exchange.OrderDetail, error) {
var orders []exchange.OrderDetail
for _, currency := range getOrdersRequest.Currencies {
resp, err := w.GetOpenOrders(exchange.FormatExchangeCurrency(w.Name, currency).String())
if err != nil {
return nil, err
}
for ID, order := range resp {
symbol := pair.NewCurrencyPairDelimiter(order.Pair, w.ConfigCurrencyPairFormat.Delimiter)
orderDate := time.Unix(int64(order.TimestampCreated), 0)
side := exchange.OrderSide(strings.ToUpper(order.Type))
orders = append(orders, exchange.OrderDetail{
ID: ID,
Amount: order.Amount,
Price: order.Rate,
OrderSide: side,
OrderDate: orderDate,
CurrencyPair: symbol,
Exchange: w.Name,
})
}
}
exchange.FilterOrdersByTickRange(&orders, getOrdersRequest.StartTicks, getOrdersRequest.EndTicks)
exchange.FilterOrdersBySide(&orders, getOrdersRequest.OrderSide)
return orders, nil
}
// GetOrderHistory retrieves account order information
// Can Limit response to specific order status
func (w *WEX) GetOrderHistory(getOrdersRequest exchange.GetOrdersRequest) ([]exchange.OrderDetail, error) {
var allOrders []TradeHistory
for _, currency := range getOrdersRequest.Currencies {
resp, err := w.GetTradeHistory(0, 10000, math.MaxInt64, getOrdersRequest.StartTicks.Unix(), getOrdersRequest.EndTicks.Unix(), "DESC", exchange.FormatExchangeCurrency(w.Name, currency).String())
if err != nil {
return nil, err
}
for _, order := range resp {
allOrders = append(allOrders, order)
}
}
var orders []exchange.OrderDetail
for _, order := range allOrders {
symbol := pair.NewCurrencyPairDelimiter(order.Pair, w.ConfigCurrencyPairFormat.Delimiter)
orderDate := time.Unix(int64(order.Timestamp), 0)
side := exchange.OrderSide(strings.ToUpper(order.Type))
orders = append(orders, exchange.OrderDetail{
ID: fmt.Sprintf("%v", order.OrderID),
Amount: order.Amount,
Price: order.Rate,
OrderSide: side,
OrderDate: orderDate,
CurrencyPair: symbol,
Exchange: w.Name,
})
}
exchange.FilterOrdersBySide(&orders, getOrdersRequest.OrderSide)
return orders, nil
}

View File

@@ -194,8 +194,8 @@ func (y *Yobit) Trade(pair, orderType string, amount, price float64) (int64, err
return int64(result.OrderID), nil
}
// GetActiveOrders returns the active orders for a specific currency
func (y *Yobit) GetActiveOrders(pair string) (map[string]ActiveOrders, error) {
// GetOpenOrders returns the active orders for a specific currency
func (y *Yobit) GetOpenOrders(pair string) (map[string]ActiveOrders, error) {
req := url.Values{}
req.Add("pair", pair)
@@ -232,20 +232,28 @@ func (y *Yobit) CancelExistingOrder(OrderID int64) (bool, error) {
}
// GetTradeHistory returns the trade history
func (y *Yobit) GetTradeHistory(TIDFrom, Count, TIDEnd int64, order, since, end, pair string) (map[string]TradeHistory, error) {
func (y *Yobit) GetTradeHistory(TIDFrom, Count, TIDEnd, since, end int64, order, pair string) (map[string]TradeHistory, error) {
req := url.Values{}
req.Add("from", strconv.FormatInt(TIDFrom, 10))
req.Add("count", strconv.FormatInt(Count, 10))
req.Add("from_id", strconv.FormatInt(TIDFrom, 10))
req.Add("end_id", strconv.FormatInt(TIDEnd, 10))
req.Add("order", order)
req.Add("since", since)
req.Add("end", end)
req.Add("since", strconv.FormatInt(since, 10))
req.Add("end", strconv.FormatInt(end, 10))
req.Add("pair", pair)
result := map[string]TradeHistory{}
result := TradeHistoryResponse{}
return result, y.SendAuthenticatedHTTPRequest(privateTradeHistory, req, &result)
err := y.SendAuthenticatedHTTPRequest(privateTradeHistory, req, &result)
if err != nil {
return nil, err
}
if result.Success == 0 {
return nil, errors.New(result.Error)
}
return result.Data, nil
}
// GetCryptoDepositAddress returns the deposit address for a specific currency

View File

@@ -1,7 +1,9 @@
package yobit
import (
"math"
"testing"
"time"
"github.com/thrasher-/gocryptotrader/common"
"github.com/thrasher-/gocryptotrader/config"
@@ -77,11 +79,11 @@ func TestGetAccountInfo(t *testing.T) {
}
}
func TestGetActiveOrders(t *testing.T) {
func TestGetOpenOrders(t *testing.T) {
t.Parallel()
_, err := y.GetActiveOrders("")
_, err := y.GetOpenOrders("")
if err == nil {
t.Error("Test Failed - GetActiveOrders() error", err)
t.Error("Test Failed - GetOpenOrders() error", err)
}
}
@@ -109,14 +111,6 @@ func TestTrade(t *testing.T) {
}
}
func TestGetTradeHistory(t *testing.T) {
t.Parallel()
_, err := y.GetTradeHistory(0, 0, 0, "", "", "", "")
if err == nil {
t.Error("Test Failed - GetTradeHistory() error", err)
}
}
func TestWithdrawCoinsToAddress(t *testing.T) {
t.Parallel()
_, err := y.WithdrawCoinsToAddress("", 0, "")
@@ -294,17 +288,52 @@ func TestGetFee(t *testing.T) {
}
func TestFormatWithdrawPermissions(t *testing.T) {
// Arrange
y.SetDefaults()
expectedResult := exchange.AutoWithdrawCryptoWithAPIPermissionText + " & " + exchange.WithdrawFiatViaWebsiteOnlyText
// Act
withdrawPermissions := y.FormatWithdrawPermissions()
// Assert
if withdrawPermissions != expectedResult {
t.Errorf("Expected: %s, Received: %s", expectedResult, withdrawPermissions)
}
}
func TestGetActiveOrders(t *testing.T) {
y.SetDefaults()
TestSetup(t)
var getOrdersRequest = exchange.GetOrdersRequest{
OrderType: exchange.AnyOrderType,
Currencies: []pair.CurrencyPair{pair.NewCurrencyPair(symbol.LTC, symbol.BTC)},
}
_, err := y.GetActiveOrders(getOrdersRequest)
if areTestAPIKeysSet() && err != nil {
t.Errorf("Could not get open orders: %s", err)
} else if !areTestAPIKeysSet() && err == nil {
t.Error("Expecting an error when no keys are set")
}
}
func TestGetOrderHistory(t *testing.T) {
y.SetDefaults()
TestSetup(t)
var getOrdersRequest = exchange.GetOrdersRequest{
OrderType: exchange.AnyOrderType,
Currencies: []pair.CurrencyPair{pair.NewCurrencyPair(symbol.LTC, symbol.BTC)},
StartTicks: time.Unix(0, 0),
EndTicks: time.Unix(math.MaxInt64, 0),
}
_, err := y.GetOrderHistory(getOrdersRequest)
if areTestAPIKeysSet() && err != nil {
t.Errorf("Could not get order history: %s", err)
} else if !areTestAPIKeysSet() && err == nil {
t.Error("Expecting an error when no keys are set")
}
}
// Any tests below this line have the ability to impact your orders on the exchange. Enable canManipulateRealOrders to run them
// ----------------------------------------------------------------------------------------------------------------------------
func areTestAPIKeysSet() bool {
@@ -328,7 +357,7 @@ func TestSubmitOrder(t *testing.T) {
FirstCurrency: symbol.BTC,
SecondCurrency: symbol.USD,
}
response, err := y.SubmitOrder(pair, exchange.Buy, exchange.Market, 1, 10, "hi")
response, err := y.SubmitOrder(pair, exchange.BuyOrderSide, exchange.MarketOrderType, 1, 10, "hi")
if areTestAPIKeysSet() && (err != nil || !response.IsOrderPlaced) {
t.Errorf("Order failed to be placed: %v", err)
} else if !areTestAPIKeysSet() && err == nil {
@@ -337,7 +366,6 @@ func TestSubmitOrder(t *testing.T) {
}
func TestCancelExchangeOrder(t *testing.T) {
// Arrange
y.SetDefaults()
TestSetup(t)
@@ -354,12 +382,9 @@ func TestCancelExchangeOrder(t *testing.T) {
CurrencyPair: currencyPair,
}
// Act
err := y.CancelOrder(orderCancellation)
// Assert
if !areTestAPIKeysSet() && err == nil {
t.Errorf("Expecting an error when no keys are set: %v", err)
t.Error("Expecting an error when no keys are set")
}
if areTestAPIKeysSet() && err != nil {
t.Errorf("Could not cancel orders: %v", err)
@@ -367,7 +392,6 @@ func TestCancelExchangeOrder(t *testing.T) {
}
func TestCancelAllExchangeOrders(t *testing.T) {
// Arrange
y.SetDefaults()
TestSetup(t)
@@ -384,12 +408,10 @@ func TestCancelAllExchangeOrders(t *testing.T) {
CurrencyPair: currencyPair,
}
// Act
resp, err := y.CancelAllOrders(orderCancellation)
// Assert
if !areTestAPIKeysSet() && err == nil {
t.Errorf("Expecting an error when no keys are set: %v", err)
t.Error("Expecting an error when no keys are set")
}
if areTestAPIKeysSet() && err != nil {
t.Errorf("Could not cancel orders: %v", err)
@@ -423,7 +445,7 @@ func TestWithdraw(t *testing.T) {
_, err := y.WithdrawCryptocurrencyFunds(withdrawCryptoRequest)
if !areTestAPIKeysSet() && err == nil {
t.Errorf("Expecting an error when no keys are set: %v", err)
t.Error("Expecting an error when no keys are set")
}
if areTestAPIKeysSet() && err != nil {
t.Errorf("Withdraw failed to be placed: %v", err)

View File

@@ -105,6 +105,13 @@ type Trade struct {
Error string `json:"error"`
}
//TradeHistoryResponse returns all your trade history
type TradeHistoryResponse struct {
Success int64 `json:"success"`
Data map[string]TradeHistory `json:"return,omitempty"`
Error string `json:"error,omitempty"`
}
// TradeHistory stores trade history
type TradeHistory struct {
Pair string `json:"pair"`

Some files were not shown because too many files have changed in this diff Show More