mirror of
https://github.com/c9s/bbgo.git
synced 2024-11-22 23:05:15 +00:00
Merge pull request #787 from c9s/strategy/pivotshort
strategy: pivotshort: use active orderbook to maintain the resistance orders
This commit is contained in:
commit
2816e42084
|
@ -86,9 +86,9 @@ func (e *GeneralOrderExecutor) Bind() {
|
||||||
e.tradeCollector.BindStream(e.session.UserDataStream)
|
e.tradeCollector.BindStream(e.session.UserDataStream)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// CancelOrders cancels the given order objects directly
|
||||||
func (e *GeneralOrderExecutor) CancelOrders(ctx context.Context, orders ...types.Order) error {
|
func (e *GeneralOrderExecutor) CancelOrders(ctx context.Context, orders ...types.Order) error {
|
||||||
err := e.session.Exchange.CancelOrders(ctx, orders...)
|
return e.session.Exchange.CancelOrders(ctx, orders...)
|
||||||
return err
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (e *GeneralOrderExecutor) SubmitOrders(ctx context.Context, submitOrders ...types.SubmitOrder) (types.OrderSlice, error) {
|
func (e *GeneralOrderExecutor) SubmitOrders(ctx context.Context, submitOrders ...types.SubmitOrder) (types.OrderSlice, error) {
|
||||||
|
@ -108,8 +108,9 @@ func (e *GeneralOrderExecutor) SubmitOrders(ctx context.Context, submitOrders ..
|
||||||
return createdOrders, err
|
return createdOrders, err
|
||||||
}
|
}
|
||||||
|
|
||||||
func (e *GeneralOrderExecutor) GracefulCancel(ctx context.Context) error {
|
// GracefulCancelActiveOrderBook cancels the orders from the active orderbook.
|
||||||
if err := e.activeMakerOrders.GracefulCancel(ctx, e.session.Exchange); err != nil {
|
func (e *GeneralOrderExecutor) GracefulCancelActiveOrderBook(ctx context.Context, activeOrders *ActiveOrderBook) error {
|
||||||
|
if err := activeOrders.GracefulCancel(ctx, e.session.Exchange); err != nil {
|
||||||
log.WithError(err).Errorf("graceful cancel order error")
|
log.WithError(err).Errorf("graceful cancel order error")
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -118,6 +119,11 @@ func (e *GeneralOrderExecutor) GracefulCancel(ctx context.Context) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// GracefulCancel cancels all active maker orders
|
||||||
|
func (e *GeneralOrderExecutor) GracefulCancel(ctx context.Context) error {
|
||||||
|
return e.GracefulCancelActiveOrderBook(ctx, e.activeMakerOrders)
|
||||||
|
}
|
||||||
|
|
||||||
func (e *GeneralOrderExecutor) ClosePosition(ctx context.Context, percentage fixedpoint.Value, tags ...string) error {
|
func (e *GeneralOrderExecutor) ClosePosition(ctx context.Context, percentage fixedpoint.Value, tags ...string) error {
|
||||||
submitOrder := e.position.NewMarketCloseOrder(percentage)
|
submitOrder := e.position.NewMarketCloseOrder(percentage)
|
||||||
if submitOrder == nil {
|
if submitOrder == nil {
|
||||||
|
|
|
@ -68,16 +68,16 @@ type ResistanceShort struct {
|
||||||
resistancePrices []float64
|
resistancePrices []float64
|
||||||
nextResistancePrice fixedpoint.Value
|
nextResistancePrice fixedpoint.Value
|
||||||
|
|
||||||
resistanceOrders []types.Order
|
activeOrders *bbgo.ActiveOrderBook
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *ResistanceShort) Bind(session *bbgo.ExchangeSession, orderExecutor *bbgo.GeneralOrderExecutor) {
|
func (s *ResistanceShort) Bind(session *bbgo.ExchangeSession, orderExecutor *bbgo.GeneralOrderExecutor) {
|
||||||
s.session = session
|
s.session = session
|
||||||
s.orderExecutor = orderExecutor
|
s.orderExecutor = orderExecutor
|
||||||
|
s.activeOrders = bbgo.NewActiveOrderBook(s.Symbol)
|
||||||
|
s.activeOrders.BindStream(session.UserDataStream)
|
||||||
|
|
||||||
position := orderExecutor.Position()
|
store, _ := session.MarketDataStore(s.Symbol)
|
||||||
symbol := position.Symbol
|
|
||||||
store, _ := session.MarketDataStore(symbol)
|
|
||||||
|
|
||||||
s.resistancePivot = &indicator.Pivot{IntervalWindow: s.IntervalWindow}
|
s.resistancePivot = &indicator.Pivot{IntervalWindow: s.IntervalWindow}
|
||||||
s.resistancePivot.Bind(store)
|
s.resistancePivot.Bind(store)
|
||||||
|
@ -87,22 +87,25 @@ func (s *ResistanceShort) Bind(session *bbgo.ExchangeSession, orderExecutor *bbg
|
||||||
lastKLine := preloadPivot(s.resistancePivot, store)
|
lastKLine := preloadPivot(s.resistancePivot, store)
|
||||||
|
|
||||||
// use the last kline from the history before we get the next closed kline
|
// use the last kline from the history before we get the next closed kline
|
||||||
s.findNextResistancePriceAndPlaceOrders(lastKLine.Close)
|
if lastKLine != nil {
|
||||||
|
s.findNextResistancePriceAndPlaceOrders(lastKLine.Close)
|
||||||
|
}
|
||||||
|
|
||||||
session.MarketDataStream.OnKLineClosed(func(kline types.KLine) {
|
session.MarketDataStream.OnKLineClosed(func(kline types.KLine) {
|
||||||
if kline.Symbol != s.Symbol || kline.Interval != s.Interval {
|
if kline.Symbol != s.Symbol || kline.Interval != s.Interval {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
position := s.orderExecutor.Position()
|
||||||
|
if position.IsOpened(kline.Close) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
s.findNextResistancePriceAndPlaceOrders(kline.Close)
|
s.findNextResistancePriceAndPlaceOrders(kline.Close)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *ResistanceShort) findNextResistancePriceAndPlaceOrders(closePrice fixedpoint.Value) {
|
func (s *ResistanceShort) findNextResistancePriceAndPlaceOrders(closePrice fixedpoint.Value) {
|
||||||
position := s.orderExecutor.Position()
|
|
||||||
if position.IsOpened(closePrice) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
minDistance := s.MinDistance.Float64()
|
minDistance := s.MinDistance.Float64()
|
||||||
lows := s.resistancePivot.Lows
|
lows := s.resistancePivot.Lows
|
||||||
|
@ -114,6 +117,7 @@ func (s *ResistanceShort) findNextResistancePriceAndPlaceOrders(closePrice fixed
|
||||||
if len(resistancePrices) > 0 {
|
if len(resistancePrices) > 0 {
|
||||||
nextResistancePrice := fixedpoint.NewFromFloat(resistancePrices[0])
|
nextResistancePrice := fixedpoint.NewFromFloat(resistancePrices[0])
|
||||||
if nextResistancePrice.Compare(s.nextResistancePrice) != 0 {
|
if nextResistancePrice.Compare(s.nextResistancePrice) != 0 {
|
||||||
|
bbgo.Notify("Found next resistance price: %f", nextResistancePrice.Float64())
|
||||||
s.nextResistancePrice = nextResistancePrice
|
s.nextResistancePrice = nextResistancePrice
|
||||||
s.placeResistanceOrders(ctx, nextResistancePrice)
|
s.placeResistanceOrders(ctx, nextResistancePrice)
|
||||||
}
|
}
|
||||||
|
@ -134,10 +138,9 @@ func (s *ResistanceShort) placeResistanceOrders(ctx context.Context, resistanceP
|
||||||
layerSpread := s.LayerSpread
|
layerSpread := s.LayerSpread
|
||||||
quantity := totalQuantity.Div(numLayersF)
|
quantity := totalQuantity.Div(numLayersF)
|
||||||
|
|
||||||
if err := s.orderExecutor.CancelOrders(ctx, s.resistanceOrders...); err != nil {
|
if err := s.orderExecutor.CancelOrders(ctx, s.activeOrders.Orders()...); err != nil {
|
||||||
log.WithError(err).Errorf("can not cancel resistance orders: %+v", s.resistanceOrders)
|
log.WithError(err).Errorf("can not cancel resistance orders: %+v", s.activeOrders.Orders())
|
||||||
}
|
}
|
||||||
s.resistanceOrders = nil
|
|
||||||
|
|
||||||
log.Infof("placing resistance orders: resistance price = %f, layer quantity = %f, num of layers = %d", resistancePrice.Float64(), quantity.Float64(), numLayers)
|
log.Infof("placing resistance orders: resistance price = %f, layer quantity = %f, num of layers = %d", resistancePrice.Float64(), quantity.Float64(), numLayers)
|
||||||
|
|
||||||
|
@ -179,7 +182,7 @@ func (s *ResistanceShort) placeResistanceOrders(ctx context.Context, resistanceP
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.WithError(err).Errorf("can not place resistance order")
|
log.WithError(err).Errorf("can not place resistance order")
|
||||||
}
|
}
|
||||||
s.resistanceOrders = createdOrders
|
s.activeOrders.Add(createdOrders...)
|
||||||
}
|
}
|
||||||
|
|
||||||
type Strategy struct {
|
type Strategy struct {
|
||||||
|
@ -206,12 +209,11 @@ type Strategy struct {
|
||||||
session *bbgo.ExchangeSession
|
session *bbgo.ExchangeSession
|
||||||
orderExecutor *bbgo.GeneralOrderExecutor
|
orderExecutor *bbgo.GeneralOrderExecutor
|
||||||
|
|
||||||
lastLow fixedpoint.Value
|
lastLow fixedpoint.Value
|
||||||
pivot *indicator.Pivot
|
pivot *indicator.Pivot
|
||||||
resistancePivot *indicator.Pivot
|
resistancePivot *indicator.Pivot
|
||||||
stopEWMA *indicator.EWMA
|
stopEWMA *indicator.EWMA
|
||||||
pivotLowPrices []fixedpoint.Value
|
pivotLowPrices []fixedpoint.Value
|
||||||
currentBounceShortPrice fixedpoint.Value
|
|
||||||
|
|
||||||
// StrategyController
|
// StrategyController
|
||||||
bbgo.StrategyController
|
bbgo.StrategyController
|
||||||
|
|
Loading…
Reference in New Issue
Block a user