-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathmain.cpp
More file actions
126 lines (112 loc) · 4.23 KB
/
main.cpp
File metadata and controls
126 lines (112 loc) · 4.23 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
#include <algorithm>
#include <cassert>
#include <csignal>
#include <cstdlib>
#include <ctime>
#include <iostream>
#include <ranges>
#include <thread>
#include "LockFreeQueue.h"
#include "OrderBook.h"
#include "util/Logger.h"
extern int matches;
template <typename T>
T randval(T min, T max) {
if constexpr (std::is_integral<T>::value) {
return ((T)rand() % (max - min + 1)) + min;
} else if constexpr (std::is_floating_point<T>::value) {
return min + static_cast<T>(rand()) / (static_cast<T>(RAND_MAX) / (max - min));
}
}
Side randomSide() {
return randval<int>(0, 1) == 0 ? BUY : SELL;
}
void signal_handler(int signum) {
if (signum == SIGINT) {
// Handle the Ctrl+C interrupt
// For example, clean up resources, save data, and exit gracefully
// Logger::getInstance().info("Ctrl+C detected! Exiting gracefully...");
// Logger::getInstance().info("Found " + std::to_string(matches) + " matches.");
std::cout << "Ctrl+C detected! Exiting gracefully..." << std::endl;
std::cout << "Found " << matches << " matches." << std::endl;
exit(signum); // Terminate the program with the signal code
}
}
void addMarketOrders(OrderBook& ob, size_t num_orders) {
for (size_t i = 0; i < num_orders; i++) {
Order order(Order::createMarketOrder(
randomSide(),
randval<uint32_t>(100, 110)));
ob.add_order(order);
}
}
int main(int argc, char const* argv[]) {
Logger& logger = Logger::getInstance();
logger.setLogFile("hft_sim.log");
logger.setLogLevel(LogLevel::INFO);
logger.enableConsole(false);
logger.enableFile(true);
logger.info("Simulation started");
// Seed the random number generator
srand(time(nullptr));
OrderBook lob; // Create limit order book
LockFreeQueue<Order> order_queue;
// Create a dedicated thread to manage logging
// std::thread logger_thread(&Logger::run, &logger);
// logger_thread.detach(); // Detach the thread to run independently
// View orders (Expectation is they should be sorted, per std::map implementation)
auto bids = lob.getBids();
auto asks = lob.getAsks();
signal(SIGINT, signal_handler);
// Simulate the market
const size_t orders_per_producer = 10;
const size_t num_producers = 2;
const size_t num_consumers = 2;
std::vector<std::thread> producers;
std::vector<std::thread> consumers;
producers.reserve(num_producers);
consumers.reserve(num_consumers);
for (size_t i = 0; i < num_producers; ++i) {
producers.emplace_back(
[](LockFreeQueue<Order>& p_queue, uint32_t num_orders) {
for (size_t j = 0; j < num_orders; ++j) {
Order order(
randomSide(), // Side (BUY/SELL)
(Type)(randval<int>(0, 1)), // Market/Limit orders
randval<float>(50, 54), // Price [50, 54]
randval<uint32_t>(100, 110)); // Order size
p_queue.push_back(order);
}
},
std::ref(order_queue),
orders_per_producer);
}
for (size_t i = 0; i < num_consumers; ++i) {
consumers.emplace_back(
[](LockFreeQueue<Order>& o_queue, OrderBook& lob) {
while (true) {
std::optional<Order> order = o_queue.pop();
if (order.has_value()) {
lob.add_order(*order);
} else {
std::this_thread::yield(); // Yield if no orders are available
}
}
},
std::ref(order_queue),
std::ref(lob));
}
// while (1) {
// Order order(
// randomSide(), // Side (BUY/SELL)
// (Type)(randval<int>(0, 1)), // Market/Limit orders
// randval<float>(50, 54), // Price [50, 54]
// randval<uint32_t>(100, 110)); // Order size
// lob.add_order(order);
// if (lob.getBids().size() > 2 and lob.getAsks().size() > 2) {
// // puts("Matching orders...");
// lob.match_orders();
// }
// }
return 0;
}