diff --git a/config/wall.yaml b/config/wall.yaml index 628088281..2f6104d3c 100644 --- a/config/wall.yaml +++ b/config/wall.yaml @@ -10,6 +10,14 @@ sessions: exchange: max envVarPrefix: MAX + +logging: + trade: true + order: true + # fields: + # env: prod + + exchangeStrategies: - on: max @@ -33,6 +41,6 @@ exchangeStrategies: byLayer: linear: domain: [ 1, 3 ] - range: [ 10.0, 30.0 ] + range: [ 10000.0, 30000.0 ] diff --git a/pkg/strategy/wall/strategy.go b/pkg/strategy/wall/strategy.go index 5cbb4294f..0967b241a 100644 --- a/pkg/strategy/wall/strategy.go +++ b/pkg/strategy/wall/strategy.go @@ -6,12 +6,11 @@ import ( "sync" "time" - "github.com/c9s/bbgo/pkg/core" - "github.com/c9s/bbgo/pkg/util" - "github.com/pkg/errors" "github.com/sirupsen/logrus" + "github.com/c9s/bbgo/pkg/strategy/common" + "github.com/c9s/bbgo/pkg/bbgo" "github.com/c9s/bbgo/pkg/fixedpoint" "github.com/c9s/bbgo/pkg/types" @@ -31,9 +30,10 @@ func init() { } type Strategy struct { - Environment *bbgo.Environment - StandardIndicatorSet *bbgo.StandardIndicatorSet - Market types.Market + *common.Strategy + + Environment *bbgo.Environment + Market types.Market // Symbol is the market symbol you want to trade Symbol string `json:"symbol"` @@ -60,18 +60,8 @@ type Strategy struct { session *bbgo.ExchangeSession - // persistence fields - Position *types.Position `json:"position,omitempty" persistence:"position"` - ProfitStats *types.ProfitStats `json:"profitStats,omitempty" persistence:"profit_stats"` - activeAdjustmentOrders *bbgo.ActiveOrderBook activeWallOrders *bbgo.ActiveOrderBook - orderStore *core.OrderStore - tradeCollector *core.TradeCollector - - groupID uint32 - - stopC chan struct{} } func (s *Strategy) ID() string { @@ -149,7 +139,6 @@ func (s *Strategy) placeAdjustmentOrders(ctx context.Context, orderExecutor bbgo Price: askPrice, Quantity: quantity, Market: s.Market, - GroupID: s.groupID, }) case types.SideTypeSell: @@ -175,7 +164,6 @@ func (s *Strategy) placeAdjustmentOrders(ctx context.Context, orderExecutor bbgo Price: bidPrice, Quantity: quantity, Market: s.Market, - GroupID: s.groupID, }) } @@ -189,12 +177,13 @@ func (s *Strategy) placeAdjustmentOrders(ctx context.Context, orderExecutor bbgo return err } - s.orderStore.Add(createdOrders...) s.activeAdjustmentOrders.Add(createdOrders...) return nil } func (s *Strategy) placeWallOrders(ctx context.Context, orderExecutor bbgo.OrderExecutor) error { + log.Infof("placing wall orders...") + var submitOrders []types.SubmitOrder var startPrice = s.FixedPrice for i := 0; i < s.NumLayers; i++ { @@ -217,7 +206,6 @@ func (s *Strategy) placeWallOrders(ctx context.Context, orderExecutor bbgo.Order Price: price, Quantity: quantity, Market: s.Market, - GroupID: s.groupID, } submitOrders = append(submitOrders, order) switch s.Side { @@ -240,74 +228,27 @@ func (s *Strategy) placeWallOrders(ctx context.Context, orderExecutor bbgo.Order return err } - s.orderStore.Add(createdOrders...) + log.Infof("wall orders placed: %+v", createdOrders) + s.activeWallOrders.Add(createdOrders...) return err } -func (s *Strategy) Run(ctx context.Context, orderExecutor bbgo.OrderExecutor, session *bbgo.ExchangeSession) error { +func (s *Strategy) Run(ctx context.Context, _ bbgo.OrderExecutor, session *bbgo.ExchangeSession) error { + s.Strategy = &common.Strategy{} + s.Strategy.Initialize(ctx, s.Environment, session, s.Market, ID, s.InstanceID()) + // initial required information s.session = session - // calculate group id for orders - instanceID := s.InstanceID() - s.groupID = util.FNV32(instanceID) - - // If position is nil, we need to allocate a new position for calculation - if s.Position == nil { - s.Position = types.NewPositionFromMarket(s.Market) - } - - if s.ProfitStats == nil { - s.ProfitStats = types.NewProfitStats(s.Market) - } - - // Always update the position fields - s.Position.Strategy = ID - s.Position.StrategyInstanceID = instanceID - - s.stopC = make(chan struct{}) - s.activeWallOrders = bbgo.NewActiveOrderBook(s.Symbol) s.activeWallOrders.BindStream(session.UserDataStream) s.activeAdjustmentOrders = bbgo.NewActiveOrderBook(s.Symbol) s.activeAdjustmentOrders.BindStream(session.UserDataStream) - s.orderStore = core.NewOrderStore(s.Symbol) - s.orderStore.BindStream(session.UserDataStream) - - s.tradeCollector = core.NewTradeCollector(s.Symbol, s.Position, s.orderStore) - - s.tradeCollector.OnTrade(func(trade types.Trade, profit, netProfit fixedpoint.Value) { - bbgo.Notify(trade) - s.ProfitStats.AddTrade(trade) - - if profit.Compare(fixedpoint.Zero) == 0 { - s.Environment.RecordPosition(s.Position, trade, nil) - } else { - log.Infof("%s generated profit: %v", s.Symbol, profit) - p := s.Position.NewProfit(trade, profit, netProfit) - p.Strategy = ID - p.StrategyInstanceID = instanceID - bbgo.Notify(&p) - - s.ProfitStats.AddProfit(p) - bbgo.Notify(&s.ProfitStats) - - s.Environment.RecordPosition(s.Position, trade, &p) - } - }) - - s.tradeCollector.OnPositionUpdate(func(position *types.Position) { - log.Infof("position changed: %s", s.Position) - bbgo.Notify(s.Position) - }) - - s.tradeCollector.BindStream(session.UserDataStream) - session.UserDataStream.OnStart(func() { - if err := s.placeWallOrders(ctx, orderExecutor); err != nil { + if err := s.placeWallOrders(ctx, s.OrderExecutor); err != nil { log.WithError(err).Errorf("can not place order") } }) @@ -318,9 +259,9 @@ func (s *Strategy) Run(ctx context.Context, orderExecutor bbgo.OrderExecutor, se } // check if there is a canceled order had partially filled. - s.tradeCollector.Process() + s.OrderExecutor.TradeCollector().Process() - if err := s.placeAdjustmentOrders(ctx, orderExecutor); err != nil { + if err := s.placeAdjustmentOrders(ctx, s.OrderExecutor); err != nil { log.WithError(err).Errorf("can not place order") } }) @@ -331,9 +272,9 @@ func (s *Strategy) Run(ctx context.Context, orderExecutor bbgo.OrderExecutor, se } // check if there is a canceled order had partially filled. - s.tradeCollector.Process() + s.OrderExecutor.TradeCollector().Process() - if err := s.placeWallOrders(ctx, orderExecutor); err != nil { + if err := s.placeWallOrders(ctx, s.OrderExecutor); err != nil { log.WithError(err).Errorf("can not place order") } @@ -342,9 +283,9 @@ func (s *Strategy) Run(ctx context.Context, orderExecutor bbgo.OrderExecutor, se } // check if there is a canceled order had partially filled. - s.tradeCollector.Process() + s.OrderExecutor.TradeCollector().Process() - if err := s.placeAdjustmentOrders(ctx, orderExecutor); err != nil { + if err := s.placeAdjustmentOrders(ctx, s.OrderExecutor); err != nil { log.WithError(err).Errorf("can not place order") } }) @@ -365,9 +306,9 @@ func (s *Strategy) Run(ctx context.Context, orderExecutor bbgo.OrderExecutor, se } // check if there is a canceled order had partially filled. - s.tradeCollector.Process() + s.OrderExecutor.TradeCollector().Process() - if err := s.placeWallOrders(ctx, orderExecutor); err != nil { + if err := s.placeWallOrders(ctx, s.OrderExecutor); err != nil { log.WithError(err).Errorf("can not place order") } } @@ -377,7 +318,6 @@ func (s *Strategy) Run(ctx context.Context, orderExecutor bbgo.OrderExecutor, se bbgo.OnShutdown(ctx, func(ctx context.Context, wg *sync.WaitGroup) { defer wg.Done() - close(s.stopC) if err := s.activeWallOrders.GracefulCancel(ctx, s.session.Exchange); err != nil { log.WithError(err).Errorf("graceful cancel order error") @@ -387,7 +327,8 @@ func (s *Strategy) Run(ctx context.Context, orderExecutor bbgo.OrderExecutor, se log.WithError(err).Errorf("graceful cancel order error") } - s.tradeCollector.Process() + // check if there is a canceled order had partially filled. + s.OrderExecutor.TradeCollector().Process() }) return nil