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 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 // GeneralOrderExecutor implements the general order executor for strategy
type GeneralOrderExecutor struct { type GeneralOrderExecutor struct {
BaseOrderExecutor BaseOrderExecutor

View File

@ -202,6 +202,15 @@ func (s *Strategy) getSourceMarket() (types.Market, bool) {
// convert triggers a convert order // convert triggers a convert order
func (s *Strategy) convert(ctx context.Context) error { 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() account := s.session.GetAccount()
fromAsset, ok := account.Balance(s.From) fromAsset, ok := account.Balance(s.From)
if !ok { if !ok {
@ -238,6 +247,8 @@ func (s *Strategy) convert(ctx context.Context) error {
} }
func (s *Strategy) collectPendingQuantity() { func (s *Strategy) collectPendingQuantity() {
log.Infof("collecting pending quantity...")
s.pendingQuantityLock.Lock() s.pendingQuantityLock.Lock()
defer s.pendingQuantityLock.Unlock() defer s.pendingQuantityLock.Unlock()
@ -246,13 +257,22 @@ func (s *Strategy) collectPendingQuantity() {
if m, ok := s.markets[o.Symbol]; ok { if m, ok := s.markets[o.Symbol]; ok {
switch o.Side { switch o.Side {
case types.SideTypeBuy: case types.SideTypeBuy:
if m.QuoteCurrency == s.From {
continue
}
qq := o.Quantity.Sub(o.ExecutedQuantity).Mul(o.Price) qq := o.Quantity.Sub(o.ExecutedQuantity).Mul(o.Price)
if q2, ok := s.pendingQuantity[m.QuoteCurrency]; ok { if q2, ok := s.pendingQuantity[m.QuoteCurrency]; ok {
s.pendingQuantity[m.QuoteCurrency] = q2.Add(qq) s.pendingQuantity[m.QuoteCurrency] = q2.Add(qq)
} else { } else {
s.pendingQuantity[m.QuoteCurrency] = qq s.pendingQuantity[m.QuoteCurrency] = qq
} }
case types.SideTypeSell: case types.SideTypeSell:
if m.BaseCurrency == s.From {
continue
}
q := o.Quantity.Sub(o.ExecutedQuantity) q := o.Quantity.Sub(o.ExecutedQuantity)
if q2, ok := s.pendingQuantity[m.BaseCurrency]; ok { if q2, ok := s.pendingQuantity[m.BaseCurrency]; ok {
s.pendingQuantity[m.BaseCurrency] = q2.Add(q) 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 { 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() s.pendingQuantityLock.Lock()
if pendingQ, ok := s.pendingQuantity[fromAsset]; ok { if pendingQ, ok := s.pendingQuantity[fromAsset]; ok {
log.Infof("adding pending quantity %s to the current quantity %s", pendingQ, available)
available = available.Add(pendingQ) available = available.Add(pendingQ)
delete(s.pendingQuantity, fromAsset) delete(s.pendingQuantity, fromAsset)