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;
98 LevelNode* 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);
128 LevelUpdate 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)));
157 LevelUpdate OrderBook::ReduceOrder(OrderNode* order_ptr, uint64_t quantity, uint64_t hidden, uint64_t visible)
160 LevelNode* level_ptr = order_ptr->Level;
163 level_ptr->TotalVolume -= quantity;
164 level_ptr->HiddenVolume -= hidden;
165 level_ptr->VisibleVolume -= visible;
168 if (order_ptr->LeavesQuantity == 0)
170 level_ptr->OrderList.pop_current(*order_ptr);
174 Level level(*level_ptr);
178 if (level_ptr->TotalVolume == 0)
181 order_ptr->Level = DeleteLevel(order_ptr);
186 return LevelUpdate(update, level, ((order_ptr->Level ==
nullptr) || (order_ptr->Level == (order_ptr->IsBuy() ? _best_bid : _best_ask))));
189 LevelUpdate OrderBook::DeleteOrder(OrderNode* order_ptr)
192 LevelNode* level_ptr = order_ptr->Level;
195 level_ptr->TotalVolume -= order_ptr->LeavesQuantity;
196 level_ptr->HiddenVolume -= order_ptr->HiddenQuantity();
197 level_ptr->VisibleVolume -= order_ptr->VisibleQuantity();
200 level_ptr->OrderList.pop_current(*order_ptr);
203 Level level(*level_ptr);
207 if (level_ptr->TotalVolume == 0)
210 order_ptr->Level = DeleteLevel(order_ptr);
215 return LevelUpdate(update, level, ((order_ptr->Level ==
nullptr) || (order_ptr->Level == (order_ptr->IsBuy() ? _best_bid : _best_ask))));
218 LevelNode* OrderBook::AddStopLevel(OrderNode* order_ptr)
220 LevelNode* level_ptr =
nullptr;
222 if (order_ptr->IsBuy())
225 level_ptr = _manager._level_pool.Create(
LevelType::ASK, order_ptr->StopPrice);
228 _buy_stop.insert(*level_ptr);
231 if ((_best_buy_stop ==
nullptr) || (level_ptr->Price < _best_buy_stop->
Price))
232 _best_buy_stop = level_ptr;
237 level_ptr = _manager._level_pool.Create(
LevelType::BID, order_ptr->StopPrice);
240 _sell_stop.insert(*level_ptr);
243 if ((_best_sell_stop ==
nullptr) || (level_ptr->Price > _best_sell_stop->
Price))
244 _best_sell_stop = level_ptr;
250 LevelNode* OrderBook::DeleteStopLevel(OrderNode* order_ptr)
253 LevelNode* level_ptr = order_ptr->
Level;
255 if (order_ptr->IsBuy())
258 if (level_ptr == _best_buy_stop)
259 _best_buy_stop = (_best_buy_stop->right !=
nullptr) ? _best_buy_stop->right : _best_buy_stop->parent;
262 _buy_stop.erase(Levels::iterator(&_buy_stop, level_ptr));
267 if (level_ptr == _best_sell_stop)
268 _best_sell_stop = (_best_sell_stop->left !=
nullptr) ? _best_sell_stop->left : _best_sell_stop->parent;
271 _sell_stop.erase(Levels::iterator(&_sell_stop, level_ptr));
275 _manager._level_pool.Release(level_ptr);
280 void OrderBook::AddStopOrder(OrderNode* order_ptr)
286 if (level_ptr ==
nullptr)
287 level_ptr = AddStopLevel(order_ptr);
290 level_ptr->TotalVolume += order_ptr->LeavesQuantity;
291 level_ptr->HiddenVolume += order_ptr->HiddenQuantity();
292 level_ptr->VisibleVolume += order_ptr->VisibleQuantity();
295 level_ptr->OrderList.push_back(*order_ptr);
299 order_ptr->Level = level_ptr;
302 void OrderBook::ReduceStopOrder(OrderNode* order_ptr, uint64_t quantity, uint64_t hidden, uint64_t visible)
305 LevelNode* level_ptr = order_ptr->Level;
308 level_ptr->TotalVolume -= quantity;
309 level_ptr->HiddenVolume -= hidden;
310 level_ptr->VisibleVolume -= visible;
313 if (order_ptr->LeavesQuantity == 0)
315 level_ptr->OrderList.pop_current(*order_ptr);
320 if (level_ptr->TotalVolume == 0)
323 order_ptr->Level = DeleteStopLevel(order_ptr);
327 void OrderBook::DeleteStopOrder(OrderNode* order_ptr)
330 LevelNode* level_ptr = order_ptr->Level;
333 level_ptr->TotalVolume -= order_ptr->LeavesQuantity;
334 level_ptr->HiddenVolume -= order_ptr->HiddenQuantity();
335 level_ptr->VisibleVolume -= order_ptr->VisibleQuantity();
338 level_ptr->OrderList.pop_current(*order_ptr);
342 if (level_ptr->TotalVolume == 0)
345 order_ptr->Level = DeleteStopLevel(order_ptr);
349 LevelNode* OrderBook::AddTrailingStopLevel(OrderNode* order_ptr)
351 LevelNode* level_ptr =
nullptr;
353 if (order_ptr->IsBuy())
356 level_ptr = _manager._level_pool.Create(
LevelType::ASK, order_ptr->StopPrice);
359 _trailing_buy_stop.insert(*level_ptr);
362 if ((_best_trailing_buy_stop ==
nullptr) || (level_ptr->Price < _best_trailing_buy_stop->
Price))
363 _best_trailing_buy_stop = level_ptr;
368 level_ptr = _manager._level_pool.Create(
LevelType::BID, order_ptr->StopPrice);
371 _trailing_sell_stop.insert(*level_ptr);
374 if ((_best_trailing_sell_stop ==
nullptr) || (level_ptr->Price > _best_trailing_sell_stop->
Price))
375 _best_trailing_sell_stop = level_ptr;
381 LevelNode* OrderBook::DeleteTrailingStopLevel(OrderNode* order_ptr)
384 LevelNode* level_ptr = order_ptr->
Level;
386 if (order_ptr->IsBuy())
389 if (level_ptr == _best_trailing_buy_stop)
390 _best_trailing_buy_stop = (_best_trailing_buy_stop->right !=
nullptr) ? _best_trailing_buy_stop->right : _best_trailing_buy_stop->parent;
393 _trailing_buy_stop.erase(Levels::iterator(&_trailing_buy_stop, level_ptr));
398 if (level_ptr == _best_trailing_sell_stop)
399 _best_trailing_sell_stop = (_best_trailing_sell_stop->left !=
nullptr) ? _best_trailing_sell_stop->left : _best_trailing_sell_stop->parent;
402 _trailing_sell_stop.erase(Levels::iterator(&_trailing_sell_stop, level_ptr));
406 _manager._level_pool.Release(level_ptr);
411 void OrderBook::AddTrailingStopOrder(OrderNode* order_ptr)
417 if (level_ptr ==
nullptr)
418 level_ptr = AddTrailingStopLevel(order_ptr);
421 level_ptr->TotalVolume += order_ptr->LeavesQuantity;
422 level_ptr->HiddenVolume += order_ptr->HiddenQuantity();
423 level_ptr->VisibleVolume += order_ptr->VisibleQuantity();
426 level_ptr->OrderList.push_back(*order_ptr);
430 order_ptr->Level = level_ptr;
433 void OrderBook::ReduceTrailingStopOrder(OrderNode* order_ptr, uint64_t quantity, uint64_t hidden, uint64_t visible)
436 LevelNode* level_ptr = order_ptr->Level;
439 level_ptr->TotalVolume -= quantity;
440 level_ptr->HiddenVolume -= hidden;
441 level_ptr->VisibleVolume -= visible;
444 if (order_ptr->LeavesQuantity == 0)
446 level_ptr->OrderList.pop_current(*order_ptr);
451 if (level_ptr->TotalVolume == 0)
454 order_ptr->Level = DeleteTrailingStopLevel(order_ptr);
458 void OrderBook::DeleteTrailingStopOrder(OrderNode* order_ptr)
461 LevelNode* level_ptr = order_ptr->Level;
464 level_ptr->TotalVolume -= order_ptr->LeavesQuantity;
465 level_ptr->HiddenVolume -= order_ptr->HiddenQuantity();
466 level_ptr->VisibleVolume -= order_ptr->VisibleQuantity();
469 level_ptr->OrderList.pop_current(*order_ptr);
473 if (level_ptr->TotalVolume == 0)
476 order_ptr->Level = DeleteTrailingStopLevel(order_ptr);
480 uint64_t OrderBook::CalculateTrailingStopPrice(
const Order& order)
const noexcept
483 uint64_t market_price = order.IsBuy() ? GetMarketTrailingStopPriceAsk() : GetMarketTrailingStopPriceBid();
484 int64_t trailing_distance = order.TrailingDistance;
485 int64_t trailing_step = order.TrailingStep;
488 if (trailing_distance < 0)
490 trailing_distance = (int64_t)((-trailing_distance * market_price) / 10000);
491 trailing_step = (int64_t)((-trailing_step * market_price) / 10000);
494 uint64_t old_price = order.StopPrice;
499 uint64_t new_price = (market_price < (std::numeric_limits<uint64_t>::max() - trailing_distance)) ? (market_price + trailing_distance) : std::numeric_limits<uint64_t>::max();
502 if (new_price < old_price)
503 if ((old_price - new_price) >= (uint64_t)trailing_step)
509 uint64_t new_price = (market_price > (uint64_t)trailing_distance) ? (market_price - trailing_distance) : 0;
512 if (new_price > old_price)
513 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_buy_stop() const noexcept
Get the order book trailing buy stop orders container.
const LevelNode * GetTrailingBuyStopLevel(uint64_t price) const noexcept
Get the order book trailing buy stop level with the given price.
const Levels & buy_stop() const noexcept
Get the order book buy stop orders container.
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_sell_stop() const noexcept
Get the order book trailing sell 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.
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?