mirror of
https://github.com/c9s/bbgo.git
synced 2024-11-10 09:11:55 +00:00
dca2: must calculate and emit profit at the end of the round
This commit is contained in:
parent
3a98660e0c
commit
91123edbd6
|
@ -45,11 +45,14 @@ func (s *Strategy) recover(ctx context.Context) error {
|
|||
}
|
||||
debugRoundOrders(s.logger, "current", currentRound)
|
||||
|
||||
// TODO: use flag
|
||||
// recover profit stats
|
||||
if err := recoverProfitStats(ctx, s); err != nil {
|
||||
return err
|
||||
}
|
||||
s.logger.Info("recover profit stats DONE")
|
||||
/*
|
||||
if err := recoverProfitStats(ctx, s); err != nil {
|
||||
return err
|
||||
}
|
||||
s.logger.Info("recover profit stats DONE")
|
||||
*/
|
||||
|
||||
// recover position
|
||||
if err := recoverPosition(ctx, s.Position, queryService, currentRound); err != nil {
|
||||
|
@ -202,6 +205,8 @@ func recoverPosition(ctx context.Context, position *types.Position, queryService
|
|||
return nil
|
||||
}
|
||||
|
||||
// TODO: use flag to decide which to recover
|
||||
/*
|
||||
func recoverProfitStats(ctx context.Context, strategy *Strategy) error {
|
||||
if strategy.ProfitStats == nil {
|
||||
return fmt.Errorf("profit stats is nil, please check it")
|
||||
|
@ -209,6 +214,7 @@ func recoverProfitStats(ctx context.Context, strategy *Strategy) error {
|
|||
|
||||
return strategy.CalculateAndEmitProfit(ctx)
|
||||
}
|
||||
*/
|
||||
|
||||
func recoverStartTimeOfNextRound(ctx context.Context, currentRound Round, coolDownInterval types.Duration) time.Time {
|
||||
if currentRound.TakeProfitOrder.OrderID != 0 && currentRound.TakeProfitOrder.Status == types.OrderStatusFilled {
|
||||
|
|
|
@ -201,7 +201,7 @@ func (s *Strategy) runTakeProfitReady(ctx context.Context, next State) {
|
|||
// reset position
|
||||
|
||||
// calculate profit stats
|
||||
if err := s.CalculateAndEmitProfit(ctx); err != nil {
|
||||
if err := s.mustCalculateAndEmitProfit(ctx); err != nil {
|
||||
s.logger.WithError(err).Warn("failed to calculate and emit profit")
|
||||
}
|
||||
|
||||
|
|
|
@ -13,6 +13,8 @@ import (
|
|||
"go.uber.org/multierr"
|
||||
|
||||
"github.com/c9s/bbgo/pkg/bbgo"
|
||||
"github.com/c9s/bbgo/pkg/exchange"
|
||||
maxapi "github.com/c9s/bbgo/pkg/exchange/max/maxapi"
|
||||
"github.com/c9s/bbgo/pkg/exchange/retry"
|
||||
"github.com/c9s/bbgo/pkg/fixedpoint"
|
||||
"github.com/c9s/bbgo/pkg/strategy/common"
|
||||
|
@ -370,7 +372,9 @@ func (s *Strategy) CleanUp(ctx context.Context) error {
|
|||
return werr
|
||||
}
|
||||
|
||||
func (s *Strategy) CalculateAndEmitProfit(ctx context.Context) error {
|
||||
func (s *Strategy) mustCalculateAndEmitProfit(ctx context.Context) error {
|
||||
fromOrderID := s.ProfitStats.FromOrderID
|
||||
|
||||
historyService, ok := s.ExchangeSession.Exchange.(types.ExchangeTradeHistoryService)
|
||||
if !ok {
|
||||
return fmt.Errorf("exchange %s doesn't support ExchangeTradeHistoryService", s.ExchangeSession.Exchange.Name())
|
||||
|
@ -381,6 +385,26 @@ func (s *Strategy) CalculateAndEmitProfit(ctx context.Context) error {
|
|||
return fmt.Errorf("exchange %s doesn't support ExchangeOrderQueryService", s.ExchangeSession.Exchange.Name())
|
||||
}
|
||||
|
||||
maxTry := 10
|
||||
for try := 1; try < maxTry; try++ {
|
||||
if err := s.CalculateAndEmitProfit(ctx, historyService, queryService); err != nil {
|
||||
s.logger.WithError(err).Warnf("failed to calculate and emit profit at #%d try, please check it", try)
|
||||
continue
|
||||
}
|
||||
|
||||
if s.ProfitStats.FromOrderID > fromOrderID {
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
if s.ProfitStats.FromOrderID == fromOrderID {
|
||||
return fmt.Errorf("after trying %d times, we still can't calculate and emit profit, please check it", maxTry)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *Strategy) CalculateAndEmitProfit(ctx context.Context, historyService types.ExchangeTradeHistoryService, queryService types.ExchangeOrderQueryService) error {
|
||||
// TODO: pagination for it
|
||||
// query the orders
|
||||
s.logger.Infof("query %s closed orders from order id #%d", s.Symbol, s.ProfitStats.FromOrderID)
|
||||
|
@ -390,6 +414,8 @@ func (s *Strategy) CalculateAndEmitProfit(ctx context.Context) error {
|
|||
}
|
||||
s.logger.Infof("there are %d closed orders from order id #%d", len(orders), s.ProfitStats.FromOrderID)
|
||||
|
||||
isMax := exchange.IsMaxExchange(s.ExchangeSession.Exchange)
|
||||
|
||||
var rounds []Round
|
||||
var round Round
|
||||
for _, order := range orders {
|
||||
|
@ -402,9 +428,23 @@ func (s *Strategy) CalculateAndEmitProfit(ctx context.Context) error {
|
|||
case types.SideTypeBuy:
|
||||
round.OpenPositionOrders = append(round.OpenPositionOrders, order)
|
||||
case types.SideTypeSell:
|
||||
if order.Status != types.OrderStatusFilled {
|
||||
continue
|
||||
if !isMax {
|
||||
if order.Status != types.OrderStatusFilled {
|
||||
s.logger.Infof("take-profit order is %s not filled, so this round is not finished. Skip it", order.Status)
|
||||
continue
|
||||
}
|
||||
} else {
|
||||
switch maxapi.OrderState(order.OriginalStatus) {
|
||||
case maxapi.OrderStateDone:
|
||||
// the same as filled
|
||||
case maxapi.OrderStateFinalizing:
|
||||
// the same as filled
|
||||
default:
|
||||
s.logger.Infof("isMax and take-profit order is %s not done or finalizing, so this round is not finished. Skip it", order.OriginalStatus)
|
||||
continue
|
||||
}
|
||||
}
|
||||
|
||||
round.TakeProfitOrder = order
|
||||
rounds = append(rounds, round)
|
||||
round = Round{}
|
||||
|
|
Loading…
Reference in New Issue
Block a user