Merge pull request #1626 from c9s/kbearXD/dca2/fee-processing

FEATURE: [dca2] make QueryOrderTradesUntilsuccessful take feeProcessi…
This commit is contained in:
kbearXD 2024-04-30 11:02:33 +08:00 committed by GitHub
commit 150366c2f3
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 30 additions and 7 deletions

View File

@ -156,11 +156,17 @@ 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
}
@ -168,11 +174,17 @@ func QueryOrderTradesUntilSuccessful(
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
}

View File

@ -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)
@ -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),
})

View File

@ -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)
@ -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
}
@ -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)
}

View File

@ -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)
}
}
@ -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()
@ -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)