Skip to content

Commit faaecc3

Browse files
committed
Merge pull request #3407 from vegaprotocol/feature/matching-deduplicate
Feature/matching deduplicate
1 parent 74c11fb commit faaecc3

2 files changed

Lines changed: 183 additions & 308 deletions

File tree

matching/orderbook.go

Lines changed: 53 additions & 67 deletions
Original file line numberDiff line numberDiff line change
@@ -93,7 +93,6 @@ func (b *OrderBook) ReloadConf(cfg Config) {
9393
// GetCloseoutPrice returns the exit price which would be achieved for a given
9494
// volume and give side of the book
9595
func (b *OrderBook) GetCloseoutPrice(volume uint64, side types.Side) (uint64, error) {
96-
var price uint64
9796
if b.auction {
9897
p := b.GetIndicativePrice()
9998
return p, nil
@@ -102,31 +101,18 @@ func (b *OrderBook) GetCloseoutPrice(volume uint64, side types.Side) (uint64, er
102101
if volume == 0 {
103102
return 0, ErrInvalidVolume
104103
}
105-
vol := volume
104+
105+
var (
106+
price uint64
107+
vol = volume
108+
levels []*PriceLevel
109+
)
106110
if side == types.Side_SIDE_SELL {
107-
levels := b.sell.getLevels()
108-
for i := len(levels) - 1; i >= 0; i-- {
109-
lvl := levels[i]
110-
if lvl.volume >= vol {
111-
price += lvl.price * vol
112-
return price / volume, nil
113-
}
114-
price += lvl.price * lvl.volume
115-
vol -= lvl.volume
116-
}
117-
// at this point, we should check vol, make sure it's 0, if not return an error to indicate something is wrong
118-
// still return the price for the volume we could close out, so the caller can make a decision on what to do
119-
if vol == volume {
120-
return b.lastTradedPrice, ErrNotEnoughOrders
121-
}
122-
price = price / (volume - vol)
123-
if vol != 0 {
124-
return price, ErrNotEnoughOrders
125-
}
126-
return price, nil
111+
levels = b.sell.getLevels()
112+
} else {
113+
levels = b.buy.getLevels()
127114
}
128-
// side == buy
129-
levels := b.buy.getLevels()
115+
130116
for i := len(levels) - 1; i >= 0; i-- {
131117
lvl := levels[i]
132118
if lvl.volume >= vol {
@@ -136,7 +122,8 @@ func (b *OrderBook) GetCloseoutPrice(volume uint64, side types.Side) (uint64, er
136122
price += lvl.price * lvl.volume
137123
vol -= lvl.volume
138124
}
139-
// if we reach this point, chances are vol != 0, in which case we should return an error along with the price
125+
// at this point, we should check vol, make sure it's 0, if not return an error to indicate something is wrong
126+
// still return the price for the volume we could close out, so the caller can make a decision on what to do
140127
if vol == volume {
141128
return b.lastTradedPrice, ErrNotEnoughOrders
142129
}
@@ -437,66 +424,65 @@ func (b *OrderBook) uncrossBook() ([]*types.OrderConfirmation, error) {
437424
return nil, nil
438425
}
439426

440-
var uncrossedOrder *types.OrderConfirmation
441-
var allOrders []*types.OrderConfirmation
427+
var (
428+
err error
429+
uncrossOrders []*types.Order
430+
opSide *OrderBookSide
431+
)
442432

443433
// Remove all the orders from that side of the book up to the given volume
444434
if uncrossSide == types.Side_SIDE_BUY {
445435
// Pull out the trades we want to process
446-
uncrossOrders, err := b.buy.ExtractOrders(price, volume)
436+
uncrossOrders, err = b.buy.ExtractOrders(price, volume)
447437
if err != nil {
448438
return nil, err
449439
}
450-
451-
// Uncross each one
452-
for _, order := range uncrossOrders {
453-
trades, affectedOrders, _, err := b.sell.uncross(order, false)
454-
455-
if err != nil {
456-
return nil, err
457-
}
458-
// Update all the trades to have the correct uncrossing price
459-
for index := 0; index < len(trades); index++ {
460-
trades[index].Price = price
461-
}
462-
// If the affected order is fully filled set the status
463-
for _, affectedOrder := range affectedOrders {
464-
if affectedOrder.Remaining == 0 {
465-
affectedOrder.Status = types.Order_STATUS_FILLED
466-
}
467-
}
468-
uncrossedOrder = &types.OrderConfirmation{Order: order, PassiveOrdersAffected: affectedOrders, Trades: trades}
469-
allOrders = append(allOrders, uncrossedOrder)
470-
}
440+
opSide = b.sell
471441
} else {
472442
// Pull out the trades we want to process
473-
uncrossOrders, err := b.sell.ExtractOrders(price, volume)
443+
uncrossOrders, err = b.sell.ExtractOrders(price, volume)
474444
if err != nil {
475445
return nil, err
476446
}
447+
opSide = b.buy
448+
}
477449

478-
// Uncross each one
479-
for _, order := range uncrossOrders {
480-
trades, affectedOrders, _, err := b.buy.uncross(order, false)
450+
return b.uncrossBookSide(uncrossOrders, opSide, price)
451+
}
481452

482-
if err != nil {
483-
return nil, err
484-
}
485-
// Update all the trades to have the correct uncrossing price
486-
for index := 0; index < len(trades); index++ {
487-
trades[index].Price = price
488-
}
489-
// If the affected order is fully filled set the status
490-
for _, affectedOrder := range affectedOrders {
491-
if affectedOrder.Remaining == 0 {
492-
affectedOrder.Status = types.Order_STATUS_FILLED
493-
}
453+
// Takes extracted order from a side of the book, and uncross them
454+
// with the opposite side.
455+
func (b *OrderBook) uncrossBookSide(
456+
uncrossOrders []*types.Order,
457+
opSide *OrderBookSide,
458+
price uint64,
459+
) ([]*types.OrderConfirmation, error) {
460+
var (
461+
uncrossedOrder *types.OrderConfirmation
462+
allOrders []*types.OrderConfirmation
463+
)
464+
// Uncross each one
465+
for _, order := range uncrossOrders {
466+
trades, affectedOrders, _, err := opSide.uncross(order, false)
467+
468+
if err != nil {
469+
return nil, err
470+
}
471+
// Update all the trades to have the correct uncrossing price
472+
for index := 0; index < len(trades); index++ {
473+
trades[index].Price = price
474+
}
475+
// If the affected order is fully filled set the status
476+
for _, affectedOrder := range affectedOrders {
477+
if affectedOrder.Remaining == 0 {
478+
affectedOrder.Status = types.Order_STATUS_FILLED
494479
}
495-
uncrossedOrder = &types.OrderConfirmation{Order: order, PassiveOrdersAffected: affectedOrders, Trades: trades}
496-
allOrders = append(allOrders, uncrossedOrder)
497480
}
481+
uncrossedOrder = &types.OrderConfirmation{Order: order, PassiveOrdersAffected: affectedOrders, Trades: trades}
482+
allOrders = append(allOrders, uncrossedOrder)
498483
}
499484
return allOrders, nil
485+
500486
}
501487

502488
func (b *OrderBook) GetOrdersPerParty(party string) []*types.Order {

0 commit comments

Comments
 (0)