CppTrader  1.0.4.0
C++ Trader
market_manager.cpp
Go to the documentation of this file.
1 
10 
11 namespace CppTrader {
12 namespace Matching {
13 
14 MarketHandler MarketManager::_default;
15 
17 {
18  // Release orders
19  for (const auto& order : _orders)
20  _order_pool.Release(order.second);
21  _orders.clear();
22 
23  // Release order books
24  for (auto order_book_ptr : _order_books)
25  if (order_book_ptr != nullptr)
26  _order_book_pool.Release(order_book_ptr);
27  _order_books.clear();
28 
29  // Release symbols
30  for (auto symbol_ptr : _symbols)
31  if (symbol_ptr != nullptr)
32  _symbol_pool.Release(symbol_ptr);
33  _symbols.clear();
34 }
35 
37 {
38  // Resize the symbol container
39  if (_symbols.size() <= symbol.Id)
40  _symbols.resize(symbol.Id + 1, nullptr);
41 
42  // Create a new symbol
43  Symbol* symbol_ptr = _symbol_pool.Create(symbol);
44 
45  // Insert the symbol
46  assert((_symbols[symbol.Id] == nullptr) && "Duplicate symbol detected!");
47  if (_symbols[symbol.Id] != nullptr)
48  {
49  // Release the symbol
50  _symbol_pool.Release(symbol_ptr);
52  }
53  _symbols[symbol.Id] = symbol_ptr;
54 
55  // Call the corresponding handler
56  _market_handler.onAddSymbol(*symbol_ptr);
57 
58  return ErrorCode::OK;
59 }
60 
62 {
63  assert(((id < _symbols.size()) && (_symbols[id] != nullptr)) && "Symbol not found!");
64  if ((_symbols.size() <= id) || (_symbols[id] == nullptr))
66 
67  // Get the symbol by Id
68  Symbol* symbol_ptr = _symbols[id];
69 
70  // Call the corresponding handler
71  _market_handler.onDeleteSymbol(*symbol_ptr);
72 
73  // Erase the symbol
74  _symbols[id] = nullptr;
75 
76  // Release the symbol
77  _symbol_pool.Release(symbol_ptr);
78 
79  return ErrorCode::OK;
80 }
81 
83 {
84  assert(((symbol.Id < _symbols.size()) && (_symbols[symbol.Id] != nullptr)) && "Symbol not found!");
85  if ((_symbols.size() <= symbol.Id) || (_symbols[symbol.Id] == nullptr))
87 
88  // Get the symbol by Id
89  Symbol* symbol_ptr = _symbols[symbol.Id];
90 
91  // Resize the order book container
92  if (_order_books.size() <= symbol.Id)
93  _order_books.resize(symbol.Id + 1, nullptr);
94 
95  // Create a new order book
96  OrderBook* order_book_ptr = _order_book_pool.Create(*this, *symbol_ptr);
97 
98  // Insert the order book
99  assert((_order_books[symbol.Id] == nullptr) && "Duplicate order book detected!");
100  if (_order_books[symbol.Id] != nullptr)
101  {
102  // Release the order book
103  _order_book_pool.Release(order_book_ptr);
105  }
106  _order_books[symbol.Id] = order_book_ptr;
107 
108  // Call the corresponding handler
109  _market_handler.onAddOrderBook(*order_book_ptr);
110 
111  return ErrorCode::OK;
112 }
113 
115 {
116  assert(((id < _order_books.size()) && (_order_books[id] != nullptr)) && "Order book not found!");
117  if ((_order_books.size() <= id) || (_order_books[id] == nullptr))
119 
120  // Get the order book by Id
121  OrderBook* order_book_ptr = _order_books[id];
122 
123  // Call the corresponding handler
124  _market_handler.onDeleteOrderBook(*order_book_ptr);
125 
126  // Erase the order book
127  _order_books[id] = nullptr;
128 
129  // Release the order book
130  _order_book_pool.Release(order_book_ptr);
131 
132  return ErrorCode::OK;
133 }
134 
136 {
137  // Validate order parameters
138  ErrorCode result = order.Validate();
139  if (result != ErrorCode::OK)
140  return result;
141 
142  // Add the corresponding order type
143  switch (order.Type)
144  {
145  case OrderType::MARKET:
146  return AddMarketOrder(order, false);
147  case OrderType::LIMIT:
148  return AddLimitOrder(order, false);
149  case OrderType::STOP:
151  return AddStopOrder(order, false);
154  return AddStopLimitOrder(order, false);
155  default:
157  }
158 }
159 
160 ErrorCode MarketManager::AddMarketOrder(const Order& order, bool recursive)
161 {
162  // Get the valid order book for the order
163  OrderBook* order_book_ptr = (OrderBook*)GetOrderBook(order.SymbolId);
164  if (order_book_ptr == nullptr)
166 
167  Order new_order(order);
168 
169  // Call the corresponding handler
170  _market_handler.onAddOrder(new_order);
171 
172  // Automatic order matching
173  if (_matching && !recursive)
174  MatchMarket(order_book_ptr, &new_order);
175 
176  // Call the corresponding handler
177  _market_handler.onDeleteOrder(new_order);
178 
179  // Automatic order matching
180  if (_matching && !recursive)
181  Match(order_book_ptr);
182 
183  // Reset matching price
184  order_book_ptr->ResetMatchingPrice();
185 
186  return ErrorCode::OK;
187 }
188 
189 ErrorCode MarketManager::AddLimitOrder(const Order& order, bool recursive)
190 {
191  // Get the valid order book for the order
192  OrderBook* order_book_ptr = (OrderBook*)GetOrderBook(order.SymbolId);
193  if (order_book_ptr == nullptr)
195 
196  Order new_order(order);
197 
198  // Call the corresponding handler
199  _market_handler.onAddOrder(new_order);
200 
201  // Automatic order matching
202  if (_matching && !recursive)
203  MatchLimit(order_book_ptr, &new_order);
204 
205  // Add a new order or delete remaining part in case of 'Immediate-Or-Cancel'/'Fill-Or-Kill' order
206  if ((new_order.LeavesQuantity > 0) && !new_order.IsIOC() && !new_order.IsFOK())
207  {
208  // Create a new order
209  OrderNode* order_ptr = _order_pool.Create(new_order);
210 
211  // Insert the order
212  if (!_orders.insert(std::make_pair(order_ptr->Id, order_ptr)).second)
213  {
214  // Call the corresponding handler
215  _market_handler.onDeleteOrder(*order_ptr);
216 
217  // Release the order
218  _order_pool.Release(order_ptr);
219 
221  }
222 
223  // Add the new limit order into the order book
224  UpdateLevel(*order_book_ptr, order_book_ptr->AddOrder(order_ptr));
225  }
226  else
227  {
228  // Call the corresponding handler
229  _market_handler.onDeleteOrder(new_order);
230  }
231 
232  // Automatic order matching
233  if (_matching && !recursive)
234  Match(order_book_ptr);
235 
236  // Reset matching price
237  order_book_ptr->ResetMatchingPrice();
238 
239  return ErrorCode::OK;
240 }
241 
242 ErrorCode MarketManager::AddStopOrder(const Order& order, bool recursive)
243 {
244  // Get the valid order book for the order
245  OrderBook* order_book_ptr = (OrderBook*)GetOrderBook(order.SymbolId);
246  if (order_book_ptr == nullptr)
248 
249  Order new_order(order);
250 
251  // Recalculate stop price for trailing stop orders
252  if (new_order.IsTrailingStop() || new_order.IsTrailingStopLimit())
253  new_order.StopPrice = order_book_ptr->CalculateTrailingStopPrice(new_order);
254 
255  // Call the corresponding handler
256  _market_handler.onAddOrder(new_order);
257 
258  // Automatic order matching
259  if (_matching && !recursive)
260  {
261  // Find the price to match the stop order
262  uint64_t stop_price = new_order.IsBuy() ? order_book_ptr->GetMarketPriceAsk() : order_book_ptr->GetMarketPriceBid();
263 
264  // Check the arbitrage bid/ask prices
265  bool arbitrage = new_order.IsBuy() ? (new_order.StopPrice <= stop_price) : (new_order.StopPrice >= stop_price);
266  if (arbitrage)
267  {
268  // Convert the stop order into the market order
269  new_order.Type = OrderType::MARKET;
270  new_order.Price = 0;
271  new_order.StopPrice = 0;
272  new_order.TimeInForce = new_order.IsFOK() ? OrderTimeInForce::FOK : OrderTimeInForce::IOC;
273 
274  // Call the corresponding handler
275  _market_handler.onUpdateOrder(new_order);
276 
277  // Match the market order
278  MatchMarket(order_book_ptr, &new_order);
279 
280  // Call the corresponding handler
281  _market_handler.onDeleteOrder(new_order);
282 
283  // Automatic order matching
284  if (_matching && !recursive)
285  Match(order_book_ptr);
286 
287  // Reset matching price
288  order_book_ptr->ResetMatchingPrice();
289 
290  return ErrorCode::OK;
291  }
292  }
293 
294  // Add a new order
295  if (new_order.LeavesQuantity > 0)
296  {
297  // Create a new order
298  OrderNode* order_ptr = _order_pool.Create(new_order);
299 
300  // Insert the order
301  if (!_orders.insert(std::make_pair(order_ptr->Id, order_ptr)).second)
302  {
303  // Call the corresponding handler
304  _market_handler.onDeleteOrder(*order_ptr);
305 
306  // Release the order
307  _order_pool.Release(order_ptr);
308 
310  }
311 
312  // Add the new stop order into the order book
313  if (order_ptr->IsTrailingStop() || order_ptr->IsTrailingStopLimit())
314  order_book_ptr->AddTrailingStopOrder(order_ptr);
315  else
316  order_book_ptr->AddStopOrder(order_ptr);
317  }
318  else
319  {
320  // Call the corresponding handler
321  _market_handler.onDeleteOrder(new_order);
322  }
323 
324  // Automatic order matching
325  if (_matching && !recursive)
326  Match(order_book_ptr);
327 
328  // Reset matching price
329  order_book_ptr->ResetMatchingPrice();
330 
331  return ErrorCode::OK;
332 }
333 
334 ErrorCode MarketManager::AddStopLimitOrder(const Order& order, bool recursive)
335 {
336  // Get the valid order book for the order
337  OrderBook* order_book_ptr = (OrderBook*)GetOrderBook(order.SymbolId);
338  if (order_book_ptr == nullptr)
340 
341  Order new_order(order);
342 
343  // Recalculate stop price for trailing stop orders
344  if (new_order.IsTrailingStop() || new_order.IsTrailingStopLimit())
345  {
346  int64_t diff = new_order.Price - new_order.StopPrice;
347  new_order.StopPrice = order_book_ptr->CalculateTrailingStopPrice(new_order);
348  new_order.Price = new_order.StopPrice + diff;
349  }
350 
351  // Call the corresponding handler
352  _market_handler.onAddOrder(new_order);
353 
354  // Automatic order matching
355  if (_matching && !recursive)
356  {
357  // Find the price to match the stop-limit order
358  uint64_t stop_price = new_order.IsBuy() ? order_book_ptr->GetMarketPriceAsk() : order_book_ptr->GetMarketPriceBid();
359 
360  // Check the arbitrage bid/ask prices
361  bool arbitrage = new_order.IsBuy() ? (new_order.StopPrice <= stop_price) : (new_order.StopPrice >= stop_price);
362  if (arbitrage)
363  {
364  // Convert the stop-limit order into the limit order
365  new_order.Type = OrderType::LIMIT;
366  new_order.StopPrice = 0;
367 
368  // Call the corresponding handler
369  _market_handler.onUpdateOrder(new_order);
370 
371  // Match the limit order
372  MatchLimit(order_book_ptr, &new_order);
373 
374  // Add a new limit order or delete remaining part in case of 'Immediate-Or-Cancel'/'Fill-Or-Kill' order
375  if ((new_order.LeavesQuantity > 0) && !new_order.IsIOC() && !new_order.IsFOK())
376  {
377  // Create a new order
378  OrderNode* order_ptr = _order_pool.Create(new_order);
379 
380  // Insert the order
381  if (!_orders.insert(std::make_pair(order_ptr->Id, order_ptr)).second)
382  {
383  // Call the corresponding handler
384  _market_handler.onDeleteOrder(*order_ptr);
385 
386  // Release the order
387  _order_pool.Release(order_ptr);
388 
390  }
391 
392  // Add the new limit order into the order book
393  UpdateLevel(*order_book_ptr, order_book_ptr->AddOrder(order_ptr));
394  }
395  else
396  {
397  // Call the corresponding handler
398  _market_handler.onDeleteOrder(new_order);
399  }
400 
401  // Automatic order matching
402  if (_matching && !recursive)
403  Match(order_book_ptr);
404 
405  // Reset matching price
406  order_book_ptr->ResetMatchingPrice();
407 
408  return ErrorCode::OK;
409  }
410  }
411 
412  // Add a new order
413  if (new_order.LeavesQuantity > 0)
414  {
415  // Create a new order
416  OrderNode* order_ptr = _order_pool.Create(new_order);
417 
418  // Insert the order
419  if (!_orders.insert(std::make_pair(order_ptr->Id, order_ptr)).second)
420  {
421  // Call the corresponding handler
422  _market_handler.onDeleteOrder(*order_ptr);
423 
424  // Release the order
425  _order_pool.Release(order_ptr);
426 
428  }
429 
430  // Add the new stop order into the order book
431  if (order_ptr->IsTrailingStop() || order_ptr->IsTrailingStopLimit())
432  order_book_ptr->AddTrailingStopOrder(order_ptr);
433  else
434  order_book_ptr->AddStopOrder(order_ptr);
435  }
436  else
437  {
438  // Call the corresponding handler
439  _market_handler.onDeleteOrder(new_order);
440  }
441 
442  // Automatic order matching
443  if (_matching && !recursive)
444  Match(order_book_ptr);
445 
446  // Reset matching price
447  order_book_ptr->ResetMatchingPrice();
448 
449  return ErrorCode::OK;
450 }
451 
452 ErrorCode MarketManager::ReduceOrder(uint64_t id, uint64_t quantity)
453 {
454  return ReduceOrder(id, quantity, false);
455 }
456 
457 ErrorCode MarketManager::ReduceOrder(uint64_t id, uint64_t quantity, bool recursive)
458 {
459  // Validate parameters
460  assert((id > 0) && "Order Id must be greater than zero!");
461  if (id == 0)
463  assert((quantity > 0) && "Order quantity must be greater than zero!");
464  if (quantity == 0)
466 
467  // Get the order to reduce
468  auto order_it = _orders.find(id);
469  assert((order_it != _orders.end()) && "Order not found!");
470  if (order_it == _orders.end())
472  OrderNode* order_ptr = (OrderNode*)order_it->second;
473 
474  // Get the valid order book for the order
475  OrderBook* order_book_ptr = (OrderBook*)GetOrderBook(order_ptr->SymbolId);
476  if (order_book_ptr == nullptr)
478 
479  // Calculate the minimal possible order quantity to reduce
480  quantity = std::min(quantity, order_ptr->LeavesQuantity);
481 
482  uint64_t hidden = order_ptr->HiddenQuantity();
483  uint64_t visible = order_ptr->VisibleQuantity();
484 
485  // Reduce the order leaves quantity
486  order_ptr->LeavesQuantity -= quantity;
487 
488  hidden -= order_ptr->HiddenQuantity();
489  visible -= order_ptr->VisibleQuantity();
490 
491  // Update the order or delete the empty order
492  if (order_ptr->LeavesQuantity > 0)
493  {
494  // Call the corresponding handler
495  _market_handler.onUpdateOrder(*order_ptr);
496 
497  // Reduce the order in the order book
498  switch (order_ptr->Type)
499  {
500  case OrderType::LIMIT:
501  UpdateLevel(*order_book_ptr, order_book_ptr->ReduceOrder(order_ptr, quantity, hidden, visible));
502  break;
503  case OrderType::STOP:
505  order_book_ptr->ReduceStopOrder(order_ptr, quantity, hidden, visible);
506  break;
509  order_book_ptr->ReduceTrailingStopOrder(order_ptr, quantity, hidden, visible);
510  break;
511  default:
512  assert(false && "Unsupported order type!");
513  break;
514  }
515  }
516  else
517  {
518  // Call the corresponding handler
519  _market_handler.onDeleteOrder(*order_ptr);
520 
521  // Reduce the order in the order book
522  switch (order_ptr->Type)
523  {
524  case OrderType::LIMIT:
525  UpdateLevel(*order_book_ptr, order_book_ptr->ReduceOrder(order_ptr, quantity, hidden, visible));
526  break;
527  case OrderType::STOP:
529  order_book_ptr->ReduceStopOrder(order_ptr, quantity, hidden, visible);
530  break;
533  order_book_ptr->ReduceTrailingStopOrder(order_ptr, quantity, hidden, visible);
534  break;
535  default:
536  assert(false && "Unsupported order type!");
537  break;
538  }
539 
540  // Erase the order
541  _orders.erase(order_it);
542 
543  // Relase the order
544  _order_pool.Release(order_ptr);
545  }
546 
547  // Automatic order matching
548  if (_matching && !recursive)
549  Match(order_book_ptr);
550 
551  // Reset matching price
552  order_book_ptr->ResetMatchingPrice();
553 
554  return ErrorCode::OK;
555 }
556 
557 ErrorCode MarketManager::ModifyOrder(uint64_t id, uint64_t new_price, uint64_t new_quantity)
558 {
559  return ModifyOrder(id, new_price, new_quantity, false, false);
560 }
561 
562 ErrorCode MarketManager::MitigateOrder(uint64_t id, uint64_t new_price, uint64_t new_quantity)
563 {
564  return ModifyOrder(id, new_price, new_quantity, true, false);
565 }
566 
567 ErrorCode MarketManager::ModifyOrder(uint64_t id, uint64_t new_price, uint64_t new_quantity, bool mitigate, bool recursive)
568 {
569  // Validate parameters
570  assert((id > 0) && "Order Id must be greater than zero!");
571  if (id == 0)
573  assert((new_quantity > 0) && "Order quantity must be greater than zero!");
574  if (new_quantity == 0)
576 
577  // Get the order to modify
578  auto order_it = _orders.find(id);
579  assert((order_it != _orders.end()) && "Order not found!");
580  if (order_it == _orders.end())
582  OrderNode* order_ptr = (OrderNode*)order_it->second;
583 
584  // Get the valid order book for the order
585  OrderBook* order_book_ptr = (OrderBook*)GetOrderBook(order_ptr->SymbolId);
586  if (order_book_ptr == nullptr)
588 
589  // Delete the order from the order book
590  switch (order_ptr->Type)
591  {
592  case OrderType::LIMIT:
593  UpdateLevel(*order_book_ptr, order_book_ptr->DeleteOrder(order_ptr));
594  break;
595  case OrderType::STOP:
597  order_book_ptr->DeleteStopOrder(order_ptr);
598  break;
601  order_book_ptr->DeleteTrailingStopOrder(order_ptr);
602  break;
603  default:
604  assert(false && "Unsupported order type!");
605  break;
606  }
607 
608  // Modify the order
609  order_ptr->Price = new_price;
610  order_ptr->Quantity = new_quantity;
611  order_ptr->LeavesQuantity = new_quantity;
612 
613  // In-Flight Mitigation (IFM)
614  if (mitigate)
615  {
616  // This calculation has the goal of preventing orders from being overfilled
617  if (new_quantity > order_ptr->ExecutedQuantity)
618  order_ptr->LeavesQuantity = new_quantity - order_ptr->ExecutedQuantity;
619  else
620  order_ptr->LeavesQuantity = 0;
621  }
622 
623  // Update the order
624  if (order_ptr->LeavesQuantity > 0)
625  {
626  // Call the corresponding handler
627  _market_handler.onUpdateOrder(*order_ptr);
628 
629  // Automatic order matching
630  if (_matching && !recursive)
631  MatchLimit(order_book_ptr, order_ptr);
632 
633  // Add non empty order into the order book
634  if (order_ptr->LeavesQuantity > 0)
635  {
636  // Add the modified order into the order book
637  switch (order_ptr->Type)
638  {
639  case OrderType::LIMIT:
640  UpdateLevel(*order_book_ptr, order_book_ptr->AddOrder(order_ptr));
641  break;
642  case OrderType::STOP:
644  order_book_ptr->AddStopOrder(order_ptr);
645  break;
648  order_book_ptr->AddTrailingStopOrder(order_ptr);
649  break;
650  default:
651  assert(false && "Unsupported order type!");
652  break;
653  }
654  }
655  }
656 
657  // Delete the empty order
658  if (order_ptr->LeavesQuantity == 0)
659  {
660  // Call the corresponding handler
661  _market_handler.onDeleteOrder(*order_ptr);
662 
663  // Erase the order
664  _orders.erase(order_it);
665 
666  // Relase the order
667  _order_pool.Release(order_ptr);
668  }
669 
670  // Automatic order matching
671  if (_matching && !recursive)
672  Match(order_book_ptr);
673 
674  // Reset matching price
675  order_book_ptr->ResetMatchingPrice();
676 
677  return ErrorCode::OK;
678 }
679 
680 ErrorCode MarketManager::ReplaceOrder(uint64_t id, uint64_t new_id, uint64_t new_price, uint64_t new_quantity)
681 {
682  return ReplaceOrder(id, new_id, new_price, new_quantity, false);
683 }
684 
685 ErrorCode MarketManager::ReplaceOrder(uint64_t id, uint64_t new_id, uint64_t new_price, uint64_t new_quantity, bool recursive)
686 {
687  // Validate parameters
688  assert((id > 0) && "Order Id must be greater than zero!");
689  if (id == 0)
691  assert((new_id > 0) && "New order Id must be greater than zero!");
692  if (new_id == 0)
694  assert((new_quantity > 0) && "Order quantity must be greater than zero!");
695  if (new_quantity == 0)
697 
698  // Get the order to replace
699  auto order_it = _orders.find(id);
700  assert((order_it != _orders.end()) && "Order not found!");
701  if (order_it == _orders.end())
703  OrderNode* order_ptr = (OrderNode*)order_it->second;
704  assert(order_ptr->IsLimit() && "Replace order operation is valid only for limit orders!");
705  if (!order_ptr->IsLimit())
707 
708  // Get the valid order book for the order
709  OrderBook* order_book_ptr = (OrderBook*)GetOrderBook(order_ptr->SymbolId);
710  if (order_book_ptr == nullptr)
712 
713  // Delete the old order from the order book
714  switch (order_ptr->Type)
715  {
716  case OrderType::LIMIT:
717  UpdateLevel(*order_book_ptr, order_book_ptr->DeleteOrder(order_ptr));
718  break;
719  case OrderType::STOP:
721  order_book_ptr->DeleteStopOrder(order_ptr);
722  break;
725  order_book_ptr->DeleteTrailingStopOrder(order_ptr);
726  break;
727  default:
728  assert(false && "Unsupported order type!");
729  break;
730  }
731 
732  // Call the corresponding handler
733  _market_handler.onDeleteOrder(*order_ptr);
734 
735  // Erase the order
736  _orders.erase(order_it);
737 
738  // Replace the order
739  order_ptr->Id = new_id;
740  order_ptr->Price = new_price;
741  order_ptr->Quantity = new_quantity;
742  order_ptr->ExecutedQuantity = 0;
743  order_ptr->LeavesQuantity = new_quantity;
744 
745  // Call the corresponding handler
746  _market_handler.onAddOrder(*order_ptr);
747 
748  // Automatic order matching
749  if (_matching && !recursive)
750  MatchLimit(order_book_ptr, order_ptr);
751 
752  if (order_ptr->LeavesQuantity > 0)
753  {
754  // Insert the order
755  if (!_orders.insert(std::make_pair(order_ptr->Id, order_ptr)).second)
756  {
757  // Call the corresponding handler
758  _market_handler.onDeleteOrder(*order_ptr);
759 
760  // Release the order
761  _order_pool.Release(order_ptr);
762 
764  }
765 
766  // Add the modified order into the order book
767  switch (order_ptr->Type)
768  {
769  case OrderType::LIMIT:
770  UpdateLevel(*order_book_ptr, order_book_ptr->AddOrder(order_ptr));
771  break;
772  case OrderType::STOP:
774  order_book_ptr->AddStopOrder(order_ptr);
775  break;
778  order_book_ptr->AddTrailingStopOrder(order_ptr);
779  break;
780  default:
781  assert(false && "Unsupported order type!");
782  break;
783  }
784  }
785  else
786  {
787  // Call the corresponding handler
788  _market_handler.onDeleteOrder(*order_ptr);
789 
790  // Relase the order
791  _order_pool.Release(order_ptr);
792  }
793 
794  // Automatic order matching
795  if (_matching && !recursive)
796  Match(order_book_ptr);
797 
798  // Reset matching price
799  order_book_ptr->ResetMatchingPrice();
800 
801  return ErrorCode::OK;
802 }
803 
804 ErrorCode MarketManager::ReplaceOrder(uint64_t id, const Order& new_order)
805 {
806  // Delete the previous order by Id
807  ErrorCode result = DeleteOrder(id);
808  if (result != ErrorCode::OK)
809  return result;
810 
811  // Add the new order
812  return AddOrder(new_order);
813 }
814 
816 {
817  return DeleteOrder(id, false);
818 }
819 
820 ErrorCode MarketManager::DeleteOrder(uint64_t id, bool recursive)
821 {
822  // Validate parameters
823  assert((id > 0) && "Order Id must be greater than zero!");
824  if (id == 0)
826 
827  // Get the order to delete
828  auto order_it = _orders.find(id);
829  assert((order_it != _orders.end()) && "Order not found!");
830  if (order_it == _orders.end())
832  OrderNode* order_ptr = (OrderNode*)order_it->second;
833 
834  // Get the valid order book for the order
835  OrderBook* order_book_ptr = (OrderBook*)GetOrderBook(order_ptr->SymbolId);
836  if (order_book_ptr == nullptr)
838 
839  // Delete the order from the order book
840  switch (order_ptr->Type)
841  {
842  case OrderType::LIMIT:
843  UpdateLevel(*order_book_ptr, order_book_ptr->DeleteOrder(order_ptr));
844  break;
845  case OrderType::STOP:
847  order_book_ptr->DeleteStopOrder(order_ptr);
848  break;
851  order_book_ptr->DeleteTrailingStopOrder(order_ptr);
852  break;
853  default:
854  assert(false && "Unsupported order type!");
855  break;
856  }
857 
858  // Call the corresponding handler
859  _market_handler.onDeleteOrder(*order_ptr);
860 
861  // Erase the order
862  _orders.erase(order_it);
863 
864  // Relase the order
865  _order_pool.Release(order_ptr);
866 
867  // Automatic order matching
868  if (_matching && !recursive)
869  Match(order_book_ptr);
870 
871  // Reset matching price
872  order_book_ptr->ResetMatchingPrice();
873 
874  return ErrorCode::OK;
875 }
876 
877 ErrorCode MarketManager::ExecuteOrder(uint64_t id, uint64_t quantity)
878 {
879  // Validate parameters
880  assert((id > 0) && "Order Id must be greater than zero!");
881  if (id == 0)
883  assert((quantity > 0) && "Order quantity must be greater than zero!");
884  if (quantity == 0)
886 
887  // Get the order to execute
888  auto order_it = _orders.find(id);
889  assert((order_it != _orders.end()) && "Order not found!");
890  if (order_it == _orders.end())
892  OrderNode* order_ptr = (OrderNode*)order_it->second;
893 
894  // Get the valid order book for the order
895  OrderBook* order_book_ptr = (OrderBook*)GetOrderBook(order_ptr->SymbolId);
896  if (order_book_ptr == nullptr)
898 
899  // Calculate the minimal possible order quantity to execute
900  quantity = std::min(quantity, order_ptr->LeavesQuantity);
901 
902  // Call the corresponding handler
903  _market_handler.onExecuteOrder(*order_ptr, order_ptr->Price, quantity);
904 
905  // Update the corresponding market price
906  order_book_ptr->UpdateLastPrice(*order_ptr, order_ptr->Price);
907  order_book_ptr->UpdateMatchingPrice(*order_ptr, order_ptr->Price);
908 
909  uint64_t hidden = order_ptr->HiddenQuantity();
910  uint64_t visible = order_ptr->VisibleQuantity();
911 
912  // Increase the order executed quantity
913  order_ptr->ExecutedQuantity += quantity;
914 
915  // Reduce the order leaves quantity
916  order_ptr->LeavesQuantity -= quantity;
917 
918  hidden -= order_ptr->HiddenQuantity();
919  visible -= order_ptr->VisibleQuantity();
920 
921  // Reduce the order in the order book
922  switch (order_ptr->Type)
923  {
924  case OrderType::LIMIT:
925  UpdateLevel(*order_book_ptr, order_book_ptr->ReduceOrder(order_ptr, quantity, hidden, visible));
926  break;
927  case OrderType::STOP:
929  order_book_ptr->ReduceStopOrder(order_ptr, quantity, hidden, visible);
930  break;
933  order_book_ptr->ReduceTrailingStopOrder(order_ptr, quantity, hidden, visible);
934  break;
935  default:
936  assert(false && "Unsupported order type!");
937  break;
938  }
939 
940  // Update the order or delete the empty order
941  if (order_ptr->LeavesQuantity > 0)
942  {
943  // Call the corresponding handler
944  _market_handler.onUpdateOrder(*order_ptr);
945  }
946  else
947  {
948  // Call the corresponding handler
949  _market_handler.onDeleteOrder(*order_ptr);
950 
951  // Erase the order
952  _orders.erase(order_it);
953 
954  // Relase the order
955  _order_pool.Release(order_ptr);
956  }
957 
958  // Automatic order matching
959  if (_matching)
960  Match(order_book_ptr);
961 
962  // Reset matching price
963  order_book_ptr->ResetMatchingPrice();
964 
965  return ErrorCode::OK;
966 }
967 
968 ErrorCode MarketManager::ExecuteOrder(uint64_t id, uint64_t price, uint64_t quantity)
969 {
970  // Validate parameters
971  assert((id > 0) && "Order Id must be greater than zero!");
972  if (id == 0)
974  assert((quantity > 0) && "Order quantity must be greater than zero!");
975  if (quantity == 0)
977 
978  // Get the order to execute
979  auto order_it = _orders.find(id);
980  assert((order_it != _orders.end()) && "Order not found!");
981  if (order_it == _orders.end())
983  OrderNode* order_ptr = (OrderNode*)order_it->second;
984 
985  // Get the valid order book for the order
986  OrderBook* order_book_ptr = (OrderBook*)GetOrderBook(order_ptr->SymbolId);
987  if (order_book_ptr == nullptr)
989 
990  // Calculate the minimal possible order quantity to execute
991  quantity = std::min(quantity, order_ptr->LeavesQuantity);
992 
993  // Call the corresponding handler
994  _market_handler.onExecuteOrder(*order_ptr, price, quantity);
995 
996  // Update the corresponding market price
997  order_book_ptr->UpdateLastPrice(*order_ptr, price);
998  order_book_ptr->UpdateMatchingPrice(*order_ptr, price);
999 
1000  uint64_t hidden = order_ptr->HiddenQuantity();
1001  uint64_t visible = order_ptr->VisibleQuantity();
1002 
1003  // Increase the order executed quantity
1004  order_ptr->ExecutedQuantity += quantity;
1005 
1006  // Reduce the order leaves quantity
1007  order_ptr->LeavesQuantity -= quantity;
1008 
1009  hidden -= order_ptr->HiddenQuantity();
1010  visible -= order_ptr->VisibleQuantity();
1011 
1012  // Reduce the order in the order book
1013  switch (order_ptr->Type)
1014  {
1015  case OrderType::LIMIT:
1016  UpdateLevel(*order_book_ptr, order_book_ptr->ReduceOrder(order_ptr, quantity, hidden, visible));
1017  break;
1018  case OrderType::STOP:
1019  case OrderType::STOP_LIMIT:
1020  order_book_ptr->ReduceStopOrder(order_ptr, quantity, hidden, visible);
1021  break;
1024  order_book_ptr->ReduceTrailingStopOrder(order_ptr, quantity, hidden, visible);
1025  break;
1026  default:
1027  assert(false && "Unsupported order type!");
1028  break;
1029  }
1030 
1031  // Update the order or delete the empty order
1032  if (order_ptr->LeavesQuantity > 0)
1033  {
1034  // Call the corresponding handler
1035  _market_handler.onUpdateOrder(*order_ptr);
1036  }
1037  else
1038  {
1039  // Call the corresponding handler
1040  _market_handler.onDeleteOrder(*order_ptr);
1041 
1042  // Erase the order
1043  _orders.erase(order_it);
1044 
1045  // Relase the order
1046  _order_pool.Release(order_ptr);
1047  }
1048 
1049  // Automatic order matching
1050  if (_matching)
1051  Match(order_book_ptr);
1052 
1053  // Reset matching price
1054  order_book_ptr->ResetMatchingPrice();
1055 
1056  return ErrorCode::OK;
1057 }
1058 
1060 {
1061  for (auto order_book_ptr : _order_books)
1062  if (order_book_ptr != nullptr)
1063  Match(order_book_ptr);
1064 }
1065 
1066 void MarketManager::Match(OrderBook* order_book_ptr)
1067 {
1068  // Matching loop
1069  for (;;)
1070  {
1071  // Check the arbitrage bid/ask prices
1072  while ((order_book_ptr->_best_bid != nullptr) &&
1073  (order_book_ptr->_best_ask != nullptr) &&
1074  (order_book_ptr->_best_bid->Price >= order_book_ptr->_best_ask->Price))
1075  {
1076  // Find the best bid/ask price level
1077  LevelNode* bid_level_ptr = order_book_ptr->_best_bid;
1078  LevelNode* ask_level_ptr = order_book_ptr->_best_ask;
1079 
1080  // Find the first order to execute and the first order to reduce
1081  OrderNode* bid_order_ptr = bid_level_ptr->OrderList.front();
1082  OrderNode* ask_order_ptr = ask_level_ptr->OrderList.front();
1083 
1084  // Execute crossed orders
1085  while ((bid_order_ptr != nullptr) && (ask_order_ptr != nullptr))
1086  {
1087  // Find the next orders pair
1088  OrderNode* next_bid_order_ptr = bid_order_ptr->next;
1089  OrderNode* next_ask_order_ptr = ask_order_ptr->next;
1090 
1091  // Special case for 'All-Or-None' orders
1092  if (bid_order_ptr->IsAON() || ask_order_ptr->IsAON())
1093  {
1094  // Calculate the matching chain
1095  uint64_t chain = CalculateMatchingChain(order_book_ptr, bid_level_ptr, ask_level_ptr);
1096 
1097  // Matching is not avaliable
1098  if (chain == 0)
1099  return;
1100 
1101  // Execute orders in the matching chain
1102  if (bid_order_ptr->IsAON())
1103  {
1104  uint64_t price = bid_order_ptr->Price;
1105  ExecuteMatchingChain(order_book_ptr, bid_level_ptr, price, chain);
1106  ExecuteMatchingChain(order_book_ptr, ask_level_ptr, price, chain);
1107  }
1108  else
1109  {
1110  uint64_t price = ask_order_ptr->Price;
1111  ExecuteMatchingChain(order_book_ptr, ask_level_ptr, price, chain);
1112  ExecuteMatchingChain(order_book_ptr, bid_level_ptr, price, chain);
1113  }
1114 
1115  break;
1116  }
1117 
1118  // Find the best order to execute and the best order to reduce
1119  OrderNode* executing_order_ptr = bid_order_ptr;
1120  OrderNode* reducing_order_ptr = ask_order_ptr;
1121  if (executing_order_ptr->LeavesQuantity > reducing_order_ptr->LeavesQuantity)
1122  std::swap(executing_order_ptr, reducing_order_ptr);
1123 
1124  // Get the execution quantity
1125  uint64_t quantity = executing_order_ptr->LeavesQuantity;
1126 
1127  // Get the execution price
1128  uint64_t price = executing_order_ptr->Price;
1129 
1130  // Call the corresponding handler
1131  _market_handler.onExecuteOrder(*executing_order_ptr, price, quantity);
1132 
1133  // Update the corresponding market price
1134  order_book_ptr->UpdateLastPrice(*executing_order_ptr, price);
1135  order_book_ptr->UpdateMatchingPrice(*executing_order_ptr, price);
1136 
1137  // Increase the order executed quantity
1138  executing_order_ptr->ExecutedQuantity += quantity;
1139 
1140  // Delete the executing order from the order book
1141  DeleteOrder(executing_order_ptr->Id, true);
1142 
1143  // Call the corresponding handler
1144  _market_handler.onExecuteOrder(*reducing_order_ptr, price, quantity);
1145 
1146  // Update the corresponding market price
1147  order_book_ptr->UpdateLastPrice(*reducing_order_ptr, price);
1148  order_book_ptr->UpdateMatchingPrice(*reducing_order_ptr, price);
1149 
1150  // Increase the order executed quantity
1151  reducing_order_ptr->ExecutedQuantity += quantity;
1152 
1153  // Reduce the remaining order in the order book
1154  ReduceOrder(reducing_order_ptr->Id, quantity, true);
1155 
1156  // Move to the next orders pair at the same price level
1157  bid_order_ptr = next_bid_order_ptr;
1158  ask_order_ptr = next_ask_order_ptr;
1159  }
1160 
1161  // Activate stop orders only if the current price level changed
1162  ActivateStopOrders(order_book_ptr, (LevelNode*)order_book_ptr->best_buy_stop(), order_book_ptr->GetMarketPriceAsk());
1163  ActivateStopOrders(order_book_ptr, (LevelNode*)order_book_ptr->best_sell_stop(), order_book_ptr->GetMarketPriceBid());
1164  }
1165 
1166  // Activate stop orders until there is something to activate
1167  if (!ActivateStopOrders(order_book_ptr))
1168  break;
1169  }
1170 }
1171 
1172 void MarketManager::MatchMarket(OrderBook* order_book_ptr, Order* order_ptr)
1173 {
1174  // Calculate acceptable marker order price with optional slippage value
1175  if (order_ptr->IsBuy())
1176  {
1177  // Check if there is nothing to buy
1178  if (order_book_ptr->best_ask() == nullptr)
1179  return;
1180 
1181  order_ptr->Price = order_book_ptr->best_ask()->Price;
1182  if (order_ptr->Price > (std::numeric_limits<uint64_t>::max() - order_ptr->Slippage))
1183  order_ptr->Price = std::numeric_limits<uint64_t>::max();
1184  else
1185  order_ptr->Price += order_ptr->Slippage;
1186  }
1187  else
1188  {
1189  // Check if there is nothing to sell
1190  if (order_book_ptr->best_bid() == nullptr)
1191  return;
1192 
1193  order_ptr->Price = order_book_ptr->best_bid()->Price;
1194  if (order_ptr->Price < (std::numeric_limits<uint64_t>::min() + order_ptr->Slippage))
1195  order_ptr->Price = std::numeric_limits<uint64_t>::min();
1196  else
1197  order_ptr->Price -= order_ptr->Slippage;
1198  }
1199 
1200  // Match the market order
1201  MatchOrder(order_book_ptr, order_ptr);
1202 }
1203 
1204 void MarketManager::MatchLimit(OrderBook* order_book_ptr, Order* order_ptr)
1205 {
1206  // Match the limit order
1207  MatchOrder(order_book_ptr, order_ptr);
1208 }
1209 
1210 void MarketManager::MatchOrder(OrderBook* order_book_ptr, Order* order_ptr)
1211 {
1212  // Start the matching from the top of the book
1213  LevelNode* level_ptr;
1214  while ((level_ptr = order_ptr->IsBuy() ? order_book_ptr->_best_ask : order_book_ptr->_best_bid) != nullptr)
1215  {
1216  // Check the arbitrage bid/ask prices
1217  bool arbitrage = order_ptr->IsBuy() ? (order_ptr->Price >= level_ptr->Price) : (order_ptr->Price <= level_ptr->Price);
1218  if (!arbitrage)
1219  return;
1220 
1221  // Special case for 'Fill-Or-Kill'/'All-Or-None' order
1222  if (order_ptr->IsFOK() || order_ptr->IsAON())
1223  {
1224  // Calculate the matching chain
1225  uint64_t chain = CalculateMatchingChain(order_book_ptr, level_ptr, order_ptr->Price, order_ptr->LeavesQuantity);
1226 
1227  // Matching is not avaliable
1228  if (chain == 0)
1229  return;
1230 
1231  // Execute orders in the matching chain
1232  ExecuteMatchingChain(order_book_ptr, level_ptr, order_ptr->Price, chain);
1233 
1234  // Call the corresponding handler
1235  _market_handler.onExecuteOrder(*order_ptr, order_ptr->Price, order_ptr->LeavesQuantity);
1236 
1237  // Update the corresponding market price
1238  order_book_ptr->UpdateLastPrice(*order_ptr, order_ptr->Price);
1239  order_book_ptr->UpdateMatchingPrice(*order_ptr, order_ptr->Price);
1240 
1241  // Increase the order executed quantity
1242  order_ptr->ExecutedQuantity += order_ptr->LeavesQuantity;
1243 
1244  // Reduce the order leaves quantity
1245  order_ptr->LeavesQuantity = 0;
1246 
1247  return;
1248  }
1249 
1250  // Find the first order to execute
1251  OrderNode* executing_order_ptr = level_ptr->OrderList.front();
1252 
1253  // Execute crossed orders
1254  while (executing_order_ptr != nullptr)
1255  {
1256  // Find the next order to execute
1257  OrderNode* next_executing_order_ptr = executing_order_ptr->next;
1258 
1259  // Get the execution quantity
1260  uint64_t quantity = std::min(executing_order_ptr->LeavesQuantity, order_ptr->LeavesQuantity);
1261 
1262  // Special case for 'All-Or-None' orders
1263  if (executing_order_ptr->IsAON() && (executing_order_ptr->LeavesQuantity > order_ptr->LeavesQuantity))
1264  return;
1265 
1266  // Get the execution price
1267  uint64_t price = executing_order_ptr->Price;
1268 
1269  // Call the corresponding handler
1270  _market_handler.onExecuteOrder(*executing_order_ptr, price, quantity);
1271 
1272  // Update the corresponding market price
1273  order_book_ptr->UpdateLastPrice(*executing_order_ptr, price);
1274  order_book_ptr->UpdateMatchingPrice(*executing_order_ptr, price);
1275 
1276  // Increase the order executed quantity
1277  executing_order_ptr->ExecutedQuantity += quantity;
1278 
1279  // Reduce the executing order in the order book
1280  ReduceOrder(executing_order_ptr->Id, quantity, true);
1281 
1282  // Call the corresponding handler
1283  _market_handler.onExecuteOrder(*order_ptr, price, quantity);
1284 
1285  // Update the corresponding market price
1286  order_book_ptr->UpdateLastPrice(*order_ptr, price);
1287  order_book_ptr->UpdateMatchingPrice(*order_ptr, price);
1288 
1289  // Increase the order executed quantity
1290  order_ptr->ExecutedQuantity += quantity;
1291 
1292  // Reduce the order leaves quantity
1293  order_ptr->LeavesQuantity -= quantity;
1294  if (order_ptr->LeavesQuantity == 0)
1295  return;
1296 
1297  // Move to the next order to execute at the same price level
1298  executing_order_ptr = next_executing_order_ptr;
1299  }
1300  }
1301 }
1302 
1303 bool MarketManager::ActivateStopOrders(OrderBook* order_book_ptr)
1304 {
1305  bool result = false;
1306  bool stop = false;
1307 
1308  while (!stop)
1309  {
1310  stop = true;
1311 
1312  // Try to activate buy stop orders
1313  if (ActivateStopOrders(order_book_ptr, (LevelNode*)order_book_ptr->best_buy_stop(), order_book_ptr->GetMarketPriceAsk()) ||
1314  ActivateStopOrders(order_book_ptr, (LevelNode*)order_book_ptr->best_trailing_buy_stop(), order_book_ptr->GetMarketPriceAsk()))
1315  {
1316  result = true;
1317  stop = false;
1318  }
1319 
1320  // Recalculate trailing buy stop orders
1321  RecalculateTrailingStopPrice(order_book_ptr, order_book_ptr->_best_ask);
1322 
1323  // Try to activate sell stop orders
1324  if (ActivateStopOrders(order_book_ptr, (LevelNode*)order_book_ptr->best_sell_stop(), order_book_ptr->GetMarketPriceBid()) ||
1325  ActivateStopOrders(order_book_ptr, (LevelNode*)order_book_ptr->best_trailing_sell_stop(), order_book_ptr->GetMarketPriceBid()))
1326  {
1327  result = true;
1328  stop = false;
1329  }
1330 
1331  // Recalculate trailing sell stop orders
1332  RecalculateTrailingStopPrice(order_book_ptr, order_book_ptr->_best_bid);
1333  }
1334 
1335  return result;
1336 }
1337 
1338 bool MarketManager::ActivateStopOrders(OrderBook* order_book_ptr, LevelNode* level_ptr, uint64_t stop_price)
1339 {
1340  bool result = false;
1341 
1342  if (level_ptr != nullptr)
1343  {
1344  // Check the arbitrage bid/ask prices
1345  bool arbitrage = level_ptr->IsBid() ? (stop_price <= level_ptr->Price) : (stop_price >= level_ptr->Price);
1346  if (!arbitrage)
1347  return result;
1348 
1349  // Find the stop order to activate
1350  OrderNode* activating_order_ptr = level_ptr->OrderList.front();
1351 
1352  // Activate all stop orders
1353  while (activating_order_ptr != nullptr)
1354  {
1355  // Find the next order to activate
1356  OrderNode* next_activating_order_ptr = activating_order_ptr->next;
1357 
1358  // Activate the stop order
1359  switch (activating_order_ptr->Type)
1360  {
1361  case OrderType::STOP:
1363  result = ActivateStopOrder(order_book_ptr, activating_order_ptr);
1364  break;
1365  case OrderType::STOP_LIMIT:
1367  result = ActivateStopLimitOrder(order_book_ptr, activating_order_ptr);
1368  break;
1369  default:
1370  assert(false && "Unsupported order type!");
1371  break;
1372 
1373  }
1374 
1375  // Move to the next order to activate at the same price level
1376  activating_order_ptr = next_activating_order_ptr;
1377  }
1378  }
1379 
1380  return result;
1381 }
1382 
1383 bool MarketManager::ActivateStopOrder(OrderBook* order_book_ptr, OrderNode* order_ptr)
1384 {
1385  // Delete the stop order from the order book
1386  if (order_ptr->IsTrailingStop() || order_ptr->IsTrailingStopLimit())
1387  order_book_ptr->DeleteTrailingStopOrder(order_ptr);
1388  else
1389  order_book_ptr->DeleteStopOrder(order_ptr);
1390 
1391  // Convert the stop order into the market order
1392  order_ptr->Type = OrderType::MARKET;
1393  order_ptr->Price = 0;
1394  order_ptr->StopPrice = 0;
1395  order_ptr->TimeInForce = order_ptr->IsFOK() ? OrderTimeInForce::FOK : OrderTimeInForce::IOC;
1396 
1397  // Call the corresponding handler
1398  _market_handler.onUpdateOrder(*order_ptr);
1399 
1400  // Match the market order
1401  MatchMarket(order_book_ptr, order_ptr);
1402 
1403  // Call the corresponding handler
1404  _market_handler.onDeleteOrder(*order_ptr);
1405 
1406  // Erase the order
1407  _orders.erase(_orders.find(order_ptr->Id));
1408 
1409  // Relase the order
1410  _order_pool.Release(order_ptr);
1411 
1412  return true;
1413 }
1414 
1415 bool MarketManager::ActivateStopLimitOrder(OrderBook* order_book_ptr, OrderNode* order_ptr)
1416 {
1417  // Delete the stop order from the order book
1418  if (order_ptr->IsTrailingStop() || order_ptr->IsTrailingStopLimit())
1419  order_book_ptr->DeleteTrailingStopOrder(order_ptr);
1420  else
1421  order_book_ptr->DeleteStopOrder(order_ptr);
1422 
1423  // Convert the stop-limit order into the limit order
1424  order_ptr->Type = OrderType::LIMIT;
1425  order_ptr->StopPrice = 0;
1426 
1427  // Call the corresponding handler
1428  _market_handler.onUpdateOrder(*order_ptr);
1429 
1430  // Match the limit order
1431  MatchLimit(order_book_ptr, order_ptr);
1432 
1433  // Add a new limit order or delete remaining part in case of 'Immediate-Or-Cancel'/'Fill-Or-Kill' order
1434  if ((order_ptr->LeavesQuantity > 0) && !order_ptr->IsIOC() && !order_ptr->IsFOK())
1435  {
1436  // Add the new limit order into the order book
1437  UpdateLevel(*order_book_ptr, order_book_ptr->AddOrder(order_ptr));
1438  }
1439  else
1440  {
1441  // Call the corresponding handler
1442  _market_handler.onDeleteOrder(*order_ptr);
1443 
1444  // Erase the order
1445  _orders.erase(_orders.find(order_ptr->Id));
1446 
1447  // Relase the order
1448  _order_pool.Release(order_ptr);
1449  }
1450 
1451  return true;
1452 }
1453 
1454 uint64_t MarketManager::CalculateMatchingChain(OrderBook* order_book_ptr, LevelNode* level_ptr, uint64_t price, uint64_t volume)
1455 {
1456  OrderNode* order_ptr = level_ptr->OrderList.front();
1457  uint64_t available = 0;
1458 
1459  // Travel through price levels
1460  while (level_ptr != nullptr)
1461  {
1462  // Check the arbitrage bid/ask prices
1463  bool arbitrage = level_ptr->IsBid() ? (price <= level_ptr->Price) : (price >= level_ptr->Price);
1464  if (!arbitrage)
1465  return 0;
1466 
1467  // Travel through orders at current price levels
1468  while (order_ptr != nullptr)
1469  {
1470  uint64_t need = volume - available;
1471  uint64_t quantity = order_ptr->IsAON() ? order_ptr->LeavesQuantity : std::min(order_ptr->LeavesQuantity, need);
1472  available += quantity;
1473 
1474  // Matching is possible, return the chain size
1475  if (volume == available)
1476  return available;
1477 
1478  // Matching is not possible
1479  if (volume < available)
1480  return 0;
1481 
1482  // Take the next order
1483  order_ptr = order_ptr->next;
1484  }
1485 
1486  // Switch to the next price level
1487  if (order_ptr == nullptr)
1488  {
1489  level_ptr = order_book_ptr->GetNextLevel(level_ptr);
1490  if (level_ptr != nullptr)
1491  order_ptr = level_ptr->OrderList.front();
1492  }
1493  }
1494 
1495  // Matching is not available
1496  return 0;
1497 }
1498 
1499 uint64_t MarketManager::CalculateMatchingChain(OrderBook* order_book_ptr, LevelNode* bid_level_ptr, LevelNode* ask_level_ptr)
1500 {
1501  LevelNode* longest_level_ptr = bid_level_ptr;
1502  LevelNode* shortest_level_ptr = ask_level_ptr;
1503  OrderNode* longest_order_ptr = bid_level_ptr->OrderList.front();
1504  OrderNode* shortest_order_ptr = ask_level_ptr->OrderList.front();
1505  uint64_t required = longest_order_ptr->LeavesQuantity;
1506  uint64_t available = 0;
1507 
1508  // Find the initial longest order chain
1509  if (longest_order_ptr->IsAON() && shortest_order_ptr->IsAON())
1510  {
1511  // Choose the longest 'All-Or-None' order
1512  if (shortest_order_ptr->LeavesQuantity > longest_order_ptr->LeavesQuantity)
1513  {
1514  required = shortest_order_ptr->LeavesQuantity;
1515  available = 0;
1516  std::swap(longest_level_ptr, shortest_level_ptr);
1517  std::swap(longest_order_ptr, shortest_order_ptr);
1518  }
1519  }
1520  else if (shortest_order_ptr->IsAON())
1521  {
1522  required = shortest_order_ptr->LeavesQuantity;
1523  available = 0;
1524  std::swap(longest_level_ptr, shortest_level_ptr);
1525  std::swap(longest_order_ptr, shortest_order_ptr);
1526  }
1527 
1528  // Travel through price levels
1529  while ((longest_level_ptr != nullptr) && (shortest_level_ptr != nullptr))
1530  {
1531  // Travel through orders at current price levels
1532  while ((longest_order_ptr != nullptr) && (shortest_order_ptr != nullptr))
1533  {
1534  uint64_t need = required - available;
1535  uint64_t quantity = shortest_order_ptr->IsAON() ? shortest_order_ptr->LeavesQuantity : std::min(shortest_order_ptr->LeavesQuantity, need);
1536  available += quantity;
1537 
1538  // Matching is possible, return the chain size
1539  if (required == available)
1540  return required;
1541 
1542  // Swap longest and shortest chains
1543  if (required < available)
1544  {
1545  OrderNode* next = longest_order_ptr->next;
1546  longest_order_ptr = shortest_order_ptr;
1547  shortest_order_ptr = next;
1548  std::swap(required, available);
1549  continue;
1550  }
1551 
1552  // Take the next order
1553  shortest_order_ptr = shortest_order_ptr->next;
1554  }
1555 
1556  // Switch to the next longest price level
1557  if (longest_order_ptr == nullptr)
1558  {
1559  longest_level_ptr = order_book_ptr->GetNextLevel(longest_level_ptr);
1560  if (longest_level_ptr != nullptr)
1561  longest_order_ptr = longest_level_ptr->OrderList.front();
1562  }
1563 
1564  // Switch to the next shortest price level
1565  if (shortest_order_ptr == nullptr)
1566  {
1567  shortest_level_ptr = order_book_ptr->GetNextLevel(shortest_level_ptr);
1568  if (shortest_level_ptr != nullptr)
1569  shortest_order_ptr = shortest_level_ptr->OrderList.front();
1570  }
1571  }
1572 
1573  // Matching is not available
1574  return 0;
1575 }
1576 
1577 void MarketManager::ExecuteMatchingChain(OrderBook* order_book_ptr, LevelNode* level_ptr, uint64_t price, uint64_t volume)
1578 {
1579  // Execute all orders in the matching chain
1580  while ((volume > 0) && (level_ptr != nullptr))
1581  {
1582  // Get the next prive level to execute
1583  LevelNode* next_level_ptr = order_book_ptr->GetNextLevel(level_ptr);
1584 
1585  // Find the first order to execute
1586  OrderNode* executing_order_ptr = level_ptr->OrderList.front();
1587 
1588  // Execute all orders in the current price level
1589  while ((volume > 0) && (executing_order_ptr != nullptr))
1590  {
1591  // Find the next order to execute
1592  OrderNode* next_executing_order_ptr = executing_order_ptr->next;
1593 
1594  uint64_t quantity;
1595 
1596  // Execute order
1597  if (executing_order_ptr->IsAON())
1598  {
1599  // Get the execution quantity
1600  quantity = executing_order_ptr->LeavesQuantity;
1601 
1602  // Call the corresponding handler
1603  _market_handler.onExecuteOrder(*executing_order_ptr, price, quantity);
1604 
1605  // Update the corresponding market price
1606  order_book_ptr->UpdateLastPrice(*executing_order_ptr, price);
1607  order_book_ptr->UpdateMatchingPrice(*executing_order_ptr, price);
1608 
1609  // Increase the order executed quantity
1610  executing_order_ptr->ExecutedQuantity += quantity;
1611 
1612  // Delete the executing order from the order book
1613  DeleteOrder(executing_order_ptr->Id, true);
1614  }
1615  else
1616  {
1617  // Get the execution quantity
1618  quantity = std::min(executing_order_ptr->LeavesQuantity, volume);
1619 
1620  // Call the corresponding handler
1621  _market_handler.onExecuteOrder(*executing_order_ptr, price, quantity);
1622 
1623  // Update the corresponding market price
1624  order_book_ptr->UpdateLastPrice(*executing_order_ptr, price);
1625  order_book_ptr->UpdateMatchingPrice(*executing_order_ptr, price);
1626 
1627  // Increase the order executed quantity
1628  executing_order_ptr->ExecutedQuantity += quantity;
1629 
1630  // Reduce the executing order in the order book
1631  ReduceOrder(executing_order_ptr->Id, quantity, true);
1632  }
1633 
1634  // Reduce the execution chain
1635  volume -= quantity;
1636 
1637  // Move to the next order to execute at the same price level
1638  executing_order_ptr = next_executing_order_ptr;
1639  }
1640 
1641  // Move to the next price level
1642  level_ptr = next_level_ptr;
1643  }
1644 }
1645 
1646 void MarketManager::RecalculateTrailingStopPrice(OrderBook* order_book_ptr, LevelNode* level_ptr)
1647 {
1648  if (level_ptr == nullptr)
1649  return;
1650 
1651  uint64_t new_trailing_price;
1652 
1653  // Check if we should skip the recalculation because of the market price goes to the wrong direction
1654  if (level_ptr->Type == LevelType::ASK)
1655  {
1656  uint64_t old_trailing_price = order_book_ptr->_trailing_ask_price;
1657  new_trailing_price = order_book_ptr->GetMarketTrailingStopPriceAsk();
1658  order_book_ptr->_trailing_ask_price = new_trailing_price;
1659  if (new_trailing_price >= old_trailing_price)
1660  return;
1661  }
1662  if (level_ptr->Type == LevelType::BID)
1663  {
1664  uint64_t old_trailing_price = order_book_ptr->_trailing_bid_price;
1665  new_trailing_price = order_book_ptr->GetMarketTrailingStopPriceBid();
1666  order_book_ptr->_trailing_bid_price = new_trailing_price;
1667  if (new_trailing_price <= old_trailing_price)
1668  return;
1669  }
1670 
1671  // Recalculate trailing stop orders
1672  LevelNode* previous = nullptr;
1673  LevelNode* current = (level_ptr->Type == LevelType::ASK) ? order_book_ptr->_best_trailing_buy_stop : order_book_ptr->_best_trailing_sell_stop;
1674  while (current != nullptr)
1675  {
1676  bool recalculated = false;
1677 
1678  // Find the first order to recalculate
1679  OrderNode* order_ptr = current->OrderList.front();
1680 
1681  while (order_ptr != nullptr)
1682  {
1683  // Find the next order to recalculate
1684  OrderNode* next_order_ptr = order_ptr->next;
1685 
1686  uint64_t old_stop_price = order_ptr->StopPrice;
1687  uint64_t new_stop_price = order_book_ptr->CalculateTrailingStopPrice(*order_ptr);
1688 
1689  // Trailing distance for the order must be changed
1690  if (new_stop_price != old_stop_price)
1691  {
1692  // Delete the order from the order book
1693  order_book_ptr->DeleteTrailingStopOrder(order_ptr);
1694 
1695  // Update the stop order price
1696  switch (order_ptr->Type)
1697  {
1699  order_ptr->StopPrice = new_stop_price;
1700  break;
1702  {
1703  int64_t diff = order_ptr->Price - order_ptr->StopPrice;
1704  order_ptr->StopPrice = new_stop_price;
1705  order_ptr->Price = order_ptr->StopPrice + diff;
1706  break;
1707  }
1708  default:
1709  assert(false && "Unsupported order type!");
1710  break;
1711 
1712  }
1713 
1714  // Call the corresponding handler
1715  _market_handler.onUpdateOrder(*order_ptr);
1716 
1717  // Add the new stop order into the order book
1718  order_book_ptr->AddTrailingStopOrder(order_ptr);
1719 
1720  recalculated = true;
1721  }
1722 
1723  // Move to the next order to recalculate at the same price level
1724  order_ptr = next_order_ptr;
1725  }
1726 
1727  if (recalculated)
1728  {
1729  // Back to the previous stop price level
1730  current = (previous != nullptr) ? previous : ((level_ptr->Type == LevelType::ASK) ? order_book_ptr->_best_trailing_buy_stop : order_book_ptr->_best_trailing_sell_stop);
1731  }
1732  else
1733  {
1734  // Move to the next stop price level
1735  previous = current;
1736  current = order_book_ptr->GetNextTrailingStopLevel(current);
1737  }
1738  }
1739 }
1740 
1741 void MarketManager::UpdateLevel(const OrderBook& order_book, const LevelUpdate& update) const
1742 {
1743  switch (update.Type)
1744  {
1745  case UpdateType::ADD:
1746  _market_handler.onAddLevel(order_book, update.Update, update.Top);
1747  break;
1748  case UpdateType::UPDATE:
1749  _market_handler.onUpdateLevel(order_book, update.Update, update.Top);
1750  break;
1751  case UpdateType::DELETE:
1752  _market_handler.onDeleteLevel(order_book, update.Update, update.Top);
1753  break;
1754  default:
1755  break;
1756  }
1757 
1758  _market_handler.onUpdateOrderBook(order_book, update.Top);
1759 }
1760 
1761 } // namespace Matching
1762 } // namespace CppTrader
virtual void onUpdateOrderBook(const OrderBook &order_book, bool top)
virtual void onAddOrder(const Order &order)
virtual void onDeleteSymbol(const Symbol &symbol)
virtual void onUpdateOrder(const Order &order)
virtual void onUpdateLevel(const OrderBook &order_book, const Level &level, bool top)
virtual void onDeleteLevel(const OrderBook &order_book, const Level &level, bool top)
virtual void onDeleteOrderBook(const OrderBook &order_book)
virtual void onDeleteOrder(const Order &order)
virtual void onAddOrderBook(const OrderBook &order_book)
virtual void onAddSymbol(const Symbol &symbol)
virtual void onAddLevel(const OrderBook &order_book, const Level &level, bool top)
virtual void onExecuteOrder(const Order &order, uint64_t price, uint64_t quantity)
ErrorCode ReduceOrder(uint64_t id, uint64_t quantity)
Reduce the order by the given quantity.
const OrderBook * GetOrderBook(uint32_t id) const noexcept
Get the order book for the given symbol Id.
ErrorCode MitigateOrder(uint64_t id, uint64_t new_price, uint64_t new_quantity)
Mitigate the order.
ErrorCode AddOrderBook(const Symbol &symbol)
Add a new order book.
ErrorCode ExecuteOrder(uint64_t id, uint64_t quantity)
Execute the order.
ErrorCode DeleteOrder(uint64_t id)
Delete the order.
ErrorCode AddSymbol(const Symbol &symbol)
Add a new symbol.
void Match()
Match crossed orders in all order books.
ErrorCode ModifyOrder(uint64_t id, uint64_t new_price, uint64_t new_quantity)
Modify the order.
ErrorCode AddOrder(const Order &order)
Add a new order.
ErrorCode ReplaceOrder(uint64_t id, uint64_t new_id, uint64_t new_price, uint64_t new_quantity)
Replace the order with a similar order but different Id, price and quantity.
ErrorCode DeleteSymbol(uint32_t id)
Delete the symbol.
ErrorCode DeleteOrderBook(uint32_t id)
Delete the order book.
const LevelNode * best_buy_stop() const noexcept
Get the order book best buy stop order price level.
Definition: order_book.h:67
const LevelNode * best_sell_stop() const noexcept
Get the order book best sell stop order price level.
Definition: order_book.h:69
Market manager definition.
ErrorCode
Error code.
Definition: errors.h:21
C++ Trader project definitions.
Definition: errors.h:16
uint64_t Price
Level price.
Definition: level.h:36
Price level node.
Definition: level.h:79
CppCommon::List< OrderNode > OrderList
Price level orders.
Definition: level.h:81
uint64_t VisibleQuantity() const noexcept
Order visible quantity.
Definition: order.h:166
ErrorCode Validate() const noexcept
Validate order parameters.
Definition: order.cpp:14
bool IsAON() const noexcept
Is the 'All-Or-None' order?
Definition: order.h:242
uint64_t Price
Order price.
Definition: order.h:138
uint64_t ExecutedQuantity
Order executed quantity.
Definition: order.h:145
uint64_t LeavesQuantity
Order leaves quantity.
Definition: order.h:147
bool IsLimit() const noexcept
Is the limit order?
Definition: order.h:220
OrderType Type
Order type.
Definition: order.h:134
uint64_t HiddenQuantity() const noexcept
Order hidden quantity.
Definition: order.h:164
uint64_t Id
Order Id.
Definition: order.h:130
uint32_t SymbolId
Symbol Id.
Definition: order.h:132
uint64_t Quantity
Order quantity.
Definition: order.h:143
uint32_t Id
Symbol Id.
Definition: symbol.h:24