fix kucoin orderTime parsing and order id conversion

This commit is contained in:
c9s 2021-12-30 22:02:50 +08:00
parent 76d31e7614
commit ba73d5a09a
6 changed files with 60 additions and 27 deletions

View File

@ -51,14 +51,14 @@ func (b *LocalActiveOrderBook) orderUpdateHandler(order types.Order) {
case types.OrderStatusNew: case types.OrderStatusNew:
if order.Quantity == 0 { if order.Quantity == 0 {
log.Debugf("[LocalActiveOrderBook] order status %s, removing %d...", order.Status, order.OrderID) log.Debugf("[LocalActiveOrderBook] order status %s, removing order %s", order.Status, order)
b.Remove(order) b.Remove(order)
} else { } else {
b.Update(order) b.Update(order)
} }
case types.OrderStatusCanceled, types.OrderStatusRejected: case types.OrderStatusCanceled, types.OrderStatusRejected:
log.Debugf("[LocalActiveOrderBook] order status %s, removing %d...", order.Status, order.OrderID) log.Debugf("[LocalActiveOrderBook] order status %s, removing order %s", order.Status, order)
b.Remove(order) b.Remove(order)
default: default:

View File

@ -2,6 +2,7 @@ package kucoin
import ( import (
"context" "context"
"fmt"
"strconv" "strconv"
"time" "time"
@ -133,7 +134,7 @@ func (e *Exchange) QueryTickers(ctx context.Context, symbols ...string) (map[str
var supportedIntervals = map[types.Interval]int{ var supportedIntervals = map[types.Interval]int{
types.Interval1m: 60, types.Interval1m: 60,
types.Interval5m: 60 * 5, types.Interval5m: 60 * 5,
types.Interval15m: 60 * 15, types.Interval15m: 60 * 15,
types.Interval30m: 60 * 30, types.Interval30m: 60 * 30,
types.Interval1h: 60 * 60, types.Interval1h: 60 * 60,
types.Interval2h: 60 * 60 * 2, types.Interval2h: 60 * 60 * 2,
@ -152,7 +153,6 @@ func (e *Exchange) IsSupportedInterval(interval types.Interval) bool {
return ok return ok
} }
func (e *Exchange) QueryKLines(ctx context.Context, symbol string, interval types.Interval, options types.KLineQueryOptions) ([]types.KLine, error) { func (e *Exchange) QueryKLines(ctx context.Context, symbol string, interval types.Interval, options types.KLineQueryOptions) ([]types.KLine, error) {
_ = marketDataLimiter.Wait(ctx) _ = marketDataLimiter.Wait(ctx)
@ -241,6 +241,7 @@ func (e *Exchange) SubmitOrders(ctx context.Context, orders ...types.SubmitOrder
SubmitOrder: order, SubmitOrder: order,
Exchange: types.ExchangeKucoin, Exchange: types.ExchangeKucoin,
OrderID: hashStringID(orderResponse.OrderID), OrderID: hashStringID(orderResponse.OrderID),
UUID: orderResponse.OrderID,
Status: types.OrderStatusNew, Status: types.OrderStatusNew,
ExecutedQuantity: 0, ExecutedQuantity: 0,
IsWorking: true, IsWorking: true,
@ -341,7 +342,10 @@ func (e *Exchange) CancelOrders(ctx context.Context, orders ...types.Order) (err
} else if o.ClientOrderID != "" { } else if o.ClientOrderID != "" {
req.ClientOrderID(o.ClientOrderID) req.ClientOrderID(o.ClientOrderID)
} else { } else {
errs = multierr.Append(errs, errors.New("can not cancel order, either order uuid nor client order id is empty")) errs = multierr.Append(
errs,
fmt.Errorf("the order uuid or client order id is empty, order: %#v", o),
)
continue continue
} }
@ -354,7 +358,7 @@ func (e *Exchange) CancelOrders(ctx context.Context, orders ...types.Order) (err
log.Infof("cancelled orders: %v", response.CancelledOrderIDs) log.Infof("cancelled orders: %v", response.CancelledOrderIDs)
} }
return errs return errors.Wrap(errs, "order cancel error")
} }
func (e *Exchange) NewStream() types.Stream { func (e *Exchange) NewStream() types.Stream {

View File

@ -134,7 +134,7 @@ func (s *Stream) handlePrivateOrderEvent(e *WebSocketPrivateOrderEvent) {
} }
switch e.Type { switch e.Type {
case "open", "match", "filled": case "open", "match", "filled", "canceled":
status := types.OrderStatusNew status := types.OrderStatusNew
if e.Status == "done" { if e.Status == "done" {
if e.FilledSize == e.Size { if e.FilledSize == e.Size {
@ -151,11 +151,11 @@ func (s *Stream) handlePrivateOrderEvent(e *WebSocketPrivateOrderEvent) {
s.StandardStream.EmitOrderUpdate(types.Order{ s.StandardStream.EmitOrderUpdate(types.Order{
SubmitOrder: types.SubmitOrder{ SubmitOrder: types.SubmitOrder{
ClientOrderID: e.ClientOid, ClientOrderID: e.ClientOid,
Symbol: toGlobalSymbol(e.Symbol), Symbol: toGlobalSymbol(e.Symbol),
Side: toGlobalSide(e.Side), Side: toGlobalSide(e.Side),
Type: toGlobalOrderType(e.OrderType), Type: toGlobalOrderType(e.OrderType),
Quantity: e.Size.Float64(), Quantity: e.Size.Float64(),
Price: e.Price.Float64(), Price: e.Price.Float64(),
}, },
Exchange: types.ExchangeKucoin, Exchange: types.ExchangeKucoin,
OrderID: hashStringID(e.OrderId), OrderID: hashStringID(e.OrderId),
@ -378,6 +378,7 @@ func (s *Stream) read(ctx context.Context) {
// used for debugging // used for debugging
// log.Println(string(message)) // log.Println(string(message))
log.Debug(string(message))
e, err := parseWebsocketPayload(message) e, err := parseWebsocketPayload(message)
if err != nil { if err != nil {
@ -387,9 +388,8 @@ func (s *Stream) read(ctx context.Context) {
// remove bytes, so we won't print them // remove bytes, so we won't print them
e.Data = nil e.Data = nil
log.Infof("event: %+v", e)
if e != nil && e.Object != nil { if e != nil && e.Object != nil {
log.Debugf("parsed event data: %+v",e.Object)
s.dispatchEvent(e) s.dispatchEvent(e)
} }
} }

View File

@ -121,17 +121,17 @@ func (e *WebSocketCandleEvent) KLine() types.KLine {
} }
type WebSocketPrivateOrderEvent struct { type WebSocketPrivateOrderEvent struct {
OrderId string `json:"orderId"` OrderId string `json:"orderId"`
TradeId string `json:"tradeId"` TradeId string `json:"tradeId"`
Symbol string `json:"symbol"` Symbol string `json:"symbol"`
OrderType string `json:"orderType"` OrderType string `json:"orderType"`
Side string `json:"side"` Side string `json:"side"`
Type string `json:"type"` Type string `json:"type"`
OrderTime types.MillisecondTimestamp `json:"orderTime"` OrderTime types.NanosecondTimestamp `json:"orderTime"`
Price fixedpoint.Value `json:"price"` Price fixedpoint.Value `json:"price"`
Size fixedpoint.Value `json:"size"` Size fixedpoint.Value `json:"size"`
FilledSize fixedpoint.Value `json:"filledSize"` FilledSize fixedpoint.Value `json:"filledSize"`
RemainSize fixedpoint.Value `json:"remainSize"` RemainSize fixedpoint.Value `json:"remainSize"`
Liquidity string `json:"liquidity"` Liquidity string `json:"liquidity"`
MatchPrice fixedpoint.Value `json:"matchPrice"` MatchPrice fixedpoint.Value `json:"matchPrice"`

View File

@ -215,12 +215,20 @@ func (o Order) Backup() SubmitOrder {
func (o Order) String() string { func (o Order) String() string {
var orderID string var orderID string
if o.UUID != "" { if o.UUID != "" {
orderID = o.UUID orderID = fmt.Sprintf("UUID %s (%d)", o.UUID, o.OrderID)
} else { } else {
orderID = strconv.FormatUint(o.OrderID, 10) orderID = strconv.FormatUint(o.OrderID, 10)
} }
return fmt.Sprintf("ORDER %s %s %s %s %f/%f @ %f -> %s", o.Exchange.String(), orderID, o.Symbol, o.Side, o.ExecutedQuantity, o.Quantity, o.Price, o.Status) return fmt.Sprintf("ORDER %s %s %s %s %f/%f @ %f -> %s",
o.Exchange.String(),
orderID,
o.Symbol,
o.Side,
o.ExecutedQuantity,
o.Quantity,
o.Price,
o.Status)
} }
// PlainText is used for telegram-styled messages // PlainText is used for telegram-styled messages

View File

@ -8,6 +8,25 @@ import (
"time" "time"
) )
type NanosecondTimestamp time.Time
func (t NanosecondTimestamp) Time() time.Time {
return time.Time(t)
}
func (t *NanosecondTimestamp) UnmarshalJSON(data []byte) error {
var v int64
var err = json.Unmarshal(data, &v)
if err != nil {
return err
}
*t = NanosecondTimestamp(time.Unix(0, v))
return nil
}
type MillisecondTimestamp time.Time type MillisecondTimestamp time.Time
func NewMillisecondTimestampFromInt(i int64) MillisecondTimestamp { func NewMillisecondTimestampFromInt(i int64) MillisecondTimestamp {
@ -97,6 +116,8 @@ func (t *MillisecondTimestamp) UnmarshalJSON(data []byte) error {
return (*time.Time)(t).UnmarshalJSON(data) return (*time.Time)(t).UnmarshalJSON(data)
} }
type Time time.Time type Time time.Time
var layout = "2006-01-02 15:04:05.999Z07:00" var layout = "2006-01-02 15:04:05.999Z07:00"