convert: fix collectPendingQuantity and use graceful order cancel

This commit is contained in:
c9s 2023-08-05 02:15:16 +08:00
parent 71186b6794
commit bc8fe22e70
No known key found for this signature in database
GPG Key ID: 7385E7E464CB0A54
2 changed files with 33 additions and 5 deletions

View File

@ -41,6 +41,15 @@ func (e *BaseOrderExecutor) ActiveMakerOrders() *ActiveOrderBook {
return e.activeMakerOrders
}
// GracefulCancel cancels all active maker orders if orders are not given, otherwise cancel all the given orders
func (e *BaseOrderExecutor) GracefulCancel(ctx context.Context, orders ...types.Order) error {
if err := e.activeMakerOrders.GracefulCancel(ctx, e.session.Exchange, orders...); err != nil {
return errors.Wrap(err, "graceful cancel error")
}
return nil
}
// GeneralOrderExecutor implements the general order executor for strategy
type GeneralOrderExecutor struct {
BaseOrderExecutor

View File

@ -202,6 +202,15 @@ func (s *Strategy) getSourceMarket() (types.Market, bool) {
// convert triggers a convert order
func (s *Strategy) convert(ctx context.Context) error {
s.collectPendingQuantity()
if err := s.orderExecutor.GracefulCancel(ctx); err != nil {
log.WithError(err).Warn("unable to cancel orders")
}
// sleep one second for exchange to unlock the balance
time.Sleep(time.Second)
account := s.session.GetAccount()
fromAsset, ok := account.Balance(s.From)
if !ok {
@ -238,6 +247,8 @@ func (s *Strategy) convert(ctx context.Context) error {
}
func (s *Strategy) collectPendingQuantity() {
log.Infof("collecting pending quantity...")
s.pendingQuantityLock.Lock()
defer s.pendingQuantityLock.Unlock()
@ -246,13 +257,22 @@ func (s *Strategy) collectPendingQuantity() {
if m, ok := s.markets[o.Symbol]; ok {
switch o.Side {
case types.SideTypeBuy:
if m.QuoteCurrency == s.From {
continue
}
qq := o.Quantity.Sub(o.ExecutedQuantity).Mul(o.Price)
if q2, ok := s.pendingQuantity[m.QuoteCurrency]; ok {
s.pendingQuantity[m.QuoteCurrency] = q2.Add(qq)
} else {
s.pendingQuantity[m.QuoteCurrency] = qq
}
case types.SideTypeSell:
if m.BaseCurrency == s.From {
continue
}
q := o.Quantity.Sub(o.ExecutedQuantity)
if q2, ok := s.pendingQuantity[m.BaseCurrency]; ok {
s.pendingQuantity[m.BaseCurrency] = q2.Add(q)
@ -262,17 +282,16 @@ func (s *Strategy) collectPendingQuantity() {
}
}
}
log.Infof("collected pending quantity: %+v", s.pendingQuantity)
}
func (s *Strategy) convertBalance(ctx context.Context, fromAsset string, available fixedpoint.Value, market types.Market, ticker *types.Ticker) error {
s.collectPendingQuantity()
if err := s.orderExecutor.CancelOrders(ctx); err != nil {
log.WithError(err).Warn("unable to cancel orders")
}
s.pendingQuantityLock.Lock()
if pendingQ, ok := s.pendingQuantity[fromAsset]; ok {
log.Infof("adding pending quantity %s to the current quantity %s", pendingQ, available)
available = available.Add(pendingQ)
delete(s.pendingQuantity, fromAsset)