mirror of
https://github.com/c9s/bbgo.git
synced 2024-11-27 09:15:15 +00:00
bbgo: add partial close option to stop loss and take profit
This commit is contained in:
parent
54782e763b
commit
1ea52e03c6
|
@ -3,14 +3,23 @@ package bbgo
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
|
||||||
|
log "github.com/sirupsen/logrus"
|
||||||
|
|
||||||
"github.com/c9s/bbgo/pkg/fixedpoint"
|
"github.com/c9s/bbgo/pkg/fixedpoint"
|
||||||
"github.com/c9s/bbgo/pkg/types"
|
"github.com/c9s/bbgo/pkg/types"
|
||||||
)
|
)
|
||||||
|
|
||||||
type RoiStopLoss struct {
|
type RoiStopLoss struct {
|
||||||
Symbol string
|
Symbol string
|
||||||
|
|
||||||
|
// Percentage is the ROI loss percentage
|
||||||
|
// 1% means when you loss 1% and it will close the position
|
||||||
Percentage fixedpoint.Value `json:"percentage"`
|
Percentage fixedpoint.Value `json:"percentage"`
|
||||||
|
|
||||||
|
// Partial is a percentage of the position to be closed
|
||||||
|
// 50% means you will close halt the position
|
||||||
|
Partial fixedpoint.Value `json:"partial,omitempty"`
|
||||||
|
|
||||||
session *ExchangeSession
|
session *ExchangeSession
|
||||||
orderExecutor *GeneralOrderExecutor
|
orderExecutor *GeneralOrderExecutor
|
||||||
}
|
}
|
||||||
|
@ -47,10 +56,25 @@ func (s *RoiStopLoss) checkStopPrice(closePrice fixedpoint.Value, position *type
|
||||||
|
|
||||||
roi := position.ROI(closePrice)
|
roi := position.ROI(closePrice)
|
||||||
// logrus.Debugf("ROIStopLoss: price=%f roi=%s stop=%s", closePrice.Float64(), roi.Percentage(), s.Percentage.Neg().Percentage())
|
// logrus.Debugf("ROIStopLoss: price=%f roi=%s stop=%s", closePrice.Float64(), roi.Percentage(), s.Percentage.Neg().Percentage())
|
||||||
if roi.Compare(s.Percentage.Neg()) < 0 {
|
|
||||||
// stop loss
|
if roi.Compare(s.Percentage.Neg()) > 0 {
|
||||||
Notify("[RoiStopLoss] %s stop loss triggered by ROI %s/%s, price: %f", position.Symbol, roi.Percentage(), s.Percentage.Neg().Percentage(), closePrice.Float64())
|
|
||||||
_ = s.orderExecutor.ClosePosition(context.Background(), fixedpoint.One, "roiStopLoss")
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// default to close the whole position
|
||||||
|
percent := one
|
||||||
|
if !s.Partial.IsZero() {
|
||||||
|
percent = s.Partial
|
||||||
|
}
|
||||||
|
|
||||||
|
Notify("[RoiStopLoss] %s stop loss triggered by ROI %s/%s, price: %f, closing: %s",
|
||||||
|
position.Symbol,
|
||||||
|
roi.Percentage(),
|
||||||
|
s.Percentage.Neg().Percentage(),
|
||||||
|
closePrice.Float64(),
|
||||||
|
percent.Percentage())
|
||||||
|
|
||||||
|
if err := s.orderExecutor.ClosePosition(context.Background(), percent, "roiStopLoss"); err != nil {
|
||||||
|
log.WithError(err).Error("failed to close position")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,6 +3,8 @@ package bbgo
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
|
||||||
|
log "github.com/sirupsen/logrus"
|
||||||
|
|
||||||
"github.com/c9s/bbgo/pkg/fixedpoint"
|
"github.com/c9s/bbgo/pkg/fixedpoint"
|
||||||
"github.com/c9s/bbgo/pkg/types"
|
"github.com/c9s/bbgo/pkg/types"
|
||||||
)
|
)
|
||||||
|
@ -12,6 +14,10 @@ type RoiTakeProfit struct {
|
||||||
Symbol string `json:"symbol"`
|
Symbol string `json:"symbol"`
|
||||||
Percentage fixedpoint.Value `json:"percentage"`
|
Percentage fixedpoint.Value `json:"percentage"`
|
||||||
|
|
||||||
|
// Partial is a percentage of the position to be closed
|
||||||
|
// 50% means you will close halt the position
|
||||||
|
Partial fixedpoint.Value `json:"partial,omitempty"`
|
||||||
|
|
||||||
session *ExchangeSession
|
session *ExchangeSession
|
||||||
orderExecutor *GeneralOrderExecutor
|
orderExecutor *GeneralOrderExecutor
|
||||||
}
|
}
|
||||||
|
@ -33,11 +39,26 @@ func (s *RoiTakeProfit) Bind(session *ExchangeSession, orderExecutor *GeneralOrd
|
||||||
}
|
}
|
||||||
|
|
||||||
roi := position.ROI(closePrice)
|
roi := position.ROI(closePrice)
|
||||||
if roi.Compare(s.Percentage) >= 0 {
|
if roi.Compare(s.Percentage) < 0 {
|
||||||
// stop loss
|
|
||||||
Notify("[RoiTakeProfit] %s take profit is triggered by ROI %s/%s, price: %f", position.Symbol, roi.Percentage(), s.Percentage.Percentage(), kline.Close.Float64())
|
|
||||||
_ = orderExecutor.ClosePosition(context.Background(), fixedpoint.One, "roiTakeProfit")
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// default to close the whole position
|
||||||
|
percent := one
|
||||||
|
if !s.Partial.IsZero() {
|
||||||
|
percent = s.Partial
|
||||||
|
}
|
||||||
|
|
||||||
|
// stop loss
|
||||||
|
Notify("[RoiTakeProfit] %s take profit is triggered by ROI %s/%s, price: %f, closing: %s",
|
||||||
|
position.Symbol,
|
||||||
|
roi.Percentage(),
|
||||||
|
s.Percentage.Percentage(),
|
||||||
|
kline.Close.Float64(),
|
||||||
|
percent.Percentage())
|
||||||
|
|
||||||
|
if err := orderExecutor.ClosePosition(context.Background(), percent, "roiTakeProfit"); err != nil {
|
||||||
|
log.WithError(err).Error("failed to close position")
|
||||||
|
}
|
||||||
}))
|
}))
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user