1#include "lob/book/order_book.hpp"
11 : bids(minPrice, tickSize, levelCount, true),
12 asks(minPrice, tickSize, levelCount, false) {}
22 return addOrderWithQuantities(orderId, price, quantity, quantity, timestamp,
23 orderSide, orderType, sequenceNumber);
34 return addOrderWithQuantities(orderId, price, originalQuantity,
35 remainingQuantity, timestamp, orderSide,
36 orderType, sequenceNumber);
44Order* OrderBook::addOrderWithQuantities(
48 if (orderType != OrderType::LIMIT) {
49 throw std::invalid_argument(
"OrderBook accepts resting limit orders only");
52 remainingQuantity > originalQuantity) {
53 throw std::invalid_argument(
"Invalid original or remaining quantity");
58 Order* order = orderPool.allocate(orderId, price, originalQuantity,
59 remainingQuantity, timestamp, orderSide,
60 orderType, sequenceNumber);
61 bool addedToLevel =
false;
62 PriceLadder* ladder =
nullptr;
63 PriceLevel* level =
nullptr;
66 if (!order->isValid()) {
67 throw std::invalid_argument(
"Cannot add an invalid order");
72 ladder = order->isBuy() ? &bids : &asks;
73 level = &ladder->levelAt(order->getPrice());
74 const bool wasEmpty = level->isEmpty();
75 level->addOrder(order);
78 ladder->markOccupied(order->getPrice());
81 orderIndex.addOrder(order);
84 level->removeOrder(order);
85 if (level->isEmpty()) {
86 ladder->markEmpty(order->getPrice());
89 orderPool.release(order);
98 Order* order = orderIndex.findOrder(orderId);
99 if (order ==
nullptr) {
112 Order* order = orderIndex.findOrder(orderId);
113 if (order ==
nullptr) {
118 const std::uint64_t target = newQuantity.
getQuantity();
119 if (target == 0 || target > remaining) {
120 throw std::invalid_argument(
121 "Reduction requires a nonzero quantity no greater than the remaining quantity");
123 if (target == remaining) {
147 if (order ==
nullptr) {
148 throw std::invalid_argument(
"Cannot remove a null order");
150 if (orderIndex.findOrder(order->
getOrderId()) != order) {
151 throw std::logic_error(
"Order is not indexed in this book");
155 if (level ==
nullptr) {
156 throw std::logic_error(
"Order is not linked to a price level");
165 orderIndex.removeOrder(order);
166 orderPool.release(order);
170 return orderIndex.findOrder(orderId);
174 return orderIndex.findOrder(orderId);
194 orderPool.reserve(orderCount);
195 orderIndex.reserve(orderCount);
209 bids.forEachOccupied(depth, [&out](
const PriceLevel& level) {
215 asks.forEachOccupied(depth, [&out](
const PriceLevel& level) {
223 out.
bestAskRaw = out.asks.empty() ? 0 : out.asks.front().priceRaw;
225 out.askLevelCount = asks.occupiedCount();
static constexpr std::size_t DefaultLevelCount
Number of representable price levels used by the default constructor.
void reserveOrderCapacity(std::size_t orderCount)
Pre-allocates order storage and index capacity for up to orderCount live orders.
PriceLevel * getBestBid()
Returns the mutable highest-priced bid level.
Order * addRestingRemainder(OrderId orderId, Price price, Quantity originalQuantity, Quantity remainingQuantity, Timestamp timestamp, OrderSide orderSide, OrderType orderType, SequenceNumber sequenceNumber)
Adds a partially filled limit order while preserving its history.
bool reduceOrder(const OrderId &orderId, Quantity newQuantity)
Shrinks a resting order in place, preserving its priority.
Order * addOrder(OrderId orderId, Price price, Quantity quantity, Timestamp timestamp, OrderSide orderSide, OrderType orderType, SequenceNumber sequenceNumber)
Adds a valid resting limit order to the appropriate side.
void captureSnapshot(BookSnapshot &out, std::size_t depth) const
Fills out with the top depth levels of each side.
OrderBook()
Creates an order book with a small default price range.
bool cancelOrder(const OrderId &orderId)
Removes a resting order by ID.
Order * findOrder(const OrderId &orderId)
Finds an order by ID, or returns nullptr when absent.
void removeOrder(Order *order)
Removes a currently resting order from every book structure.
PriceLevel * getBestAsk()
Returns the mutable lowest-priced ask level.
Type-safe identifier for an order; zero is reserved as invalid.
Represents a resting or incoming order and its lifecycle state.
OrderId getOrderId() const
Returns the unique order identifier.
Price getPrice() const
Returns the limit or reference price.
PriceLevel * getPriceLevel() const
Returns the price level this order rests on, or nullptr when unlinked.
Quantity getRemainingQuantity() const
Returns the quantity that has not yet executed.
void setRemainingQuantity(Quantity quantity)
Updates quantity while the order remains at its current price level.
bool isBuy() const
Returns true for a buy order.
Fixed-range, tick-indexed array of PriceLevel slots for one side of a book.
void markEmpty(Price price)
Marks a level empty; call exactly once when its order count transitions from nonzero to zero.
Maintains FIFO resting orders at one price.
void reduceTotalQuantity(Quantity quantity)
Decreases aggregate quantity after a partial execution.
Price getPrice() const
Returns the level price.
std::size_t getOrderCount() const
Returns the number of resting orders.
void removeOrder(Order *order)
Unlinks an order and updates aggregate state.
bool isEmpty() const
Returns true when no orders are resting at this price.
Quantity getTotalQuantity() const
Returns the aggregate remaining quantity.
Type-safe nonzero price value used for price ordering.
std::uint64_t getPrice() const
Returns the underlying numeric price.
Type-safe unsigned order quantity; zero represents a filled state.
bool isValid() const
Returns whether the quantity is valid for a submitted order.
std::uint64_t getQuantity() const
Returns the underlying numeric quantity.
Monotonic engine sequence used for deterministic processing order.
Nanoseconds since the Unix epoch; zero is reserved as invalid.
One aggregated price level as seen from outside the engine.
Top-of-book depth plus the counters a viewer needs for context.
std::uint64_t bestBidRaw
Best bid price in raw units, or 0 when no bids rest.
std::size_t bidLevelCount
Occupied level count per side, which may exceed the captured depth.
std::uint64_t bestAskRaw
Best ask price in raw units, or 0 when no asks rest.
std::vector< BookSnapshotLevel > bids
Top levels, best first.