Skip to content

Commit 23fc45c

Browse files
committed
FEATURE: [dca2] UpdateProfitStatsUntilSuccess -> UpdateProfitStatsUntilDuration to avoid it infinity trying
1 parent 4e9d285 commit 23fc45c

File tree

4 files changed

+23
-10
lines changed

4 files changed

+23
-10
lines changed

pkg/strategy/dca2/profit_stats.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ func newProfitStats(market types.Market, quoteInvestment fixedpoint.Value) *Prof
3838
}
3939
}
4040

41+
// AddTrade adds a trade to the profit stats and updates the current round profit and total profit.
4142
func (s *ProfitStats) AddTrade(trade types.Trade) {
4243
if s.CurrentRoundFee == nil {
4344
s.CurrentRoundFee = make(map[string]fixedpoint.Value)

pkg/strategy/dca2/state.go

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,10 @@ import (
1010

1111
type State int64
1212

13+
const (
14+
MaxRetryDurationToUpdateProfitStats time.Duration = 30 * time.Minute
15+
)
16+
1317
const (
1418
None State = iota
1519
IdleWaiting
@@ -243,8 +247,9 @@ func (s *Strategy) finishTakeProfitStage(ctx context.Context, next State) bool {
243247
s.logger.Info("[State] finishTakeProfitStage - start resetting position and calculate quote investment for next round")
244248

245249
// update profit stats
246-
if err := s.UpdateProfitStatsUntilSuccessful(ctx); err != nil {
247-
s.logger.WithError(err).Warn("failed to calculate and emit profit")
250+
// it will try to update profit stats for 30 minutes
251+
if err := s.UpdateProfitStatsUntilDuration(ctx, MaxRetryDurationToUpdateProfitStats); err != nil {
252+
s.logger.WithError(err).Error("failed to calculate and emit profit, please check it")
248253
}
249254

250255
// reset position and open new round for profit stats before position opening

pkg/strategy/dca2/strategy.go

Lines changed: 14 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -366,6 +366,7 @@ func (s *Strategy) Close(ctx context.Context) error {
366366

367367
var err error
368368
if s.UseCancelAllOrdersApiWhenClose {
369+
s.logger.Info("UseCancelAllOrdersApiWhenClose is set, will cancel all orders by cancel all orders API")
369370
err = tradingutil.UniversalCancelAllOrders(ctx, s.ExchangeSession.Exchange, s.Symbol, nil)
370371
} else {
371372
err = s.OrderExecutor.GracefulCancel(ctx)
@@ -429,7 +430,10 @@ func (s *Strategy) ContinueNextRound() {
429430
s.nextRoundPaused = false
430431
}
431432

432-
func (s *Strategy) UpdateProfitStatsUntilSuccessful(ctx context.Context) error {
433+
// UpdateProfitStatsUntilSuccessful will update the profit stats until duration (duration == 0 means no stop)
434+
// it will retry for 30 minutes with exponential backoff
435+
// if it is not successful, it will return an error and the ProfitStats will not be updated into persistence
436+
func (s *Strategy) UpdateProfitStatsUntilDuration(ctx context.Context, duration time.Duration) error {
433437
var op = func() error {
434438
if updated, err := s.UpdateProfitStats(ctx); err != nil {
435439
return errors.Wrapf(err, "failed to update profit stats, please check it")
@@ -443,8 +447,8 @@ func (s *Strategy) UpdateProfitStatsUntilSuccessful(ctx context.Context) error {
443447
// exponential increased interval retry until success
444448
bo := backoff.NewExponentialBackOff()
445449
bo.InitialInterval = 5 * time.Second
446-
bo.MaxInterval = 20 * time.Minute
447-
bo.MaxElapsedTime = 0
450+
bo.MaxInterval = 5 * time.Minute
451+
bo.MaxElapsedTime = duration
448452

449453
return backoff.Retry(op, backoff.WithContext(bo, ctx))
450454
}
@@ -460,6 +464,8 @@ func (s *Strategy) UpdateProfitStats(ctx context.Context) (bool, error) {
460464
return false, errors.Wrapf(err, "failed to collect finish rounds from #%d", s.ProfitStats.FromOrderID)
461465
}
462466

467+
s.logger.Infof("there are %d finished rounds from #%d", len(rounds), s.ProfitStats.FromOrderID)
468+
463469
var updated bool = false
464470
for _, round := range rounds {
465471
trades, err := s.collector.CollectRoundTrades(ctx, round)
@@ -472,6 +478,11 @@ func (s *Strategy) UpdateProfitStats(ctx context.Context) (bool, error) {
472478
s.ProfitStats.AddTrade(trade)
473479
}
474480

481+
s.logger.Infof("profit stats:\n%s", s.ProfitStats.String())
482+
483+
// emit profit
484+
s.EmitProfit(s.ProfitStats)
485+
475486
// update profit stats FromOrderID to make sure we will not collect duplicated rounds
476487
for _, order := range round.TakeProfitOrders {
477488
if order.OrderID >= s.ProfitStats.FromOrderID {
@@ -486,11 +497,6 @@ func (s *Strategy) UpdateProfitStats(ctx context.Context) (bool, error) {
486497
bbgo.Sync(ctx, s)
487498
updated = true
488499

489-
s.logger.Infof("profit stats:\n%s", s.ProfitStats.String())
490-
491-
// emit profit
492-
s.EmitProfit(s.ProfitStats)
493-
494500
// make profit stats forward to new round
495501
s.ProfitStats.NewRound()
496502
}

pkg/strategy/grid2/strategy.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -980,6 +980,7 @@ func (s *Strategy) cancelAll(ctx context.Context) error {
980980

981981
var err error
982982
if s.UseCancelAllOrdersApiWhenClose {
983+
s.logger.Info("UseCancelAllOrdersApiWhenClose is set, will cancel all orders by cancel all orders API")
983984
err = tradingutil.UniversalCancelAllOrders(ctx, session.Exchange, s.Symbol, nil)
984985
} else {
985986
err = s.orderExecutor.GracefulCancel(ctx)

0 commit comments

Comments
 (0)