strategy: make TrailingStopCallBackRatio and MinimumProfitPercentage fixedpoint.Value

This commit is contained in:
Andy Cheng 2022-01-28 13:06:57 +08:00
parent 883f43a9ad
commit b48c7f40d7
No known key found for this signature in database
GPG Key ID: 936427CF651A9D28

View File

@ -79,8 +79,8 @@ func (stop *PercentageTargetStop) GenerateOrders(market types.Market, pos *types
} }
type TrailingStopTarget struct { type TrailingStopTarget struct {
TrailingStopCallBackRatio float64 `json:"trailingStopCallBackRatio"` TrailingStopCallBackRatio fixedpoint.Value `json:"trailingStopCallBackRatio"`
MinimumProfitPercentage float64 `json:"minimumProfitPercentage"` MinimumProfitPercentage fixedpoint.Value `json:"minimumProfitPercentage"`
} }
type TrailingStopControl struct { type TrailingStopControl struct {
@ -88,21 +88,21 @@ type TrailingStopControl struct {
market types.Market market types.Market
marginSideEffect types.MarginOrderSideEffectType marginSideEffect types.MarginOrderSideEffectType
trailingStopCallBackRatio float64 trailingStopCallBackRatio fixedpoint.Value
minimumProfitPercentage float64 minimumProfitPercentage fixedpoint.Value
CurrentHighestPrice fixedpoint.Value CurrentHighestPrice fixedpoint.Value
OrderID uint64 OrderID uint64
} }
func (control *TrailingStopControl) IsHigherThanMin(minTargetPrice float64) bool { func (control *TrailingStopControl) IsHigherThanMin(minTargetPrice float64) bool {
targetPrice := control.CurrentHighestPrice.Float64() * (1 - control.trailingStopCallBackRatio) targetPrice := control.CurrentHighestPrice.Float64() * (1 - control.trailingStopCallBackRatio.Float64())
return targetPrice >= minTargetPrice return targetPrice >= minTargetPrice
} }
func (control *TrailingStopControl) GenerateStopOrder(quantity float64) types.SubmitOrder { func (control *TrailingStopControl) GenerateStopOrder(quantity float64) types.SubmitOrder {
targetPrice := control.CurrentHighestPrice.Float64() * (1 - control.trailingStopCallBackRatio) targetPrice := control.CurrentHighestPrice.Float64() * (1 - control.trailingStopCallBackRatio.Float64())
orderForm := types.SubmitOrder{ orderForm := types.SubmitOrder{
Symbol: control.symbol, Symbol: control.symbol,
@ -375,7 +375,7 @@ func (s *Strategy) Run(ctx context.Context, orderExecutor bbgo.OrderExecutor, se
s.orderStore = bbgo.NewOrderStore(s.Symbol) s.orderStore = bbgo.NewOrderStore(s.Symbol)
s.orderStore.BindStream(session.UserDataStream) s.orderStore.BindStream(session.UserDataStream)
if s.TrailingStopTarget.TrailingStopCallBackRatio != 0 { if s.TrailingStopTarget.TrailingStopCallBackRatio.Float64() != 0 {
s.trailingStopControl = &TrailingStopControl{ s.trailingStopControl = &TrailingStopControl{
symbol: s.Symbol, symbol: s.Symbol,
market: s.Market, market: s.Market,
@ -394,7 +394,7 @@ func (s *Strategy) Run(ctx context.Context, orderExecutor bbgo.OrderExecutor, se
s.tradeCollector = bbgo.NewTradeCollector(s.Symbol, s.state.Position, s.orderStore) s.tradeCollector = bbgo.NewTradeCollector(s.Symbol, s.state.Position, s.orderStore)
if s.TrailingStopTarget.TrailingStopCallBackRatio != 0 { if s.TrailingStopTarget.TrailingStopCallBackRatio.Float64() != 0 {
// Update trailing stop when the position changes // Update trailing stop when the position changes
s.tradeCollector.OnPositionUpdate(func(position *types.Position) { s.tradeCollector.OnPositionUpdate(func(position *types.Position) {
if position.Base.Float64() > 0 { // Update order if we have a position if position.Base.Float64() > 0 { // Update order if we have a position
@ -406,8 +406,8 @@ func (s *Strategy) Run(ctx context.Context, orderExecutor bbgo.OrderExecutor, se
// Calculate minimum target price // Calculate minimum target price
var minTargetPrice = 0.0 var minTargetPrice = 0.0
if s.trailingStopControl.minimumProfitPercentage > 0 { if s.trailingStopControl.minimumProfitPercentage.Float64() > 0 {
minTargetPrice = position.AverageCost.Float64() * (1 + s.trailingStopControl.minimumProfitPercentage) minTargetPrice = position.AverageCost.Float64() * (1 + s.trailingStopControl.minimumProfitPercentage.Float64())
} }
// Place new order if the target price is higher than the minimum target price // Place new order if the target price is higher than the minimum target price
@ -449,7 +449,7 @@ func (s *Strategy) Run(ctx context.Context, orderExecutor bbgo.OrderExecutor, se
highPriceF := kline.GetHigh() highPriceF := kline.GetHigh()
highPrice := fixedpoint.NewFromFloat(highPriceF) highPrice := fixedpoint.NewFromFloat(highPriceF)
if s.TrailingStopTarget.TrailingStopCallBackRatio > 0 { if s.TrailingStopTarget.TrailingStopCallBackRatio.Float64() > 0 {
if s.state.Position.Base.Float64() <= 0 { // Without a position if s.state.Position.Base.Float64() <= 0 { // Without a position
// Update trailing orders with current high price // Update trailing orders with current high price
s.trailingStopControl.CurrentHighestPrice = highPrice s.trailingStopControl.CurrentHighestPrice = highPrice
@ -465,8 +465,8 @@ func (s *Strategy) Run(ctx context.Context, orderExecutor bbgo.OrderExecutor, se
// Calculate minimum target price // Calculate minimum target price
var minTargetPrice = 0.0 var minTargetPrice = 0.0
if s.trailingStopControl.minimumProfitPercentage > 0 { if s.trailingStopControl.minimumProfitPercentage.Float64() > 0 {
minTargetPrice = s.state.Position.AverageCost.Float64() * (1 + s.trailingStopControl.minimumProfitPercentage) minTargetPrice = s.state.Position.AverageCost.Float64() * (1 + s.trailingStopControl.minimumProfitPercentage.Float64())
} }
// Place new order if the target price is higher than the minimum target price // Place new order if the target price is higher than the minimum target price
@ -580,7 +580,7 @@ func (s *Strategy) Run(ctx context.Context, orderExecutor bbgo.OrderExecutor, se
s.Notify("%s position is saved", s.Symbol, s.state.Position) s.Notify("%s position is saved", s.Symbol, s.state.Position)
} }
if s.TrailingStopTarget.TrailingStopCallBackRatio == 0 { // submit fixed target orders if s.TrailingStopTarget.TrailingStopCallBackRatio.Float64() == 0 { // submit fixed target orders
var targetOrders []types.SubmitOrder var targetOrders []types.SubmitOrder
for _, target := range s.Targets { for _, target := range s.Targets {
targetPrice := closePrice.Float64() * (1.0 + target.ProfitPercentage) targetPrice := closePrice.Float64() * (1.0 + target.ProfitPercentage)
@ -621,7 +621,7 @@ func (s *Strategy) Run(ctx context.Context, orderExecutor bbgo.OrderExecutor, se
defer wg.Done() defer wg.Done()
// Cancel trailing stop order // Cancel trailing stop order
if s.TrailingStopTarget.TrailingStopCallBackRatio > 0 { if s.TrailingStopTarget.TrailingStopCallBackRatio.Float64() > 0 {
if err := s.cancelOrder(s.trailingStopControl.OrderID, ctx, session); err != nil { if err := s.cancelOrder(s.trailingStopControl.OrderID, ctx, session); err != nil {
log.WithError(err).Errorf("Can not cancel the trailing stop order!") log.WithError(err).Errorf("Can not cancel the trailing stop order!")
} }