Skip to content

Commit

Permalink
FEATURE: [dca2] make QueryOrderTradesUntilsuccessful take feeProcessi…
Browse files Browse the repository at this point in the history
…ng into consideration
  • Loading branch information
kbearXD committed Apr 29, 2024
1 parent 0a2b976 commit 0396fc1
Show file tree
Hide file tree
Showing 4 changed files with 30 additions and 7 deletions.
12 changes: 12 additions & 0 deletions pkg/exchange/retry/order.go
Original file line number Diff line number Diff line change
Expand Up @@ -156,23 +156,35 @@ func QueryClosedOrdersUntilSuccessfulLite(
return closedOrders, err
}

// QueryOrderTradesUntilSuccessful query order's trades until success (include the trading fee is not processing)
func QueryOrderTradesUntilSuccessful(
ctx context.Context, ex types.ExchangeOrderQueryService, q types.OrderQuery,
) (trades []types.Trade, err error) {
var op = func() (err2 error) {
trades, err2 = ex.QueryOrderTrades(ctx, q)
for _, trade := range trades {
if trade.FeeProcessing {
return fmt.Errorf("there are some trades which trading fee is not ready")
}
}
return err2
}

err = GeneralBackoff(ctx, op)
return trades, err
}

// QueryOrderTradesUntilSuccessfulLite query order's trades until success (include the trading fee is not processing)
func QueryOrderTradesUntilSuccessfulLite(
ctx context.Context, ex types.ExchangeOrderQueryService, q types.OrderQuery,
) (trades []types.Trade, err error) {
var op = func() (err2 error) {
trades, err2 = ex.QueryOrderTrades(ctx, q)
for _, trade := range trades {
if trade.FeeProcessing {
return fmt.Errorf("there are some trades which trading fee is not ready")
}
}
return err2
}

Expand Down
4 changes: 3 additions & 1 deletion pkg/strategy/dca2/collector.go
Original file line number Diff line number Diff line change
Expand Up @@ -152,6 +152,7 @@ func (rc *Collector) CollectFinishRounds(ctx context.Context, fromOrderID uint64
return rounds, nil
}

// CollectRoundTrades collect the trades of the orders in the given round. The trades' fee are processed (feeProcessing = false)
func (rc *Collector) CollectRoundTrades(ctx context.Context, round Round) ([]types.Trade, error) {
debugRoundOrders(rc.logger, "collect round trades", round)

Expand All @@ -171,7 +172,8 @@ func (rc *Collector) CollectRoundTrades(ctx context.Context, round Round) ([]typ
rc.logger.Info("collect trades from order ", order.String())
}

trades, err := retry.QueryOrderTradesUntilSuccessfulLite(ctx, rc.queryService, types.OrderQuery{
// QueryOrderTradesUntilSuccessful will query trades and their feeProcessing = false
trades, err := retry.QueryOrderTradesUntilSuccessful(ctx, rc.queryService, types.OrderQuery{
Symbol: order.Symbol,
OrderID: strconv.FormatUint(order.OrderID, 10),
})
Expand Down
12 changes: 8 additions & 4 deletions pkg/strategy/dca2/recover.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,9 @@ import (
"time"

"github.com/c9s/bbgo/pkg/bbgo"
"github.com/c9s/bbgo/pkg/exchange/retry"
"github.com/c9s/bbgo/pkg/types"
"github.com/pkg/errors"
)

var recoverSinceLimit = time.Date(2024, time.January, 29, 12, 0, 0, 0, time.Local)
Expand Down Expand Up @@ -139,9 +141,12 @@ func recoverPosition(ctx context.Context, position *types.Position, currentRound
return fmt.Errorf("position is nil, please check it")
}

var positionOrders []types.Order
// reset position to recover
position.Reset()

var positionOrders []types.Order
if currentRound.TakeProfitOrder.OrderID != 0 {
// if the take-profit order is already filled, the position is 0
if !types.IsActiveOrder(currentRound.TakeProfitOrder) {
return nil
}
Expand All @@ -159,15 +164,14 @@ func recoverPosition(ctx context.Context, position *types.Position, currentRound
}

for _, positionOrder := range positionOrders {
trades, err := queryService.QueryOrderTrades(ctx, types.OrderQuery{
trades, err := retry.QueryOrderTradesUntilSuccessful(ctx, queryService, types.OrderQuery{
Symbol: position.Symbol,
OrderID: strconv.FormatUint(positionOrder.OrderID, 10),
})

if err != nil {
return fmt.Errorf("failed to get trades of order (%d)", positionOrder.OrderID)
return errors.Wrapf(err, "failed to get order (%d) trades", positionOrder.OrderID)
}

position.AddTrades(trades)
}

Expand Down
9 changes: 7 additions & 2 deletions pkg/strategy/dca2/strategy.go
Original file line number Diff line number Diff line change
Expand Up @@ -318,6 +318,9 @@ func (s *Strategy) Run(ctx context.Context, _ bbgo.OrderExecutor, session *bbgo.
s.logger.Errorf("failed to recover after %d trying, please check it", maxTry)
return
}

// sleep 10 second to retry the recovery
time.Sleep(10 * time.Second)
}
}

Expand All @@ -337,14 +340,15 @@ func (s *Strategy) Run(ctx context.Context, _ bbgo.OrderExecutor, session *bbgo.
// ready
s.EmitReady()

// start to sync periodically
go s.syncPeriodically(ctx)

// start running state machine
s.runState(ctx)
}
})
})

go s.syncPeriodically(ctx)

bbgo.OnShutdown(ctx, func(ctx context.Context, wg *sync.WaitGroup) {
defer wg.Done()

Expand Down Expand Up @@ -456,6 +460,7 @@ func (s *Strategy) UpdateProfitStatsUntilSuccessful(ctx context.Context) error {
// return false, nil -> there is no finished round!
// return true, error -> At least one round update profit stats successfully but there is error when collecting other rounds
func (s *Strategy) UpdateProfitStats(ctx context.Context) (bool, error) {
s.logger.Info("update profit stats")
rounds, err := s.collector.CollectFinishRounds(ctx, s.ProfitStats.FromOrderID)
if err != nil {
return false, errors.Wrapf(err, "failed to collect finish rounds from #%d", s.ProfitStats.FromOrderID)
Expand Down

0 comments on commit 0396fc1

Please sign in to comment.