mirror of
https://github.com/c9s/bbgo.git
synced 2024-11-26 08:45:16 +00:00
strategy: make TrailingStopCallBackRatio and MinimumProfitPercentage fixedpoint.Value
This commit is contained in:
parent
883f43a9ad
commit
b48c7f40d7
|
@ -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!")
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user