CppTrader 1.0.5.0
C++ Trader
Loading...
Searching...
No Matches
market_manager.cpp
Go to the documentation of this file.
1
10
11namespace CppTrader {
12namespace Matching {
13
14MarketHandler 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 {
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
160ErrorCode 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
189ErrorCode 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
242ErrorCode 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
334ErrorCode 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
452ErrorCode MarketManager::ReduceOrder(uint64_t id, uint64_t quantity)
453{
454 return ReduceOrder(id, quantity, false);
455}
456
457ErrorCode 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
557ErrorCode 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
562ErrorCode 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
567ErrorCode 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
680ErrorCode 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
685ErrorCode 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
804ErrorCode 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
820ErrorCode 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
877ErrorCode 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
968ErrorCode 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:
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
1066void 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
1172void 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
1204void MarketManager::MatchLimit(OrderBook* order_book_ptr, Order* order_ptr)
1205{
1206 // Match the limit order
1207 MatchOrder(order_book_ptr, order_ptr);
1208}
1209
1210void 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
1303bool 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
1338bool 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;
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
1383bool 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
1415bool 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
1454uint64_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
1499uint64_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
1577void 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
1646void 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
1741void 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_sell_stop() const noexcept
Get the order book best sell stop order price level.
Definition order_book.h:69
const LevelNode * best_buy_stop() const noexcept
Get the order book best buy stop order price level.
Definition order_book.h:67
Market manager definition.
LevelType
Price level type.
Definition level.h:22
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
OrderType Type
Order type.
Definition order.h:134
uint64_t HiddenQuantity() const noexcept
Order hidden quantity.
Definition order.h:164
uint32_t SymbolId
Symbol Id.
Definition order.h:132
uint32_t Id
Symbol Id.
Definition symbol.h:24