From d98252482439f95593c2657a2d5dac0393441af9 Mon Sep 17 00:00:00 2001 From: c9s Date: Mon, 8 Jul 2024 14:15:15 +0800 Subject: [PATCH 1/2] liquiditymaker: refactor profit fixer --- pkg/strategy/liquiditymaker/strategy.go | 51 +++++++++++++++++++++++++ pkg/strategy/xdepthmaker/strategy.go | 2 +- 2 files changed, 52 insertions(+), 1 deletion(-) diff --git a/pkg/strategy/liquiditymaker/strategy.go b/pkg/strategy/liquiditymaker/strategy.go index d87dbf057..74a80c5ed 100644 --- a/pkg/strategy/liquiditymaker/strategy.go +++ b/pkg/strategy/liquiditymaker/strategy.go @@ -4,6 +4,7 @@ import ( "context" "fmt" "sync" + "time" log "github.com/sirupsen/logrus" @@ -27,6 +28,41 @@ func init() { bbgo.RegisterStrategy(ID, &Strategy{}) } +type ProfitFixer struct { + ProfitFixerConfig *common.ProfitFixerConfig `json:"profitFixer,omitempty"` +} + +func (f *ProfitFixer) Fix( + ctx context.Context, + symbol string, + position *types.Position, + profitStats *types.ProfitStats, + sessions ...*bbgo.ExchangeSession, +) error { + bbgo.Notify("Fixing %s profitStats and position...", symbol) + + log.Infof("profitFixer is enabled, checking checkpoint: %+v", f.ProfitFixerConfig.TradesSince) + + if f.ProfitFixerConfig.TradesSince.Time().IsZero() { + return fmt.Errorf("tradesSince time can not be zero") + } + + fixer := common.NewProfitFixer() + for _, session := range sessions { + if ss, ok := session.Exchange.(types.ExchangeTradeHistoryService); ok { + log.Infof("adding makerSession %s to profitFixer", session.Name) + fixer.AddExchange(session.Name, ss) + } + } + + return fixer.Fix(ctx, + symbol, + f.ProfitFixerConfig.TradesSince.Time(), + time.Now(), + profitStats, + position) +} + // Strategy is the strategy struct of LiquidityMaker // liquidity maker does not care about the current price, it tries to place liquidity orders (limit maker orders) // around the current mid price @@ -63,6 +99,8 @@ type Strategy struct { MinProfit fixedpoint.Value `json:"minProfit"` + ProfitFixer + liquidityOrderBook, adjustmentOrderBook *bbgo.ActiveOrderBook liquidityScale bbgo.Scale @@ -91,6 +129,19 @@ func (s *Strategy) Subscribe(session *bbgo.ExchangeSession) { } func (s *Strategy) Run(ctx context.Context, _ bbgo.OrderExecutor, session *bbgo.ExchangeSession) error { + if s.ProfitFixer.ProfitFixerConfig != nil { + market, _ := session.Market(s.Symbol) + s.Position = types.NewPositionFromMarket(market) + s.ProfitStats = types.NewProfitStats(market) + + if err := s.ProfitFixer.Fix(ctx, s.Symbol, s.Position, s.ProfitStats, session); err != nil { + return err + } + + bbgo.Notify("Fixed %s position", s.Symbol, s.Position) + bbgo.Notify("Fixed %s profitStats", s.Symbol, s.ProfitStats) + } + s.Strategy.Initialize(ctx, s.Environment, session, s.Market, ID, s.InstanceID()) s.orderGenerator = &LiquidityOrderGenerator{ diff --git a/pkg/strategy/xdepthmaker/strategy.go b/pkg/strategy/xdepthmaker/strategy.go index 4e9539f49..a989cf8ab 100644 --- a/pkg/strategy/xdepthmaker/strategy.go +++ b/pkg/strategy/xdepthmaker/strategy.go @@ -196,7 +196,7 @@ type Strategy struct { // Pips is the pips of the layer prices Pips fixedpoint.Value `json:"pips"` - ProfitFixerConfig *common.ProfitFixerConfig `json:"profitFixer"` + ProfitFixerConfig *common.ProfitFixerConfig `json:"profitFixer,omitempty"` // -------------------------------- // private fields From c217aadc1b5631cafcbb924d2d1476cc7498a80a Mon Sep 17 00:00:00 2001 From: c9s Date: Mon, 8 Jul 2024 14:16:40 +0800 Subject: [PATCH 2/2] common: pull out ProfitFixerBundle --- pkg/strategy/common/profit_fixer.go | 37 ++++++++++++++++++++++ pkg/strategy/liquiditymaker/strategy.go | 42 ++----------------------- 2 files changed, 40 insertions(+), 39 deletions(-) diff --git a/pkg/strategy/common/profit_fixer.go b/pkg/strategy/common/profit_fixer.go index 1092092f2..91d4b8158 100644 --- a/pkg/strategy/common/profit_fixer.go +++ b/pkg/strategy/common/profit_fixer.go @@ -2,12 +2,14 @@ package common import ( "context" + "fmt" "sync" "time" log "github.com/sirupsen/logrus" "golang.org/x/sync/errgroup" + "github.com/c9s/bbgo/pkg/bbgo" "github.com/c9s/bbgo/pkg/exchange/batch" "github.com/c9s/bbgo/pkg/types" ) @@ -101,3 +103,38 @@ func (f *ProfitFixer) FixFromTrades(allTrades []types.Trade, stats *types.Profit log.Infof("profitFixer fix finished: profitStats and position are updated from %d trades", len(allTrades)) return nil } + +type ProfitFixerBundle struct { + ProfitFixerConfig *ProfitFixerConfig `json:"profitFixer,omitempty"` +} + +func (f *ProfitFixerBundle) Fix( + ctx context.Context, + symbol string, + position *types.Position, + profitStats *types.ProfitStats, + sessions ...*bbgo.ExchangeSession, +) error { + bbgo.Notify("Fixing %s profitStats and position...", symbol) + + log.Infof("profitFixer is enabled, checking checkpoint: %+v", f.ProfitFixerConfig.TradesSince) + + if f.ProfitFixerConfig.TradesSince.Time().IsZero() { + return fmt.Errorf("tradesSince time can not be zero") + } + + fixer := NewProfitFixer() + for _, session := range sessions { + if ss, ok := session.Exchange.(types.ExchangeTradeHistoryService); ok { + log.Infof("adding makerSession %s to profitFixer", session.Name) + fixer.AddExchange(session.Name, ss) + } + } + + return fixer.Fix(ctx, + symbol, + f.ProfitFixerConfig.TradesSince.Time(), + time.Now(), + profitStats, + position) +} diff --git a/pkg/strategy/liquiditymaker/strategy.go b/pkg/strategy/liquiditymaker/strategy.go index 74a80c5ed..d26d4e757 100644 --- a/pkg/strategy/liquiditymaker/strategy.go +++ b/pkg/strategy/liquiditymaker/strategy.go @@ -4,7 +4,6 @@ import ( "context" "fmt" "sync" - "time" log "github.com/sirupsen/logrus" @@ -28,41 +27,6 @@ func init() { bbgo.RegisterStrategy(ID, &Strategy{}) } -type ProfitFixer struct { - ProfitFixerConfig *common.ProfitFixerConfig `json:"profitFixer,omitempty"` -} - -func (f *ProfitFixer) Fix( - ctx context.Context, - symbol string, - position *types.Position, - profitStats *types.ProfitStats, - sessions ...*bbgo.ExchangeSession, -) error { - bbgo.Notify("Fixing %s profitStats and position...", symbol) - - log.Infof("profitFixer is enabled, checking checkpoint: %+v", f.ProfitFixerConfig.TradesSince) - - if f.ProfitFixerConfig.TradesSince.Time().IsZero() { - return fmt.Errorf("tradesSince time can not be zero") - } - - fixer := common.NewProfitFixer() - for _, session := range sessions { - if ss, ok := session.Exchange.(types.ExchangeTradeHistoryService); ok { - log.Infof("adding makerSession %s to profitFixer", session.Name) - fixer.AddExchange(session.Name, ss) - } - } - - return fixer.Fix(ctx, - symbol, - f.ProfitFixerConfig.TradesSince.Time(), - time.Now(), - profitStats, - position) -} - // Strategy is the strategy struct of LiquidityMaker // liquidity maker does not care about the current price, it tries to place liquidity orders (limit maker orders) // around the current mid price @@ -99,7 +63,7 @@ type Strategy struct { MinProfit fixedpoint.Value `json:"minProfit"` - ProfitFixer + common.ProfitFixerBundle liquidityOrderBook, adjustmentOrderBook *bbgo.ActiveOrderBook @@ -129,12 +93,12 @@ func (s *Strategy) Subscribe(session *bbgo.ExchangeSession) { } func (s *Strategy) Run(ctx context.Context, _ bbgo.OrderExecutor, session *bbgo.ExchangeSession) error { - if s.ProfitFixer.ProfitFixerConfig != nil { + if s.ProfitFixerBundle.ProfitFixerConfig != nil { market, _ := session.Market(s.Symbol) s.Position = types.NewPositionFromMarket(market) s.ProfitStats = types.NewProfitStats(market) - if err := s.ProfitFixer.Fix(ctx, s.Symbol, s.Position, s.ProfitStats, session); err != nil { + if err := s.ProfitFixerBundle.Fix(ctx, s.Symbol, s.Position, s.ProfitStats, session); err != nil { return err }