mirror of
https://github.com/c9s/bbgo.git
synced 2024-11-10 09:11:55 +00:00
Merge pull request #1640 from c9s/kbearXD/dca2/flexible-recovery
FEATURE: [dca2] change state recovery logic
This commit is contained in:
commit
c42c52d549
43
pkg/exchange/retry/account.go
Normal file
43
pkg/exchange/retry/account.go
Normal file
|
@ -0,0 +1,43 @@
|
|||
package retry
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/c9s/bbgo/pkg/types"
|
||||
)
|
||||
|
||||
func QueryAccountUntilSuccessful(
|
||||
ctx context.Context, ex types.ExchangeAccountService,
|
||||
) (account *types.Account, err error) {
|
||||
var op = func() (err2 error) {
|
||||
account, err2 = ex.QueryAccount(ctx)
|
||||
return err2
|
||||
}
|
||||
|
||||
err = GeneralBackoff(ctx, op)
|
||||
return account, err
|
||||
}
|
||||
|
||||
func QueryAccountBalancesUntilSuccessful(
|
||||
ctx context.Context, ex types.ExchangeAccountService,
|
||||
) (bals types.BalanceMap, err error) {
|
||||
var op = func() (err2 error) {
|
||||
bals, err2 = ex.QueryAccountBalances(ctx)
|
||||
return err2
|
||||
}
|
||||
|
||||
err = GeneralBackoff(ctx, op)
|
||||
return bals, err
|
||||
}
|
||||
|
||||
func QueryAccountBalancesUntilSuccessfulLite(
|
||||
ctx context.Context, ex types.ExchangeAccountService,
|
||||
) (bals types.BalanceMap, err error) {
|
||||
var op = func() (err2 error) {
|
||||
bals, err2 = ex.QueryAccountBalances(ctx)
|
||||
return err2
|
||||
}
|
||||
|
||||
err = GeneralLiteBackoff(ctx, op)
|
||||
return bals, err
|
||||
}
|
|
@ -180,18 +180,6 @@ func QueryOrderTradesUntilSuccessfulLite(
|
|||
return trades, err
|
||||
}
|
||||
|
||||
func QueryAccountUntilSuccessful(
|
||||
ctx context.Context, ex types.ExchangeAccountService,
|
||||
) (account *types.Account, err error) {
|
||||
var op = func() (err2 error) {
|
||||
account, err2 = ex.QueryAccount(ctx)
|
||||
return err2
|
||||
}
|
||||
|
||||
err = GeneralBackoff(ctx, op)
|
||||
return account, err
|
||||
}
|
||||
|
||||
func QueryOrderUntilSuccessful(
|
||||
ctx context.Context, query types.ExchangeOrderQueryService, opts types.OrderQuery,
|
||||
) (order *types.Order, err error) {
|
||||
|
|
|
@ -113,13 +113,13 @@ func recoverState(ctx context.Context, maxOrderCount int, currentRound Round, or
|
|||
}
|
||||
}
|
||||
|
||||
// all open-position orders are still not filled -> OpenPositionReady
|
||||
if filledCnt == 0 && cancelledCnt == 0 {
|
||||
// no order is filled -> OpenPositionReady
|
||||
if filledCnt == 0 {
|
||||
return OpenPositionReady, nil
|
||||
}
|
||||
|
||||
// there are at least one open-position orders filled
|
||||
if filledCnt > 0 && cancelledCnt == 0 {
|
||||
if cancelledCnt == 0 {
|
||||
if openedCnt > 0 {
|
||||
return OpenPositionOrderFilled, nil
|
||||
} else {
|
||||
|
@ -128,12 +128,8 @@ func recoverState(ctx context.Context, maxOrderCount int, currentRound Round, or
|
|||
}
|
||||
}
|
||||
|
||||
// there are at last one open-position orders cancelled ->
|
||||
if cancelledCnt > 0 {
|
||||
// there are at last one open-position orders cancelled and at least one filled order -> open position order cancelling
|
||||
return OpenPositionOrdersCancelling, nil
|
||||
}
|
||||
|
||||
return None, fmt.Errorf("unexpected order status combination (opened, filled, cancelled) = (%d, %d, %d)", openedCnt, filledCnt, cancelledCnt)
|
||||
}
|
||||
|
||||
func recoverPosition(ctx context.Context, position *types.Position, currentRound Round, queryService types.ExchangeOrderQueryService) error {
|
||||
|
|
|
@ -4,6 +4,7 @@ import (
|
|||
"context"
|
||||
"fmt"
|
||||
|
||||
"github.com/c9s/bbgo/pkg/exchange/retry"
|
||||
"github.com/c9s/bbgo/pkg/fixedpoint"
|
||||
"github.com/c9s/bbgo/pkg/types"
|
||||
"github.com/pkg/errors"
|
||||
|
@ -39,6 +40,27 @@ func (s *Strategy) placeTakeProfitOrders(ctx context.Context) error {
|
|||
s.logger.Infof("position of this round before place the take-profit order: %s", roundPosition.String())
|
||||
|
||||
order := generateTakeProfitOrder(s.Market, s.TakeProfitRatio, roundPosition, s.OrderGroupID)
|
||||
|
||||
// verify the volume of order
|
||||
bals, err := retry.QueryAccountBalancesUntilSuccessfulLite(ctx, s.ExchangeSession.Exchange)
|
||||
if err != nil {
|
||||
return errors.Wrapf(err, "failed to query balance to verify")
|
||||
}
|
||||
|
||||
bal, exist := bals[s.Market.BaseCurrency]
|
||||
if !exist {
|
||||
return fmt.Errorf("there is no %s in the balances %+v", s.Market.BaseCurrency, bals)
|
||||
}
|
||||
|
||||
quantityDiff := bal.Available.Sub(order.Quantity)
|
||||
if quantityDiff.Sign() < 0 {
|
||||
return fmt.Errorf("the balance (%s) is not enough for the order (%s)", bal.String(), order.Quantity.String())
|
||||
}
|
||||
|
||||
if quantityDiff.Compare(s.Market.MinQuantity) > 0 {
|
||||
s.logger.Warnf("the diff between balance (%s) and the take-profit order (%s) is larger than min quantity %s", bal.String(), order.Quantity.String(), s.Market.MinQuantity.String())
|
||||
}
|
||||
|
||||
createdOrders, err := s.OrderExecutor.SubmitOrders(ctx, order)
|
||||
if err != nil {
|
||||
return err
|
||||
|
|
Loading…
Reference in New Issue
Block a user