-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathmain.cpp
More file actions
155 lines (127 loc) · 6.12 KB
/
main.cpp
File metadata and controls
155 lines (127 loc) · 6.12 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
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
#include <iostream>
#include <iomanip>
#include <thread>
#include <chrono>
#include <random>
#include <vector>
#include <limits>
#include <numeric>
#include <algorithm>
#include "feed_handler.h"
#include "matching_engine.h"
#include "messenger.h"
class TradingSystem {
private:
FeedHandler feed_;
MatchingEngine engine_;
UDPMessenger udp_;
std::mt19937 rng_;
std::uniform_int_distribution<int> side_dist_;
std::uniform_real_distribution<double> offset_dist_;
// Latency tracking
std::vector<double> order_latencies_;
std::vector<double> trade_latencies_;
uint64_t last_order_time_;
void on_market_data(const MarketData& data) {
std::cout << "[FEED] " << data.symbol << " @ " << std::fixed << std::setprecision(2)
<< data.price << " x " << data.quantity << "\n";
// Randomly submit orders based on market data
auto order_start = std::chrono::high_resolution_clock::now();
if (side_dist_(rng_) == 0) {
double bid_price = data.price - 1.0 + offset_dist_(rng_);
int qty = 100 + (data.quantity % 500);
last_order_time_ = std::chrono::duration_cast<std::chrono::nanoseconds>(
order_start.time_since_epoch()).count();
uint64_t order_id = engine_.submit_order(data.symbol, BUY, bid_price, qty);
auto order_end = std::chrono::high_resolution_clock::now();
double latency_us = std::chrono::duration<double, std::micro>(order_end - order_start).count();
order_latencies_.push_back(latency_us);
std::cout << "[ORDER] Buy " << data.symbol << " " << qty << " @ " << bid_price
<< " (ID: " << order_id << ", Latency: " << std::fixed << std::setprecision(2)
<< latency_us << " μs)\n";
} else {
double ask_price = data.price + 1.0 + offset_dist_(rng_);
int qty = 100 + (data.quantity % 500);
last_order_time_ = std::chrono::duration_cast<std::chrono::nanoseconds>(
order_start.time_since_epoch()).count();
uint64_t order_id = engine_.submit_order(data.symbol, SELL, ask_price, qty);
auto order_end = std::chrono::high_resolution_clock::now();
double latency_us = std::chrono::duration<double, std::micro>(order_end - order_start).count();
order_latencies_.push_back(latency_us);
std::cout << "[ORDER] Sell " << data.symbol << " " << qty << " @ " << ask_price
<< " (ID: " << order_id << ", Latency: " << std::fixed << std::setprecision(2)
<< latency_us << " μs)\n";
}
}
void on_trade(const Trade& trade) {
// Calculate trade latency (time from order submission to trade execution)
uint64_t trade_time = std::chrono::duration_cast<std::chrono::nanoseconds>(
std::chrono::high_resolution_clock::now().time_since_epoch()).count();
double trade_latency_us = (trade_time - last_order_time_) / 1000.0;
trade_latencies_.push_back(trade_latency_us);
std::cout << "[TRADE] " << trade.symbol << " " << trade.quantity << " @ "
<< std::fixed << std::setprecision(2) << trade.price
<< " (Buy: " << trade.buy_order_id << ", Sell: " << trade.sell_order_id
<< ", E2E Latency: " << trade_latency_us << " μs)\n";
// Broadcast trade via UDP
char msg[256];
snprintf(msg, sizeof(msg), "TRADE,%s,%.2f,%d,%llu",
trade.symbol, trade.price, trade.quantity, trade.timestamp);
udp_.send_to("127.0.0.1", 9999, msg, strlen(msg));
}
void print_latency_stats(const std::string& name, const std::vector<double>& latencies) {
if (latencies.empty()) {
std::cout << name << ": No data\n";
return;
}
double min_lat = *std::min_element(latencies.begin(), latencies.end());
double max_lat = *std::max_element(latencies.begin(), latencies.end());
double avg_lat = std::accumulate(latencies.begin(), latencies.end(), 0.0) / latencies.size();
std::cout << name << ":\n"
<< " Min: " << std::fixed << std::setprecision(2) << min_lat << " μs\n"
<< " Max: " << max_lat << " μs\n"
<< " Avg: " << avg_lat << " μs\n"
<< " Count: " << latencies.size() << "\n";
}
public:
TradingSystem() : rng_(std::random_device{}()), side_dist_(0, 1), offset_dist_(-0.5, 0.5), last_order_time_(0) {
engine_.set_trade_callback([this](const Trade& t) { on_trade(t); });
}
void start() {
std::cout << "=== Mini Trading System ===\n\n";
// Initialize UDP messenger
if (!udp_.create_socket()) {
std::cerr << "Failed to create UDP socket\n";
return;
}
std::cout << "[SYSTEM] UDP messenger ready\n";
// Start feed handler
feed_.start([this](const MarketData& data) { on_market_data(data); });
std::cout << "[SYSTEM] Feed handler started\n\n";
// Let it run for a while
std::this_thread::sleep_for(std::chrono::seconds(10));
// Display order book stats
std::cout << "\n=== Order Book Summary ===\n";
const char* symbols[] = {"AAPL", "GOOGL", "MSFT", "AMZN"};
for (const char* symbol : symbols) {
double bid_price, ask_price;
int bid_qty, ask_qty;
if (engine_.get_best_bid_ask(symbol, bid_price, bid_qty, ask_price, ask_qty)) {
std::cout << symbol << ": Bid " << std::fixed << std::setprecision(2)
<< bid_price << " x " << bid_qty << " | Ask " << ask_price
<< " x " << ask_qty << "\n";
}
}
// Display latency statistics
std::cout << "\n=== Latency Statistics ===\n";
print_latency_stats("Order Submission Latency", order_latencies_);
print_latency_stats("End-to-End Trade Latency", trade_latencies_);
feed_.stop();
std::cout << "\n[SYSTEM] Trading system stopped\n";
}
};
int main() {
TradingSystem system;
system.start();
return 0;
}