Fix garbled Unicode box-drawing chars in Windows console output
Browse filesReplace UTF-8 box-drawing characters (β, β) with ASCII equivalents
(=, -) so output displays correctly on Windows consoles that use
legacy codepages. Update version to v0.5.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- src/main.cpp +21 -21
src/main.cpp
CHANGED
|
@@ -1,4 +1,4 @@
|
|
| 1 |
-
//
|
| 2 |
// EuNEx Matching Engine β Main Entry Point
|
| 3 |
//
|
| 4 |
// Multi-threaded actor topology (mirrors Optiq architecture):
|
|
@@ -12,7 +12,7 @@
|
|
| 12 |
// OEActor β LogicalCoreActor (Book) β MDLimit β MDIMP
|
| 13 |
// β OE Ack (back to OEActor)
|
| 14 |
// β ClearingHouse (via Kafka/PTB)
|
| 15 |
-
//
|
| 16 |
|
| 17 |
#include "engine/SimplxShim.hpp"
|
| 18 |
#include "actors/MECoreActor.hpp"
|
|
@@ -35,15 +35,15 @@ static std::atomic<bool> g_running{true};
|
|
| 35 |
void signalHandler(int) { g_running = false; }
|
| 36 |
|
| 37 |
int main() {
|
| 38 |
-
std::cout << "
|
| 39 |
-
std::cout << " EuNEx Matching Engine v0.
|
| 40 |
std::cout << " C++ Actor Architecture (Optiq model)\n";
|
| 41 |
-
std::cout << "
|
| 42 |
|
| 43 |
std::signal(SIGINT, signalHandler);
|
| 44 |
std::signal(SIGTERM, signalHandler);
|
| 45 |
|
| 46 |
-
//
|
| 47 |
constexpr SymbolIndex_t SYM_AAPL = 1;
|
| 48 |
constexpr SymbolIndex_t SYM_MSFT = 2;
|
| 49 |
constexpr SymbolIndex_t SYM_GOOGL = 3;
|
|
@@ -51,13 +51,13 @@ int main() {
|
|
| 51 |
|
| 52 |
std::vector<SymbolIndex_t> allSymbols = {SYM_AAPL, SYM_MSFT, SYM_GOOGL, SYM_EURO50};
|
| 53 |
|
| 54 |
-
//
|
| 55 |
auto oeGateway = std::make_unique<OEGActor>();
|
| 56 |
|
| 57 |
-
//
|
| 58 |
auto mdActor = std::make_unique<MDGActor>();
|
| 59 |
|
| 60 |
-
//
|
| 61 |
auto chActor = std::make_unique<ClearingHouseActor>();
|
| 62 |
|
| 63 |
// Map AI trader sessions to clearing house members
|
|
@@ -71,7 +71,7 @@ int main() {
|
|
| 71 |
static_cast<MemberId_t>(i + 1));
|
| 72 |
}
|
| 73 |
|
| 74 |
-
//
|
| 75 |
auto bookAAPL = std::make_unique<MECoreActor>(
|
| 76 |
SYM_AAPL, oeGateway->getActorId(), mdActor->getActorId(), chActor->getActorId());
|
| 77 |
auto bookMSFT = std::make_unique<MECoreActor>(
|
|
@@ -86,17 +86,17 @@ int main() {
|
|
| 86 |
oeGateway->mapSymbol(SYM_GOOGL, bookGOOGL->getActorId());
|
| 87 |
oeGateway->mapSymbol(SYM_EURO50, bookEURO50->getActorId());
|
| 88 |
|
| 89 |
-
//
|
| 90 |
auto fixGateway = std::make_unique<FIXAcceptorActor>(oeGateway->getActorId(), 9001);
|
| 91 |
|
| 92 |
-
//
|
| 93 |
auto aiTrader = std::make_unique<AITraderActor>(oeGateway->getActorId(), allSymbols);
|
| 94 |
|
| 95 |
-
//
|
| 96 |
oeGateway->addExecReportSubscriber(fixGateway->getActorId());
|
| 97 |
oeGateway->addExecReportSubscriber(aiTrader->getActorId());
|
| 98 |
|
| 99 |
-
//
|
| 100 |
std::cout << "Actor topology:\n";
|
| 101 |
std::cout << " Core 0: OEG (id=" << oeGateway->getActorId().id
|
| 102 |
<< "), FIXAcceptor (id=" << fixGateway->getActorId().id << ")\n";
|
|
@@ -113,7 +113,7 @@ int main() {
|
|
| 113 |
std::cout << " AI Traders: 10 members (MBR01-MBR10)\n";
|
| 114 |
std::cout << " Symbols: AAPL, MSFT, GOOGL, EURO50\n\n";
|
| 115 |
|
| 116 |
-
//
|
| 117 |
std::cout << "Seeding initial order book...\n";
|
| 118 |
SessionId_t seedSession = 200;
|
| 119 |
|
|
@@ -138,7 +138,7 @@ int main() {
|
|
| 138 |
|
| 139 |
std::cout << "Initial orders seeded.\n\n";
|
| 140 |
|
| 141 |
-
//
|
| 142 |
std::cout << "Running AI trading... (Ctrl+C to stop)\n";
|
| 143 |
std::cout << "FIX clients can connect to localhost:9001\n\n";
|
| 144 |
|
|
@@ -148,7 +148,7 @@ int main() {
|
|
| 148 |
round++;
|
| 149 |
|
| 150 |
if (round % 10 == 0) {
|
| 151 |
-
std::cout << "
|
| 152 |
|
| 153 |
auto leaderboard = chActor->getLeaderboard();
|
| 154 |
std::cout << " Leaderboard:\n";
|
|
@@ -185,11 +185,11 @@ int main() {
|
|
| 185 |
std::this_thread::sleep_for(std::chrono::seconds(3));
|
| 186 |
}
|
| 187 |
|
| 188 |
-
//
|
| 189 |
std::cout << "\nShutting down...\n";
|
| 190 |
fixGateway->stop();
|
| 191 |
|
| 192 |
-
std::cout << "\n
|
| 193 |
for (auto sym : allSymbols) {
|
| 194 |
auto* snap = mdActor->getSnapshot(sym);
|
| 195 |
if (snap) {
|
|
@@ -199,7 +199,7 @@ int main() {
|
|
| 199 |
}
|
| 200 |
}
|
| 201 |
|
| 202 |
-
std::cout << "\n
|
| 203 |
auto lb = chActor->getLeaderboard();
|
| 204 |
for (auto& e : lb) {
|
| 205 |
std::cout << " " << e.name
|
|
@@ -210,7 +210,7 @@ int main() {
|
|
| 210 |
}
|
| 211 |
|
| 212 |
std::cout << "\nTrades processed: " << mdActor->getRecentTrades().size() << "\n";
|
| 213 |
-
std::cout << "
|
| 214 |
std::cout << " Engine stopped.\n";
|
| 215 |
return 0;
|
| 216 |
}
|
|
|
|
| 1 |
+
// ====================================================================
|
| 2 |
// EuNEx Matching Engine β Main Entry Point
|
| 3 |
//
|
| 4 |
// Multi-threaded actor topology (mirrors Optiq architecture):
|
|
|
|
| 12 |
// OEActor β LogicalCoreActor (Book) β MDLimit β MDIMP
|
| 13 |
// β OE Ack (back to OEActor)
|
| 14 |
// β ClearingHouse (via Kafka/PTB)
|
| 15 |
+
// ====================================================================
|
| 16 |
|
| 17 |
#include "engine/SimplxShim.hpp"
|
| 18 |
#include "actors/MECoreActor.hpp"
|
|
|
|
| 35 |
void signalHandler(int) { g_running = false; }
|
| 36 |
|
| 37 |
int main() {
|
| 38 |
+
std::cout << "===========================================\n";
|
| 39 |
+
std::cout << " EuNEx Matching Engine v0.5\n";
|
| 40 |
std::cout << " C++ Actor Architecture (Optiq model)\n";
|
| 41 |
+
std::cout << "===========================================\n\n";
|
| 42 |
|
| 43 |
std::signal(SIGINT, signalHandler);
|
| 44 |
std::signal(SIGTERM, signalHandler);
|
| 45 |
|
| 46 |
+
// --Symbol definitions ----------------------------------------
|
| 47 |
constexpr SymbolIndex_t SYM_AAPL = 1;
|
| 48 |
constexpr SymbolIndex_t SYM_MSFT = 2;
|
| 49 |
constexpr SymbolIndex_t SYM_GOOGL = 3;
|
|
|
|
| 51 |
|
| 52 |
std::vector<SymbolIndex_t> allSymbols = {SYM_AAPL, SYM_MSFT, SYM_GOOGL, SYM_EURO50};
|
| 53 |
|
| 54 |
+
// --Core 0: OE Gateway ----------------------------------------
|
| 55 |
auto oeGateway = std::make_unique<OEGActor>();
|
| 56 |
|
| 57 |
+
// --Core 2: Market Data ---------------------------------------
|
| 58 |
auto mdActor = std::make_unique<MDGActor>();
|
| 59 |
|
| 60 |
+
// --Core 3: Clearing House ------------------------------------
|
| 61 |
auto chActor = std::make_unique<ClearingHouseActor>();
|
| 62 |
|
| 63 |
// Map AI trader sessions to clearing house members
|
|
|
|
| 71 |
static_cast<MemberId_t>(i + 1));
|
| 72 |
}
|
| 73 |
|
| 74 |
+
// --Core 1: Order Books (per symbol) --------------------------
|
| 75 |
auto bookAAPL = std::make_unique<MECoreActor>(
|
| 76 |
SYM_AAPL, oeGateway->getActorId(), mdActor->getActorId(), chActor->getActorId());
|
| 77 |
auto bookMSFT = std::make_unique<MECoreActor>(
|
|
|
|
| 86 |
oeGateway->mapSymbol(SYM_GOOGL, bookGOOGL->getActorId());
|
| 87 |
oeGateway->mapSymbol(SYM_EURO50, bookEURO50->getActorId());
|
| 88 |
|
| 89 |
+
// --Core 0: FIX Gateway --------------------------------------
|
| 90 |
auto fixGateway = std::make_unique<FIXAcceptorActor>(oeGateway->getActorId(), 9001);
|
| 91 |
|
| 92 |
+
// --Core 3: AI Trader -----------------------------------------
|
| 93 |
auto aiTrader = std::make_unique<AITraderActor>(oeGateway->getActorId(), allSymbols);
|
| 94 |
|
| 95 |
+
// --Wire exec report subscribers ------------------------------
|
| 96 |
oeGateway->addExecReportSubscriber(fixGateway->getActorId());
|
| 97 |
oeGateway->addExecReportSubscriber(aiTrader->getActorId());
|
| 98 |
|
| 99 |
+
// --Print topology --------------------------------------------
|
| 100 |
std::cout << "Actor topology:\n";
|
| 101 |
std::cout << " Core 0: OEG (id=" << oeGateway->getActorId().id
|
| 102 |
<< "), FIXAcceptor (id=" << fixGateway->getActorId().id << ")\n";
|
|
|
|
| 113 |
std::cout << " AI Traders: 10 members (MBR01-MBR10)\n";
|
| 114 |
std::cout << " Symbols: AAPL, MSFT, GOOGL, EURO50\n\n";
|
| 115 |
|
| 116 |
+
// --Seed initial orders for AI to have market data ------------
|
| 117 |
std::cout << "Seeding initial order book...\n";
|
| 118 |
SessionId_t seedSession = 200;
|
| 119 |
|
|
|
|
| 138 |
|
| 139 |
std::cout << "Initial orders seeded.\n\n";
|
| 140 |
|
| 141 |
+
// --Run AI trading rounds -------------------------------------
|
| 142 |
std::cout << "Running AI trading... (Ctrl+C to stop)\n";
|
| 143 |
std::cout << "FIX clients can connect to localhost:9001\n\n";
|
| 144 |
|
|
|
|
| 148 |
round++;
|
| 149 |
|
| 150 |
if (round % 10 == 0) {
|
| 151 |
+
std::cout << "--Round " << round << " --\n";
|
| 152 |
|
| 153 |
auto leaderboard = chActor->getLeaderboard();
|
| 154 |
std::cout << " Leaderboard:\n";
|
|
|
|
| 185 |
std::this_thread::sleep_for(std::chrono::seconds(3));
|
| 186 |
}
|
| 187 |
|
| 188 |
+
// --Shutdown --------------------------------------------------
|
| 189 |
std::cout << "\nShutting down...\n";
|
| 190 |
fixGateway->stop();
|
| 191 |
|
| 192 |
+
std::cout << "\n--Final Market Data ---------------------\n";
|
| 193 |
for (auto sym : allSymbols) {
|
| 194 |
auto* snap = mdActor->getSnapshot(sym);
|
| 195 |
if (snap) {
|
|
|
|
| 199 |
}
|
| 200 |
}
|
| 201 |
|
| 202 |
+
std::cout << "\n--Final Leaderboard ---------------------\n";
|
| 203 |
auto lb = chActor->getLeaderboard();
|
| 204 |
for (auto& e : lb) {
|
| 205 |
std::cout << " " << e.name
|
|
|
|
| 210 |
}
|
| 211 |
|
| 212 |
std::cout << "\nTrades processed: " << mdActor->getRecentTrades().size() << "\n";
|
| 213 |
+
std::cout << "===========================================\n";
|
| 214 |
std::cout << " Engine stopped.\n";
|
| 215 |
return 0;
|
| 216 |
}
|