Kraken: Fix websocket order updates (#1327)

* Kraken: Fix error on WS update without status

* Kraken: Fix parsing of WS updates without Desc

* Kraken: Fix WS market order handling

* Kraken: Fix tests in parallel using DataHandler

* WebsocketManager: Fix order summary printing

* Kraken: Fix parallel tests race with DataHandler

* Kraken: Issue a classification err on asset 404

* Kraken: Switch to testify and close fixture
This commit is contained in:
Gareth Kirwan
2023-09-05 04:22:34 +01:00
committed by GitHub
parent 052327343e
commit 253b9a5049
6 changed files with 563 additions and 576 deletions

View File

@@ -307,7 +307,7 @@ func (m *WebsocketRoutineManager) websocketDataHandler(exchName string, data int
if err != nil {
return err
}
m.printOrderSummary(d, true)
m.printOrderSummary(od, true)
}
case []order.Detail:
for x := range d {
@@ -330,7 +330,7 @@ func (m *WebsocketRoutineManager) websocketDataHandler(exchName string, data int
if err != nil {
return err
}
m.printOrderSummary(&d[x], true)
m.printOrderSummary(od, true)
}
}
case order.ClassificationError:

File diff suppressed because it is too large Load Diff

View File

@@ -600,6 +600,7 @@ type wsSubscription struct {
type WsOpenOrder struct {
UserReferenceID int64 `json:"userref"`
ExpireTime float64 `json:"expiretm,string"`
LastUpdated float64 `json:"lastupdated,string"`
OpenTime float64 `json:"opentm,string"`
StartTime float64 `json:"starttm,string"`
Fee float64 `json:"fee,string"`
@@ -608,7 +609,7 @@ type WsOpenOrder struct {
Volume float64 `json:"vol,string"`
ExecutedVolume float64 `json:"vol_exec,string"`
Cost float64 `json:"cost,string"`
Price float64 `json:"price,string"`
AveragePrice float64 `json:"avg_price,string"`
Misc string `json:"misc"`
OFlags string `json:"oflags"`
RefID string `json:"refid"`

View File

@@ -550,74 +550,83 @@ func (k *Kraken) wsProcessOpenOrders(ownOrders interface{}) error {
return err
}
for key, val := range result {
var oStatus order.Status
oStatus, err = order.StringToOrderStatus(val.Status)
if err != nil {
k.Websocket.DataHandler <- order.ClassificationError{
Exchange: k.Name,
OrderID: key,
Err: err,
}
d := &order.Detail{
Exchange: k.Name,
OrderID: key,
AverageExecutedPrice: val.AveragePrice,
Amount: val.Volume,
LimitPriceUpper: val.LimitPrice,
ExecutedAmount: val.ExecutedVolume,
Fee: val.Fee,
Date: convert.TimeFromUnixTimestampDecimal(val.OpenTime).Truncate(time.Microsecond),
LastUpdated: convert.TimeFromUnixTimestampDecimal(val.LastUpdated).Truncate(time.Microsecond),
}
if val.Description.Price > 0 {
oSide, err := order.StringToOrderSide(val.Description.Type)
if err != nil {
if val.Status != "" {
if s, err := order.StringToOrderStatus(val.Status); err != nil {
k.Websocket.DataHandler <- order.ClassificationError{
Exchange: k.Name,
OrderID: key,
Err: err,
}
} else {
d.Status = s
}
}
if val.Description.Pair != "" {
if strings.Contains(val.Description.Order, "sell") {
oSide = order.Sell
d.Side = order.Sell
} else {
if oSide, err := order.StringToOrderSide(val.Description.Type); err != nil {
k.Websocket.DataHandler <- order.ClassificationError{
Exchange: k.Name,
OrderID: key,
Err: err,
}
} else {
d.Side = oSide
}
}
oType, err := order.StringToOrderType(val.Description.OrderType)
if err != nil {
if oType, err := order.StringToOrderType(val.Description.OrderType); err != nil {
k.Websocket.DataHandler <- order.ClassificationError{
Exchange: k.Name,
OrderID: key,
Err: err,
}
} else {
d.Type = oType
}
p, err := currency.NewPairFromString(val.Description.Pair)
if err != nil {
if p, err := currency.NewPairFromString(val.Description.Pair); err != nil {
k.Websocket.DataHandler <- order.ClassificationError{
Exchange: k.Name,
OrderID: key,
Err: err,
}
}
var a asset.Item
a, err = k.GetPairAssetType(p)
if err != nil {
return err
}
k.Websocket.DataHandler <- &order.Detail{
Leverage: val.Description.Leverage,
Price: val.Price,
Amount: val.Volume,
LimitPriceUpper: val.LimitPrice,
ExecutedAmount: val.ExecutedVolume,
RemainingAmount: val.Volume - val.ExecutedVolume,
Fee: val.Fee,
Exchange: k.Name,
OrderID: key,
Type: oType,
Side: oSide,
Status: oStatus,
AssetType: a,
Date: convert.TimeFromUnixTimestampDecimal(val.OpenTime),
Pair: p,
}
} else {
k.Websocket.DataHandler <- &order.Detail{
Exchange: k.Name,
OrderID: key,
Status: oStatus,
} else {
d.Pair = p
if d.AssetType, err = k.GetPairAssetType(p); err != nil {
k.Websocket.DataHandler <- order.ClassificationError{
Exchange: k.Name,
OrderID: key,
Err: err,
}
}
}
}
if val.Description.Price > 0 {
d.Leverage = val.Description.Leverage
d.Price = val.Description.Price
}
if val.Volume > 0 {
// Note: We don't seem to ever get both there values
d.RemainingAmount = val.Volume - val.ExecutedVolume
}
k.Websocket.DataHandler <- d
}
}
return nil

View File

@@ -0,0 +1,6 @@
[[{"OGTT3Y-C6I3P-XRI6HR":{"cost":"0.00000","descr":{"close":"","leverage":"0.1","order":"sell 10.00345345 XBT/USD @ limit 34.50000 with 0:1 leverage","ordertype":"limit","pair":"XBT/USD","price":"34.50000","price2":"0.00000","type":"sell"},"expiretm":"0.000000","fee":"0.00000","limitprice":"34.50000","misc":"","oflags":"fcib","opentm":"0.000000","avg_price":"0.00000","refid":"LIMIT-OPEN","starttm":"0.000000","status":"open","stopprice":"0.000000","userref":0,"vol":"10.00345345","vol_exec":"0.00000000"}},{"OKB55A-UEMMN-YUXM2A":{"avg_price":"0.00000","cost":"0.00000","descr":{"close":null,"leverage":null,"order":"buy 0.00010000 XBT/USDT @ market 0.00000","ordertype":"market","pair":"XBT/USDT","price":"0.00000","price2":"0.00000","type":"buy"},"expiretm":null,"fee":"0.00000","limitprice":"0.00000","misc":"","oflags":"fciq","opentm":"1692851641.361371","refid":null,"starttm":null,"status":"pending","stopprice":"0.00000","timeinforce":"GTC","userref":0,"vol":"0.00010000","vol_exec":"0.00000000"}}],"openOrders",{"sequence":1}]
[[{"OKB55A-UEMMN-YUXM2A":{"status":"open","userref":0}}],"openOrders",{"sequence":2}]
[[{"OKB55A-UEMMN-YUXM2A":{"vol_exec":"0.00010000","cost":"2.64252","fee":"0.00687","avg_price":"26425.20000","userref":0}}],"openOrders",{"sequence":3}]
[[{"OKB55A-UEMMN-YUXM2A":{"lastupdated":"1692851641.361447","status":"closed","vol_exec":"0.00010000","cost":"2.64252","fee":"0.00687","avg_price":"26425.20000","userref":0}}],"openOrders",{"sequence":4}]
[[{"OGTT3Y-C6I3P-XRI6HR":{"vol_exec":"10.00345345","cost":"345.119144","fee":"0.001","avg_price":"34.50000"}}],"openOrders",{"sequence":5}]
[[{"OGTT3Y-C6I3P-XRI6HR":{"status":"closed","vol_exec":"10.00345345","lastupdated":"1692675961.789052","cost":"345.119144","fee":"0.001","avg_price":"34.50000","userref":0}}],"openOrders",{"sequence":6}]

3
go.mod
View File

@@ -16,6 +16,7 @@ require (
github.com/pquerna/otp v1.4.0
github.com/shopspring/decimal v1.3.1
github.com/spf13/viper v1.16.0
github.com/stretchr/testify v1.8.3
github.com/thrasher-corp/gct-ta v0.0.0-20200623072738-f2b55b7f9f41
github.com/thrasher-corp/goose v2.7.0-rc4.0.20191002032028-0f2c2a27abdb+incompatible
github.com/thrasher-corp/sqlboiler v1.0.1-0.20191001234224-71e17f37a85e
@@ -33,6 +34,7 @@ require (
require (
github.com/boombuler/barcode v1.0.1 // indirect
github.com/cpuguy83/go-md2man/v2 v2.0.2 // indirect
github.com/davecgh/go-spew v1.1.1 // indirect
github.com/friendsofgo/errors v0.9.2 // indirect
github.com/fsnotify/fsnotify v1.6.0 // indirect
github.com/golang/protobuf v1.5.3 // indirect
@@ -40,6 +42,7 @@ require (
github.com/magiconair/properties v1.8.7 // indirect
github.com/mitchellh/mapstructure v1.5.0 // indirect
github.com/pelletier/go-toml/v2 v2.0.8 // indirect
github.com/pmezard/go-difflib v1.0.0 // indirect
github.com/russross/blackfriday/v2 v2.1.0 // indirect
github.com/spf13/afero v1.9.5 // indirect
github.com/spf13/cast v1.5.1 // indirect