mirror of
https://github.com/c9s/bbgo.git
synced 2024-11-25 16:25:16 +00:00
Merge pull request #1386 from c9s/c9s/refactor-wall-strategy
REFACTOR: [wall] refactor wall strategy with common.Strategy
This commit is contained in:
commit
2ffc617dac
|
@ -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 ]
|
||||
|
||||
|
||||
|
|
|
@ -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,8 +30,9 @@ func init() {
|
|||
}
|
||||
|
||||
type Strategy struct {
|
||||
*common.Strategy
|
||||
|
||||
Environment *bbgo.Environment
|
||||
StandardIndicatorSet *bbgo.StandardIndicatorSet
|
||||
Market types.Market
|
||||
|
||||
// Symbol is the market symbol you want to trade
|
||||
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue
Block a user