orders: add Filter() method to GetOrdersRequest and force FilteredOrders return type on wrapper functions (#1055)

* orders: filter options return on validate

* exchanges: force filter usage by wrapper return type and shift method functionality

* exchanges: update tests and fix err shadow

* exchanges: shadowland

* exchanges: more shadow land spookyness

* glorious: nits and ftx upgrade

* linter: fix

* orders: preserve unpopulated fields through filtering operation

* glorious: nits

Co-authored-by: Ryan O'Hara-Reid <ryan.oharareid@thrasher.io>
This commit is contained in:
Ryan O'Hara-Reid
2022-10-24 13:28:32 +11:00
committed by GitHub
parent 4e135c9590
commit 558a70e87f
65 changed files with 705 additions and 617 deletions

View File

@@ -442,6 +442,7 @@ func TestGetActiveOrders(t *testing.T) {
var getOrdersRequest = order.GetOrdersRequest{
Type: order.AnyType,
AssetType: asset.Spot,
Side: order.AnySide,
}
_, err := a.GetActiveOrders(context.Background(), &getOrdersRequest)
@@ -457,6 +458,7 @@ func TestGetOrderHistory(t *testing.T) {
var getOrdersRequest = order.GetOrdersRequest{
Type: order.AnyType,
AssetType: asset.Spot,
Side: order.AnySide,
}
_, err := a.GetOrderHistory(context.Background(), &getOrdersRequest)

View File

@@ -363,8 +363,9 @@ func (a *Alphapoint) GetFeeByType(_ *exchange.FeeBuilder) (float64, error) {
// GetActiveOrders retrieves any orders that are active/open
// This function is not concurrency safe due to orderSide/orderType maps
func (a *Alphapoint) GetActiveOrders(ctx context.Context, req *order.GetOrdersRequest) ([]order.Detail, error) {
if err := req.Validate(); err != nil {
func (a *Alphapoint) GetActiveOrders(ctx context.Context, req *order.GetOrdersRequest) (order.FilteredOrders, error) {
err := req.Validate()
if err != nil {
return nil, err
}
resp, err := a.GetOrders(ctx)
@@ -395,21 +396,15 @@ func (a *Alphapoint) GetActiveOrders(ctx context.Context, req *order.GetOrdersRe
orders = append(orders, orderDetail)
}
}
order.FilterOrdersByType(&orders, req.Type)
order.FilterOrdersBySide(&orders, req.Side)
err = order.FilterOrdersByTimeRange(&orders, req.StartTime, req.EndTime)
if err != nil {
log.Errorf(log.ExchangeSys, "%s %v", a.Name, err)
}
return orders, nil
return req.Filter(a.Name, 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(ctx context.Context, req *order.GetOrdersRequest) ([]order.Detail, error) {
if err := req.Validate(); err != nil {
func (a *Alphapoint) GetOrderHistory(ctx context.Context, req *order.GetOrdersRequest) (order.FilteredOrders, error) {
err := req.Validate()
if err != nil {
return nil, err
}
@@ -441,14 +436,7 @@ func (a *Alphapoint) GetOrderHistory(ctx context.Context, req *order.GetOrdersRe
orders = append(orders, orderDetail)
}
}
order.FilterOrdersByType(&orders, req.Type)
order.FilterOrdersBySide(&orders, req.Side)
err = order.FilterOrdersByTimeRange(&orders, req.StartTime, req.EndTime)
if err != nil {
log.Errorf(log.ExchangeSys, "%s %v", a.Name, err)
}
return orders, nil
return req.Filter(a.Name, orders), nil
}
// ValidateCredentials validates current credentials used for wrapper

View File

@@ -1518,6 +1518,7 @@ func TestGetActiveOrders(t *testing.T) {
Type: order.AnyType,
Pairs: currency.Pairs{pair},
AssetType: asset.Spot,
Side: order.AnySide,
}
_, err = b.GetActiveOrders(context.Background(), &getOrdersRequest)
@@ -1537,6 +1538,7 @@ func TestGetOrderHistory(t *testing.T) {
var getOrdersRequest = order.GetOrdersRequest{
Type: order.AnyType,
AssetType: asset.Spot,
Side: order.AnySide,
}
_, err := b.GetOrderHistory(context.Background(), &getOrdersRequest)

View File

@@ -1357,8 +1357,9 @@ func (b *Binance) GetFeeByType(ctx context.Context, feeBuilder *exchange.FeeBuil
}
// GetActiveOrders retrieves any orders that are active/open
func (b *Binance) GetActiveOrders(ctx context.Context, req *order.GetOrdersRequest) ([]order.Detail, error) {
if err := req.Validate(); err != nil {
func (b *Binance) GetActiveOrders(ctx context.Context, req *order.GetOrdersRequest) (order.FilteredOrders, error) {
err := req.Validate()
if err != nil {
return nil, err
}
if len(req.Pairs) == 0 || len(req.Pairs) >= 40 {
@@ -1473,20 +1474,14 @@ func (b *Binance) GetActiveOrders(ctx context.Context, req *order.GetOrdersReque
return orders, fmt.Errorf("assetType not supported")
}
}
order.FilterOrdersByPairs(&orders, req.Pairs)
order.FilterOrdersByType(&orders, req.Type)
order.FilterOrdersBySide(&orders, req.Side)
err := order.FilterOrdersByTimeRange(&orders, req.StartTime, req.EndTime)
if err != nil {
log.Errorf(log.ExchangeSys, "%s %v", b.Name, err)
}
return orders, nil
return req.Filter(b.Name, orders), nil
}
// GetOrderHistory retrieves account order information
// Can Limit response to specific order status
func (b *Binance) GetOrderHistory(ctx context.Context, req *order.GetOrdersRequest) ([]order.Detail, error) {
if err := req.Validate(); err != nil {
func (b *Binance) GetOrderHistory(ctx context.Context, req *order.GetOrdersRequest) (order.FilteredOrders, error) {
err := req.Validate()
if err != nil {
return nil, err
}
if len(req.Pairs) == 0 {
@@ -1669,14 +1664,7 @@ func (b *Binance) GetOrderHistory(ctx context.Context, req *order.GetOrdersReque
default:
return orders, fmt.Errorf("assetType not supported")
}
order.FilterOrdersByType(&orders, req.Type)
order.FilterOrdersBySide(&orders, req.Side)
err := order.FilterOrdersByTimeRange(&orders, req.StartTime, req.EndTime)
if err != nil {
log.Errorf(log.ExchangeSys, "%s %v", b.Name, err)
}
return orders, nil
return req.Filter(b.Name, orders), nil
}
// ValidateCredentials validates current credentials used for wrapper

View File

@@ -362,6 +362,7 @@ func TestGetActiveOrders(t *testing.T) {
var getOrdersRequest = order.GetOrdersRequest{
Type: order.AnyType,
AssetType: asset.Spot,
Side: order.AnySide,
}
_, err := bi.GetActiveOrders(context.Background(), &getOrdersRequest)
if err != nil {

View File

@@ -777,11 +777,11 @@ func (bi *Binanceus) WithdrawFiatFundsToInternationalBank(ctx context.Context, w
}
// GetActiveOrders retrieves any orders that are active/open
func (bi *Binanceus) GetActiveOrders(ctx context.Context, getOrdersRequest *order.GetOrdersRequest) ([]order.Detail, error) {
if err := getOrdersRequest.Validate(); err != nil {
func (bi *Binanceus) GetActiveOrders(ctx context.Context, getOrdersRequest *order.GetOrdersRequest) (order.FilteredOrders, error) {
err := getOrdersRequest.Validate()
if err != nil {
return nil, err
}
var err error
var symbol string
var pair currency.Pair
var selectedOrders []Order
@@ -844,16 +844,11 @@ func (bi *Binanceus) GetActiveOrders(ctx context.Context, getOrdersRequest *orde
LastUpdated: resp[x].UpdateTime,
}
}
order.FilterOrdersByPairs(&orders, getOrdersRequest.Pairs)
order.FilterOrdersByType(&orders, getOrdersRequest.Type)
order.FilterOrdersBySide(&orders, getOrdersRequest.Side)
err = order.FilterOrdersByTimeRange(&orders, getOrdersRequest.StartTime, getOrdersRequest.EndTime)
return orders, err
return getOrdersRequest.Filter(bi.Name, orders), nil
}
// GetOrderHistory retrieves account order information Can Limit response to specific order status
func (bi *Binanceus) GetOrderHistory(ctx context.Context, getOrdersRequest *order.GetOrdersRequest) ([]order.Detail, error) {
func (bi *Binanceus) GetOrderHistory(ctx context.Context, getOrdersRequest *order.GetOrdersRequest) (order.FilteredOrders, error) {
// An endpoint like /api/v3/allOrders does not exist in the binance us
// so This end point is left unimplemented
return nil, common.ErrFunctionNotSupported

View File

@@ -838,6 +838,7 @@ func TestGetActiveOrders(t *testing.T) {
var getOrdersRequest = order.GetOrdersRequest{
Type: order.AnyType,
AssetType: asset.Spot,
Side: order.AnySide,
}
_, err := b.GetActiveOrders(context.Background(), &getOrdersRequest)
@@ -853,6 +854,7 @@ func TestGetOrderHistory(t *testing.T) {
var getOrdersRequest = order.GetOrdersRequest{
Type: order.AnyType,
AssetType: asset.Spot,
Side: order.AnySide,
}
_, err := b.GetOrderHistory(context.Background(), &getOrdersRequest)

View File

@@ -901,8 +901,9 @@ func (b *Bitfinex) GetFeeByType(ctx context.Context, feeBuilder *exchange.FeeBui
}
// GetActiveOrders retrieves any orders that are active/open
func (b *Bitfinex) GetActiveOrders(ctx context.Context, req *order.GetOrdersRequest) ([]order.Detail, error) {
if err := req.Validate(); err != nil {
func (b *Bitfinex) GetActiveOrders(ctx context.Context, req *order.GetOrdersRequest) (order.FilteredOrders, error) {
err := req.Validate()
if err != nil {
return nil, err
}
@@ -969,21 +970,14 @@ func (b *Bitfinex) GetActiveOrders(ctx context.Context, req *order.GetOrdersRequ
orders[i] = orderDetail
}
order.FilterOrdersBySide(&orders, req.Side)
order.FilterOrdersByType(&orders, req.Type)
err = order.FilterOrdersByTimeRange(&orders, req.StartTime, req.EndTime)
if err != nil {
log.Errorf(log.ExchangeSys, "%s %v", b.Name, err)
}
order.FilterOrdersByPairs(&orders, req.Pairs)
return orders, nil
return req.Filter(b.Name, orders), nil
}
// GetOrderHistory retrieves account order information
// Can Limit response to specific order status
func (b *Bitfinex) GetOrderHistory(ctx context.Context, req *order.GetOrdersRequest) ([]order.Detail, error) {
if err := req.Validate(); err != nil {
func (b *Bitfinex) GetOrderHistory(ctx context.Context, req *order.GetOrdersRequest) (order.FilteredOrders, error) {
err := req.Validate()
if err != nil {
return nil, err
}
@@ -1052,17 +1046,10 @@ func (b *Bitfinex) GetOrderHistory(ctx context.Context, req *order.GetOrdersRequ
orders[i] = orderDetail
}
order.FilterOrdersBySide(&orders, req.Side)
order.FilterOrdersByType(&orders, req.Type)
err = order.FilterOrdersByTimeRange(&orders, req.StartTime, req.EndTime)
if err != nil {
log.Errorf(log.ExchangeSys, "%s %v", b.Name, err)
}
for i := range req.Pairs {
b.appendOptionalDelimiter(&req.Pairs[i])
}
order.FilterOrdersByPairs(&orders, req.Pairs)
return orders, nil
return req.Filter(b.Name, orders), nil
}
// AuthenticateWebsocket sends an authentication message to the websocket

View File

@@ -297,6 +297,7 @@ func TestGetActiveOrders(t *testing.T) {
var getOrdersRequest = order.GetOrdersRequest{
Type: order.AnyType,
AssetType: asset.Spot,
Side: order.AnySide,
}
_, err := b.GetActiveOrders(context.Background(), &getOrdersRequest)
@@ -312,6 +313,7 @@ func TestGetOrderHistory(t *testing.T) {
var getOrdersRequest = order.GetOrdersRequest{
Type: order.AnyType,
AssetType: asset.Spot,
Side: order.AnySide,
}
_, err := b.GetOrderHistory(context.Background(), &getOrdersRequest)

View File

@@ -449,13 +449,13 @@ func (b *Bitflyer) WithdrawFiatFundsToInternationalBank(_ context.Context, _ *wi
}
// GetActiveOrders retrieves any orders that are active/open
func (b *Bitflyer) GetActiveOrders(_ context.Context, _ *order.GetOrdersRequest) ([]order.Detail, error) {
func (b *Bitflyer) GetActiveOrders(_ context.Context, _ *order.GetOrdersRequest) (order.FilteredOrders, error) {
return nil, common.ErrNotYetImplemented
}
// GetOrderHistory retrieves account order information
// Can Limit response to specific order status
func (b *Bitflyer) GetOrderHistory(_ context.Context, _ *order.GetOrdersRequest) ([]order.Detail, error) {
func (b *Bitflyer) GetOrderHistory(_ context.Context, _ *order.GetOrdersRequest) (order.FilteredOrders, error) {
return nil, common.ErrNotYetImplemented
}

View File

@@ -391,6 +391,7 @@ func TestGetOrderHistory(t *testing.T) {
var getOrdersRequest = order.GetOrdersRequest{
Type: order.AnyType,
AssetType: asset.Spot,
Side: order.AnySide,
}
_, err := b.GetOrderHistory(context.Background(), &getOrdersRequest)

View File

@@ -659,8 +659,9 @@ func (b *Bithumb) GetFeeByType(ctx context.Context, feeBuilder *exchange.FeeBuil
}
// GetActiveOrders retrieves any orders that are active/open
func (b *Bithumb) GetActiveOrders(ctx context.Context, req *order.GetOrdersRequest) ([]order.Detail, error) {
if err := req.Validate(); err != nil {
func (b *Bithumb) GetActiveOrders(ctx context.Context, req *order.GetOrdersRequest) (order.FilteredOrders, error) {
err := req.Validate()
if err != nil {
return nil, err
}
@@ -709,20 +710,14 @@ func (b *Bithumb) GetActiveOrders(ctx context.Context, req *order.GetOrdersReque
orders = append(orders, orderDetail)
}
}
order.FilterOrdersBySide(&orders, req.Side)
err = order.FilterOrdersByTimeRange(&orders, req.StartTime, req.EndTime)
if err != nil {
log.Errorf(log.ExchangeSys, "%s %v", b.Name, err)
}
order.FilterOrdersByPairs(&orders, req.Pairs)
return orders, nil
return req.Filter(b.Name, orders), nil
}
// GetOrderHistory retrieves account order information
// Can Limit response to specific order status
func (b *Bithumb) GetOrderHistory(ctx context.Context, req *order.GetOrdersRequest) ([]order.Detail, error) {
if err := req.Validate(); err != nil {
func (b *Bithumb) GetOrderHistory(ctx context.Context, req *order.GetOrdersRequest) (order.FilteredOrders, error) {
err := req.Validate()
if err != nil {
return nil, err
}
@@ -771,14 +766,7 @@ func (b *Bithumb) GetOrderHistory(ctx context.Context, req *order.GetOrdersReque
orders = append(orders, orderDetail)
}
}
order.FilterOrdersBySide(&orders, req.Side)
err = order.FilterOrdersByTimeRange(&orders, req.StartTime, req.EndTime)
if err != nil {
log.Errorf(log.ExchangeSys, "%s %v", b.Name, err)
}
order.FilterOrdersByPairs(&orders, req.Pairs)
return orders, nil
return req.Filter(b.Name, orders), nil
}
// ValidateCredentials validates current credentials used for wrapper

View File

@@ -623,6 +623,7 @@ func TestGetActiveOrders(t *testing.T) {
var getOrdersRequest = order.GetOrdersRequest{
Type: order.AnyType,
AssetType: asset.Spot,
Side: order.AnySide,
}
_, err := b.GetActiveOrders(context.Background(), &getOrdersRequest)
@@ -636,10 +637,10 @@ func TestGetActiveOrders(t *testing.T) {
func TestGetOrderHistory(t *testing.T) {
t.Parallel()
var getOrdersRequest = order.GetOrdersRequest{
Type: order.AnyType,
Pairs: []currency.Pair{currency.NewPair(currency.LTC,
currency.BTC)},
Type: order.AnyType,
Pairs: []currency.Pair{currency.NewPair(currency.LTC, currency.BTC)},
AssetType: asset.Spot,
Side: order.AnySide,
}
_, err := b.GetOrderHistory(context.Background(), &getOrdersRequest)

View File

@@ -797,8 +797,9 @@ func (b *Bitmex) GetFeeByType(ctx context.Context, feeBuilder *exchange.FeeBuild
// GetActiveOrders retrieves any orders that are active/open
// This function is not concurrency safe due to orderSide/orderType maps
func (b *Bitmex) GetActiveOrders(ctx context.Context, req *order.GetOrdersRequest) ([]order.Detail, error) {
if err := req.Validate(); err != nil {
func (b *Bitmex) GetActiveOrders(ctx context.Context, req *order.GetOrdersRequest) (order.FilteredOrders, error) {
err := req.Validate()
if err != nil {
return nil, err
}
@@ -845,22 +846,15 @@ func (b *Bitmex) GetActiveOrders(ctx context.Context, req *order.GetOrdersReques
orders[i] = orderDetail
}
order.FilterOrdersBySide(&orders, req.Side)
order.FilterOrdersByType(&orders, req.Type)
err = order.FilterOrdersByTimeRange(&orders, req.StartTime, req.EndTime)
if err != nil {
log.Errorf(log.ExchangeSys, "%s %v", b.Name, err)
}
order.FilterOrdersByPairs(&orders, req.Pairs)
return orders, nil
return req.Filter(b.Name, 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(ctx context.Context, req *order.GetOrdersRequest) ([]order.Detail, error) {
if err := req.Validate(); err != nil {
func (b *Bitmex) GetOrderHistory(ctx context.Context, req *order.GetOrdersRequest) (order.FilteredOrders, error) {
err := req.Validate()
if err != nil {
return nil, err
}
@@ -911,15 +905,7 @@ func (b *Bitmex) GetOrderHistory(ctx context.Context, req *order.GetOrdersReques
orders[i] = orderDetail
}
order.FilterOrdersBySide(&orders, req.Side)
order.FilterOrdersByType(&orders, req.Type)
err = order.FilterOrdersByTimeRange(&orders, req.StartTime, req.EndTime)
if err != nil {
log.Errorf(log.ExchangeSys, "%s %v", b.Name, err)
}
order.FilterOrdersByPairs(&orders, req.Pairs)
return orders, nil
return req.Filter(b.Name, orders), nil
}
// AuthenticateWebsocket sends an authentication message to the websocket

View File

@@ -355,6 +355,7 @@ func TestGetActiveOrders(t *testing.T) {
var getOrdersRequest = order.GetOrdersRequest{
Type: order.AnyType,
AssetType: asset.Spot,
Side: order.AnySide,
}
_, err := b.GetActiveOrders(context.Background(), &getOrdersRequest)
@@ -374,6 +375,7 @@ func TestGetOrderHistory(t *testing.T) {
var getOrdersRequest = order.GetOrdersRequest{
Type: order.AnyType,
AssetType: asset.Spot,
Side: order.AnySide,
}
_, err := b.GetOrderHistory(context.Background(), &getOrdersRequest)

View File

@@ -701,8 +701,9 @@ func (b *Bitstamp) WithdrawFiatFundsToInternationalBank(ctx context.Context, wit
}
// GetActiveOrders retrieves any orders that are active/open
func (b *Bitstamp) GetActiveOrders(ctx context.Context, req *order.GetOrdersRequest) ([]order.Detail, error) {
if err := req.Validate(); err != nil {
func (b *Bitstamp) GetActiveOrders(ctx context.Context, req *order.GetOrdersRequest) (order.FilteredOrders, error) {
err := req.Validate()
if err != nil {
return nil, err
}
@@ -710,7 +711,8 @@ func (b *Bitstamp) GetActiveOrders(ctx context.Context, req *order.GetOrdersRequ
if len(req.Pairs) != 1 {
currPair = "all"
} else {
fPair, err := b.FormatExchangeCurrency(req.Pairs[0], asset.Spot)
var fPair currency.Pair
fPair, err = b.FormatExchangeCurrency(req.Pairs[0], asset.Spot)
if err != nil {
return nil, err
}
@@ -759,25 +761,21 @@ func (b *Bitstamp) GetActiveOrders(ctx context.Context, req *order.GetOrdersRequ
Exchange: b.Name,
}
}
err = order.FilterOrdersByTimeRange(&orders, req.StartTime, req.EndTime)
if err != nil {
log.Errorf(log.ExchangeSys, "%s %v", b.Name, err)
}
order.FilterOrdersByPairs(&orders, req.Pairs)
return orders, nil
return req.Filter(b.Name, orders), nil
}
// GetOrderHistory retrieves account order information
// Can Limit response to specific order status
func (b *Bitstamp) GetOrderHistory(ctx context.Context, req *order.GetOrdersRequest) ([]order.Detail, error) {
if err := req.Validate(); err != nil {
func (b *Bitstamp) GetOrderHistory(ctx context.Context, req *order.GetOrdersRequest) (order.FilteredOrders, error) {
err := req.Validate()
if err != nil {
return nil, err
}
var currPair string
if len(req.Pairs) == 1 {
fPair, err := b.FormatExchangeCurrency(req.Pairs[0], asset.Spot)
var fPair currency.Pair
fPair, err = b.FormatExchangeCurrency(req.Pairs[0], asset.Spot)
if err != nil {
return nil, err
}
@@ -846,13 +844,7 @@ func (b *Bitstamp) GetOrderHistory(ctx context.Context, req *order.GetOrdersRequ
Pair: currPair,
})
}
err = order.FilterOrdersByTimeRange(&orders, req.StartTime, req.EndTime)
if err != nil {
log.Errorf(log.ExchangeSys, "%s %v", b.Name, err)
}
order.FilterOrdersByPairs(&orders, req.Pairs)
return orders, nil
return req.Filter(b.Name, orders), nil
}
// ValidateCredentials validates current credentials used for wrapper

View File

@@ -478,6 +478,7 @@ func TestGetActiveOrders(t *testing.T) {
Type: order.AnyType,
Pairs: []currency.Pair{p},
AssetType: asset.Spot,
Side: order.AnySide,
}
getOrdersRequest.Pairs[0].Delimiter = currency.DashDelimiter
@@ -494,6 +495,7 @@ func TestGetOrderHistory(t *testing.T) {
var getOrdersRequest = order.GetOrdersRequest{
Type: order.AnyType,
AssetType: asset.Spot,
Side: order.AnySide,
}
_, err := b.GetOrderHistory(context.Background(), &getOrdersRequest)

View File

@@ -757,14 +757,16 @@ func (b *Bittrex) WithdrawFiatFundsToInternationalBank(_ context.Context, _ *wit
}
// GetActiveOrders retrieves any orders that are active/open
func (b *Bittrex) GetActiveOrders(ctx context.Context, req *order.GetOrdersRequest) ([]order.Detail, error) {
if err := req.Validate(); err != nil {
func (b *Bittrex) GetActiveOrders(ctx context.Context, req *order.GetOrdersRequest) (order.FilteredOrders, error) {
err := req.Validate()
if err != nil {
return nil, err
}
var currPair string
if len(req.Pairs) == 1 {
formattedPair, err := b.FormatExchangeCurrency(req.Pairs[0], asset.Spot)
var formattedPair currency.Pair
formattedPair, err = b.FormatExchangeCurrency(req.Pairs[0], asset.Spot)
if err != nil {
return nil, err
}
@@ -821,22 +823,15 @@ func (b *Bittrex) GetActiveOrders(ctx context.Context, req *order.GetOrdersReque
Pair: pair,
})
}
order.FilterOrdersByType(&resp, req.Type)
err = order.FilterOrdersByTimeRange(&resp, req.StartTime, req.EndTime)
if err != nil {
log.Errorf(log.ExchangeSys, "%s %v", b.Name, err)
}
order.FilterOrdersByPairs(&resp, req.Pairs)
b.WsSequenceOrders = sequence
return resp, nil
return req.Filter(b.Name, resp), nil
}
// GetOrderHistory retrieves account order information
// Can Limit response to specific order status
func (b *Bittrex) GetOrderHistory(ctx context.Context, req *order.GetOrdersRequest) ([]order.Detail, error) {
if err := req.Validate(); err != nil {
func (b *Bittrex) GetOrderHistory(ctx context.Context, req *order.GetOrdersRequest) (order.FilteredOrders, error) {
err := req.Validate()
if err != nil {
return nil, err
}
if len(req.Pairs) == 0 {
@@ -910,16 +905,8 @@ func (b *Bittrex) GetOrderHistory(ctx context.Context, req *order.GetOrdersReque
detail.InferCostsAndTimes()
resp = append(resp, detail)
}
order.FilterOrdersByType(&resp, req.Type)
err = order.FilterOrdersByTimeRange(&resp, req.StartTime, req.EndTime)
if err != nil {
log.Errorf(log.ExchangeSys, "%s %v", b.Name, err)
}
order.FilterOrdersByPairs(&resp, req.Pairs)
}
return resp, nil
return req.Filter(b.Name, resp), nil
}
// GetFeeByType returns an estimate of fee based on type of transaction

View File

@@ -540,6 +540,7 @@ func TestGetOrderHistory(t *testing.T) {
_, err := b.GetOrderHistory(context.Background(), &order.GetOrdersRequest{
Side: order.Buy,
AssetType: asset.Spot,
Type: order.AnyType,
})
if err != nil {
t.Error(err)
@@ -579,7 +580,7 @@ func TestGetActiveOrders(t *testing.T) {
}
_, err := b.GetActiveOrders(context.Background(),
&order.GetOrdersRequest{AssetType: asset.Spot})
&order.GetOrdersRequest{AssetType: asset.Spot, Side: order.AnySide, Type: order.AnyType})
if err != nil {
t.Fatal(err)
}

View File

@@ -810,8 +810,9 @@ func (b *BTCMarkets) GetFeeByType(ctx context.Context, feeBuilder *exchange.FeeB
}
// GetActiveOrders retrieves any orders that are active/open
func (b *BTCMarkets) GetActiveOrders(ctx context.Context, req *order.GetOrdersRequest) ([]order.Detail, error) {
if err := req.Validate(); err != nil {
func (b *BTCMarkets) GetActiveOrders(ctx context.Context, req *order.GetOrdersRequest) (order.FilteredOrders, error) {
err := req.Validate()
if err != nil {
return nil, err
}
if len(req.Pairs) == 0 {
@@ -880,19 +881,14 @@ func (b *BTCMarkets) GetActiveOrders(ctx context.Context, req *order.GetOrdersRe
resp = append(resp, tempResp)
}
}
order.FilterOrdersByType(&resp, req.Type)
err := order.FilterOrdersByTimeRange(&resp, req.StartTime, req.EndTime)
if err != nil {
log.Errorf(log.ExchangeSys, "%s %v", b.Name, err)
}
order.FilterOrdersBySide(&resp, req.Side)
return resp, nil
return req.Filter(b.Name, resp), nil
}
// GetOrderHistory retrieves account order information
// Can Limit response to specific order status
func (b *BTCMarkets) GetOrderHistory(ctx context.Context, req *order.GetOrdersRequest) ([]order.Detail, error) {
if err := req.Validate(); err != nil {
func (b *BTCMarkets) GetOrderHistory(ctx context.Context, req *order.GetOrdersRequest) (order.FilteredOrders, error) {
err := req.Validate()
if err != nil {
return nil, err
}
var resp []order.Detail
@@ -966,7 +962,7 @@ func (b *BTCMarkets) GetOrderHistory(ctx context.Context, req *order.GetOrdersRe
resp = append(resp, tempResp)
}
}
return resp, nil
return req.Filter(b.Name, resp), nil
}
// ValidateCredentials validates current credentials used for wrapper

View File

@@ -445,6 +445,7 @@ func TestGetActiveOrders(t *testing.T) {
},
Type: order.AnyType,
AssetType: asset.Spot,
Side: order.AnySide,
}
_, err := b.GetActiveOrders(context.Background(), &getOrdersRequest)
@@ -461,6 +462,7 @@ func TestGetOrderHistory(t *testing.T) {
var getOrdersRequest = order.GetOrdersRequest{
Type: order.AnyType,
AssetType: asset.Spot,
Side: order.AnySide,
}
_, err := b.GetOrderHistory(context.Background(), &getOrdersRequest)
if err != nil {

View File

@@ -778,8 +778,9 @@ func (b *BTSE) WithdrawFiatFundsToInternationalBank(_ context.Context, _ *withdr
}
// GetActiveOrders retrieves any orders that are active/open
func (b *BTSE) GetActiveOrders(ctx context.Context, req *order.GetOrdersRequest) ([]order.Detail, error) {
if err := req.Validate(); err != nil {
func (b *BTSE) GetActiveOrders(ctx context.Context, req *order.GetOrdersRequest) (order.FilteredOrders, error) {
err := req.Validate()
if err != nil {
return nil, err
}
@@ -882,14 +883,7 @@ func (b *BTSE) GetActiveOrders(ctx context.Context, req *order.GetOrdersRequest)
orders = append(orders, openOrder)
}
}
order.FilterOrdersByType(&orders, req.Type)
err := order.FilterOrdersByTimeRange(&orders, req.StartTime, req.EndTime)
if err != nil {
log.Errorf(log.ExchangeSys, "%s %v", b.Name, err)
}
order.FilterOrdersBySide(&orders, req.Side)
return orders, nil
return req.Filter(b.Name, orders), nil
}
func matchType(input int, required order.Type) bool {
@@ -901,8 +895,9 @@ func matchType(input int, required order.Type) bool {
// GetOrderHistory retrieves account order information
// Can Limit response to specific order status
func (b *BTSE) GetOrderHistory(ctx context.Context, getOrdersRequest *order.GetOrdersRequest) ([]order.Detail, error) {
if err := getOrdersRequest.Validate(); err != nil {
func (b *BTSE) GetOrderHistory(ctx context.Context, getOrdersRequest *order.GetOrdersRequest) (order.FilteredOrders, error) {
err := getOrdersRequest.Validate()
if err != nil {
return nil, err
}
@@ -956,7 +951,7 @@ func (b *BTSE) GetOrderHistory(ctx context.Context, getOrdersRequest *order.GetO
resp = append(resp, tempOrder)
}
}
return resp, nil
return getOrdersRequest.Filter(b.Name, resp), nil
}
// GetFeeByType returns an estimate of fee based on type of transaction

View File

@@ -2794,6 +2794,8 @@ func TestGetActiveOrders(t *testing.T) {
var getOrdersRequestSpot = order.GetOrdersRequest{
Pairs: currency.Pairs{pair},
AssetType: asset.Spot,
Side: order.AnySide,
Type: order.AnyType,
}
_, err = b.GetActiveOrders(context.Background(), &getOrdersRequestSpot)
@@ -2804,6 +2806,8 @@ func TestGetActiveOrders(t *testing.T) {
var getOrdersRequestUMF = order.GetOrdersRequest{
Pairs: currency.Pairs{pair},
AssetType: asset.USDTMarginedFutures,
Side: order.AnySide,
Type: order.AnyType,
}
_, err = b.GetActiveOrders(context.Background(), &getOrdersRequestUMF)
@@ -2819,6 +2823,8 @@ func TestGetActiveOrders(t *testing.T) {
var getOrdersRequestCMF = order.GetOrdersRequest{
Pairs: currency.Pairs{pair1},
AssetType: asset.CoinMarginedFutures,
Side: order.AnySide,
Type: order.AnyType,
}
_, err = b.GetActiveOrders(context.Background(), &getOrdersRequestCMF)
@@ -2834,6 +2840,8 @@ func TestGetActiveOrders(t *testing.T) {
var getOrdersRequestFutures = order.GetOrdersRequest{
Pairs: currency.Pairs{pair2},
AssetType: asset.Futures,
Side: order.AnySide,
Type: order.AnyType,
}
_, err = b.GetActiveOrders(context.Background(), &getOrdersRequestFutures)
@@ -2849,6 +2857,8 @@ func TestGetActiveOrders(t *testing.T) {
var getOrdersRequestUSDC = order.GetOrdersRequest{
Pairs: currency.Pairs{pair3},
AssetType: asset.USDCMarginedFutures,
Side: order.AnySide,
Type: order.AnyType,
}
_, err = b.GetActiveOrders(context.Background(), &getOrdersRequestUSDC)
@@ -2871,6 +2881,8 @@ func TestGetOrderHistory(t *testing.T) {
var getOrdersRequestSpot = order.GetOrdersRequest{
Pairs: currency.Pairs{pair},
AssetType: asset.Spot,
Type: order.AnyType,
Side: order.AnySide,
}
_, err = b.GetOrderHistory(context.Background(), &getOrdersRequestSpot)
@@ -2881,6 +2893,8 @@ func TestGetOrderHistory(t *testing.T) {
var getOrdersRequestUMF = order.GetOrdersRequest{
Pairs: currency.Pairs{pair},
AssetType: asset.USDTMarginedFutures,
Type: order.AnyType,
Side: order.AnySide,
}
_, err = b.GetOrderHistory(context.Background(), &getOrdersRequestUMF)
@@ -2896,6 +2910,8 @@ func TestGetOrderHistory(t *testing.T) {
var getOrdersRequestCMF = order.GetOrdersRequest{
Pairs: currency.Pairs{pair1},
AssetType: asset.CoinMarginedFutures,
Type: order.AnyType,
Side: order.AnySide,
}
_, err = b.GetOrderHistory(context.Background(), &getOrdersRequestCMF)
@@ -2911,6 +2927,8 @@ func TestGetOrderHistory(t *testing.T) {
var getOrdersRequestFutures = order.GetOrdersRequest{
Pairs: currency.Pairs{pair2},
AssetType: asset.Futures,
Type: order.AnyType,
Side: order.AnySide,
}
_, err = b.GetOrderHistory(context.Background(), &getOrdersRequestFutures)
@@ -2926,6 +2944,8 @@ func TestGetOrderHistory(t *testing.T) {
var getOrdersRequestUSDC = order.GetOrdersRequest{
Pairs: currency.Pairs{pair3},
AssetType: asset.USDCMarginedFutures,
Type: order.AnyType,
Side: order.AnySide,
}
_, err = b.GetOrderHistory(context.Background(), &getOrdersRequestUSDC)

View File

@@ -1406,8 +1406,9 @@ func (by *Bybit) WithdrawFiatFundsToInternationalBank(ctx context.Context, withd
}
// GetActiveOrders retrieves any orders that are active/open
func (by *Bybit) GetActiveOrders(ctx context.Context, req *order.GetOrdersRequest) ([]order.Detail, error) {
if err := req.Validate(); err != nil {
func (by *Bybit) GetActiveOrders(ctx context.Context, req *order.GetOrdersRequest) (order.FilteredOrders, error) {
err := req.Validate()
if err != nil {
return nil, err
}
@@ -1557,20 +1558,14 @@ func (by *Bybit) GetActiveOrders(ctx context.Context, req *order.GetOrdersReques
default:
return orders, fmt.Errorf("%s %w", req.AssetType, asset.ErrNotSupported)
}
order.FilterOrdersByPairs(&orders, req.Pairs)
order.FilterOrdersByType(&orders, req.Type)
order.FilterOrdersBySide(&orders, req.Side)
err := order.FilterOrdersByTimeRange(&orders, req.StartTime, req.EndTime)
if err != nil {
log.Errorf(log.ExchangeSys, "%s %v", by.Name, err)
}
return orders, nil
return req.Filter(by.Name, orders), nil
}
// GetOrderHistory retrieves account order information
// Can Limit response to specific order status
func (by *Bybit) GetOrderHistory(ctx context.Context, req *order.GetOrdersRequest) ([]order.Detail, error) {
if err := req.Validate(); err != nil {
func (by *Bybit) GetOrderHistory(ctx context.Context, req *order.GetOrdersRequest) (order.FilteredOrders, error) {
err := req.Validate()
if err != nil {
return nil, err
}
var orders []order.Detail
@@ -1735,14 +1730,7 @@ func (by *Bybit) GetOrderHistory(ctx context.Context, req *order.GetOrdersReques
default:
return orders, fmt.Errorf("%s %w", req.AssetType, asset.ErrNotSupported)
}
order.FilterOrdersByType(&orders, req.Type)
order.FilterOrdersBySide(&orders, req.Side)
err := order.FilterOrdersByTimeRange(&orders, req.StartTime, req.EndTime)
if err != nil {
log.Errorf(log.ExchangeSys, "%s %v", by.Name, err)
}
return orders, nil
return req.Filter(by.Name, orders), nil
}
// GetFeeByType returns an estimate of fee based on the type of transaction

View File

@@ -441,6 +441,7 @@ func TestGetActiveOrders(t *testing.T) {
Type: order.AnyType,
AssetType: asset.Spot,
Pairs: []currency.Pair{testPair},
Side: order.AnySide,
}
_, err := c.GetActiveOrders(context.Background(), &getOrdersRequest)
@@ -456,6 +457,7 @@ func TestGetOrderHistory(t *testing.T) {
Type: order.AnyType,
AssetType: asset.Spot,
Pairs: []currency.Pair{testPair},
Side: order.AnySide,
}
_, err := c.GetOrderHistory(context.Background(), &getOrdersRequest)

View File

@@ -750,20 +750,23 @@ func (c *CoinbasePro) GetFeeByType(ctx context.Context, feeBuilder *exchange.Fee
}
// GetActiveOrders retrieves any orders that are active/open
func (c *CoinbasePro) GetActiveOrders(ctx context.Context, req *order.GetOrdersRequest) ([]order.Detail, error) {
if err := req.Validate(); err != nil {
func (c *CoinbasePro) GetActiveOrders(ctx context.Context, req *order.GetOrdersRequest) (order.FilteredOrders, error) {
err := req.Validate()
if err != nil {
return nil, err
}
var respOrders []GeneralizedOrderResponse
var fPair currency.Pair
for i := range req.Pairs {
fpair, err := c.FormatExchangeCurrency(req.Pairs[i], asset.Spot)
fPair, err = c.FormatExchangeCurrency(req.Pairs[i], asset.Spot)
if err != nil {
return nil, err
}
resp, err := c.GetOrders(ctx,
var resp []GeneralizedOrderResponse
resp, err = c.GetOrders(ctx,
[]string{"open", "pending", "active"},
fpair.String())
fPair.String())
if err != nil {
return nil, err
}
@@ -804,45 +807,36 @@ func (c *CoinbasePro) GetActiveOrders(ctx context.Context, req *order.GetOrdersR
Exchange: c.Name,
}
}
order.FilterOrdersByType(&orders, req.Type)
err = order.FilterOrdersByTimeRange(&orders, req.StartTime, req.EndTime)
if err != nil {
log.Errorf(log.ExchangeSys, "%s %v", c.Name, err)
}
order.FilterOrdersBySide(&orders, req.Side)
return orders, nil
return req.Filter(c.Name, orders), nil
}
// GetOrderHistory retrieves account order information
// Can Limit response to specific order status
func (c *CoinbasePro) GetOrderHistory(ctx context.Context, req *order.GetOrdersRequest) ([]order.Detail, error) {
if err := req.Validate(); err != nil {
func (c *CoinbasePro) GetOrderHistory(ctx context.Context, req *order.GetOrdersRequest) (order.FilteredOrders, error) {
err := req.Validate()
if err != nil {
return nil, err
}
var respOrders []GeneralizedOrderResponse
if len(req.Pairs) > 0 {
var fPair currency.Pair
var resp []GeneralizedOrderResponse
for i := range req.Pairs {
fpair, err := c.FormatExchangeCurrency(req.Pairs[i], asset.Spot)
fPair, err = c.FormatExchangeCurrency(req.Pairs[i], asset.Spot)
if err != nil {
return nil, err
}
resp, err := c.GetOrders(ctx,
[]string{"done"},
fpair.String())
resp, err = c.GetOrders(ctx, []string{"done"}, fPair.String())
if err != nil {
return nil, err
}
respOrders = append(respOrders, resp...)
}
} else {
resp, err := c.GetOrders(ctx,
[]string{"done"},
"")
respOrders, err = c.GetOrders(ctx, []string{"done"}, "")
if err != nil {
return nil, err
}
respOrders = resp
}
format, err := c.GetPairFormat(asset.Spot, false)
@@ -894,14 +888,7 @@ func (c *CoinbasePro) GetOrderHistory(ctx context.Context, req *order.GetOrdersR
detail.InferCostsAndTimes()
orders[i] = detail
}
order.FilterOrdersByType(&orders, req.Type)
err = order.FilterOrdersByTimeRange(&orders, req.StartTime, req.EndTime)
if err != nil {
log.Errorf(log.ExchangeSys, "%s %v", c.Name, err)
}
order.FilterOrdersBySide(&orders, req.Side)
return orders, nil
return req.Filter(c.Name, orders), nil
}
// checkInterval checks allowable interval

View File

@@ -264,6 +264,7 @@ func TestGetActiveOrders(t *testing.T) {
var getOrdersRequest = order.GetOrdersRequest{
Type: order.AnyType,
AssetType: asset.Spot,
Side: order.AnySide,
}
_, err := c.GetActiveOrders(context.Background(), &getOrdersRequest)
if areTestAPIKeysSet() && err != nil {
@@ -276,8 +277,8 @@ func TestGetOrderHistoryWrapper(t *testing.T) {
var getOrdersRequest = order.GetOrdersRequest{
Type: order.AnyType,
AssetType: asset.Spot,
Pairs: []currency.Pair{currency.NewPair(currency.BTC,
currency.USD)},
Pairs: []currency.Pair{currency.NewPair(currency.BTC, currency.USD)},
Side: order.AnySide,
}
_, err := c.GetOrderHistory(context.Background(), &getOrdersRequest)

View File

@@ -867,12 +867,13 @@ func (c *COINUT) GetFeeByType(ctx context.Context, feeBuilder *exchange.FeeBuild
}
// GetActiveOrders retrieves any orders that are active/open
func (c *COINUT) GetActiveOrders(ctx context.Context, req *order.GetOrdersRequest) ([]order.Detail, error) {
if err := req.Validate(); err != nil {
func (c *COINUT) GetActiveOrders(ctx context.Context, req *order.GetOrdersRequest) (order.FilteredOrders, error) {
err := req.Validate()
if err != nil {
return nil, err
}
err := c.loadInstrumentsIfNotLoaded()
err = c.loadInstrumentsIfNotLoaded()
if err != nil {
return nil, err
}
@@ -991,23 +992,18 @@ func (c *COINUT) GetActiveOrders(ctx context.Context, req *order.GetOrdersReques
}
}
}
err = order.FilterOrdersByTimeRange(&orders, req.StartTime, req.EndTime)
if err != nil {
log.Errorf(log.ExchangeSys, "%s %v", c.Name, err)
}
order.FilterOrdersBySide(&orders, req.Side)
return orders, nil
return req.Filter(c.Name, orders), nil
}
// GetOrderHistory retrieves account order information
// Can Limit response to specific order status
func (c *COINUT) GetOrderHistory(ctx context.Context, req *order.GetOrdersRequest) ([]order.Detail, error) {
if err := req.Validate(); err != nil {
func (c *COINUT) GetOrderHistory(ctx context.Context, req *order.GetOrdersRequest) (order.FilteredOrders, error) {
err := req.Validate()
if err != nil {
return nil, err
}
err := c.loadInstrumentsIfNotLoaded()
err = c.loadInstrumentsIfNotLoaded()
if err != nil {
return nil, err
}
@@ -1116,13 +1112,7 @@ func (c *COINUT) GetOrderHistory(ctx context.Context, req *order.GetOrdersReques
}
}
}
err = order.FilterOrdersByTimeRange(&allOrders, req.StartTime, req.EndTime)
if err != nil {
log.Errorf(log.ExchangeSys, "%s %v", c.Name, err)
}
order.FilterOrdersBySide(&allOrders, req.Side)
return allOrders, nil
return req.Filter(c.Name, allOrders), nil
}
// AuthenticateWebsocket sends an authentication message to the websocket

View File

@@ -271,6 +271,7 @@ func TestGetActiveOrders(t *testing.T) {
var getOrdersRequest = order.GetOrdersRequest{
Type: order.AnyType,
AssetType: asset.Spot,
Side: order.AnySide,
}
_, err := e.GetActiveOrders(context.Background(), &getOrdersRequest)
@@ -285,6 +286,7 @@ func TestGetOrderHistory(t *testing.T) {
var getOrdersRequest = order.GetOrdersRequest{
Type: order.AnyType,
AssetType: asset.Spot,
Side: order.AnySide,
}
currPair := currency.NewPair(currency.BTC, currency.USD)
currPair.Delimiter = "_"

View File

@@ -631,8 +631,9 @@ func (e *EXMO) GetFeeByType(ctx context.Context, feeBuilder *exchange.FeeBuilder
}
// GetActiveOrders retrieves any orders that are active/open
func (e *EXMO) GetActiveOrders(ctx context.Context, req *order.GetOrdersRequest) ([]order.Detail, error) {
if err := req.Validate(); err != nil {
func (e *EXMO) GetActiveOrders(ctx context.Context, req *order.GetOrdersRequest) (order.FilteredOrders, error) {
err := req.Validate()
if err != nil {
return nil, err
}
@@ -664,19 +665,14 @@ func (e *EXMO) GetActiveOrders(ctx context.Context, req *order.GetOrdersRequest)
Pair: symbol,
})
}
err = order.FilterOrdersByTimeRange(&orders, req.StartTime, req.EndTime)
if err != nil {
log.Errorf(log.ExchangeSys, "%s %v", e.Name, err)
}
order.FilterOrdersBySide(&orders, req.Side)
return orders, nil
return req.Filter(e.Name, orders), nil
}
// GetOrderHistory retrieves account order information
// Can Limit response to specific order status
func (e *EXMO) GetOrderHistory(ctx context.Context, req *order.GetOrdersRequest) ([]order.Detail, error) {
if err := req.Validate(); err != nil {
func (e *EXMO) GetOrderHistory(ctx context.Context, req *order.GetOrdersRequest) (order.FilteredOrders, error) {
err := req.Validate()
if err != nil {
return nil, err
}
@@ -727,13 +723,7 @@ func (e *EXMO) GetOrderHistory(ctx context.Context, req *order.GetOrdersRequest)
detail.InferCostsAndTimes()
orders[i] = detail
}
err := order.FilterOrdersByTimeRange(&orders, req.StartTime, req.EndTime)
if err != nil {
log.Errorf(log.ExchangeSys, "%s %v", e.Name, err)
}
order.FilterOrdersBySide(&orders, req.Side)
return orders, nil
return req.Filter(e.Name, orders), nil
}
// ValidateCredentials validates current credentials used for wrapper

View File

@@ -1099,7 +1099,16 @@ func TestGetActiveOrders(t *testing.T) {
cp := currency.NewPairWithDelimiter(currency.BTC.String(), currency.USDT.String(), "/")
orderReq.Pairs = append(orderReq.Pairs, cp)
orderReq.AssetType = asset.Spot
orderReq.Side = order.AnySide
orderReq.Type = order.ImmediateOrCancel
_, err := f.GetActiveOrders(context.Background(), &orderReq)
if !errors.Is(err, errUnhandledOrderType) {
t.Fatalf("received: '%v' but expected: '%v'", err, errUnhandledOrderType)
}
orderReq.Type = order.AnyType
_, err = f.GetActiveOrders(context.Background(), &orderReq)
if err != nil {
t.Fatal(err)
}
@@ -1114,7 +1123,23 @@ func TestGetOrderHistory(t *testing.T) {
cp := currency.NewPairWithDelimiter(currency.BTC.String(), currency.USDT.String(), "/")
orderReq.Pairs = append(orderReq.Pairs, cp)
orderReq.AssetType = asset.Spot
orderReq.Side = order.AnySide
orderReq.Type = order.ImmediateOrCancel
_, err := f.GetOrderHistory(context.Background(), &orderReq)
if !errors.Is(err, errUnhandledOrderType) {
t.Fatalf("received: '%v' but expected: '%v'", err, errUnhandledOrderType)
}
orderReq.Type = order.AnyType
orderReq.Side = order.CouldNotCloseShort
_, err = f.GetOrderHistory(context.Background(), &orderReq)
if !errors.Is(err, errUnhandledOrderSide) {
t.Fatalf("received: '%v' but expected: '%v'", err, errUnhandledOrderSide)
}
orderReq.Side = order.AnySide
_, err = f.GetOrderHistory(context.Background(), &orderReq)
if err != nil {
t.Fatal(err)
}

View File

@@ -1,6 +1,8 @@
package ftx
import (
"errors"
"fmt"
"time"
"github.com/shopspring/decimal"
@@ -956,3 +958,62 @@ type ReferralRebateHistory struct {
Size float64 `json:"size"`
Day time.Time `json:"day"`
}
var errUnhandledOrderType = errors.New("unhandled order type")
// validTypes attaches package specific checker functionality for valid type
// check
type validTypes struct {
*order.GetOrdersRequest
}
// Check determines if the request is valid
func (v validTypes) Check() error {
for x := range validOrderTypeForRequest {
if v.Type == validOrderTypeForRequest[x] {
return nil
}
}
return fmt.Errorf("%w %s, expected: [%v]",
errUnhandledOrderType,
v.Type,
validOrderTypeForRequest)
}
var validOrderTypeForRequest = []order.Type{
order.AnyType,
order.Stop,
order.TrailingStop,
order.TakeProfit,
order.Limit,
order.Market,
}
var errUnhandledOrderSide = errors.New("unhandled order side")
// validSides attaches package specific checker functionality for valid side
// check
type validSides struct {
*order.GetOrdersRequest
}
// Check determines if the request is valid
func (v validSides) Check() error {
for x := range validOrderSideForRequest {
if v.Side == validOrderSideForRequest[x] {
return nil
}
}
return fmt.Errorf("%w %s, expected: %v",
errUnhandledOrderSide,
v.Type,
validOrderSideForRequest)
}
var validOrderSideForRequest = []order.Side{
order.AnySide,
order.Buy,
order.Sell,
}

View File

@@ -918,60 +918,77 @@ func (f *FTX) GetWebsocket() (*stream.Websocket, error) {
}
// GetActiveOrders retrieves any orders that are active/open
func (f *FTX) GetActiveOrders(ctx context.Context, getOrdersRequest *order.GetOrdersRequest) ([]order.Detail, error) {
if err := getOrdersRequest.Validate(); err != nil {
func (f *FTX) GetActiveOrders(ctx context.Context, request *order.GetOrdersRequest) (order.FilteredOrders, error) {
err := request.Validate(validTypes{request})
if err != nil {
return nil, err
}
var resp []order.Detail
for x := range getOrdersRequest.Pairs {
assetType, err := f.GetPairAssetType(getOrdersRequest.Pairs[x])
for x := range request.Pairs {
var assetType asset.Item
assetType, err = f.GetPairAssetType(request.Pairs[x])
if err != nil {
return resp, err
}
formattedPair, err := f.FormatExchangeCurrency(getOrdersRequest.Pairs[x], assetType)
var fPair currency.Pair
fPair, err = f.FormatExchangeCurrency(request.Pairs[x], assetType)
if err != nil {
return nil, err
}
var tempResp order.Detail
orderData, err := f.GetOpenOrders(ctx, formattedPair.String())
if err != nil {
return resp, err
}
for y := range orderData {
tempResp.OrderID = strconv.FormatInt(orderData[y].ID, 10)
tempResp.Amount = orderData[y].Size
tempResp.AssetType = assetType
tempResp.ClientOrderID = orderData[y].ClientID
tempResp.Date = orderData[y].CreatedAt
tempResp.Exchange = f.Name
tempResp.ExecutedAmount = orderData[y].Size - orderData[y].RemainingSize
tempResp.Pair = orderData[y].Market
tempResp.Price = orderData[y].Price
tempResp.RemainingAmount = orderData[y].RemainingSize
var orderVars OrderVars
orderVars, err = f.compatibleOrderVars(ctx,
orderData[y].Side,
orderData[y].Status,
orderData[y].Type,
orderData[y].Size,
orderData[y].FilledSize,
orderData[y].AvgFillPrice)
if request.Type == order.AnyType ||
request.Type == order.Limit ||
request.Type == order.Market {
orderData, err := f.GetOpenOrders(ctx, fPair.String())
if err != nil {
return resp, err
}
tempResp.Status = orderVars.Status
tempResp.Side = orderVars.Side
tempResp.Type = orderVars.OrderType
tempResp.Fee = orderVars.Fee
resp = append(resp, tempResp)
for y := range orderData {
tempResp.OrderID = strconv.FormatInt(orderData[y].ID, 10)
tempResp.Amount = orderData[y].Size
tempResp.AssetType = assetType
tempResp.ClientOrderID = orderData[y].ClientID
tempResp.Date = orderData[y].CreatedAt
tempResp.Exchange = f.Name
tempResp.ExecutedAmount = orderData[y].Size - orderData[y].RemainingSize
tempResp.Pair = orderData[y].Market
tempResp.Price = orderData[y].Price
tempResp.RemainingAmount = orderData[y].RemainingSize
var orderVars OrderVars
orderVars, err = f.compatibleOrderVars(ctx,
orderData[y].Side,
orderData[y].Status,
orderData[y].Type,
orderData[y].Size,
orderData[y].FilledSize,
orderData[y].AvgFillPrice)
if err != nil {
return resp, err
}
tempResp.Status = orderVars.Status
tempResp.Side = orderVars.Side
tempResp.Type = orderVars.OrderType
tempResp.Fee = orderVars.Fee
resp = append(resp, tempResp)
}
}
triggerOrderData, err := f.GetOpenTriggerOrders(ctx,
formattedPair.String(),
getOrdersRequest.Type.String())
if request.Type != order.AnyType &&
request.Type != order.Stop &&
request.Type != order.TrailingStop &&
request.Type != order.TakeProfit {
continue
}
var t string
if request.Type != order.AnyType {
t = request.Type.Lower()
}
triggerOrderData, err := f.GetOpenTriggerOrders(ctx, fPair.String(), t)
if err != nil {
return resp, err
}
@@ -1008,13 +1025,14 @@ func (f *FTX) GetActiveOrders(ctx context.Context, getOrdersRequest *order.GetOr
resp = append(resp, tempResp)
}
}
return resp, nil
return request.Filter(f.Name, resp), nil
}
// GetOrderHistory retrieves account order information
// Can Limit response to specific order status
func (f *FTX) GetOrderHistory(ctx context.Context, request *order.GetOrdersRequest) ([]order.Detail, error) {
if err := request.Validate(); err != nil {
func (f *FTX) GetOrderHistory(ctx context.Context, request *order.GetOrdersRequest) (order.FilteredOrders, error) {
err := request.Validate(validTypes{request}, validSides{request})
if err != nil {
return nil, err
}
var resp []order.Detail
@@ -1025,50 +1043,66 @@ func (f *FTX) GetOrderHistory(ctx context.Context, request *order.GetOrdersReque
return nil, err
}
history, err := f.FetchOrderHistory(ctx,
fp.String(),
request.StartTime,
request.EndTime,
"")
if err != nil {
return nil, err
}
for y := range history {
d.OrderID = strconv.FormatInt(history[y].ID, 10)
d.Amount = history[y].Size
d.AssetType = request.AssetType
d.AverageExecutedPrice = history[y].AvgFillPrice
d.ClientOrderID = history[y].ClientID
d.Date = history[y].CreatedAt
d.Exchange = f.Name
d.ExecutedAmount = history[y].Size - history[y].RemainingSize
d.Pair = history[y].Market
d.Price = history[y].Price
d.RemainingAmount = history[y].RemainingSize
var orderVars OrderVars
orderVars, err = f.compatibleOrderVars(ctx,
history[y].Side,
history[y].Status,
history[y].Type,
history[y].Size,
history[y].FilledSize,
history[y].AvgFillPrice)
if request.Type == order.AnyType ||
request.Type == order.Limit ||
request.Type == order.Market {
var history []OrderData
history, err = f.FetchOrderHistory(ctx,
fp.String(),
request.StartTime,
request.EndTime,
"")
if err != nil {
return resp, err
return nil, err
}
for y := range history {
d.OrderID = strconv.FormatInt(history[y].ID, 10)
d.Amount = history[y].Size
d.AssetType = request.AssetType
d.AverageExecutedPrice = history[y].AvgFillPrice
d.ClientOrderID = history[y].ClientID
d.Date = history[y].CreatedAt
d.Exchange = f.Name
d.ExecutedAmount = history[y].Size - history[y].RemainingSize
d.Pair = history[y].Market
d.Price = history[y].Price
d.RemainingAmount = history[y].RemainingSize
var orderVars OrderVars
orderVars, err = f.compatibleOrderVars(ctx,
history[y].Side,
history[y].Status,
history[y].Type,
history[y].Size,
history[y].FilledSize,
history[y].AvgFillPrice)
if err != nil {
return resp, err
}
d.Status = orderVars.Status
d.Side = orderVars.Side
d.Type = orderVars.OrderType
d.Fee = orderVars.Fee
resp = append(resp, d)
}
d.Status = orderVars.Status
d.Side = orderVars.Side
d.Type = orderVars.OrderType
d.Fee = orderVars.Fee
resp = append(resp, d)
}
var side, t string
if request.Side != order.UnknownSide {
if request.Type != order.AnyType &&
request.Type != order.Stop &&
request.Type != order.TrailingStop &&
request.Type != order.TakeProfit {
continue
}
var side string
if request.Side != order.AnySide {
side = request.Side.Lower()
}
if request.Type != order.UnknownType {
var t string
if request.Type != order.AnyType {
t = request.Type.Lower()
}
triggerOrderData, err := f.GetTriggerOrderHistory(ctx,
fp.String(),
request.StartTime,
@@ -1114,7 +1148,7 @@ func (f *FTX) GetOrderHistory(ctx context.Context, request *order.GetOrdersReque
resp = append(resp, d)
}
}
return resp, nil
return request.Filter(f.Name, resp), nil
}
// GetFeeByType returns an estimate of fee based on the type of transaction

View File

@@ -390,9 +390,9 @@ func (g *Gateio) GetOpenOrders(ctx context.Context, symbol string) (OpenOrdersRe
}
// GetTradeHistory retrieves all orders with an optional symbol filter
func (g *Gateio) GetTradeHistory(ctx context.Context, symbol string) (TradHistoryResponse, error) {
func (g *Gateio) GetTradeHistory(ctx context.Context, symbol string) (TradeHistoryResponse, error) {
var params string
var result TradHistoryResponse
var result TradeHistoryResponse
params = fmt.Sprintf("currencyPair=%s", symbol)
err := g.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodPost, gateioTradeHistory, params, &result)

View File

@@ -301,6 +301,7 @@ func TestGetActiveOrders(t *testing.T) {
var getOrdersRequest = order.GetOrdersRequest{
Type: order.AnyType,
AssetType: asset.Spot,
Side: order.AnySide,
}
_, err := g.GetActiveOrders(context.Background(), &getOrdersRequest)
@@ -315,6 +316,7 @@ func TestGetOrderHistory(t *testing.T) {
var getOrdersRequest = order.GetOrdersRequest{
Type: order.AnyType,
AssetType: asset.Spot,
Side: order.AnySide,
}
currPair := currency.NewPair(currency.LTC, currency.BTC)

View File

@@ -147,8 +147,8 @@ type OpenOrder struct {
Type string `json:"type"`
}
// TradHistoryResponse The full response for retrieving all user trade history
type TradHistoryResponse struct {
// TradeHistoryResponse The full response for retrieving all user trade history
type TradeHistoryResponse struct {
Code int `json:"code,omitempty"`
Elapsed string `json:"elapsed,omitempty"`
Message string `json:"message"`

View File

@@ -718,15 +718,17 @@ func (g *Gateio) GetFeeByType(ctx context.Context, feeBuilder *exchange.FeeBuild
}
// GetActiveOrders retrieves any orders that are active/open
func (g *Gateio) GetActiveOrders(ctx context.Context, req *order.GetOrdersRequest) ([]order.Detail, error) {
if err := req.Validate(); err != nil {
func (g *Gateio) GetActiveOrders(ctx context.Context, req *order.GetOrdersRequest) (order.FilteredOrders, error) {
err := req.Validate()
if err != nil {
return nil, err
}
var orders []order.Detail
var currPair string
if len(req.Pairs) == 1 {
fPair, err := g.FormatExchangeCurrency(req.Pairs[0], asset.Spot)
var fPair currency.Pair
fPair, err = g.FormatExchangeCurrency(req.Pairs[0], asset.Spot)
if err != nil {
return nil, err
}
@@ -734,7 +736,8 @@ func (g *Gateio) GetActiveOrders(ctx context.Context, req *order.GetOrdersReques
}
if g.Websocket.CanUseAuthenticatedWebsocketForWrapper() {
for i := 0; ; i += 100 {
resp, err := g.wsGetOrderInfo(req.Type.String(), i, 100)
var resp *WebSocketOrderQueryResult
resp, err = g.wsGetOrderInfo(req.Type.String(), i, 100)
if err != nil {
return orders, err
}
@@ -748,7 +751,8 @@ func (g *Gateio) GetActiveOrders(ctx context.Context, req *order.GetOrdersReques
if resp.WebSocketOrderQueryRecords[j].OrderType == 1 {
orderType = order.Limit
}
p, err := currency.NewPairFromString(resp.WebSocketOrderQueryRecords[j].Market)
var p currency.Pair
p, err = currency.NewPairFromString(resp.WebSocketOrderQueryRecords[j].Market)
if err != nil {
return nil, err
}
@@ -772,12 +776,14 @@ func (g *Gateio) GetActiveOrders(ctx context.Context, req *order.GetOrdersReques
}
}
} else {
resp, err := g.GetOpenOrders(ctx, currPair)
var resp OpenOrdersResponse
resp, err = g.GetOpenOrders(ctx, currPair)
if err != nil {
return nil, err
}
format, err := g.GetPairFormat(asset.Spot, false)
var format currency.PairFormat
format, err = g.GetPairFormat(asset.Spot, false)
if err != nil {
return nil, err
}
@@ -797,7 +803,8 @@ func (g *Gateio) GetActiveOrders(ctx context.Context, req *order.GetOrdersReques
if err != nil {
log.Errorf(log.ExchangeSys, "%s %v", g.Name, err)
}
status, err := order.StringToOrderStatus(resp.Orders[i].Status)
var status order.Status
status, err = order.StringToOrderStatus(resp.Orders[i].Status)
if err != nil {
log.Errorf(log.ExchangeSys, "%s %v", g.Name, err)
}
@@ -816,24 +823,21 @@ func (g *Gateio) GetActiveOrders(ctx context.Context, req *order.GetOrdersReques
})
}
}
err := order.FilterOrdersByTimeRange(&orders, req.StartTime, req.EndTime)
if err != nil {
log.Errorf(log.ExchangeSys, "%s %v", g.Name, err)
}
order.FilterOrdersBySide(&orders, req.Side)
return orders, nil
return req.Filter(g.Name, orders), nil
}
// GetOrderHistory retrieves account order information
// Can Limit response to specific order status
func (g *Gateio) GetOrderHistory(ctx context.Context, req *order.GetOrdersRequest) ([]order.Detail, error) {
if err := req.Validate(); err != nil {
func (g *Gateio) GetOrderHistory(ctx context.Context, req *order.GetOrdersRequest) (order.FilteredOrders, error) {
err := req.Validate()
if err != nil {
return nil, err
}
var trades []TradesResponse
for i := range req.Pairs {
resp, err := g.GetTradeHistory(ctx, req.Pairs[i].String())
var resp TradeHistoryResponse
resp, err = g.GetTradeHistory(ctx, req.Pairs[i].String())
if err != nil {
return nil, err
}
@@ -872,13 +876,7 @@ func (g *Gateio) GetOrderHistory(ctx context.Context, req *order.GetOrdersReques
detail.InferCostsAndTimes()
orders[i] = detail
}
err = order.FilterOrdersByTimeRange(&orders, req.StartTime, req.EndTime)
if err != nil {
log.Errorf(log.ExchangeSys, "%s %v", g.Name, err)
}
order.FilterOrdersBySide(&orders, req.Side)
return orders, nil
return req.Filter(g.Name, orders), nil
}
// AuthenticateWebsocket sends an authentication message to the websocket

View File

@@ -368,6 +368,7 @@ func TestGetActiveOrders(t *testing.T) {
currency.NewPair(currency.LTC, currency.BTC),
},
AssetType: asset.Spot,
Side: order.AnySide,
}
_, err := g.GetActiveOrders(context.Background(), &getOrdersRequest)
@@ -387,6 +388,7 @@ func TestGetOrderHistory(t *testing.T) {
Type: order.AnyType,
Pairs: []currency.Pair{currency.NewPair(currency.LTC, currency.BTC)},
AssetType: asset.Spot,
Side: order.AnySide,
}
_, err := g.GetOrderHistory(context.Background(), &getOrdersRequest)

View File

@@ -676,8 +676,9 @@ func (g *Gemini) GetFeeByType(ctx context.Context, feeBuilder *exchange.FeeBuild
}
// GetActiveOrders retrieves any orders that are active/open
func (g *Gemini) GetActiveOrders(ctx context.Context, req *order.GetOrdersRequest) ([]order.Detail, error) {
if err := req.Validate(); err != nil {
func (g *Gemini) GetActiveOrders(ctx context.Context, req *order.GetOrdersRequest) (order.FilteredOrders, error) {
err := req.Validate()
if err != nil {
return nil, err
}
@@ -729,21 +730,14 @@ func (g *Gemini) GetActiveOrders(ctx context.Context, req *order.GetOrdersReques
Date: orderDate,
}
}
err = order.FilterOrdersByTimeRange(&orders, req.StartTime, req.EndTime)
if err != nil {
log.Errorf(log.ExchangeSys, "%s %v", g.Name, err)
}
order.FilterOrdersBySide(&orders, req.Side)
order.FilterOrdersByType(&orders, req.Type)
order.FilterOrdersByPairs(&orders, req.Pairs)
return orders, nil
return req.Filter(g.Name, orders), nil
}
// GetOrderHistory retrieves account order information
// Can Limit response to specific order status
func (g *Gemini) GetOrderHistory(ctx context.Context, req *order.GetOrdersRequest) ([]order.Detail, error) {
if err := req.Validate(); err != nil {
func (g *Gemini) GetOrderHistory(ctx context.Context, req *order.GetOrdersRequest) (order.FilteredOrders, error) {
err := req.Validate()
if err != nil {
return nil, err
}
@@ -753,14 +747,14 @@ func (g *Gemini) GetOrderHistory(ctx context.Context, req *order.GetOrdersReques
var trades []TradeHistory
for j := range req.Pairs {
fpair, err := g.FormatExchangeCurrency(req.Pairs[j], asset.Spot)
var fPair currency.Pair
fPair, err = g.FormatExchangeCurrency(req.Pairs[j], asset.Spot)
if err != nil {
return nil, err
}
resp, err := g.GetTradeHistory(ctx,
fpair.String(),
req.StartTime.Unix())
var resp []TradeHistory
resp, err = g.GetTradeHistory(ctx, fPair.String(), req.StartTime.Unix())
if err != nil {
return nil, err
}
@@ -805,13 +799,7 @@ func (g *Gemini) GetOrderHistory(ctx context.Context, req *order.GetOrdersReques
detail.InferCostsAndTimes()
orders[i] = detail
}
err = order.FilterOrdersByTimeRange(&orders, req.StartTime, req.EndTime)
if err != nil {
log.Errorf(log.ExchangeSys, "%s %v", g.Name, err)
}
order.FilterOrdersBySide(&orders, req.Side)
return orders, nil
return req.Filter(g.Name, orders), nil
}
// ValidateCredentials validates current credentials used for wrapper

View File

@@ -293,6 +293,7 @@ func TestGetActiveOrders(t *testing.T) {
Type: order.AnyType,
Pairs: []currency.Pair{currency.NewPair(currency.ETH, currency.BTC)},
AssetType: asset.Spot,
Side: order.AnySide,
}
_, err := h.GetActiveOrders(context.Background(), &getOrdersRequest)
@@ -308,6 +309,7 @@ func TestGetOrderHistory(t *testing.T) {
Type: order.AnyType,
AssetType: asset.Spot,
Pairs: []currency.Pair{currency.NewPair(currency.ETH, currency.BTC)},
Side: order.AnySide,
}
_, err := h.GetOrderHistory(context.Background(), &getOrdersRequest)

View File

@@ -723,8 +723,9 @@ func (h *HitBTC) GetFeeByType(ctx context.Context, feeBuilder *exchange.FeeBuild
}
// GetActiveOrders retrieves any orders that are active/open
func (h *HitBTC) GetActiveOrders(ctx context.Context, req *order.GetOrdersRequest) ([]order.Detail, error) {
if err := req.Validate(); err != nil {
func (h *HitBTC) GetActiveOrders(ctx context.Context, req *order.GetOrdersRequest) (order.FilteredOrders, error) {
err := req.Validate()
if err != nil {
return nil, err
}
@@ -734,7 +735,8 @@ func (h *HitBTC) GetActiveOrders(ctx context.Context, req *order.GetOrdersReques
var allOrders []OrderHistoryResponse
for i := range req.Pairs {
resp, err := h.GetOpenOrders(ctx, req.Pairs[i].String())
var resp []OrderHistoryResponse
resp, err = h.GetOpenOrders(ctx, req.Pairs[i].String())
if err != nil {
return nil, err
}
@@ -769,19 +771,14 @@ func (h *HitBTC) GetActiveOrders(ctx context.Context, req *order.GetOrdersReques
Pair: symbol,
}
}
err = order.FilterOrdersByTimeRange(&orders, req.StartTime, req.EndTime)
if err != nil {
log.Errorf(log.ExchangeSys, "%s %v", h.Name, err)
}
order.FilterOrdersBySide(&orders, req.Side)
return orders, nil
return req.Filter(h.Name, orders), nil
}
// GetOrderHistory retrieves account order information
// Can Limit response to specific order status
func (h *HitBTC) GetOrderHistory(ctx context.Context, req *order.GetOrdersRequest) ([]order.Detail, error) {
if err := req.Validate(); err != nil {
func (h *HitBTC) GetOrderHistory(ctx context.Context, req *order.GetOrdersRequest) (order.FilteredOrders, error) {
err := req.Validate()
if err != nil {
return nil, err
}
@@ -791,7 +788,8 @@ func (h *HitBTC) GetOrderHistory(ctx context.Context, req *order.GetOrdersReques
var allOrders []OrderHistoryResponse
for i := range req.Pairs {
resp, err := h.GetOrders(ctx, req.Pairs[i].String())
var resp []OrderHistoryResponse
resp, err = h.GetOrders(ctx, req.Pairs[i].String())
if err != nil {
return nil, err
}
@@ -838,13 +836,7 @@ func (h *HitBTC) GetOrderHistory(ctx context.Context, req *order.GetOrdersReques
detail.InferCostsAndTimes()
orders[i] = detail
}
err = order.FilterOrdersByTimeRange(&orders, req.StartTime, req.EndTime)
if err != nil {
log.Errorf(log.ExchangeSys, "%s %v", h.Name, err)
}
order.FilterOrdersBySide(&orders, req.Side)
return orders, nil
return req.Filter(h.Name, orders), nil
}
// AuthenticateWebsocket sends an authentication message to the websocket

View File

@@ -817,6 +817,7 @@ func TestGetOrderHistory(t *testing.T) {
Type: order.AnyType,
Pairs: []currency.Pair{currency.NewPair(currency.BTC, currency.USDT)},
AssetType: asset.Spot,
Side: order.AnySide,
}
_, err := h.GetOrderHistory(context.Background(), &getOrdersRequest)
if err != nil {
@@ -2009,6 +2010,7 @@ func TestGetActiveOrders(t *testing.T) {
AssetType: asset.Spot,
Type: order.AnyType,
Pairs: []currency.Pair{currency.NewPair(currency.BTC, currency.USDT)},
Side: order.AnySide,
}
_, err := h.GetActiveOrders(context.Background(), &getOrdersRequest)

View File

@@ -1361,8 +1361,9 @@ func (h *HUOBI) GetFeeByType(ctx context.Context, feeBuilder *exchange.FeeBuilde
}
// GetActiveOrders retrieves any orders that are active/open
func (h *HUOBI) GetActiveOrders(ctx context.Context, req *order.GetOrdersRequest) ([]order.Detail, error) {
if err := req.Validate(); err != nil {
func (h *HUOBI) GetActiveOrders(ctx context.Context, req *order.GetOrdersRequest) (order.FilteredOrders, error) {
err := req.Validate()
if err != nil {
return nil, err
}
var orders []order.Detail
@@ -1544,19 +1545,14 @@ func (h *HUOBI) GetActiveOrders(ctx context.Context, req *order.GetOrdersRequest
}
}
}
order.FilterOrdersByType(&orders, req.Type)
order.FilterOrdersBySide(&orders, req.Side)
err := order.FilterOrdersByTimeRange(&orders, req.StartTime, req.EndTime)
if err != nil {
log.Errorf(log.ExchangeSys, "%s %v", h.Name, err)
}
return orders, nil
return req.Filter(h.Name, orders), nil
}
// GetOrderHistory retrieves account order information
// Can Limit response to specific order status
func (h *HUOBI) GetOrderHistory(ctx context.Context, req *order.GetOrdersRequest) ([]order.Detail, error) {
if err := req.Validate(); err != nil {
func (h *HUOBI) GetOrderHistory(ctx context.Context, req *order.GetOrdersRequest) (order.FilteredOrders, error) {
err := req.Validate()
if err != nil {
return nil, err
}
var orders []order.Detail
@@ -1709,11 +1705,7 @@ func (h *HUOBI) GetOrderHistory(ctx context.Context, req *order.GetOrdersRequest
}
}
}
err := order.FilterOrdersByTimeRange(&orders, req.StartTime, req.EndTime)
if err != nil {
log.Errorf(log.ExchangeSys, "%s %v", h.Name, err)
}
return orders, nil
return req.Filter(h.Name, orders), nil
}
func setOrderSideStatusAndType(orderState, requestType string, orderDetail *order.Detail) {

View File

@@ -90,8 +90,8 @@ type OrderManagement interface {
CancelBatchOrders(ctx context.Context, o []order.Cancel) (order.CancelBatchResponse, error)
CancelAllOrders(ctx context.Context, orders *order.Cancel) (order.CancelAllResponse, error)
GetOrderInfo(ctx context.Context, orderID string, pair currency.Pair, assetType asset.Item) (order.Detail, error)
GetActiveOrders(ctx context.Context, getOrdersRequest *order.GetOrdersRequest) ([]order.Detail, error)
GetOrderHistory(ctx context.Context, getOrdersRequest *order.GetOrdersRequest) ([]order.Detail, error)
GetActiveOrders(ctx context.Context, getOrdersRequest *order.GetOrdersRequest) (order.FilteredOrders, error)
GetOrderHistory(ctx context.Context, getOrdersRequest *order.GetOrdersRequest) (order.FilteredOrders, error)
}
// CurrencyStateManagement defines functionality for currency state management

View File

@@ -284,6 +284,7 @@ func TestGetActiveOrders(t *testing.T) {
var getOrdersRequest = order.GetOrdersRequest{
Type: order.AnyType,
AssetType: asset.Spot,
Side: order.AnySide,
}
_, err := i.GetActiveOrders(context.Background(), &getOrdersRequest)
@@ -298,6 +299,7 @@ func TestGetOrderHistory(t *testing.T) {
var getOrdersRequest = order.GetOrdersRequest{
Type: order.AnyType,
AssetType: asset.Spot,
Side: order.AnySide,
}
_, err := i.GetOrderHistory(context.Background(), &getOrdersRequest)

View File

@@ -524,8 +524,9 @@ func (i *ItBit) GetFeeByType(ctx context.Context, feeBuilder *exchange.FeeBuilde
}
// GetActiveOrders retrieves any orders that are active/open
func (i *ItBit) GetActiveOrders(ctx context.Context, req *order.GetOrdersRequest) ([]order.Detail, error) {
if err := req.Validate(); err != nil {
func (i *ItBit) GetActiveOrders(ctx context.Context, req *order.GetOrdersRequest) (order.FilteredOrders, error) {
err := req.Validate()
if err != nil {
return nil, err
}
wallets, err := i.GetWallets(ctx, url.Values{})
@@ -583,20 +584,14 @@ func (i *ItBit) GetActiveOrders(ctx context.Context, req *order.GetOrdersRequest
Pair: symbol,
})
}
err = order.FilterOrdersByTimeRange(&orders, req.StartTime, req.EndTime)
if err != nil {
log.Errorf(log.ExchangeSys, "%s %v", i.Name, err)
}
order.FilterOrdersBySide(&orders, req.Side)
order.FilterOrdersByPairs(&orders, req.Pairs)
return orders, nil
return req.Filter(i.Name, orders), nil
}
// GetOrderHistory retrieves account order information
// Can Limit response to specific order status
func (i *ItBit) GetOrderHistory(ctx context.Context, req *order.GetOrdersRequest) ([]order.Detail, error) {
if err := req.Validate(); err != nil {
func (i *ItBit) GetOrderHistory(ctx context.Context, req *order.GetOrdersRequest) (order.FilteredOrders, error) {
err := req.Validate()
if err != nil {
return nil, err
}
@@ -668,14 +663,7 @@ func (i *ItBit) GetOrderHistory(ctx context.Context, req *order.GetOrdersRequest
detail.InferCostsAndTimes()
orders = append(orders, detail)
}
err = order.FilterOrdersByTimeRange(&orders, req.StartTime, req.EndTime)
if err != nil {
log.Errorf(log.ExchangeSys, "%s %v", i.Name, err)
}
order.FilterOrdersBySide(&orders, req.Side)
order.FilterOrdersByPairs(&orders, req.Pairs)
return orders, nil
return req.Filter(i.Name, orders), nil
}
// ValidateCredentials validates current credentials used for wrapper

View File

@@ -862,6 +862,7 @@ func TestGetActiveOrders(t *testing.T) {
Type: order.AnyType,
AssetType: asset.Spot,
Pairs: currency.Pairs{pair},
Side: order.AnySide,
}
_, err = k.GetActiveOrders(context.Background(), &getOrdersRequest)
@@ -876,6 +877,7 @@ func TestGetOrderHistory(t *testing.T) {
var getOrdersRequest = order.GetOrdersRequest{
Type: order.AnyType,
AssetType: asset.Spot,
Side: order.AnySide,
}
_, err := k.GetOrderHistory(context.Background(), &getOrdersRequest)

View File

@@ -1110,8 +1110,9 @@ func (k *Kraken) GetFeeByType(ctx context.Context, feeBuilder *exchange.FeeBuild
}
// GetActiveOrders retrieves any orders that are active/open
func (k *Kraken) GetActiveOrders(ctx context.Context, req *order.GetOrdersRequest) ([]order.Detail, error) {
if err := req.Validate(); err != nil {
func (k *Kraken) GetActiveOrders(ctx context.Context, req *order.GetOrdersRequest) (order.FilteredOrders, error) {
err := req.Validate()
if err != nil {
return nil, err
}
var orders []order.Detail
@@ -1217,19 +1218,14 @@ func (k *Kraken) GetActiveOrders(ctx context.Context, req *order.GetOrdersReques
default:
return nil, fmt.Errorf("%s assetType not supported", req.AssetType)
}
err := order.FilterOrdersByTimeRange(&orders, req.StartTime, req.EndTime)
if err != nil {
log.Errorf(log.ExchangeSys, "%s %v", k.Name, err)
}
order.FilterOrdersBySide(&orders, req.Side)
order.FilterOrdersByPairs(&orders, req.Pairs)
return orders, nil
return req.Filter(k.Name, orders), nil
}
// GetOrderHistory retrieves account order information
// Can Limit response to specific order status
func (k *Kraken) GetOrderHistory(ctx context.Context, getOrdersRequest *order.GetOrdersRequest) ([]order.Detail, error) {
if err := getOrdersRequest.Validate(); err != nil {
func (k *Kraken) GetOrderHistory(ctx context.Context, getOrdersRequest *order.GetOrdersRequest) (order.FilteredOrders, error) {
err := getOrdersRequest.Validate()
if err != nil {
return nil, err
}
var orders []order.Detail
@@ -1447,10 +1443,7 @@ func (k *Kraken) GetOrderHistory(ctx context.Context, getOrdersRequest *order.Ge
}
}
}
order.FilterOrdersBySide(&orders, getOrdersRequest.Side)
order.FilterOrdersByPairs(&orders, getOrdersRequest.Pairs)
return orders, nil
return getOrdersRequest.Filter(k.Name, orders), nil
}
// AuthenticateWebsocket sends an authentication message to the websocket

View File

@@ -425,6 +425,22 @@ func TestGetAccountInfo(t *testing.T) {
}
}
func TestGetActiveOrders(t *testing.T) {
t.Parallel()
if !areTestAPIKeysSet() {
t.Skip("API keys required but not set, skipping test")
}
var input order.GetOrdersRequest
input.Side = order.Buy
input.AssetType = asset.Spot
input.Type = order.AnyType
input.Side = order.AnySide
_, err := l.GetActiveOrders(context.Background(), &input)
if err != nil {
t.Error(err)
}
}
func TestGetOrderHistory(t *testing.T) {
t.Parallel()
if !areTestAPIKeysSet() {
@@ -433,6 +449,8 @@ func TestGetOrderHistory(t *testing.T) {
var input order.GetOrdersRequest
input.Side = order.Buy
input.AssetType = asset.Spot
input.Type = order.AnyType
input.Side = order.AnySide
_, err := l.GetOrderHistory(context.Background(), &input)
if err != nil {
t.Error(err)

View File

@@ -655,8 +655,9 @@ func (l *Lbank) WithdrawFiatFundsToInternationalBank(_ context.Context, _ *withd
}
// GetActiveOrders retrieves any orders that are active/open
func (l *Lbank) GetActiveOrders(ctx context.Context, getOrdersRequest *order.GetOrdersRequest) ([]order.Detail, error) {
if err := getOrdersRequest.Validate(); err != nil {
func (l *Lbank) GetActiveOrders(ctx context.Context, getOrdersRequest *order.GetOrdersRequest) (order.FilteredOrders, error) {
err := getOrdersRequest.Validate()
if err != nil {
return nil, err
}
@@ -713,13 +714,14 @@ func (l *Lbank) GetActiveOrders(ctx context.Context, getOrdersRequest *order.Get
}
}
}
return finalResp, nil
return getOrdersRequest.Filter(l.Name, finalResp), nil
}
// GetOrderHistory retrieves account order information *
// Can Limit response to specific order status
func (l *Lbank) GetOrderHistory(ctx context.Context, getOrdersRequest *order.GetOrdersRequest) ([]order.Detail, error) {
if err := getOrdersRequest.Validate(); err != nil {
func (l *Lbank) GetOrderHistory(ctx context.Context, getOrdersRequest *order.GetOrdersRequest) (order.FilteredOrders, error) {
err := getOrdersRequest.Validate()
if err != nil {
return nil, err
}
@@ -786,7 +788,7 @@ func (l *Lbank) GetOrderHistory(ctx context.Context, getOrdersRequest *order.Get
}
}
}
return finalResp, nil
return getOrdersRequest.Filter(l.Name, finalResp), nil
}
// GetFeeByType returns an estimate of fee based on the type of transaction *

View File

@@ -237,6 +237,7 @@ func TestGetActiveOrders(t *testing.T) {
var getOrdersRequest = order.GetOrdersRequest{
Type: order.AnyType,
AssetType: asset.Spot,
Side: order.AnySide,
}
_, err := l.GetActiveOrders(context.Background(), &getOrdersRequest)
@@ -256,6 +257,7 @@ func TestGetOrderHistory(t *testing.T) {
var getOrdersRequest = order.GetOrdersRequest{
Type: order.AnyType,
AssetType: asset.Spot,
Side: order.AnySide,
}
_, err := l.GetOrderHistory(context.Background(), &getOrdersRequest)

View File

@@ -553,8 +553,9 @@ func (l *LocalBitcoins) GetFeeByType(ctx context.Context, feeBuilder *exchange.F
}
// GetActiveOrders retrieves any orders that are active/open
func (l *LocalBitcoins) GetActiveOrders(ctx context.Context, getOrdersRequest *order.GetOrdersRequest) ([]order.Detail, error) {
if err := getOrdersRequest.Validate(); err != nil {
func (l *LocalBitcoins) GetActiveOrders(ctx context.Context, getOrdersRequest *order.GetOrdersRequest) (order.FilteredOrders, error) {
err := getOrdersRequest.Validate()
if err != nil {
return nil, err
}
@@ -598,20 +599,14 @@ func (l *LocalBitcoins) GetActiveOrders(ctx context.Context, getOrdersRequest *o
Exchange: l.Name,
}
}
err = order.FilterOrdersByTimeRange(&orders, getOrdersRequest.StartTime,
getOrdersRequest.EndTime)
if err != nil {
log.Errorf(log.ExchangeSys, "%s %v", l.Name, err)
}
order.FilterOrdersBySide(&orders, getOrdersRequest.Side)
return orders, nil
return getOrdersRequest.Filter(l.Name, orders), nil
}
// GetOrderHistory retrieves account order information
// Can Limit response to specific order status
func (l *LocalBitcoins) GetOrderHistory(ctx context.Context, getOrdersRequest *order.GetOrdersRequest) ([]order.Detail, error) {
if err := getOrdersRequest.Validate(); err != nil {
func (l *LocalBitcoins) GetOrderHistory(ctx context.Context, getOrdersRequest *order.GetOrdersRequest) (order.FilteredOrders, error) {
err := getOrdersRequest.Validate()
if err != nil {
return nil, err
}
@@ -693,15 +688,7 @@ func (l *LocalBitcoins) GetOrderHistory(ctx context.Context, getOrdersRequest *o
Exchange: l.Name,
}
}
err = order.FilterOrdersByTimeRange(&orders, getOrdersRequest.StartTime,
getOrdersRequest.EndTime)
if err != nil {
log.Errorf(log.ExchangeSys, "%s %v", l.Name, err)
}
order.FilterOrdersBySide(&orders, getOrdersRequest.Side)
return orders, nil
return getOrdersRequest.Filter(l.Name, orders), nil
}
// ValidateCredentials validates current credentials used for wrapper

View File

@@ -505,12 +505,13 @@ func (o *OKGroup) GetWithdrawalsHistory(ctx context.Context, c currency.Code, a
}
// GetActiveOrders retrieves any orders that are active/open
func (o *OKGroup) GetActiveOrders(ctx context.Context, req *order.GetOrdersRequest) (resp []order.Detail, err error) {
err = req.Validate()
func (o *OKGroup) GetActiveOrders(ctx context.Context, req *order.GetOrdersRequest) (order.FilteredOrders, error) {
err := req.Validate()
if err != nil {
return nil, err
}
var resp []order.Detail
for x := range req.Pairs {
var fPair currency.Pair
fPair, err = o.FormatExchangeCurrency(req.Pairs[x], asset.Spot)
@@ -523,7 +524,7 @@ func (o *OKGroup) GetActiveOrders(ctx context.Context, req *order.GetOrdersReque
InstrumentID: fPair.String(),
})
if err != nil {
return resp, err
return nil, err
}
for i := range spotOpenOrders {
var status order.Status
@@ -555,17 +556,18 @@ func (o *OKGroup) GetActiveOrders(ctx context.Context, req *order.GetOrdersReque
})
}
}
return resp, err
return req.Filter(o.Name, resp), nil
}
// GetOrderHistory retrieves account order information
// Can Limit response to specific order status
func (o *OKGroup) GetOrderHistory(ctx context.Context, req *order.GetOrdersRequest) (resp []order.Detail, err error) {
err = req.Validate()
func (o *OKGroup) GetOrderHistory(ctx context.Context, req *order.GetOrdersRequest) (order.FilteredOrders, error) {
err := req.Validate()
if err != nil {
return nil, err
}
var resp []order.Detail
for x := range req.Pairs {
var fPair currency.Pair
fPair, err = o.FormatExchangeCurrency(req.Pairs[x], asset.Spot)
@@ -579,7 +581,7 @@ func (o *OKGroup) GetOrderHistory(ctx context.Context, req *order.GetOrdersReque
InstrumentID: fPair.String(),
})
if err != nil {
return resp, err
return nil, err
}
for i := range spotOrders {
var status order.Status
@@ -615,7 +617,7 @@ func (o *OKGroup) GetOrderHistory(ctx context.Context, req *order.GetOrdersReque
resp = append(resp, detail)
}
}
return resp, err
return req.Filter(o.Name, resp), nil
}
// GetFeeByType returns an estimate of fee based on type of transaction

View File

@@ -4,6 +4,7 @@ import (
"errors"
"fmt"
"reflect"
"strconv"
"strings"
"testing"
"time"
@@ -373,20 +374,21 @@ func TestFilterOrdersByType(t *testing.T) {
{
Type: Limit,
},
{}, // Unpopulated fields are preserved for API differences
}
FilterOrdersByType(&orders, AnyType)
if len(orders) != 2 {
if len(orders) != 3 {
t.Errorf("Orders failed to be filtered. Expected %v, received %v", 2, len(orders))
}
FilterOrdersByType(&orders, Limit)
if len(orders) != 1 {
if len(orders) != 2 {
t.Errorf("Orders failed to be filtered. Expected %v, received %v", 1, len(orders))
}
FilterOrdersByType(&orders, Stop)
if len(orders) != 0 {
if len(orders) != 1 {
t.Errorf("Orders failed to be filtered. Expected %v, received %v", 0, len(orders))
}
}
@@ -424,7 +426,7 @@ func TestFilterOrdersBySide(t *testing.T) {
{
Side: Sell,
},
{},
{}, // Unpopulated fields are preserved for API differences
}
FilterOrdersBySide(&orders, AnySide)
@@ -433,12 +435,12 @@ func TestFilterOrdersBySide(t *testing.T) {
}
FilterOrdersBySide(&orders, Buy)
if len(orders) != 1 {
if len(orders) != 2 {
t.Errorf("Orders failed to be filtered. Expected %v, received %v", 1, len(orders))
}
FilterOrdersBySide(&orders, Sell)
if len(orders) != 0 {
if len(orders) != 1 {
t.Errorf("Orders failed to be filtered. Expected %v, received %v", 0, len(orders))
}
}
@@ -567,43 +569,44 @@ func TestFilterOrdersByPairs(t *testing.T) {
{
Pair: currency.NewPair(currency.DOGE, currency.RUB),
},
{}, // Unpopulated fields are preserved for API differences
}
currencies := []currency.Pair{currency.NewPair(currency.BTC, currency.USD),
currency.NewPair(currency.LTC, currency.EUR),
currency.NewPair(currency.DOGE, currency.RUB)}
FilterOrdersByPairs(&orders, currencies)
if len(orders) != 3 {
if len(orders) != 4 {
t.Errorf("Orders failed to be filtered. Expected %v, received %v", 3, len(orders))
}
currencies = []currency.Pair{currency.NewPair(currency.BTC, currency.USD),
currency.NewPair(currency.LTC, currency.EUR)}
FilterOrdersByPairs(&orders, currencies)
if len(orders) != 2 {
if len(orders) != 3 {
t.Errorf("Orders failed to be filtered. Expected %v, received %v", 2, len(orders))
}
currencies = []currency.Pair{currency.NewPair(currency.BTC, currency.USD)}
FilterOrdersByPairs(&orders, currencies)
if len(orders) != 1 {
if len(orders) != 2 {
t.Errorf("Orders failed to be filtered. Expected %v, received %v", 1, len(orders))
}
currencies = []currency.Pair{currency.NewPair(currency.USD, currency.BTC)}
FilterOrdersByPairs(&orders, currencies)
if len(orders) != 1 {
if len(orders) != 2 {
t.Errorf("Reverse Orders failed to be filtered. Expected %v, received %v", 1, len(orders))
}
currencies = []currency.Pair{}
FilterOrdersByPairs(&orders, currencies)
if len(orders) != 1 {
if len(orders) != 2 {
t.Errorf("Orders failed to be filtered. Expected %v, received %v", 1, len(orders))
}
currencies = append(currencies, currency.EMPTYPAIR)
FilterOrdersByPairs(&orders, currencies)
if len(orders) != 1 {
if len(orders) != 2 {
t.Errorf("Orders failed to be filtered. Expected %v, received %v", 1, len(orders))
}
}
@@ -1310,25 +1313,43 @@ func TestValidationOnOrderTypes(t *testing.T) {
}
var getOrders *GetOrdersRequest
if getOrders.Validate() != ErrGetOrdersRequestIsNil {
t.Fatal("unexpected error")
err = getOrders.Validate()
if !errors.Is(err, ErrGetOrdersRequestIsNil) {
t.Fatalf("received: '%v' but expected: '%v'", err, ErrGetOrdersRequestIsNil)
}
getOrders = new(GetOrdersRequest)
if getOrders.Validate() == nil {
t.Fatal("should error since assetType hasn't been provided")
err = getOrders.Validate()
if !errors.Is(err, asset.ErrNotSupported) {
t.Fatalf("received: '%v' but expected: '%v'", err, asset.ErrNotSupported)
}
if getOrders.Validate(validate.Check(func() error {
return errors.New("this should error")
})) == nil {
t.Fatal("expected error")
getOrders.AssetType = asset.Spot
err = getOrders.Validate()
if !errors.Is(err, errUnrecognisedOrderSide) {
t.Fatalf("received: '%v' but expected: '%v'", err, errUnrecognisedOrderSide)
}
if getOrders.Validate(validate.Check(func() error {
getOrders.Side = AnySide
err = getOrders.Validate()
if !errors.Is(err, errUnrecognisedOrderType) {
t.Fatalf("received: '%v' but expected: '%v'", err, errUnrecognisedOrderType)
}
var errTestError = errors.New("test error")
getOrders.Type = AnyType
err = getOrders.Validate(validate.Check(func() error {
return errTestError
}))
if !errors.Is(err, errTestError) {
t.Fatalf("received: '%v' but expected: '%v'", err, errTestError)
}
err = getOrders.Validate(validate.Check(func() error {
return nil
})) == nil {
t.Fatal("should output an error since assetType isn't provided")
}))
if !errors.Is(err, nil) {
t.Fatalf("received: '%v' but expected: '%v'", err, nil)
}
var modifyOrder *Modify
@@ -1869,3 +1890,58 @@ func TestDeriveCancel(t *testing.T) {
t.Fatalf("unexpected values %+v", cancel)
}
}
func TestGetOrdersRequest_Filter(t *testing.T) {
request := new(GetOrdersRequest)
request.AssetType = asset.Spot
request.Type = AnyType
request.Side = AnySide
var orders = []Detail{
{OrderID: "0", Pair: btcusd, AssetType: asset.Spot, Type: Limit, Side: Buy},
{OrderID: "1", Pair: btcusd, AssetType: asset.Spot, Type: Limit, Side: Sell},
{OrderID: "2", Pair: btcusd, AssetType: asset.Spot, Type: Market, Side: Buy},
{OrderID: "3", Pair: btcusd, AssetType: asset.Spot, Type: Market, Side: Sell},
{OrderID: "4", Pair: btcusd, AssetType: asset.Futures, Type: Limit, Side: Buy},
{OrderID: "5", Pair: btcusd, AssetType: asset.Futures, Type: Limit, Side: Sell},
{OrderID: "6", Pair: btcusd, AssetType: asset.Futures, Type: Market, Side: Buy},
{OrderID: "7", Pair: btcusd, AssetType: asset.Futures, Type: Market, Side: Sell},
{OrderID: "8", Pair: btcltc, AssetType: asset.Spot, Type: Limit, Side: Buy},
{OrderID: "9", Pair: btcltc, AssetType: asset.Spot, Type: Limit, Side: Sell},
{OrderID: "10", Pair: btcltc, AssetType: asset.Spot, Type: Market, Side: Buy},
{OrderID: "11", Pair: btcltc, AssetType: asset.Spot, Type: Market, Side: Sell},
{OrderID: "12", Pair: btcltc, AssetType: asset.Futures, Type: Limit, Side: Buy},
{OrderID: "13", Pair: btcltc, AssetType: asset.Futures, Type: Limit, Side: Sell},
{OrderID: "14", Pair: btcltc, AssetType: asset.Futures, Type: Market, Side: Buy},
{OrderID: "15", Pair: btcltc, AssetType: asset.Futures, Type: Market, Side: Sell},
}
shinyAndClean := request.Filter("test", orders)
if len(shinyAndClean) != 16 {
t.Fatalf("received: '%v' but expected: '%v'", len(shinyAndClean), 16)
}
for x := range shinyAndClean {
if strconv.FormatInt(int64(x), 10) != shinyAndClean[x].OrderID {
t.Fatalf("received: '%v' but expected: '%v'", shinyAndClean[x].OrderID, int64(x))
}
}
request.Pairs = []currency.Pair{btcltc}
// Kicks off time error
request.EndTime = time.Unix(1336, 0)
request.StartTime = time.Unix(1337, 0)
shinyAndClean = request.Filter("test", orders)
if len(shinyAndClean) != 8 {
t.Fatalf("received: '%v' but expected: '%v'", len(shinyAndClean), 8)
}
for x := range shinyAndClean {
if strconv.FormatInt(int64(x)+8, 10) != shinyAndClean[x].OrderID {
t.Fatalf("received: '%v' but expected: '%v'", shinyAndClean[x].OrderID, int64(x)+8)
}
}
}

View File

@@ -356,3 +356,8 @@ type ClassificationError struct {
OrderID string
Err error
}
// FilteredOrders defines orders that have been filtered at the wrapper level
// forcing required filter operations when calling method Filter() on
// GetOrdersRequest.
type FilteredOrders []Detail

View File

@@ -12,6 +12,7 @@ import (
"github.com/thrasher-corp/gocryptotrader/currency"
"github.com/thrasher-corp/gocryptotrader/exchanges/asset"
"github.com/thrasher-corp/gocryptotrader/exchanges/validate"
"github.com/thrasher-corp/gocryptotrader/log"
)
const (
@@ -772,7 +773,7 @@ func FilterOrdersBySide(orders *[]Detail, side Side) {
target := 0
for i := range *orders {
if (*orders)[i].Side == side {
if (*orders)[i].Side == UnknownSide || (*orders)[i].Side == side {
(*orders)[target] = (*orders)[i]
target++
}
@@ -789,7 +790,7 @@ func FilterOrdersByType(orders *[]Detail, orderType Type) {
target := 0
for i := range *orders {
if (*orders)[i].Type == orderType {
if (*orders)[i].Type == UnknownType || (*orders)[i].Type == orderType {
(*orders)[target] = (*orders)[i]
target++
}
@@ -834,6 +835,12 @@ func FilterOrdersByPairs(orders *[]Detail, pairs []currency.Pair) {
target := 0
for x := range *orders {
if (*orders)[x].Pair.IsEmpty() { // If pair not set then keep
(*orders)[target] = (*orders)[x]
target++
continue
}
for y := range pairs {
if (*orders)[x].Pair.EqualIncludeReciprocal(pairs[y]) {
(*orders)[target] = (*orders)[x]
@@ -1106,14 +1113,25 @@ func (c *Cancel) Validate(opt ...validate.Checker) error {
return nil
}
// Validate checks internal struct requirements
// Validate checks internal struct requirements and returns filter requirement
// options for wrapper standardization procedures.
func (g *GetOrdersRequest) Validate(opt ...validate.Checker) error {
if g == nil {
return ErrGetOrdersRequestIsNil
}
if !g.AssetType.IsValid() {
return fmt.Errorf("%v %w", g.AssetType, asset.ErrNotSupported)
}
if g.Side == UnknownSide {
return errUnrecognisedOrderSide
}
if g.Type == UnknownType {
return errUnrecognisedOrderType
}
var errs common.Errors
for _, o := range opt {
err := o.Check()
@@ -1121,13 +1139,26 @@ func (g *GetOrdersRequest) Validate(opt ...validate.Checker) error {
errs = append(errs, err)
}
}
if errs != nil {
return errs
}
return nil
}
// Filter reduces slice by optional fields
func (g *GetOrdersRequest) Filter(exch string, orders []Detail) FilteredOrders {
filtered := make([]Detail, len(orders))
copy(filtered, orders)
FilterOrdersByPairs(&filtered, g.Pairs)
FilterOrdersByType(&filtered, g.Type)
FilterOrdersBySide(&filtered, g.Side)
err := FilterOrdersByTimeRange(&filtered, g.StartTime, g.EndTime)
if err != nil {
log.Errorf(log.ExchangeSys, "%s %v", exch, err)
}
return filtered
}
// Validate checks internal struct requirements
func (m *Modify) Validate(opt ...validate.Checker) error {
if m == nil {

View File

@@ -225,6 +225,7 @@ func TestGetActiveOrders(t *testing.T) {
var getOrdersRequest = order.GetOrdersRequest{
Type: order.AnyType,
AssetType: asset.Spot,
Side: order.AnySide,
}
_, err := p.GetActiveOrders(context.Background(), &getOrdersRequest)
@@ -243,6 +244,7 @@ func TestGetOrderHistory(t *testing.T) {
var getOrdersRequest = order.GetOrdersRequest{
Type: order.AnyType,
AssetType: asset.Spot,
Side: order.AnySide,
}
_, err := p.GetOrderHistory(context.Background(), &getOrdersRequest)

View File

@@ -811,8 +811,9 @@ func (p *Poloniex) GetFeeByType(ctx context.Context, feeBuilder *exchange.FeeBui
}
// GetActiveOrders retrieves any orders that are active/open
func (p *Poloniex) GetActiveOrders(ctx context.Context, req *order.GetOrdersRequest) ([]order.Detail, error) {
if err := req.Validate(); err != nil {
func (p *Poloniex) GetActiveOrders(ctx context.Context, req *order.GetOrdersRequest) (order.FilteredOrders, error) {
err := req.Validate()
if err != nil {
return nil, err
}
@@ -861,21 +862,14 @@ func (p *Poloniex) GetActiveOrders(ctx context.Context, req *order.GetOrdersRequ
})
}
}
err = order.FilterOrdersByTimeRange(&orders, req.StartTime, req.EndTime)
if err != nil {
log.Errorf(log.ExchangeSys, "%s %v", p.Name, err)
}
order.FilterOrdersByPairs(&orders, req.Pairs)
order.FilterOrdersBySide(&orders, req.Side)
return orders, nil
return req.Filter(p.Name, orders), nil
}
// GetOrderHistory retrieves account order information
// Can Limit response to specific order status
func (p *Poloniex) GetOrderHistory(ctx context.Context, req *order.GetOrdersRequest) ([]order.Detail, error) {
if err := req.Validate(); err != nil {
func (p *Poloniex) GetOrderHistory(ctx context.Context, req *order.GetOrdersRequest) (order.FilteredOrders, error) {
err := req.Validate()
if err != nil {
return nil, err
}
@@ -932,10 +926,7 @@ func (p *Poloniex) GetOrderHistory(ctx context.Context, req *order.GetOrdersRequ
orders = append(orders, detail)
}
}
order.FilterOrdersByPairs(&orders, req.Pairs)
order.FilterOrdersBySide(&orders, req.Side)
return orders, nil
return req.Filter(p.Name, orders), nil
}
// ValidateCredentials validates current credentials used for wrapper

View File

@@ -209,7 +209,7 @@ func (c *CustomEx) GetDepositAddress(ctx context.Context, cryptocurrency currenc
}
// GetOrderHistory is a mock method for CustomEx
func (c *CustomEx) GetOrderHistory(ctx context.Context, getOrdersRequest *order.GetOrdersRequest) ([]order.Detail, error) {
func (c *CustomEx) GetOrderHistory(ctx context.Context, getOrdersRequest *order.GetOrdersRequest) (order.FilteredOrders, error) {
return nil, nil
}
@@ -219,7 +219,7 @@ func (c *CustomEx) GetWithdrawalsHistory(ctx context.Context, code currency.Code
}
// GetActiveOrders is a mock method for CustomEx
func (c *CustomEx) GetActiveOrders(ctx context.Context, getOrdersRequest *order.GetOrdersRequest) ([]order.Detail, error) {
func (c *CustomEx) GetActiveOrders(ctx context.Context, getOrdersRequest *order.GetOrdersRequest) (order.FilteredOrders, error) {
return []order.Detail{}, nil
}

View File

@@ -334,10 +334,10 @@ func TestFormatWithdrawPermissions(t *testing.T) {
func TestGetActiveOrders(t *testing.T) {
var getOrdersRequest = order.GetOrdersRequest{
Type: order.AnyType,
Pairs: []currency.Pair{currency.NewPair(currency.LTC,
currency.BTC)},
Type: order.AnyType,
Pairs: []currency.Pair{currency.NewPair(currency.LTC, currency.BTC)},
AssetType: asset.Spot,
Side: order.AnySide,
}
_, err := y.GetActiveOrders(context.Background(), &getOrdersRequest)
@@ -352,10 +352,10 @@ func TestGetOrderHistory(t *testing.T) {
var getOrdersRequest = order.GetOrdersRequest{
Type: order.AnyType,
AssetType: asset.Spot,
Pairs: []currency.Pair{currency.NewPair(currency.LTC,
currency.BTC)},
Pairs: []currency.Pair{currency.NewPair(currency.LTC, currency.BTC)},
StartTime: time.Unix(0, 0),
EndTime: time.Unix(math.MaxInt64, 0),
Side: order.AnySide,
}
_, err := y.GetOrderHistory(context.Background(), &getOrdersRequest)

View File

@@ -571,18 +571,18 @@ func (y *Yobit) GetFeeByType(ctx context.Context, feeBuilder *exchange.FeeBuilde
}
// GetActiveOrders retrieves any orders that are active/open
func (y *Yobit) GetActiveOrders(ctx context.Context, req *order.GetOrdersRequest) ([]order.Detail, error) {
if err := req.Validate(); err != nil {
func (y *Yobit) GetActiveOrders(ctx context.Context, req *order.GetOrdersRequest) (order.FilteredOrders, error) {
err := req.Validate()
if err != nil {
return nil, err
}
var orders []order.Detail
format, err := y.GetPairFormat(asset.Spot, false)
if err != nil {
return nil, err
}
var orders []order.Detail
for x := range req.Pairs {
var fCurr currency.Pair
fCurr, err = y.FormatExchangeCurrency(req.Pairs[x], asset.Spot)
@@ -617,36 +617,33 @@ func (y *Yobit) GetActiveOrders(ctx context.Context, req *order.GetOrdersRequest
})
}
}
err = order.FilterOrdersByTimeRange(&orders, req.StartTime, req.EndTime)
if err != nil {
log.Errorf(log.ExchangeSys, "%s %v", y.Name, err)
}
order.FilterOrdersBySide(&orders, req.Side)
return orders, nil
return req.Filter(y.Name, orders), nil
}
// GetOrderHistory retrieves account order information
// Can Limit response to specific order status
func (y *Yobit) GetOrderHistory(ctx context.Context, req *order.GetOrdersRequest) ([]order.Detail, error) {
if err := req.Validate(); err != nil {
func (y *Yobit) GetOrderHistory(ctx context.Context, req *order.GetOrdersRequest) (order.FilteredOrders, error) {
err := req.Validate()
if err != nil {
return nil, err
}
var allOrders []TradeHistory
for x := range req.Pairs {
fpair, err := y.FormatExchangeCurrency(req.Pairs[x], asset.Spot)
var fPair currency.Pair
fPair, err = y.FormatExchangeCurrency(req.Pairs[x], asset.Spot)
if err != nil {
return nil, err
}
resp, err := y.GetTradeHistory(ctx,
var resp map[string]TradeHistory
resp, err = y.GetTradeHistory(ctx,
0,
10000,
math.MaxInt64,
req.StartTime.Unix(),
req.EndTime.Unix(),
"DESC",
fpair.String())
fPair.String())
if err != nil {
return nil, err
}
@@ -689,9 +686,7 @@ func (y *Yobit) GetOrderHistory(ctx context.Context, req *order.GetOrdersRequest
detail.InferCostsAndTimes()
orders[i] = detail
}
order.FilterOrdersBySide(&orders, req.Side)
return orders, nil
return req.Filter(y.Name, orders), nil
}
// ValidateCredentials validates current credentials used for wrapper

View File

@@ -248,10 +248,10 @@ func TestGetActiveOrders(t *testing.T) {
t.Skip("skipping authenticated function for mock testing")
}
var getOrdersRequest = order.GetOrdersRequest{
Type: order.AnyType,
Pairs: []currency.Pair{currency.NewPair(currency.XRP,
currency.USDT)},
Type: order.AnyType,
Pairs: []currency.Pair{currency.NewPair(currency.XRP, currency.USDT)},
AssetType: asset.Spot,
Side: order.AnySide,
}
_, err := z.GetActiveOrders(context.Background(), &getOrdersRequest)
@@ -270,8 +270,7 @@ func TestGetOrderHistory(t *testing.T) {
Type: order.AnyType,
Side: order.Buy,
AssetType: asset.Spot,
Pairs: []currency.Pair{currency.NewPair(currency.LTC,
currency.BTC)},
Pairs: []currency.Pair{currency.NewPair(currency.LTC, currency.BTC)},
}
_, err := z.GetOrderHistory(context.Background(), &getOrdersRequest)

View File

@@ -702,19 +702,22 @@ func (z *ZB) GetFeeByType(ctx context.Context, feeBuilder *exchange.FeeBuilder)
// GetActiveOrders retrieves any orders that are active/open
// This function is not concurrency safe due to orderSide/orderType maps
func (z *ZB) GetActiveOrders(ctx context.Context, req *order.GetOrdersRequest) ([]order.Detail, error) {
if err := req.Validate(); err != nil {
func (z *ZB) GetActiveOrders(ctx context.Context, req *order.GetOrdersRequest) (order.FilteredOrders, error) {
err := req.Validate()
if err != nil {
return nil, err
}
var allOrders []Order
for x := range req.Pairs {
for i := int64(1); ; i++ {
fPair, err := z.FormatExchangeCurrency(req.Pairs[x], asset.Spot)
var fPair currency.Pair
fPair, err = z.FormatExchangeCurrency(req.Pairs[x], asset.Spot)
if err != nil {
return nil, err
}
resp, err := z.GetUnfinishedOrdersIgnoreTradeType(ctx,
var resp []Order
resp, err = z.GetUnfinishedOrdersIgnoreTradeType(ctx,
fPair.String(), i, 10)
if err != nil {
if strings.Contains(err.Error(), "3001") {
@@ -760,20 +763,15 @@ func (z *ZB) GetActiveOrders(ctx context.Context, req *order.GetOrdersRequest) (
Pair: symbol,
}
}
err = order.FilterOrdersByTimeRange(&orders, req.StartTime, req.EndTime)
if err != nil {
log.Errorf(log.ExchangeSys, "%s %v", z.Name, err)
}
order.FilterOrdersBySide(&orders, req.Side)
return orders, nil
return req.Filter(z.Name, 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 (z *ZB) GetOrderHistory(ctx context.Context, req *order.GetOrdersRequest) ([]order.Detail, error) {
if err := req.Validate(); err != nil {
func (z *ZB) GetOrderHistory(ctx context.Context, req *order.GetOrdersRequest) (order.FilteredOrders, error) {
err := req.Validate()
if err != nil {
return nil, err
}
@@ -782,12 +780,11 @@ func (z *ZB) GetOrderHistory(ctx context.Context, req *order.GetOrdersRequest) (
}
var allOrders []Order
var side int64
if z.Websocket.CanUseAuthenticatedWebsocketForWrapper() {
for x := range req.Pairs {
for y := int64(1); ; y++ {
resp, err := z.wsGetOrdersIgnoreTradeType(ctx, req.Pairs[x], y, 10)
var resp *WsGetOrdersIgnoreTradeTypeResponse
resp, err = z.wsGetOrdersIgnoreTradeType(ctx, req.Pairs[x], y, 10)
if err != nil {
return nil, err
}
@@ -798,16 +795,19 @@ func (z *ZB) GetOrderHistory(ctx context.Context, req *order.GetOrdersRequest) (
}
}
} else {
var side int64
if req.Side == order.Buy {
side = 1
}
for x := range req.Pairs {
for y := int64(1); ; y++ {
fPair, err := z.FormatExchangeCurrency(req.Pairs[x], asset.Spot)
var fPair currency.Pair
fPair, err = z.FormatExchangeCurrency(req.Pairs[x], asset.Spot)
if err != nil {
return nil, err
}
resp, err := z.GetOrders(ctx, fPair.String(), y, side)
var resp []Order
resp, err = z.GetOrders(ctx, fPair.String(), y, side)
if err != nil {
return nil, err
}
@@ -852,12 +852,7 @@ func (z *ZB) GetOrderHistory(ctx context.Context, req *order.GetOrdersRequest) (
detail.InferCostsAndTimes()
orders[i] = detail
}
err = order.FilterOrdersByTimeRange(&orders, req.StartTime, req.EndTime)
if err != nil {
log.Errorf(log.ExchangeSys, "%s %v", z.Name, err)
}
return orders, nil
return req.Filter(z.Name, orders), nil
}
// ValidateCredentials validates current credentials used for wrapper