diff --git a/pkg/bbgo/activeorderbook.go b/pkg/bbgo/activeorderbook.go index 7cfab2dfd..5240a9f7c 100644 --- a/pkg/bbgo/activeorderbook.go +++ b/pkg/bbgo/activeorderbook.go @@ -16,7 +16,7 @@ import ( "github.com/c9s/bbgo/pkg/types" ) -const DefaultCancelOrderWaitTime = 20 * time.Millisecond +const DefaultCancelOrderWaitTime = 50 * time.Millisecond const DefaultOrderCancelTimeout = 5 * time.Second // ActiveOrderBook manages the local active order books. @@ -336,7 +336,7 @@ func (b *ActiveOrderBook) Update(order types.Order) { // if we can't detect which is newer, isNewerOrderUpdate returns false // if you pass two same objects to isNewerOrderUpdate, it returns false if !isNewerOrderUpdate(order, previousOrder) { - log.Infof("[ActiveOrderBook] order #%d updateTime %s is out of date, skip it", order.OrderID, order.UpdateTime) + log.Infof("[ActiveOrderBook] order #%d (update time %s) is out of date, skip it", order.OrderID, order.UpdateTime) b.mu.Unlock() return } @@ -393,26 +393,33 @@ func (b *ActiveOrderBook) Add(orders ...types.Order) { } } +// isNewerOrderUpdate checks if the order a is newer than the order b. func isNewerOrderUpdate(a, b types.Order) bool { // compare state first switch a.Status { case types.OrderStatusCanceled, types.OrderStatusRejected: // canceled is a final state switch b.Status { - case types.OrderStatusNew, types.OrderStatusPartiallyFilled: + + case types.OrderStatusCanceled, types.OrderStatusRejected, types.OrderStatusNew, types.OrderStatusPartiallyFilled: return true } case types.OrderStatusPartiallyFilled: switch b.Status { + case types.OrderStatusNew: return true + case types.OrderStatusPartiallyFilled: // unknown for equal if a.ExecutedQuantity.Compare(b.ExecutedQuantity) > 0 { return true } + if a.UpdateTime.After(b.UpdateTime.Time()) { + return true + } } case types.OrderStatusFilled: diff --git a/pkg/core/orderstore.go b/pkg/core/orderstore.go index 7ba228248..bcbd055de 100644 --- a/pkg/core/orderstore.go +++ b/pkg/core/orderstore.go @@ -147,6 +147,7 @@ func (s *OrderStore) Prune(expiryDuration time.Duration) { defer s.mu.Unlock() for idx, o := range s.orders { + // if the order is canceled or filled, we should remove the order if the update time is before the cut off time if o.Status == types.OrderStatusCanceled || o.Status == types.OrderStatusFilled { if o.UpdateTime.Time().Before(cutOffTime) { continue diff --git a/pkg/strategy/xmaker/strategy.go b/pkg/strategy/xmaker/strategy.go index 2b94a9034..90ba8d276 100644 --- a/pkg/strategy/xmaker/strategy.go +++ b/pkg/strategy/xmaker/strategy.go @@ -1213,16 +1213,13 @@ func (s *Strategy) Hedge(ctx context.Context, pos fixedpoint.Value) { } lastPrice := s.lastPrice.Get() - sourceBook := s.sourceBook.CopyDepth(1) - switch side { - case types.SideTypeBuy: - if bestAsk, ok := sourceBook.BestAsk(); ok { + bestBid, bestAsk, ok := s.sourceBook.BestBidAndAsk() + if ok { + switch side { + case types.SideTypeBuy: lastPrice = bestAsk.Price - } - - case types.SideTypeSell: - if bestBid, ok := sourceBook.BestBid(); ok { + case types.SideTypeSell: lastPrice = bestBid.Price } }