Merge pull request #1064 from c9s/fix/pending-maker-order-handler

fix: emit order update handler from the pending maker order
This commit is contained in:
Yo-An Lin 2023-02-23 21:57:03 +08:00 committed by GitHub
commit f453a22972
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 43 additions and 19 deletions

View File

@ -307,13 +307,23 @@ func (b *ActiveOrderBook) Add(orders ...types.Order) {
// add the order to the active order book and check the pending order
func (b *ActiveOrderBook) add(order types.Order) {
if pendingOrder, ok := b.pendingOrderUpdates.Get(order.OrderID); ok {
// if the pending order update time is newer than the adding order
// we should use the pending order rather than the adding order.
// if pending order is older, than we should add the new one, and drop the pending order
if pendingOrder.UpdateTime.Time().After(order.UpdateTime.Time()) {
b.orders.Add(pendingOrder)
} else {
b.orders.Add(order)
order = pendingOrder
}
b.orders.Add(order)
b.pendingOrderUpdates.Remove(pendingOrder.OrderID)
// when using add(order), it's usually a new maker order on the order book.
// so, when it's not status=new, we should trigger order update handler
if order.Status != types.OrderStatusNew {
// emit the order update handle function to trigger callback
b.orderUpdateHandler(order)
}
b.pendingOrderUpdates.Remove(order.OrderID)
} else {
b.orders.Add(order)
}

View File

@ -12,8 +12,14 @@ import (
func TestActiveOrderBook_pendingOrders(t *testing.T) {
now := time.Now()
ob := NewActiveOrderBook("")
filled := false
ob.OnFilled(func(o types.Order) {
filled = true
})
// if we received filled order first
// should be added to pending orders
ob.orderUpdateHandler(types.Order{
@ -34,6 +40,11 @@ func TestActiveOrderBook_pendingOrders(t *testing.T) {
assert.Len(t, ob.pendingOrderUpdates.Orders(), 1)
o99, ok := ob.pendingOrderUpdates.Get(99)
if assert.True(t, ok) {
assert.Equal(t, types.OrderStatusFilled, o99.Status)
}
// should be added to pending orders
ob.Add(types.Order{
OrderID: 99,
@ -51,7 +62,6 @@ func TestActiveOrderBook_pendingOrders(t *testing.T) {
UpdateTime: types.Time(now.Add(-time.Second)),
})
o99, ok := ob.Get(99)
assert.True(t, ok)
assert.Equal(t, types.OrderStatusFilled, o99.Status)
assert.True(t, filled, "filled event should be fired")
}

View File

@ -1578,6 +1578,7 @@ func (s *Strategy) Run(ctx context.Context, _ bbgo.OrderExecutor, session *bbgo.
if err := s.recoverGrid(ctx, session); err != nil {
log.WithError(err).Errorf("recover error")
}
}
if err := s.openGrid(ctx, session); err != nil {
@ -1596,21 +1597,24 @@ func (s *Strategy) recoverGrid(ctx context.Context, session *bbgo.ExchangeSessio
return err
}
s.logger.Infof("found %d open orders left on the %s order book", len(openOrders), s.Symbol)
// do recover only when openOrders > 0
if len(openOrders) > 0 {
historyService, implemented := session.Exchange.(types.ExchangeTradeHistoryService)
if !implemented {
s.logger.Warn("ExchangeTradeHistoryService is not implemented, can not recover grid")
return nil
}
if err := s.recoverGridWithOpenOrders(ctx, historyService, openOrders); err != nil {
return errors.Wrap(err, "recover grid error")
}
if len(openOrders) == 0 {
return nil
}
s.logger.Infof("found %d open orders left on the %s order book", len(openOrders), s.Symbol)
historyService, implemented := session.Exchange.(types.ExchangeTradeHistoryService)
if !implemented {
s.logger.Warn("ExchangeTradeHistoryService is not implemented, can not recover grid")
return nil
}
if err := s.recoverGridWithOpenOrders(ctx, historyService, openOrders); err != nil {
return errors.Wrap(err, "recover grid error")
}
s.updateOpenOrderPricesMetrics(s.orderExecutor.ActiveMakerOrders().Orders())
return nil
}