Skip to content

Commit 6009186

Browse files
committed
Added concurrent market example and string functions
1 parent 285cfee commit 6009186

31 files changed

+222
-105
lines changed

CMakeLists.txt

+17-13
Original file line numberDiff line numberDiff line change
@@ -136,32 +136,36 @@ set(MEMORYCHECK_COMMAND_OPTIONS "${MEMORYCHECK_COMMAND_OPTIONS} --error-exitcode
136136
# ------------------------------------------------------------------------------
137137
file(GLOB_RECURSE LIB_HEADER_FILES "include/*.h")
138138
file(GLOB_RECURSE LIB_SOURCE_FILES "src/*.cpp")
139-
add_library(rapid_trader ${LIB_HEADER_FILES} ${LIB_SOURCE_FILES} src/matching/orderbook/symbol.cpp)
140-
target_link_libraries(rapid_trader spdlog)
139+
add_library(trader_lib ${LIB_HEADER_FILES} ${LIB_SOURCE_FILES})
140+
target_link_libraries(trader_lib spdlog)
141+
install(TARGETS trader_lib DESTINATION ${TRADER_INSTALL_LIB_DIR})
141142

142143
# ------------------------------------------------------------------------------
143144
# Rapid Trader Example
144145
# ------------------------------------------------------------------------------
145-
add_executable(rapid_trader_example examples/market_example.cpp)
146-
target_link_libraries(rapid_trader_example rapid_trader)
147-
install(TARGETS rapid_trader_example DESTINATION ${TRADER_INSTALL_BIN_DIR}/examples)
146+
add_executable(trader_market_example examples/market_example.cpp)
147+
add_executable(trader_concurrent_market_example examples/concurrent_market_example.cpp examples/simple_event_handler.h)
148+
target_link_libraries(trader_market_example trader_lib)
149+
target_link_libraries(trader_concurrent_market_example trader_lib)
150+
install(TARGETS trader_market_example DESTINATION ${TRADER_INSTALL_BIN_DIR}/examples)
151+
install(TARGETS trader_concurrent_market_example DESTINATION ${TRADER_INSTALL_BIN_DIR}/examples)
148152

149153
# ------------------------------------------------------------------------------
150154
# Rapid Trader Benchmark
151155
# ------------------------------------------------------------------------------
152-
add_executable(rapid_trader_benchmark benchmark/bench_market.cpp)
153-
target_link_libraries(rapid_trader_benchmark benchmark::benchmark rapid_trader)
154-
install(TARGETS rapid_trader_benchmark DESTINATION ${TRADER_INSTALL_BIN_DIR}/benchmarks)
156+
add_executable(trader_benchmark benchmark/bench_market.cpp)
157+
target_link_libraries(trader_benchmark benchmark::benchmark trader_lib)
158+
install(TARGETS trader_benchmark DESTINATION ${TRADER_INSTALL_BIN_DIR}/benchmarks)
155159

156160
# ------------------------------------------------------------------------------
157161
# Rapid Trader Tests
158162
# ------------------------------------------------------------------------------
159163
include(CTest)
160164
include(GoogleTest)
161165
file(GLOB_RECURSE TEST_SOURCE_FILES "test/*.cpp")
162-
add_executable(rapid_trader_tests ${TEST_SOURCE_FILES})
163-
target_link_libraries(rapid_trader_tests rapid_trader)
164-
target_link_libraries(rapid_trader_tests gtest_main)
165-
gtest_discover_tests(rapid_trader_tests)
166-
install(TARGETS rapid_trader_tests DESTINATION ${TRADER_INSTALL_BIN_DIR}/tests)
166+
add_executable(trader_tests ${TEST_SOURCE_FILES})
167+
target_link_libraries(trader_tests trader_lib)
168+
target_link_libraries(trader_tests gtest_main)
169+
gtest_discover_tests(trader_tests)
170+
install(TARGETS trader_tests DESTINATION ${TRADER_INSTALL_BIN_DIR}/tests)
167171

benchmark/bench_market.cpp

+3-1
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@
44
#include "market/market.h"
55
#include "event_handler/event_handler.h"
66

7+
using namespace RapidTrader;
8+
79
class DebugEventHandler : public EventHandler
810
{};
911

@@ -37,7 +39,7 @@ static void BM_Market(benchmark::State &state)
3739
for (auto _ : state)
3840
{
3941
state.PauseTiming();
40-
RapidTrader::Matching::Market market{std::make_unique<EventHandler>()};
42+
Market market{std::make_unique<EventHandler>()};
4143
for (int i = 1; i <= num_symbols; ++i)
4244
market.addSymbol(i, "MARKET BENCH");
4345
state.ResumeTiming();
+39
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
#include <iostream>
2+
#include "market/concurrent_market.h"
3+
#include "simple_event_handler.h"
4+
5+
using namespace RapidTrader;
6+
7+
int main()
8+
{
9+
// Create a new concurrent market that uses 2 threads.
10+
// Note that there must be one event handler per thread.
11+
const uint32_t num_threads = 2;
12+
std::vector<std::unique_ptr<EventHandler>> event_handlers;
13+
for (uint32_t i = 0; i < num_threads; ++i)
14+
event_handlers.push_back(std::unique_ptr<EventHandler>(new SimpleEventHandler));
15+
ConcurrentMarket market{event_handlers, num_threads};
16+
17+
// Add a new symbol to the market. A symbol must be added to the market before any orders with that symbol are submitted.
18+
std::string symbol1_name = "GOOG";
19+
uint32_t symbol1_id = 1;
20+
market.addSymbol(symbol1_id, symbol1_name);
21+
22+
// Add bid limit order to the market.
23+
OrderTimeInForce time_in_force1 = OrderTimeInForce::GTC;
24+
uint64_t quantity1 = 200;
25+
uint64_t price1 = 350;
26+
uint64_t id1 = 1;
27+
Order order1 = Order::limitBidOrder(id1, symbol1_id, price1, quantity1, time_in_force1);
28+
market.addOrder(order1);
29+
30+
// Add ask limit order to the market.
31+
OrderTimeInForce time_in_force2 = OrderTimeInForce::GTC;
32+
uint64_t quantity2 = 200;
33+
uint64_t price2 = 350;
34+
uint64_t id2 = 2;
35+
Order order2 = Order::limitAskOrder(id2, symbol1_id, price2, quantity2, time_in_force2);
36+
market.addOrder(order2);
37+
38+
return 0;
39+
}

examples/market_example.cpp

+5-31
Original file line numberDiff line numberDiff line change
@@ -1,55 +1,29 @@
11
#include <iostream>
22
#include "market/market.h"
3-
#include "event_handler.h"
3+
#include "simple_event_handler.h"
44

5-
class SimpleEventHandler : public EventHandler
6-
{
7-
protected:
8-
void handleOrderAdded(const OrderAdded &notification) override
9-
{
10-
std::cout << notification << "\n";
11-
}
12-
void handleOrderDeleted(const OrderDeleted &notification) override
13-
{
14-
std::cout << notification << "\n";
15-
}
16-
void handleOrderUpdated(const OrderUpdated &notification) override
17-
{
18-
std::cout << notification << "\n";
19-
}
20-
void handleOrderExecuted(const ExecutedOrder &notification) override
21-
{
22-
std::cout << notification << "\n";
23-
}
24-
void handleSymbolAdded(const SymbolAdded &notification) override
25-
{
26-
std::cout << notification << "\n";
27-
}
28-
void handleSymbolDeleted(const SymbolDeleted &notification) override
29-
{
30-
std::cout << notification << "\n";
31-
}
32-
};
5+
using namespace RapidTrader;
336

347
int main()
358
{
369
// Create a new market with an event handler. Note that the market requires ownership of the event handler.
3710
auto event_handler = std::unique_ptr<EventHandler>(new SimpleEventHandler);
38-
RapidTrader::Matching::Market market{std::move(event_handler)};
11+
Market market{std::move(event_handler)};
3912

4013
// Add a new symbol to the market. A symbol must be added to the market before any orders with that symbol are submitted.
4114
std::string symbol_name = "GOOG";
4215
uint32_t symbol_id = 1;
4316
market.addSymbol(symbol_id, symbol_name);
4417

45-
// Add some limit orders to the market.
18+
// Add bid limit order to the market.
4619
OrderTimeInForce time_in_force1 = OrderTimeInForce::GTC;
4720
uint64_t quantity1 = 200;
4821
uint64_t price1 = 350;
4922
uint64_t id1 = 1;
5023
Order order1 = Order::limitBidOrder(id1, symbol_id, price1, quantity1, time_in_force1);
5124
market.addOrder(order1);
5225

26+
// Add ask limit order to the market.
5327
OrderTimeInForce time_in_force2 = OrderTimeInForce::GTC;
5428
uint64_t quantity2 = 200;
5529
uint64_t price2 = 350;

examples/simple_event_handler.h

+36
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
#ifndef RAPID_TRADER_SIMPLE_EVENT_HANDLER_H
2+
#define RAPID_TRADER_SIMPLE_EVENT_HANDLER_H
3+
#include "event_handler.h"
4+
5+
using namespace RapidTrader;
6+
7+
class SimpleEventHandler : public EventHandler
8+
{
9+
10+
protected:
11+
void handleOrderAdded(const OrderAdded &notification) override
12+
{
13+
std::cout << notification << std::endl;;
14+
}
15+
void handleOrderDeleted(const OrderDeleted &notification) override
16+
{
17+
std::cout << notification << std::endl;;
18+
}
19+
void handleOrderUpdated(const OrderUpdated &notification) override
20+
{
21+
std::cout << notification << std::endl;;
22+
}
23+
void handleOrderExecuted(const ExecutedOrder &notification) override
24+
{
25+
std::cout << notification << std::endl;;
26+
}
27+
void handleSymbolAdded(const SymbolAdded &notification) override
28+
{
29+
std::cout << notification << std::endl;;
30+
}
31+
void handleSymbolDeleted(const SymbolDeleted &notification) override
32+
{
33+
std::cout << notification << std::endl;;
34+
}
35+
};
36+
#endif // RAPID_TRADER_SIMPLE_EVENT_HANDLER_H

include/concurrent/queue.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
#include <mutex>
55
#include <condition_variable>
66

7-
namespace Concurrent {
7+
namespace RapidTrader::Concurrent {
88
/**
99
* A thread-safe queue.
1010
*

include/concurrent/thread_joiner.h

+2
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
#include <vector>
44
#include <thread>
55

6+
namespace RapidTrader::Concurrent {
67
/**
78
* A class to clean up threads used by the thread pool.
89
*/
@@ -26,4 +27,5 @@ struct ThreadJoiner
2627
// The threads that the joiner is responsible for joining.
2728
std::vector<std::thread> &threads;
2829
};
30+
}
2931
#endif // RAPID_TRADER_THREAD_JOINER_H

include/concurrent/thread_pool.h

+2-1
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
#include "concurrent/thread_joiner.h"
99
#include "concurrent/queue.h"
1010

11-
namespace Concurrent {
11+
namespace RapidTrader::Concurrent {
1212
class ThreadPool
1313
{
1414
public:
@@ -98,6 +98,7 @@ class ThreadPool
9898
task_promise->set_exception(std::current_exception());
9999
}
100100
});
101+
return task_promise->get_future();
101102
}
102103

103104
/**

include/event_handler/event.h

+2
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
#define RAPID_TRADER_EVENT_H
33
#include "order.h"
44

5+
namespace RapidTrader {
56
struct Event
67
{
78
virtual ~Event() = default;
@@ -80,4 +81,5 @@ struct OrderUpdated : public OrderEvent
8081

8182
friend std::ostream &operator<<(std::ostream &os, const OrderUpdated &notification);
8283
};
84+
}
8385
#endif // RAPID_TRADER_EVENT_H

include/event_handler/event_handler.h

+2
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
#include "market/concurrent_market.h"
55
#include "event_handler/event.h"
66

7+
namespace RapidTrader {
78
class EventHandler
89
{
910
public:
@@ -62,4 +63,5 @@ class EventHandler
6263
virtual void handleSymbolDeleted(const SymbolDeleted &event) {}
6364
// LCOV_EXCL_STOP
6465
};
66+
}
6567
#endif // RAPID_TRADER_EVENT_HANDLER_H

include/matching/market/concurrent_market.h

+20-5
Original file line numberDiff line numberDiff line change
@@ -9,10 +9,12 @@
99
#include "orderbook.h"
1010
#include "symbol.h"
1111

12+
13+
namespace RapidTrader {
14+
using namespace Concurrent;
1215
class EventHandler;
1316
class OrderBookHandler;
1417

15-
namespace RapidTrader::Matching {
1618
class ConcurrentMarket
1719
{
1820
public:
@@ -58,7 +60,6 @@ class ConcurrentMarket
5860
*
5961
* @param symbol_id the symbol ID associated with the order.
6062
* @param order_id the ID associated with the order.
61-
* @return ErrorStatus indicating whether the order was successfully deleted.
6263
*/
6364
void deleteOrder(uint32_t symbol_id, uint64_t order_id);
6465

@@ -68,7 +69,6 @@ class ConcurrentMarket
6869
* @param symbol_id the symbol ID associated with the order.
6970
* @param order_id the ID associated with the order.
7071
* @param cancelled_quantity the quantity of the order to cancel, require that cancelled_quantity is positive.
71-
* @return ErrorStatus indicating whether the order was successfully cancelled.
7272
*/
7373
void cancelOrder(uint32_t symbol_id, uint64_t order_id, uint64_t cancelled_quantity);
7474

@@ -101,6 +101,21 @@ class ConcurrentMarket
101101
*/
102102
void executeOrder(uint32_t symbol_id, uint64_t order_id, uint64_t quantity);
103103

104+
/**
105+
* @return the string representation of the market.
106+
*/
107+
[[nodiscard]] std::string toString();
108+
109+
/**
110+
* Writes the string representation to a file with the provided
111+
* name. Creates a new file.
112+
*
113+
* @param name the name to the file that will be written to.
114+
*/
115+
void dumpMarket(const std::string &name);
116+
117+
friend std::ostream &operator<<(std::ostream &os, ConcurrentMarket &concurrent_market);
118+
104119
private:
105120
/**
106121
* Gets the index that that corresponds to the queue in the thread pool
@@ -127,10 +142,10 @@ class ConcurrentMarket
127142
// handler that is associated with the symbol ID.
128143
robin_hood::unordered_map<uint32_t, uint32_t> id_to_submission_index;
129144
// The thread pool that order operations will be submitted to.
130-
Concurrent::ThreadPool thread_pool;
145+
ThreadPool thread_pool;
131146
// The index of the thread pool queue and orderbook handler that will be associated
132147
// with a newly added symbol.
133148
uint32_t symbol_submission_index;
134149
};
135-
} // namespace RapidTrader::Matching
150+
}
136151
#endif // RAPID_TRADER_CONCURRENT_MARKET_H

include/matching/market/market.h

+7-7
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,9 @@
88
#include "order.h"
99
#include "orderbook.h"
1010
#include "symbol.h"
11+
#include "event_handler.h"
1112

13+
namespace RapidTrader {
1214
class EventHandler;
1315

1416
// A struct for the shared logic between market and concurrent market.
@@ -42,7 +44,6 @@ struct OrderBookHandler
4244
std::unique_ptr<EventHandler> event_handler;
4345
};
4446

45-
namespace RapidTrader::Matching {
4647
class Market
4748
{
4849
public:
@@ -138,12 +139,12 @@ class Market
138139
[[nodiscard]] std::string toString() const;
139140

140141
/**
141-
* Writes the string representation of the the market to
142-
* a file at the provided path. Creates a new file.
142+
* Writes the string representation to a file with the provided
143+
* name. Creates a new file.
143144
*
144-
* @param path the path to the file that will be written to.
145+
* @param name the name to the file that will be written to.
145146
*/
146-
void dumpMarket(const std::string &path) const;
147+
void dumpMarket(const std::string &name) const;
147148

148149
friend std::ostream &operator<<(std::ostream &os, const Market &book);
149150

@@ -153,6 +154,5 @@ class Market
153154
// Symbol IDs to symbols.
154155
robin_hood::unordered_map<uint32_t, std::unique_ptr<Symbol>> id_to_symbol;
155156
};
156-
157-
} // namespace RapidTrader::Matching
157+
} // namespace RapidTrader
158158
#endif // RAPID_TRADER_MARKET_H

include/matching/orderbook/level.h

+2
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
#define RAPID_TRADER_LEVEL_H
33
#include "order.h"
44

5+
namespace RapidTrader {
56
// Only validate level in debug mode.
67
#ifndef NDEBUG
78
# define VALIDATE_LEVEL validateLevel()
@@ -180,4 +181,5 @@ class Level
180181
uint64_t volume;
181182
uint64_t price;
182183
};
184+
}
183185
#endif // RAPID_TRADER_LEVEL_H

0 commit comments

Comments
 (0)