Leka
A low-latency C++20 price-time-priority limit order book and matching engine
▶ Replay viewer
Toggle main menu visibility
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"
7
#include "
lob/order/order_event.hpp
"
8
9
#include <vector>
10
11
namespace
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
*/
20
class
MatchingEngine
{
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
lob::MatchingEngine::MatchingEngine
MatchingEngine(OrderBook &orderBook)
Creates an engine that operates on the supplied book.
Definition
matching_engine.cpp:14
lob::MatchingEngine::processOrder
std::vector< Execution > processOrder(OrderId orderId, Price price, Quantity quantity, Timestamp timestamp, OrderSide orderSide, OrderType orderType)
Processes an incoming order and returns generated executions.
Definition
matching_engine.cpp:61
lob::MatchingEngine::processEvent
std::vector< Execution > processEvent(const OrderEvent &event)
Dispatches an event before interpreting its payload.
Definition
matching_engine.cpp:18
lob::OrderBook
Owns resting limit orders and maintains their book indexes.
Definition
order_book.hpp:29
lob::OrderEvent
Type-safe event-first command for the matching engine.
Definition
order_event.hpp:77
lob::OrderId
Type-safe identifier for an order; zero is reserved as invalid.
Definition
order_id.hpp:10
lob::Price
Type-safe nonzero price value used for price ordering.
Definition
price.hpp:9
lob::Quantity
Type-safe unsigned order quantity; zero represents a filled state.
Definition
quantity.hpp:8
lob::SequenceNumberGenerator
Generates process-wide monotonic sequence numbers.
Definition
sequence_number_generator.hpp:14
lob::Timestamp
Nanoseconds since the Unix epoch; zero is reserved as invalid.
Definition
timestamp.hpp:10
order_event.hpp
Defines event-first order command payloads and dispatch types.
include
lob
matching
matching_engine.hpp
Generated by
1.18.0