mirror of
https://github.com/d0zingcat/gocryptotrader.git
synced 2026-05-16 23:16:48 +00:00
order: slight optimizations (#917)
* order: slight optimizations * orders: add benchmarks, small optimize and change order side to uin8 for comparitive optimizations. * orders: continue to convert string type -> uint * orders/backtester: interim move type to orders package, later can expand or deprecate. * orders: handle errors * orders: optimize filters and remove error returns when its clearly not needed * orders: remove log call * backtester: zero value check * orders/futures: zero value -> flag * linter: fix * linter: more fixes * linters: rides again * glorious: nits * common: Add zero value unix check for time values; also addresses glorious nits * glorious scott: nits Co-authored-by: Ryan O'Hara-Reid <ryan.oharareid@thrasher.io>
This commit is contained in:
@@ -12,20 +12,6 @@ import (
|
||||
)
|
||||
|
||||
const (
|
||||
// DoNothing is an explicit signal for the backtester to not perform an action
|
||||
// based upon indicator results
|
||||
DoNothing order.Side = "DO NOTHING"
|
||||
// TransferredFunds is a status signal to do nothing
|
||||
TransferredFunds order.Side = "TRANSFERRED FUNDS"
|
||||
// CouldNotBuy is flagged when a BUY signal is raised in the strategy/signal phase, but the
|
||||
// portfolio manager or exchange cannot place an order
|
||||
CouldNotBuy order.Side = "COULD NOT BUY"
|
||||
// CouldNotSell is flagged when a SELL signal is raised in the strategy/signal phase, but the
|
||||
// portfolio manager or exchange cannot place an order
|
||||
CouldNotSell order.Side = "COULD NOT SELL"
|
||||
// MissingData is signalled during the strategy/signal phase when data has been identified as missing
|
||||
// No buy or sell events can occur
|
||||
MissingData order.Side = "MISSING DATA"
|
||||
// CandleStr is a config readable data type to tell the backtester to retrieve candle data
|
||||
CandleStr = "candle"
|
||||
// TradeStr is a config readable data type to tell the backtester to retrieve trade data
|
||||
|
||||
@@ -77,11 +77,11 @@ func (e *Exchange) ExecuteOrder(o order.Event, data data.Handler, orderManager *
|
||||
if err != nil {
|
||||
switch f.GetDirection() {
|
||||
case gctorder.Buy:
|
||||
f.SetDirection(common.CouldNotBuy)
|
||||
f.SetDirection(gctorder.CouldNotBuy)
|
||||
case gctorder.Sell:
|
||||
f.SetDirection(common.CouldNotSell)
|
||||
f.SetDirection(gctorder.CouldNotSell)
|
||||
default:
|
||||
f.SetDirection(common.DoNothing)
|
||||
f.SetDirection(gctorder.DoNothing)
|
||||
}
|
||||
f.AppendReason(err.Error())
|
||||
return f, err
|
||||
@@ -117,9 +117,9 @@ func (e *Exchange) ExecuteOrder(o order.Event, data data.Handler, orderManager *
|
||||
f.AppendReason(fundErr.Error())
|
||||
}
|
||||
if f.GetDirection() == gctorder.Buy {
|
||||
f.SetDirection(common.CouldNotBuy)
|
||||
f.SetDirection(gctorder.CouldNotBuy)
|
||||
} else if f.GetDirection() == gctorder.Sell {
|
||||
f.SetDirection(common.CouldNotSell)
|
||||
f.SetDirection(gctorder.CouldNotSell)
|
||||
}
|
||||
return f, err
|
||||
}
|
||||
@@ -138,7 +138,7 @@ func (e *Exchange) ExecuteOrder(o order.Event, data data.Handler, orderManager *
|
||||
funds.IncreaseAvailable(limitReducedAmount.Mul(adjustedPrice), f.GetDirection())
|
||||
}
|
||||
|
||||
ords := orderManager.GetOrdersSnapshot("")
|
||||
ords := orderManager.GetOrdersSnapshot(gctorder.UnknownStatus)
|
||||
for i := range ords {
|
||||
if ords[i].ID != orderID {
|
||||
continue
|
||||
@@ -172,13 +172,13 @@ func verifyOrderWithinLimits(f *fill.Fill, limitReducedAmount decimal.Decimal, c
|
||||
switch f.GetDirection() {
|
||||
case gctorder.Buy:
|
||||
minMax = cs.BuySide
|
||||
direction = common.CouldNotBuy
|
||||
direction = gctorder.CouldNotBuy
|
||||
case gctorder.Sell:
|
||||
minMax = cs.SellSide
|
||||
direction = common.CouldNotSell
|
||||
direction = gctorder.CouldNotSell
|
||||
default:
|
||||
direction = f.GetDirection()
|
||||
f.SetDirection(common.DoNothing)
|
||||
f.SetDirection(gctorder.DoNothing)
|
||||
return fmt.Errorf("%w: %v", errInvalidDirection, direction)
|
||||
}
|
||||
var minOrMax, belowExceed string
|
||||
|
||||
@@ -73,7 +73,7 @@ func (h *Holding) update(e fill.Event, f funding.IPairReader) {
|
||||
case order.Sell:
|
||||
h.SoldAmount = h.SoldAmount.Add(amount)
|
||||
h.SoldValue = h.SoldAmount.Mul(price)
|
||||
case common.DoNothing, common.CouldNotSell, common.CouldNotBuy, common.MissingData, common.TransferredFunds, "":
|
||||
case order.DoNothing, order.CouldNotSell, order.CouldNotBuy, order.MissingData, order.TransferredFunds, order.UnknownSide:
|
||||
}
|
||||
}
|
||||
h.TotalValueLostToVolumeSizing = h.TotalValueLostToVolumeSizing.Add(e.GetClosePrice().Sub(e.GetVolumeAdjustedPrice()).Mul(e.GetAmount()))
|
||||
|
||||
@@ -17,13 +17,7 @@ import (
|
||||
"github.com/thrasher-corp/gocryptotrader/exchanges/order"
|
||||
)
|
||||
|
||||
const (
|
||||
testExchange = "binance"
|
||||
)
|
||||
|
||||
var (
|
||||
riskFreeRate = decimal.NewFromFloat(0.03)
|
||||
)
|
||||
const testExchange = "binance"
|
||||
|
||||
func pair(t *testing.T) *funding.Pair {
|
||||
t.Helper()
|
||||
|
||||
@@ -101,7 +101,7 @@ func (p *Portfolio) OnSignal(ev signal.Event, cs *exchange.Settings, funds fundi
|
||||
},
|
||||
Direction: ev.GetDirection(),
|
||||
}
|
||||
if ev.GetDirection() == "" {
|
||||
if ev.GetDirection() == gctorder.UnknownSide {
|
||||
return o, errInvalidDirection
|
||||
}
|
||||
|
||||
@@ -114,20 +114,19 @@ func (p *Portfolio) OnSignal(ev signal.Event, cs *exchange.Settings, funds fundi
|
||||
ev.Pair())
|
||||
}
|
||||
|
||||
if ev.GetDirection() == common.DoNothing ||
|
||||
ev.GetDirection() == common.MissingData ||
|
||||
ev.GetDirection() == common.TransferredFunds ||
|
||||
ev.GetDirection() == "" {
|
||||
if ev.GetDirection() == gctorder.DoNothing ||
|
||||
ev.GetDirection() == gctorder.MissingData ||
|
||||
ev.GetDirection() == gctorder.TransferredFunds {
|
||||
return o, nil
|
||||
}
|
||||
|
||||
if !funds.CanPlaceOrder(ev.GetDirection()) {
|
||||
if ev.GetDirection() == gctorder.Sell {
|
||||
o.AppendReason("no holdings to sell")
|
||||
o.SetDirection(common.CouldNotSell)
|
||||
o.SetDirection(gctorder.CouldNotSell)
|
||||
} else if ev.GetDirection() == gctorder.Buy {
|
||||
o.AppendReason("not enough funds to buy")
|
||||
o.SetDirection(common.CouldNotBuy)
|
||||
o.SetDirection(gctorder.CouldNotBuy)
|
||||
}
|
||||
ev.SetDirection(o.Direction)
|
||||
return o, nil
|
||||
@@ -160,12 +159,12 @@ func (p *Portfolio) evaluateOrder(d common.Directioner, originalOrderSignal, siz
|
||||
originalOrderSignal.AppendReason(err.Error())
|
||||
switch d.GetDirection() {
|
||||
case gctorder.Buy:
|
||||
originalOrderSignal.Direction = common.CouldNotBuy
|
||||
originalOrderSignal.Direction = gctorder.CouldNotBuy
|
||||
case gctorder.Sell:
|
||||
originalOrderSignal.Direction = common.CouldNotSell
|
||||
case common.CouldNotBuy, common.CouldNotSell:
|
||||
originalOrderSignal.Direction = gctorder.CouldNotSell
|
||||
case gctorder.CouldNotBuy, gctorder.CouldNotSell:
|
||||
default:
|
||||
originalOrderSignal.Direction = common.DoNothing
|
||||
originalOrderSignal.Direction = gctorder.DoNothing
|
||||
}
|
||||
d.SetDirection(originalOrderSignal.Direction)
|
||||
return originalOrderSignal, nil
|
||||
@@ -180,11 +179,11 @@ func (p *Portfolio) sizeOrder(d common.Directioner, cs *exchange.Settings, origi
|
||||
originalOrderSignal.AppendReason(err.Error())
|
||||
switch originalOrderSignal.Direction {
|
||||
case gctorder.Buy:
|
||||
originalOrderSignal.Direction = common.CouldNotBuy
|
||||
originalOrderSignal.Direction = gctorder.CouldNotBuy
|
||||
case gctorder.Sell:
|
||||
originalOrderSignal.Direction = common.CouldNotSell
|
||||
originalOrderSignal.Direction = gctorder.CouldNotSell
|
||||
default:
|
||||
originalOrderSignal.Direction = common.DoNothing
|
||||
originalOrderSignal.Direction = gctorder.DoNothing
|
||||
}
|
||||
d.SetDirection(originalOrderSignal.Direction)
|
||||
return originalOrderSignal
|
||||
@@ -193,11 +192,11 @@ func (p *Portfolio) sizeOrder(d common.Directioner, cs *exchange.Settings, origi
|
||||
if sizedOrder.Amount.IsZero() {
|
||||
switch originalOrderSignal.Direction {
|
||||
case gctorder.Buy:
|
||||
originalOrderSignal.Direction = common.CouldNotBuy
|
||||
originalOrderSignal.Direction = gctorder.CouldNotBuy
|
||||
case gctorder.Sell:
|
||||
originalOrderSignal.Direction = common.CouldNotSell
|
||||
originalOrderSignal.Direction = gctorder.CouldNotSell
|
||||
default:
|
||||
originalOrderSignal.Direction = common.DoNothing
|
||||
originalOrderSignal.Direction = gctorder.DoNothing
|
||||
}
|
||||
d.SetDirection(originalOrderSignal.Direction)
|
||||
originalOrderSignal.AppendReason("sized order to 0")
|
||||
@@ -210,7 +209,7 @@ func (p *Portfolio) sizeOrder(d common.Directioner, cs *exchange.Settings, origi
|
||||
sizedOrder.AllocatedFunds = sizedOrder.Amount.Mul(sizedOrder.Price)
|
||||
}
|
||||
if err != nil {
|
||||
sizedOrder.Direction = common.DoNothing
|
||||
sizedOrder.Direction = gctorder.DoNothing
|
||||
sizedOrder.AppendReason(err.Error())
|
||||
}
|
||||
return sizedOrder
|
||||
@@ -256,11 +255,11 @@ func (p *Portfolio) OnFill(ev fill.Event, funding funding.IPairReader) (*fill.Fi
|
||||
}
|
||||
|
||||
direction := ev.GetDirection()
|
||||
if direction == common.DoNothing ||
|
||||
direction == common.CouldNotBuy ||
|
||||
direction == common.CouldNotSell ||
|
||||
direction == common.MissingData ||
|
||||
direction == "" {
|
||||
if direction == gctorder.DoNothing ||
|
||||
direction == gctorder.CouldNotBuy ||
|
||||
direction == gctorder.CouldNotSell ||
|
||||
direction == gctorder.MissingData ||
|
||||
direction == gctorder.UnknownSide {
|
||||
fe, ok := ev.(*fill.Fill)
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("%w expected fill event", common.ErrInvalidDataType)
|
||||
|
||||
@@ -508,7 +508,7 @@ func TestOnSignal(t *testing.T) {
|
||||
t.Error("expected issue")
|
||||
}
|
||||
|
||||
s.Direction = common.MissingData
|
||||
s.Direction = gctorder.MissingData
|
||||
_, err = p.OnSignal(s, &exchange.Settings{}, pair)
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
@@ -533,7 +533,7 @@ func TestOnSignal(t *testing.T) {
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
if resp.Direction != common.CouldNotBuy {
|
||||
if resp.Direction != gctorder.CouldNotBuy {
|
||||
t.Errorf("expected common.CouldNotBuy, received %v", resp.Direction)
|
||||
}
|
||||
|
||||
|
||||
@@ -62,7 +62,7 @@ func (c *CurrencyPairStatistic) CalculateResults(riskFreeRate decimal.Decimal) e
|
||||
if i == 0 {
|
||||
continue
|
||||
}
|
||||
if c.Events[i].SignalEvent != nil && c.Events[i].SignalEvent.GetDirection() == common.MissingData {
|
||||
if c.Events[i].SignalEvent != nil && c.Events[i].SignalEvent.GetDirection() == gctorder.MissingData {
|
||||
c.ShowMissingDataWarning = true
|
||||
}
|
||||
if c.Events[i].DataEvent.GetClosePrice().IsZero() || c.Events[i-1].DataEvent.GetClosePrice().IsZero() {
|
||||
|
||||
@@ -5,7 +5,6 @@ import (
|
||||
"time"
|
||||
|
||||
"github.com/shopspring/decimal"
|
||||
"github.com/thrasher-corp/gocryptotrader/backtester/common"
|
||||
"github.com/thrasher-corp/gocryptotrader/backtester/eventhandlers/portfolio/compliance"
|
||||
"github.com/thrasher-corp/gocryptotrader/backtester/eventhandlers/portfolio/holdings"
|
||||
"github.com/thrasher-corp/gocryptotrader/backtester/eventtypes/event"
|
||||
@@ -106,7 +105,7 @@ func TestCalculateResults(t *testing.T) {
|
||||
SignalEvent: &signal.Signal{
|
||||
Base: even2,
|
||||
ClosePrice: decimal.NewFromInt(1337),
|
||||
Direction: common.MissingData,
|
||||
Direction: order.MissingData,
|
||||
},
|
||||
}
|
||||
|
||||
|
||||
@@ -19,6 +19,7 @@ import (
|
||||
gctmath "github.com/thrasher-corp/gocryptotrader/common/math"
|
||||
"github.com/thrasher-corp/gocryptotrader/currency"
|
||||
"github.com/thrasher-corp/gocryptotrader/exchanges/asset"
|
||||
gctorder "github.com/thrasher-corp/gocryptotrader/exchanges/order"
|
||||
"github.com/thrasher-corp/gocryptotrader/log"
|
||||
)
|
||||
|
||||
@@ -308,12 +309,12 @@ func (s *Statistic) PrintAllEventsChronologically() {
|
||||
switch {
|
||||
case currencyStatistic.Events[i].FillEvent != nil:
|
||||
direction := currencyStatistic.Events[i].FillEvent.GetDirection()
|
||||
if direction == common.CouldNotBuy ||
|
||||
direction == common.CouldNotSell ||
|
||||
direction == common.DoNothing ||
|
||||
direction == common.MissingData ||
|
||||
direction == common.TransferredFunds ||
|
||||
direction == "" {
|
||||
if direction == gctorder.CouldNotBuy ||
|
||||
direction == gctorder.CouldNotSell ||
|
||||
direction == gctorder.DoNothing ||
|
||||
direction == gctorder.MissingData ||
|
||||
direction == gctorder.TransferredFunds ||
|
||||
direction == gctorder.UnknownSide {
|
||||
results = addEventOutputToTime(results, currencyStatistic.Events[i].FillEvent.GetTime(),
|
||||
fmt.Sprintf("%v %v %v %v | Price: $%v - Direction: %v - Reason: %s",
|
||||
currencyStatistic.Events[i].FillEvent.GetTime().Format(gctcommon.SimpleTimeFormat),
|
||||
|
||||
@@ -47,7 +47,7 @@ func (s *Strategy) OnSignal(d data.Handler, _ funding.IFundTransferer, _ portfol
|
||||
}
|
||||
|
||||
if !d.HasDataAtTime(d.Latest().GetTime()) {
|
||||
es.SetDirection(common.MissingData)
|
||||
es.SetDirection(order.MissingData)
|
||||
es.AppendReason(fmt.Sprintf("missing data at %v, cannot perform any actions", d.Latest().GetTime()))
|
||||
return &es, nil
|
||||
}
|
||||
|
||||
@@ -80,7 +80,7 @@ func TestOnSignal(t *testing.T) {
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
if resp.GetDirection() != common.MissingData {
|
||||
if resp.GetDirection() != gctorder.MissingData {
|
||||
t.Error("expected missing data")
|
||||
}
|
||||
|
||||
@@ -162,7 +162,7 @@ func TestOnSignals(t *testing.T) {
|
||||
if len(resp) != 1 {
|
||||
t.Fatal("expected 1 response")
|
||||
}
|
||||
if resp[0].GetDirection() != common.MissingData {
|
||||
if resp[0].GetDirection() != gctorder.MissingData {
|
||||
t.Error("expected missing data")
|
||||
}
|
||||
|
||||
|
||||
@@ -59,7 +59,7 @@ func (s *Strategy) OnSignal(d data.Handler, _ funding.IFundTransferer, _ portfol
|
||||
|
||||
if offset := d.Offset(); offset <= int(s.rsiPeriod.IntPart()) {
|
||||
es.AppendReason("Not enough data for signal generation")
|
||||
es.SetDirection(common.DoNothing)
|
||||
es.SetDirection(order.DoNothing)
|
||||
return &es, nil
|
||||
}
|
||||
|
||||
@@ -72,7 +72,7 @@ func (s *Strategy) OnSignal(d data.Handler, _ funding.IFundTransferer, _ portfol
|
||||
rsi := indicators.RSI(massagedData, int(s.rsiPeriod.IntPart()))
|
||||
latestRSIValue := decimal.NewFromFloat(rsi[len(rsi)-1])
|
||||
if !d.HasDataAtTime(d.Latest().GetTime()) {
|
||||
es.SetDirection(common.MissingData)
|
||||
es.SetDirection(order.MissingData)
|
||||
es.AppendReason(fmt.Sprintf("missing data at %v, cannot perform any actions. RSI %v", d.Latest().GetTime(), latestRSIValue))
|
||||
return &es, nil
|
||||
}
|
||||
@@ -83,7 +83,7 @@ func (s *Strategy) OnSignal(d data.Handler, _ funding.IFundTransferer, _ portfol
|
||||
case latestRSIValue.LessThanOrEqual(s.rsiLow):
|
||||
es.SetDirection(order.Buy)
|
||||
default:
|
||||
es.SetDirection(common.DoNothing)
|
||||
es.SetDirection(order.DoNothing)
|
||||
}
|
||||
es.AppendReason(fmt.Sprintf("RSI at %v", latestRSIValue))
|
||||
|
||||
|
||||
@@ -17,6 +17,7 @@ import (
|
||||
"github.com/thrasher-corp/gocryptotrader/currency"
|
||||
"github.com/thrasher-corp/gocryptotrader/exchanges/asset"
|
||||
gctkline "github.com/thrasher-corp/gocryptotrader/exchanges/kline"
|
||||
"github.com/thrasher-corp/gocryptotrader/exchanges/order"
|
||||
)
|
||||
|
||||
func TestName(t *testing.T) {
|
||||
@@ -160,7 +161,7 @@ func TestOnSignal(t *testing.T) {
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
if resp.GetDirection() != common.DoNothing {
|
||||
if resp.GetDirection() != order.DoNothing {
|
||||
t.Error("expected do nothing")
|
||||
}
|
||||
}
|
||||
|
||||
@@ -107,7 +107,7 @@ func (s *Strategy) OnSimultaneousSignals(d []data.Handler, f funding.IFundTransf
|
||||
|
||||
if offset <= int(s.mfiPeriod.IntPart()) {
|
||||
es.AppendReason("Not enough data for signal generation")
|
||||
es.SetDirection(common.DoNothing)
|
||||
es.SetDirection(order.DoNothing)
|
||||
resp = append(resp, &es)
|
||||
continue
|
||||
}
|
||||
@@ -136,13 +136,13 @@ func (s *Strategy) OnSimultaneousSignals(d []data.Handler, f funding.IFundTransf
|
||||
mfi := indicators.MFI(massagedHighData, massagedLowData, massagedCloseData, massagedVolumeData, int(s.mfiPeriod.IntPart()))
|
||||
latestMFI := decimal.NewFromFloat(mfi[len(mfi)-1])
|
||||
if !d[i].HasDataAtTime(d[i].Latest().GetTime()) {
|
||||
es.SetDirection(common.MissingData)
|
||||
es.SetDirection(order.MissingData)
|
||||
es.AppendReason(fmt.Sprintf("missing data at %v, cannot perform any actions. MFI %v", d[i].Latest().GetTime(), latestMFI))
|
||||
resp = append(resp, &es)
|
||||
continue
|
||||
}
|
||||
|
||||
es.SetDirection(common.DoNothing)
|
||||
es.SetDirection(order.DoNothing)
|
||||
es.AppendReason(fmt.Sprintf("MFI at %v", latestMFI))
|
||||
|
||||
funds, err := f.GetFundingForEvent(&es)
|
||||
@@ -183,7 +183,7 @@ func (s *Strategy) selectTopAndBottomPerformers(mfiFundEvents []mfiFundEvent, re
|
||||
}
|
||||
}
|
||||
for i := range mfiFundEvents {
|
||||
if buyingOrSelling && mfiFundEvents[i].event.GetDirection() == common.DoNothing {
|
||||
if buyingOrSelling && mfiFundEvents[i].event.GetDirection() == order.DoNothing {
|
||||
mfiFundEvents[i].event.AppendReason("MFI was not in the top or bottom two ranks")
|
||||
}
|
||||
resp = append(resp, mfiFundEvents[i].event)
|
||||
|
||||
@@ -171,35 +171,35 @@ func TestSelectTopAndBottomPerformers(t *testing.T) {
|
||||
{
|
||||
event: &signal.Signal{
|
||||
ClosePrice: decimal.NewFromInt(99),
|
||||
Direction: common.DoNothing,
|
||||
Direction: order.DoNothing,
|
||||
},
|
||||
mfi: decimal.NewFromInt(99),
|
||||
},
|
||||
{
|
||||
event: &signal.Signal{
|
||||
ClosePrice: decimal.NewFromInt(98),
|
||||
Direction: common.DoNothing,
|
||||
Direction: order.DoNothing,
|
||||
},
|
||||
mfi: decimal.NewFromInt(98),
|
||||
},
|
||||
{
|
||||
event: &signal.Signal{
|
||||
ClosePrice: decimal.NewFromInt(1),
|
||||
Direction: common.DoNothing,
|
||||
Direction: order.DoNothing,
|
||||
},
|
||||
mfi: decimal.NewFromInt(1),
|
||||
},
|
||||
{
|
||||
event: &signal.Signal{
|
||||
ClosePrice: decimal.NewFromInt(2),
|
||||
Direction: common.DoNothing,
|
||||
Direction: order.DoNothing,
|
||||
},
|
||||
mfi: decimal.NewFromInt(2),
|
||||
},
|
||||
{
|
||||
event: &signal.Signal{
|
||||
ClosePrice: decimal.NewFromInt(50),
|
||||
Direction: common.DoNothing,
|
||||
Direction: order.DoNothing,
|
||||
},
|
||||
mfi: decimal.NewFromInt(50),
|
||||
},
|
||||
@@ -221,7 +221,7 @@ func TestSelectTopAndBottomPerformers(t *testing.T) {
|
||||
if !resp[i].GetPrice().Equal(decimal.NewFromInt(99)) && !resp[i].GetPrice().Equal(decimal.NewFromInt(98)) {
|
||||
t.Error("expected 99 or 98")
|
||||
}
|
||||
case common.DoNothing:
|
||||
case order.DoNothing:
|
||||
if !resp[i].GetPrice().Equal(decimal.NewFromInt(50)) {
|
||||
t.Error("expected 50")
|
||||
}
|
||||
|
||||
@@ -11,7 +11,7 @@ import (
|
||||
"github.com/thrasher-corp/gocryptotrader/currency"
|
||||
"github.com/thrasher-corp/gocryptotrader/exchanges/asset"
|
||||
gctkline "github.com/thrasher-corp/gocryptotrader/exchanges/kline"
|
||||
gctorder "github.com/thrasher-corp/gocryptotrader/exchanges/order"
|
||||
"github.com/thrasher-corp/gocryptotrader/exchanges/order"
|
||||
)
|
||||
|
||||
var (
|
||||
@@ -484,23 +484,23 @@ func TestReservePair(t *testing.T) {
|
||||
baseItem.pairedWith = quoteItem
|
||||
quoteItem.pairedWith = baseItem
|
||||
pairItems := Pair{Base: baseItem, Quote: quoteItem}
|
||||
err = pairItems.Reserve(decimal.Zero, gctorder.Buy)
|
||||
err = pairItems.Reserve(decimal.Zero, order.Buy)
|
||||
if !errors.Is(err, errZeroAmountReceived) {
|
||||
t.Errorf("received '%v' expected '%v'", err, errZeroAmountReceived)
|
||||
}
|
||||
err = pairItems.Reserve(elite, gctorder.Buy)
|
||||
err = pairItems.Reserve(elite, order.Buy)
|
||||
if !errors.Is(err, nil) {
|
||||
t.Errorf("received '%v' expected '%v'", err, nil)
|
||||
}
|
||||
err = pairItems.Reserve(decimal.Zero, gctorder.Sell)
|
||||
err = pairItems.Reserve(decimal.Zero, order.Sell)
|
||||
if !errors.Is(err, errZeroAmountReceived) {
|
||||
t.Errorf("received '%v' expected '%v'", err, errZeroAmountReceived)
|
||||
}
|
||||
err = pairItems.Reserve(elite, gctorder.Sell)
|
||||
err = pairItems.Reserve(elite, order.Sell)
|
||||
if !errors.Is(err, errCannotAllocate) {
|
||||
t.Errorf("received '%v' expected '%v'", err, errCannotAllocate)
|
||||
}
|
||||
err = pairItems.Reserve(elite, common.DoNothing)
|
||||
err = pairItems.Reserve(elite, order.DoNothing)
|
||||
if !errors.Is(err, errCannotAllocate) {
|
||||
t.Errorf("received '%v' expected '%v'", err, errCannotAllocate)
|
||||
}
|
||||
@@ -519,46 +519,46 @@ func TestReleasePair(t *testing.T) {
|
||||
baseItem.pairedWith = quoteItem
|
||||
quoteItem.pairedWith = baseItem
|
||||
pairItems := Pair{Base: baseItem, Quote: quoteItem}
|
||||
err = pairItems.Reserve(decimal.Zero, gctorder.Buy)
|
||||
err = pairItems.Reserve(decimal.Zero, order.Buy)
|
||||
if !errors.Is(err, errZeroAmountReceived) {
|
||||
t.Errorf("received '%v' expected '%v'", err, errZeroAmountReceived)
|
||||
}
|
||||
err = pairItems.Reserve(elite, gctorder.Buy)
|
||||
err = pairItems.Reserve(elite, order.Buy)
|
||||
if !errors.Is(err, nil) {
|
||||
t.Errorf("received '%v' expected '%v'", err, nil)
|
||||
}
|
||||
err = pairItems.Reserve(decimal.Zero, gctorder.Sell)
|
||||
err = pairItems.Reserve(decimal.Zero, order.Sell)
|
||||
if !errors.Is(err, errZeroAmountReceived) {
|
||||
t.Errorf("received '%v' expected '%v'", err, errZeroAmountReceived)
|
||||
}
|
||||
err = pairItems.Reserve(elite, gctorder.Sell)
|
||||
err = pairItems.Reserve(elite, order.Sell)
|
||||
if !errors.Is(err, errCannotAllocate) {
|
||||
t.Errorf("received '%v' expected '%v'", err, errCannotAllocate)
|
||||
}
|
||||
|
||||
err = pairItems.Release(decimal.Zero, decimal.Zero, gctorder.Buy)
|
||||
err = pairItems.Release(decimal.Zero, decimal.Zero, order.Buy)
|
||||
if !errors.Is(err, errZeroAmountReceived) {
|
||||
t.Errorf("received '%v' expected '%v'", err, errZeroAmountReceived)
|
||||
}
|
||||
err = pairItems.Release(elite, decimal.Zero, gctorder.Buy)
|
||||
err = pairItems.Release(elite, decimal.Zero, order.Buy)
|
||||
if !errors.Is(err, nil) {
|
||||
t.Errorf("received '%v' expected '%v'", err, nil)
|
||||
}
|
||||
err = pairItems.Release(elite, decimal.Zero, gctorder.Buy)
|
||||
err = pairItems.Release(elite, decimal.Zero, order.Buy)
|
||||
if !errors.Is(err, errCannotAllocate) {
|
||||
t.Errorf("received '%v' expected '%v'", err, errCannotAllocate)
|
||||
}
|
||||
|
||||
err = pairItems.Release(elite, decimal.Zero, common.DoNothing)
|
||||
err = pairItems.Release(elite, decimal.Zero, order.DoNothing)
|
||||
if !errors.Is(err, errCannotAllocate) {
|
||||
t.Errorf("received '%v' expected '%v'", err, errCannotAllocate)
|
||||
}
|
||||
|
||||
err = pairItems.Release(elite, decimal.Zero, gctorder.Sell)
|
||||
err = pairItems.Release(elite, decimal.Zero, order.Sell)
|
||||
if !errors.Is(err, errCannotAllocate) {
|
||||
t.Errorf("received '%v' expected '%v'", err, errCannotAllocate)
|
||||
}
|
||||
err = pairItems.Release(decimal.Zero, decimal.Zero, gctorder.Sell)
|
||||
err = pairItems.Release(decimal.Zero, decimal.Zero, order.Sell)
|
||||
if !errors.Is(err, errZeroAmountReceived) {
|
||||
t.Errorf("received '%v' expected '%v'", err, errZeroAmountReceived)
|
||||
}
|
||||
@@ -577,25 +577,25 @@ func TestIncreaseAvailablePair(t *testing.T) {
|
||||
baseItem.pairedWith = quoteItem
|
||||
quoteItem.pairedWith = baseItem
|
||||
pairItems := Pair{Base: baseItem, Quote: quoteItem}
|
||||
pairItems.IncreaseAvailable(decimal.Zero, gctorder.Buy)
|
||||
pairItems.IncreaseAvailable(decimal.Zero, order.Buy)
|
||||
if !pairItems.Quote.available.Equal(elite) {
|
||||
t.Errorf("received '%v' expected '%v'", elite, pairItems.Quote.available)
|
||||
}
|
||||
pairItems.IncreaseAvailable(decimal.Zero, gctorder.Sell)
|
||||
pairItems.IncreaseAvailable(decimal.Zero, order.Sell)
|
||||
if !pairItems.Base.available.Equal(decimal.Zero) {
|
||||
t.Errorf("received '%v' expected '%v'", decimal.Zero, pairItems.Base.available)
|
||||
}
|
||||
|
||||
pairItems.IncreaseAvailable(elite.Neg(), gctorder.Sell)
|
||||
pairItems.IncreaseAvailable(elite.Neg(), order.Sell)
|
||||
if !pairItems.Quote.available.Equal(elite) {
|
||||
t.Errorf("received '%v' expected '%v'", elite, pairItems.Quote.available)
|
||||
}
|
||||
pairItems.IncreaseAvailable(elite, gctorder.Buy)
|
||||
pairItems.IncreaseAvailable(elite, order.Buy)
|
||||
if !pairItems.Base.available.Equal(elite) {
|
||||
t.Errorf("received '%v' expected '%v'", elite, pairItems.Base.available)
|
||||
}
|
||||
|
||||
pairItems.IncreaseAvailable(elite, common.DoNothing)
|
||||
pairItems.IncreaseAvailable(elite, order.DoNothing)
|
||||
if !pairItems.Base.available.Equal(elite) {
|
||||
t.Errorf("received '%v' expected '%v'", elite, pairItems.Base.available)
|
||||
}
|
||||
@@ -607,22 +607,22 @@ func TestCanPlaceOrderPair(t *testing.T) {
|
||||
Base: &Item{},
|
||||
Quote: &Item{},
|
||||
}
|
||||
if p.CanPlaceOrder(common.DoNothing) {
|
||||
if p.CanPlaceOrder(order.DoNothing) {
|
||||
t.Error("expected false")
|
||||
}
|
||||
if p.CanPlaceOrder(gctorder.Buy) {
|
||||
if p.CanPlaceOrder(order.Buy) {
|
||||
t.Error("expected false")
|
||||
}
|
||||
if p.CanPlaceOrder(gctorder.Sell) {
|
||||
if p.CanPlaceOrder(order.Sell) {
|
||||
t.Error("expected false")
|
||||
}
|
||||
|
||||
p.Quote.available = decimal.NewFromInt(32)
|
||||
if !p.CanPlaceOrder(gctorder.Buy) {
|
||||
if !p.CanPlaceOrder(order.Buy) {
|
||||
t.Error("expected true")
|
||||
}
|
||||
p.Base.available = decimal.NewFromInt(32)
|
||||
if !p.CanPlaceOrder(gctorder.Sell) {
|
||||
if !p.CanPlaceOrder(order.Sell) {
|
||||
t.Error("expected true")
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9,7 +9,6 @@ import (
|
||||
"time"
|
||||
|
||||
"github.com/shopspring/decimal"
|
||||
"github.com/thrasher-corp/gocryptotrader/backtester/common"
|
||||
"github.com/thrasher-corp/gocryptotrader/exchanges/kline"
|
||||
"github.com/thrasher-corp/gocryptotrader/exchanges/order"
|
||||
"github.com/thrasher-corp/gocryptotrader/log"
|
||||
@@ -209,14 +208,14 @@ func (d *Data) enhanceCandles() error {
|
||||
}
|
||||
if !requiresIteration {
|
||||
if statsForCandles.Events[intVal].SignalEvent.GetTime().Equal(d.OriginalCandles[intVal].Candles[j].Time) &&
|
||||
statsForCandles.Events[intVal].SignalEvent.GetDirection() == common.MissingData &&
|
||||
statsForCandles.Events[intVal].SignalEvent.GetDirection() == order.MissingData &&
|
||||
len(enhancedKline.Candles) > 0 {
|
||||
enhancedCandle.copyCloseFromPreviousEvent(&enhancedKline)
|
||||
}
|
||||
} else {
|
||||
for k := range statsForCandles.Events {
|
||||
if statsForCandles.Events[k].SignalEvent.GetTime().Equal(d.OriginalCandles[intVal].Candles[j].Time) &&
|
||||
statsForCandles.Events[k].SignalEvent.GetDirection() == common.MissingData &&
|
||||
statsForCandles.Events[k].SignalEvent.GetDirection() == order.MissingData &&
|
||||
len(enhancedKline.Candles) > 0 {
|
||||
enhancedCandle.copyCloseFromPreviousEvent(&enhancedKline)
|
||||
}
|
||||
@@ -261,7 +260,7 @@ func (d *DetailedCandle) copyCloseFromPreviousEvent(enhancedKline *DetailedKline
|
||||
d.Colour = "white"
|
||||
d.Position = "aboveBar"
|
||||
d.Shape = "arrowDown"
|
||||
d.Text = common.MissingData.String()
|
||||
d.Text = order.MissingData.String()
|
||||
}
|
||||
|
||||
// UseDarkMode sets whether to use a dark theme by default
|
||||
|
||||
@@ -57,6 +57,7 @@ var (
|
||||
errUserAgentInvalid = errors.New("cannot set invalid user agent")
|
||||
errHTTPClientInvalid = errors.New("custom http client cannot be nil")
|
||||
|
||||
zeroValueUnix = time.Unix(0, 0)
|
||||
// ErrTypeAssertFailure defines an error when type assertion fails
|
||||
ErrTypeAssertFailure = errors.New("type assert failure")
|
||||
)
|
||||
@@ -429,10 +430,10 @@ func (e Errors) Unwrap() error {
|
||||
// StartEndTimeCheck provides some basic checks which occur
|
||||
// frequently in the codebase
|
||||
func StartEndTimeCheck(start, end time.Time) error {
|
||||
if start.IsZero() {
|
||||
if start.IsZero() || start.Equal(zeroValueUnix) {
|
||||
return fmt.Errorf("start %w", ErrDateUnset)
|
||||
}
|
||||
if end.IsZero() {
|
||||
if end.IsZero() || end.Equal(zeroValueUnix) {
|
||||
return fmt.Errorf("end %w", ErrDateUnset)
|
||||
}
|
||||
if start.After(time.Now()) {
|
||||
|
||||
@@ -655,6 +655,16 @@ func TestParseStartEndDate(t *testing.T) {
|
||||
t.Errorf("received %v, expected %v", err, ErrDateUnset)
|
||||
}
|
||||
|
||||
err = StartEndTimeCheck(et, zeroValueUnix)
|
||||
if !errors.Is(err, ErrDateUnset) {
|
||||
t.Errorf("received %v, expected %v", err, ErrDateUnset)
|
||||
}
|
||||
|
||||
err = StartEndTimeCheck(zeroValueUnix, et)
|
||||
if !errors.Is(err, ErrDateUnset) {
|
||||
t.Errorf("received %v, expected %v", err, ErrDateUnset)
|
||||
}
|
||||
|
||||
err = StartEndTimeCheck(et, et)
|
||||
if !errors.Is(err, ErrStartEqualsEnd) {
|
||||
t.Errorf("received %v, expected %v", err, ErrStartEqualsEnd)
|
||||
|
||||
@@ -518,9 +518,7 @@ func (m *OrderManager) GetOrdersSnapshot(s order.Status) []order.Detail {
|
||||
var os []order.Detail
|
||||
for _, v := range m.orderStore.Orders {
|
||||
for i := range v {
|
||||
if s != v[i].Status &&
|
||||
s != order.AnyStatus &&
|
||||
s != "" {
|
||||
if s != v[i].Status && s != order.AnyStatus && s != order.UnknownStatus {
|
||||
continue
|
||||
}
|
||||
os = append(os, *v[i])
|
||||
@@ -685,7 +683,7 @@ func (m *OrderManager) processOrders() {
|
||||
Exchange: exchanges[i].GetName(),
|
||||
}
|
||||
orders := m.orderStore.getActiveOrders(filter)
|
||||
order.FilterOrdersByCurrencies(&orders, pairs)
|
||||
order.FilterOrdersByPairs(&orders, pairs)
|
||||
requiresProcessing := make(map[string]bool, len(orders))
|
||||
for x := range orders {
|
||||
requiresProcessing[orders[x].InternalOrderID] = true
|
||||
|
||||
@@ -879,7 +879,7 @@ func TestProcessOrders(t *testing.T) {
|
||||
t.Errorf("Expected 3 result, got: %d", len(res))
|
||||
}
|
||||
if res[0].Status != order.Active {
|
||||
t.Errorf("Order 1 should be active, but status is %s", string(res[0].Status))
|
||||
t.Errorf("Order 1 should be active, but status is %s", res[0].Status)
|
||||
}
|
||||
|
||||
// Order2 is not returned by exch.GetActiveOrders()
|
||||
@@ -892,7 +892,7 @@ func TestProcessOrders(t *testing.T) {
|
||||
t.Errorf("Expected 1 result, got: %d", len(res))
|
||||
}
|
||||
if res[0].Status != order.Cancelled {
|
||||
t.Errorf("Order 2 should be cancelled, but status is %s", string(res[0].Status))
|
||||
t.Errorf("Order 2 should be cancelled, but status is %s", res[0].Status)
|
||||
}
|
||||
|
||||
// Order3 is returned by exch.GetActiveOrders(), which will say it is active
|
||||
@@ -904,7 +904,7 @@ func TestProcessOrders(t *testing.T) {
|
||||
t.Errorf("Expected 1 result, got: %d", len(res))
|
||||
}
|
||||
if res[0].Status != order.Active {
|
||||
t.Errorf("Order 3 should be active, but status is %s", string(res[0].Status))
|
||||
t.Errorf("Order 3 should be active, but status is %s", res[0].Status)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1195,10 +1195,20 @@ func (s *RPCServer) SubmitOrder(ctx context.Context, r *gctrpc.SubmitOrderReques
|
||||
return nil, err
|
||||
}
|
||||
|
||||
side, err := order.StringToOrderSide(r.Side)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
oType, err := order.StringToOrderType(r.OrderType)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
submission := &order.Submit{
|
||||
Pair: p,
|
||||
Side: order.Side(r.Side),
|
||||
Type: order.Type(r.OrderType),
|
||||
Side: side,
|
||||
Type: oType,
|
||||
Amount: r.Amount,
|
||||
Price: r.Price,
|
||||
ClientID: r.ClientId,
|
||||
@@ -1362,12 +1372,18 @@ func (s *RPCServer) CancelOrder(ctx context.Context, r *gctrpc.CancelOrderReques
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var side order.Side
|
||||
side, err = order.StringToOrderSide(r.Side)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
err = s.OrderManager.Cancel(ctx,
|
||||
&order.Cancel{
|
||||
Exchange: r.Exchange,
|
||||
AccountID: r.AccountId,
|
||||
ID: r.OrderId,
|
||||
Side: order.Side(r.Side),
|
||||
Side: side,
|
||||
WalletAddress: r.WalletAddress,
|
||||
Pair: p,
|
||||
AssetType: a,
|
||||
@@ -1402,6 +1418,12 @@ func (s *RPCServer) CancelBatchOrders(ctx context.Context, r *gctrpc.CancelBatch
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var side order.Side
|
||||
side, err = order.StringToOrderSide(r.Side)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
status := make(map[string]string)
|
||||
orders := strings.Split(r.OrdersId, ",")
|
||||
request := make([]order.Cancel, len(orders))
|
||||
@@ -1411,7 +1433,7 @@ func (s *RPCServer) CancelBatchOrders(ctx context.Context, r *gctrpc.CancelBatch
|
||||
request[x] = order.Cancel{
|
||||
AccountID: r.AccountId,
|
||||
ID: orderID,
|
||||
Side: order.Side(r.Side),
|
||||
Side: side,
|
||||
WalletAddress: r.WalletAddress,
|
||||
Pair: pair,
|
||||
AssetType: assetType,
|
||||
|
||||
@@ -1837,7 +1837,7 @@ func TestGetManagedOrders(t *testing.T) {
|
||||
ClientID: "",
|
||||
WalletAddress: "",
|
||||
Type: order.Limit,
|
||||
Side: "SELL",
|
||||
Side: order.Sell,
|
||||
Status: order.New,
|
||||
AssetType: asset.Spot,
|
||||
Pair: currency.NewPair(currency.BTC, currency.USDT),
|
||||
|
||||
@@ -392,17 +392,16 @@ func (a *Alphapoint) GetActiveOrders(ctx context.Context, req *order.GetOrdersRe
|
||||
orderDetail.Side = orderSideMap[resp[x].OpenOrders[y].Side]
|
||||
orderDetail.Date = time.Unix(resp[x].OpenOrders[y].ReceiveTime, 0)
|
||||
orderDetail.Type = orderTypeMap[resp[x].OpenOrders[y].OrderType]
|
||||
if orderDetail.Type == "" {
|
||||
orderDetail.Type = order.UnknownType
|
||||
}
|
||||
|
||||
orders = append(orders, orderDetail)
|
||||
}
|
||||
}
|
||||
|
||||
order.FilterOrdersByType(&orders, req.Type)
|
||||
order.FilterOrdersBySide(&orders, req.Side)
|
||||
order.FilterOrdersByTimeRange(&orders, req.StartTime, req.EndTime)
|
||||
err = order.FilterOrdersByTimeRange(&orders, req.StartTime, req.EndTime)
|
||||
if err != nil {
|
||||
log.Errorf(log.ExchangeSys, "%s %v", a.Name, err)
|
||||
}
|
||||
return orders, nil
|
||||
}
|
||||
|
||||
@@ -439,17 +438,16 @@ func (a *Alphapoint) GetOrderHistory(ctx context.Context, req *order.GetOrdersRe
|
||||
orderDetail.Side = orderSideMap[resp[x].OpenOrders[y].Side]
|
||||
orderDetail.Date = time.Unix(resp[x].OpenOrders[y].ReceiveTime, 0)
|
||||
orderDetail.Type = orderTypeMap[resp[x].OpenOrders[y].OrderType]
|
||||
if orderDetail.Type == "" {
|
||||
orderDetail.Type = order.UnknownType
|
||||
}
|
||||
|
||||
orders = append(orders, orderDetail)
|
||||
}
|
||||
}
|
||||
|
||||
order.FilterOrdersByType(&orders, req.Type)
|
||||
order.FilterOrdersBySide(&orders, req.Side)
|
||||
order.FilterOrdersByTimeRange(&orders, req.StartTime, req.EndTime)
|
||||
err = order.FilterOrdersByTimeRange(&orders, req.StartTime, req.EndTime)
|
||||
if err != nil {
|
||||
log.Errorf(log.ExchangeSys, "%s %v", a.Name, err)
|
||||
}
|
||||
return orders, nil
|
||||
}
|
||||
|
||||
|
||||
@@ -1181,7 +1181,11 @@ func (b *Binance) GetOrderInfo(ctx context.Context, orderID string, pair currenc
|
||||
if err != nil {
|
||||
return respData, err
|
||||
}
|
||||
orderSide := order.Side(resp.Side)
|
||||
var side order.Side
|
||||
side, err = order.StringToOrderSide(resp.Side)
|
||||
if err != nil {
|
||||
return respData, err
|
||||
}
|
||||
status, err := order.StringToOrderStatus(resp.Status)
|
||||
if err != nil {
|
||||
log.Errorf(log.ExchangeSys, "%s %v", b.Name, err)
|
||||
@@ -1196,7 +1200,7 @@ func (b *Binance) GetOrderInfo(ctx context.Context, orderID string, pair currenc
|
||||
Exchange: b.Name,
|
||||
ID: strconv.FormatInt(resp.OrderID, 10),
|
||||
ClientOrderID: resp.ClientOrderID,
|
||||
Side: orderSide,
|
||||
Side: side,
|
||||
Type: orderType,
|
||||
Pair: pair,
|
||||
Cost: resp.CummulativeQuoteQty,
|
||||
@@ -1350,8 +1354,16 @@ func (b *Binance) GetActiveOrders(ctx context.Context, req *order.GetOrdersReque
|
||||
return nil, err
|
||||
}
|
||||
for x := range resp {
|
||||
orderSide := order.Side(strings.ToUpper(resp[x].Side))
|
||||
orderType := order.Type(strings.ToUpper(resp[x].Type))
|
||||
var side order.Side
|
||||
side, err = order.StringToOrderSide(resp[x].Side)
|
||||
if err != nil {
|
||||
log.Errorf(log.ExchangeSys, "%s %v", b.Name, err)
|
||||
}
|
||||
var orderType order.Type
|
||||
orderType, err = order.StringToOrderType(resp[x].Type)
|
||||
if err != nil {
|
||||
log.Errorf(log.ExchangeSys, "%s %v", b.Name, err)
|
||||
}
|
||||
orderStatus, err := order.StringToOrderStatus(resp[i].Status)
|
||||
if err != nil {
|
||||
log.Errorf(log.ExchangeSys, "%s %v", b.Name, err)
|
||||
@@ -1362,7 +1374,7 @@ func (b *Binance) GetActiveOrders(ctx context.Context, req *order.GetOrdersReque
|
||||
Exchange: b.Name,
|
||||
ID: strconv.FormatInt(resp[x].OrderID, 10),
|
||||
ClientOrderID: resp[x].ClientOrderID,
|
||||
Side: orderSide,
|
||||
Side: side,
|
||||
Type: orderType,
|
||||
Price: resp[x].Price,
|
||||
Status: orderStatus,
|
||||
@@ -1441,10 +1453,13 @@ func (b *Binance) GetActiveOrders(ctx context.Context, req *order.GetOrdersReque
|
||||
return orders, fmt.Errorf("assetType not supported")
|
||||
}
|
||||
}
|
||||
order.FilterOrdersByCurrencies(&orders, req.Pairs)
|
||||
order.FilterOrdersByPairs(&orders, req.Pairs)
|
||||
order.FilterOrdersByType(&orders, req.Type)
|
||||
order.FilterOrdersBySide(&orders, req.Side)
|
||||
order.FilterOrdersByTimeRange(&orders, req.StartTime, req.EndTime)
|
||||
err := order.FilterOrdersByTimeRange(&orders, req.StartTime, req.EndTime)
|
||||
if err != nil {
|
||||
log.Errorf(log.ExchangeSys, "%s %v", b.Name, err)
|
||||
}
|
||||
return orders, nil
|
||||
}
|
||||
|
||||
@@ -1470,8 +1485,16 @@ 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))
|
||||
var side order.Side
|
||||
side, err = order.StringToOrderSide(resp[x].Side)
|
||||
if err != nil {
|
||||
log.Errorf(log.ExchangeSys, "%s %v", b.Name, err)
|
||||
}
|
||||
var orderType order.Type
|
||||
orderType, err = order.StringToOrderType(resp[i].Type)
|
||||
if err != nil {
|
||||
log.Errorf(log.ExchangeSys, "%s %v", b.Name, err)
|
||||
}
|
||||
orderStatus, err := order.StringToOrderStatus(resp[i].Status)
|
||||
if err != nil {
|
||||
log.Errorf(log.ExchangeSys, "%s %v", b.Name, err)
|
||||
@@ -1497,7 +1520,7 @@ func (b *Binance) GetOrderHistory(ctx context.Context, req *order.GetOrdersReque
|
||||
LastUpdated: resp[i].UpdateTime,
|
||||
Exchange: b.Name,
|
||||
ID: strconv.FormatInt(resp[i].OrderID, 10),
|
||||
Side: orderSide,
|
||||
Side: side,
|
||||
Type: orderType,
|
||||
Price: resp[i].Price,
|
||||
Pair: req.Pairs[x],
|
||||
@@ -1628,7 +1651,11 @@ func (b *Binance) GetOrderHistory(ctx context.Context, req *order.GetOrdersReque
|
||||
}
|
||||
order.FilterOrdersByType(&orders, req.Type)
|
||||
order.FilterOrdersBySide(&orders, req.Side)
|
||||
order.FilterOrdersByTimeRange(&orders, req.StartTime, req.EndTime)
|
||||
err := order.FilterOrdersByTimeRange(&orders, req.StartTime, req.EndTime)
|
||||
if err != nil {
|
||||
log.Errorf(log.ExchangeSys, "%s %v", b.Name, err)
|
||||
}
|
||||
|
||||
return orders, nil
|
||||
}
|
||||
|
||||
|
||||
@@ -896,15 +896,21 @@ func (b *Bitfinex) GetActiveOrders(ctx context.Context, req *order.GetOrdersRequ
|
||||
|
||||
orders := make([]order.Detail, len(resp))
|
||||
for i := range resp {
|
||||
orderSide := order.Side(strings.ToUpper(resp[i].Side))
|
||||
timestamp, err := strconv.ParseFloat(resp[i].Timestamp, 64)
|
||||
var side order.Side
|
||||
side, err = order.StringToOrderSide(resp[i].Side)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
var timestamp float64
|
||||
timestamp, err = strconv.ParseFloat(resp[i].Timestamp, 64)
|
||||
if err != nil {
|
||||
log.Warnf(log.ExchangeSys,
|
||||
"Unable to convert timestamp '%s', leaving blank",
|
||||
resp[i].Timestamp)
|
||||
}
|
||||
|
||||
pair, err := currency.NewPairFromString(resp[i].Symbol)
|
||||
var pair currency.Pair
|
||||
pair, err = currency.NewPairFromString(resp[i].Symbol)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -914,7 +920,7 @@ func (b *Bitfinex) GetActiveOrders(ctx context.Context, req *order.GetOrdersRequ
|
||||
Date: time.Unix(int64(timestamp), 0),
|
||||
Exchange: b.Name,
|
||||
ID: strconv.FormatInt(resp[i].ID, 10),
|
||||
Side: orderSide,
|
||||
Side: side,
|
||||
Price: resp[i].Price,
|
||||
RemainingAmount: resp[i].RemainingAmount,
|
||||
Pair: pair,
|
||||
@@ -938,7 +944,10 @@ func (b *Bitfinex) GetActiveOrders(ctx context.Context, req *order.GetOrdersRequ
|
||||
if orderType == "trailing-stop" {
|
||||
orderDetail.Type = order.TrailingStop
|
||||
} else {
|
||||
orderDetail.Type = order.Type(strings.ToUpper(orderType))
|
||||
orderDetail.Type, err = order.StringToOrderType(orderType)
|
||||
if err != nil {
|
||||
log.Errorf(log.ExchangeSys, "%s %v", b.Name, err)
|
||||
}
|
||||
}
|
||||
|
||||
orders[i] = orderDetail
|
||||
@@ -946,8 +955,11 @@ func (b *Bitfinex) GetActiveOrders(ctx context.Context, req *order.GetOrdersRequ
|
||||
|
||||
order.FilterOrdersBySide(&orders, req.Side)
|
||||
order.FilterOrdersByType(&orders, req.Type)
|
||||
order.FilterOrdersByTimeRange(&orders, req.StartTime, req.EndTime)
|
||||
order.FilterOrdersByCurrencies(&orders, req.Pairs)
|
||||
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
|
||||
}
|
||||
|
||||
@@ -965,14 +977,20 @@ func (b *Bitfinex) GetOrderHistory(ctx context.Context, req *order.GetOrdersRequ
|
||||
|
||||
orders := make([]order.Detail, len(resp))
|
||||
for i := range resp {
|
||||
orderSide := order.Side(strings.ToUpper(resp[i].Side))
|
||||
timestamp, err := strconv.ParseInt(resp[i].Timestamp, 10, 64)
|
||||
var side order.Side
|
||||
side, err = order.StringToOrderSide(resp[i].Side)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
var timestamp int64
|
||||
timestamp, err = strconv.ParseInt(resp[i].Timestamp, 10, 64)
|
||||
if err != nil {
|
||||
log.Warnf(log.ExchangeSys, "Unable to convert timestamp '%v', leaving blank", resp[i].Timestamp)
|
||||
}
|
||||
orderDate := time.Unix(timestamp, 0)
|
||||
|
||||
pair, err := currency.NewPairFromString(resp[i].Symbol)
|
||||
var pair currency.Pair
|
||||
pair, err = currency.NewPairFromString(resp[i].Symbol)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -982,7 +1000,7 @@ func (b *Bitfinex) GetOrderHistory(ctx context.Context, req *order.GetOrdersRequ
|
||||
Date: orderDate,
|
||||
Exchange: b.Name,
|
||||
ID: strconv.FormatInt(resp[i].ID, 10),
|
||||
Side: orderSide,
|
||||
Side: side,
|
||||
Price: resp[i].Price,
|
||||
AverageExecutedPrice: resp[i].AverageExecutionPrice,
|
||||
RemainingAmount: resp[i].RemainingAmount,
|
||||
@@ -1008,7 +1026,10 @@ func (b *Bitfinex) GetOrderHistory(ctx context.Context, req *order.GetOrdersRequ
|
||||
if orderType == "trailing-stop" {
|
||||
orderDetail.Type = order.TrailingStop
|
||||
} else {
|
||||
orderDetail.Type = order.Type(strings.ToUpper(orderType))
|
||||
orderDetail.Type, err = order.StringToOrderType(orderType)
|
||||
if err != nil {
|
||||
log.Errorf(log.ExchangeSys, "%s %v", b.Name, err)
|
||||
}
|
||||
}
|
||||
|
||||
orders[i] = orderDetail
|
||||
@@ -1016,11 +1037,14 @@ func (b *Bitfinex) GetOrderHistory(ctx context.Context, req *order.GetOrdersRequ
|
||||
|
||||
order.FilterOrdersBySide(&orders, req.Side)
|
||||
order.FilterOrdersByType(&orders, req.Type)
|
||||
order.FilterOrdersByTimeRange(&orders, req.StartTime, req.EndTime)
|
||||
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.FilterOrdersByCurrencies(&orders, req.Pairs)
|
||||
order.FilterOrdersByPairs(&orders, req.Pairs)
|
||||
return orders, nil
|
||||
}
|
||||
|
||||
|
||||
@@ -7,7 +7,6 @@ import (
|
||||
|
||||
"github.com/thrasher-corp/gocryptotrader/currency"
|
||||
"github.com/thrasher-corp/gocryptotrader/exchanges/asset"
|
||||
"github.com/thrasher-corp/gocryptotrader/exchanges/order"
|
||||
)
|
||||
|
||||
// WsResponse is a generalised response data structure which will defer
|
||||
@@ -48,7 +47,7 @@ type WsOrderbooks struct {
|
||||
// WsOrderbook defines a singular orderbook tranche
|
||||
type WsOrderbook struct {
|
||||
Symbol currency.Pair `json:"symbol"`
|
||||
OrderSide order.Side `json:"orderType"`
|
||||
OrderSide string `json:"orderType"`
|
||||
Price float64 `json:"price,string"`
|
||||
Quantity float64 `json:"quantity,string"`
|
||||
Total int32 `json:"total,string"`
|
||||
|
||||
@@ -702,7 +702,8 @@ func (b *Bithumb) GetActiveOrders(ctx context.Context, req *order.GetOrdersReque
|
||||
|
||||
var orders []order.Detail
|
||||
for x := range req.Pairs {
|
||||
resp, err := b.GetOrders(ctx, "", "", "1000", "", req.Pairs[x].Base.String())
|
||||
var resp Orders
|
||||
resp, err = b.GetOrders(ctx, "", "", "1000", "", req.Pairs[x].Base.String())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -737,8 +738,11 @@ func (b *Bithumb) GetActiveOrders(ctx context.Context, req *order.GetOrdersReque
|
||||
}
|
||||
|
||||
order.FilterOrdersBySide(&orders, req.Side)
|
||||
order.FilterOrdersByTimeRange(&orders, req.StartTime, req.EndTime)
|
||||
order.FilterOrdersByCurrencies(&orders, req.Pairs)
|
||||
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
|
||||
}
|
||||
|
||||
@@ -760,7 +764,8 @@ func (b *Bithumb) GetOrderHistory(ctx context.Context, req *order.GetOrdersReque
|
||||
|
||||
var orders []order.Detail
|
||||
for x := range req.Pairs {
|
||||
resp, err := b.GetOrders(ctx, "", "", "1000", "", req.Pairs[x].Base.String())
|
||||
var resp Orders
|
||||
resp, err = b.GetOrders(ctx, "", "", "1000", "", req.Pairs[x].Base.String())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -795,8 +800,11 @@ func (b *Bithumb) GetOrderHistory(ctx context.Context, req *order.GetOrdersReque
|
||||
}
|
||||
|
||||
order.FilterOrdersBySide(&orders, req.Side)
|
||||
order.FilterOrdersByTimeRange(&orders, req.StartTime, req.EndTime)
|
||||
order.FilterOrdersByCurrencies(&orders, req.Pairs)
|
||||
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
|
||||
}
|
||||
|
||||
|
||||
@@ -1174,6 +1174,22 @@ func TestCurrencyNormalization(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestGetOrderType(t *testing.T) {
|
||||
t.Parallel()
|
||||
if _, err := b.getOrderType(0); !errors.Is(err, order.ErrTypeIsInvalid) {
|
||||
t.Fatalf("received: '%v' but expected: '%v'", err, order.ErrTypeIsInvalid)
|
||||
}
|
||||
|
||||
o, err := b.getOrderType(1)
|
||||
if !errors.Is(err, nil) {
|
||||
t.Fatalf("received: '%v' but expected: '%v'", err, nil)
|
||||
}
|
||||
|
||||
if o != order.Market {
|
||||
t.Fatal("unexpected value")
|
||||
}
|
||||
}
|
||||
|
||||
func TestGetActionFromString(t *testing.T) {
|
||||
t.Parallel()
|
||||
_, err := b.GetActionFromString("meow")
|
||||
|
||||
@@ -767,16 +767,16 @@ func (b *Bitmex) GetActiveOrders(ctx context.Context, req *order.GetOrdersReques
|
||||
|
||||
orders := make([]order.Detail, len(resp))
|
||||
for i := range resp {
|
||||
orderSide := orderSideMap[resp[i].Side]
|
||||
orderStatus, err := order.StringToOrderStatus(resp[i].OrdStatus)
|
||||
var orderStatus order.Status
|
||||
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
|
||||
var oType order.Type
|
||||
oType, err = b.getOrderType(resp[i].OrdType)
|
||||
if err != nil {
|
||||
log.Errorf(log.ExchangeSys, "%s %v", b.Name, err)
|
||||
}
|
||||
|
||||
orderDetail := order.Detail{
|
||||
Date: resp[i].Timestamp,
|
||||
Price: resp[i].Price,
|
||||
@@ -785,9 +785,9 @@ func (b *Bitmex) GetActiveOrders(ctx context.Context, req *order.GetOrdersReques
|
||||
RemainingAmount: resp[i].LeavesQty,
|
||||
Exchange: b.Name,
|
||||
ID: resp[i].OrderID,
|
||||
Side: orderSide,
|
||||
Side: orderSideMap[resp[i].Side],
|
||||
Status: orderStatus,
|
||||
Type: orderType,
|
||||
Type: oType,
|
||||
Pair: currency.NewPairWithDelimiter(resp[i].Symbol,
|
||||
resp[i].SettlCurrency,
|
||||
format.Delimiter),
|
||||
@@ -798,8 +798,11 @@ func (b *Bitmex) GetActiveOrders(ctx context.Context, req *order.GetOrdersReques
|
||||
|
||||
order.FilterOrdersBySide(&orders, req.Side)
|
||||
order.FilterOrdersByType(&orders, req.Type)
|
||||
order.FilterOrdersByTimeRange(&orders, req.StartTime, req.EndTime)
|
||||
order.FilterOrdersByCurrencies(&orders, req.Pairs)
|
||||
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
|
||||
}
|
||||
|
||||
@@ -825,16 +828,20 @@ func (b *Bitmex) GetOrderHistory(ctx context.Context, req *order.GetOrdersReques
|
||||
orders := make([]order.Detail, len(resp))
|
||||
for i := range resp {
|
||||
orderSide := orderSideMap[resp[i].Side]
|
||||
orderStatus, err := order.StringToOrderStatus(resp[i].OrdStatus)
|
||||
var orderStatus order.Status
|
||||
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)
|
||||
|
||||
var oType order.Type
|
||||
oType, err = b.getOrderType(resp[i].OrdType)
|
||||
if err != nil {
|
||||
log.Errorf(log.ExchangeSys, "%s %v", b.Name, err)
|
||||
}
|
||||
|
||||
orderDetail := order.Detail{
|
||||
Price: resp[i].Price,
|
||||
AverageExecutedPrice: resp[i].AvgPx,
|
||||
@@ -847,7 +854,7 @@ func (b *Bitmex) GetOrderHistory(ctx context.Context, req *order.GetOrdersReques
|
||||
ID: resp[i].OrderID,
|
||||
Side: orderSide,
|
||||
Status: orderStatus,
|
||||
Type: orderType,
|
||||
Type: oType,
|
||||
Pair: pair,
|
||||
}
|
||||
orderDetail.InferCostsAndTimes()
|
||||
@@ -857,8 +864,11 @@ func (b *Bitmex) GetOrderHistory(ctx context.Context, req *order.GetOrdersReques
|
||||
|
||||
order.FilterOrdersBySide(&orders, req.Side)
|
||||
order.FilterOrdersByType(&orders, req.Type)
|
||||
order.FilterOrdersByTimeRange(&orders, req.StartTime, req.EndTime)
|
||||
order.FilterOrdersByCurrencies(&orders, req.Pairs)
|
||||
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
|
||||
}
|
||||
|
||||
@@ -883,3 +893,12 @@ func (b *Bitmex) GetHistoricCandles(ctx context.Context, pair currency.Pair, a a
|
||||
func (b *Bitmex) GetHistoricCandlesExtended(ctx context.Context, pair currency.Pair, a asset.Item, start, end time.Time, interval kline.Interval) (kline.Item, error) {
|
||||
return kline.Item{}, common.ErrFunctionNotSupported
|
||||
}
|
||||
|
||||
// getOrderType derives an order type from bitmex int representation
|
||||
func (b *Bitmex) getOrderType(id int64) (order.Type, error) {
|
||||
o, ok := orderTypeMap[id]
|
||||
if !ok {
|
||||
return order.UnknownType, fmt.Errorf("unhandled order type for '%d': %w", id, order.ErrTypeIsInvalid)
|
||||
}
|
||||
return o, nil
|
||||
}
|
||||
|
||||
@@ -730,7 +730,8 @@ func (b *Bitstamp) GetActiveOrders(ctx context.Context, req *order.GetOrdersRequ
|
||||
orderSide = order.Sell
|
||||
}
|
||||
|
||||
tm, err := parseTime(resp[i].DateTime)
|
||||
var tm time.Time
|
||||
tm, err = parseTime(resp[i].DateTime)
|
||||
if err != nil {
|
||||
log.Errorf(log.ExchangeSys,
|
||||
"%s GetActiveOrders unable to parse time: %s\n", b.Name, err)
|
||||
@@ -760,8 +761,11 @@ func (b *Bitstamp) GetActiveOrders(ctx context.Context, req *order.GetOrdersRequ
|
||||
}
|
||||
}
|
||||
|
||||
order.FilterOrdersByTimeRange(&orders, req.StartTime, req.EndTime)
|
||||
order.FilterOrdersByCurrencies(&orders, req.Pairs)
|
||||
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
|
||||
}
|
||||
|
||||
@@ -829,7 +833,8 @@ func (b *Bitstamp) GetOrderHistory(ctx context.Context, req *order.GetOrdersRequ
|
||||
format.Delimiter)
|
||||
}
|
||||
|
||||
tm, err := parseTime(resp[i].Date)
|
||||
var tm time.Time
|
||||
tm, err = parseTime(resp[i].Date)
|
||||
if err != nil {
|
||||
log.Errorf(log.ExchangeSys,
|
||||
"%s GetOrderHistory unable to parse time: %s\n", b.Name, err)
|
||||
@@ -843,8 +848,11 @@ func (b *Bitstamp) GetOrderHistory(ctx context.Context, req *order.GetOrdersRequ
|
||||
})
|
||||
}
|
||||
|
||||
order.FilterOrdersByTimeRange(&orders, req.StartTime, req.EndTime)
|
||||
order.FilterOrdersByCurrencies(&orders, req.Pairs)
|
||||
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
|
||||
}
|
||||
|
||||
|
||||
@@ -5,7 +5,6 @@ import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"sort"
|
||||
"strings"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
@@ -666,10 +665,12 @@ func (b *Bittrex) ConstructOrderDetail(orderData *OrderData) (order.Detail, erro
|
||||
orderData.ID,
|
||||
err)
|
||||
}
|
||||
orderType := order.Type(strings.ToUpper(orderData.Type))
|
||||
orderType, err := order.StringToOrderType(orderData.Type)
|
||||
if err != nil {
|
||||
log.Errorf(log.ExchangeSys, "%s %v", b.Name, err)
|
||||
}
|
||||
|
||||
var orderStatus order.Status
|
||||
|
||||
switch orderData.Status {
|
||||
case order.Open.String():
|
||||
switch orderData.FillQuantity {
|
||||
@@ -778,7 +779,8 @@ func (b *Bittrex) GetActiveOrders(ctx context.Context, req *order.GetOrdersReque
|
||||
|
||||
resp := make([]order.Detail, 0, len(orderData))
|
||||
for i := range orderData {
|
||||
pair, err := currency.NewPairDelimiter(orderData[i].MarketSymbol,
|
||||
var pair currency.Pair
|
||||
pair, err = currency.NewPairDelimiter(orderData[i].MarketSymbol,
|
||||
format.Delimiter)
|
||||
if err != nil {
|
||||
log.Errorf(log.ExchangeSys,
|
||||
@@ -788,12 +790,17 @@ func (b *Bittrex) GetActiveOrders(ctx context.Context, req *order.GetOrdersReque
|
||||
orderData[i].ID,
|
||||
err)
|
||||
}
|
||||
orderType := order.Type(strings.ToUpper(orderData[i].Type))
|
||||
|
||||
orderSide, err := order.StringToOrderSide(orderData[i].Direction)
|
||||
var orderType order.Type
|
||||
orderType, err = order.StringToOrderType(orderData[i].Type)
|
||||
if err != nil {
|
||||
log.Errorf(log.ExchangeSys, "%s %v", b.Name, err)
|
||||
}
|
||||
|
||||
var orderSide order.Side
|
||||
orderSide, err = order.StringToOrderSide(orderData[i].Direction)
|
||||
if err != nil {
|
||||
log.Errorf(log.ExchangeSys, "GetActiveOrders - %s - cannot get order side - %s\n", b.Name, err.Error())
|
||||
continue
|
||||
}
|
||||
|
||||
resp = append(resp, order.Detail{
|
||||
@@ -812,8 +819,11 @@ func (b *Bittrex) GetActiveOrders(ctx context.Context, req *order.GetOrdersReque
|
||||
}
|
||||
|
||||
order.FilterOrdersByType(&resp, req.Type)
|
||||
order.FilterOrdersByTimeRange(&resp, req.StartTime, req.EndTime)
|
||||
order.FilterOrdersByCurrencies(&resp, req.Pairs)
|
||||
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
|
||||
@@ -836,18 +846,21 @@ func (b *Bittrex) GetOrderHistory(ctx context.Context, req *order.GetOrdersReque
|
||||
|
||||
var resp []order.Detail
|
||||
for x := range req.Pairs {
|
||||
formattedPair, err := b.FormatExchangeCurrency(req.Pairs[x], req.AssetType)
|
||||
var formattedPair currency.Pair
|
||||
formattedPair, err = b.FormatExchangeCurrency(req.Pairs[x], req.AssetType)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
orderData, err := b.GetOrderHistoryForCurrency(ctx, formattedPair.String())
|
||||
var orderData []OrderData
|
||||
orderData, err = b.GetOrderHistoryForCurrency(ctx, formattedPair.String())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
for i := range orderData {
|
||||
pair, err := currency.NewPairDelimiter(orderData[i].MarketSymbol,
|
||||
var pair currency.Pair
|
||||
pair, err = currency.NewPairDelimiter(orderData[i].MarketSymbol,
|
||||
format.Delimiter)
|
||||
if err != nil {
|
||||
log.Errorf(log.ExchangeSys,
|
||||
@@ -857,17 +870,22 @@ func (b *Bittrex) GetOrderHistory(ctx context.Context, req *order.GetOrdersReque
|
||||
orderData[i].ID,
|
||||
err)
|
||||
}
|
||||
orderType := order.Type(strings.ToUpper(orderData[i].Type))
|
||||
var orderType order.Type
|
||||
orderType, err = order.StringToOrderType(orderData[i].Type)
|
||||
if err != nil {
|
||||
log.Errorf(log.ExchangeSys, "%s %v", b.Name, err)
|
||||
}
|
||||
|
||||
orderSide, err := order.StringToOrderSide(orderData[i].Direction)
|
||||
var orderSide order.Side
|
||||
orderSide, err = order.StringToOrderSide(orderData[i].Direction)
|
||||
if err != nil {
|
||||
log.Errorf(log.ExchangeSys, "GetActiveOrders - %s - cannot get order side - %s\n", b.Name, err.Error())
|
||||
continue
|
||||
}
|
||||
orderStatus, err := order.StringToOrderStatus(orderData[i].Status)
|
||||
|
||||
var orderStatus order.Status
|
||||
orderStatus, err = order.StringToOrderStatus(orderData[i].Status)
|
||||
if err != nil {
|
||||
log.Errorf(log.ExchangeSys, "GetActiveOrders - %s - cannot get order status - %s\n", b.Name, err.Error())
|
||||
continue
|
||||
}
|
||||
|
||||
detail := order.Detail{
|
||||
@@ -890,8 +908,11 @@ func (b *Bittrex) GetOrderHistory(ctx context.Context, req *order.GetOrdersReque
|
||||
}
|
||||
|
||||
order.FilterOrdersByType(&resp, req.Type)
|
||||
order.FilterOrdersByTimeRange(&resp, req.StartTime, req.EndTime)
|
||||
order.FilterOrdersByCurrencies(&resp, req.Pairs)
|
||||
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
|
||||
|
||||
@@ -946,7 +946,7 @@ func TestTrim(t *testing.T) {
|
||||
|
||||
func TestFormatOrderType(t *testing.T) {
|
||||
t.Parallel()
|
||||
_, err := b.formatOrderType(order.Type("SWOOON"))
|
||||
_, err := b.formatOrderType(0)
|
||||
if !errors.Is(err, order.ErrTypeIsInvalid) {
|
||||
t.Fatalf("received: '%v' but expected: '%v'", err, order.ErrTypeIsInvalid)
|
||||
}
|
||||
@@ -999,7 +999,7 @@ func TestFormatOrderType(t *testing.T) {
|
||||
|
||||
func TestFormatOrderSide(t *testing.T) {
|
||||
t.Parallel()
|
||||
_, err := b.formatOrderSide("invalid")
|
||||
_, err := b.formatOrderSide(255)
|
||||
if !errors.Is(err, order.ErrSideIsInvalid) {
|
||||
t.Fatalf("received: '%v' but expected: '%v'", err, order.ErrSideIsInvalid)
|
||||
}
|
||||
|
||||
@@ -487,7 +487,7 @@ func (b *BTCMarkets) GetRecentTrades(ctx context.Context, p currency.Pair, asset
|
||||
|
||||
resp := make([]trade.Data, len(tradeData))
|
||||
for i := range tradeData {
|
||||
side := order.Side("")
|
||||
var side order.Side
|
||||
if tradeData[i].Side != "" {
|
||||
side, err = order.StringToOrderSide(tradeData[i].Side)
|
||||
if err != nil {
|
||||
@@ -829,7 +829,10 @@ func (b *BTCMarkets) GetActiveOrders(ctx context.Context, req *order.GetOrdersRe
|
||||
}
|
||||
}
|
||||
order.FilterOrdersByType(&resp, req.Type)
|
||||
order.FilterOrdersByTimeRange(&resp, req.StartTime, req.EndTime)
|
||||
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
|
||||
}
|
||||
|
||||
@@ -684,13 +684,18 @@ func (b *BTSE) GetOrderInfo(ctx context.Context, orderID string, pair currency.P
|
||||
log.Errorf(log.ExchangeSys,
|
||||
"%s GetOrderInfo unable to parse time: %s\n", b.Name, err)
|
||||
}
|
||||
var orderSide order.Side
|
||||
orderSide, err = order.StringToOrderSide(th[i].Side)
|
||||
if err != nil {
|
||||
return order.Detail{}, err
|
||||
}
|
||||
od.Trades = append(od.Trades, order.TradeHistory{
|
||||
Timestamp: createdAt,
|
||||
TID: th[i].TradeID,
|
||||
Price: th[i].Price,
|
||||
Amount: th[i].Size,
|
||||
Exchange: b.Name,
|
||||
Side: order.Side(th[i].Side),
|
||||
Side: orderSide,
|
||||
Fee: th[i].FeeAmount,
|
||||
})
|
||||
}
|
||||
@@ -854,13 +859,18 @@ func (b *BTSE) GetActiveOrders(ctx context.Context, req *order.GetOrdersRequest)
|
||||
b.Name,
|
||||
err)
|
||||
}
|
||||
var orderSide order.Side
|
||||
orderSide, err = order.StringToOrderSide(fills[i].Side)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
openOrder.Trades = append(openOrder.Trades, order.TradeHistory{
|
||||
Timestamp: createdAt,
|
||||
TID: fills[i].TradeID,
|
||||
Price: fills[i].Price,
|
||||
Amount: fills[i].Size,
|
||||
Exchange: b.Name,
|
||||
Side: order.Side(fills[i].Side),
|
||||
Side: orderSide,
|
||||
Fee: fills[i].FeeAmount,
|
||||
})
|
||||
}
|
||||
@@ -869,7 +879,10 @@ func (b *BTSE) GetActiveOrders(ctx context.Context, req *order.GetOrdersRequest)
|
||||
}
|
||||
|
||||
order.FilterOrdersByType(&orders, req.Type)
|
||||
order.FilterOrdersByTimeRange(&orders, req.StartTime, req.EndTime)
|
||||
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
|
||||
}
|
||||
@@ -914,6 +927,11 @@ func (b *BTSE) GetOrderHistory(ctx context.Context, getOrdersRequest *order.GetO
|
||||
if err != nil {
|
||||
log.Errorf(log.ExchangeSys, "%s %v", b.Name, err)
|
||||
}
|
||||
var orderSide order.Side
|
||||
orderSide, err = order.StringToOrderSide(currentOrder[y].Side)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
orderTime := time.UnixMilli(currentOrder[y].Timestamp)
|
||||
tempOrder := order.Detail{
|
||||
ID: currentOrder[y].OrderID,
|
||||
@@ -925,7 +943,7 @@ func (b *BTSE) GetOrderHistory(ctx context.Context, getOrdersRequest *order.GetO
|
||||
ExecutedAmount: currentOrder[y].FilledSize,
|
||||
RemainingAmount: currentOrder[y].Size - currentOrder[y].FilledSize,
|
||||
Date: orderTime,
|
||||
Side: order.Side(currentOrder[y].Side),
|
||||
Side: orderSide,
|
||||
Status: orderStatus,
|
||||
Pair: orderDeref.Pairs[x],
|
||||
}
|
||||
|
||||
@@ -6,7 +6,6 @@ import (
|
||||
"fmt"
|
||||
"sort"
|
||||
"strconv"
|
||||
"strings"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
@@ -783,22 +782,33 @@ func (c *CoinbasePro) GetActiveOrders(ctx context.Context, req *order.GetOrdersR
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
orderSide := order.Side(strings.ToUpper(respOrders[i].Side))
|
||||
orderType := order.Type(strings.ToUpper(respOrders[i].Type))
|
||||
var side order.Side
|
||||
side, err = order.StringToOrderSide(respOrders[i].Side)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
var orderType order.Type
|
||||
orderType, err = order.StringToOrderType(respOrders[i].Type)
|
||||
if err != nil {
|
||||
log.Errorf(log.ExchangeSys, "%s %v", c.Name, err)
|
||||
}
|
||||
orders[i] = order.Detail{
|
||||
ID: respOrders[i].ID,
|
||||
Amount: respOrders[i].Size,
|
||||
ExecutedAmount: respOrders[i].FilledSize,
|
||||
Type: orderType,
|
||||
Date: respOrders[i].CreatedAt,
|
||||
Side: orderSide,
|
||||
Side: side,
|
||||
Pair: curr,
|
||||
Exchange: c.Name,
|
||||
}
|
||||
}
|
||||
|
||||
order.FilterOrdersByType(&orders, req.Type)
|
||||
order.FilterOrdersByTimeRange(&orders, req.StartTime, req.EndTime)
|
||||
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
|
||||
}
|
||||
@@ -847,12 +857,21 @@ func (c *CoinbasePro) GetOrderHistory(ctx context.Context, req *order.GetOrdersR
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
orderSide := order.Side(strings.ToUpper(respOrders[i].Side))
|
||||
orderStatus, err := order.StringToOrderStatus(respOrders[i].Status)
|
||||
var side order.Side
|
||||
side, err = order.StringToOrderSide(respOrders[i].Side)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
var orderStatus order.Status
|
||||
orderStatus, err = order.StringToOrderStatus(respOrders[i].Status)
|
||||
if err != nil {
|
||||
log.Errorf(log.ExchangeSys, "%s %v", c.Name, err)
|
||||
}
|
||||
var orderType order.Type
|
||||
orderType, err = order.StringToOrderType(respOrders[i].Type)
|
||||
if err != nil {
|
||||
log.Errorf(log.ExchangeSys, "%s %v", c.Name, err)
|
||||
}
|
||||
orderType := order.Type(strings.ToUpper(respOrders[i].Type))
|
||||
detail := order.Detail{
|
||||
ID: respOrders[i].ID,
|
||||
Amount: respOrders[i].Size,
|
||||
@@ -865,7 +884,7 @@ func (c *CoinbasePro) GetOrderHistory(ctx context.Context, req *order.GetOrdersR
|
||||
CloseTime: respOrders[i].DoneAt,
|
||||
Fee: respOrders[i].FillFees,
|
||||
FeeAsset: curr.Quote,
|
||||
Side: orderSide,
|
||||
Side: side,
|
||||
Status: orderStatus,
|
||||
Pair: curr,
|
||||
Price: respOrders[i].Price,
|
||||
@@ -876,7 +895,10 @@ func (c *CoinbasePro) GetOrderHistory(ctx context.Context, req *order.GetOrdersR
|
||||
}
|
||||
|
||||
order.FilterOrdersByType(&orders, req.Type)
|
||||
order.FilterOrdersByTimeRange(&orders, req.StartTime, req.EndTime)
|
||||
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
|
||||
}
|
||||
|
||||
@@ -775,7 +775,7 @@ func (c *COINUT) wsSubmitOrder(o *WsSubmitOrderParameters) (*order.Detail, error
|
||||
orderSubmissionRequest.InstrumentID = c.instrumentMap.LookupID(curr.String())
|
||||
orderSubmissionRequest.Quantity = o.Amount
|
||||
orderSubmissionRequest.Price = o.Price
|
||||
orderSubmissionRequest.Side = string(o.Side)
|
||||
orderSubmissionRequest.Side = o.Side.String()
|
||||
|
||||
if o.OrderID > 0 {
|
||||
orderSubmissionRequest.OrderID = o.OrderID
|
||||
@@ -816,7 +816,7 @@ func (c *COINUT) wsSubmitOrders(orders []WsSubmitOrderParameters) ([]order.Detai
|
||||
WsSubmitOrdersRequestData{
|
||||
Quantity: orders[i].Amount,
|
||||
Price: orders[i].Price,
|
||||
Side: string(orders[i].Side),
|
||||
Side: orders[i].Side.String(),
|
||||
InstrumentID: c.instrumentMap.LookupID(curr.String()),
|
||||
ClientOrderID: i + 1,
|
||||
})
|
||||
|
||||
@@ -872,11 +872,12 @@ func (c *COINUT) GetActiveOrders(ctx context.Context, req *order.GetOrdersReques
|
||||
var currenciesToCheck []string
|
||||
if len(req.Pairs) == 0 {
|
||||
for i := range req.Pairs {
|
||||
fpair, err := c.FormatExchangeCurrency(req.Pairs[i], asset.Spot)
|
||||
var fPair currency.Pair
|
||||
fPair, err = c.FormatExchangeCurrency(req.Pairs[i], asset.Spot)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
currenciesToCheck = append(currenciesToCheck, fpair.String())
|
||||
currenciesToCheck = append(currenciesToCheck, fPair.String())
|
||||
}
|
||||
} else {
|
||||
for k := range c.instrumentMap.Instruments {
|
||||
@@ -885,17 +886,26 @@ func (c *COINUT) GetActiveOrders(ctx context.Context, req *order.GetOrdersReques
|
||||
}
|
||||
if c.Websocket.CanUseAuthenticatedWebsocketForWrapper() {
|
||||
for x := range currenciesToCheck {
|
||||
openOrders, err := c.wsGetOpenOrders(currenciesToCheck[x])
|
||||
var openOrders *WsUserOpenOrdersResponse
|
||||
openOrders, err = c.wsGetOpenOrders(currenciesToCheck[x])
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
for i := range openOrders.Orders {
|
||||
p, err := currency.NewPairFromString(currenciesToCheck[x])
|
||||
var p currency.Pair
|
||||
p, err = currency.NewPairFromString(currenciesToCheck[x])
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
fpair, err := c.FormatExchangeCurrency(p, asset.Spot)
|
||||
var fPair currency.Pair
|
||||
fPair, err = c.FormatExchangeCurrency(p, asset.Spot)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var side order.Side
|
||||
side, err = order.StringToOrderSide(openOrders.Orders[i].Side)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -903,8 +913,8 @@ func (c *COINUT) GetActiveOrders(ctx context.Context, req *order.GetOrdersReques
|
||||
orders = append(orders, order.Detail{
|
||||
Exchange: c.Name,
|
||||
ID: strconv.FormatInt(openOrders.Orders[i].OrderID, 10),
|
||||
Pair: fpair,
|
||||
Side: order.Side(openOrders.Orders[i].Side),
|
||||
Pair: fPair,
|
||||
Side: side,
|
||||
Date: time.Unix(0, openOrders.Orders[i].Timestamp),
|
||||
Status: order.Active,
|
||||
Price: openOrders.Orders[i].Price,
|
||||
@@ -917,8 +927,8 @@ func (c *COINUT) GetActiveOrders(ctx context.Context, req *order.GetOrdersReques
|
||||
} else {
|
||||
var instrumentsToUse []int64
|
||||
for x := range req.Pairs {
|
||||
curr, err := c.FormatExchangeCurrency(req.Pairs[x],
|
||||
asset.Spot)
|
||||
var curr currency.Pair
|
||||
curr, err = c.FormatExchangeCurrency(req.Pairs[x], asset.Spot)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -929,46 +939,55 @@ func (c *COINUT) GetActiveOrders(ctx context.Context, req *order.GetOrdersReques
|
||||
instrumentsToUse = c.instrumentMap.GetInstrumentIDs()
|
||||
}
|
||||
|
||||
pairs, err := c.GetEnabledPairs(asset.Spot)
|
||||
var pairs currency.Pairs
|
||||
pairs, err = c.GetEnabledPairs(asset.Spot)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
format, err := c.GetPairFormat(asset.Spot, true)
|
||||
var format currency.PairFormat
|
||||
format, err = c.GetPairFormat(asset.Spot, true)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
for x := range instrumentsToUse {
|
||||
openOrders, err := c.GetOpenOrders(ctx, instrumentsToUse[x])
|
||||
var openOrders GetOpenOrdersResponse
|
||||
openOrders, err = c.GetOpenOrders(ctx, instrumentsToUse[x])
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
for y := range openOrders.Orders {
|
||||
curr := c.instrumentMap.LookupInstrument(instrumentsToUse[x])
|
||||
p, err := currency.NewPairFromFormattedPairs(curr,
|
||||
pairs,
|
||||
format)
|
||||
var p currency.Pair
|
||||
p, err = currency.NewPairFromFormattedPairs(curr, pairs, format)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var side order.Side
|
||||
side, err = order.StringToOrderSide(openOrders.Orders[y].Side)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
orderSide := order.Side(strings.ToUpper(openOrders.Orders[y].Side))
|
||||
orderDate := time.Unix(openOrders.Orders[y].Timestamp, 0)
|
||||
orders = append(orders, order.Detail{
|
||||
ID: strconv.FormatInt(openOrders.Orders[y].OrderID, 10),
|
||||
Amount: openOrders.Orders[y].Quantity,
|
||||
Price: openOrders.Orders[y].Price,
|
||||
Exchange: c.Name,
|
||||
Side: orderSide,
|
||||
Date: orderDate,
|
||||
Side: side,
|
||||
Date: time.Unix(openOrders.Orders[y].Timestamp, 0),
|
||||
Pair: p,
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
order.FilterOrdersByTimeRange(&orders, req.StartTime, req.EndTime)
|
||||
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
|
||||
}
|
||||
@@ -988,13 +1007,21 @@ func (c *COINUT) GetOrderHistory(ctx context.Context, req *order.GetOrdersReques
|
||||
if c.Websocket.CanUseAuthenticatedWebsocketForWrapper() {
|
||||
for i := range req.Pairs {
|
||||
for j := int64(0); ; j += 100 {
|
||||
trades, err := c.wsGetTradeHistory(req.Pairs[i], j, 100)
|
||||
var trades *WsTradeHistoryResponse
|
||||
trades, err = c.wsGetTradeHistory(req.Pairs[i], j, 100)
|
||||
if err != nil {
|
||||
return allOrders, err
|
||||
}
|
||||
for x := range trades.Trades {
|
||||
curr := c.instrumentMap.LookupInstrument(trades.Trades[x].InstrumentID)
|
||||
p, err := currency.NewPairFromString(curr)
|
||||
var p currency.Pair
|
||||
p, err = currency.NewPairFromString(curr)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var side order.Side
|
||||
side, err = order.StringToOrderSide(trades.Trades[x].Side)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -1003,7 +1030,7 @@ func (c *COINUT) GetOrderHistory(ctx context.Context, req *order.GetOrdersReques
|
||||
Exchange: c.Name,
|
||||
ID: strconv.FormatInt(trades.Trades[x].OrderID, 10),
|
||||
Pair: p,
|
||||
Side: order.Side(trades.Trades[x].Side),
|
||||
Side: side,
|
||||
Date: time.Unix(0, trades.Trades[x].Timestamp),
|
||||
Status: order.Filled,
|
||||
Price: trades.Trades[x].Price,
|
||||
@@ -1022,8 +1049,8 @@ func (c *COINUT) GetOrderHistory(ctx context.Context, req *order.GetOrdersReques
|
||||
} else {
|
||||
var instrumentsToUse []int64
|
||||
for x := range req.Pairs {
|
||||
curr, err := c.FormatExchangeCurrency(req.Pairs[x],
|
||||
asset.Spot)
|
||||
var curr currency.Pair
|
||||
curr, err = c.FormatExchangeCurrency(req.Pairs[x], asset.Spot)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -1037,46 +1064,55 @@ func (c *COINUT) GetOrderHistory(ctx context.Context, req *order.GetOrdersReques
|
||||
instrumentsToUse = c.instrumentMap.GetInstrumentIDs()
|
||||
}
|
||||
|
||||
pairs, err := c.GetEnabledPairs(asset.Spot)
|
||||
var pairs currency.Pairs
|
||||
pairs, err = c.GetEnabledPairs(asset.Spot)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
format, err := c.GetPairFormat(asset.Spot, true)
|
||||
var format currency.PairFormat
|
||||
format, err = c.GetPairFormat(asset.Spot, true)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
for x := range instrumentsToUse {
|
||||
orders, err := c.GetTradeHistory(ctx, instrumentsToUse[x], -1, -1)
|
||||
var orders TradeHistory
|
||||
orders, err = c.GetTradeHistory(ctx, instrumentsToUse[x], -1, -1)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
for y := range orders.Trades {
|
||||
curr := c.instrumentMap.LookupInstrument(instrumentsToUse[x])
|
||||
p, err := currency.NewPairFromFormattedPairs(curr,
|
||||
pairs,
|
||||
format)
|
||||
var p currency.Pair
|
||||
p, err = currency.NewPairFromFormattedPairs(curr, pairs, format)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var side order.Side
|
||||
side, err = order.StringToOrderSide(orders.Trades[y].Order.Side)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
orderSide := order.Side(strings.ToUpper(orders.Trades[y].Order.Side))
|
||||
orderDate := time.Unix(orders.Trades[y].Order.Timestamp, 0)
|
||||
allOrders = append(allOrders, order.Detail{
|
||||
ID: strconv.FormatInt(orders.Trades[y].Order.OrderID, 10),
|
||||
Amount: orders.Trades[y].Order.Quantity,
|
||||
Price: orders.Trades[y].Order.Price,
|
||||
Exchange: c.Name,
|
||||
Side: orderSide,
|
||||
Date: orderDate,
|
||||
Side: side,
|
||||
Date: time.Unix(orders.Trades[y].Order.Timestamp, 0),
|
||||
Pair: p,
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
order.FilterOrdersByTimeRange(&allOrders, req.StartTime, req.EndTime)
|
||||
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
|
||||
}
|
||||
|
||||
@@ -650,19 +650,26 @@ func (e *EXMO) GetActiveOrders(ctx context.Context, req *order.GetOrdersRequest)
|
||||
return nil, err
|
||||
}
|
||||
orderDate := time.Unix(resp[i].Created, 0)
|
||||
orderSide := order.Side(strings.ToUpper(resp[i].Type))
|
||||
var side order.Side
|
||||
side, err = order.StringToOrderSide(resp[i].Type)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
orders = append(orders, order.Detail{
|
||||
ID: strconv.FormatInt(resp[i].OrderID, 10),
|
||||
Amount: resp[i].Quantity,
|
||||
Date: orderDate,
|
||||
Price: resp[i].Price,
|
||||
Side: orderSide,
|
||||
Side: side,
|
||||
Exchange: e.Name,
|
||||
Pair: symbol,
|
||||
})
|
||||
}
|
||||
|
||||
order.FilterOrdersByTimeRange(&orders, req.StartTime, req.EndTime)
|
||||
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
|
||||
}
|
||||
@@ -701,7 +708,11 @@ func (e *EXMO) GetOrderHistory(ctx context.Context, req *order.GetOrdersRequest)
|
||||
return nil, err
|
||||
}
|
||||
orderDate := time.Unix(allTrades[i].Date, 0)
|
||||
orderSide := order.Side(strings.ToUpper(allTrades[i].Type))
|
||||
var side order.Side
|
||||
side, err = order.StringToOrderSide(allTrades[i].Type)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
detail := order.Detail{
|
||||
ID: strconv.FormatInt(allTrades[i].TradeID, 10),
|
||||
Amount: allTrades[i].Quantity,
|
||||
@@ -710,7 +721,7 @@ func (e *EXMO) GetOrderHistory(ctx context.Context, req *order.GetOrdersRequest)
|
||||
CostAsset: pair.Quote,
|
||||
Date: orderDate,
|
||||
Price: allTrades[i].Price,
|
||||
Side: orderSide,
|
||||
Side: side,
|
||||
Exchange: e.Name,
|
||||
Pair: pair,
|
||||
}
|
||||
@@ -718,7 +729,10 @@ func (e *EXMO) GetOrderHistory(ctx context.Context, req *order.GetOrdersRequest)
|
||||
orders[i] = detail
|
||||
}
|
||||
|
||||
order.FilterOrdersByTimeRange(&orders, req.StartTime, req.EndTime)
|
||||
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
|
||||
}
|
||||
|
||||
@@ -787,7 +787,11 @@ func (g *Gateio) GetActiveOrders(ctx context.Context, req *order.GetOrdersReques
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
side := order.Side(strings.ToUpper(resp.Orders[i].Type))
|
||||
var side order.Side
|
||||
side, err = order.StringToOrderSide(resp.Orders[i].Type)
|
||||
if err != nil {
|
||||
log.Errorf(log.ExchangeSys, "%s %v", g.Name, err)
|
||||
}
|
||||
status, err := order.StringToOrderStatus(resp.Orders[i].Status)
|
||||
if err != nil {
|
||||
log.Errorf(log.ExchangeSys, "%s %v", g.Name, err)
|
||||
@@ -807,7 +811,10 @@ func (g *Gateio) GetActiveOrders(ctx context.Context, req *order.GetOrdersReques
|
||||
})
|
||||
}
|
||||
}
|
||||
order.FilterOrdersByTimeRange(&orders, req.StartTime, req.EndTime)
|
||||
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
|
||||
}
|
||||
@@ -840,7 +847,11 @@ func (g *Gateio) GetOrderHistory(ctx context.Context, req *order.GetOrdersReques
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
side := order.Side(strings.ToUpper(trades[i].Type))
|
||||
var side order.Side
|
||||
side, err = order.StringToOrderSide(trades[i].Type)
|
||||
if err != nil {
|
||||
log.Errorf(log.ExchangeSys, "%s %v", g.Name, err)
|
||||
}
|
||||
orderDate := time.Unix(trades[i].TimeUnix, 0)
|
||||
detail := order.Detail{
|
||||
ID: strconv.FormatInt(trades[i].OrderID, 10),
|
||||
@@ -857,7 +868,10 @@ func (g *Gateio) GetOrderHistory(ctx context.Context, req *order.GetOrdersReques
|
||||
orders[i] = detail
|
||||
}
|
||||
|
||||
order.FilterOrdersByTimeRange(&orders, req.StartTime, req.EndTime)
|
||||
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
|
||||
}
|
||||
|
||||
@@ -7,7 +7,6 @@ import (
|
||||
"net/url"
|
||||
"sort"
|
||||
"strconv"
|
||||
"strings"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
@@ -710,8 +709,11 @@ func (g *Gemini) GetActiveOrders(ctx context.Context, req *order.GetOrdersReques
|
||||
} else if resp[i].Type == "market buy" || resp[i].Type == "market sell" {
|
||||
orderType = order.Market
|
||||
}
|
||||
|
||||
side := order.Side(strings.ToUpper(resp[i].Type))
|
||||
var side order.Side
|
||||
side, err = order.StringToOrderSide(resp[i].Type)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
orderDate := time.Unix(resp[i].Timestamp, 0)
|
||||
|
||||
orders[i] = order.Detail{
|
||||
@@ -728,10 +730,13 @@ func (g *Gemini) GetActiveOrders(ctx context.Context, req *order.GetOrdersReques
|
||||
}
|
||||
}
|
||||
|
||||
order.FilterOrdersByTimeRange(&orders, req.StartTime, req.EndTime)
|
||||
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.FilterOrdersByCurrencies(&orders, req.Pairs)
|
||||
order.FilterOrdersByPairs(&orders, req.Pairs)
|
||||
return orders, nil
|
||||
}
|
||||
|
||||
@@ -774,7 +779,11 @@ func (g *Gemini) GetOrderHistory(ctx context.Context, req *order.GetOrdersReques
|
||||
|
||||
orders := make([]order.Detail, len(trades))
|
||||
for i := range trades {
|
||||
side := order.Side(strings.ToUpper(trades[i].Type))
|
||||
var side order.Side
|
||||
side, err = order.StringToOrderSide(trades[i].Type)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
orderDate := time.Unix(trades[i].Timestamp, 0)
|
||||
|
||||
detail := order.Detail{
|
||||
@@ -797,7 +806,10 @@ func (g *Gemini) GetOrderHistory(ctx context.Context, req *order.GetOrdersReques
|
||||
orders[i] = detail
|
||||
}
|
||||
|
||||
order.FilterOrdersByTimeRange(&orders, req.StartTime, req.EndTime)
|
||||
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
|
||||
}
|
||||
|
||||
@@ -742,7 +742,11 @@ func (h *HitBTC) GetActiveOrders(ctx context.Context, req *order.GetOrdersReques
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
side := order.Side(strings.ToUpper(allOrders[i].Side))
|
||||
var side order.Side
|
||||
side, err = order.StringToOrderSide(allOrders[i].Side)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
orders[i] = order.Detail{
|
||||
ID: allOrders[i].ID,
|
||||
Amount: allOrders[i].Quantity,
|
||||
@@ -754,7 +758,10 @@ func (h *HitBTC) GetActiveOrders(ctx context.Context, req *order.GetOrdersReques
|
||||
}
|
||||
}
|
||||
|
||||
order.FilterOrdersByTimeRange(&orders, req.StartTime, req.EndTime)
|
||||
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
|
||||
}
|
||||
@@ -792,8 +799,13 @@ func (h *HitBTC) GetOrderHistory(ctx context.Context, req *order.GetOrdersReques
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
side := order.Side(strings.ToUpper(allOrders[i].Side))
|
||||
status, err := order.StringToOrderStatus(allOrders[i].Status)
|
||||
var side order.Side
|
||||
side, err = order.StringToOrderSide(allOrders[i].Side)
|
||||
if err != nil {
|
||||
log.Errorf(log.ExchangeSys, "%s %v", h.Name, err)
|
||||
}
|
||||
var status order.Status
|
||||
status, err = order.StringToOrderStatus(allOrders[i].Status)
|
||||
if err != nil {
|
||||
log.Errorf(log.ExchangeSys, "%s %v", h.Name, err)
|
||||
}
|
||||
@@ -815,7 +827,10 @@ func (h *HitBTC) GetOrderHistory(ctx context.Context, req *order.GetOrdersReques
|
||||
orders[i] = detail
|
||||
}
|
||||
|
||||
order.FilterOrdersByTimeRange(&orders, req.StartTime, req.EndTime)
|
||||
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
|
||||
}
|
||||
|
||||
@@ -1351,9 +1351,7 @@ func (h *HUOBI) GetActiveOrders(ctx context.Context, req *order.GetOrdersRequest
|
||||
return nil, errors.New("currency must be supplied")
|
||||
}
|
||||
side := ""
|
||||
if req.Side == order.AnySide || req.Side == "" {
|
||||
side = ""
|
||||
} else if req.Side == order.Sell {
|
||||
if req.Side == order.Sell {
|
||||
side = req.Side.Lower()
|
||||
}
|
||||
if h.Websocket.CanUseAuthenticatedWebsocketForWrapper() {
|
||||
@@ -1527,7 +1525,10 @@ func (h *HUOBI) GetActiveOrders(ctx context.Context, req *order.GetOrdersRequest
|
||||
}
|
||||
order.FilterOrdersByType(&orders, req.Type)
|
||||
order.FilterOrdersBySide(&orders, req.Side)
|
||||
order.FilterOrdersByTimeRange(&orders, req.StartTime, req.EndTime)
|
||||
err := order.FilterOrdersByTimeRange(&orders, req.StartTime, req.EndTime)
|
||||
if err != nil {
|
||||
log.Errorf(log.ExchangeSys, "%s %v", h.Name, err)
|
||||
}
|
||||
return orders, nil
|
||||
}
|
||||
|
||||
@@ -1687,7 +1688,10 @@ func (h *HUOBI) GetOrderHistory(ctx context.Context, req *order.GetOrdersRequest
|
||||
}
|
||||
}
|
||||
}
|
||||
order.FilterOrdersByTimeRange(&orders, req.StartTime, req.EndTime)
|
||||
err := order.FilterOrdersByTimeRange(&orders, req.StartTime, req.EndTime)
|
||||
if err != nil {
|
||||
log.Errorf(log.ExchangeSys, "%s %v", h.Name, err)
|
||||
}
|
||||
return orders, nil
|
||||
}
|
||||
|
||||
|
||||
@@ -6,7 +6,6 @@ import (
|
||||
"net/url"
|
||||
"sort"
|
||||
"strconv"
|
||||
"strings"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
@@ -551,13 +550,18 @@ func (i *ItBit) GetActiveOrders(ctx context.Context, req *order.GetOrdersRequest
|
||||
orders := make([]order.Detail, 0, len(allOrders))
|
||||
for j := range allOrders {
|
||||
var symbol currency.Pair
|
||||
symbol, err := currency.NewPairDelimiter(allOrders[j].Instrument,
|
||||
symbol, err = currency.NewPairDelimiter(allOrders[j].Instrument,
|
||||
format.Delimiter)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
side := order.Side(strings.ToUpper(allOrders[j].Side))
|
||||
orderDate, err := time.Parse(time.RFC3339, allOrders[j].CreatedTime)
|
||||
var side order.Side
|
||||
side, err = order.StringToOrderSide(allOrders[j].Side)
|
||||
if err != nil {
|
||||
log.Errorf(log.ExchangeSys, "%s %v", i.Name, err)
|
||||
}
|
||||
var orderDate time.Time
|
||||
orderDate, err = time.Parse(time.RFC3339, allOrders[j].CreatedTime)
|
||||
if err != nil {
|
||||
log.Errorf(log.ExchangeSys,
|
||||
"Exchange %v Func %v Order %v Could not parse date to unix with value of %v",
|
||||
@@ -579,9 +583,12 @@ func (i *ItBit) GetActiveOrders(ctx context.Context, req *order.GetOrdersRequest
|
||||
})
|
||||
}
|
||||
|
||||
order.FilterOrdersByTimeRange(&orders, req.StartTime, req.EndTime)
|
||||
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.FilterOrdersByCurrencies(&orders, req.Pairs)
|
||||
order.FilterOrdersByPairs(&orders, req.Pairs)
|
||||
return orders, nil
|
||||
}
|
||||
|
||||
@@ -623,13 +630,18 @@ func (i *ItBit) GetOrderHistory(ctx context.Context, req *order.GetOrdersRequest
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
side := order.Side(strings.ToUpper(allOrders[j].Side))
|
||||
status, err := order.StringToOrderStatus(allOrders[j].Status)
|
||||
var side order.Side
|
||||
side, err = order.StringToOrderSide(allOrders[j].Side)
|
||||
if err != nil {
|
||||
log.Errorf(log.ExchangeSys, "%s %v", i.Name, err)
|
||||
}
|
||||
orderDate, err := time.Parse(time.RFC3339, allOrders[j].CreatedTime)
|
||||
var status order.Status
|
||||
status, err = order.StringToOrderStatus(allOrders[j].Status)
|
||||
if err != nil {
|
||||
log.Errorf(log.ExchangeSys, "%s %v", i.Name, err)
|
||||
}
|
||||
var orderDate time.Time
|
||||
orderDate, err = time.Parse(time.RFC3339, allOrders[j].CreatedTime)
|
||||
if err != nil {
|
||||
log.Errorf(log.ExchangeSys,
|
||||
"Exchange %v Func %v Order %v Could not parse date to unix with value of %v",
|
||||
@@ -656,9 +668,12 @@ func (i *ItBit) GetOrderHistory(ctx context.Context, req *order.GetOrdersRequest
|
||||
orders = append(orders, detail)
|
||||
}
|
||||
|
||||
order.FilterOrdersByTimeRange(&orders, req.StartTime, req.EndTime)
|
||||
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.FilterOrdersByCurrencies(&orders, req.Pairs)
|
||||
order.FilterOrdersByPairs(&orders, req.Pairs)
|
||||
return orders, nil
|
||||
}
|
||||
|
||||
|
||||
@@ -1127,8 +1127,16 @@ func (k *Kraken) GetActiveOrders(ctx context.Context, req *order.GetOrdersReques
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
side := order.Side(strings.ToUpper(resp.Open[i].Description.Type))
|
||||
orderType := order.Type(strings.ToUpper(resp.Open[i].Description.OrderType))
|
||||
var side order.Side
|
||||
side, err = order.StringToOrderSide(resp.Open[i].Description.Type)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
var orderType order.Type
|
||||
orderType, err = order.StringToOrderType(resp.Open[i].Description.OrderType)
|
||||
if err != nil {
|
||||
log.Errorf(log.ExchangeSys, "%s %v", k.Name, err)
|
||||
}
|
||||
orders = append(orders, order.Detail{
|
||||
ID: i,
|
||||
Amount: resp.Open[i].Volume,
|
||||
@@ -1193,9 +1201,12 @@ func (k *Kraken) GetActiveOrders(ctx context.Context, req *order.GetOrdersReques
|
||||
default:
|
||||
return nil, fmt.Errorf("%s assetType not supported", req.AssetType)
|
||||
}
|
||||
order.FilterOrdersByTimeRange(&orders, req.StartTime, req.EndTime)
|
||||
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.FilterOrdersByCurrencies(&orders, req.Pairs)
|
||||
order.FilterOrdersByPairs(&orders, req.Pairs)
|
||||
return orders, nil
|
||||
}
|
||||
|
||||
@@ -1244,12 +1255,20 @@ func (k *Kraken) GetOrderHistory(ctx context.Context, getOrdersRequest *order.Ge
|
||||
return nil, err
|
||||
}
|
||||
|
||||
side := order.Side(strings.ToUpper(resp.Closed[i].Description.Type))
|
||||
var side order.Side
|
||||
side, err = order.StringToOrderSide(resp.Closed[i].Description.Type)
|
||||
if err != nil {
|
||||
log.Errorf(log.ExchangeSys, "%s %v", k.Name, err)
|
||||
}
|
||||
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))
|
||||
var orderType order.Type
|
||||
orderType, err = order.StringToOrderType(resp.Closed[i].Description.OrderType)
|
||||
if err != nil {
|
||||
log.Errorf(log.ExchangeSys, "%s %v", k.Name, err)
|
||||
}
|
||||
detail := order.Detail{
|
||||
ID: i,
|
||||
Amount: resp.Closed[i].Volume,
|
||||
@@ -1414,7 +1433,7 @@ func (k *Kraken) GetOrderHistory(ctx context.Context, getOrdersRequest *order.Ge
|
||||
}
|
||||
|
||||
order.FilterOrdersBySide(&orders, getOrdersRequest.Side)
|
||||
order.FilterOrdersByCurrencies(&orders, getOrdersRequest.Pairs)
|
||||
order.FilterOrdersByPairs(&orders, getOrdersRequest.Pairs)
|
||||
return orders, nil
|
||||
}
|
||||
|
||||
|
||||
@@ -567,3 +567,27 @@ func TestUpdateTickers(t *testing.T) {
|
||||
t.Error(err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestGetStatus(t *testing.T) {
|
||||
t.Parallel()
|
||||
for _, tt := range []struct {
|
||||
status int64
|
||||
resp order.Status
|
||||
}{
|
||||
{status: -1, resp: order.Cancelled},
|
||||
{status: 0, resp: order.Active},
|
||||
{status: 1, resp: order.PartiallyFilled},
|
||||
{status: 2, resp: order.Filled},
|
||||
{status: 4, resp: order.Cancelling},
|
||||
{status: 5, resp: order.UnknownStatus},
|
||||
} {
|
||||
tt := tt
|
||||
t.Run("", func(t *testing.T) {
|
||||
t.Parallel()
|
||||
resp := l.GetStatus(tt.status)
|
||||
if resp != tt.resp {
|
||||
t.Fatalf("received: '%v' but expected: '%v'", resp, tt.resp)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
@@ -596,30 +596,16 @@ func (l *Lbank) GetOrderInfo(ctx context.Context, orderID string, pair currency.
|
||||
} else {
|
||||
resp.Side = order.Sell
|
||||
}
|
||||
z := tempResp.Orders[0].Status
|
||||
switch {
|
||||
case z == -1:
|
||||
resp.Status = "cancelled"
|
||||
case z == 0:
|
||||
resp.Status = "on trading"
|
||||
case z == 1:
|
||||
resp.Status = "filled partially"
|
||||
case z == 2:
|
||||
resp.Status = "Filled totally"
|
||||
case z == 4:
|
||||
resp.Status = "Cancelling"
|
||||
default:
|
||||
resp.Status = "Invalid Order Status"
|
||||
}
|
||||
|
||||
resp.Status = l.GetStatus(tempResp.Orders[0].Status)
|
||||
resp.Price = tempResp.Orders[0].Price
|
||||
resp.Amount = tempResp.Orders[0].Amount
|
||||
resp.ExecutedAmount = tempResp.Orders[0].DealAmount
|
||||
resp.RemainingAmount = tempResp.Orders[0].Amount - tempResp.Orders[0].DealAmount
|
||||
resp.Fee, err = l.GetFeeByType(ctx,
|
||||
&exchange.FeeBuilder{
|
||||
FeeType: exchange.CryptocurrencyTradeFee,
|
||||
Amount: tempResp.Orders[0].Amount,
|
||||
PurchasePrice: tempResp.Orders[0].Price})
|
||||
resp.Fee, err = l.GetFeeByType(ctx, &exchange.FeeBuilder{
|
||||
FeeType: exchange.CryptocurrencyTradeFee,
|
||||
Amount: tempResp.Orders[0].Amount,
|
||||
PurchasePrice: tempResp.Orders[0].Price})
|
||||
if err != nil {
|
||||
resp.Fee = lbankFeeNotFound
|
||||
}
|
||||
@@ -696,21 +682,7 @@ func (l *Lbank) GetActiveOrders(ctx context.Context, getOrdersRequest *order.Get
|
||||
} else {
|
||||
resp.Side = order.Sell
|
||||
}
|
||||
z := tempResp.Orders[0].Status
|
||||
switch {
|
||||
case z == -1:
|
||||
resp.Status = "cancelled"
|
||||
case z == 1:
|
||||
resp.Status = "on trading"
|
||||
case z == 2:
|
||||
resp.Status = "filled partially"
|
||||
case z == 3:
|
||||
resp.Status = "Filled totally"
|
||||
case z == 4:
|
||||
resp.Status = "Cancelling"
|
||||
default:
|
||||
resp.Status = "Invalid Order Status"
|
||||
}
|
||||
resp.Status = l.GetStatus(tempResp.Orders[0].Status)
|
||||
resp.Price = tempResp.Orders[0].Price
|
||||
resp.Amount = tempResp.Orders[0].Amount
|
||||
resp.Date = time.Unix(tempResp.Orders[0].CreateTime, 0)
|
||||
@@ -728,7 +700,7 @@ func (l *Lbank) GetActiveOrders(ctx context.Context, getOrdersRequest *order.Get
|
||||
if getOrdersRequest.Pairs[y].String() != key {
|
||||
continue
|
||||
}
|
||||
if getOrdersRequest.Side == "ANY" {
|
||||
if getOrdersRequest.Side == order.AnySide {
|
||||
finalResp = append(finalResp, resp)
|
||||
continue
|
||||
}
|
||||
@@ -791,21 +763,7 @@ func (l *Lbank) GetOrderHistory(ctx context.Context, getOrdersRequest *order.Get
|
||||
} else {
|
||||
resp.Side = order.Sell
|
||||
}
|
||||
z := tempResp.Orders[x].Status
|
||||
switch {
|
||||
case z == -1:
|
||||
resp.Status = "cancelled"
|
||||
case z == 1:
|
||||
resp.Status = "on trading"
|
||||
case z == 2:
|
||||
resp.Status = "filled partially"
|
||||
case z == 3:
|
||||
resp.Status = "Filled totally"
|
||||
case z == 4:
|
||||
resp.Status = "Cancelling"
|
||||
default:
|
||||
resp.Status = "Invalid Order Status"
|
||||
}
|
||||
resp.Status = l.GetStatus(tempResp.Orders[x].Status)
|
||||
resp.Price = tempResp.Orders[x].Price
|
||||
resp.AverageExecutedPrice = tempResp.Orders[x].AvgPrice
|
||||
resp.Amount = tempResp.Orders[x].Amount
|
||||
@@ -1028,3 +986,28 @@ func (l *Lbank) GetHistoricCandlesExtended(ctx context.Context, pair currency.Pa
|
||||
ret.SortCandlesByTimestamp(false)
|
||||
return ret, nil
|
||||
}
|
||||
|
||||
// GetStatus returns the order.Status from the int representation.
|
||||
func (l *Lbank) GetStatus(status int64) order.Status {
|
||||
var oStatus order.Status
|
||||
switch status {
|
||||
case -1:
|
||||
// "cancelled"
|
||||
oStatus = order.Cancelled
|
||||
case 0:
|
||||
// "on trading"
|
||||
oStatus = order.Active
|
||||
case 1:
|
||||
// "filled partially"
|
||||
oStatus = order.PartiallyFilled
|
||||
case 2:
|
||||
// "filled totally"
|
||||
oStatus = order.Filled
|
||||
case 4:
|
||||
// "Cancelling"
|
||||
oStatus = order.Cancelling
|
||||
default:
|
||||
log.Errorf(log.Global, "%s Unhandled Order Status '%v'", l.GetName(), status)
|
||||
}
|
||||
return oStatus
|
||||
}
|
||||
|
||||
@@ -211,7 +211,7 @@ type DashBoardInfo struct {
|
||||
FeeBTC float64 `json:"fee_btc,string"`
|
||||
ExchangeRateUpdatedAt string `json:"exchange_rate_updated_at"`
|
||||
Advertisement struct {
|
||||
ID int `json:"id"`
|
||||
ID int64 `json:"id"`
|
||||
TradeType string `json:"trade_type"`
|
||||
Advertiser struct {
|
||||
Username string `json:"username"`
|
||||
|
||||
@@ -562,7 +562,8 @@ func (l *LocalBitcoins) GetActiveOrders(ctx context.Context, getOrdersRequest *o
|
||||
|
||||
orders := make([]order.Detail, len(resp))
|
||||
for i := range resp {
|
||||
orderDate, err := time.Parse(time.RFC3339, resp[i].Data.CreatedAt)
|
||||
var orderDate time.Time
|
||||
orderDate, err = time.Parse(time.RFC3339, resp[i].Data.CreatedAt)
|
||||
if err != nil {
|
||||
log.Errorf(log.ExchangeSys, "Exchange %v Func %v Order %v Could not parse date to unix with value of %v",
|
||||
l.Name,
|
||||
@@ -579,7 +580,7 @@ func (l *LocalBitcoins) GetActiveOrders(ctx context.Context, getOrdersRequest *o
|
||||
orders[i] = order.Detail{
|
||||
Amount: resp[i].Data.AmountBTC,
|
||||
Price: resp[i].Data.Amount,
|
||||
ID: strconv.FormatInt(int64(resp[i].Data.Advertisement.ID), 10),
|
||||
ID: strconv.FormatInt(resp[i].Data.Advertisement.ID, 10),
|
||||
Date: orderDate,
|
||||
Fee: resp[i].Data.FeeBTC,
|
||||
Side: side,
|
||||
@@ -590,10 +591,12 @@ func (l *LocalBitcoins) GetActiveOrders(ctx context.Context, getOrdersRequest *o
|
||||
}
|
||||
}
|
||||
|
||||
order.FilterOrdersByTimeRange(&orders, getOrdersRequest.StartTime,
|
||||
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
|
||||
}
|
||||
|
||||
@@ -630,7 +633,8 @@ func (l *LocalBitcoins) GetOrderHistory(ctx context.Context, getOrdersRequest *o
|
||||
|
||||
orders := make([]order.Detail, len(allTrades))
|
||||
for i := range allTrades {
|
||||
orderDate, err := time.Parse(time.RFC3339, allTrades[i].Data.CreatedAt)
|
||||
var orderDate time.Time
|
||||
orderDate, err = time.Parse(time.RFC3339, allTrades[i].Data.CreatedAt)
|
||||
if err != nil {
|
||||
log.Errorf(log.ExchangeSys,
|
||||
"Exchange %v Func %v Order %v Could not parse date to unix with value of %v",
|
||||
@@ -661,7 +665,8 @@ func (l *LocalBitcoins) GetOrderHistory(ctx context.Context, getOrdersRequest *o
|
||||
status = "Closed"
|
||||
}
|
||||
|
||||
orderStatus, err := order.StringToOrderStatus(status)
|
||||
var orderStatus order.Status
|
||||
orderStatus, err = order.StringToOrderStatus(status)
|
||||
if err != nil {
|
||||
log.Errorf(log.ExchangeSys, "%s %v", l.Name, err)
|
||||
}
|
||||
@@ -669,7 +674,7 @@ func (l *LocalBitcoins) GetOrderHistory(ctx context.Context, getOrdersRequest *o
|
||||
orders[i] = order.Detail{
|
||||
Amount: allTrades[i].Data.AmountBTC,
|
||||
Price: allTrades[i].Data.Amount,
|
||||
ID: strconv.FormatInt(int64(allTrades[i].Data.Advertisement.ID), 10),
|
||||
ID: strconv.FormatInt(allTrades[i].Data.Advertisement.ID, 10),
|
||||
Date: orderDate,
|
||||
Fee: allTrades[i].Data.FeeBTC,
|
||||
Side: side,
|
||||
@@ -681,8 +686,11 @@ func (l *LocalBitcoins) GetOrderHistory(ctx context.Context, getOrdersRequest *o
|
||||
}
|
||||
}
|
||||
|
||||
order.FilterOrdersByTimeRange(&orders, getOrdersRequest.StartTime,
|
||||
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
|
||||
|
||||
@@ -420,6 +420,11 @@ func (o *OKGroup) GetOrderInfo(ctx context.Context, orderID string, pair currenc
|
||||
if err != nil {
|
||||
log.Errorf(log.ExchangeSys, "%s %v", o.Name, err)
|
||||
}
|
||||
|
||||
side, err := order.StringToOrderSide(mOrder.Side)
|
||||
if err != nil {
|
||||
log.Errorf(log.ExchangeSys, "%s %v", o.Name, err)
|
||||
}
|
||||
resp = order.Detail{
|
||||
Amount: mOrder.Size,
|
||||
Pair: p,
|
||||
@@ -427,7 +432,7 @@ func (o *OKGroup) GetOrderInfo(ctx context.Context, orderID string, pair currenc
|
||||
Date: mOrder.Timestamp,
|
||||
ExecutedAmount: mOrder.FilledSize,
|
||||
Status: status,
|
||||
Side: order.Side(mOrder.Side),
|
||||
Side: side,
|
||||
}
|
||||
return resp, nil
|
||||
}
|
||||
@@ -523,14 +528,24 @@ func (o *OKGroup) GetActiveOrders(ctx context.Context, req *order.GetOrdersReque
|
||||
if err != nil {
|
||||
log.Errorf(log.ExchangeSys, "%s %v", o.Name, err)
|
||||
}
|
||||
var side order.Side
|
||||
side, err = order.StringToOrderSide(spotOpenOrders[i].Side)
|
||||
if err != nil {
|
||||
log.Errorf(log.ExchangeSys, "%s %v", o.Name, err)
|
||||
}
|
||||
var orderType order.Type
|
||||
orderType, err = order.StringToOrderType(spotOpenOrders[i].Type)
|
||||
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,
|
||||
Amount: spotOpenOrders[i].Size,
|
||||
Pair: req.Pairs[x],
|
||||
Exchange: o.Name,
|
||||
Side: order.Side(spotOpenOrders[i].Side),
|
||||
Type: order.Type(spotOpenOrders[i].Type),
|
||||
Side: side,
|
||||
Type: orderType,
|
||||
ExecutedAmount: spotOpenOrders[i].FilledSize,
|
||||
Date: spotOpenOrders[i].Timestamp,
|
||||
Status: status,
|
||||
@@ -569,6 +584,16 @@ func (o *OKGroup) GetOrderHistory(ctx context.Context, req *order.GetOrdersReque
|
||||
if err != nil {
|
||||
log.Errorf(log.ExchangeSys, "%s %v", o.Name, err)
|
||||
}
|
||||
var side order.Side
|
||||
side, err = order.StringToOrderSide(spotOrders[i].Side)
|
||||
if err != nil {
|
||||
log.Errorf(log.ExchangeSys, "%s %v", o.Name, err)
|
||||
}
|
||||
var orderType order.Type
|
||||
orderType, err = order.StringToOrderType(spotOrders[i].Type)
|
||||
if err != nil {
|
||||
log.Errorf(log.ExchangeSys, "%s %v", o.Name, err)
|
||||
}
|
||||
detail := order.Detail{
|
||||
ID: spotOrders[i].OrderID,
|
||||
Price: spotOrders[i].Price,
|
||||
@@ -578,8 +603,8 @@ func (o *OKGroup) GetOrderHistory(ctx context.Context, req *order.GetOrdersReque
|
||||
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),
|
||||
Side: side,
|
||||
Type: orderType,
|
||||
Date: spotOrders[i].Timestamp,
|
||||
Status: status,
|
||||
}
|
||||
|
||||
@@ -422,7 +422,7 @@ func (p *PositionTracker) TrackNewOrder(d *Detail) error {
|
||||
if p.asset != d.AssetType {
|
||||
return fmt.Errorf("%w asset '%v' received: '%v'", errOrderNotEqualToTracker, d.AssetType, p.asset)
|
||||
}
|
||||
if d.Side == "" {
|
||||
if d.Side == UnknownSide {
|
||||
return ErrSideIsInvalid
|
||||
}
|
||||
if d.ID == "" {
|
||||
@@ -473,7 +473,7 @@ func (p *PositionTracker) TrackNewOrder(d *Detail) error {
|
||||
longSide = longSide.Add(decimal.NewFromFloat(p.longPositions[i].Amount))
|
||||
}
|
||||
|
||||
if p.currentDirection == "" {
|
||||
if p.currentDirection == UnknownSide {
|
||||
p.currentDirection = d.Side
|
||||
}
|
||||
|
||||
|
||||
@@ -8,6 +8,7 @@ import (
|
||||
"time"
|
||||
|
||||
"github.com/gofrs/uuid"
|
||||
"github.com/thrasher-corp/gocryptotrader/common"
|
||||
"github.com/thrasher-corp/gocryptotrader/currency"
|
||||
"github.com/thrasher-corp/gocryptotrader/exchanges/asset"
|
||||
"github.com/thrasher-corp/gocryptotrader/exchanges/validate"
|
||||
@@ -16,6 +17,7 @@ import (
|
||||
var errValidationCheckFailed = errors.New("validation check failed")
|
||||
|
||||
func TestValidate(t *testing.T) {
|
||||
t.Parallel()
|
||||
testPair := currency.NewPair(currency.BTC, currency.LTC)
|
||||
tester := []struct {
|
||||
ExpectedErr error
|
||||
@@ -115,7 +117,7 @@ func TestValidate(t *testing.T) {
|
||||
for x := range tester {
|
||||
err := tester[x].Submit.Validate(tester[x].ValidOpts)
|
||||
if !errors.Is(err, tester[x].ExpectedErr) {
|
||||
t.Errorf("Unexpected result. Got: %v, want: %v", err, tester[x].ExpectedErr)
|
||||
t.Fatalf("Unexpected result. %d Got: %v, want: %v", x+1, err, tester[x].ExpectedErr)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -140,17 +142,16 @@ func TestOrderSides(t *testing.T) {
|
||||
func TestOrderTypes(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
var ot Type = "Mo'Money"
|
||||
|
||||
if ot.String() != "Mo'Money" {
|
||||
var ot Type
|
||||
if ot.String() != "UNKNOWN" {
|
||||
t.Errorf("unexpected string %s", ot.String())
|
||||
}
|
||||
|
||||
if ot.Lower() != "mo'money" {
|
||||
if ot.Lower() != "unknown" {
|
||||
t.Errorf("unexpected string %s", ot.Lower())
|
||||
}
|
||||
|
||||
if ot.Title() != "Mo'Money" {
|
||||
if ot.Title() != "Unknown" {
|
||||
t.Errorf("unexpected string %s", ot.Title())
|
||||
}
|
||||
}
|
||||
@@ -267,6 +268,27 @@ func TestFilterOrdersByType(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
var filterOrdersByTypeBenchmark = &[]Detail{
|
||||
{Type: Limit},
|
||||
{Type: Limit},
|
||||
{Type: Limit},
|
||||
{Type: Limit},
|
||||
{Type: Limit},
|
||||
{Type: Limit},
|
||||
{Type: Limit},
|
||||
{Type: Limit},
|
||||
{Type: Limit},
|
||||
{Type: Limit},
|
||||
}
|
||||
|
||||
// 392455 3226 ns/op 15840 B/op 5 allocs/op // PREV
|
||||
// 9486490 109.5 ns/op 0 B/op 0 allocs/op // CURRENT
|
||||
func BenchmarkFilterOrdersByType(b *testing.B) {
|
||||
for x := 0; x < b.N; x++ {
|
||||
FilterOrdersByType(filterOrdersByTypeBenchmark, Limit)
|
||||
}
|
||||
}
|
||||
|
||||
func TestFilterOrdersBySide(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
@@ -296,6 +318,27 @@ func TestFilterOrdersBySide(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
var filterOrdersBySideBenchmark = &[]Detail{
|
||||
{Side: Ask},
|
||||
{Side: Ask},
|
||||
{Side: Ask},
|
||||
{Side: Ask},
|
||||
{Side: Ask},
|
||||
{Side: Ask},
|
||||
{Side: Ask},
|
||||
{Side: Ask},
|
||||
{Side: Ask},
|
||||
{Side: Ask},
|
||||
}
|
||||
|
||||
// 372594 3049 ns/op 15840 B/op 5 allocs/op // PREV
|
||||
// 7412187 148.8 ns/op 0 B/op 0 allocs/op // CURRENT
|
||||
func BenchmarkFilterOrdersBySide(b *testing.B) {
|
||||
for x := 0; x < b.N; x++ {
|
||||
FilterOrdersBySide(filterOrdersBySideBenchmark, Ask)
|
||||
}
|
||||
}
|
||||
|
||||
func TestFilterOrdersByTimeRange(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
@@ -311,34 +354,78 @@ func TestFilterOrdersByTimeRange(t *testing.T) {
|
||||
},
|
||||
}
|
||||
|
||||
FilterOrdersByTimeRange(&orders, time.Unix(0, 0), time.Unix(0, 0))
|
||||
err := FilterOrdersByTimeRange(&orders, time.Unix(0, 0), time.Unix(0, 0))
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if len(orders) != 3 {
|
||||
t.Errorf("Orders failed to be filtered. Expected %v, received %v", 3, len(orders))
|
||||
}
|
||||
|
||||
FilterOrdersByTimeRange(&orders, time.Unix(100, 0), time.Unix(111, 0))
|
||||
err = FilterOrdersByTimeRange(&orders, time.Unix(100, 0), time.Unix(111, 0))
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if len(orders) != 3 {
|
||||
t.Errorf("Orders failed to be filtered. Expected %v, received %v", 3, len(orders))
|
||||
}
|
||||
|
||||
FilterOrdersByTimeRange(&orders, time.Unix(101, 0), time.Unix(111, 0))
|
||||
err = FilterOrdersByTimeRange(&orders, time.Unix(101, 0), time.Unix(111, 0))
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if len(orders) != 2 {
|
||||
t.Errorf("Orders failed to be filtered. Expected %v, received %v", 2, len(orders))
|
||||
}
|
||||
|
||||
FilterOrdersByTimeRange(&orders, time.Unix(200, 0), time.Unix(300, 0))
|
||||
err = FilterOrdersByTimeRange(&orders, time.Unix(200, 0), time.Unix(300, 0))
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if len(orders) != 0 {
|
||||
t.Errorf("Orders failed to be filtered. Expected %v, received %v", 0, len(orders))
|
||||
}
|
||||
orders = append(orders, Detail{})
|
||||
// test for event no timestamp is set on an order, best to include it
|
||||
FilterOrdersByTimeRange(&orders, time.Unix(200, 0), time.Unix(300, 0))
|
||||
err = FilterOrdersByTimeRange(&orders, time.Unix(200, 0), time.Unix(300, 0))
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if len(orders) != 1 {
|
||||
t.Errorf("Orders failed to be filtered. Expected %v, received %v", 1, len(orders))
|
||||
}
|
||||
|
||||
err = FilterOrdersByTimeRange(&orders, time.Unix(300, 0), time.Unix(50, 0))
|
||||
if !errors.Is(err, common.ErrStartAfterEnd) {
|
||||
t.Fatalf("received: '%v' but expected: '%v'", err, common.ErrStartAfterEnd)
|
||||
}
|
||||
}
|
||||
|
||||
func TestFilterOrdersByCurrencies(t *testing.T) {
|
||||
var filterOrdersByTimeRangeBenchmark = &[]Detail{
|
||||
{Date: time.Unix(100, 0)},
|
||||
{Date: time.Unix(100, 0)},
|
||||
{Date: time.Unix(100, 0)},
|
||||
{Date: time.Unix(100, 0)},
|
||||
{Date: time.Unix(100, 0)},
|
||||
{Date: time.Unix(100, 0)},
|
||||
{Date: time.Unix(100, 0)},
|
||||
{Date: time.Unix(100, 0)},
|
||||
{Date: time.Unix(100, 0)},
|
||||
{Date: time.Unix(100, 0)},
|
||||
}
|
||||
|
||||
// 390822 3335 ns/op 15840 B/op 5 allocs/op // PREV
|
||||
// 6201034 172.1 ns/op 0 B/op 0 allocs/op // CURRENT
|
||||
func BenchmarkFilterOrdersByTimeRange(b *testing.B) {
|
||||
for x := 0; x < b.N; x++ {
|
||||
err := FilterOrdersByTimeRange(filterOrdersByTimeRangeBenchmark, time.Unix(50, 0), time.Unix(150, 0))
|
||||
if err != nil {
|
||||
b.Fatal(err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestFilterOrdersByPairs(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
var orders = []Detail{
|
||||
@@ -356,42 +443,64 @@ func TestFilterOrdersByCurrencies(t *testing.T) {
|
||||
currencies := []currency.Pair{currency.NewPair(currency.BTC, currency.USD),
|
||||
currency.NewPair(currency.LTC, currency.EUR),
|
||||
currency.NewPair(currency.DOGE, currency.RUB)}
|
||||
FilterOrdersByCurrencies(&orders, currencies)
|
||||
FilterOrdersByPairs(&orders, currencies)
|
||||
if len(orders) != 3 {
|
||||
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)}
|
||||
FilterOrdersByCurrencies(&orders, currencies)
|
||||
FilterOrdersByPairs(&orders, currencies)
|
||||
if len(orders) != 2 {
|
||||
t.Errorf("Orders failed to be filtered. Expected %v, received %v", 2, len(orders))
|
||||
}
|
||||
|
||||
currencies = []currency.Pair{currency.NewPair(currency.BTC, currency.USD)}
|
||||
FilterOrdersByCurrencies(&orders, currencies)
|
||||
FilterOrdersByPairs(&orders, currencies)
|
||||
if len(orders) != 1 {
|
||||
t.Errorf("Orders failed to be filtered. Expected %v, received %v", 1, len(orders))
|
||||
}
|
||||
|
||||
currencies = []currency.Pair{currency.NewPair(currency.USD, currency.BTC)}
|
||||
FilterOrdersByCurrencies(&orders, currencies)
|
||||
FilterOrdersByPairs(&orders, currencies)
|
||||
if len(orders) != 1 {
|
||||
t.Errorf("Reverse Orders failed to be filtered. Expected %v, received %v", 1, len(orders))
|
||||
}
|
||||
|
||||
currencies = []currency.Pair{}
|
||||
FilterOrdersByCurrencies(&orders, currencies)
|
||||
FilterOrdersByPairs(&orders, currencies)
|
||||
if len(orders) != 1 {
|
||||
t.Errorf("Orders failed to be filtered. Expected %v, received %v", 1, len(orders))
|
||||
}
|
||||
currencies = append(currencies, currency.EMPTYPAIR)
|
||||
FilterOrdersByCurrencies(&orders, currencies)
|
||||
FilterOrdersByPairs(&orders, currencies)
|
||||
if len(orders) != 1 {
|
||||
t.Errorf("Orders failed to be filtered. Expected %v, received %v", 1, len(orders))
|
||||
}
|
||||
}
|
||||
|
||||
var filterOrdersByPairsBenchmark = &[]Detail{
|
||||
{Pair: currency.NewPair(currency.BTC, currency.USD)},
|
||||
{Pair: currency.NewPair(currency.BTC, currency.USD)},
|
||||
{Pair: currency.NewPair(currency.BTC, currency.USD)},
|
||||
{Pair: currency.NewPair(currency.BTC, currency.USD)},
|
||||
{Pair: currency.NewPair(currency.BTC, currency.USD)},
|
||||
{Pair: currency.NewPair(currency.BTC, currency.USD)},
|
||||
{Pair: currency.NewPair(currency.BTC, currency.USD)},
|
||||
{Pair: currency.NewPair(currency.BTC, currency.USD)},
|
||||
{Pair: currency.NewPair(currency.BTC, currency.USD)},
|
||||
{Pair: currency.NewPair(currency.BTC, currency.USD)},
|
||||
}
|
||||
|
||||
// 400032 2977 ns/op 15840 B/op 5 allocs/op // PREV
|
||||
// 6977242 172.8 ns/op 0 B/op 0 allocs/op // CURRENT
|
||||
func BenchmarkFilterOrdersByPairs(b *testing.B) {
|
||||
pairs := []currency.Pair{currency.NewPair(currency.BTC, currency.USD)}
|
||||
for x := 0; x < b.N; x++ {
|
||||
FilterOrdersByPairs(filterOrdersByPairsBenchmark, pairs)
|
||||
}
|
||||
}
|
||||
|
||||
func TestSortOrdersByPrice(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
@@ -546,41 +655,39 @@ func TestSortOrdersByOrderType(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
var stringsToOrderSide = []struct {
|
||||
in string
|
||||
out Side
|
||||
err error
|
||||
}{
|
||||
{"buy", Buy, nil},
|
||||
{"BUY", Buy, nil},
|
||||
{"bUy", Buy, nil},
|
||||
{"sell", Sell, nil},
|
||||
{"SELL", Sell, nil},
|
||||
{"sElL", Sell, nil},
|
||||
{"bid", Bid, nil},
|
||||
{"BID", Bid, nil},
|
||||
{"bId", Bid, nil},
|
||||
{"ask", Ask, nil},
|
||||
{"ASK", Ask, nil},
|
||||
{"aSk", Ask, nil},
|
||||
{"lOnG", Long, nil},
|
||||
{"ShoRt", Short, nil},
|
||||
{"any", AnySide, nil},
|
||||
{"ANY", AnySide, nil},
|
||||
{"aNy", AnySide, nil},
|
||||
{"woahMan", Buy, errors.New("WOAHMAN not recognised as order side")},
|
||||
}
|
||||
|
||||
func TestStringToOrderSide(t *testing.T) {
|
||||
for i := range stringsToOrderSide {
|
||||
testData := &stringsToOrderSide[i]
|
||||
cases := []struct {
|
||||
in string
|
||||
out Side
|
||||
err error
|
||||
}{
|
||||
{"buy", Buy, nil},
|
||||
{"BUY", Buy, nil},
|
||||
{"bUy", Buy, nil},
|
||||
{"sell", Sell, nil},
|
||||
{"SELL", Sell, nil},
|
||||
{"sElL", Sell, nil},
|
||||
{"bid", Bid, nil},
|
||||
{"BID", Bid, nil},
|
||||
{"bId", Bid, nil},
|
||||
{"ask", Ask, nil},
|
||||
{"ASK", Ask, nil},
|
||||
{"aSk", Ask, nil},
|
||||
{"lOnG", Long, nil},
|
||||
{"ShoRt", Short, nil},
|
||||
{"any", AnySide, nil},
|
||||
{"ANY", AnySide, nil},
|
||||
{"aNy", AnySide, nil},
|
||||
{"woahMan", UnknownSide, errUnrecognisedOrderSide},
|
||||
}
|
||||
for i := range cases {
|
||||
testData := &cases[i]
|
||||
t.Run(testData.in, func(t *testing.T) {
|
||||
out, err := StringToOrderSide(testData.in)
|
||||
if err != nil {
|
||||
if err.Error() != testData.err.Error() {
|
||||
t.Error("Unexpected error", err)
|
||||
}
|
||||
} else if out != testData.out {
|
||||
if !errors.Is(err, testData.err) {
|
||||
t.Fatalf("received: '%v' but expected: '%v'", err, testData.err)
|
||||
}
|
||||
if out != testData.out {
|
||||
t.Errorf("Unexpected output %v. Expected %v", out, testData.out)
|
||||
}
|
||||
})
|
||||
@@ -597,53 +704,51 @@ func BenchmarkStringToOrderSide(b *testing.B) {
|
||||
}
|
||||
}
|
||||
|
||||
var stringsToOrderType = []struct {
|
||||
in string
|
||||
out Type
|
||||
err error
|
||||
}{
|
||||
{"limit", Limit, nil},
|
||||
{"LIMIT", Limit, nil},
|
||||
{"lImIt", Limit, nil},
|
||||
{"market", Market, nil},
|
||||
{"MARKET", Market, nil},
|
||||
{"mArKeT", Market, nil},
|
||||
{"immediate_or_cancel", ImmediateOrCancel, nil},
|
||||
{"IMMEDIATE_OR_CANCEL", ImmediateOrCancel, nil},
|
||||
{"iMmEdIaTe_Or_CaNcEl", ImmediateOrCancel, nil},
|
||||
{"iMmEdIaTe Or CaNcEl", ImmediateOrCancel, nil},
|
||||
{"stop", Stop, nil},
|
||||
{"STOP", Stop, nil},
|
||||
{"sToP", Stop, nil},
|
||||
{"sToP LiMit", StopLimit, nil},
|
||||
{"ExchangE sToP Limit", StopLimit, nil},
|
||||
{"trailing_stop", TrailingStop, nil},
|
||||
{"TRAILING_STOP", TrailingStop, nil},
|
||||
{"tRaIlInG_sToP", TrailingStop, nil},
|
||||
{"tRaIlInG sToP", TrailingStop, nil},
|
||||
{"fOk", FillOrKill, nil},
|
||||
{"exchange fOk", FillOrKill, nil},
|
||||
{"ios", IOS, nil},
|
||||
{"post_ONly", PostOnly, nil},
|
||||
{"any", AnyType, nil},
|
||||
{"ANY", AnyType, nil},
|
||||
{"aNy", AnyType, nil},
|
||||
{"trigger", Trigger, nil},
|
||||
{"TRIGGER", Trigger, nil},
|
||||
{"tRiGgEr", Trigger, nil},
|
||||
{"woahMan", UnknownType, errors.New("WOAHMAN not recognised as order type")},
|
||||
}
|
||||
|
||||
func TestStringToOrderType(t *testing.T) {
|
||||
for i := range stringsToOrderType {
|
||||
testData := &stringsToOrderType[i]
|
||||
cases := []struct {
|
||||
in string
|
||||
out Type
|
||||
err error
|
||||
}{
|
||||
{"limit", Limit, nil},
|
||||
{"LIMIT", Limit, nil},
|
||||
{"lImIt", Limit, nil},
|
||||
{"market", Market, nil},
|
||||
{"MARKET", Market, nil},
|
||||
{"mArKeT", Market, nil},
|
||||
{"immediate_or_cancel", ImmediateOrCancel, nil},
|
||||
{"IMMEDIATE_OR_CANCEL", ImmediateOrCancel, nil},
|
||||
{"iMmEdIaTe_Or_CaNcEl", ImmediateOrCancel, nil},
|
||||
{"iMmEdIaTe Or CaNcEl", ImmediateOrCancel, nil},
|
||||
{"stop", Stop, nil},
|
||||
{"STOP", Stop, nil},
|
||||
{"sToP", Stop, nil},
|
||||
{"sToP LiMit", StopLimit, nil},
|
||||
{"ExchangE sToP Limit", StopLimit, nil},
|
||||
{"trailing_stop", TrailingStop, nil},
|
||||
{"TRAILING_STOP", TrailingStop, nil},
|
||||
{"tRaIlInG_sToP", TrailingStop, nil},
|
||||
{"tRaIlInG sToP", TrailingStop, nil},
|
||||
{"fOk", FillOrKill, nil},
|
||||
{"exchange fOk", FillOrKill, nil},
|
||||
{"ios", IOS, nil},
|
||||
{"post_ONly", PostOnly, nil},
|
||||
{"any", AnyType, nil},
|
||||
{"ANY", AnyType, nil},
|
||||
{"aNy", AnyType, nil},
|
||||
{"trigger", Trigger, nil},
|
||||
{"TRIGGER", Trigger, nil},
|
||||
{"tRiGgEr", Trigger, nil},
|
||||
{"woahMan", UnknownType, errUnrecognisedOrderType},
|
||||
}
|
||||
for i := range cases {
|
||||
testData := &cases[i]
|
||||
t.Run(testData.in, func(t *testing.T) {
|
||||
out, err := StringToOrderType(testData.in)
|
||||
if err != nil {
|
||||
if err.Error() != testData.err.Error() {
|
||||
t.Error("Unexpected error", err)
|
||||
}
|
||||
} else if out != testData.out {
|
||||
if !errors.Is(err, testData.err) {
|
||||
t.Fatalf("received: '%v' but expected: '%v'", err, testData.err)
|
||||
}
|
||||
if out != testData.out {
|
||||
t.Errorf("Unexpected output %v. Expected %v", out, testData.out)
|
||||
}
|
||||
})
|
||||
@@ -705,7 +810,8 @@ var stringsToOrderStatus = []struct {
|
||||
{"partially canceLLed", PartiallyCancelled, nil},
|
||||
{"opeN", Open, nil},
|
||||
{"cLosEd", Closed, nil},
|
||||
{"woahMan", UnknownStatus, errors.New("WOAHMAN not recognised as order status")},
|
||||
{"cancellinG", Cancelling, nil},
|
||||
{"woahMan", UnknownStatus, errUnrecognisedOrderStatus},
|
||||
}
|
||||
|
||||
func TestStringToOrderStatus(t *testing.T) {
|
||||
@@ -713,11 +819,10 @@ func TestStringToOrderStatus(t *testing.T) {
|
||||
testData := &stringsToOrderStatus[i]
|
||||
t.Run(testData.in, func(t *testing.T) {
|
||||
out, err := StringToOrderStatus(testData.in)
|
||||
if err != nil {
|
||||
if err.Error() != testData.err.Error() {
|
||||
t.Error("Unexpected error", err)
|
||||
}
|
||||
} else if out != testData.out {
|
||||
if !errors.Is(err, testData.err) {
|
||||
t.Fatalf("received: '%v' but expected: '%v'", err, testData.err)
|
||||
}
|
||||
if out != testData.out {
|
||||
t.Errorf("Unexpected output %v. Expected %v", out, testData.out)
|
||||
}
|
||||
})
|
||||
@@ -736,34 +841,7 @@ func BenchmarkStringToOrderStatus(b *testing.B) {
|
||||
|
||||
func TestUpdateOrderFromModify(t *testing.T) {
|
||||
var leet = "1337"
|
||||
od := Detail{
|
||||
ImmediateOrCancel: false,
|
||||
HiddenOrder: false,
|
||||
FillOrKill: false,
|
||||
PostOnly: false,
|
||||
Leverage: 0,
|
||||
Price: 0,
|
||||
Amount: 0,
|
||||
LimitPriceUpper: 0,
|
||||
LimitPriceLower: 0,
|
||||
TriggerPrice: 0,
|
||||
QuoteAmount: 0,
|
||||
ExecutedAmount: 0,
|
||||
RemainingAmount: 0,
|
||||
Fee: 0,
|
||||
Exchange: "",
|
||||
ID: "1",
|
||||
AccountID: "",
|
||||
ClientID: "",
|
||||
WalletAddress: "",
|
||||
Type: "",
|
||||
Side: "",
|
||||
Status: "",
|
||||
Date: time.Time{},
|
||||
LastUpdated: time.Time{},
|
||||
Pair: currency.EMPTYPAIR,
|
||||
Trades: nil,
|
||||
}
|
||||
od := Detail{ID: "1"}
|
||||
updated := time.Now()
|
||||
|
||||
pair, err := currency.NewPairFromString("BTCUSD")
|
||||
@@ -792,9 +870,9 @@ func TestUpdateOrderFromModify(t *testing.T) {
|
||||
AccountID: "1",
|
||||
ClientID: "1",
|
||||
WalletAddress: "1",
|
||||
Type: "1",
|
||||
Side: "1",
|
||||
Status: "1",
|
||||
Type: 1,
|
||||
Side: 1,
|
||||
Status: 1,
|
||||
AssetType: 1,
|
||||
LastUpdated: updated,
|
||||
Pair: pair,
|
||||
@@ -859,13 +937,13 @@ func TestUpdateOrderFromModify(t *testing.T) {
|
||||
if od.WalletAddress != "1" {
|
||||
t.Error("Failed to update")
|
||||
}
|
||||
if od.Type != "1" {
|
||||
if od.Type != 1 {
|
||||
t.Error("Failed to update")
|
||||
}
|
||||
if od.Side != "1" {
|
||||
if od.Side != 1 {
|
||||
t.Error("Failed to update")
|
||||
}
|
||||
if od.Status != "1" {
|
||||
if od.Status != 1 {
|
||||
t.Error("Failed to update")
|
||||
}
|
||||
if od.AssetType != 1 {
|
||||
@@ -927,34 +1005,7 @@ func TestUpdateOrderFromModify(t *testing.T) {
|
||||
|
||||
func TestUpdateOrderFromDetail(t *testing.T) {
|
||||
var leet = "1337"
|
||||
od := Detail{
|
||||
ImmediateOrCancel: false,
|
||||
HiddenOrder: false,
|
||||
FillOrKill: false,
|
||||
PostOnly: false,
|
||||
Leverage: 0,
|
||||
Price: 0,
|
||||
Amount: 0,
|
||||
LimitPriceUpper: 0,
|
||||
LimitPriceLower: 0,
|
||||
TriggerPrice: 0,
|
||||
QuoteAmount: 0,
|
||||
ExecutedAmount: 0,
|
||||
RemainingAmount: 0,
|
||||
Fee: 0,
|
||||
Exchange: "test",
|
||||
ID: "",
|
||||
AccountID: "",
|
||||
ClientID: "",
|
||||
WalletAddress: "",
|
||||
Type: "",
|
||||
Side: "",
|
||||
Status: "",
|
||||
Date: time.Time{},
|
||||
LastUpdated: time.Time{},
|
||||
Pair: currency.EMPTYPAIR,
|
||||
Trades: nil,
|
||||
}
|
||||
od := Detail{Exchange: "test"}
|
||||
updated := time.Now()
|
||||
|
||||
pair, err := currency.NewPairFromString("BTCUSD")
|
||||
@@ -983,9 +1034,9 @@ func TestUpdateOrderFromDetail(t *testing.T) {
|
||||
AccountID: "1",
|
||||
ClientID: "1",
|
||||
WalletAddress: "1",
|
||||
Type: "1",
|
||||
Side: "1",
|
||||
Status: "1",
|
||||
Type: 1,
|
||||
Side: 1,
|
||||
Status: 1,
|
||||
AssetType: 1,
|
||||
LastUpdated: updated,
|
||||
Pair: pair,
|
||||
@@ -1050,13 +1101,13 @@ func TestUpdateOrderFromDetail(t *testing.T) {
|
||||
if od.WalletAddress != "1" {
|
||||
t.Error("Failed to update")
|
||||
}
|
||||
if od.Type != "1" {
|
||||
if od.Type != 1 {
|
||||
t.Error("Failed to update")
|
||||
}
|
||||
if od.Side != "1" {
|
||||
if od.Side != 1 {
|
||||
t.Error("Failed to update")
|
||||
}
|
||||
if od.Status != "1" {
|
||||
if od.Status != 1 {
|
||||
t.Error("Failed to update")
|
||||
}
|
||||
if od.AssetType != 1 {
|
||||
@@ -1373,7 +1424,8 @@ func TestIsActive(t *testing.T) {
|
||||
o Detail
|
||||
expRes bool
|
||||
}{
|
||||
0: {Detail{Amount: 1.0, ExecutedAmount: 0.0, Status: AnyStatus}, true},
|
||||
// For now force inactive on any status
|
||||
0: {Detail{Amount: 1.0, ExecutedAmount: 0.0, Status: AnyStatus}, false},
|
||||
1: {Detail{Amount: 1.0, ExecutedAmount: 0.0, Status: New}, true},
|
||||
2: {Detail{Amount: 1.0, ExecutedAmount: 0.0, Status: Active}, true},
|
||||
3: {Detail{Amount: 1.0, ExecutedAmount: 0.0, Status: PartiallyCancelled}, false},
|
||||
@@ -1386,7 +1438,8 @@ func TestIsActive(t *testing.T) {
|
||||
10: {Detail{Amount: 1.0, ExecutedAmount: 0.0, Status: Rejected}, false},
|
||||
11: {Detail{Amount: 1.0, ExecutedAmount: 0.0, Status: Expired}, false},
|
||||
12: {Detail{Amount: 1.0, ExecutedAmount: 0.0, Status: Hidden}, true},
|
||||
13: {Detail{Amount: 1.0, ExecutedAmount: 0.0, Status: UnknownStatus}, true},
|
||||
// For now force inactive on unknown status
|
||||
13: {Detail{Amount: 1.0, ExecutedAmount: 0.0, Status: UnknownStatus}, false},
|
||||
14: {Detail{Amount: 1.0, ExecutedAmount: 0.0, Status: Open}, true},
|
||||
15: {Detail{Amount: 1.0, ExecutedAmount: 0.0, Status: AutoDeleverage}, true},
|
||||
16: {Detail{Amount: 1.0, ExecutedAmount: 0.0, Status: Closed}, false},
|
||||
@@ -1395,12 +1448,24 @@ func TestIsActive(t *testing.T) {
|
||||
// specific tests
|
||||
for num, tt := range statusTests {
|
||||
if tt.o.IsActive() != tt.expRes {
|
||||
t.Errorf("statusTests[%v] failed", num)
|
||||
t.Fatalf("statusTests[%v] failed", num)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestIsInctive(t *testing.T) {
|
||||
var activeBenchmark = Detail{Status: Pending, Amount: 1}
|
||||
|
||||
// 610732089 2.414 ns/op 0 B/op 0 allocs/op // PREV
|
||||
// 1000000000 1.188 ns/op 0 B/op 0 allocs/op // CURRENT
|
||||
func BenchmarkIsActive(b *testing.B) {
|
||||
for x := 0; x < b.N; x++ {
|
||||
if !activeBenchmark.IsActive() {
|
||||
b.Fatal("expected true")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestIsInactive(t *testing.T) {
|
||||
orders := map[int]Detail{
|
||||
0: {Amount: 0.0, Status: Active},
|
||||
1: {Amount: 1.0, ExecutedAmount: 0.9, Status: Active},
|
||||
@@ -1428,7 +1493,8 @@ func TestIsInctive(t *testing.T) {
|
||||
o Detail
|
||||
expRes bool
|
||||
}{
|
||||
0: {Detail{Amount: 1.0, ExecutedAmount: 0.0, Status: AnyStatus}, false},
|
||||
// For now force inactive on any status
|
||||
0: {Detail{Amount: 1.0, ExecutedAmount: 0.0, Status: AnyStatus}, true},
|
||||
1: {Detail{Amount: 1.0, ExecutedAmount: 0.0, Status: New}, false},
|
||||
2: {Detail{Amount: 1.0, ExecutedAmount: 0.0, Status: Active}, false},
|
||||
3: {Detail{Amount: 1.0, ExecutedAmount: 0.0, Status: PartiallyCancelled}, true},
|
||||
@@ -1441,7 +1507,8 @@ func TestIsInctive(t *testing.T) {
|
||||
10: {Detail{Amount: 1.0, ExecutedAmount: 0.0, Status: Rejected}, true},
|
||||
11: {Detail{Amount: 1.0, ExecutedAmount: 0.0, Status: Expired}, true},
|
||||
12: {Detail{Amount: 1.0, ExecutedAmount: 0.0, Status: Hidden}, false},
|
||||
13: {Detail{Amount: 1.0, ExecutedAmount: 0.0, Status: UnknownStatus}, false},
|
||||
// For now force inactive on unknown status
|
||||
13: {Detail{Amount: 1.0, ExecutedAmount: 0.0, Status: UnknownStatus}, true},
|
||||
14: {Detail{Amount: 1.0, ExecutedAmount: 0.0, Status: Open}, false},
|
||||
15: {Detail{Amount: 1.0, ExecutedAmount: 0.0, Status: AutoDeleverage}, false},
|
||||
16: {Detail{Amount: 1.0, ExecutedAmount: 0.0, Status: Closed}, true},
|
||||
@@ -1455,6 +1522,17 @@ func TestIsInctive(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
var inactiveBenchmark = Detail{Status: Closed, Amount: 1}
|
||||
|
||||
// 1000000000 1.043 ns/op 0 B/op 0 allocs/op // CURRENT
|
||||
func BenchmarkIsInactive(b *testing.B) {
|
||||
for x := 0; x < b.N; x++ {
|
||||
if !inactiveBenchmark.IsInactive() {
|
||||
b.Fatal("expected true")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestGenerateInternalOrderID(t *testing.T) {
|
||||
id, err := uuid.NewV4()
|
||||
if err != nil {
|
||||
|
||||
@@ -242,66 +242,73 @@ type GetOrdersRequest struct {
|
||||
}
|
||||
|
||||
// Status defines order status types
|
||||
type Status string
|
||||
type Status uint32
|
||||
|
||||
// All order status types
|
||||
const (
|
||||
AnyStatus Status = "ANY"
|
||||
New Status = "NEW"
|
||||
Active Status = "ACTIVE"
|
||||
PartiallyCancelled Status = "PARTIALLY_CANCELLED"
|
||||
PartiallyFilled Status = "PARTIALLY_FILLED"
|
||||
Filled Status = "FILLED"
|
||||
Cancelled Status = "CANCELLED"
|
||||
PendingCancel Status = "PENDING_CANCEL"
|
||||
InsufficientBalance Status = "INSUFFICIENT_BALANCE"
|
||||
MarketUnavailable Status = "MARKET_UNAVAILABLE"
|
||||
Rejected Status = "REJECTED"
|
||||
Expired Status = "EXPIRED"
|
||||
Hidden Status = "HIDDEN"
|
||||
UnknownStatus Status = "UNKNOWN"
|
||||
Open Status = "OPEN"
|
||||
AutoDeleverage Status = "ADL"
|
||||
Closed Status = "CLOSED"
|
||||
Pending Status = "PENDING"
|
||||
UnknownStatus Status = 0
|
||||
AnyStatus Status = 1 << iota
|
||||
New
|
||||
Active
|
||||
PartiallyCancelled
|
||||
PartiallyFilled
|
||||
Filled
|
||||
Cancelled
|
||||
PendingCancel
|
||||
InsufficientBalance
|
||||
MarketUnavailable
|
||||
Rejected
|
||||
Expired
|
||||
Hidden
|
||||
Open
|
||||
AutoDeleverage
|
||||
Closed
|
||||
Pending
|
||||
Cancelling
|
||||
)
|
||||
|
||||
// Type enforces a standard for order types across the code base
|
||||
type Type string
|
||||
type Type uint16
|
||||
|
||||
// Defined package order types
|
||||
const (
|
||||
AnyType Type = "ANY"
|
||||
Limit Type = "LIMIT"
|
||||
Market Type = "MARKET"
|
||||
PostOnly Type = "POST_ONLY"
|
||||
ImmediateOrCancel Type = "IMMEDIATE_OR_CANCEL"
|
||||
Stop Type = "STOP"
|
||||
StopLimit Type = "STOP LIMIT"
|
||||
StopMarket Type = "STOP MARKET"
|
||||
TakeProfit Type = "TAKE PROFIT"
|
||||
TakeProfitMarket Type = "TAKE PROFIT MARKET"
|
||||
TrailingStop Type = "TRAILING_STOP"
|
||||
FillOrKill Type = "FOK"
|
||||
IOS Type = "IOS"
|
||||
UnknownType Type = "UNKNOWN"
|
||||
Liquidation Type = "LIQUIDATION"
|
||||
Trigger Type = "TRIGGER"
|
||||
UnknownType Type = 0
|
||||
Limit Type = 1 << iota
|
||||
Market
|
||||
PostOnly
|
||||
ImmediateOrCancel
|
||||
Stop
|
||||
StopLimit
|
||||
StopMarket
|
||||
TakeProfit
|
||||
TakeProfitMarket
|
||||
TrailingStop
|
||||
FillOrKill
|
||||
IOS
|
||||
AnyType
|
||||
Liquidation
|
||||
Trigger
|
||||
)
|
||||
|
||||
// Side enforces a standard for order sides across the code base
|
||||
type Side string
|
||||
type Side uint16
|
||||
|
||||
// Order side types
|
||||
const (
|
||||
AnySide Side = "ANY"
|
||||
Buy Side = "BUY"
|
||||
Sell Side = "SELL"
|
||||
Bid Side = "BID"
|
||||
Ask Side = "ASK"
|
||||
UnknownSide Side = "UNKNOWN"
|
||||
Long Side = "LONG"
|
||||
Short Side = "SHORT"
|
||||
UnknownSide Side = 0
|
||||
Buy Side = 1 << iota
|
||||
Sell
|
||||
Bid
|
||||
Ask
|
||||
AnySide
|
||||
Long
|
||||
Short
|
||||
// Backtester signal types
|
||||
DoNothing
|
||||
TransferredFunds
|
||||
CouldNotBuy
|
||||
CouldNotSell
|
||||
MissingData
|
||||
)
|
||||
|
||||
// ByPrice used for sorting orders by price
|
||||
|
||||
@@ -14,7 +14,22 @@ import (
|
||||
"github.com/thrasher-corp/gocryptotrader/exchanges/validate"
|
||||
)
|
||||
|
||||
var errTimeInForceConflict = errors.New("multiple time in force options applied")
|
||||
const (
|
||||
orderSubmissionValidSides = Buy | Sell | Bid | Ask | Long | Short
|
||||
shortSide = Short | Sell | Ask
|
||||
longSide = Long | Buy | Bid
|
||||
inactiveStatuses = Filled | Cancelled | InsufficientBalance | MarketUnavailable | Rejected | PartiallyCancelled | Expired | Closed | AnyStatus | Cancelling
|
||||
activeStatuses = Active | Open | PartiallyFilled | New | PendingCancel | Hidden | AutoDeleverage | Pending
|
||||
bypassSideFilter = UnknownSide | AnySide
|
||||
bypassTypeFilter = UnknownType | AnyType
|
||||
)
|
||||
|
||||
var (
|
||||
errTimeInForceConflict = errors.New("multiple time in force options applied")
|
||||
errUnrecognisedOrderSide = errors.New("unrecognised order side")
|
||||
errUnrecognisedOrderType = errors.New("unrecognised order type")
|
||||
errUnrecognisedOrderStatus = errors.New("unrecognised order status")
|
||||
)
|
||||
|
||||
// Validate checks the supplied data and returns whether or not it's valid
|
||||
func (s *Submit) Validate(opt ...validate.Checker) error {
|
||||
@@ -30,10 +45,7 @@ func (s *Submit) Validate(opt ...validate.Checker) error {
|
||||
return ErrAssetNotSet
|
||||
}
|
||||
|
||||
if s.Side != Buy &&
|
||||
s.Side != Sell &&
|
||||
s.Side != Bid &&
|
||||
s.Side != Ask {
|
||||
if s.Side == UnknownSide || orderSubmissionValidSides&s.Side != s.Side {
|
||||
return ErrSideIsInvalid
|
||||
}
|
||||
|
||||
@@ -145,15 +157,15 @@ func (d *Detail) UpdateOrderFromDetail(m *Detail) {
|
||||
d.WalletAddress = m.WalletAddress
|
||||
updated = true
|
||||
}
|
||||
if m.Type != "" && m.Type != d.Type {
|
||||
if m.Type != UnknownType && m.Type != d.Type {
|
||||
d.Type = m.Type
|
||||
updated = true
|
||||
}
|
||||
if m.Side != "" && m.Side != d.Side {
|
||||
if m.Side != UnknownSide && m.Side != d.Side {
|
||||
d.Side = m.Side
|
||||
updated = true
|
||||
}
|
||||
if m.Status != "" && m.Status != d.Status {
|
||||
if m.Status != UnknownStatus && m.Status != d.Status {
|
||||
d.Status = m.Status
|
||||
updated = true
|
||||
}
|
||||
@@ -161,53 +173,51 @@ func (d *Detail) UpdateOrderFromDetail(m *Detail) {
|
||||
d.AssetType = m.AssetType
|
||||
updated = true
|
||||
}
|
||||
if m.Trades != nil {
|
||||
for x := range m.Trades {
|
||||
var found bool
|
||||
for y := range d.Trades {
|
||||
if d.Trades[y].TID != m.Trades[x].TID {
|
||||
continue
|
||||
}
|
||||
found = true
|
||||
if d.Trades[y].Fee != m.Trades[x].Fee {
|
||||
d.Trades[y].Fee = m.Trades[x].Fee
|
||||
updated = true
|
||||
}
|
||||
if m.Trades[x].Price != 0 && d.Trades[y].Price != m.Trades[x].Price {
|
||||
d.Trades[y].Price = m.Trades[x].Price
|
||||
updated = true
|
||||
}
|
||||
if d.Trades[y].Side != m.Trades[x].Side {
|
||||
d.Trades[y].Side = m.Trades[x].Side
|
||||
updated = true
|
||||
}
|
||||
if d.Trades[y].Type != m.Trades[x].Type {
|
||||
d.Trades[y].Type = m.Trades[x].Type
|
||||
updated = true
|
||||
}
|
||||
if d.Trades[y].Description != m.Trades[x].Description {
|
||||
d.Trades[y].Description = m.Trades[x].Description
|
||||
updated = true
|
||||
}
|
||||
if m.Trades[x].Amount != 0 && d.Trades[y].Amount != m.Trades[x].Amount {
|
||||
d.Trades[y].Amount = m.Trades[x].Amount
|
||||
updated = true
|
||||
}
|
||||
if d.Trades[y].Timestamp != m.Trades[x].Timestamp {
|
||||
d.Trades[y].Timestamp = m.Trades[x].Timestamp
|
||||
updated = true
|
||||
}
|
||||
if d.Trades[y].IsMaker != m.Trades[x].IsMaker {
|
||||
d.Trades[y].IsMaker = m.Trades[x].IsMaker
|
||||
updated = true
|
||||
}
|
||||
for x := range m.Trades {
|
||||
var found bool
|
||||
for y := range d.Trades {
|
||||
if d.Trades[y].TID != m.Trades[x].TID {
|
||||
continue
|
||||
}
|
||||
if !found {
|
||||
d.Trades = append(d.Trades, m.Trades[x])
|
||||
found = true
|
||||
if d.Trades[y].Fee != m.Trades[x].Fee {
|
||||
d.Trades[y].Fee = m.Trades[x].Fee
|
||||
updated = true
|
||||
}
|
||||
if m.Trades[x].Price != 0 && d.Trades[y].Price != m.Trades[x].Price {
|
||||
d.Trades[y].Price = m.Trades[x].Price
|
||||
updated = true
|
||||
}
|
||||
if d.Trades[y].Side != m.Trades[x].Side {
|
||||
d.Trades[y].Side = m.Trades[x].Side
|
||||
updated = true
|
||||
}
|
||||
if d.Trades[y].Type != m.Trades[x].Type {
|
||||
d.Trades[y].Type = m.Trades[x].Type
|
||||
updated = true
|
||||
}
|
||||
if d.Trades[y].Description != m.Trades[x].Description {
|
||||
d.Trades[y].Description = m.Trades[x].Description
|
||||
updated = true
|
||||
}
|
||||
if m.Trades[x].Amount != 0 && d.Trades[y].Amount != m.Trades[x].Amount {
|
||||
d.Trades[y].Amount = m.Trades[x].Amount
|
||||
updated = true
|
||||
}
|
||||
if d.Trades[y].Timestamp != m.Trades[x].Timestamp {
|
||||
d.Trades[y].Timestamp = m.Trades[x].Timestamp
|
||||
updated = true
|
||||
}
|
||||
if d.Trades[y].IsMaker != m.Trades[x].IsMaker {
|
||||
d.Trades[y].IsMaker = m.Trades[x].IsMaker
|
||||
updated = true
|
||||
}
|
||||
m.RemainingAmount -= m.Trades[x].Amount
|
||||
}
|
||||
if !found {
|
||||
d.Trades = append(d.Trades, m.Trades[x])
|
||||
updated = true
|
||||
}
|
||||
m.RemainingAmount -= m.Trades[x].Amount
|
||||
}
|
||||
if m.RemainingAmount > 0 && m.RemainingAmount != d.RemainingAmount {
|
||||
d.RemainingAmount = m.RemainingAmount
|
||||
@@ -309,15 +319,15 @@ func (d *Detail) UpdateOrderFromModify(m *Modify) {
|
||||
d.WalletAddress = m.WalletAddress
|
||||
updated = true
|
||||
}
|
||||
if m.Type != "" && m.Type != d.Type {
|
||||
if m.Type != UnknownType && m.Type != d.Type {
|
||||
d.Type = m.Type
|
||||
updated = true
|
||||
}
|
||||
if m.Side != "" && m.Side != d.Side {
|
||||
if m.Side != UnknownSide && m.Side != d.Side {
|
||||
d.Side = m.Side
|
||||
updated = true
|
||||
}
|
||||
if m.Status != "" && m.Status != d.Status {
|
||||
if m.Status != UnknownStatus && m.Status != d.Status {
|
||||
d.Status = m.Status
|
||||
updated = true
|
||||
}
|
||||
@@ -325,53 +335,51 @@ func (d *Detail) UpdateOrderFromModify(m *Modify) {
|
||||
d.AssetType = m.AssetType
|
||||
updated = true
|
||||
}
|
||||
if m.Trades != nil {
|
||||
for x := range m.Trades {
|
||||
var found bool
|
||||
for y := range d.Trades {
|
||||
if d.Trades[y].TID != m.Trades[x].TID {
|
||||
continue
|
||||
}
|
||||
found = true
|
||||
if d.Trades[y].Fee != m.Trades[x].Fee {
|
||||
d.Trades[y].Fee = m.Trades[x].Fee
|
||||
updated = true
|
||||
}
|
||||
if m.Trades[x].Price != 0 && d.Trades[y].Price != m.Trades[x].Price {
|
||||
d.Trades[y].Price = m.Trades[x].Price
|
||||
updated = true
|
||||
}
|
||||
if d.Trades[y].Side != m.Trades[x].Side {
|
||||
d.Trades[y].Side = m.Trades[x].Side
|
||||
updated = true
|
||||
}
|
||||
if d.Trades[y].Type != m.Trades[x].Type {
|
||||
d.Trades[y].Type = m.Trades[x].Type
|
||||
updated = true
|
||||
}
|
||||
if d.Trades[y].Description != m.Trades[x].Description {
|
||||
d.Trades[y].Description = m.Trades[x].Description
|
||||
updated = true
|
||||
}
|
||||
if m.Trades[x].Amount != 0 && d.Trades[y].Amount != m.Trades[x].Amount {
|
||||
d.Trades[y].Amount = m.Trades[x].Amount
|
||||
updated = true
|
||||
}
|
||||
if d.Trades[y].Timestamp != m.Trades[x].Timestamp {
|
||||
d.Trades[y].Timestamp = m.Trades[x].Timestamp
|
||||
updated = true
|
||||
}
|
||||
if d.Trades[y].IsMaker != m.Trades[x].IsMaker {
|
||||
d.Trades[y].IsMaker = m.Trades[x].IsMaker
|
||||
updated = true
|
||||
}
|
||||
for x := range m.Trades {
|
||||
var found bool
|
||||
for y := range d.Trades {
|
||||
if d.Trades[y].TID != m.Trades[x].TID {
|
||||
continue
|
||||
}
|
||||
if !found {
|
||||
d.Trades = append(d.Trades, m.Trades[x])
|
||||
found = true
|
||||
if d.Trades[y].Fee != m.Trades[x].Fee {
|
||||
d.Trades[y].Fee = m.Trades[x].Fee
|
||||
updated = true
|
||||
}
|
||||
if m.Trades[x].Price != 0 && d.Trades[y].Price != m.Trades[x].Price {
|
||||
d.Trades[y].Price = m.Trades[x].Price
|
||||
updated = true
|
||||
}
|
||||
if d.Trades[y].Side != m.Trades[x].Side {
|
||||
d.Trades[y].Side = m.Trades[x].Side
|
||||
updated = true
|
||||
}
|
||||
if d.Trades[y].Type != m.Trades[x].Type {
|
||||
d.Trades[y].Type = m.Trades[x].Type
|
||||
updated = true
|
||||
}
|
||||
if d.Trades[y].Description != m.Trades[x].Description {
|
||||
d.Trades[y].Description = m.Trades[x].Description
|
||||
updated = true
|
||||
}
|
||||
if m.Trades[x].Amount != 0 && d.Trades[y].Amount != m.Trades[x].Amount {
|
||||
d.Trades[y].Amount = m.Trades[x].Amount
|
||||
updated = true
|
||||
}
|
||||
if d.Trades[y].Timestamp != m.Trades[x].Timestamp {
|
||||
d.Trades[y].Timestamp = m.Trades[x].Timestamp
|
||||
updated = true
|
||||
}
|
||||
if d.Trades[y].IsMaker != m.Trades[x].IsMaker {
|
||||
d.Trades[y].IsMaker = m.Trades[x].IsMaker
|
||||
updated = true
|
||||
}
|
||||
m.RemainingAmount -= m.Trades[x].Amount
|
||||
}
|
||||
if !found {
|
||||
d.Trades = append(d.Trades, m.Trades[x])
|
||||
updated = true
|
||||
}
|
||||
m.RemainingAmount -= m.Trades[x].Amount
|
||||
}
|
||||
if m.RemainingAmount > 0 && m.RemainingAmount != d.RemainingAmount {
|
||||
d.RemainingAmount = m.RemainingAmount
|
||||
@@ -401,13 +409,13 @@ func (d *Detail) MatchFilter(f *Filter) bool {
|
||||
if f.ID != "" && d.ID != f.ID {
|
||||
return false
|
||||
}
|
||||
if f.Type != "" && f.Type != AnyType && d.Type != f.Type {
|
||||
if f.Type != UnknownType && f.Type != AnyType && d.Type != f.Type {
|
||||
return false
|
||||
}
|
||||
if f.Side != "" && f.Side != AnySide && d.Side != f.Side {
|
||||
if f.Side != UnknownSide && f.Side != AnySide && d.Side != f.Side {
|
||||
return false
|
||||
}
|
||||
if f.Status != "" && f.Status != AnyStatus && d.Status != f.Status {
|
||||
if f.Status != UnknownStatus && f.Status != AnyStatus && d.Status != f.Status {
|
||||
return false
|
||||
}
|
||||
if f.ClientOrderID != "" && d.ClientOrderID != f.ClientOrderID {
|
||||
@@ -428,25 +436,21 @@ func (d *Detail) MatchFilter(f *Filter) bool {
|
||||
return true
|
||||
}
|
||||
|
||||
// IsActive returns true if an order has a status that indicates it is
|
||||
// currently available on the exchange
|
||||
// IsActive returns true if an order has a status that indicates it is currently
|
||||
// available on the exchange
|
||||
func (d *Detail) IsActive() bool {
|
||||
if d.Amount <= 0 || d.Amount <= d.ExecutedAmount {
|
||||
return false
|
||||
}
|
||||
return d.Status == Active || d.Status == Open || d.Status == PartiallyFilled || d.Status == New ||
|
||||
d.Status == AnyStatus || d.Status == PendingCancel || d.Status == Hidden || d.Status == UnknownStatus ||
|
||||
d.Status == AutoDeleverage || d.Status == Pending
|
||||
return d.Status != UnknownStatus &&
|
||||
d.Amount > 0 &&
|
||||
d.Amount > d.ExecutedAmount &&
|
||||
activeStatuses&d.Status == d.Status
|
||||
}
|
||||
|
||||
// IsInactive returns true if an order has a status that indicates it is
|
||||
// currently not available on the exchange
|
||||
func (d *Detail) IsInactive() bool {
|
||||
if d.Amount <= 0 || d.Amount <= d.ExecutedAmount {
|
||||
return true
|
||||
}
|
||||
return d.Status == Filled || d.Status == Cancelled || d.Status == InsufficientBalance || d.Status == MarketUnavailable ||
|
||||
d.Status == Rejected || d.Status == PartiallyCancelled || d.Status == Expired || d.Status == Closed
|
||||
return d.Amount <= 0 ||
|
||||
d.Amount <= d.ExecutedAmount ||
|
||||
inactiveStatuses&d.Status == d.Status
|
||||
}
|
||||
|
||||
// GenerateInternalOrderID sets a new V4 order ID or a V5 order ID if
|
||||
@@ -474,50 +478,151 @@ func (d *Detail) Copy() Detail {
|
||||
|
||||
// String implements the stringer interface
|
||||
func (t Type) String() string {
|
||||
return string(t)
|
||||
switch t {
|
||||
case AnyType:
|
||||
return "ANY"
|
||||
case Limit:
|
||||
return "LIMIT"
|
||||
case Market:
|
||||
return "MARKET"
|
||||
case PostOnly:
|
||||
return "POST_ONLY"
|
||||
case ImmediateOrCancel:
|
||||
return "IMMEDIATE_OR_CANCEL"
|
||||
case Stop:
|
||||
return "STOP"
|
||||
case StopLimit:
|
||||
return "STOP LIMIT"
|
||||
case StopMarket:
|
||||
return "STOP MARKET"
|
||||
case TakeProfit:
|
||||
return "TAKE PROFIT"
|
||||
case TakeProfitMarket:
|
||||
return "TAKE PROFIT MARKET"
|
||||
case TrailingStop:
|
||||
return "TRAILING_STOP"
|
||||
case FillOrKill:
|
||||
return "FOK"
|
||||
case IOS:
|
||||
return "IOS"
|
||||
case Liquidation:
|
||||
return "LIQUIDATION"
|
||||
case Trigger:
|
||||
return "TRIGGER"
|
||||
default:
|
||||
return "UNKNOWN"
|
||||
}
|
||||
}
|
||||
|
||||
// Lower returns the type lower case string
|
||||
func (t Type) Lower() string {
|
||||
return strings.ToLower(string(t))
|
||||
return strings.ToLower(t.String())
|
||||
}
|
||||
|
||||
// Title returns the type titleized, eg "Limit"
|
||||
func (t Type) Title() string {
|
||||
return strings.Title(strings.ToLower(string(t))) // nolint:staticcheck // Ignore Title usage warning
|
||||
return strings.Title(strings.ToLower(t.String())) // nolint:staticcheck // Ignore Title usage warning
|
||||
}
|
||||
|
||||
// String implements the stringer interface
|
||||
func (s Side) String() string {
|
||||
return string(s)
|
||||
switch s {
|
||||
case Buy:
|
||||
return "BUY"
|
||||
case Sell:
|
||||
return "SELL"
|
||||
case Bid:
|
||||
return "BID"
|
||||
case Ask:
|
||||
return "ASK"
|
||||
case Long:
|
||||
return "LONG"
|
||||
case Short:
|
||||
return "SHORT"
|
||||
case AnySide:
|
||||
return "ANY"
|
||||
// Backtester signal types below.
|
||||
case DoNothing:
|
||||
return "DO NOTHING"
|
||||
case TransferredFunds:
|
||||
return "TRANSFERRED FUNDS"
|
||||
case CouldNotBuy:
|
||||
return "COULD NOT BUY"
|
||||
case CouldNotSell:
|
||||
return "COULD NOT SELL"
|
||||
case MissingData:
|
||||
return "MISSING DATA"
|
||||
default:
|
||||
return "UNKNOWN"
|
||||
}
|
||||
}
|
||||
|
||||
// Lower returns the side lower case string
|
||||
func (s Side) Lower() string {
|
||||
return strings.ToLower(string(s))
|
||||
return strings.ToLower(s.String())
|
||||
}
|
||||
|
||||
// Title returns the side titleized, eg "Buy"
|
||||
func (s Side) Title() string {
|
||||
return strings.Title(strings.ToLower(string(s))) // nolint:staticcheck // Ignore Title usage warning
|
||||
return strings.Title(strings.ToLower(s.String())) // nolint:staticcheck // Ignore Title usage warning
|
||||
}
|
||||
|
||||
// IsShort returns if the side is short
|
||||
func (s Side) IsShort() bool {
|
||||
return s == Short || s == Sell
|
||||
return s != UnknownSide && shortSide&s == s
|
||||
}
|
||||
|
||||
// IsLong returns if the side is long
|
||||
func (s Side) IsLong() bool {
|
||||
return s == Long || s == Buy
|
||||
return s != UnknownSide && longSide&s == s
|
||||
}
|
||||
|
||||
// String implements the stringer interface
|
||||
func (s Status) String() string {
|
||||
return string(s)
|
||||
switch s {
|
||||
case AnyStatus:
|
||||
return "ANY"
|
||||
case New:
|
||||
return "NEW"
|
||||
case Active:
|
||||
return "ACTIVE"
|
||||
case PartiallyCancelled:
|
||||
return "PARTIALLY_CANCELLED"
|
||||
case PartiallyFilled:
|
||||
return "PARTIALLY_FILLED"
|
||||
case Filled:
|
||||
return "FILLED"
|
||||
case Cancelled:
|
||||
return "CANCELLED"
|
||||
case PendingCancel:
|
||||
return "PENDING_CANCEL"
|
||||
case InsufficientBalance:
|
||||
return "INSUFFICIENT_BALANCE"
|
||||
case MarketUnavailable:
|
||||
return "MARKET_UNAVAILABLE"
|
||||
case Rejected:
|
||||
return "REJECTED"
|
||||
case Expired:
|
||||
return "EXPIRED"
|
||||
case Hidden:
|
||||
return "HIDDEN"
|
||||
case Open:
|
||||
return "OPEN"
|
||||
case AutoDeleverage:
|
||||
return "ADL"
|
||||
case Closed:
|
||||
return "CLOSED"
|
||||
case Pending:
|
||||
return "PENDING"
|
||||
case Cancelling:
|
||||
return "CANCELLING"
|
||||
default:
|
||||
return "UNKNOWN"
|
||||
}
|
||||
}
|
||||
|
||||
// InferCostsAndTimes infer order costs using execution information and times when available
|
||||
// InferCostsAndTimes infer order costs using execution information and times
|
||||
// when available
|
||||
func (d *Detail) InferCostsAndTimes() {
|
||||
if d.CostAsset.IsEmpty() {
|
||||
d.CostAsset = d.Pair.Quote
|
||||
@@ -547,83 +652,86 @@ func (d *Detail) InferCostsAndTimes() {
|
||||
}
|
||||
}
|
||||
|
||||
// FilterOrdersBySide removes any order details that don't match the
|
||||
// order status provided
|
||||
// FilterOrdersBySide removes any order details that don't match the order
|
||||
// status provided
|
||||
func FilterOrdersBySide(orders *[]Detail, side Side) {
|
||||
if side == "" || side == AnySide {
|
||||
if bypassSideFilter&side == side || len(*orders) == 0 {
|
||||
return
|
||||
}
|
||||
|
||||
var filteredOrders []Detail
|
||||
target := 0
|
||||
for i := range *orders {
|
||||
if strings.EqualFold(string((*orders)[i].Side), string(side)) {
|
||||
filteredOrders = append(filteredOrders, (*orders)[i])
|
||||
if (*orders)[i].Side == side {
|
||||
(*orders)[target] = (*orders)[i]
|
||||
target++
|
||||
}
|
||||
}
|
||||
|
||||
*orders = filteredOrders
|
||||
*orders = (*orders)[:target]
|
||||
}
|
||||
|
||||
// FilterOrdersByType removes any order details that don't match the order type
|
||||
// provided
|
||||
func FilterOrdersByType(orders *[]Detail, orderType Type) {
|
||||
if orderType == "" || orderType == AnyType {
|
||||
if bypassTypeFilter&orderType == orderType || len(*orders) == 0 {
|
||||
return
|
||||
}
|
||||
|
||||
var filteredOrders []Detail
|
||||
target := 0
|
||||
for i := range *orders {
|
||||
if strings.EqualFold(string((*orders)[i].Type), string(orderType)) {
|
||||
filteredOrders = append(filteredOrders, (*orders)[i])
|
||||
if (*orders)[i].Type == orderType {
|
||||
(*orders)[target] = (*orders)[i]
|
||||
target++
|
||||
}
|
||||
}
|
||||
|
||||
*orders = filteredOrders
|
||||
*orders = (*orders)[:target]
|
||||
}
|
||||
|
||||
// FilterOrdersByTimeRange removes any OrderDetails outside of the time range
|
||||
func FilterOrdersByTimeRange(orders *[]Detail, startTime, endTime time.Time) {
|
||||
if startTime.IsZero() ||
|
||||
endTime.IsZero() ||
|
||||
startTime.Unix() == 0 ||
|
||||
endTime.Unix() == 0 ||
|
||||
endTime.Before(startTime) {
|
||||
return
|
||||
func FilterOrdersByTimeRange(orders *[]Detail, startTime, endTime time.Time) error {
|
||||
if len(*orders) == 0 {
|
||||
return nil
|
||||
}
|
||||
|
||||
var filteredOrders []Detail
|
||||
if err := common.StartEndTimeCheck(startTime, endTime); err != nil {
|
||||
if errors.Is(err, common.ErrDateUnset) {
|
||||
return nil
|
||||
}
|
||||
return fmt.Errorf("cannot filter orders by time range %w", err)
|
||||
}
|
||||
|
||||
target := 0
|
||||
for i := range *orders {
|
||||
if ((*orders)[i].Date.Unix() >= startTime.Unix() && (*orders)[i].Date.Unix() <= endTime.Unix()) ||
|
||||
(*orders)[i].Date.IsZero() {
|
||||
filteredOrders = append(filteredOrders, (*orders)[i])
|
||||
(*orders)[target] = (*orders)[i]
|
||||
target++
|
||||
}
|
||||
}
|
||||
|
||||
*orders = filteredOrders
|
||||
*orders = (*orders)[:target]
|
||||
return nil
|
||||
}
|
||||
|
||||
// FilterOrdersByCurrencies removes any order details that do not match the
|
||||
// provided currency list. It is forgiving in that the provided currencies can
|
||||
// match quote or base currencies
|
||||
func FilterOrdersByCurrencies(orders *[]Detail, currencies []currency.Pair) {
|
||||
if len(currencies) == 0 {
|
||||
return
|
||||
}
|
||||
if len(currencies) == 1 && currencies[0].IsEmpty() {
|
||||
// FilterOrdersByPairs removes any order details that do not match the
|
||||
// provided currency pairs list. It is forgiving in that the provided pairs can
|
||||
// match quote or base pairs
|
||||
func FilterOrdersByPairs(orders *[]Detail, pairs []currency.Pair) {
|
||||
if len(pairs) == 0 ||
|
||||
(len(pairs) == 1 && pairs[0].IsEmpty()) ||
|
||||
len(*orders) == 0 {
|
||||
return
|
||||
}
|
||||
|
||||
var filteredOrders []Detail
|
||||
for i := range *orders {
|
||||
for _, c := range currencies {
|
||||
if (*orders)[i].Pair.EqualIncludeReciprocal(c) {
|
||||
filteredOrders = append(filteredOrders, (*orders)[i])
|
||||
target := 0
|
||||
for x := range *orders {
|
||||
for y := range pairs {
|
||||
if (*orders)[x].Pair.EqualIncludeReciprocal(pairs[y]) {
|
||||
(*orders)[target] = (*orders)[x]
|
||||
target++
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
*orders = filteredOrders
|
||||
*orders = (*orders)[:target]
|
||||
}
|
||||
|
||||
func (b ByPrice) Len() int {
|
||||
@@ -735,23 +843,23 @@ func SortOrdersBySide(orders *[]Detail, reverse bool) {
|
||||
// and returning a real Side
|
||||
func StringToOrderSide(side string) (Side, error) {
|
||||
side = strings.ToUpper(side)
|
||||
switch Side(side) {
|
||||
case Buy:
|
||||
switch side {
|
||||
case Buy.String():
|
||||
return Buy, nil
|
||||
case Sell:
|
||||
case Sell.String():
|
||||
return Sell, nil
|
||||
case Bid:
|
||||
case Bid.String():
|
||||
return Bid, nil
|
||||
case Ask:
|
||||
case Ask.String():
|
||||
return Ask, nil
|
||||
case Long:
|
||||
case Long.String():
|
||||
return Long, nil
|
||||
case Short:
|
||||
case Short.String():
|
||||
return Short, nil
|
||||
case AnySide:
|
||||
case AnySide.String():
|
||||
return AnySide, nil
|
||||
default:
|
||||
return UnknownSide, errors.New(side + " not recognised as order side")
|
||||
return UnknownSide, fmt.Errorf("'%s' %w", side, errUnrecognisedOrderSide)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -783,7 +891,7 @@ func StringToOrderType(oType string) (Type, error) {
|
||||
case Trigger.String():
|
||||
return Trigger, nil
|
||||
default:
|
||||
return UnknownType, errors.New(oType + " not recognised as order type")
|
||||
return UnknownType, fmt.Errorf("'%v' %w", oType, errUnrecognisedOrderType)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -822,8 +930,10 @@ func StringToOrderStatus(status string) (Status, error) {
|
||||
return InsufficientBalance, nil
|
||||
case MarketUnavailable.String():
|
||||
return MarketUnavailable, nil
|
||||
case Cancelling.String():
|
||||
return Cancelling, nil
|
||||
default:
|
||||
return UnknownStatus, errors.New(status + " not recognised as order status")
|
||||
return UnknownStatus, fmt.Errorf("'%s' %w", status, errUnrecognisedOrderStatus)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -891,7 +1001,7 @@ func (g *GetOrdersRequest) Validate(opt ...validate.Checker) error {
|
||||
return ErrGetOrdersRequestIsNil
|
||||
}
|
||||
if !g.AssetType.IsValid() {
|
||||
return fmt.Errorf("assetType %v not supported", g.AssetType)
|
||||
return fmt.Errorf("%v %w", g.AssetType, asset.ErrNotSupported)
|
||||
}
|
||||
var errs common.Errors
|
||||
for _, o := range opt {
|
||||
@@ -917,7 +1027,7 @@ func (m *Modify) Validate(opt ...validate.Checker) error {
|
||||
return ErrPairIsEmpty
|
||||
}
|
||||
|
||||
if m.AssetType.String() == "" {
|
||||
if m.AssetType == asset.Empty {
|
||||
return ErrAssetNotSet
|
||||
}
|
||||
|
||||
|
||||
@@ -843,8 +843,13 @@ func (p *Poloniex) GetActiveOrders(ctx context.Context, req *order.GetOrdersRequ
|
||||
return nil, err
|
||||
}
|
||||
for i := range resp.Data[key] {
|
||||
orderSide := order.Side(strings.ToUpper(resp.Data[key][i].Type))
|
||||
orderDate, err := time.Parse(common.SimpleTimeFormat, resp.Data[key][i].Date)
|
||||
var orderSide order.Side
|
||||
orderSide, err = order.StringToOrderSide(resp.Data[key][i].Type)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
var orderDate time.Time
|
||||
orderDate, err = time.Parse(common.SimpleTimeFormat, resp.Data[key][i].Date)
|
||||
if err != nil {
|
||||
log.Errorf(log.ExchangeSys,
|
||||
"Exchange %v Func %v Order %v Could not parse date to unix with value of %v",
|
||||
@@ -866,8 +871,11 @@ func (p *Poloniex) GetActiveOrders(ctx context.Context, req *order.GetOrdersRequ
|
||||
}
|
||||
}
|
||||
|
||||
order.FilterOrdersByTimeRange(&orders, req.StartTime, req.EndTime)
|
||||
order.FilterOrdersByCurrencies(&orders, req.Pairs)
|
||||
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
|
||||
@@ -902,7 +910,10 @@ func (p *Poloniex) GetOrderHistory(ctx context.Context, req *order.GetOrdersRequ
|
||||
}
|
||||
|
||||
for i := range resp.Data[key] {
|
||||
orderSide := order.Side(strings.ToUpper(resp.Data[key][i].Type))
|
||||
orderSide, err := order.StringToOrderSide(resp.Data[key][i].Type)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
orderDate, err := time.Parse(common.SimpleTimeFormat,
|
||||
resp.Data[key][i].Date)
|
||||
if err != nil {
|
||||
@@ -931,9 +942,8 @@ func (p *Poloniex) GetOrderHistory(ctx context.Context, req *order.GetOrdersRequ
|
||||
}
|
||||
}
|
||||
|
||||
order.FilterOrdersByCurrencies(&orders, req.Pairs)
|
||||
order.FilterOrdersByPairs(&orders, req.Pairs)
|
||||
order.FilterOrdersBySide(&orders, req.Side)
|
||||
|
||||
return orders, nil
|
||||
}
|
||||
|
||||
|
||||
@@ -82,7 +82,6 @@ func TestAddTradesToBuffer(t *testing.T) {
|
||||
AssetType: asset.Spot,
|
||||
Price: -1,
|
||||
Amount: -1,
|
||||
Side: "",
|
||||
},
|
||||
}...)
|
||||
if err != nil {
|
||||
|
||||
@@ -583,11 +583,13 @@ func (y *Yobit) GetActiveOrders(ctx context.Context, req *order.GetOrdersRequest
|
||||
}
|
||||
|
||||
for x := range req.Pairs {
|
||||
fCurr, err := y.FormatExchangeCurrency(req.Pairs[x], asset.Spot)
|
||||
var fCurr currency.Pair
|
||||
fCurr, err = y.FormatExchangeCurrency(req.Pairs[x], asset.Spot)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
resp, err := y.GetOpenOrders(ctx, fCurr.String())
|
||||
var resp map[string]ActiveOrders
|
||||
resp, err = y.GetOpenOrders(ctx, fCurr.String())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -598,21 +600,27 @@ func (y *Yobit) GetActiveOrders(ctx context.Context, req *order.GetOrdersRequest
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
orderDate := time.Unix(int64(resp[id].TimestampCreated), 0)
|
||||
side := order.Side(strings.ToUpper(resp[id].Type))
|
||||
var side order.Side
|
||||
side, err = order.StringToOrderSide(resp[id].Type)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
orders = append(orders, order.Detail{
|
||||
ID: id,
|
||||
Amount: resp[id].Amount,
|
||||
Price: resp[id].Rate,
|
||||
Side: side,
|
||||
Date: orderDate,
|
||||
Date: time.Unix(int64(resp[id].TimestampCreated), 0),
|
||||
Pair: symbol,
|
||||
Exchange: y.Name,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
order.FilterOrdersByTimeRange(&orders, req.StartTime, req.EndTime)
|
||||
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
|
||||
}
|
||||
@@ -660,7 +668,11 @@ func (y *Yobit) GetOrderHistory(ctx context.Context, req *order.GetOrdersRequest
|
||||
return nil, err
|
||||
}
|
||||
orderDate := time.Unix(int64(allOrders[i].Timestamp), 0)
|
||||
side := order.Side(strings.ToUpper(allOrders[i].Type))
|
||||
var side order.Side
|
||||
side, err = order.StringToOrderSide(allOrders[i].Type)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
detail := order.Detail{
|
||||
ID: strconv.FormatFloat(allOrders[i].OrderID, 'f', -1, 64),
|
||||
Amount: allOrders[i].Amount,
|
||||
@@ -678,7 +690,6 @@ func (y *Yobit) GetOrderHistory(ctx context.Context, req *order.GetOrdersRequest
|
||||
}
|
||||
|
||||
order.FilterOrdersBySide(&orders, req.Side)
|
||||
|
||||
return orders, nil
|
||||
}
|
||||
|
||||
|
||||
@@ -765,7 +765,10 @@ func (z *ZB) GetActiveOrders(ctx context.Context, req *order.GetOrdersRequest) (
|
||||
}
|
||||
}
|
||||
|
||||
order.FilterOrdersByTimeRange(&orders, req.StartTime, req.EndTime)
|
||||
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
|
||||
}
|
||||
@@ -778,7 +781,7 @@ func (z *ZB) GetOrderHistory(ctx context.Context, req *order.GetOrdersRequest) (
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if req.Side == order.AnySide || req.Side == "" {
|
||||
if req.Side == order.AnySide {
|
||||
return nil, errors.New("specific order side is required")
|
||||
}
|
||||
|
||||
@@ -854,7 +857,10 @@ func (z *ZB) GetOrderHistory(ctx context.Context, req *order.GetOrdersRequest) (
|
||||
orders[i] = detail
|
||||
}
|
||||
|
||||
order.FilterOrdersByTimeRange(&orders, req.StartTime, req.EndTime)
|
||||
err = order.FilterOrdersByTimeRange(&orders, req.StartTime, req.EndTime)
|
||||
if err != nil {
|
||||
log.Errorf(log.ExchangeSys, "%s %v", z.Name, err)
|
||||
}
|
||||
return orders, nil
|
||||
}
|
||||
|
||||
|
||||
@@ -452,10 +452,20 @@ func ExchangeOrderSubmit(args ...objects.Object) (objects.Object, error) {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
side, err := order.StringToOrderSide(orderSide)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
oType, err := order.StringToOrderType(orderType)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
tempSubmit := &order.Submit{
|
||||
Pair: pair,
|
||||
Type: order.Type(orderType),
|
||||
Side: order.Side(orderSide),
|
||||
Type: oType,
|
||||
Side: side,
|
||||
Price: orderPrice,
|
||||
Amount: orderAmount,
|
||||
ClientID: orderClientID,
|
||||
|
||||
@@ -124,10 +124,10 @@ func (w Wrapper) QueryOrder(ctx context.Context, exch, _ string, _ currency.Pair
|
||||
AccountID: "hello",
|
||||
ID: "1",
|
||||
Pair: pair,
|
||||
Side: "ask",
|
||||
Type: "limit",
|
||||
Side: order.Ask,
|
||||
Type: order.Limit,
|
||||
Date: time.Now(),
|
||||
Status: "cancelled",
|
||||
Status: order.Cancelled,
|
||||
Price: 1,
|
||||
Amount: 2,
|
||||
ExecutedAmount: 1,
|
||||
@@ -139,8 +139,8 @@ func (w Wrapper) QueryOrder(ctx context.Context, exch, _ string, _ currency.Pair
|
||||
Price: 1,
|
||||
Amount: 2,
|
||||
Exchange: exch,
|
||||
Type: "limit",
|
||||
Side: "ask",
|
||||
Type: order.Limit,
|
||||
Side: order.Ask,
|
||||
Fee: 0,
|
||||
Description: "",
|
||||
},
|
||||
|
||||
Reference in New Issue
Block a user