From f5feb72355c6deec2d5931456e9fd12a3501c857 Mon Sep 17 00:00:00 2001 From: c9s Date: Tue, 25 Jul 2023 13:35:08 +0800 Subject: [PATCH 1/5] max: add fee_discounted to Trade struct for RESTful api --- pkg/exchange/max/convert.go | 5 +---- pkg/exchange/max/maxapi/userdata.go | 4 ++-- .../maxapi/v3/get_wallet_trades_request_requestgen.go | 1 - pkg/exchange/max/maxapi/v3/trade.go | 10 +++++++++- 4 files changed, 12 insertions(+), 8 deletions(-) diff --git a/pkg/exchange/max/convert.go b/pkg/exchange/max/convert.go index 48b7687f7..3368ffc7b 100644 --- a/pkg/exchange/max/convert.go +++ b/pkg/exchange/max/convert.go @@ -285,9 +285,6 @@ func convertWebSocketTrade(t max.TradeUpdate) (*types.Trade, error) { // skip trade ID that is the same. however this should not happen var side = toGlobalSideType(t.Side) - // trade time - mts := time.Unix(0, t.Timestamp*int64(time.Millisecond)) - return &types.Trade{ ID: t.ID, OrderID: t.OrderID, @@ -301,7 +298,7 @@ func convertWebSocketTrade(t max.TradeUpdate) (*types.Trade, error) { Fee: t.Fee, FeeCurrency: toGlobalCurrency(t.FeeCurrency), QuoteQuantity: t.Price.Mul(t.Volume), - Time: types.Time(mts), + Time: types.Time(t.Timestamp.Time()), }, nil } diff --git a/pkg/exchange/max/maxapi/userdata.go b/pkg/exchange/max/maxapi/userdata.go index 26ff6cf4b..03a06f8cc 100644 --- a/pkg/exchange/max/maxapi/userdata.go +++ b/pkg/exchange/max/maxapi/userdata.go @@ -104,8 +104,8 @@ type TradeUpdate struct { FeeCurrency string `json:"fc"` FeeDiscounted bool `json:"fd"` - Timestamp int64 `json:"T"` - UpdateTime int64 `json:"TU"` + Timestamp types.MillisecondTimestamp `json:"T"` + UpdateTime int64 `json:"TU"` OrderID uint64 `json:"oi"` diff --git a/pkg/exchange/max/maxapi/v3/get_wallet_trades_request_requestgen.go b/pkg/exchange/max/maxapi/v3/get_wallet_trades_request_requestgen.go index 647916103..2baeeb611 100644 --- a/pkg/exchange/max/maxapi/v3/get_wallet_trades_request_requestgen.go +++ b/pkg/exchange/max/maxapi/v3/get_wallet_trades_request_requestgen.go @@ -6,7 +6,6 @@ import ( "context" "encoding/json" "fmt" - "github.com/c9s/bbgo/pkg/exchange/max/maxapi" "net/url" "reflect" "regexp" diff --git a/pkg/exchange/max/maxapi/v3/trade.go b/pkg/exchange/max/maxapi/v3/trade.go index c9e975bb0..1774e4ba5 100644 --- a/pkg/exchange/max/maxapi/v3/trade.go +++ b/pkg/exchange/max/maxapi/v3/trade.go @@ -5,6 +5,13 @@ import ( "github.com/c9s/bbgo/pkg/types" ) +type Liquidity string + +const ( + LiquidityMaker = "maker" + LiquidityTaker = "taker" +) + type Trade struct { ID uint64 `json:"id" db:"exchange_id"` WalletType WalletType `json:"wallet_type,omitempty"` @@ -18,7 +25,8 @@ type Trade struct { OrderID uint64 `json:"order_id"` Fee fixedpoint.Value `json:"fee"` // float number as string FeeCurrency string `json:"fee_currency"` - Liquidity string `json:"liquidity"` + FeeDiscounted bool `json:"fee_discounted"` + Liquidity Liquidity `json:"liquidity"` SelfTradeBidFee fixedpoint.Value `json:"self_trade_bid_fee"` SelfTradeBidFeeCurrency string `json:"self_trade_bid_fee_currency"` SelfTradeBidOrderID uint64 `json:"self_trade_bid_order_id"` From 4de82ccdff302332d420e6c07c8b6d1e304aa3d3 Mon Sep 17 00:00:00 2001 From: c9s Date: Tue, 25 Jul 2023 13:37:31 +0800 Subject: [PATCH 2/5] max: use types.MillisecondTimestamp for UpdateTime field --- pkg/exchange/max/maxapi/userdata.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkg/exchange/max/maxapi/userdata.go b/pkg/exchange/max/maxapi/userdata.go index 03a06f8cc..551d3d685 100644 --- a/pkg/exchange/max/maxapi/userdata.go +++ b/pkg/exchange/max/maxapi/userdata.go @@ -105,7 +105,7 @@ type TradeUpdate struct { FeeDiscounted bool `json:"fd"` Timestamp types.MillisecondTimestamp `json:"T"` - UpdateTime int64 `json:"TU"` + UpdateTime types.MillisecondTimestamp `json:"TU"` OrderID uint64 `json:"oi"` From fcca3f6432b08b6d2230ffad626b80650c9152a2 Mon Sep 17 00:00:00 2001 From: c9s Date: Tue, 25 Jul 2023 13:40:10 +0800 Subject: [PATCH 3/5] types: add fee discounted field to the global trade struct --- pkg/exchange/max/convert.go | 1 + pkg/exchange/max/maxapi/userdata_test.go | 2 +- .../max/maxapi/v3/get_wallet_trades_request_requestgen.go | 2 +- pkg/types/trade.go | 6 ++++++ 4 files changed, 9 insertions(+), 2 deletions(-) diff --git a/pkg/exchange/max/convert.go b/pkg/exchange/max/convert.go index 3368ffc7b..4c578bde6 100644 --- a/pkg/exchange/max/convert.go +++ b/pkg/exchange/max/convert.go @@ -297,6 +297,7 @@ func convertWebSocketTrade(t max.TradeUpdate) (*types.Trade, error) { IsMaker: t.Maker, Fee: t.Fee, FeeCurrency: toGlobalCurrency(t.FeeCurrency), + FeeDiscounted: t.FeeDiscounted, QuoteQuantity: t.Price.Mul(t.Volume), Time: types.Time(t.Timestamp.Time()), }, nil diff --git a/pkg/exchange/max/maxapi/userdata_test.go b/pkg/exchange/max/maxapi/userdata_test.go index 2967e16df..5c4880ce5 100644 --- a/pkg/exchange/max/maxapi/userdata_test.go +++ b/pkg/exchange/max/maxapi/userdata_test.go @@ -39,7 +39,7 @@ func Test_parseTradeSnapshotEvent(t *testing.T) { assert.Equal(t, 1, len(evt.Trades)) assert.Equal(t, "bid", evt.Trades[0].Side) assert.Equal(t, "ethtwd", evt.Trades[0].Market) - assert.Equal(t, int64(1521726960357), evt.Trades[0].Timestamp) + assert.Equal(t, int64(1521726960357), evt.Trades[0].Timestamp.Time().UnixMilli()) assert.Equal(t, "3.2", evt.Trades[0].Fee.String()) assert.Equal(t, "twd", evt.Trades[0].FeeCurrency) } diff --git a/pkg/exchange/max/maxapi/v3/get_wallet_trades_request_requestgen.go b/pkg/exchange/max/maxapi/v3/get_wallet_trades_request_requestgen.go index 2baeeb611..ec7614c10 100644 --- a/pkg/exchange/max/maxapi/v3/get_wallet_trades_request_requestgen.go +++ b/pkg/exchange/max/maxapi/v3/get_wallet_trades_request_requestgen.go @@ -38,7 +38,7 @@ func (g *GetWalletTradesRequest) Limit(limit uint64) *GetWalletTradesRequest { return g } -func (g *GetWalletTradesRequest) WalletType(walletType max.WalletType) *GetWalletTradesRequest { +func (g *GetWalletTradesRequest) WalletType(walletType WalletType) *GetWalletTradesRequest { g.walletType = walletType return g } diff --git a/pkg/types/trade.go b/pkg/types/trade.go index 0db78b6ef..f80b864a2 100644 --- a/pkg/types/trade.go +++ b/pkg/types/trade.go @@ -67,6 +67,12 @@ type Trade struct { Fee fixedpoint.Value `json:"fee" db:"fee"` FeeCurrency string `json:"feeCurrency" db:"fee_currency"` + // FeeDiscounted is an optional field which indicates whether the trade is using the platform fee token for discount. + // When FeeDiscounted = true, means the fee is deducted outside the trade + // By default, it's set to false. + // This is only used by the MAX exchange + FeeDiscounted bool `json:"feeDiscounted" db:"-"` + IsMargin bool `json:"isMargin" db:"is_margin"` IsFutures bool `json:"isFutures" db:"is_futures"` IsIsolated bool `json:"isIsolated" db:"is_isolated"` From b02ac837ea3e7d04eae9c843e983a8b673f1e939 Mon Sep 17 00:00:00 2001 From: c9s Date: Thu, 27 Jul 2023 16:28:54 +0800 Subject: [PATCH 4/5] max: handle SelfTradeBidFeeDiscounted --- pkg/exchange/max/convert.go | 2 ++ pkg/exchange/max/maxapi/v3/trade.go | 35 +++++++++++++++-------------- 2 files changed, 20 insertions(+), 17 deletions(-) diff --git a/pkg/exchange/max/convert.go b/pkg/exchange/max/convert.go index 4c578bde6..b6ea59ba2 100644 --- a/pkg/exchange/max/convert.go +++ b/pkg/exchange/max/convert.go @@ -211,6 +211,7 @@ func toGlobalTradeV3(t v3.Trade) ([]types.Trade, error) { IsMaker: t.IsMaker(), Fee: t.Fee, FeeCurrency: toGlobalCurrency(t.FeeCurrency), + FeeDiscounted: t.FeeDiscounted, QuoteQuantity: t.Funds, Time: types.Time(t.CreatedAt), IsMargin: isMargin, @@ -227,6 +228,7 @@ func toGlobalTradeV3(t v3.Trade) ([]types.Trade, error) { bidTrade.OrderID = t.SelfTradeBidOrderID bidTrade.Fee = t.SelfTradeBidFee bidTrade.FeeCurrency = toGlobalCurrency(t.SelfTradeBidFeeCurrency) + bidTrade.FeeDiscounted = t.SelfTradeBidFeeDiscounted bidTrade.IsBuyer = !trade.IsBuyer bidTrade.IsMaker = !trade.IsMaker trades = append(trades, bidTrade) diff --git a/pkg/exchange/max/maxapi/v3/trade.go b/pkg/exchange/max/maxapi/v3/trade.go index 1774e4ba5..d5569deb6 100644 --- a/pkg/exchange/max/maxapi/v3/trade.go +++ b/pkg/exchange/max/maxapi/v3/trade.go @@ -13,23 +13,24 @@ const ( ) type Trade struct { - ID uint64 `json:"id" db:"exchange_id"` - WalletType WalletType `json:"wallet_type,omitempty"` - Price fixedpoint.Value `json:"price"` - Volume fixedpoint.Value `json:"volume"` - Funds fixedpoint.Value `json:"funds"` - Market string `json:"market"` - MarketName string `json:"market_name"` - CreatedAt types.MillisecondTimestamp `json:"created_at"` - Side string `json:"side"` - OrderID uint64 `json:"order_id"` - Fee fixedpoint.Value `json:"fee"` // float number as string - FeeCurrency string `json:"fee_currency"` - FeeDiscounted bool `json:"fee_discounted"` - Liquidity Liquidity `json:"liquidity"` - SelfTradeBidFee fixedpoint.Value `json:"self_trade_bid_fee"` - SelfTradeBidFeeCurrency string `json:"self_trade_bid_fee_currency"` - SelfTradeBidOrderID uint64 `json:"self_trade_bid_order_id"` + ID uint64 `json:"id" db:"exchange_id"` + WalletType WalletType `json:"wallet_type,omitempty"` + Price fixedpoint.Value `json:"price"` + Volume fixedpoint.Value `json:"volume"` + Funds fixedpoint.Value `json:"funds"` + Market string `json:"market"` + MarketName string `json:"market_name"` + CreatedAt types.MillisecondTimestamp `json:"created_at"` + Side string `json:"side"` + OrderID uint64 `json:"order_id"` + Fee fixedpoint.Value `json:"fee"` // float number as string + FeeCurrency string `json:"fee_currency"` + FeeDiscounted bool `json:"fee_discounted"` + Liquidity Liquidity `json:"liquidity"` + SelfTradeBidFee fixedpoint.Value `json:"self_trade_bid_fee"` + SelfTradeBidFeeCurrency string `json:"self_trade_bid_fee_currency"` + SelfTradeBidFeeDiscounted bool `json:"self_trade_bid_fee_discounted"` + SelfTradeBidOrderID uint64 `json:"self_trade_bid_order_id"` } func (t Trade) IsBuyer() bool { From 4eefe72cb68eae1510b801acd96fd3d5fc01b8be Mon Sep 17 00:00:00 2001 From: c9s Date: Fri, 28 Jul 2023 14:41:36 +0800 Subject: [PATCH 5/5] service: fix db reflection --- pkg/service/reflect.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pkg/service/reflect.go b/pkg/service/reflect.go index b60c0c337..1f8ce68a6 100644 --- a/pkg/service/reflect.go +++ b/pkg/service/reflect.go @@ -40,7 +40,7 @@ func placeholdersOf(record interface{}) []string { for i := 0; i < rt.NumField(); i++ { fieldType := rt.Field(i) if tag, ok := fieldType.Tag.Lookup("db"); ok { - if tag == "gid" { + if tag == "gid" || tag == "-" || tag == "" { continue } @@ -65,7 +65,7 @@ func fieldsNamesOf(record interface{}) []string { for i := 0; i < rt.NumField(); i++ { fieldType := rt.Field(i) if tag, ok := fieldType.Tag.Lookup("db"); ok { - if tag == "gid" { + if tag == "gid" || tag == "-" || tag == "" { continue }