-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathmain.cpp
More file actions
121 lines (93 loc) · 4.74 KB
/
Copy pathmain.cpp
File metadata and controls
121 lines (93 loc) · 4.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
#include "OrderBook.hpp"
#include <chrono>
#include <random>
int main() {
OrderBook ob;
// Configuration d'un générateur de nombres aléatoires réalistes
std::random_device rd;
std::mt19937 gen(rd());
std::uniform_real_distribution<> priceDist(99.0, 101.0); // Les prix oscillent autour de 100€
std::uniform_int_distribution<> qtyDist(1, 100); // Quantités entre 1 et 100 actions
std::uniform_int_distribution<> sideDist(0, 1); // 0 = Vente, 1 = Achat
std::uniform_int_distribution<> actionDist(0, 9); // Pour simuler 10% d'annulations
const int TOTAL_ORDERS = 1000000;
uint64_t currentOrderId = 1;
std::vector<uint64_t> activeOrderIds; // Garde une trace des IDs pour simuler les annulations
std::cout << "Préchauffage du moteur... Génération de " << TOTAL_ORDERS << " ordres réels...\n";
// Démarrage du chronomètre haute résolution
auto start = std::chrono::high_resolution_clock::now();
for (int i = 0; i < TOTAL_ORDERS; ++i) {
// 10% de chance d'envoyer une annulation si nous avons des ordres en attente
if (actionDist(gen) == 0 && !activeOrderIds.empty()) {
// On pioche un ID actif au hasard et on l'annule
size_t idx = gen() % activeOrderIds.size();
uint64_t cancelId = activeOrderIds[idx];
ob.cancelOrder(cancelId);
// Retrait rapide de l'ID de notre vecteur de suivi
activeOrderIds[idx] = activeOrderIds.back();
activeOrderIds.pop_back();
}
// 90% de chance de passer un nouvel ordre (Achat ou Vente)
else {
Order order;
order.id = currentOrderId++;
order.isBid = (sideDist(gen) == 1);
// Arrondi du prix à 2 décimales pour simuler un "Tick Size" de 0.01
order.price = std::round(priceDist(gen) * 100.0) / 100.0;
order.quantity = qtyDist(gen);
// Envoi de l'ordre au moteur de matching
auto reports = ob.processOrder(order);
// Si l'ordre n'a pas été entièrement exécuté, il est dans le carnet.
// On peut donc potentiellement l'annuler plus tard.
if (reports.empty() || reports.back().quantityFilled < order.quantity) {
activeOrderIds.push_back(order.id);
}
}
}
// Arrêt du chronomètre
auto end = std::chrono::high_resolution_clock::now();
std::chrono::duration<double> elapsed = end - start;
// Calculs des métriques de performance
double totalSeconds = elapsed.count();
double ordersPerSecond = TOTAL_ORDERS / totalSeconds;
double averageLatencyNanoseconds = (totalSeconds / TOTAL_ORDERS) * 1'000'000'000.0;
std::cout << "\n================ RESULTATS DU TEST ================\n";
std::cout << " Ordres traités : " << TOTAL_ORDERS << " (Matching + Annulations)\n";
std::cout << " Temps total requis : " << totalSeconds << " secondes\n";
std::cout << " Débit global : " << static_cast<uint64_t>(ordersPerSecond) << " ordres/sec\n";
std::cout << " Latence moyenne : " << averageLatencyNanoseconds << " nanosecondes (ns)\n";
std::cout << "===================================================\n";
// Mode demo interactif pour tester le moteur
std::cout << "\n>>> PASSAGE EN MODE INTERACTIF POUR LA DEMO <<<\n";
char rejouer = 'o';
while (rejouer == 'o' || rejouer == 'O') {
Order manuelOrder;
int choixSide;
manuelOrder.id = currentOrderId++;
std::cout << "Type d'ordre (1 pour ACHAT, 0 pour VENTE) : ";
std::cin >> choixSide;
manuelOrder.isBid = (choixSide == 1);
std::cout << "Prix de l'ordre : ";
std::cin >> manuelOrder.price;
std::cout << "Quantité : ";
std::cin >> manuelOrder.quantity;
std::cout << "\nTraitement de votre ordre en direct...\n";
auto reports = ob.processOrder(manuelOrder);
if (!reports.empty()) {
std::cout << "-> MATCH REUSSI ! Transactions :\n";
for (const auto& rep : reports) {
std::cout << " Ordre ID matché : " << rep.orderId
<< " | Prix exéc : " << rep.executionPrice
<< " | Qté transférée : " << rep.quantityFilled << "\n";
}
} else {
std::cout << "-> Aucun match immédiat. L'ordre a été placé dans le carnet.\n";
}
ob.print();
std::cout << "Voulez-vous tester un autre ordre ? (o/n) : ";
std::cin >> rejouer;
}
// Affichage d'un aperçu visuel du carnet final obtenu après le test
ob.print();
return 0;
}