Skip to content

Commit 632d649

Browse files
authored
Merge pull request #18 from bbalouki/bbs-dev
bug fix
2 parents c697c70 + 738f62b commit 632d649

5 files changed

Lines changed: 121 additions & 184 deletions

File tree

examples/CMakeLists.txt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,14 @@
11
cmake_minimum_required(VERSION 3.20)
22

3-
add_executable(parser_example parser/main.cpp)
3+
add_executable(parser_example parser/parser_example.cpp)
44

55
target_link_libraries(
66
parser_example PRIVATE
77
itch::itch
88
warnings::strict
99
)
1010

11-
add_executable(order_book_example order_book/main.cpp)
11+
add_executable(order_book_example order_book/order_book_example.cpp)
1212

1313
target_link_libraries(
1414
order_book_example PRIVATE

examples/order_book/main.cpp

Lines changed: 0 additions & 154 deletions
This file was deleted.
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
#include <chrono>
2+
#include <fstream>
3+
#include <iostream>
4+
#include <vector>
5+
6+
#include "itch/order_book.hpp"
7+
#include "itch/parser.hpp"
8+
9+
10+
int main(int argc, char* argv[]) {
11+
if (argc != 2) {
12+
std::cerr << "Usage: " << argv[0] << " <itch_file>\n";
13+
return 1;
14+
}
15+
16+
std::ifstream file(argv[1], std::ios::binary);
17+
if (!file) {
18+
std::cerr << "Error: Could not open file " << argv[1] << "\n";
19+
return 1;
20+
}
21+
22+
itch::Parser parser;
23+
itch::LimitOrderBook order_book;
24+
25+
try {
26+
auto processor = [&](auto&& msg) { order_book.process(msg); };
27+
parser.parse(file, processor);
28+
order_book.print(std::cout);
29+
30+
} catch (const std::exception& e) {
31+
std::cerr << "An error occurred: " << e.what() << "\n";
32+
return 1;
33+
}
34+
35+
return 0;
36+
}

include/itch/order_book.hpp

Lines changed: 83 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -16,13 +16,20 @@ namespace itch {
1616

1717
struct PriceLevel;
1818

19-
// Represent a single order in the order book.
19+
/**
20+
* @struct Order
21+
* @brief Represents a single resting order within the Limit Order Book.
22+
*
23+
* Encapsulates all necessary state data for an order, including its unique
24+
* reference number, side (Buy/Sell), quantity, and price. It also maintains
25+
* a pointer to its parent PriceLevel for efficient traversal.
26+
*/
2027
struct Order {
21-
uint64_t order_reference_number;
22-
char buy_sell_indicator;
23-
uint32_t shares;
24-
uint32_t price;
25-
PriceLevel* level;
28+
uint64_t order_reference_number; ///< Unique identifier assigned to the order by the exchange.
29+
char buy_sell_indicator; ///< 'B' for Buy, 'S' for Sell.
30+
uint32_t shares; ///< Current quantity of shares available in this order.
31+
uint32_t price; ///< Limit price of the order.
32+
PriceLevel* level; ///< Pointer to the price level containing this order.
2633

2734
Order(uint64_t ref_num, char side, uint32_t shrs, uint32_t prc)
2835
: order_reference_number{ref_num},
@@ -32,67 +39,115 @@ struct Order {
3239
level{nullptr} {}
3340
};
3441

42+
/// Iterator type for navigating the list of orders within a price level.
3543
using OrderIt = std::list<std::shared_ptr<Order>>::iterator;
3644

37-
// Represent a price level in the order book.
38-
// Contains a list of orders at that price, in time priority.
45+
/**
46+
* @struct PriceLevel
47+
* @brief Represents a specific price node in the order book.
48+
*
49+
* Maintains a queue of orders at a specific price, enforcing Time-Priority
50+
* (FIFO) execution. It tracks the aggregate share volume for this level.
51+
*/
3952
struct PriceLevel {
40-
uint32_t total_shares{0};
41-
std::list<std::shared_ptr<Order>> orders;
53+
uint32_t total_shares{0}; ///< Aggregate volume of shares at this price.
54+
std::list<std::shared_ptr<Order>> orders; ///< FIFO queue of orders.
4255

56+
/**
57+
* @brief Appends an order to the end of the queue (Time priority).
58+
* @param order Shared pointer to the order to add.
59+
*/
4360
void add_order(std::shared_ptr<Order> order);
61+
62+
/**
63+
* @brief Removes a specific order from the queue.
64+
* @param order_it Iterator pointing to the order to remove.
65+
*/
4466
void remove_order(OrderIt order_it);
4567
};
4668

4769
/**
4870
* @class LimitOrderBook
49-
* @brief A class that represents and maintains a limit order book for a single stock.
71+
* @brief Manages the state of a limit order book for a specific financial instrument.
72+
*
73+
* The LimitOrderBook ingests raw Nasdaq ITCH 5.0 messages and reconstructs the
74+
* full depth of market. It supports standard order lifecycle events including
75+
* addition, execution, cancellation, deletion, and replacement.
5076
*
51-
* The LimitOrderBook processes ITCH 5.0 messages to build and maintain the
52-
* state of the order book. It handles adding, executing, canceling, deleting,
53-
* and replacing orders.
77+
* @note This implementation uses `std::map` for price levels to ensure
78+
* keys (prices) are always sorted, allowing for O(log n) insertion and deletion
79+
* of price levels, and O(1) access to the best bid/ask.
5480
*/
5581
class LimitOrderBook {
5682
public:
5783
/**
58-
* @brief Processes a single ITCH message and updates the order book accordingly.
59-
* @param message The ITCH message to process.
84+
* @brief Dispatches and processes a generic ITCH message.
85+
*
86+
* Identifies the specific type within the `Message` variant and routes it
87+
* to the appropriate internal handler to update the book state.
88+
*
89+
* @param message The parsed ITCH message variant.
6090
*/
6191
void process(const Message& message);
6292

6393
/**
64-
* @brief Prints the current state of the order book to the given output stream.
65-
* @param out The output stream to print to.
94+
* @brief Visualizes the current state of the order book to an output stream.
95+
*
96+
* Prints the best Ask and Bid levels formatted in a table.
97+
*
98+
* @param out The output stream (e.g., std::cout) to write to.
99+
* @param delay_ms Optional delay in milliseconds between printing each line.
100+
* Useful for slowing down output during debugging or replays
101+
* to create an animation effect. Defaults to 0 (no delay).
66102
*/
67103
void print(std::ostream& out, unsigned int delay_ms = 0) const;
68104

69-
// Type aliases for the bid and ask maps.
105+
// Type aliases for the bid and ask maps (sorted containers).
70106
using BidMap = std::map<uint32_t, PriceLevel, std::greater<uint32_t>>;
71107
using AskMap = std::map<uint32_t, PriceLevel, std::less<uint32_t>>;
72108

73-
const BidMap& get_bids() const { return m_bids; }
74-
const AskMap& get_asks() const { return m_asks; }
109+
/**
110+
* @return A reference to the map of active Bids, sorted descending by price.
111+
*/
112+
const BidMap& get_bids() const { return m_bids; }
113+
114+
/**
115+
* @return A reference to the map of active Asks, sorted ascending by price.
116+
*/
117+
const AskMap& get_asks() const { return m_asks; }
118+
119+
/// Set of message type characters that affect the book state.
75120
const std::set<char> book_messages{'A', 'F', 'E', 'C', 'X', 'D', 'U'};
76121

77122
private:
78-
BidMap m_bids; ///< Map of bid price levels (price -> PriceLevel)
79-
AskMap m_asks; ///< Map of ask price levels (price -> PriceLevel)
80-
std::map<uint64_t, OrderIt> m_orders; ///< Map of orders by reference number
123+
BidMap m_bids; ///< Ask price levels (Price -> Level). Sorted Low-to-High.
124+
AskMap m_asks; ///< Bid price levels (Price -> Level). Sorted High-to-Low.
125+
std::map<uint64_t, OrderIt> m_orders; ///< Hash map for O(1) order lookup by Reference Number.
81126

82-
// Handler methods for specific message types
127+
// Message Handlers
83128
void handle_message(const AddOrderMessage& msg);
84129
void handle_message(const AddOrderMPIDAttributionMessage& msg);
85130
void handle_message(const OrderExecutedMessage& msg);
86131
void handle_message(const OrderExecutedWithPriceMessage& msg);
87132
void handle_message(const OrderCancelMessage& msg);
88133
void handle_message(const OrderDeleteMessage& msg);
89134
void handle_message(const OrderReplaceMessage& msg);
90-
// Generic handler for message types we don't care about
135+
136+
// Generic handler/sink for message types that do not impact book state.
91137
template <typename T>
92-
void handle_message(const T& msg) { /* Ignore */ }
138+
void handle_message(const T& /* msg */) { /* No-op for irrelevant messages */ }
93139

94-
// Helper methods
140+
/**
141+
* @brief Creates an Order object and inserts it into the appropriate PriceLevel.
142+
*/
95143
void add_order(uint64_t order_ref, char side, uint32_t shares, uint32_t price);
144+
145+
/**
146+
* @brief Reduces shares from an order or removes it entirely if fully depleted.
147+
*
148+
* @param order_ref The unique reference number of the target order.
149+
* @param canceled_shares The number of shares to remove.
150+
*/
96151
void remove_order(uint64_t order_ref, uint32_t canceled_shares);
97152
};
98153

0 commit comments

Comments
 (0)