From 8f2d551399348f485ad28d98387df10110546273 Mon Sep 17 00:00:00 2001 From: narumi <4680567+narumiruna@users.noreply.github.com> Date: Fri, 23 Feb 2024 13:46:07 +0800 Subject: [PATCH 1/2] add price type --- config/autobuy.yaml | 4 +-- config/rebalance.yaml | 1 + pkg/strategy/autobuy/strategy.go | 23 ++++----------- pkg/strategy/autobuy/types.go | 10 ------- pkg/strategy/rebalance/strategy.go | 12 +++++--- pkg/types/price_type.go | 45 ++++++++++++++++++++++++++++++ 6 files changed, 61 insertions(+), 34 deletions(-) delete mode 100644 pkg/strategy/autobuy/types.go create mode 100644 pkg/types/price_type.go diff --git a/config/autobuy.yaml b/config/autobuy.yaml index 7b174ea33..4e55e0833 100644 --- a/config/autobuy.yaml +++ b/config/autobuy.yaml @@ -6,8 +6,8 @@ exchangeStrategies: symbol: MAXTWD schedule: "@every 1s" threshold: 200 - # price type: buy, sell, last or mid - priceType: buy + # price type: LAST, BUY, SELL, MID, TAKER, MAKER + priceType: BUY # order quantity or amount # quantity: 100 diff --git a/config/rebalance.yaml b/config/rebalance.yaml index e98c5a82c..a73207f32 100644 --- a/config/rebalance.yaml +++ b/config/rebalance.yaml @@ -11,5 +11,6 @@ exchangeStrategies: threshold: 1% maxAmount: 1_000 # max amount to buy or sell per order orderType: LIMIT_MAKER # LIMIT, LIMIT_MAKER or MARKET + priceType: MAKER # LAST, MID, TAKER or MAKER dryRun: true onStart: true diff --git a/pkg/strategy/autobuy/strategy.go b/pkg/strategy/autobuy/strategy.go index dbb44a88d..87e0bb1eb 100644 --- a/pkg/strategy/autobuy/strategy.go +++ b/pkg/strategy/autobuy/strategy.go @@ -18,8 +18,6 @@ const ID = "autobuy" var log = logrus.WithField("strategy", ID) -var two = fixedpoint.NewFromInt(2) - func init() { bbgo.RegisterStrategy(ID, &Strategy{}) } @@ -33,7 +31,7 @@ type Strategy struct { Symbol string `json:"symbol"` Schedule string `json:"schedule"` Threshold fixedpoint.Value `json:"threshold"` - PriceType PriceType `json:"priceType"` + PriceType types.PriceType `json:"priceType"` Bollinger *types.BollingerSetting `json:"bollinger"` DryRun bool `json:"dryRun"` @@ -67,7 +65,7 @@ func (s *Strategy) Validate() error { func (s *Strategy) Defaults() error { if s.PriceType == "" { - s.PriceType = PriceTypeBuy + s.PriceType = types.PriceTypeMaker } return nil } @@ -122,19 +120,8 @@ func (s *Strategy) autobuy(ctx context.Context) { return } - var price fixedpoint.Value - switch s.PriceType { - case PriceTypeLast: - price = ticker.Last - case PriceTypeBuy: - price = ticker.Buy - case PriceTypeSell: - price = ticker.Sell - case PriceTypeMid: - price = ticker.Buy.Add(ticker.Sell).Div(two) - default: - price = ticker.Buy - } + side := types.SideTypeBuy + price := s.PriceType.Map(ticker, side) if price.Float64() > s.boll.UpBand.Last(0) { log.Infof("price %s is higher than upper band %f, skip", price.String(), s.boll.UpBand.Last(0)) @@ -150,7 +137,7 @@ func (s *Strategy) autobuy(ctx context.Context) { quantity := s.CalculateQuantity(price) submitOrder := types.SubmitOrder{ Symbol: s.Symbol, - Side: types.SideTypeBuy, + Side: side, Type: types.OrderTypeLimitMaker, Quantity: quantity, Price: price, diff --git a/pkg/strategy/autobuy/types.go b/pkg/strategy/autobuy/types.go deleted file mode 100644 index 0e3347ae0..000000000 --- a/pkg/strategy/autobuy/types.go +++ /dev/null @@ -1,10 +0,0 @@ -package autobuy - -type PriceType string - -const ( - PriceTypeLast = PriceType("last") - PriceTypeBuy = PriceType("buy") - PriceTypeSell = PriceType("sell") - PriceTypeMid = PriceType("mid") -) diff --git a/pkg/strategy/rebalance/strategy.go b/pkg/strategy/rebalance/strategy.go index 0b1a0909a..a3846d242 100644 --- a/pkg/strategy/rebalance/strategy.go +++ b/pkg/strategy/rebalance/strategy.go @@ -33,6 +33,7 @@ type Strategy struct { Threshold fixedpoint.Value `json:"threshold"` MaxAmount fixedpoint.Value `json:"maxAmount"` // max amount to buy or sell per order OrderType types.OrderType `json:"orderType"` + PriceType types.PriceType `json:"priceType"` DryRun bool `json:"dryRun"` OnStart bool `json:"onStart"` // rebalance on start @@ -46,6 +47,10 @@ func (s *Strategy) Defaults() error { if s.OrderType == "" { s.OrderType = types.OrderTypeLimitMaker } + + if s.PriceType == "" { + s.PriceType = types.PriceTypeMaker + } return nil } @@ -243,12 +248,11 @@ func (s *Strategy) generateOrder(ctx context.Context) (*types.SubmitOrder, error return nil, err } - var price fixedpoint.Value + price := s.PriceType.Map(ticker, side) + if side == types.SideTypeBuy { - price = ticker.Buy - quantity = fixedpoint.Min(quantity, balances[s.QuoteCurrency].Available.Div(ticker.Sell)) + quantity = fixedpoint.Min(quantity, balances[s.QuoteCurrency].Available.Div(price)) } else if side == types.SideTypeSell { - price = ticker.Sell quantity = fixedpoint.Min(quantity, balances[market.BaseCurrency].Available) } diff --git a/pkg/types/price_type.go b/pkg/types/price_type.go new file mode 100644 index 000000000..a51648104 --- /dev/null +++ b/pkg/types/price_type.go @@ -0,0 +1,45 @@ +package types + +import ( + "github.com/c9s/bbgo/pkg/fixedpoint" +) + +type PriceType string + +const ( + PriceTypeLast PriceType = "LAST" + PriceTypeBuy PriceType = "BUY" // BID + PriceTypeSell PriceType = "SELL" // ASK + PriceTypeMid PriceType = "MID" + PriceTypeMaker PriceType = "MAKER" + PriceTypeTaker PriceType = "TAKER" +) + +func (p PriceType) Map(ticker *Ticker, side SideType) fixedpoint.Value { + price := ticker.Last + + switch p { + case PriceTypeLast: + price = ticker.Last + case PriceTypeBuy: + price = ticker.Buy + case PriceTypeSell: + price = ticker.Sell + case PriceTypeMid: + price = ticker.Buy.Add(ticker.Sell).Div(fixedpoint.NewFromInt(2)) + case PriceTypeMaker: + if side == SideTypeBuy { + price = ticker.Buy + } else if side == SideTypeSell { + price = ticker.Sell + } + case PriceTypeTaker: + if side == SideTypeBuy { + price = ticker.Sell + } else if side == SideTypeSell { + price = ticker.Buy + } + } + + return price +} From dae445ad5ca8150ee37fc97521e006f20dd77d9a Mon Sep 17 00:00:00 2001 From: narumi <4680567+narumiruna@users.noreply.github.com> Date: Fri, 23 Feb 2024 16:29:26 +0800 Subject: [PATCH 2/2] unmarshal price type --- pkg/types/price_type.go | 42 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 42 insertions(+) diff --git a/pkg/types/price_type.go b/pkg/types/price_type.go index a51648104..bd2fc477f 100644 --- a/pkg/types/price_type.go +++ b/pkg/types/price_type.go @@ -1,7 +1,11 @@ package types import ( + "encoding/json" + "strings" + "github.com/c9s/bbgo/pkg/fixedpoint" + "github.com/pkg/errors" ) type PriceType string @@ -15,6 +19,44 @@ const ( PriceTypeTaker PriceType = "TAKER" ) +var ErrInvalidPriceType = errors.New("invalid price type") + +func StrToPriceType(s string) (price PriceType, err error) { + switch strings.ToLower(s) { + case "last": + price = PriceTypeLast + case "buy": + price = PriceTypeBuy + case "sell": + price = PriceTypeSell + case "mid": + price = PriceTypeMid + case "maker": + price = PriceTypeMaker + case "taker": + price = PriceTypeTaker + default: + err = ErrInvalidPriceType + } + return price, err +} + +func (p *PriceType) UnmarshalJSON(data []byte) error { + var s string + + if err := json.Unmarshal(data, &s); err != nil { + return err + } + + t, err := StrToPriceType(s) + if err != nil { + return err + } + + *p = t + return nil +} + func (p PriceType) Map(ticker *Ticker, side SideType) fixedpoint.Value { price := ticker.Last