|
Leka
A low-latency C++20 price-time-priority limit order book and matching engine
|
Owns resting limit orders and maintains their book indexes. More...
#include <order_book.hpp>
Public Member Functions | |
| OrderBook () | |
| Creates an order book with a small default price range. | |
| OrderBook (Price minPrice, Price tickSize, std::size_t levelCount) | |
| Creates an order book with an explicitly sized price ladder. | |
| OrderBook (const OrderBook &)=delete | |
| OrderBook & | operator= (const OrderBook &)=delete |
| OrderBook (OrderBook &&)=delete | |
| OrderBook & | operator= (OrderBook &&)=delete |
| 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. | |
| 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 | cancelOrder (const OrderId &orderId) |
| Removes a resting order by ID. | |
| bool | reduceOrder (const OrderId &orderId, Quantity newQuantity) |
| Shrinks a resting order in place, preserving its priority. | |
| void | removeOrder (Order *order) |
| Removes a currently resting order from every book structure. | |
| Order * | findOrder (const OrderId &orderId) |
| Finds an order by ID, or returns nullptr when absent. | |
| const Order * | findOrder (const OrderId &orderId) const |
| Finds an order by ID without allowing mutation. | |
| PriceLevel * | getBestBid () |
| Returns the mutable highest-priced bid level. | |
| PriceLevel * | getBestAsk () |
| Returns the mutable lowest-priced ask level. | |
| const PriceLevel * | getBestBid () const |
| Returns the best bid level for read-only inspection. | |
| const PriceLevel * | getBestAsk () const |
| Returns the best ask level for read-only inspection. | |
| std::size_t | getBidLevelCount () const |
| Returns the number of occupied bid price levels. | |
| std::size_t | getAskLevelCount () const |
| Returns the number of occupied ask price levels. | |
| void | reserveOrderCapacity (std::size_t orderCount) |
Pre-allocates order storage and index capacity for up to orderCount live orders. | |
| void | captureSnapshot (BookSnapshot &out, std::size_t depth) const |
Fills out with the top depth levels of each side. | |
Static Public Attributes | |
| static constexpr std::size_t | DefaultLevelCount = 65536 |
| Number of representable price levels used by the default constructor. | |
Owns resting limit orders and maintains their book indexes.
OrderBook owns Order storage through OrderPool. OrderIndex and PriceLevel objects hold non-owning references to those orders. Matching decisions are made by MatchingEngine; this class maintains synchronized book state.
Bid and ask levels are tick-indexed arrays (PriceLadder), not ordered maps: a price is an index, not a search key, so both adding a level and finding the best one are array operations rather than a tree allocation and a tree descent. That requires a bounded, pre-configured price range; see the two-argument constructor.
Definition at line 29 of file order_book.hpp.
| lob::OrderBook::OrderBook | ( | ) |
Creates an order book with a small default price range.
The default range and tick (integer prices 1 through 65536, tick 1) exist for tests and examples that do not care about the ladder's configuration. A real instrument should use the explicit constructor, sized to its actual tick size and trading range, and call it once at startup: the ladder never grows after construction.
See the header for why 65536 levels of tick 1 starting at 1 are adequate defaults for tests and examples only.
Definition at line 8 of file order_book.cpp.
References DefaultLevelCount, and OrderBook().
Referenced by OrderBook().
Creates an order book with an explicitly sized price ladder.
| minPrice | Lowest representable price on either side. |
| tickSize | Price increment between adjacent levels. |
| levelCount | Number of representable price levels. |
| std::invalid_argument | for an invalid or overflowing range. |
Definition at line 10 of file order_book.cpp.
| Order * lob::OrderBook::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.
The book allocates the order, links it into the side's PriceLevel FIFO, and registers it in OrderIndex. If any step fails, all earlier state is rolled back before the pool slot is released.
| std::invalid_argument | if the order is invalid or not a limit. |
| std::logic_error | if the order ID already exists. |
A new order starts with equal original and remaining quantities. The shared insertion helper provides the same transactional guarantees as remainder insertion while keeping the public API concise.
Definition at line 19 of file order_book.cpp.
| Order * lob::OrderBook::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.
This is used when MatchingEngine has executed part of an incoming order. The stored order retains the submitted quantity as originalQuantity and enters the book with only remainingQuantity available.
| originalQuantity | Quantity submitted before any executions. |
| remainingQuantity | Quantity still available to execute. |
| std::invalid_argument | if remainingQuantity is zero, exceeds the original quantity, or the order is otherwise invalid. |
The original quantity is preserved for audit and lifecycle semantics; only the remaining quantity is placed into the level aggregate.
Definition at line 30 of file order_book.cpp.
| bool lob::OrderBook::cancelOrder | ( | const OrderId & | orderId | ) |
Removes a resting order by ID.
Removal is delegated to removeOrder(Order*) so the PriceLevel, OrderIndex, and OrderPool remain synchronized.
Looks up the order, then delegates all structural cleanup to removeOrder().
Definition at line 97 of file order_book.cpp.
References removeOrder().
Shrinks a resting order in place, preserving its priority.
The order keeps its price, its FIFO position, and its sequence number; only its remaining quantity and the level aggregate change. This is the sole modification that does not forfeit time priority, which is why repricing and size increases are expressed as a cancel followed by a new order rather than handled here.
A missing order is reported rather than thrown: a replayed feed may reference an order that was resting before the captured window began.
| std::invalid_argument | if newQuantity is zero or above the order's current remaining quantity. |
The order is resolved once and mutated where it lies. Because the price is unchanged the order cannot move between levels, so no relinking, no level lookup, and no sequence number are involved.
Definition at line 111 of file order_book.cpp.
References lob::Order::getPriceLevel(), lob::Quantity::getQuantity(), lob::Order::getRemainingQuantity(), lob::PriceLevel::reduceTotalQuantity(), and lob::Order::setRemainingQuantity().
| void lob::OrderBook::removeOrder | ( | Order * | order | ) |
Removes a currently resting order from every book structure.
The order is unlinked from its FIFO and its empty PriceLevel is erased before its index entry and pool storage are released. The caller must not use the pointer after this function returns.
This is the single removal path used by cancellation and matching. It removes non-owning references while the Order is alive, then destroys and recycles the object through OrderPool.
Order already carries a direct pointer to its PriceLevel, set when it was inserted, so removal uses that pointer instead of independently re-deriving the level from price through the ladder. PriceLevel::removeOrder still checks that the order actually belongs to the level it names, which is the same identity check a map-based re-lookup would have produced; the ladder-based lookup here would only have been useful for detecting a corrupted Order::priceLevel pointer, at the cost of a lookup on every removal to guard against a case OrderPool's own invariants already rule out.
Definition at line 146 of file order_book.cpp.
References lob::Order::getOrderId(), lob::Order::getPrice(), lob::Order::getPriceLevel(), lob::Order::isBuy(), lob::PriceLevel::isEmpty(), lob::PriceLadder::markEmpty(), and lob::PriceLevel::removeOrder().
Referenced by cancelOrder().
Finds an order by ID, or returns nullptr when absent.
Definition at line 169 of file order_book.cpp.
Finds an order by ID without allowing mutation.
Definition at line 173 of file order_book.cpp.
| PriceLevel * lob::OrderBook::getBestBid | ( | ) |
Returns the mutable highest-priced bid level.
Definition at line 177 of file order_book.cpp.
| PriceLevel * lob::OrderBook::getBestAsk | ( | ) |
Returns the mutable lowest-priced ask level.
Definition at line 181 of file order_book.cpp.
| const PriceLevel * lob::OrderBook::getBestBid | ( | ) | const |
Returns the best bid level for read-only inspection.
Definition at line 185 of file order_book.cpp.
| const PriceLevel * lob::OrderBook::getBestAsk | ( | ) | const |
Returns the best ask level for read-only inspection.
Definition at line 189 of file order_book.cpp.
|
inline |
Returns the number of occupied bid price levels.
Definition at line 147 of file order_book.hpp.
|
inline |
Returns the number of occupied ask price levels.
Definition at line 149 of file order_book.hpp.
| void lob::OrderBook::reserveOrderCapacity | ( | std::size_t | orderCount | ) |
Pre-allocates order storage and index capacity for up to orderCount live orders.
See OrderPool::reserve(), OrderIndex::reserve(), and ARCH_DECISIONS.md ADR-008. Call once, before trading begins.
Definition at line 193 of file order_book.cpp.
| void lob::OrderBook::captureSnapshot | ( | BookSnapshot & | out, |
| std::size_t | depth ) const |
Fills out with the top depth levels of each side.
Read-only, and deliberately not called from anywhere inside the matching path: a caller captures this between events so that nothing a snapshot consumer needs can ever execute inside processEvent(). out is reused rather than returned by value, so a caller snapshotting repeatedly stops allocating once its vectors reach steady-state capacity — the same reasoning as the execution buffer in ADR-005.
Walks each ladder outward from the touch via PriceLadder::forEachOccupied(), which visits levels in price priority without sorting because "best" is the lowest occupied index on both sides. Nothing here mutates book state, and no caller inside the matching path invokes it.
Definition at line 205 of file order_book.cpp.
References lob::BookSnapshot::bestAskRaw, lob::BookSnapshot::bestBidRaw, lob::BookSnapshot::bidLevelCount, lob::BookSnapshot::bids, lob::PriceLevel::getOrderCount(), lob::Price::getPrice(), lob::PriceLevel::getPrice(), lob::Quantity::getQuantity(), and lob::PriceLevel::getTotalQuantity().
|
staticconstexpr |
Number of representable price levels used by the default constructor.
Definition at line 32 of file order_book.hpp.
Referenced by OrderBook().