20 _best_buy_stop(nullptr),
21 _best_sell_stop(nullptr),
22 _best_trailing_buy_stop(nullptr),
23 _best_trailing_sell_stop(nullptr),
25 _last_ask_price(std::numeric_limits<uint64_t>::max()),
26 _matching_bid_price(0),
27 _matching_ask_price(std::numeric_limits<uint64_t>::max()),
28 _trailing_bid_price(0),
29 _trailing_ask_price(std::numeric_limits<uint64_t>::max())
36 for (
auto& bid : _bids)
37 _manager._level_pool.Release(&bid);
41 for (
auto& ask : _asks)
42 _manager._level_pool.Release(&ask);
47 _manager._level_pool.Release(&
buy_stop);
58 _trailing_buy_stop.clear();
63 _trailing_sell_stop.clear();
70 if (order_ptr->
IsBuy())
76 _bids.insert(*level_ptr);
79 if ((_best_bid ==
nullptr) || (level_ptr->
Price > _best_bid->
Price))
80 _best_bid = level_ptr;
88 _asks.insert(*level_ptr);
91 if ((_best_ask ==
nullptr) || (level_ptr->
Price < _best_ask->
Price))
92 _best_ask = level_ptr;
98LevelNode* OrderBook::DeleteLevel(OrderNode* order_ptr)
101 LevelNode* level_ptr = order_ptr->
Level;
103 if (order_ptr->IsBuy())
106 if (level_ptr == _best_bid)
107 _best_bid = (_best_bid->left !=
nullptr) ? _best_bid->left : ((_best_bid->parent != nullptr) ? _best_bid->parent : _best_bid->right);
110 _bids.erase(Levels::iterator(&_bids, level_ptr));
115 if (level_ptr == _best_ask)
116 _best_ask = (_best_ask->right !=
nullptr) ? _best_ask->right : ((_best_ask->parent != nullptr) ? _best_ask->parent : _best_ask->left);
119 _asks.erase(Levels::iterator(&_asks, level_ptr));
123 _manager._level_pool.Release(level_ptr);
128LevelUpdate OrderBook::AddOrder(OrderNode* order_ptr)
131 LevelNode* level_ptr = order_ptr->IsBuy() ? (LevelNode*)
GetBid(order_ptr->Price) : (LevelNode*)
GetAsk(order_ptr->Price);
135 if (level_ptr ==
nullptr)
137 level_ptr = AddLevel(order_ptr);
142 level_ptr->TotalVolume += order_ptr->LeavesQuantity;
143 level_ptr->HiddenVolume += order_ptr->HiddenQuantity();
144 level_ptr->VisibleVolume += order_ptr->VisibleQuantity();
147 level_ptr->OrderList.push_back(*order_ptr);
151 order_ptr->Level = level_ptr;
154 return LevelUpdate(update, *order_ptr->Level, (order_ptr->Level == (order_ptr->IsBuy() ? _best_bid : _best_ask)));
157LevelUpdate OrderBook::ReduceOrder(OrderNode* order_ptr, uint64_t quantity, uint64_t hidden, uint64_t visible)
159 bool top = (order_ptr->Level == (order_ptr->IsBuy() ? _best_bid : _best_ask));
162 LevelNode* level_ptr = order_ptr->Level;
165 level_ptr->TotalVolume -= quantity;
166 level_ptr->HiddenVolume -= hidden;
167 level_ptr->VisibleVolume -= visible;
170 if (order_ptr->LeavesQuantity == 0)
172 level_ptr->OrderList.pop_current(*order_ptr);
176 Level level(*level_ptr);
180 if (level_ptr->TotalVolume == 0)
183 order_ptr->Level = DeleteLevel(order_ptr);
188 return LevelUpdate(update, level, top);
191LevelUpdate OrderBook::DeleteOrder(OrderNode* order_ptr)
193 bool top = (order_ptr->Level == (order_ptr->IsBuy() ? _best_bid : _best_ask));
196 LevelNode* level_ptr = order_ptr->Level;
199 level_ptr->TotalVolume -= order_ptr->LeavesQuantity;
200 level_ptr->HiddenVolume -= order_ptr->HiddenQuantity();
201 level_ptr->VisibleVolume -= order_ptr->VisibleQuantity();
204 level_ptr->OrderList.pop_current(*order_ptr);
207 Level level(*level_ptr);
211 if (level_ptr->TotalVolume == 0)
214 order_ptr->Level = DeleteLevel(order_ptr);
219 return LevelUpdate(update, level, top);
222LevelNode* OrderBook::AddStopLevel(OrderNode* order_ptr)
224 LevelNode* level_ptr =
nullptr;
226 if (order_ptr->IsBuy())
229 level_ptr = _manager._level_pool.Create(
LevelType::ASK, order_ptr->StopPrice);
232 _buy_stop.insert(*level_ptr);
235 if ((_best_buy_stop ==
nullptr) || (level_ptr->Price < _best_buy_stop->
Price))
236 _best_buy_stop = level_ptr;
241 level_ptr = _manager._level_pool.Create(
LevelType::BID, order_ptr->StopPrice);
244 _sell_stop.insert(*level_ptr);
247 if ((_best_sell_stop ==
nullptr) || (level_ptr->Price > _best_sell_stop->
Price))
248 _best_sell_stop = level_ptr;
254LevelNode* OrderBook::DeleteStopLevel(OrderNode* order_ptr)
257 LevelNode* level_ptr = order_ptr->
Level;
259 if (order_ptr->IsBuy())
262 if (level_ptr == _best_buy_stop)
263 _best_buy_stop = (_best_buy_stop->right !=
nullptr) ? _best_buy_stop->right : _best_buy_stop->parent;
266 _buy_stop.erase(Levels::iterator(&_buy_stop, level_ptr));
271 if (level_ptr == _best_sell_stop)
272 _best_sell_stop = (_best_sell_stop->left !=
nullptr) ? _best_sell_stop->left : _best_sell_stop->parent;
275 _sell_stop.erase(Levels::iterator(&_sell_stop, level_ptr));
279 _manager._level_pool.Release(level_ptr);
284void OrderBook::AddStopOrder(OrderNode* order_ptr)
290 if (level_ptr ==
nullptr)
291 level_ptr = AddStopLevel(order_ptr);
294 level_ptr->TotalVolume += order_ptr->LeavesQuantity;
295 level_ptr->HiddenVolume += order_ptr->HiddenQuantity();
296 level_ptr->VisibleVolume += order_ptr->VisibleQuantity();
299 level_ptr->OrderList.push_back(*order_ptr);
303 order_ptr->Level = level_ptr;
306void OrderBook::ReduceStopOrder(OrderNode* order_ptr, uint64_t quantity, uint64_t hidden, uint64_t visible)
309 LevelNode* level_ptr = order_ptr->Level;
312 level_ptr->TotalVolume -= quantity;
313 level_ptr->HiddenVolume -= hidden;
314 level_ptr->VisibleVolume -= visible;
317 if (order_ptr->LeavesQuantity == 0)
319 level_ptr->OrderList.pop_current(*order_ptr);
324 if (level_ptr->TotalVolume == 0)
327 order_ptr->Level = DeleteStopLevel(order_ptr);
331void OrderBook::DeleteStopOrder(OrderNode* order_ptr)
334 LevelNode* level_ptr = order_ptr->Level;
337 level_ptr->TotalVolume -= order_ptr->LeavesQuantity;
338 level_ptr->HiddenVolume -= order_ptr->HiddenQuantity();
339 level_ptr->VisibleVolume -= order_ptr->VisibleQuantity();
342 level_ptr->OrderList.pop_current(*order_ptr);
346 if (level_ptr->TotalVolume == 0)
349 order_ptr->Level = DeleteStopLevel(order_ptr);
353LevelNode* OrderBook::AddTrailingStopLevel(OrderNode* order_ptr)
355 LevelNode* level_ptr =
nullptr;
357 if (order_ptr->IsBuy())
360 level_ptr = _manager._level_pool.Create(
LevelType::ASK, order_ptr->StopPrice);
363 _trailing_buy_stop.insert(*level_ptr);
366 if ((_best_trailing_buy_stop ==
nullptr) || (level_ptr->Price < _best_trailing_buy_stop->
Price))
367 _best_trailing_buy_stop = level_ptr;
372 level_ptr = _manager._level_pool.Create(
LevelType::BID, order_ptr->StopPrice);
375 _trailing_sell_stop.insert(*level_ptr);
378 if ((_best_trailing_sell_stop ==
nullptr) || (level_ptr->Price > _best_trailing_sell_stop->
Price))
379 _best_trailing_sell_stop = level_ptr;
385LevelNode* OrderBook::DeleteTrailingStopLevel(OrderNode* order_ptr)
388 LevelNode* level_ptr = order_ptr->
Level;
390 if (order_ptr->IsBuy())
393 if (level_ptr == _best_trailing_buy_stop)
394 _best_trailing_buy_stop = (_best_trailing_buy_stop->right !=
nullptr) ? _best_trailing_buy_stop->right : _best_trailing_buy_stop->parent;
397 _trailing_buy_stop.erase(Levels::iterator(&_trailing_buy_stop, level_ptr));
402 if (level_ptr == _best_trailing_sell_stop)
403 _best_trailing_sell_stop = (_best_trailing_sell_stop->left !=
nullptr) ? _best_trailing_sell_stop->left : _best_trailing_sell_stop->parent;
406 _trailing_sell_stop.erase(Levels::iterator(&_trailing_sell_stop, level_ptr));
410 _manager._level_pool.Release(level_ptr);
415void OrderBook::AddTrailingStopOrder(OrderNode* order_ptr)
421 if (level_ptr ==
nullptr)
422 level_ptr = AddTrailingStopLevel(order_ptr);
425 level_ptr->TotalVolume += order_ptr->LeavesQuantity;
426 level_ptr->HiddenVolume += order_ptr->HiddenQuantity();
427 level_ptr->VisibleVolume += order_ptr->VisibleQuantity();
430 level_ptr->OrderList.push_back(*order_ptr);
434 order_ptr->Level = level_ptr;
437void OrderBook::ReduceTrailingStopOrder(OrderNode* order_ptr, uint64_t quantity, uint64_t hidden, uint64_t visible)
440 LevelNode* level_ptr = order_ptr->Level;
443 level_ptr->TotalVolume -= quantity;
444 level_ptr->HiddenVolume -= hidden;
445 level_ptr->VisibleVolume -= visible;
448 if (order_ptr->LeavesQuantity == 0)
450 level_ptr->OrderList.pop_current(*order_ptr);
455 if (level_ptr->TotalVolume == 0)
458 order_ptr->Level = DeleteTrailingStopLevel(order_ptr);
462void OrderBook::DeleteTrailingStopOrder(OrderNode* order_ptr)
465 LevelNode* level_ptr = order_ptr->Level;
468 level_ptr->TotalVolume -= order_ptr->LeavesQuantity;
469 level_ptr->HiddenVolume -= order_ptr->HiddenQuantity();
470 level_ptr->VisibleVolume -= order_ptr->VisibleQuantity();
473 level_ptr->OrderList.pop_current(*order_ptr);
477 if (level_ptr->TotalVolume == 0)
480 order_ptr->Level = DeleteTrailingStopLevel(order_ptr);
484uint64_t OrderBook::CalculateTrailingStopPrice(
const Order& order)
const noexcept
487 uint64_t market_price = order.IsBuy() ? GetMarketTrailingStopPriceAsk() : GetMarketTrailingStopPriceBid();
488 int64_t trailing_distance = order.TrailingDistance;
489 int64_t trailing_step = order.TrailingStep;
492 if (trailing_distance < 0)
494 trailing_distance = (int64_t)((-trailing_distance * market_price) / 10000);
495 trailing_step = (int64_t)((-trailing_step * market_price) / 10000);
498 uint64_t old_price = order.StopPrice;
503 uint64_t new_price = (market_price < (std::numeric_limits<uint64_t>::max() - trailing_distance)) ? (market_price + trailing_distance) : std::numeric_limits<uint64_t>::max();
506 if (new_price < old_price)
507 if ((old_price - new_price) >= (uint64_t)trailing_step)
513 uint64_t new_price = (market_price > (uint64_t)trailing_distance) ? (market_price - trailing_distance) : 0;
516 if (new_price > old_price)
517 if ((new_price - old_price) >= (uint64_t)trailing_step)
const LevelNode * GetAsk(uint64_t price) const noexcept
Get the order book ask price level with the given price.
OrderBook(MarketManager &manager, const Symbol &symbol)
const Levels & trailing_sell_stop() const noexcept
Get the order book trailing sell stop orders container.
const LevelNode * GetTrailingBuyStopLevel(uint64_t price) const noexcept
Get the order book trailing buy stop level with the given price.
const LevelNode * GetBid(uint64_t price) const noexcept
Get the order book bid price level with the given price.
const LevelNode * GetSellStopLevel(uint64_t price) const noexcept
Get the order book sell stop level with the given price.
const Levels & trailing_buy_stop() const noexcept
Get the order book trailing buy stop orders container.
const LevelNode * GetTrailingSellStopLevel(uint64_t price) const noexcept
Get the order book trailing sell stop level with the given price.
const Levels & sell_stop() const noexcept
Get the order book sell stop orders container.
const LevelNode * GetBuyStopLevel(uint64_t price) const noexcept
Get the order book buy stop level with the given price.
const Levels & buy_stop() const noexcept
Get the order book buy stop orders container.
Market manager definition.
C++ Trader project definitions.
Level(LevelType type, uint64_t price) noexcept
uint64_t Price
Level price.
uint64_t Price
Order price.
bool IsBuy() const noexcept
Is the order with buy side?