From bdfcbdcf56632c5a43738c414744ef5e091e45d1 Mon Sep 17 00:00:00 2001 From: edwin Date: Mon, 30 Sep 2024 16:28:07 +0800 Subject: [PATCH] pkg/exchange: move common execution field to bybitapi.trade --- pkg/exchange/bybit/types.go | 25 +---- pkg/exchange/bybit/types_test.go | 160 ++++++++++++++++++------------- 2 files changed, 99 insertions(+), 86 deletions(-) diff --git a/pkg/exchange/bybit/types.go b/pkg/exchange/bybit/types.go index 1c95f638c..48641ee74 100644 --- a/pkg/exchange/bybit/types.go +++ b/pkg/exchange/bybit/types.go @@ -287,33 +287,18 @@ func (k *KLine) toGlobalKLine(symbol string) (types.KLine, error) { } type TradeEvent struct { + bybitapi.Trade // linear and inverse order id format: 42f4f364-82e1-49d3-ad1d-cd8cf9aa308d (UUID format) // spot: 1468264727470772736 (only numbers) // we only use spot trading. - OrderId string `json:"orderId"` OrderLinkId string `json:"orderLinkId"` Category bybitapi.Category `json:"category"` - Symbol string `json:"symbol"` - ExecId string `json:"execId"` - ExecPrice fixedpoint.Value `json:"execPrice"` - ExecQty fixedpoint.Value `json:"execQty"` - // Is maker order. true: maker, false: taker - IsMaker bool `json:"isMaker"` // Paradigm block trade ID BlockTradeId string `json:"blockTradeId"` - // Order type. Market,Limit - OrderType bybitapi.OrderType `json:"orderType"` - // Side. Buy,Sell - Side bybitapi.Side `json:"side"` - // Executed timestamp(ms) - ExecTime types.MillisecondTimestamp `json:"execTime"` // Closed position size ClosedSize fixedpoint.Value `json:"closedSize"` - /* The following parameters do not support SPOT trading. */ - // Executed trading fee. You can get spot fee currency instruction here. Normal spot is not supported - ExecFee fixedpoint.Value `json:"execFee"` // Executed type. Normal spot is not supported ExecType string `json:"execType"` // Executed order value. Normal spot is not supported @@ -377,7 +362,7 @@ func (t *TradeEvent) toGlobalTrade(symbolFee symbolFeeDetail) (*types.Trade, err Fee: fixedpoint.Zero, FeeCurrency: "", } - trade.FeeCurrency, trade.Fee = calculateFee(*t, symbolFee) + trade.FeeCurrency, trade.Fee = calculateFee(t.Trade, symbolFee) return trade, nil } @@ -400,7 +385,7 @@ func (t *TradeEvent) toGlobalTrade(symbolFee symbolFeeDetail) (*types.Trade, err // IsMakerOrder = FALSE // -> Side = Buy -> base currency (BTC) // -> Side = Sell -> quote currency (USDT) -func calculateFee(t TradeEvent, feeDetail symbolFeeDetail) (string, fixedpoint.Value) { +func calculateFee(t bybitapi.Trade, feeDetail symbolFeeDetail) (string, fixedpoint.Value) { if feeDetail.MakerFeeRate.Sign() > 0 || !t.IsMaker { if t.Side == bybitapi.SideBuy { return feeDetail.BaseCoin, baseCoinAsFee(t, feeDetail) @@ -414,14 +399,14 @@ func calculateFee(t TradeEvent, feeDetail symbolFeeDetail) (string, fixedpoint.V return feeDetail.BaseCoin, baseCoinAsFee(t, feeDetail) } -func baseCoinAsFee(t TradeEvent, feeDetail symbolFeeDetail) fixedpoint.Value { +func baseCoinAsFee(t bybitapi.Trade, feeDetail symbolFeeDetail) fixedpoint.Value { if t.IsMaker { return feeDetail.MakerFeeRate.Mul(t.ExecQty) } return feeDetail.TakerFeeRate.Mul(t.ExecQty) } -func quoteCoinAsFee(t TradeEvent, feeDetail symbolFeeDetail) fixedpoint.Value { +func quoteCoinAsFee(t bybitapi.Trade, feeDetail symbolFeeDetail) fixedpoint.Value { baseFee := t.ExecPrice.Mul(t.ExecQty) if t.IsMaker { return feeDetail.MakerFeeRate.Mul(baseFee) diff --git a/pkg/exchange/bybit/types_test.go b/pkg/exchange/bybit/types_test.go index 603c49f09..f469e84fd 100644 --- a/pkg/exchange/bybit/types_test.go +++ b/pkg/exchange/bybit/types_test.go @@ -556,20 +556,22 @@ func TestTradeEvent_toGlobalTrade(t *testing.T) { FeeCurrency: "BTC", } tradeEvent := TradeEvent{ - OrderId: fmt.Sprintf("%d", expTrade.OrderID), + Trade: bybitapi.Trade{ + OrderId: fmt.Sprintf("%d", expTrade.OrderID), + Symbol: expTrade.Symbol, + ExecId: fmt.Sprintf("%d", expTrade.ID), + ExecPrice: expTrade.Price, + ExecQty: expTrade.Quantity, + IsMaker: false, + OrderType: "", + Side: bybitapi.SideBuy, + ExecTime: types.MillisecondTimestamp(timeNow), + ExecFee: fixedpoint.NewFromInt(0), + }, OrderLinkId: "1691419101980", Category: "spot", - Symbol: expTrade.Symbol, - ExecId: fmt.Sprintf("%d", expTrade.ID), - ExecPrice: expTrade.Price, - ExecQty: expTrade.Quantity, - IsMaker: false, BlockTradeId: "", - OrderType: "", - Side: bybitapi.SideBuy, - ExecTime: types.MillisecondTimestamp(timeNow), ClosedSize: fixedpoint.NewFromInt(0), - ExecFee: fixedpoint.NewFromInt(0), ExecType: "", ExecValue: fixedpoint.NewFromInt(0), FeeRate: fixedpoint.NewFromInt(0), @@ -602,8 +604,10 @@ func TestTradeEvent_toGlobalTrade(t *testing.T) { t.Run("unexpected side", func(t *testing.T) { tradeEvent := TradeEvent{ + Trade: bybitapi.Trade{ + Side: bybitapi.Side("BOTH"), + }, Category: "spot", - Side: bybitapi.Side("BOTH"), } actualTrade, err := tradeEvent.toGlobalTrade(symbolFeeDetail{}) @@ -613,9 +617,11 @@ func TestTradeEvent_toGlobalTrade(t *testing.T) { t.Run("unexpected order id", func(t *testing.T) { tradeEvent := TradeEvent{ + Trade: bybitapi.Trade{ + Side: bybitapi.SideBuy, + OrderId: "ABCD3123", + }, Category: "spot", - Side: bybitapi.SideBuy, - OrderId: "ABCD3123", } _, nerr := strconv.ParseUint(tradeEvent.OrderId, 10, 64) @@ -626,10 +632,12 @@ func TestTradeEvent_toGlobalTrade(t *testing.T) { t.Run("unexpected exec id", func(t *testing.T) { tradeEvent := TradeEvent{ + Trade: bybitapi.Trade{ + Side: bybitapi.SideBuy, + OrderId: "3123", + ExecId: "ABC3123", + }, Category: "spot", - Side: bybitapi.SideBuy, - OrderId: "3123", - ExecId: "ABC3123", } _, nerr := strconv.ParseUint(tradeEvent.ExecId, 10, 64) @@ -654,13 +662,15 @@ func TestTradeEvent_CalculateFee(t *testing.T) { qty := fixedpoint.NewFromFloat(0.010000) price := fixedpoint.NewFromFloat(28830.8100) trade := &TradeEvent{ - ExecPrice: price, - ExecQty: qty, - IsMaker: true, - Side: bybitapi.SideBuy, + Trade: bybitapi.Trade{ + ExecPrice: price, + ExecQty: qty, + IsMaker: true, + Side: bybitapi.SideBuy, + }, } - feeCurrency, fee := calculateFee(*trade, symbolFee) + feeCurrency, fee := calculateFee(trade.Trade, symbolFee) assert.Equal(t, feeCurrency, "BTC") assert.Equal(t, fee, qty.Mul(symbolFee.FeeRate.MakerFeeRate)) }) @@ -679,13 +689,15 @@ func TestTradeEvent_CalculateFee(t *testing.T) { qty := fixedpoint.NewFromFloat(0.010000) price := fixedpoint.NewFromFloat(28830.8099) trade := &TradeEvent{ - ExecPrice: price, - ExecQty: qty, - IsMaker: true, - Side: bybitapi.SideSell, + Trade: bybitapi.Trade{ + ExecPrice: price, + ExecQty: qty, + IsMaker: true, + Side: bybitapi.SideSell, + }, } - feeCurrency, fee := calculateFee(*trade, symbolFee) + feeCurrency, fee := calculateFee(trade.Trade, symbolFee) assert.Equal(t, feeCurrency, "USDT") assert.Equal(t, fee, qty.Mul(price).Mul(symbolFee.FeeRate.MakerFeeRate)) }) @@ -704,13 +716,15 @@ func TestTradeEvent_CalculateFee(t *testing.T) { qty := fixedpoint.NewFromFloat(0.010000) price := fixedpoint.NewFromFloat(28830.8100) trade := &TradeEvent{ - ExecPrice: price, - ExecQty: qty, - IsMaker: false, - Side: bybitapi.SideBuy, + Trade: bybitapi.Trade{ + ExecPrice: price, + ExecQty: qty, + IsMaker: false, + Side: bybitapi.SideBuy, + }, } - feeCurrency, fee := calculateFee(*trade, symbolFee) + feeCurrency, fee := calculateFee(trade.Trade, symbolFee) assert.Equal(t, feeCurrency, "BTC") assert.Equal(t, fee, qty.Mul(symbolFee.FeeRate.TakerFeeRate)) }) @@ -729,13 +743,15 @@ func TestTradeEvent_CalculateFee(t *testing.T) { qty := fixedpoint.NewFromFloat(0.010000) price := fixedpoint.NewFromFloat(28830.8099) trade := &TradeEvent{ - ExecPrice: price, - ExecQty: qty, - IsMaker: false, - Side: bybitapi.SideSell, + Trade: bybitapi.Trade{ + ExecPrice: price, + ExecQty: qty, + IsMaker: false, + Side: bybitapi.SideSell, + }, } - feeCurrency, fee := calculateFee(*trade, symbolFee) + feeCurrency, fee := calculateFee(trade.Trade, symbolFee) assert.Equal(t, feeCurrency, "USDT") assert.Equal(t, fee, qty.Mul(price).Mul(symbolFee.FeeRate.TakerFeeRate)) }) @@ -754,13 +770,15 @@ func TestTradeEvent_CalculateFee(t *testing.T) { qty := fixedpoint.NewFromFloat(0.002289) price := fixedpoint.NewFromFloat(28829.7600) trade := &TradeEvent{ - ExecPrice: price, - ExecQty: qty, - IsMaker: true, - Side: bybitapi.SideBuy, + Trade: bybitapi.Trade{ + ExecPrice: price, + ExecQty: qty, + IsMaker: true, + Side: bybitapi.SideBuy, + }, } - feeCurrency, fee := calculateFee(*trade, symbolFee) + feeCurrency, fee := calculateFee(trade.Trade, symbolFee) assert.Equal(t, feeCurrency, "USDT") assert.Equal(t, fee, qty.Mul(price).Mul(symbolFee.FeeRate.MakerFeeRate)) }) @@ -779,13 +797,15 @@ func TestTradeEvent_CalculateFee(t *testing.T) { qty := fixedpoint.NewFromFloat(0.002289) price := fixedpoint.NewFromFloat(28829.7600) trade := &TradeEvent{ - ExecPrice: price, - ExecQty: qty, - IsMaker: true, - Side: bybitapi.SideSell, + Trade: bybitapi.Trade{ + ExecPrice: price, + ExecQty: qty, + IsMaker: true, + Side: bybitapi.SideSell, + }, } - feeCurrency, fee := calculateFee(*trade, symbolFee) + feeCurrency, fee := calculateFee(trade.Trade, symbolFee) assert.Equal(t, feeCurrency, "BTC") assert.Equal(t, fee, qty.Mul(symbolFee.FeeRate.MakerFeeRate)) }) @@ -804,13 +824,15 @@ func TestTradeEvent_CalculateFee(t *testing.T) { qty := fixedpoint.NewFromFloat(0.002289) price := fixedpoint.NewFromFloat(28829.7600) trade := &TradeEvent{ - ExecPrice: price, - ExecQty: qty, - IsMaker: false, - Side: bybitapi.SideBuy, + Trade: bybitapi.Trade{ + ExecPrice: price, + ExecQty: qty, + IsMaker: false, + Side: bybitapi.SideBuy, + }, } - feeCurrency, fee := calculateFee(*trade, symbolFee) + feeCurrency, fee := calculateFee(trade.Trade, symbolFee) assert.Equal(t, feeCurrency, "BTC") assert.Equal(t, fee, qty.Mul(symbolFee.FeeRate.TakerFeeRate)) }) @@ -829,13 +851,15 @@ func TestTradeEvent_CalculateFee(t *testing.T) { qty := fixedpoint.NewFromFloat(0.002289) price := fixedpoint.NewFromFloat(28829.7600) trade := &TradeEvent{ - ExecPrice: price, - ExecQty: qty, - IsMaker: false, - Side: bybitapi.SideSell, + Trade: bybitapi.Trade{ + ExecPrice: price, + ExecQty: qty, + IsMaker: false, + Side: bybitapi.SideSell, + }, } - feeCurrency, fee := calculateFee(*trade, symbolFee) + feeCurrency, fee := calculateFee(trade.Trade, symbolFee) assert.Equal(t, feeCurrency, "USDT") assert.Equal(t, fee, qty.Mul(price).Mul(symbolFee.FeeRate.TakerFeeRate)) }) @@ -855,14 +879,16 @@ func TestTradeEvent_baseCoinAsFee(t *testing.T) { qty := fixedpoint.NewFromFloat(0.002289) price := fixedpoint.NewFromFloat(28829.7600) trade := &TradeEvent{ - ExecPrice: price, - ExecQty: qty, - IsMaker: false, + Trade: bybitapi.Trade{ + ExecPrice: price, + ExecQty: qty, + IsMaker: false, + }, } - assert.Equal(t, symbolFee.FeeRate.TakerFeeRate.Mul(qty), baseCoinAsFee(*trade, symbolFee)) + assert.Equal(t, symbolFee.FeeRate.TakerFeeRate.Mul(qty), baseCoinAsFee(trade.Trade, symbolFee)) trade.IsMaker = true - assert.Equal(t, symbolFee.FeeRate.MakerFeeRate.Mul(qty), baseCoinAsFee(*trade, symbolFee)) + assert.Equal(t, symbolFee.FeeRate.MakerFeeRate.Mul(qty), baseCoinAsFee(trade.Trade, symbolFee)) } func TestTradeEvent_quoteCoinAsFee(t *testing.T) { @@ -878,12 +904,14 @@ func TestTradeEvent_quoteCoinAsFee(t *testing.T) { qty := fixedpoint.NewFromFloat(0.002289) price := fixedpoint.NewFromFloat(28829.7600) trade := &TradeEvent{ - ExecPrice: price, - ExecQty: qty, - IsMaker: false, + Trade: bybitapi.Trade{ + ExecPrice: price, + ExecQty: qty, + IsMaker: false, + }, } - assert.Equal(t, symbolFee.FeeRate.TakerFeeRate.Mul(qty.Mul(price)), quoteCoinAsFee(*trade, symbolFee)) + assert.Equal(t, symbolFee.FeeRate.TakerFeeRate.Mul(qty.Mul(price)), quoteCoinAsFee(trade.Trade, symbolFee)) trade.IsMaker = true - assert.Equal(t, symbolFee.FeeRate.MakerFeeRate.Mul(qty.Mul(price)), quoteCoinAsFee(*trade, symbolFee)) + assert.Equal(t, symbolFee.FeeRate.MakerFeeRate.Mul(qty.Mul(price)), quoteCoinAsFee(trade.Trade, symbolFee)) }