mirror of
https://github.com/d0zingcat/gocryptotrader.git
synced 2026-06-01 15:10:44 +00:00
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:
@@ -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)
|
||||
}
|
||||
|
||||
@@ -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,
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user