mirror of
https://github.com/c9s/bbgo.git
synced 2024-11-15 03:23:52 +00:00
Merge pull request #1772 from c9s/edwin/bybit/query-trade
FEATURE: [bybit] use fee currency of trade
This commit is contained in:
commit
0dd1e01d4a
|
@ -80,6 +80,26 @@ func TestClient(t *testing.T) {
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
|
t.Run("GetTrade", func(t *testing.T) {
|
||||||
|
cursor := ""
|
||||||
|
for {
|
||||||
|
req := client.NewGetExecutionListRequest().Limit(50)
|
||||||
|
if len(cursor) != 0 {
|
||||||
|
req = req.Cursor(cursor)
|
||||||
|
}
|
||||||
|
trades, err := req.Do(ctx)
|
||||||
|
assert.NoError(t, err)
|
||||||
|
|
||||||
|
for _, o := range trades.List {
|
||||||
|
t.Logf("openOrders: %+v", o)
|
||||||
|
}
|
||||||
|
if len(trades.NextPageCursor) == 0 {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
cursor = trades.NextPageCursor
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
t.Run("PlaceOrderRequest", func(t *testing.T) {
|
t.Run("PlaceOrderRequest", func(t *testing.T) {
|
||||||
req := client.NewPlaceOrderRequest().
|
req := client.NewPlaceOrderRequest().
|
||||||
Symbol("DOTUSDT").
|
Symbol("DOTUSDT").
|
||||||
|
|
|
@ -24,12 +24,14 @@ type Trade struct {
|
||||||
Side Side `json:"side"`
|
Side Side `json:"side"`
|
||||||
OrderType OrderType `json:"orderType"`
|
OrderType OrderType `json:"orderType"`
|
||||||
// ExecFee is supported on restful API v5, but not on websocket API.
|
// ExecFee is supported on restful API v5, but not on websocket API.
|
||||||
ExecFee fixedpoint.Value `json:"execFee"`
|
ExecFee fixedpoint.Value `json:"execFee"`
|
||||||
ExecId string `json:"execId"`
|
ExecId string `json:"execId"`
|
||||||
ExecPrice fixedpoint.Value `json:"execPrice"`
|
ExecPrice fixedpoint.Value `json:"execPrice"`
|
||||||
ExecQty fixedpoint.Value `json:"execQty"`
|
ExecQty fixedpoint.Value `json:"execQty"`
|
||||||
ExecTime types.MillisecondTimestamp `json:"execTime"`
|
ExecTime types.MillisecondTimestamp `json:"execTime"`
|
||||||
IsMaker bool `json:"isMaker"`
|
IsMaker bool `json:"isMaker"`
|
||||||
|
FeeRate fixedpoint.Value `json:"feeRate"`
|
||||||
|
FeeCurrency string `json:"feeCurrency"`
|
||||||
}
|
}
|
||||||
|
|
||||||
//go:generate GetRequest -url "/v5/execution/list" -type GetExecutionListRequest -responseDataType .TradesResponse -rateLimiter 5+15/1s
|
//go:generate GetRequest -url "/v5/execution/list" -type GetExecutionListRequest -responseDataType .TradesResponse -rateLimiter 5+15/1s
|
||||||
|
@ -38,8 +40,9 @@ type GetExecutionListRequest struct {
|
||||||
|
|
||||||
category Category `param:"category,query" validValues:"spot"`
|
category Category `param:"category,query" validValues:"spot"`
|
||||||
|
|
||||||
symbol *string `param:"symbol,query"`
|
symbol *string `param:"symbol,query"`
|
||||||
orderId *string `param:"orderId,query"`
|
orderId *string `param:"orderId,query"`
|
||||||
|
orderLinkId *string `param:"orderLinkId,query"`
|
||||||
|
|
||||||
// startTime the start timestamp (ms)
|
// startTime the start timestamp (ms)
|
||||||
// startTime and endTime are not passed, return 7 days by default;
|
// startTime and endTime are not passed, return 7 days by default;
|
||||||
|
|
|
@ -31,6 +31,11 @@ func (g *GetExecutionListRequest) OrderId(orderId string) *GetExecutionListReque
|
||||||
return g
|
return g
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (g *GetExecutionListRequest) OrderLinkId(orderLinkId string) *GetExecutionListRequest {
|
||||||
|
g.orderLinkId = &orderLinkId
|
||||||
|
return g
|
||||||
|
}
|
||||||
|
|
||||||
func (g *GetExecutionListRequest) StartTime(startTime time.Time) *GetExecutionListRequest {
|
func (g *GetExecutionListRequest) StartTime(startTime time.Time) *GetExecutionListRequest {
|
||||||
g.startTime = &startTime
|
g.startTime = &startTime
|
||||||
return g
|
return g
|
||||||
|
@ -86,6 +91,14 @@ func (g *GetExecutionListRequest) GetQueryParameters() (url.Values, error) {
|
||||||
params["orderId"] = orderId
|
params["orderId"] = orderId
|
||||||
} else {
|
} else {
|
||||||
}
|
}
|
||||||
|
// check orderLinkId field -> json key orderLinkId
|
||||||
|
if g.orderLinkId != nil {
|
||||||
|
orderLinkId := *g.orderLinkId
|
||||||
|
|
||||||
|
// assign parameter of orderLinkId
|
||||||
|
params["orderLinkId"] = orderLinkId
|
||||||
|
} else {
|
||||||
|
}
|
||||||
// check startTime field -> json key startTime
|
// check startTime field -> json key startTime
|
||||||
if g.startTime != nil {
|
if g.startTime != nil {
|
||||||
startTime := *g.startTime
|
startTime := *g.startTime
|
||||||
|
@ -275,7 +288,6 @@ func (g *GetExecutionListRequest) Do(ctx context.Context) (*TradesResponse, erro
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var data TradesResponse
|
var data TradesResponse
|
||||||
if err := json.Unmarshal(apiResponse.Result, &data); err != nil {
|
if err := json.Unmarshal(apiResponse.Result, &data); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
|
|
|
@ -325,7 +325,7 @@ func v3ToGlobalTrade(trade v3.Trade) (*types.Trade, error) {
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func toGlobalTrade(trade bybitapi.Trade, feeDetail SymbolFeeDetail) (*types.Trade, error) {
|
func toGlobalTrade(trade bybitapi.Trade) (*types.Trade, error) {
|
||||||
side, err := toGlobalSideType(trade.Side)
|
side, err := toGlobalSideType(trade.Side)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("unexpected side: %s, err: %w", trade.Side, err)
|
return nil, fmt.Errorf("unexpected side: %s, err: %w", trade.Side, err)
|
||||||
|
@ -339,8 +339,6 @@ func toGlobalTrade(trade bybitapi.Trade, feeDetail SymbolFeeDetail) (*types.Trad
|
||||||
return nil, fmt.Errorf("unexpected trade id: %s, err: %w", trade.ExecId, err)
|
return nil, fmt.Errorf("unexpected trade id: %s, err: %w", trade.ExecId, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
fc, _ := calculateFee(trade, feeDetail)
|
|
||||||
|
|
||||||
return &types.Trade{
|
return &types.Trade{
|
||||||
ID: tradeIdNum,
|
ID: tradeIdNum,
|
||||||
OrderID: orderIdNum,
|
OrderID: orderIdNum,
|
||||||
|
@ -354,7 +352,7 @@ func toGlobalTrade(trade bybitapi.Trade, feeDetail SymbolFeeDetail) (*types.Trad
|
||||||
IsMaker: trade.IsMaker,
|
IsMaker: trade.IsMaker,
|
||||||
Time: types.Time(trade.ExecTime),
|
Time: types.Time(trade.ExecTime),
|
||||||
Fee: trade.ExecFee,
|
Fee: trade.ExecFee,
|
||||||
FeeCurrency: fc,
|
FeeCurrency: trade.FeeCurrency,
|
||||||
IsMargin: false,
|
IsMargin: false,
|
||||||
IsFutures: false,
|
IsFutures: false,
|
||||||
IsIsolated: false,
|
IsIsolated: false,
|
||||||
|
|
|
@ -231,15 +231,17 @@ func (e *Exchange) QueryOrder(ctx context.Context, q types.OrderQuery) (*types.O
|
||||||
return toGlobalOrder(res.List[0])
|
return toGlobalOrder(res.List[0])
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// QueryOrderTrades You can query by symbol, baseCoin, orderId and orderLinkId, and if you pass multiple params,
|
||||||
|
// the system will process them according to this priority: orderId > orderLinkId > symbol > baseCoin.
|
||||||
func (e *Exchange) QueryOrderTrades(ctx context.Context, q types.OrderQuery) (trades []types.Trade, err error) {
|
func (e *Exchange) QueryOrderTrades(ctx context.Context, q types.OrderQuery) (trades []types.Trade, err error) {
|
||||||
|
req := e.client.NewGetExecutionListRequest()
|
||||||
if len(q.ClientOrderID) != 0 {
|
if len(q.ClientOrderID) != 0 {
|
||||||
log.Warn("!!!BYBIT EXCHANGE API NOTICE!!! Bybit does not support searching for trades using OrderClientId.")
|
req.OrderLinkId(q.ClientOrderID)
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(q.OrderID) == 0 {
|
if len(q.OrderID) != 0 {
|
||||||
return nil, errors.New("orderID is required parameter")
|
req.OrderLinkId(q.OrderID)
|
||||||
}
|
}
|
||||||
req := e.client.NewGetExecutionListRequest().OrderId(q.OrderID)
|
|
||||||
|
|
||||||
if len(q.Symbol) != 0 {
|
if len(q.Symbol) != 0 {
|
||||||
req.Symbol(q.Symbol)
|
req.Symbol(q.Symbol)
|
||||||
|
@ -437,11 +439,7 @@ func (e *Exchange) queryTrades(ctx context.Context, req *bybitapi.GetExecutionLi
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, trade := range res.List {
|
for _, trade := range res.List {
|
||||||
feeRate, err := pollAndGetFeeRate(ctx, trade.Symbol, e.FeeRatePoller, e.marketsInfo)
|
trade, err := toGlobalTrade(trade)
|
||||||
if err != nil {
|
|
||||||
return nil, fmt.Errorf("failed to get fee rate, err: %v", err)
|
|
||||||
}
|
|
||||||
trade, err := toGlobalTrade(trade, feeRate)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("failed to convert trade, err: %v", err)
|
return nil, fmt.Errorf("failed to convert trade, err: %v", err)
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user