Leka
A low-latency C++20 price-time-priority limit order book and matching engine
▶ Replay viewer
Loading...
Searching...
No Matches
matching_engine.hpp
1#ifndef MATCHING_ENGINE_HPP
2#define MATCHING_ENGINE_HPP
3
4#include "lob/book/order_book.hpp"
5#include "lob/matching/execution.hpp"
6#include "lob/matching/sequence_number_generator.hpp"
8
9#include <vector>
10
11namespace lob {
12
13/**
14 * @brief Matches incoming orders against resting liquidity in an OrderBook.
15 *
16 * The engine owns matching decisions while OrderBook owns resting order
17 * storage and index consistency. Market orders are processed here rather
18 * than inserted into the resting book.
19 */
21 public:
22 /** Creates an engine that operates on the supplied book. */
23 explicit MatchingEngine(OrderBook& orderBook);
24 MatchingEngine(const MatchingEngine&) = delete;
25 MatchingEngine& operator=(const MatchingEngine&) = delete;
26
27 /**
28 * @brief Processes an incoming order and returns generated executions.
29 *
30 * The engine repeatedly examines the best opposing price level and its
31 * FIFO head. Limit orders cross only at prices permitted by their limit;
32 * market orders cross any available opposing liquidity. Each execution is
33 * priced from the resting order, preserving price-time priority.
34 *
35 * A remaining limit quantity is added to the book with its original
36 * submitted quantity preserved. Fully executed orders and unfilled market
37 * remainders are not stored in the book.
38 *
39 * @param orderId Unique identifier for the incoming order.
40 * @param price Limit price. Ignored for market orders.
41 * @param quantity Original quantity submitted by the caller.
42 * @param timestamp Timestamp assigned to the incoming order.
43 * @param orderSide Whether the order buys or sells.
44 * @param orderType Whether the order is a limit or market order.
45 * @return Executions in the order they occurred.
46 * @throws std::invalid_argument if an input value is invalid.
47 * @throws std::logic_error if the order ID is already present.
48 * @throws std::overflow_error if sequence numbers are exhausted.
49 *
50 * @details This convenience form returns a fresh vector on every call,
51 * so it allocates on the first execution just as returning any
52 * non-empty vector by value would. It exists for tests, tools, and
53 * call sites that do not run repeatedly on a latency-sensitive path.
54 * A caller in that position should use the buffer-taking overload
55 * below instead, reusing one vector across calls.
56 */
57 std::vector<Execution> processOrder(
58 OrderId orderId,
59 Price price,
60 Quantity quantity,
61 Timestamp timestamp,
62 OrderSide orderSide,
63 OrderType orderType);
64
65 /**
66 * @brief Same as above, but appends into a caller-owned buffer.
67 *
68 * @c out is cleared before matching begins, then filled in the order
69 * executions occurred. Its capacity is otherwise left alone: a caller
70 * that reuses the same vector across many calls pays for at most one
71 * allocation, ever, once that vector's capacity has grown to cover
72 * the largest execution burst seen so far. This is the form to use on
73 * a repeatedly-called, latency-sensitive path.
74 *
75 * @return The number of executions appended, equal to @c out.size().
76 */
77 std::size_t processOrder(
78 OrderId orderId,
79 Price price,
80 Quantity quantity,
81 Timestamp timestamp,
82 OrderSide orderSide,
83 OrderType orderType,
84 std::vector<Execution>& out);
85
86 /**
87 * @brief Dispatches an event before interpreting its payload.
88 *
89 * NEW is the only event that can execute, so it is also the only event
90 * that consumes a sequence number. CANCEL and REDUCE return no
91 * executions and cannot cross the book, because neither can move an
92 * order to a price on the opposite side. A reprice is submitted as
93 * CANCEL followed by NEW, which routes it through the matcher and so
94 * cannot leave the book crossed.
95 *
96 * @details See processOrder() above for the same allocation tradeoff:
97 * this by-value form is a convenience wrapper, not the hot-path API.
98 */
99 std::vector<Execution> processEvent(const OrderEvent& event);
100 /** @brief Event-oriented alias for processEvent(). */
101 std::vector<Execution> processOrder(const OrderEvent& event);
102
103 /**
104 * @brief Buffer-taking form of processEvent(); see processOrder() above.
105 * @return The number of executions appended, equal to @c out.size().
106 */
107 std::size_t processEvent(const OrderEvent& event, std::vector<Execution>& out);
108
109 private:
110 OrderBook& orderBook;
111 SequenceNumberGenerator sequenceNumberGenerator;
112
113 /**
114 * @brief The matching loop shared by every entry point above.
115 *
116 * Appends to @c out without clearing it first, so the two public
117 * overloads control clearing and this stays a single source of truth
118 * for the matching algorithm regardless of which entry point is used.
119 */
120 void matchOrder(
121 OrderId orderId,
122 Price price,
123 Quantity quantity,
124 Timestamp timestamp,
125 OrderSide orderSide,
126 OrderType orderType,
127 std::vector<Execution>& out);
128};
129
130} // namespace lob
131
132#endif // MATCHING_ENGINE_HPP
MatchingEngine(OrderBook &orderBook)
Creates an engine that operates on the supplied book.
std::vector< Execution > processOrder(OrderId orderId, Price price, Quantity quantity, Timestamp timestamp, OrderSide orderSide, OrderType orderType)
Processes an incoming order and returns generated executions.
std::vector< Execution > processEvent(const OrderEvent &event)
Dispatches an event before interpreting its payload.
Owns resting limit orders and maintains their book indexes.
Type-safe event-first command for the matching engine.
Type-safe identifier for an order; zero is reserved as invalid.
Definition order_id.hpp:10
Type-safe nonzero price value used for price ordering.
Definition price.hpp:9
Type-safe unsigned order quantity; zero represents a filled state.
Definition quantity.hpp:8
Generates process-wide monotonic sequence numbers.
Nanoseconds since the Unix epoch; zero is reserved as invalid.
Definition timestamp.hpp:10
Defines event-first order command payloads and dispatch types.