pivotshort: clean up

This commit is contained in:
austin362667 2022-05-12 19:27:57 +08:00 committed by Austin Liu
parent 2c4a52ba30
commit 62d11181a4
2 changed files with 74 additions and 38 deletions

View File

@ -2,7 +2,7 @@ sessions:
binance: binance:
exchange: binance exchange: binance
envVarPrefix: binance envVarPrefix: binance
# futures: true futures: true
exchangeStrategies: exchangeStrategies:
@ -10,10 +10,11 @@ exchangeStrategies:
pivotshort: pivotshort:
symbol: BTCBUSD symbol: BTCBUSD
interval: 5m interval: 5m
quantity: 0.9 quantity: 1.0
pivotLength: 20 pivotLength: 60
stopLossRatio: 0.8% stopLossRatio: 0.8%
catBounceRatio: 2% catBounceRatio: 3%
numLayers: 5
shadowTPRatio: 2% shadowTPRatio: 2%
backtest: backtest:

View File

@ -26,15 +26,24 @@ type IntervalWindowSetting struct {
} }
type Strategy struct { type Strategy struct {
*bbgo.Graceful
*bbgo.Notifiability
*bbgo.Persistence
Environment *bbgo.Environment
Symbol string `json:"symbol"` Symbol string `json:"symbol"`
Market types.Market Market types.Market
Interval types.Interval `json:"interval"` Interval types.Interval `json:"interval"`
Quantity fixedpoint.Value `json:"quantity"` Quantity fixedpoint.Value `json:"quantity"`
Position *types.Position `json:"position,omitempty"` // persistence fields
Position *types.Position `json:"position,omitempty" persistence:"position"`
ProfitStats *types.ProfitStats `json:"profitStats,omitempty" persistence:"profit_stats"`
PivotLength int `json:"pivotLength"` PivotLength int `json:"pivotLength"`
StopLossRatio fixedpoint.Value `json:"stopLossRatio"` StopLossRatio fixedpoint.Value `json:"stopLossRatio"`
CatBounceRatio fixedpoint.Value `json:"catBounceRatio"` CatBounceRatio fixedpoint.Value `json:"catBounceRatio"`
NumLayers fixedpoint.Value `json:"numLayers"`
ShadowTPRatio fixedpoint.Value `json:"shadowTPRatio"` ShadowTPRatio fixedpoint.Value `json:"shadowTPRatio"`
activeMakerOrders *bbgo.LocalActiveOrderBook activeMakerOrders *bbgo.LocalActiveOrderBook
@ -43,8 +52,10 @@ type Strategy struct {
session *bbgo.ExchangeSession session *bbgo.ExchangeSession
//pivotHigh *PIVOTHIGH
pivot *Pivot pivot *Pivot
// StrategyController
bbgo.StrategyController
} }
func (s *Strategy) ID() string { func (s *Strategy) ID() string {
@ -96,7 +107,7 @@ func (s *Strategy) ClosePosition(ctx context.Context, percentage fixedpoint.Valu
Symbol: s.Symbol, Symbol: s.Symbol,
Side: side, Side: side,
Type: types.OrderTypeMarket, Type: types.OrderTypeMarket,
Quantity: s.Quantity, Quantity: quantity,
Market: s.Market, Market: s.Market,
} }
@ -111,6 +122,9 @@ func (s *Strategy) ClosePosition(ctx context.Context, percentage fixedpoint.Valu
s.activeMakerOrders.Add(createdOrders...) s.activeMakerOrders.Add(createdOrders...)
return err return err
} }
func (s *Strategy) InstanceID() string {
return fmt.Sprintf("%s:%s", ID, s.Symbol)
}
func (s *Strategy) Run(ctx context.Context, orderExecutor bbgo.OrderExecutor, session *bbgo.ExchangeSession) error { func (s *Strategy) Run(ctx context.Context, orderExecutor bbgo.OrderExecutor, session *bbgo.ExchangeSession) error {
// initial required information // initial required information
@ -130,7 +144,44 @@ func (s *Strategy) Run(ctx context.Context, orderExecutor bbgo.OrderExecutor, se
s.Position = types.NewPositionFromMarket(s.Market) s.Position = types.NewPositionFromMarket(s.Market)
} }
// calculate group id for orders
instanceID := s.InstanceID()
//s.groupID = util.FNV32(instanceID)
// Always update the position fields
s.Position.Strategy = ID
s.Position.StrategyInstanceID = instanceID
s.tradeCollector = bbgo.NewTradeCollector(s.Symbol, s.Position, s.orderStore) s.tradeCollector = bbgo.NewTradeCollector(s.Symbol, s.Position, s.orderStore)
s.tradeCollector.OnTrade(func(trade types.Trade, profit, netProfit fixedpoint.Value) {
// StrategyController
if s.Status != types.StrategyStatusRunning {
return
}
s.Notifiability.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
s.Notify(&p)
s.ProfitStats.AddProfit(p)
s.Notify(&s.ProfitStats)
s.Environment.RecordPosition(s.Position, trade, &p)
}
})
s.tradeCollector.OnPositionUpdate(func(position *types.Position) {
log.Infof("position changed: %s", s.Position)
s.Notify(s.Position)
})
s.tradeCollector.BindStream(session.UserDataStream) s.tradeCollector.BindStream(session.UserDataStream)
iw := types.IntervalWindow{Window: s.PivotLength, Interval: s.Interval} iw := types.IntervalWindow{Window: s.PivotLength, Interval: s.Interval}
@ -180,34 +231,18 @@ func (s *Strategy) Run(ctx context.Context, orderExecutor bbgo.OrderExecutor, se
if !lastLow.IsZero() { if !lastLow.IsZero() {
futuresMode := s.session.Futures futuresMode := s.session.Futures
// LO layer d := s.CatBounceRatio.Div(s.NumLayers)
p1 := lastLow.Mul(fixedpoint.One.Add(s.CatBounceRatio.Div(two).Div(two))) q := s.Quantity.Div(s.NumLayers)
p2 := lastLow.Mul(fixedpoint.One.Add(s.CatBounceRatio.Div(two))) for i := 0; i < int(s.NumLayers.Float64()); i++ {
p3 := lastLow.Mul(fixedpoint.One.Add(s.CatBounceRatio))
q := s.Quantity.Div(three)
balances := s.session.GetAccount().Balances() balances := s.session.GetAccount().Balances()
quoteBalance, _ := balances[s.Market.QuoteCurrency] quoteBalance, _ := balances[s.Market.QuoteCurrency]
baseBalance, _ := balances[s.Market.BaseCurrency] baseBalance, _ := balances[s.Market.BaseCurrency]
if (futuresMode && q.Mul(p1).Compare(quoteBalance.Available) < 0) || q.Compare(baseBalance.Available) < 0 {
s.placeOrder(ctx, p1, q, orderExecutor) p := lastLow.Mul(fixedpoint.One.Add(s.CatBounceRatio.Sub(fixedpoint.NewFromFloat(d.Float64() * float64(i)))))
if (futuresMode && q.Mul(p).Compare(quoteBalance.Available) < 0) || q.Compare(baseBalance.Available) < 0 {
s.placeOrder(ctx, p, q, orderExecutor)
s.tradeCollector.Process() s.tradeCollector.Process()
} }
balances = s.session.GetAccount().Balances()
quoteBalance, _ = balances[s.Market.QuoteCurrency]
baseBalance, _ = balances[s.Market.BaseCurrency]
if (futuresMode && q.Mul(p2).Compare(quoteBalance.Available) < 0) || q.Compare(baseBalance.Available) < 0 {
s.placeOrder(ctx, p2, q, orderExecutor)
s.tradeCollector.Process()
}
balances = s.session.GetAccount().Balances()
quoteBalance, _ = balances[s.Market.QuoteCurrency]
baseBalance, _ = balances[s.Market.BaseCurrency]
if (futuresMode && q.Mul(p3).Compare(quoteBalance.Available) < 0) || q.Compare(baseBalance.Available) < 0 {
s.placeOrder(ctx, p3, q, orderExecutor)
s.tradeCollector.Process()
} }
//s.placeOrder(ctx, lastLow.Mul(fixedpoint.One.Add(s.CatBounceRatio)), s.Quantity, orderExecutor) //s.placeOrder(ctx, lastLow.Mul(fixedpoint.One.Add(s.CatBounceRatio)), s.Quantity, orderExecutor)
} }