mirror of
https://github.com/d0zingcat/gocryptotrader.git
synced 2026-05-13 23:16:45 +00:00
Exchanges: enrich order history with avg executed price, cost, and more (#792)
* Exchanges: enrich order history with avg executed price, cost, and more * Fix division by zero in order detail enrichment * Remove DateCompleted from Bithumb OrderData and fix OrderDate parsing * Fixes on order detail fields and rename EnrichOrderDetail to CalculateCostsAndAmounts * BTSE order history populate name and id * Calculate average executed price for market order or when order amount is zero * Minor fixes on infer order amounts, costs, and times * Attach InferAmountsCostsAndTimes to Order.Detail * Binance: fix order status * Always use order.StringToOrderStatus() and ensure order has at least one of executed/remaining amount set
This commit is contained in:
@@ -376,6 +376,7 @@ func (a *Alphapoint) GetActiveOrders(ctx context.Context, req *order.GetOrdersRe
|
||||
orderDetail := order.Detail{
|
||||
Amount: resp[x].OpenOrders[y].QtyTotal,
|
||||
Exchange: a.Name,
|
||||
ExecutedAmount: resp[x].OpenOrders[y].QtyTotal - resp[x].OpenOrders[y].QtyRemaining,
|
||||
AccountID: strconv.FormatInt(int64(resp[x].OpenOrders[y].AccountID), 10),
|
||||
ID: strconv.FormatInt(int64(resp[x].OpenOrders[y].ServerOrderID), 10),
|
||||
Price: resp[x].OpenOrders[y].Price,
|
||||
@@ -423,6 +424,7 @@ func (a *Alphapoint) GetOrderHistory(ctx context.Context, req *order.GetOrdersRe
|
||||
Amount: resp[x].OpenOrders[y].QtyTotal,
|
||||
AccountID: strconv.FormatInt(int64(resp[x].OpenOrders[y].AccountID), 10),
|
||||
Exchange: a.Name,
|
||||
ExecutedAmount: resp[x].OpenOrders[y].QtyTotal - resp[x].OpenOrders[y].QtyRemaining,
|
||||
ID: strconv.FormatInt(int64(resp[x].OpenOrders[y].ServerOrderID), 10),
|
||||
Price: resp[x].OpenOrders[y].Price,
|
||||
RemainingAmount: resp[x].OpenOrders[y].QtyRemaining,
|
||||
|
||||
@@ -1130,7 +1130,7 @@ func (b *Binance) GetOrderInfo(ctx context.Context, orderID string, pair currenc
|
||||
orderSide := order.Side(resp.Side)
|
||||
status, err := order.StringToOrderStatus(resp.Status)
|
||||
if err != nil {
|
||||
return respData, err
|
||||
log.Errorf(log.ExchangeSys, "%s %v", b.Name, err)
|
||||
}
|
||||
orderType := order.Limit
|
||||
if resp.Type == "MARKET" {
|
||||
@@ -1295,6 +1295,10 @@ func (b *Binance) GetActiveOrders(ctx context.Context, req *order.GetOrdersReque
|
||||
for x := range resp {
|
||||
orderSide := order.Side(strings.ToUpper(resp[x].Side))
|
||||
orderType := order.Type(strings.ToUpper(resp[x].Type))
|
||||
orderStatus, err := order.StringToOrderStatus(resp[i].Status)
|
||||
if err != nil {
|
||||
log.Errorf(log.ExchangeSys, "%s %v", b.Name, err)
|
||||
}
|
||||
orders = append(orders, order.Detail{
|
||||
Amount: resp[x].OrigQty,
|
||||
Date: resp[x].Time,
|
||||
@@ -1304,7 +1308,7 @@ func (b *Binance) GetActiveOrders(ctx context.Context, req *order.GetOrdersReque
|
||||
Side: orderSide,
|
||||
Type: orderType,
|
||||
Price: resp[x].Price,
|
||||
Status: order.Status(resp[x].Status),
|
||||
Status: orderStatus,
|
||||
Pair: req.Pairs[i],
|
||||
AssetType: req.AssetType,
|
||||
LastUpdated: resp[x].UpdateTime,
|
||||
@@ -1411,22 +1415,39 @@ func (b *Binance) GetOrderHistory(ctx context.Context, req *order.GetOrdersReque
|
||||
for i := range resp {
|
||||
orderSide := order.Side(strings.ToUpper(resp[i].Side))
|
||||
orderType := order.Type(strings.ToUpper(resp[i].Type))
|
||||
orderStatus, err := order.StringToOrderStatus(resp[i].Status)
|
||||
if err != nil {
|
||||
log.Errorf(log.ExchangeSys, "%s %v", b.Name, err)
|
||||
}
|
||||
// New orders are covered in GetOpenOrders
|
||||
if resp[i].Status == "NEW" {
|
||||
if orderStatus == order.New {
|
||||
continue
|
||||
}
|
||||
|
||||
orders = append(orders, order.Detail{
|
||||
Amount: resp[i].OrigQty,
|
||||
Date: resp[i].Time,
|
||||
Exchange: b.Name,
|
||||
ID: strconv.FormatInt(resp[i].OrderID, 10),
|
||||
Side: orderSide,
|
||||
Type: orderType,
|
||||
Price: resp[i].Price,
|
||||
Pair: req.Pairs[x],
|
||||
Status: order.Status(resp[i].Status),
|
||||
})
|
||||
var cost float64
|
||||
// For some historical orders cummulativeQuoteQty will be < 0,
|
||||
// meaning the data is not available at this time.
|
||||
if resp[i].CummulativeQuoteQty > 0 {
|
||||
cost = resp[i].CummulativeQuoteQty
|
||||
}
|
||||
detail := order.Detail{
|
||||
Amount: resp[i].OrigQty,
|
||||
ExecutedAmount: resp[i].ExecutedQty,
|
||||
RemainingAmount: resp[i].OrigQty - resp[i].ExecutedQty,
|
||||
Cost: cost,
|
||||
CostAsset: req.Pairs[x].Quote,
|
||||
Date: resp[i].Time,
|
||||
LastUpdated: resp[i].UpdateTime,
|
||||
Exchange: b.Name,
|
||||
ID: strconv.FormatInt(resp[i].OrderID, 10),
|
||||
Side: orderSide,
|
||||
Type: orderType,
|
||||
Price: resp[i].Price,
|
||||
Pair: req.Pairs[x],
|
||||
Status: orderStatus,
|
||||
}
|
||||
detail.InferCostsAndTimes()
|
||||
orders = append(orders, detail)
|
||||
}
|
||||
}
|
||||
case asset.CoinMarginedFutures:
|
||||
|
||||
@@ -956,16 +956,18 @@ func (b *Bitfinex) GetOrderHistory(ctx context.Context, req *order.GetOrdersRequ
|
||||
}
|
||||
|
||||
orderDetail := order.Detail{
|
||||
Amount: resp[i].OriginalAmount,
|
||||
Date: orderDate,
|
||||
Exchange: b.Name,
|
||||
ID: strconv.FormatInt(resp[i].ID, 10),
|
||||
Side: orderSide,
|
||||
Price: resp[i].Price,
|
||||
RemainingAmount: resp[i].RemainingAmount,
|
||||
ExecutedAmount: resp[i].ExecutedAmount,
|
||||
Pair: pair,
|
||||
Amount: resp[i].OriginalAmount,
|
||||
Date: orderDate,
|
||||
Exchange: b.Name,
|
||||
ID: strconv.FormatInt(resp[i].ID, 10),
|
||||
Side: orderSide,
|
||||
Price: resp[i].Price,
|
||||
AverageExecutedPrice: resp[i].AverageExecutionPrice,
|
||||
RemainingAmount: resp[i].RemainingAmount,
|
||||
ExecutedAmount: resp[i].ExecutedAmount,
|
||||
Pair: pair,
|
||||
}
|
||||
orderDetail.InferCostsAndTimes()
|
||||
|
||||
switch {
|
||||
case resp[i].IsLive:
|
||||
|
||||
@@ -127,18 +127,17 @@ type Orders struct {
|
||||
|
||||
// OrderData contains all individual order details
|
||||
type OrderData struct {
|
||||
OrderID string `json:"order_id"`
|
||||
OrderCurrency string `json:"order_currency"`
|
||||
OrderDate int64 `json:"order_date"`
|
||||
PaymentCurrency string `json:"payment_currency"`
|
||||
Type string `json:"type"`
|
||||
Status string `json:"status"`
|
||||
Units float64 `json:"units,string"`
|
||||
UnitsRemaining float64 `json:"units_remaining,string"`
|
||||
Price float64 `json:"price,string"`
|
||||
Fee float64 `json:"fee,string"`
|
||||
Total float64 `json:"total,string"`
|
||||
DateCompleted int64 `json:"date_completed"`
|
||||
OrderID string `json:"order_id"`
|
||||
OrderCurrency string `json:"order_currency"`
|
||||
OrderDate bithumbTime `json:"order_date"`
|
||||
PaymentCurrency string `json:"payment_currency"`
|
||||
Type string `json:"type"`
|
||||
Status string `json:"status"`
|
||||
Units float64 `json:"units,string"`
|
||||
UnitsRemaining float64 `json:"units_remaining,string"`
|
||||
Price float64 `json:"price,string"`
|
||||
Fee float64 `json:"fee,string"`
|
||||
Total float64 `json:"total,string"`
|
||||
}
|
||||
|
||||
// UserTransactions holds users full transaction list
|
||||
|
||||
@@ -692,12 +692,12 @@ func (b *Bithumb) GetActiveOrders(ctx context.Context, req *order.GetOrdersReque
|
||||
continue
|
||||
}
|
||||
|
||||
orderDate := time.Unix(resp.Data[i].OrderDate, 0)
|
||||
orderDetail := order.Detail{
|
||||
Amount: resp.Data[i].Units,
|
||||
Exchange: b.Name,
|
||||
ExecutedAmount: resp.Data[i].Units - resp.Data[i].UnitsRemaining,
|
||||
ID: resp.Data[i].OrderID,
|
||||
Date: orderDate,
|
||||
Date: resp.Data[i].OrderDate.Time(),
|
||||
Price: resp.Data[i].Price,
|
||||
RemainingAmount: resp.Data[i].UnitsRemaining,
|
||||
Status: order.Active,
|
||||
@@ -750,14 +750,14 @@ func (b *Bithumb) GetOrderHistory(ctx context.Context, req *order.GetOrdersReque
|
||||
continue
|
||||
}
|
||||
|
||||
orderDate := time.Unix(resp.Data[i].OrderDate, 0)
|
||||
orderDetail := order.Detail{
|
||||
Amount: resp.Data[i].Units,
|
||||
ExecutedAmount: resp.Data[i].Units - resp.Data[i].UnitsRemaining,
|
||||
RemainingAmount: resp.Data[i].UnitsRemaining,
|
||||
Exchange: b.Name,
|
||||
ID: resp.Data[i].OrderID,
|
||||
Date: orderDate,
|
||||
Date: resp.Data[i].OrderDate.Time(),
|
||||
Price: resp.Data[i].Price,
|
||||
RemainingAmount: resp.Data[i].UnitsRemaining,
|
||||
Pair: currency.NewPairWithDelimiter(resp.Data[i].OrderCurrency,
|
||||
resp.Data[i].PaymentCurrency,
|
||||
format.Delimiter),
|
||||
@@ -769,6 +769,7 @@ func (b *Bithumb) GetOrderHistory(ctx context.Context, req *order.GetOrdersReque
|
||||
orderDetail.Side = order.Sell
|
||||
}
|
||||
|
||||
orderDetail.InferCostsAndTimes()
|
||||
orders = append(orders, orderDetail)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -291,18 +291,18 @@ type Order struct {
|
||||
ClOrdID string `json:"clOrdID"`
|
||||
ClOrdLinkID string `json:"clOrdLinkID"`
|
||||
ContingencyType string `json:"contingencyType"`
|
||||
CumQty int64 `json:"cumQty"`
|
||||
CumQty float64 `json:"cumQty"`
|
||||
Currency string `json:"currency"`
|
||||
DisplayQuantity int64 `json:"displayQty"`
|
||||
ExDestination string `json:"exDestination"`
|
||||
ExecInst string `json:"execInst"`
|
||||
LeavesQty int64 `json:"leavesQty"`
|
||||
LeavesQty float64 `json:"leavesQty"`
|
||||
MultiLegReportingType string `json:"multiLegReportingType"`
|
||||
OrdRejReason string `json:"ordRejReason"`
|
||||
OrdStatus string `json:"ordStatus"`
|
||||
OrdType int64 `json:"ordType,string"`
|
||||
OrderID string `json:"orderID"`
|
||||
OrderQty int64 `json:"orderQty"`
|
||||
OrderQty float64 `json:"orderQty"`
|
||||
PegOffsetValue float64 `json:"pegOffsetValue"`
|
||||
PegPriceType string `json:"pegPriceType"`
|
||||
Price float64 `json:"price"`
|
||||
@@ -316,7 +316,7 @@ type Order struct {
|
||||
Text string `json:"text"`
|
||||
TimeInForce string `json:"timeInForce"`
|
||||
Timestamp time.Time `json:"timestamp"`
|
||||
TransactTime string `json:"transactTime"`
|
||||
TransactTime time.Time `json:"transactTime"`
|
||||
Triggered string `json:"triggered"`
|
||||
WorkingIndicator bool `json:"workingIndicator"`
|
||||
}
|
||||
|
||||
@@ -748,20 +748,26 @@ func (b *Bitmex) GetActiveOrders(ctx context.Context, req *order.GetOrdersReques
|
||||
|
||||
for i := range resp {
|
||||
orderSide := orderSideMap[resp[i].Side]
|
||||
orderStatus, err := order.StringToOrderStatus(resp[i].OrdStatus)
|
||||
if err != nil {
|
||||
log.Errorf(log.ExchangeSys, "%s %v", b.Name, err)
|
||||
}
|
||||
orderType := orderTypeMap[resp[i].OrdType]
|
||||
if orderType == "" {
|
||||
orderType = order.UnknownType
|
||||
}
|
||||
|
||||
orderDetail := order.Detail{
|
||||
Date: resp[i].Timestamp,
|
||||
Price: resp[i].Price,
|
||||
Amount: float64(resp[i].OrderQty),
|
||||
Exchange: b.Name,
|
||||
ID: resp[i].OrderID,
|
||||
Side: orderSide,
|
||||
Type: orderType,
|
||||
Status: order.Status(resp[i].OrdStatus),
|
||||
Date: resp[i].Timestamp,
|
||||
Price: resp[i].Price,
|
||||
Amount: resp[i].OrderQty,
|
||||
ExecutedAmount: resp[i].CumQty,
|
||||
RemainingAmount: resp[i].LeavesQty,
|
||||
Exchange: b.Name,
|
||||
ID: resp[i].OrderID,
|
||||
Side: orderSide,
|
||||
Status: orderStatus,
|
||||
Type: orderType,
|
||||
Pair: currency.NewPairWithDelimiter(resp[i].Symbol,
|
||||
resp[i].SettlCurrency,
|
||||
format.Delimiter),
|
||||
@@ -799,23 +805,32 @@ func (b *Bitmex) GetOrderHistory(ctx context.Context, req *order.GetOrdersReques
|
||||
|
||||
for i := range resp {
|
||||
orderSide := orderSideMap[resp[i].Side]
|
||||
orderStatus, err := order.StringToOrderStatus(resp[i].OrdStatus)
|
||||
if err != nil {
|
||||
log.Errorf(log.ExchangeSys, "%s %v", b.Name, err)
|
||||
}
|
||||
orderType := orderTypeMap[resp[i].OrdType]
|
||||
if orderType == "" {
|
||||
orderType = order.UnknownType
|
||||
}
|
||||
pair := currency.NewPairWithDelimiter(resp[i].Symbol, resp[i].SettlCurrency, format.Delimiter)
|
||||
|
||||
orderDetail := order.Detail{
|
||||
Price: resp[i].Price,
|
||||
Amount: float64(resp[i].OrderQty),
|
||||
Exchange: b.Name,
|
||||
ID: resp[i].OrderID,
|
||||
Side: orderSide,
|
||||
Type: orderType,
|
||||
Status: order.Status(resp[i].OrdStatus),
|
||||
Pair: currency.NewPairWithDelimiter(resp[i].Symbol,
|
||||
resp[i].SettlCurrency,
|
||||
format.Delimiter),
|
||||
Price: resp[i].Price,
|
||||
AverageExecutedPrice: resp[i].AvgPx,
|
||||
Amount: resp[i].OrderQty,
|
||||
ExecutedAmount: resp[i].CumQty,
|
||||
RemainingAmount: resp[i].LeavesQty,
|
||||
Date: resp[i].TransactTime,
|
||||
CloseTime: resp[i].Timestamp,
|
||||
Exchange: b.Name,
|
||||
ID: resp[i].OrderID,
|
||||
Side: orderSide,
|
||||
Status: orderStatus,
|
||||
Type: orderType,
|
||||
Pair: pair,
|
||||
}
|
||||
orderDetail.InferCostsAndTimes()
|
||||
|
||||
orders = append(orders, orderDetail)
|
||||
}
|
||||
|
||||
@@ -856,12 +856,13 @@ func (b *Bittrex) GetOrderHistory(ctx context.Context, req *order.GetOrdersReque
|
||||
continue
|
||||
}
|
||||
|
||||
resp = append(resp, order.Detail{
|
||||
detail := order.Detail{
|
||||
Amount: orderData[i].Quantity,
|
||||
RemainingAmount: orderData[i].Quantity - orderData[i].FillQuantity,
|
||||
ExecutedAmount: orderData[i].FillQuantity,
|
||||
RemainingAmount: orderData[i].Quantity - orderData[i].FillQuantity,
|
||||
Price: orderData[i].Limit,
|
||||
Date: orderData[i].CreatedAt,
|
||||
CloseTime: orderData[i].ClosedAt,
|
||||
ID: orderData[i].ID,
|
||||
Exchange: b.Name,
|
||||
Type: orderType,
|
||||
@@ -869,7 +870,9 @@ func (b *Bittrex) GetOrderHistory(ctx context.Context, req *order.GetOrdersReque
|
||||
Status: orderStatus,
|
||||
Fee: orderData[i].Commission,
|
||||
Pair: pair,
|
||||
})
|
||||
}
|
||||
detail.InferCostsAndTimes()
|
||||
resp = append(resp, detail)
|
||||
}
|
||||
|
||||
order.FilterOrdersByType(&resp, req.Type)
|
||||
|
||||
@@ -864,7 +864,10 @@ func (b *BTCMarkets) GetOrderHistory(ctx context.Context, req *order.GetOrdersRe
|
||||
tempResp.ID = tempData.Orders[c].OrderID
|
||||
tempResp.Date = tempData.Orders[c].CreationTime
|
||||
tempResp.Price = tempData.Orders[c].Price
|
||||
tempResp.ExecutedAmount = tempData.Orders[c].Amount
|
||||
tempResp.Amount = tempData.Orders[c].Amount
|
||||
tempResp.ExecutedAmount = tempData.Orders[c].Amount - tempData.Orders[c].OpenAmount
|
||||
tempResp.RemainingAmount = tempData.Orders[c].OpenAmount
|
||||
tempResp.InferCostsAndTimes()
|
||||
resp = append(resp, tempResp)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -648,7 +648,9 @@ func (b *BTSE) GetOrderInfo(ctx context.Context, orderID string, pair currency.P
|
||||
od.Type = orderIntToType(o[i].OrderType)
|
||||
|
||||
od.Price = o[i].Price
|
||||
od.Status = order.Status(o[i].OrderState)
|
||||
if od.Status, err = order.StringToOrderStatus(o[i].OrderState); err != nil {
|
||||
log.Errorf(log.ExchangeSys, "%s %v", b.Name, err)
|
||||
}
|
||||
|
||||
th, err := b.TradeHistory(ctx,
|
||||
"",
|
||||
@@ -782,6 +784,11 @@ func (b *BTSE) GetActiveOrders(ctx context.Context, req *order.GetOrdersRequest)
|
||||
side = order.Sell
|
||||
}
|
||||
|
||||
status, err := order.StringToOrderStatus(resp[i].OrderState)
|
||||
if err != nil {
|
||||
log.Errorf(log.ExchangeSys, "%s %v", b.Name, err)
|
||||
}
|
||||
|
||||
p, err := currency.NewPairDelimiter(resp[i].Symbol,
|
||||
format.Delimiter)
|
||||
if err != nil {
|
||||
@@ -792,14 +799,16 @@ func (b *BTSE) GetActiveOrders(ctx context.Context, req *order.GetOrdersRequest)
|
||||
}
|
||||
|
||||
openOrder := order.Detail{
|
||||
Pair: p,
|
||||
Exchange: b.Name,
|
||||
Amount: resp[i].Size,
|
||||
ID: resp[i].OrderID,
|
||||
Date: time.Unix(resp[i].Timestamp, 0),
|
||||
Side: side,
|
||||
Price: resp[i].Price,
|
||||
Status: order.Status(resp[i].OrderState),
|
||||
Pair: p,
|
||||
Exchange: b.Name,
|
||||
Amount: resp[i].Size,
|
||||
ExecutedAmount: resp[i].FilledSize,
|
||||
RemainingAmount: resp[i].Size - resp[i].FilledSize,
|
||||
ID: resp[i].OrderID,
|
||||
Date: time.Unix(resp[i].Timestamp, 0),
|
||||
Side: side,
|
||||
Price: resp[i].Price,
|
||||
Status: status,
|
||||
}
|
||||
|
||||
if resp[i].OrderType == 77 {
|
||||
@@ -886,24 +895,26 @@ func (b *BTSE) GetOrderHistory(ctx context.Context, getOrdersRequest *order.GetO
|
||||
if !matchType(currentOrder[y].OrderType, orderDeref.Type) {
|
||||
continue
|
||||
}
|
||||
orderStatus, err := order.StringToOrderStatus(currentOrder[x].OrderState)
|
||||
if err != nil {
|
||||
log.Errorf(log.ExchangeSys, "%s %v", b.Name, err)
|
||||
}
|
||||
orderTime := time.UnixMilli(currentOrder[y].Timestamp)
|
||||
tempOrder := order.Detail{
|
||||
Price: currentOrder[y].Price,
|
||||
Amount: currentOrder[y].Size,
|
||||
Side: order.Side(currentOrder[y].Side),
|
||||
Pair: orderDeref.Pairs[x],
|
||||
}
|
||||
switch currentOrder[x].OrderState {
|
||||
case "STATUS_ACTIVE":
|
||||
tempOrder.Status = order.Active
|
||||
case "ORDER_CANCELLED":
|
||||
tempOrder.Status = order.Cancelled
|
||||
case "ORDER_FULLY_TRANSACTED":
|
||||
tempOrder.Status = order.Filled
|
||||
case "ORDER_PARTIALLY_TRANSACTED":
|
||||
tempOrder.Status = order.PartiallyFilled
|
||||
default:
|
||||
tempOrder.Status = order.UnknownStatus
|
||||
ID: currentOrder[y].OrderID,
|
||||
ClientID: currentOrder[y].ClOrderID,
|
||||
Exchange: b.Name,
|
||||
Price: currentOrder[y].Price,
|
||||
AverageExecutedPrice: currentOrder[y].AverageFillPrice,
|
||||
Amount: currentOrder[y].Size,
|
||||
ExecutedAmount: currentOrder[y].FilledSize,
|
||||
RemainingAmount: currentOrder[y].Size - currentOrder[y].FilledSize,
|
||||
Date: orderTime,
|
||||
Side: order.Side(currentOrder[y].Side),
|
||||
Status: orderStatus,
|
||||
Pair: orderDeref.Pairs[x],
|
||||
}
|
||||
tempOrder.InferCostsAndTimes()
|
||||
resp = append(resp, tempOrder)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -125,7 +125,7 @@ type GeneralizedOrderResponse struct {
|
||||
Funds float64 `json:"funds,string"`
|
||||
SpecifiedFunds float64 `json:"specified_funds,string"`
|
||||
DoneReason string `json:"done_reason"`
|
||||
DoneAt string `json:"done_at"`
|
||||
DoneAt time.Time `json:"done_at"`
|
||||
}
|
||||
|
||||
// Funding holds funding data
|
||||
|
||||
@@ -588,10 +588,6 @@ func (c *CoinbasePro) GetOrderInfo(ctx context.Context, orderID string, pair cur
|
||||
if errGo != nil {
|
||||
return order.Detail{}, fmt.Errorf("error retrieving order %s : %s", orderID, errGo)
|
||||
}
|
||||
od, errOd := time.Parse(time.RFC3339, genOrderDetail.DoneAt)
|
||||
if errOd != nil {
|
||||
return order.Detail{}, fmt.Errorf("error parsing order done at time: %s", errOd)
|
||||
}
|
||||
os, errOs := order.StringToOrderStatus(genOrderDetail.Status)
|
||||
if errOs != nil {
|
||||
return order.Detail{}, fmt.Errorf("error parsing order status: %s", errOs)
|
||||
@@ -615,7 +611,7 @@ func (c *CoinbasePro) GetOrderInfo(ctx context.Context, orderID string, pair cur
|
||||
Pair: p,
|
||||
Side: ss,
|
||||
Type: tt,
|
||||
Date: od,
|
||||
Date: genOrderDetail.DoneAt,
|
||||
Status: os,
|
||||
Price: genOrderDetail.Price,
|
||||
Amount: genOrderDetail.Size,
|
||||
@@ -828,20 +824,31 @@ func (c *CoinbasePro) GetOrderHistory(ctx context.Context, req *order.GetOrdersR
|
||||
return nil, err
|
||||
}
|
||||
orderSide := order.Side(strings.ToUpper(respOrders[i].Side))
|
||||
orderStatus, err := order.StringToOrderStatus(respOrders[i].Status)
|
||||
if err != nil {
|
||||
log.Errorf(log.ExchangeSys, "%s %v", c.Name, err)
|
||||
}
|
||||
orderType := order.Type(strings.ToUpper(respOrders[i].Type))
|
||||
orders = append(orders, order.Detail{
|
||||
ID: respOrders[i].ID,
|
||||
Amount: respOrders[i].Size,
|
||||
ExecutedAmount: respOrders[i].FilledSize,
|
||||
Type: orderType,
|
||||
Date: respOrders[i].CreatedAt,
|
||||
Fee: respOrders[i].FillFees,
|
||||
FeeAsset: curr.Quote,
|
||||
Side: orderSide,
|
||||
Pair: curr,
|
||||
Price: respOrders[i].Price,
|
||||
Exchange: c.Name,
|
||||
})
|
||||
detail := order.Detail{
|
||||
ID: respOrders[i].ID,
|
||||
Amount: respOrders[i].Size,
|
||||
ExecutedAmount: respOrders[i].FilledSize,
|
||||
RemainingAmount: respOrders[i].Size - respOrders[i].FilledSize,
|
||||
Cost: respOrders[i].ExecutedValue,
|
||||
CostAsset: curr.Quote,
|
||||
Type: orderType,
|
||||
Date: respOrders[i].CreatedAt,
|
||||
CloseTime: respOrders[i].DoneAt,
|
||||
Fee: respOrders[i].FillFees,
|
||||
FeeAsset: curr.Quote,
|
||||
Side: orderSide,
|
||||
Status: orderStatus,
|
||||
Pair: curr,
|
||||
Price: respOrders[i].Price,
|
||||
Exchange: c.Name,
|
||||
}
|
||||
detail.InferCostsAndTimes()
|
||||
orders = append(orders, detail)
|
||||
}
|
||||
|
||||
order.FilterOrdersByType(&orders, req.Type)
|
||||
|
||||
@@ -774,7 +774,9 @@ func (c *Coinbene) GetActiveOrders(ctx context.Context, getOrdersRequest *order.
|
||||
tempResp.Side = order.Sell
|
||||
}
|
||||
tempResp.Date = tempData[y].OrderTime
|
||||
tempResp.Status = order.Status(tempData[y].OrderStatus)
|
||||
if tempResp.Status, err = order.StringToOrderStatus(tempData[y].OrderStatus); err != nil {
|
||||
log.Errorf(log.ExchangeSys, "%s %v", c.Name, err)
|
||||
}
|
||||
tempResp.Price = tempData[y].OrderPrice
|
||||
tempResp.Amount = tempData[y].Amount
|
||||
tempResp.ExecutedAmount = tempData[y].FilledAmount
|
||||
@@ -831,12 +833,18 @@ func (c *Coinbene) GetOrderHistory(ctx context.Context, getOrdersRequest *order.
|
||||
tempResp.Side = order.Sell
|
||||
}
|
||||
tempResp.Date = tempData[y].OrderTime
|
||||
tempResp.Status = order.Status(tempData[y].OrderStatus)
|
||||
if tempResp.Status, err = order.StringToOrderStatus(tempData[y].OrderStatus); err != nil {
|
||||
log.Errorf(log.ExchangeSys, "%s %v", c.Name, err)
|
||||
}
|
||||
tempResp.Price = tempData[y].OrderPrice
|
||||
tempResp.AverageExecutedPrice = tempData[y].AvgPrice
|
||||
tempResp.Amount = tempData[y].Amount
|
||||
tempResp.ExecutedAmount = tempData[y].FilledAmount
|
||||
tempResp.RemainingAmount = tempData[y].Amount - tempData[y].FilledAmount
|
||||
tempResp.Cost = tempData[y].Quantity
|
||||
tempResp.CostAsset = tempResp.Pair.Quote
|
||||
tempResp.Fee = tempData[y].TotalFee
|
||||
tempResp.InferCostsAndTimes()
|
||||
resp = append(resp, tempResp)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -977,7 +977,7 @@ func (c *COINUT) GetOrderHistory(ctx context.Context, req *order.GetOrdersReques
|
||||
return nil, err
|
||||
}
|
||||
|
||||
allOrders = append(allOrders, order.Detail{
|
||||
detail := order.Detail{
|
||||
Exchange: c.Name,
|
||||
ID: strconv.FormatInt(trades.Trades[x].OrderID, 10),
|
||||
Pair: p,
|
||||
@@ -986,9 +986,11 @@ func (c *COINUT) GetOrderHistory(ctx context.Context, req *order.GetOrdersReques
|
||||
Status: order.Filled,
|
||||
Price: trades.Trades[x].Price,
|
||||
Amount: trades.Trades[x].Quantity,
|
||||
ExecutedAmount: trades.Trades[x].Quantity,
|
||||
ExecutedAmount: trades.Trades[x].Quantity - trades.Trades[x].OpenQuantity,
|
||||
RemainingAmount: trades.Trades[x].OpenQuantity,
|
||||
})
|
||||
}
|
||||
detail.InferCostsAndTimes()
|
||||
allOrders = append(allOrders, detail)
|
||||
}
|
||||
if len(trades.Trades) < 100 {
|
||||
break
|
||||
|
||||
@@ -670,21 +670,26 @@ func (e *EXMO) GetOrderHistory(ctx context.Context, req *order.GetOrdersRequest)
|
||||
|
||||
var orders []order.Detail
|
||||
for i := range allTrades {
|
||||
symbol, err := currency.NewPairDelimiter(allTrades[i].Pair, "_")
|
||||
pair, err := currency.NewPairDelimiter(allTrades[i].Pair, "_")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
orderDate := time.Unix(allTrades[i].Date, 0)
|
||||
orderSide := order.Side(strings.ToUpper(allTrades[i].Type))
|
||||
orders = append(orders, order.Detail{
|
||||
ID: strconv.FormatInt(allTrades[i].TradeID, 10),
|
||||
Amount: allTrades[i].Quantity,
|
||||
Date: orderDate,
|
||||
Price: allTrades[i].Price,
|
||||
Side: orderSide,
|
||||
Exchange: e.Name,
|
||||
Pair: symbol,
|
||||
})
|
||||
detail := order.Detail{
|
||||
ID: strconv.FormatInt(allTrades[i].TradeID, 10),
|
||||
Amount: allTrades[i].Quantity,
|
||||
ExecutedAmount: allTrades[i].Quantity,
|
||||
Cost: allTrades[i].Amount,
|
||||
CostAsset: pair.Quote,
|
||||
Date: orderDate,
|
||||
Price: allTrades[i].Price,
|
||||
Side: orderSide,
|
||||
Exchange: e.Name,
|
||||
Pair: pair,
|
||||
}
|
||||
detail.InferCostsAndTimes()
|
||||
orders = append(orders, detail)
|
||||
}
|
||||
|
||||
order.FilterOrdersByTimeRange(&orders, req.StartTime, req.EndTime)
|
||||
|
||||
@@ -1016,6 +1016,7 @@ func (f *FTX) GetOrderHistory(ctx context.Context, getOrdersRequest *order.GetOr
|
||||
tempResp.ID = strconv.FormatInt(orderData[y].ID, 10)
|
||||
tempResp.Amount = orderData[y].Size
|
||||
tempResp.AssetType = assetType
|
||||
tempResp.AverageExecutedPrice = orderData[y].AvgFillPrice
|
||||
tempResp.ClientOrderID = orderData[y].ClientID
|
||||
tempResp.Date = orderData[y].CreatedAt
|
||||
tempResp.Exchange = f.Name
|
||||
@@ -1080,6 +1081,7 @@ func (f *FTX) GetOrderHistory(ctx context.Context, getOrdersRequest *order.GetOr
|
||||
tempResp.Side = orderVars.Side
|
||||
tempResp.Type = orderVars.OrderType
|
||||
tempResp.Fee = orderVars.Fee
|
||||
tempResp.InferCostsAndTimes()
|
||||
resp = append(resp, tempResp)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -605,7 +605,9 @@ func (g *Gateio) GetOrderInfo(ctx context.Context, orderID string, pair currency
|
||||
orderDetail.ExecutedAmount = orders.Orders[x].FilledAmount
|
||||
orderDetail.Amount = orders.Orders[x].InitialAmount
|
||||
orderDetail.Date = time.Unix(orders.Orders[x].Timestamp, 0)
|
||||
orderDetail.Status = order.Status(orders.Orders[x].Status)
|
||||
if orderDetail.Status, err = order.StringToOrderStatus(orders.Orders[x].Status); err != nil {
|
||||
log.Errorf(log.ExchangeSys, "%s %v", g.Name, err)
|
||||
}
|
||||
orderDetail.Price = orders.Orders[x].Rate
|
||||
orderDetail.Pair, err = currency.NewPairDelimiter(orders.Orders[x].CurrencyPair,
|
||||
format.Delimiter)
|
||||
@@ -763,17 +765,22 @@ func (g *Gateio) GetActiveOrders(ctx context.Context, req *order.GetOrdersReques
|
||||
return nil, err
|
||||
}
|
||||
side := order.Side(strings.ToUpper(resp.Orders[i].Type))
|
||||
status, err := order.StringToOrderStatus(resp.Orders[i].Status)
|
||||
if err != nil {
|
||||
log.Errorf(log.ExchangeSys, "%s %v", g.Name, err)
|
||||
}
|
||||
orderDate := time.Unix(resp.Orders[i].Timestamp, 0)
|
||||
orders = append(orders, order.Detail{
|
||||
ID: resp.Orders[i].OrderNumber,
|
||||
Amount: resp.Orders[i].Amount,
|
||||
Price: resp.Orders[i].Rate,
|
||||
ExecutedAmount: resp.Orders[i].Amount - resp.Orders[i].FilledAmount,
|
||||
RemainingAmount: resp.Orders[i].FilledAmount,
|
||||
Price: resp.Orders[i].Rate,
|
||||
Date: orderDate,
|
||||
Side: side,
|
||||
Exchange: g.Name,
|
||||
Pair: symbol,
|
||||
Status: order.Status(resp.Orders[i].Status),
|
||||
Status: status,
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -805,22 +812,26 @@ func (g *Gateio) GetOrderHistory(ctx context.Context, req *order.GetOrdersReques
|
||||
|
||||
var orders []order.Detail
|
||||
for i := range trades {
|
||||
var symbol currency.Pair
|
||||
symbol, err = currency.NewPairDelimiter(trades[i].Pair, format.Delimiter)
|
||||
var pair currency.Pair
|
||||
pair, err = currency.NewPairDelimiter(trades[i].Pair, format.Delimiter)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
side := order.Side(strings.ToUpper(trades[i].Type))
|
||||
orderDate := time.Unix(trades[i].TimeUnix, 0)
|
||||
orders = append(orders, order.Detail{
|
||||
ID: strconv.FormatInt(trades[i].OrderID, 10),
|
||||
Amount: trades[i].Amount,
|
||||
Price: trades[i].Rate,
|
||||
Date: orderDate,
|
||||
Side: side,
|
||||
Exchange: g.Name,
|
||||
Pair: symbol,
|
||||
})
|
||||
detail := order.Detail{
|
||||
ID: strconv.FormatInt(trades[i].OrderID, 10),
|
||||
Amount: trades[i].Amount,
|
||||
ExecutedAmount: trades[i].Amount,
|
||||
Price: trades[i].Rate,
|
||||
AverageExecutedPrice: trades[i].Rate,
|
||||
Date: orderDate,
|
||||
Side: side,
|
||||
Exchange: g.Name,
|
||||
Pair: pair,
|
||||
}
|
||||
detail.InferCostsAndTimes()
|
||||
orders = append(orders, detail)
|
||||
}
|
||||
|
||||
order.FilterOrdersByTimeRange(&orders, req.StartTime, req.EndTime)
|
||||
|
||||
@@ -757,18 +757,24 @@ func (g *Gemini) GetOrderHistory(ctx context.Context, req *order.GetOrdersReques
|
||||
side := order.Side(strings.ToUpper(trades[i].Type))
|
||||
orderDate := time.Unix(trades[i].Timestamp, 0)
|
||||
|
||||
orders = append(orders, order.Detail{
|
||||
Amount: trades[i].Amount,
|
||||
ID: strconv.FormatInt(trades[i].OrderID, 10),
|
||||
Exchange: g.Name,
|
||||
Date: orderDate,
|
||||
Side: side,
|
||||
Fee: trades[i].FeeAmount,
|
||||
Price: trades[i].Price,
|
||||
Pair: currency.NewPairWithDelimiter(trades[i].BaseCurrency,
|
||||
detail := order.Detail{
|
||||
ID: strconv.FormatInt(trades[i].OrderID, 10),
|
||||
Amount: trades[i].Amount,
|
||||
ExecutedAmount: trades[i].Amount,
|
||||
Exchange: g.Name,
|
||||
Date: orderDate,
|
||||
Side: side,
|
||||
Fee: trades[i].FeeAmount,
|
||||
Price: trades[i].Price,
|
||||
AverageExecutedPrice: trades[i].Price,
|
||||
Pair: currency.NewPairWithDelimiter(
|
||||
trades[i].BaseCurrency,
|
||||
trades[i].QuoteCurrency,
|
||||
format.Delimiter),
|
||||
})
|
||||
format.Delimiter,
|
||||
),
|
||||
}
|
||||
detail.InferCostsAndTimes()
|
||||
orders = append(orders, detail)
|
||||
}
|
||||
|
||||
order.FilterOrdersByTimeRange(&orders, req.StartTime, req.EndTime)
|
||||
|
||||
@@ -184,6 +184,7 @@ type OrderHistoryResponse struct {
|
||||
Type string `json:"type"`
|
||||
TimeInForce string `json:"timeInForce"`
|
||||
Price float64 `json:"price,string"`
|
||||
AvgPrice float64 `json:"avgPrice,string"`
|
||||
Quantity float64 `json:"quantity,string"`
|
||||
PostOnly bool `json:"postOnly"`
|
||||
CumQuantity float64 `json:"cumQuantity,string"`
|
||||
|
||||
@@ -768,22 +768,33 @@ func (h *HitBTC) GetOrderHistory(ctx context.Context, req *order.GetOrdersReques
|
||||
|
||||
var orders []order.Detail
|
||||
for i := range allOrders {
|
||||
var symbol currency.Pair
|
||||
symbol, err = currency.NewPairDelimiter(allOrders[i].Symbol,
|
||||
var pair currency.Pair
|
||||
pair, err = currency.NewPairDelimiter(allOrders[i].Symbol,
|
||||
format.Delimiter)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
side := order.Side(strings.ToUpper(allOrders[i].Side))
|
||||
orders = append(orders, order.Detail{
|
||||
ID: allOrders[i].ID,
|
||||
Amount: allOrders[i].Quantity,
|
||||
Exchange: h.Name,
|
||||
Price: allOrders[i].Price,
|
||||
Date: allOrders[i].CreatedAt,
|
||||
Side: side,
|
||||
Pair: symbol,
|
||||
})
|
||||
status, err := order.StringToOrderStatus(allOrders[i].Status)
|
||||
if err != nil {
|
||||
log.Errorf(log.ExchangeSys, "%s %v", h.Name, err)
|
||||
}
|
||||
detail := order.Detail{
|
||||
ID: allOrders[i].ID,
|
||||
Amount: allOrders[i].Quantity,
|
||||
ExecutedAmount: allOrders[i].CumQuantity,
|
||||
RemainingAmount: allOrders[i].Quantity - allOrders[i].CumQuantity,
|
||||
Exchange: h.Name,
|
||||
Price: allOrders[i].Price,
|
||||
AverageExecutedPrice: allOrders[i].AvgPrice,
|
||||
Date: allOrders[i].CreatedAt,
|
||||
LastUpdated: allOrders[i].UpdatedAt,
|
||||
Side: side,
|
||||
Status: status,
|
||||
Pair: pair,
|
||||
}
|
||||
detail.InferCostsAndTimes()
|
||||
orders = append(orders, detail)
|
||||
}
|
||||
|
||||
order.FilterOrdersByTimeRange(&orders, req.StartTime, req.EndTime)
|
||||
|
||||
@@ -1384,18 +1384,18 @@ func (h *HUOBI) GetActiveOrders(ctx context.Context, req *order.GetOrdersRequest
|
||||
}
|
||||
for x := range resp {
|
||||
orderDetail := order.Detail{
|
||||
ID: strconv.FormatInt(resp[x].ID, 10),
|
||||
Price: resp[x].Price,
|
||||
Amount: resp[x].Amount,
|
||||
Pair: req.Pairs[i],
|
||||
Exchange: h.Name,
|
||||
ExecutedAmount: resp[x].FilledAmount,
|
||||
Date: time.UnixMilli(resp[x].CreatedAt),
|
||||
Status: order.Status(resp[x].State),
|
||||
AccountID: strconv.FormatInt(resp[x].AccountID, 10),
|
||||
Fee: resp[x].FilledFees,
|
||||
ID: strconv.FormatInt(resp[x].ID, 10),
|
||||
Price: resp[x].Price,
|
||||
Amount: resp[x].Amount,
|
||||
ExecutedAmount: resp[x].FilledAmount,
|
||||
RemainingAmount: resp[x].Amount - resp[x].FilledAmount,
|
||||
Pair: req.Pairs[i],
|
||||
Exchange: h.Name,
|
||||
Date: time.UnixMilli(resp[x].CreatedAt),
|
||||
AccountID: strconv.FormatInt(resp[x].AccountID, 10),
|
||||
Fee: resp[x].FilledFees,
|
||||
}
|
||||
setOrderSideAndType(resp[x].Type, &orderDetail)
|
||||
setOrderSideStatusAndType(resp[x].State, resp[x].Type, &orderDetail)
|
||||
orders = append(orders, orderDetail)
|
||||
}
|
||||
}
|
||||
@@ -1520,18 +1520,22 @@ func (h *HUOBI) GetOrderHistory(ctx context.Context, req *order.GetOrdersRequest
|
||||
}
|
||||
for x := range resp {
|
||||
orderDetail := order.Detail{
|
||||
ID: strconv.FormatInt(resp[x].ID, 10),
|
||||
Price: resp[x].Price,
|
||||
Amount: resp[x].Amount,
|
||||
Pair: req.Pairs[i],
|
||||
Exchange: h.Name,
|
||||
ExecutedAmount: resp[x].FilledAmount,
|
||||
Date: time.UnixMilli(resp[x].CreatedAt),
|
||||
Status: order.Status(resp[x].State),
|
||||
AccountID: strconv.FormatInt(resp[x].AccountID, 10),
|
||||
Fee: resp[x].FilledFees,
|
||||
ID: strconv.FormatInt(resp[x].ID, 10),
|
||||
Price: resp[x].Price,
|
||||
Amount: resp[x].Amount,
|
||||
ExecutedAmount: resp[x].FilledAmount,
|
||||
RemainingAmount: resp[x].Amount - resp[x].FilledAmount,
|
||||
Cost: resp[x].FilledCashAmount,
|
||||
CostAsset: req.Pairs[i].Quote,
|
||||
Pair: req.Pairs[i],
|
||||
Exchange: h.Name,
|
||||
Date: time.UnixMilli(resp[x].CreatedAt),
|
||||
CloseTime: time.UnixMilli(resp[x].FinishedAt),
|
||||
AccountID: strconv.FormatInt(resp[x].AccountID, 10),
|
||||
Fee: resp[x].FilledFees,
|
||||
}
|
||||
setOrderSideAndType(resp[x].Type, &orderDetail)
|
||||
setOrderSideStatusAndType(resp[x].State, resp[x].Type, &orderDetail)
|
||||
orderDetail.InferCostsAndTimes()
|
||||
orders = append(orders, orderDetail)
|
||||
}
|
||||
}
|
||||
@@ -1648,7 +1652,12 @@ func (h *HUOBI) GetOrderHistory(ctx context.Context, req *order.GetOrdersRequest
|
||||
return orders, nil
|
||||
}
|
||||
|
||||
func setOrderSideAndType(requestType string, orderDetail *order.Detail) {
|
||||
func setOrderSideStatusAndType(orderState, requestType string, orderDetail *order.Detail) {
|
||||
var err error
|
||||
if orderDetail.Status, err = order.StringToOrderStatus(orderState); err != nil {
|
||||
log.Errorf(log.ExchangeSys, "%s %v", orderDetail.Exchange, err)
|
||||
}
|
||||
|
||||
switch SpotNewOrderRequestParamsType(requestType) {
|
||||
case SpotNewOrderRequestTypeBuyMarket:
|
||||
orderDetail.Side = order.Buy
|
||||
|
||||
@@ -614,6 +614,10 @@ func (i *ItBit) GetOrderHistory(ctx context.Context, req *order.GetOrdersRequest
|
||||
}
|
||||
|
||||
side := order.Side(strings.ToUpper(allOrders[j].Side))
|
||||
status, err := order.StringToOrderStatus(allOrders[j].Status)
|
||||
if err != nil {
|
||||
log.Errorf(log.ExchangeSys, "%s %v", i.Name, err)
|
||||
}
|
||||
orderDate, err := time.Parse(time.RFC3339, allOrders[j].CreatedTime)
|
||||
if err != nil {
|
||||
log.Errorf(log.ExchangeSys,
|
||||
@@ -624,16 +628,21 @@ func (i *ItBit) GetOrderHistory(ctx context.Context, req *order.GetOrdersRequest
|
||||
allOrders[j].CreatedTime)
|
||||
}
|
||||
|
||||
orders = append(orders, order.Detail{
|
||||
ID: allOrders[j].ID,
|
||||
Side: side,
|
||||
Amount: allOrders[j].Amount,
|
||||
ExecutedAmount: allOrders[j].AmountFilled,
|
||||
RemainingAmount: (allOrders[j].Amount - allOrders[j].AmountFilled),
|
||||
Exchange: i.Name,
|
||||
Date: orderDate,
|
||||
Pair: symbol,
|
||||
})
|
||||
detail := order.Detail{
|
||||
ID: allOrders[j].ID,
|
||||
Side: side,
|
||||
Status: status,
|
||||
Amount: allOrders[j].Amount,
|
||||
ExecutedAmount: allOrders[j].AmountFilled,
|
||||
RemainingAmount: allOrders[j].Amount - allOrders[j].AmountFilled,
|
||||
Price: allOrders[j].Price,
|
||||
AverageExecutedPrice: allOrders[j].VolumeWeightedAveragePrice,
|
||||
Exchange: i.Name,
|
||||
Date: orderDate,
|
||||
Pair: symbol,
|
||||
}
|
||||
detail.InferCostsAndTimes()
|
||||
orders = append(orders, detail)
|
||||
}
|
||||
|
||||
order.FilterOrdersByTimeRange(&orders, req.StartTime, req.EndTime)
|
||||
|
||||
@@ -904,7 +904,7 @@ func (k *Kraken) GetOrderInfo(ctx context.Context, orderID string, pair currency
|
||||
}
|
||||
status, err := order.StringToOrderStatus(orderInfo.Status)
|
||||
if err != nil {
|
||||
return orderDetail, err
|
||||
log.Errorf(log.ExchangeSys, "%s %v", k.Name, err)
|
||||
}
|
||||
oType, err := order.StringToOrderType(orderInfo.Description.OrderType)
|
||||
if err != nil {
|
||||
@@ -1225,20 +1225,29 @@ func (k *Kraken) GetOrderHistory(ctx context.Context, getOrdersRequest *order.Ge
|
||||
}
|
||||
|
||||
side := order.Side(strings.ToUpper(resp.Closed[i].Description.Type))
|
||||
status, err := order.StringToOrderStatus(resp.Closed[i].Status)
|
||||
if err != nil {
|
||||
log.Errorf(log.ExchangeSys, "%s %v", k.Name, err)
|
||||
}
|
||||
orderType := order.Type(strings.ToUpper(resp.Closed[i].Description.OrderType))
|
||||
orders = append(orders, order.Detail{
|
||||
detail := order.Detail{
|
||||
ID: i,
|
||||
Amount: resp.Closed[i].Volume,
|
||||
RemainingAmount: (resp.Closed[i].Volume - resp.Closed[i].VolumeExecuted),
|
||||
ExecutedAmount: resp.Closed[i].VolumeExecuted,
|
||||
RemainingAmount: resp.Closed[i].Volume - resp.Closed[i].VolumeExecuted,
|
||||
Cost: resp.Closed[i].Cost,
|
||||
CostAsset: p.Quote,
|
||||
Exchange: k.Name,
|
||||
Date: convert.TimeFromUnixTimestampDecimal(resp.Closed[i].OpenTime),
|
||||
CloseTime: convert.TimeFromUnixTimestampDecimal(resp.Closed[i].CloseTime),
|
||||
Price: resp.Closed[i].Description.Price,
|
||||
Side: side,
|
||||
Status: status,
|
||||
Type: orderType,
|
||||
Pair: p,
|
||||
})
|
||||
}
|
||||
detail.InferCostsAndTimes()
|
||||
orders = append(orders, detail)
|
||||
}
|
||||
case asset.Futures:
|
||||
var orderHistory FuturesRecentOrdersData
|
||||
|
||||
@@ -790,10 +790,11 @@ func (l *Lbank) GetOrderHistory(ctx context.Context, getOrdersRequest *order.Get
|
||||
resp.Status = "Invalid Order Status"
|
||||
}
|
||||
resp.Price = tempResp.Orders[x].Price
|
||||
resp.AverageExecutedPrice = tempResp.Orders[x].AvgPrice
|
||||
resp.Amount = tempResp.Orders[x].Amount
|
||||
resp.Date = time.Unix(tempResp.Orders[x].CreateTime, 0)
|
||||
resp.ExecutedAmount = tempResp.Orders[x].DealAmount
|
||||
resp.RemainingAmount = tempResp.Orders[x].Price - tempResp.Orders[x].DealAmount
|
||||
resp.RemainingAmount = tempResp.Orders[x].Amount - tempResp.Orders[x].DealAmount
|
||||
resp.Fee, err = l.GetFeeByType(ctx,
|
||||
&exchange.FeeBuilder{
|
||||
FeeType: exchange.CryptocurrencyTradeFee,
|
||||
@@ -802,6 +803,7 @@ func (l *Lbank) GetOrderHistory(ctx context.Context, getOrdersRequest *order.Get
|
||||
if err != nil {
|
||||
resp.Fee = lbankFeeNotFound
|
||||
}
|
||||
resp.InferCostsAndTimes()
|
||||
finalResp = append(finalResp, resp)
|
||||
b++
|
||||
}
|
||||
|
||||
@@ -638,6 +638,11 @@ func (l *LocalBitcoins) GetOrderHistory(ctx context.Context, getOrdersRequest *o
|
||||
status = "Closed"
|
||||
}
|
||||
|
||||
orderStatus, err := order.StringToOrderStatus(status)
|
||||
if err != nil {
|
||||
log.Errorf(log.ExchangeSys, "%s %v", l.Name, err)
|
||||
}
|
||||
|
||||
orders = append(orders, order.Detail{
|
||||
Amount: allTrades[i].Data.AmountBTC,
|
||||
Price: allTrades[i].Data.Amount,
|
||||
@@ -645,7 +650,7 @@ func (l *LocalBitcoins) GetOrderHistory(ctx context.Context, getOrdersRequest *o
|
||||
Date: orderDate,
|
||||
Fee: allTrades[i].Data.FeeBTC,
|
||||
Side: side,
|
||||
Status: order.Status(status),
|
||||
Status: orderStatus,
|
||||
Pair: currency.NewPairWithDelimiter(currency.BTC.String(),
|
||||
allTrades[i].Data.Currency,
|
||||
format.Delimiter),
|
||||
|
||||
@@ -319,6 +319,7 @@ type GetSpotOrderResponse struct {
|
||||
Notional string `json:"notional"`
|
||||
OrderID string `json:"order_id"`
|
||||
Price float64 `json:"price,string"`
|
||||
PriceAvg float64 `json:"price_avg,string"`
|
||||
Side string `json:"side"`
|
||||
Size float64 `json:"size,string"`
|
||||
Status string `json:"status"`
|
||||
|
||||
@@ -408,16 +408,20 @@ func (o *OKGroup) GetOrderInfo(ctx context.Context, orderID string, pair currenc
|
||||
return resp, err
|
||||
}
|
||||
|
||||
status, err := order.StringToOrderStatus(mOrder.Status)
|
||||
if err != nil {
|
||||
log.Errorf(log.ExchangeSys, "%s %v", o.Name, err)
|
||||
}
|
||||
resp = order.Detail{
|
||||
Amount: mOrder.Size,
|
||||
Pair: p,
|
||||
Exchange: o.Name,
|
||||
Date: mOrder.Timestamp,
|
||||
ExecutedAmount: mOrder.FilledSize,
|
||||
Status: order.Status(mOrder.Status),
|
||||
Status: status,
|
||||
Side: order.Side(mOrder.Side),
|
||||
}
|
||||
return
|
||||
return resp, nil
|
||||
}
|
||||
|
||||
// GetDepositAddress returns a deposit address for a specified currency
|
||||
@@ -501,6 +505,11 @@ func (o *OKGroup) GetActiveOrders(ctx context.Context, req *order.GetOrdersReque
|
||||
return resp, err
|
||||
}
|
||||
for i := range spotOpenOrders {
|
||||
var status order.Status
|
||||
status, err = order.StringToOrderStatus(spotOpenOrders[i].Status)
|
||||
if err != nil {
|
||||
log.Errorf(log.ExchangeSys, "%s %v", o.Name, err)
|
||||
}
|
||||
resp = append(resp, order.Detail{
|
||||
ID: spotOpenOrders[i].OrderID,
|
||||
Price: spotOpenOrders[i].Price,
|
||||
@@ -511,7 +520,7 @@ func (o *OKGroup) GetActiveOrders(ctx context.Context, req *order.GetOrdersReque
|
||||
Type: order.Type(spotOpenOrders[i].Type),
|
||||
ExecutedAmount: spotOpenOrders[i].FilledSize,
|
||||
Date: spotOpenOrders[i].Timestamp,
|
||||
Status: order.Status(spotOpenOrders[i].Status),
|
||||
Status: status,
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -532,8 +541,8 @@ func (o *OKGroup) GetOrderHistory(ctx context.Context, req *order.GetOrdersReque
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
var spotOpenOrders []GetSpotOrderResponse
|
||||
spotOpenOrders, err = o.GetSpotOrders(ctx,
|
||||
var spotOrders []GetSpotOrderResponse
|
||||
spotOrders, err = o.GetSpotOrders(ctx,
|
||||
GetSpotOrdersRequest{
|
||||
Status: strings.Join([]string{"filled", "cancelled", "failure"}, "|"),
|
||||
InstrumentID: fPair.String(),
|
||||
@@ -541,19 +550,28 @@ func (o *OKGroup) GetOrderHistory(ctx context.Context, req *order.GetOrdersReque
|
||||
if err != nil {
|
||||
return resp, err
|
||||
}
|
||||
for i := range spotOpenOrders {
|
||||
resp = append(resp, order.Detail{
|
||||
ID: spotOpenOrders[i].OrderID,
|
||||
Price: spotOpenOrders[i].Price,
|
||||
Amount: spotOpenOrders[i].Size,
|
||||
Pair: req.Pairs[x],
|
||||
Exchange: o.Name,
|
||||
Side: order.Side(spotOpenOrders[i].Side),
|
||||
Type: order.Type(spotOpenOrders[i].Type),
|
||||
ExecutedAmount: spotOpenOrders[i].FilledSize,
|
||||
Date: spotOpenOrders[i].Timestamp,
|
||||
Status: order.Status(spotOpenOrders[i].Status),
|
||||
})
|
||||
for i := range spotOrders {
|
||||
var status order.Status
|
||||
status, err = order.StringToOrderStatus(spotOrders[i].Status)
|
||||
if err != nil {
|
||||
log.Errorf(log.ExchangeSys, "%s %v", o.Name, err)
|
||||
}
|
||||
detail := order.Detail{
|
||||
ID: spotOrders[i].OrderID,
|
||||
Price: spotOrders[i].Price,
|
||||
AverageExecutedPrice: spotOrders[i].PriceAvg,
|
||||
Amount: spotOrders[i].Size,
|
||||
ExecutedAmount: spotOrders[i].FilledSize,
|
||||
RemainingAmount: spotOrders[i].Size - spotOrders[i].FilledSize,
|
||||
Pair: req.Pairs[x],
|
||||
Exchange: o.Name,
|
||||
Side: order.Side(spotOrders[i].Side),
|
||||
Type: order.Type(spotOrders[i].Type),
|
||||
Date: spotOrders[i].Timestamp,
|
||||
Status: status,
|
||||
}
|
||||
detail.InferCostsAndTimes()
|
||||
resp = append(resp, detail)
|
||||
}
|
||||
}
|
||||
return resp, err
|
||||
|
||||
@@ -144,6 +144,90 @@ func TestOrderTypes(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestInferCostsAndTimes(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
var detail Detail
|
||||
detail.InferCostsAndTimes()
|
||||
if detail.Amount != detail.ExecutedAmount+detail.RemainingAmount {
|
||||
t.Errorf(
|
||||
"Order detail amounts not equals. Expected 0, received %f",
|
||||
detail.Amount-(detail.ExecutedAmount+detail.RemainingAmount),
|
||||
)
|
||||
}
|
||||
|
||||
detail.CloseTime = time.Now()
|
||||
detail.InferCostsAndTimes()
|
||||
if detail.LastUpdated != detail.CloseTime {
|
||||
t.Errorf(
|
||||
"Order last updated not equals close time. Expected %s, received %s",
|
||||
detail.CloseTime,
|
||||
detail.LastUpdated,
|
||||
)
|
||||
}
|
||||
|
||||
detail.Amount = 1
|
||||
detail.ExecutedAmount = 1
|
||||
detail.InferCostsAndTimes()
|
||||
if detail.AverageExecutedPrice != 0 {
|
||||
t.Errorf(
|
||||
"Unexpected AverageExecutedPrice. Expected 0, received %f",
|
||||
detail.AverageExecutedPrice,
|
||||
)
|
||||
}
|
||||
|
||||
detail.Amount = 1
|
||||
detail.ExecutedAmount = 1
|
||||
detail.InferCostsAndTimes()
|
||||
if detail.Cost != 0 {
|
||||
t.Errorf(
|
||||
"Unexpected Cost. Expected 0, received %f",
|
||||
detail.Cost,
|
||||
)
|
||||
}
|
||||
detail.ExecutedAmount = 0
|
||||
|
||||
detail.Amount = 1
|
||||
detail.RemainingAmount = 1
|
||||
detail.InferCostsAndTimes()
|
||||
if detail.Amount != detail.ExecutedAmount+detail.RemainingAmount {
|
||||
t.Errorf(
|
||||
"Order detail amounts not equals. Expected 0, received %f",
|
||||
detail.Amount-(detail.ExecutedAmount+detail.RemainingAmount),
|
||||
)
|
||||
}
|
||||
detail.RemainingAmount = 0
|
||||
|
||||
detail.Amount = 1
|
||||
detail.ExecutedAmount = 1
|
||||
detail.Price = 2
|
||||
detail.InferCostsAndTimes()
|
||||
if detail.AverageExecutedPrice != 2 {
|
||||
t.Errorf(
|
||||
"Unexpected AverageExecutedPrice. Expected 2, received %f",
|
||||
detail.AverageExecutedPrice,
|
||||
)
|
||||
}
|
||||
|
||||
detail = Detail{Amount: 1, ExecutedAmount: 2, Cost: 3, Price: 0}
|
||||
detail.InferCostsAndTimes()
|
||||
if detail.AverageExecutedPrice != 1.5 {
|
||||
t.Errorf(
|
||||
"Unexpected AverageExecutedPrice. Expected 1.5, received %f",
|
||||
detail.AverageExecutedPrice,
|
||||
)
|
||||
}
|
||||
|
||||
detail = Detail{Amount: 1, ExecutedAmount: 2, AverageExecutedPrice: 3}
|
||||
detail.InferCostsAndTimes()
|
||||
if detail.Cost != 6 {
|
||||
t.Errorf(
|
||||
"Unexpected Cost. Expected 6, received %f",
|
||||
detail.Cost,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
func TestFilterOrdersByType(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
|
||||
@@ -488,6 +488,36 @@ func (s Status) String() string {
|
||||
return string(s)
|
||||
}
|
||||
|
||||
// InferCostsAndTimes infer order costs using execution information and times when available
|
||||
func (d *Detail) InferCostsAndTimes() {
|
||||
if d.CostAsset.IsEmpty() {
|
||||
d.CostAsset = d.Pair.Quote
|
||||
}
|
||||
|
||||
if d.LastUpdated.IsZero() {
|
||||
if d.CloseTime.IsZero() {
|
||||
d.LastUpdated = d.Date
|
||||
} else {
|
||||
d.LastUpdated = d.CloseTime
|
||||
}
|
||||
}
|
||||
|
||||
if d.ExecutedAmount <= 0 {
|
||||
return
|
||||
}
|
||||
|
||||
if d.AverageExecutedPrice == 0 {
|
||||
if d.Cost != 0 {
|
||||
d.AverageExecutedPrice = d.Cost / d.ExecutedAmount
|
||||
} else {
|
||||
d.AverageExecutedPrice = d.Price
|
||||
}
|
||||
}
|
||||
if d.Cost == 0 {
|
||||
d.Cost = d.AverageExecutedPrice * d.ExecutedAmount
|
||||
}
|
||||
}
|
||||
|
||||
// FilterOrdersBySide removes any order details that don't match the
|
||||
// order status provided
|
||||
func FilterOrdersBySide(orders *[]Detail, side Side) {
|
||||
@@ -743,7 +773,8 @@ func StringToOrderStatus(status string) (Status, error) {
|
||||
case strings.EqualFold(status, New.String()),
|
||||
strings.EqualFold(status, "placed"):
|
||||
return New, nil
|
||||
case strings.EqualFold(status, Active.String()):
|
||||
case strings.EqualFold(status, Active.String()),
|
||||
strings.EqualFold(status, "STATUS_ACTIVE"): // BTSE case
|
||||
return Active, nil
|
||||
case strings.EqualFold(status, PartiallyFilled.String()),
|
||||
strings.EqualFold(status, "partially matched"),
|
||||
@@ -751,18 +782,20 @@ func StringToOrderStatus(status string) (Status, error) {
|
||||
return PartiallyFilled, nil
|
||||
case strings.EqualFold(status, Filled.String()),
|
||||
strings.EqualFold(status, "fully matched"),
|
||||
strings.EqualFold(status, "fully filled"):
|
||||
strings.EqualFold(status, "fully filled"),
|
||||
strings.EqualFold(status, "ORDER_FULLY_TRANSACTED"): // BTSE case
|
||||
return Filled, nil
|
||||
case strings.EqualFold(status, PartiallyCancelled.String()),
|
||||
strings.EqualFold(status, "partially cancelled"):
|
||||
strings.EqualFold(status, "partially cancelled"),
|
||||
strings.EqualFold(status, "ORDER_PARTIALLY_TRANSACTED"): // BTSE case
|
||||
return PartiallyCancelled, nil
|
||||
case strings.EqualFold(status, Open.String()):
|
||||
return Open, nil
|
||||
case strings.EqualFold(status, Closed.String()):
|
||||
return Closed, nil
|
||||
case strings.EqualFold(status, Cancelled.String()):
|
||||
return Cancelled, nil
|
||||
case strings.EqualFold(status, "CANCELED"): // Kraken case
|
||||
case strings.EqualFold(status, Cancelled.String()),
|
||||
strings.EqualFold(status, "CANCELED"), // Binance and Kraken case
|
||||
strings.EqualFold(status, "ORDER_CANCELLED"): // BTSE case
|
||||
return Cancelled, nil
|
||||
case strings.EqualFold(status, PendingCancel.String()),
|
||||
strings.EqualFold(status, "pending cancel"),
|
||||
|
||||
@@ -668,7 +668,9 @@ func (p *Poloniex) GetOrderInfo(ctx context.Context, orderID string, pair curren
|
||||
return orderInfo, err
|
||||
}
|
||||
|
||||
orderInfo.Status, _ = order.StringToOrderStatus(resp.Status)
|
||||
if orderInfo.Status, err = order.StringToOrderStatus(resp.Status); err != nil {
|
||||
log.Errorf(log.ExchangeSys, "%s %v", p.Name, err)
|
||||
}
|
||||
orderInfo.Price = resp.Rate
|
||||
orderInfo.Amount = resp.Amount
|
||||
orderInfo.Cost = resp.Total
|
||||
@@ -874,8 +876,8 @@ func (p *Poloniex) GetOrderHistory(ctx context.Context, req *order.GetOrdersRequ
|
||||
|
||||
var orders []order.Detail
|
||||
for key := range resp.Data {
|
||||
var symbol currency.Pair
|
||||
symbol, err = currency.NewPairDelimiter(key, format.Delimiter)
|
||||
var pair currency.Pair
|
||||
pair, err = currency.NewPairDelimiter(key, format.Delimiter)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -893,15 +895,20 @@ func (p *Poloniex) GetOrderHistory(ctx context.Context, req *order.GetOrdersRequ
|
||||
resp.Data[key][i].Date)
|
||||
}
|
||||
|
||||
orders = append(orders, order.Detail{
|
||||
ID: strconv.FormatInt(resp.Data[key][i].GlobalTradeID, 10),
|
||||
Side: orderSide,
|
||||
Amount: resp.Data[key][i].Amount,
|
||||
Date: orderDate,
|
||||
Price: resp.Data[key][i].Rate,
|
||||
Pair: symbol,
|
||||
Exchange: p.Name,
|
||||
})
|
||||
detail := order.Detail{
|
||||
ID: strconv.FormatInt(resp.Data[key][i].GlobalTradeID, 10),
|
||||
Side: orderSide,
|
||||
Amount: resp.Data[key][i].Amount,
|
||||
ExecutedAmount: resp.Data[key][i].Amount,
|
||||
Date: orderDate,
|
||||
Price: resp.Data[key][i].Rate,
|
||||
AverageExecutedPrice: resp.Data[key][i].Rate,
|
||||
Pair: pair,
|
||||
Status: order.Filled,
|
||||
Exchange: p.Name,
|
||||
}
|
||||
detail.InferCostsAndTimes()
|
||||
orders = append(orders, detail)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -635,22 +635,27 @@ func (y *Yobit) GetOrderHistory(ctx context.Context, req *order.GetOrdersRequest
|
||||
|
||||
var orders []order.Detail
|
||||
for i := range allOrders {
|
||||
var symbol currency.Pair
|
||||
symbol, err = currency.NewPairDelimiter(allOrders[i].Pair, format.Delimiter)
|
||||
var pair currency.Pair
|
||||
pair, err = currency.NewPairDelimiter(allOrders[i].Pair, format.Delimiter)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
orderDate := time.Unix(int64(allOrders[i].Timestamp), 0)
|
||||
side := order.Side(strings.ToUpper(allOrders[i].Type))
|
||||
orders = append(orders, order.Detail{
|
||||
ID: strconv.FormatFloat(allOrders[i].OrderID, 'f', -1, 64),
|
||||
Amount: allOrders[i].Amount,
|
||||
Price: allOrders[i].Rate,
|
||||
Side: side,
|
||||
Date: orderDate,
|
||||
Pair: symbol,
|
||||
Exchange: y.Name,
|
||||
})
|
||||
detail := order.Detail{
|
||||
ID: strconv.FormatFloat(allOrders[i].OrderID, 'f', -1, 64),
|
||||
Amount: allOrders[i].Amount,
|
||||
ExecutedAmount: allOrders[i].Amount,
|
||||
Price: allOrders[i].Rate,
|
||||
AverageExecutedPrice: allOrders[i].Rate,
|
||||
Side: side,
|
||||
Status: order.Filled,
|
||||
Date: orderDate,
|
||||
Pair: pair,
|
||||
Exchange: y.Name,
|
||||
}
|
||||
detail.InferCostsAndTimes()
|
||||
orders = append(orders, detail)
|
||||
}
|
||||
|
||||
order.FilterOrdersBySide(&orders, req.Side)
|
||||
|
||||
@@ -40,7 +40,7 @@ type Order struct {
|
||||
Price float64 `json:"price"`
|
||||
Status int `json:"status"`
|
||||
TotalAmount float64 `json:"total_amount"`
|
||||
TradeAmount int `json:"trade_amount"`
|
||||
TradeAmount float64 `json:"trade_amount"`
|
||||
TradeDate int `json:"trade_date"`
|
||||
TradeMoney float64 `json:"trade_money"`
|
||||
Type int64 `json:"type"`
|
||||
|
||||
@@ -812,23 +812,28 @@ func (z *ZB) GetOrderHistory(ctx context.Context, req *order.GetOrdersRequest) (
|
||||
}
|
||||
|
||||
for i := range allOrders {
|
||||
var symbol currency.Pair
|
||||
symbol, err = currency.NewPairDelimiter(allOrders[i].Currency,
|
||||
var pair currency.Pair
|
||||
pair, err = currency.NewPairDelimiter(allOrders[i].Currency,
|
||||
format.Delimiter)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
orderDate := time.Unix(int64(allOrders[i].TradeDate), 0)
|
||||
orderSide := orderSideMap[allOrders[i].Type]
|
||||
orders = append(orders, order.Detail{
|
||||
ID: strconv.FormatInt(allOrders[i].ID, 10),
|
||||
Amount: allOrders[i].TotalAmount,
|
||||
Exchange: z.Name,
|
||||
Date: orderDate,
|
||||
Price: allOrders[i].Price,
|
||||
Side: orderSide,
|
||||
Pair: symbol,
|
||||
})
|
||||
detail := order.Detail{
|
||||
ID: strconv.FormatInt(allOrders[i].ID, 10),
|
||||
Amount: allOrders[i].TotalAmount,
|
||||
ExecutedAmount: allOrders[i].TradeAmount,
|
||||
RemainingAmount: allOrders[i].TotalAmount - allOrders[i].TradeAmount,
|
||||
Exchange: z.Name,
|
||||
Date: orderDate,
|
||||
Price: allOrders[i].Price,
|
||||
AverageExecutedPrice: allOrders[i].TradePrice,
|
||||
Side: orderSide,
|
||||
Pair: pair,
|
||||
}
|
||||
detail.InferCostsAndTimes()
|
||||
orders = append(orders, detail)
|
||||
}
|
||||
|
||||
order.FilterOrdersByTimeRange(&orders, req.StartTime, req.EndTime)
|
||||
|
||||
Reference in New Issue
Block a user