-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathmain.cpp
More file actions
220 lines (188 loc) Β· 9.74 KB
/
main.cpp
File metadata and controls
220 lines (188 loc) Β· 9.74 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
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
#include "orderbook.h"
#include "csv_parser.h"
#include <iostream>
#include <chrono>
#include <vector>
#include <iomanip>
void printUsage(const char* program_name) {
std::cout << "Usage: " << program_name << " <input_mbo_file> [output_mbp_file] [options]" << std::endl;
std::cout << " input_mbo_file: Path to MBO CSV file" << std::endl;
std::cout << " output_mbp_file: Path to output MBP CSV file (default: output_mbp.csv)" << std::endl;
std::cout << "Options:" << std::endl;
std::cout << " --verbose, -v: Enable detailed logging" << std::endl;
std::cout << " --validate: Enable data validation checks" << std::endl;
std::cout << " --help, -h: Show this help message" << std::endl;
}
int main(int argc, char* argv[]) {
if (argc < 2) {
printUsage(argv[0]);
return 1;
}
std::string input_file = argv[1];
std::string output_file = "output_mbp.csv";
bool verbose = false;
bool validate = false;
// Parse command line arguments
for (int i = 2; i < argc; i++) {
std::string arg = argv[i];
if (arg == "--verbose" || arg == "-v") {
verbose = true;
} else if (arg == "--validate") {
validate = true;
} else if (arg == "--help" || arg == "-h") {
printUsage(argv[0]);
return 0;
} else if (arg.find("--") != 0) {
output_file = arg;
}
}
std::cout << "MBP-10 Orderbook Reconstruction v1.0" << std::endl;
std::cout << "====================================" << std::endl;
std::cout << "Input file: " << input_file << std::endl;
std::cout << "Output file: " << output_file << std::endl;
if (verbose) std::cout << "Verbose mode: ENABLED" << std::endl;
if (validate) std::cout << "Validation mode: ENABLED" << std::endl;
std::cout << "====================================" << std::endl;
// Start timing
auto start_time = std::chrono::high_resolution_clock::now();
// Read MBO data
std::cout << "π Reading MBO data..." << std::endl;
auto mbo_records = CSVParser::readMBOFile(input_file);
if (mbo_records.empty()) {
std::cerr << "β Error: No valid MBO records found in input file." << std::endl;
return 1;
}
// Process records through orderbook
std::cout << "βοΈ Processing orderbook..." << std::endl;
OrderBook orderbook;
std::vector<MBPRecord> mbp_output;
mbp_output.reserve(mbo_records.size()); // Reserve space for efficiency
size_t processed_count = 0;
size_t add_count = 0, cancel_count = 0, modify_count = 0, trade_count = 0, clear_count = 0;
size_t n_side_count = 0, unknown_action_count = 0;
size_t trade_sequences = 0;
for (const auto& record : mbo_records) {
// Count action types for statistics
switch (record.action) {
case 'A': add_count++; break;
case 'C': cancel_count++; break;
case 'M': modify_count++; break;
case 'T':
trade_count++;
if (processed_count > 0 && mbo_records[processed_count-1].action != 'T') {
trade_sequences++;
}
break;
case 'R': clear_count++; break;
default: unknown_action_count++; break;
}
if (record.side == 'N') {
n_side_count++;
}
if (verbose && processed_count < 10) {
std::cout << " Processing: " << record.action << " " << record.side
<< " " << std::fixed << std::setprecision(2) << record.price
<< " x " << record.size
<< " (order " << record.order_id << ")" << std::endl;
}
size_t output_before = mbp_output.size();
orderbook.processAction(record, mbp_output);
if (validate && mbp_output.size() > output_before && verbose) {
std::cout << " β Generated MBP record" << std::endl;
}
processed_count++;
// Progress indicator for large files
if (processed_count % 10000 == 0) {
std::cout << " Processed " << processed_count << " records..." << std::endl;
}
}
// Write output
std::cout << "πΎ Writing MBP output..." << std::endl;
if (!CSVParser::writeMBPFile(output_file, mbp_output)) {
std::cerr << "β Error: Failed to write output file." << std::endl;
return 1;
}
// End timing
auto end_time = std::chrono::high_resolution_clock::now();
auto duration = std::chrono::duration_cast<std::chrono::milliseconds>(end_time - start_time);
// Print detailed statistics
std::cout << "\nβ
=== PROCESSING COMPLETE ===" << std::endl;
std::cout << "π Input Analysis:" << std::endl;
std::cout << " Total records: " << mbo_records.size() << std::endl;
std::cout << " - Add orders (A): " << add_count << " ("
<< std::fixed << std::setprecision(1) << (100.0 * add_count / mbo_records.size()) << "%)" << std::endl;
std::cout << " - Cancel orders (C): " << cancel_count << " ("
<< std::fixed << std::setprecision(1) << (100.0 * cancel_count / mbo_records.size()) << "%)" << std::endl;
std::cout << " - Modify orders (M): " << modify_count << " ("
<< std::fixed << std::setprecision(1) << (100.0 * modify_count / mbo_records.size()) << "%)" << std::endl;
std::cout << " - Trades (T): " << trade_count << " ("
<< std::fixed << std::setprecision(1) << (100.0 * trade_count / mbo_records.size()) << "%)" << std::endl;
std::cout << " - Trade sequences: ~" << trade_sequences << std::endl;
std::cout << " - Clear actions (R): " << clear_count << std::endl;
std::cout << " - 'N' side records: " << n_side_count << " (ignored)" << std::endl;
if (unknown_action_count > 0) {
std::cout << " - Unknown actions: " << unknown_action_count << std::endl;
}
std::cout << "\nπ Output Analysis:" << std::endl;
std::cout << " MBP records generated: " << mbp_output.size() << std::endl;
std::cout << " Conversion ratio: " << std::fixed << std::setprecision(1)
<< (100.0 * mbp_output.size() / mbo_records.size()) << "%" << std::endl;
std::cout << "\nβ‘ Performance Metrics:" << std::endl;
std::cout << " Processing time: " << duration.count() << " ms" << std::endl;
if (duration.count() > 0) {
double ops_per_sec = (static_cast<double>(mbo_records.size()) / duration.count()) * 1000.0;
std::cout << " Processing rate: " << std::fixed << std::setprecision(0)
<< ops_per_sec << " operations/second" << std::endl;
double throughput_mb = (static_cast<double>(mbo_records.size() * 100) / (1024 * 1024)) / (duration.count() / 1000.0);
std::cout << " Estimated throughput: " << std::fixed << std::setprecision(1)
<< throughput_mb << " MB/second" << std::endl;
}
std::cout << "\nπ Final Orderbook State:" << std::endl;
std::cout << " Active orders: " << orderbook.getOrderCount() << std::endl;
std::cout << " Bid levels: " << orderbook.getBidLevels() << std::endl;
std::cout << " Ask levels: " << orderbook.getAskLevels() << std::endl;
// Print final orderbook state
orderbook.printOrderBook();
// Validation checks
if (validate) {
std::cout << "\nπ Validation Results:" << std::endl;
// Check for reasonable conversion ratio
double conversion_ratio = static_cast<double>(mbp_output.size()) / mbo_records.size();
if (conversion_ratio < 0.5) {
std::cout << " β οΈ Low conversion ratio (" << std::fixed << std::setprecision(1)
<< conversion_ratio * 100 << "%) - investigate data quality" << std::endl;
} else if (conversion_ratio > 0.95) {
std::cout << " β
Excellent conversion ratio (" << std::fixed << std::setprecision(1)
<< conversion_ratio * 100 << "%)" << std::endl;
} else {
std::cout << " β
Good conversion ratio (" << std::fixed << std::setprecision(1)
<< conversion_ratio * 100 << "%)" << std::endl;
}
// Check orderbook integrity
if (orderbook.getOrderCount() == 0 && (orderbook.getBidLevels() > 0 || orderbook.getAskLevels() > 0)) {
std::cout << " β οΈ Orderbook has price levels but no orders - possible data inconsistency" << std::endl;
} else {
std::cout << " β
Orderbook integrity check passed" << std::endl;
}
// Check for balanced add/cancel ratio
if (add_count > 0 && cancel_count > 0) {
double add_cancel_ratio = static_cast<double>(cancel_count) / add_count;
if (add_cancel_ratio > 1.1 || add_cancel_ratio < 0.9) {
std::cout << " β οΈ Unbalanced add/cancel ratio: " << std::fixed << std::setprecision(2)
<< add_cancel_ratio << " (expected ~1.0)" << std::endl;
} else {
std::cout << " β
Balanced add/cancel ratio: " << std::fixed << std::setprecision(2)
<< add_cancel_ratio << std::endl;
}
}
// Check for reasonable spread
if (orderbook.getBidLevels() > 0 && orderbook.getAskLevels() > 0) {
std::cout << " β
Orderbook has both bids and asks" << std::endl;
} else {
std::cout << " β οΈ Orderbook missing " << (orderbook.getBidLevels() == 0 ? "bids" : "asks") << std::endl;
}
}
std::cout << "\nProcessing completed successfully!" << std::endl;
std::cout << "π Output written to: " << output_file << std::endl;
return 0;
}