mirror of
https://github.com/c9s/bbgo.git
synced 2024-11-10 09:11:55 +00:00
kucoin: fix trades sync
This commit is contained in:
parent
fad9449ee6
commit
a34dbf12e2
|
@ -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()
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -195,4 +195,3 @@ type APIResponse struct {
|
|||
Message string `json:"msg"`
|
||||
Data json.RawMessage `json:"data"`
|
||||
}
|
||||
|
||||
|
|
|
@ -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"
|
||||
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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
13
pkg/types/sort.go
Normal 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
|
||||
}
|
Loading…
Reference in New Issue
Block a user