kucoin: fix trades sync

This commit is contained in:
c9s 2022-04-12 23:25:41 +08:00
parent fad9449ee6
commit a34dbf12e2
7 changed files with 73 additions and 55 deletions

View File

@ -3,7 +3,6 @@ package batch
import (
"context"
"errors"
"sort"
"time"
"github.com/sirupsen/logrus"
@ -41,7 +40,6 @@ func (e TradeBatchQuery) Query(ctx context.Context, symbol string, options *type
var startTime = *options.StartTime
var endTime = *options.EndTime
go func() {
limiter := rate.NewLimiter(rate.Every(5*time.Second), 2) // from binance (original 1200, use 1000 for safety)
@ -66,9 +64,7 @@ func (e TradeBatchQuery) Query(ctx context.Context, symbol string, options *type
})
// sort trades by time in ascending order
sort.Slice(trades, func(i, j int) bool {
return trades[i].Time.Before(time.Time(trades[j].Time))
})
types.SortTradesAscending(trades)
if err != nil {
errC <- err
@ -78,7 +74,9 @@ func (e TradeBatchQuery) Query(ctx context.Context, symbol string, options *type
// if all trades are duplicated or empty, we end the batch query
if len(trades) == 0 {
return
} else if len(trades) > 0 {
}
if len(trades) > 0 {
allExists := true
for _, td := range trades {
k := td.Key()

View File

@ -364,10 +364,9 @@ func (e *Exchange) QueryTrades(ctx context.Context, symbol string, options *type
if options.StartTime != nil && options.EndTime != nil {
req.StartAt(*options.StartTime)
if options.EndTime.Sub(*options.StartTime) < 7*24*time.Hour {
req.EndAt(*options.EndTime)
} else {
req.StartAt(options.StartTime.Add(7*24*time.Hour - time.Minute))
}
} else if options.StartTime != nil {
req.StartAt(*options.StartTime)
@ -383,6 +382,7 @@ func (e *Exchange) QueryTrades(ctx context.Context, symbol string, options *type
if err != nil {
return trades, err
}
for _, fill := range response.Items {
trade := toGlobalTrade(fill)
trades = append(trades, trade)

View File

@ -195,4 +195,3 @@ type APIResponse struct {
Message string `json:"msg"`
Data json.RawMessage `json:"data"`
}

View File

@ -50,18 +50,6 @@ func (r *GetFillsRequest) EndAt(endAt time.Time) *GetFillsRequest {
// GetQueryParameters builds and checks the query parameters and returns url.Values
func (r *GetFillsRequest) GetQueryParameters() (url.Values, error) {
var params = map[string]interface{}{}
query := url.Values{}
for k, v := range params {
query.Add(k, fmt.Sprintf("%v", v))
}
return query, nil
}
// GetParameters builds and checks the parameters and return the result in a map object
func (r *GetFillsRequest) GetParameters() (map[string]interface{}, error) {
var params = map[string]interface{}{}
// check orderID field -> json key orderId
if r.orderID != nil {
orderID := *r.orderID
@ -147,6 +135,18 @@ func (r *GetFillsRequest) GetParameters() (map[string]interface{}, error) {
} else {
}
query := url.Values{}
for k, v := range params {
query.Add(k, fmt.Sprintf("%v", v))
}
return query, nil
}
// GetParameters builds and checks the parameters and return the result in a map object
func (r *GetFillsRequest) GetParameters() (map[string]interface{}, error) {
var params = map[string]interface{}{}
return params, nil
}
@ -208,9 +208,12 @@ func (r *GetFillsRequest) GetSlugsMap() (map[string]string, error) {
func (r *GetFillsRequest) Do(ctx context.Context) (*FillListPage, error) {
// empty params for GET operation
// no body params
var params interface{}
query := url.Values{}
query, err := r.GetQueryParameters()
if err != nil {
return nil, err
}
apiURL := "/api/v1/fills"

View File

@ -52,19 +52,19 @@ func (c *TradeService) NewGetFillsRequest() *GetFillsRequest {
type GetFillsRequest struct {
client requestgen.AuthenticatedAPIClient
orderID *string `param:"orderId"`
orderID *string `param:"orderId,query"`
tradeType *string `param:"tradeType" default:"TRADE"`
tradeType *string `param:"tradeType,query" default:"TRADE"`
symbol *string `param:"symbol"`
symbol *string `param:"symbol,query"`
side *string `param:"side" validValues:"buy,sell"`
side *string `param:"side,query" validValues:"buy,sell"`
orderType *string `param:"type" validValues:"limit,market,limit_stop,market_stop"`
orderType *string `param:"type,query" validValues:"limit,market,limit_stop,market_stop"`
startAt *time.Time `param:"startAt,milliseconds"`
startAt *time.Time `param:"startAt,query,milliseconds"`
endAt *time.Time `param:"endAt,milliseconds"`
endAt *time.Time `param:"endAt,query,milliseconds"`
}
type FillListPage struct {

View File

@ -61,32 +61,37 @@ func (s *Server) Subscribe(request *pb.SubscribeRequest, server pb.MarketDataSer
streamPool := map[string]types.Stream{}
for sessionName, subs := range exchangeSubscriptions {
if session, ok := s.Environ.Session(sessionName); ok {
stream := session.Exchange.NewStream()
stream.SetPublicOnly()
for _, sub := range subs {
stream.Subscribe(sub.Channel, sub.Symbol, sub.Options)
}
stream.OnBookSnapshot(func(book types.SliceOrderBook) {
if err := server.Send(transBook(session, book, pb.Event_SNAPSHOT)); err != nil {
log.WithError(err).Error("grpc stream send error")
}
})
stream.OnBookUpdate(func(book types.SliceOrderBook) {
if err := server.Send(transBook(session, book, pb.Event_UPDATE)); err != nil {
log.WithError(err).Error("grpc stream send error")
}
})
stream.OnKLineClosed(func(kline types.KLine) {
err := server.Send(transKLine(session, kline))
if err != nil {
log.WithError(err).Error("grpc stream send error")
}
})
streamPool[sessionName] = stream
session, ok := s.Environ.Session(sessionName)
if !ok {
log.Errorf("session %s not found", sessionName)
continue
}
stream := session.Exchange.NewStream()
stream.SetPublicOnly()
for _, sub := range subs {
log.Infof("%s subscribe %s %s %+v", sessionName, sub.Channel, sub.Symbol, sub.Options)
stream.Subscribe(sub.Channel, sub.Symbol, sub.Options)
}
stream.OnBookSnapshot(func(book types.SliceOrderBook) {
if err := server.Send(transBook(session, book, pb.Event_SNAPSHOT)); err != nil {
log.WithError(err).Error("grpc stream send error")
}
})
stream.OnBookUpdate(func(book types.SliceOrderBook) {
if err := server.Send(transBook(session, book, pb.Event_UPDATE)); err != nil {
log.WithError(err).Error("grpc stream send error")
}
})
stream.OnKLineClosed(func(kline types.KLine) {
err := server.Send(transKLine(session, kline))
if err != nil {
log.WithError(err).Error("grpc stream send error")
}
})
streamPool[sessionName] = stream
}
for sessionName, stream := range streamPool {

13
pkg/types/sort.go Normal file
View File

@ -0,0 +1,13 @@
package types
import (
"sort"
"time"
)
func SortTradesAscending(trades []Trade) []Trade {
sort.Slice(trades, func(i, j int) bool {
return trades[i].Time.Before(time.Time(trades[j].Time))
})
return trades
}