title: EuNEx
emoji: π
colorFrom: green
colorTo: blue
sdk: docker
app_port: 7860
pinned: false
EuNEx β Euronext Optiq Architecture Learning Project
C++ actor-based matching engine that mirrors the Euronext Optiq architecture, ported from the StockEx Python prototype.
Architecture Mapping
StockEx (Python/Kafka) EuNEx (C++/Simplx) Optiq (Production)
βββββββββββββββββββββ ββββββββββββββββββ ββββββββββββββββββ
fix_oeg_server.py β OEGActor β OEActor
Kafka 'orders' topic β Event::Pipe β Simplx Event::Pipe
matcher.py β MECoreActor β LogicalCoreActor + Book
match_order() β Book::newOrder() β RecoveryCause β IACA Cause β forwardToBook
handle_cancel() β Book::cancelOrder() β CancelOrderData
handle_amend() β Book::modifyOrder() β ModifyOrderData
Kafka 'trades' topic β TradeEvent via Pipe β IACA fragment chain
dashboard.py (SSE) β MDGActor β MDLimitLogicalCoreHandler
/orderbook/<sym> β BookUpdateEvent β PublishLimitUpdateRequest
/trades β TradeEvent β IACA β IA SBE message
database.py (SQLite) β RecoveryProxy (memory) β RecoveryProxy β Kafka
save_trade() β FragmentStore::append() β PersistenceAgent β Kafka produce
fix_oeg_server.py β FIXAcceptorActor β FIX 4.4 OEG Acceptor
NewOrderSingle β 35=D handling β Optiq FIX gateway
ExecutionReport β 35=8 response β Execution reports
ch_ai_trader.py β ClearingHouseActor β Clearing House (PTB path)
AI strategies β AITraderActor β Trading obligations
Actor Topology (v0.9)
Core 0: OEGActor + FIXAcceptorActor β Order entry & FIX protocol
Core 1: MECoreActor (per symbol) β Matching engine (Book)
Core 2: MDGActor β Market data snapshots
Core 3: ClearingHouseActor + AITrader β Post-trade & AI members
Dual Engine Architecture
The dashboard can run in two modes, switchable at runtime via a toggle in the UI:
βββββββββββββββββββββββββββββββββββββ
β Browser (:8090) β
β [Python ββββββ C++] toggle β
ββββββββββββββββ¬βββββββββββββββββββββ
β
ββββββββββββββββΌβββββββββββββββββββββ
β Dashboard (Flask :8090) β
β β
β ββββββββββββββ βββββββββββββββ β
β β Python ME β β C++ Bridge β β
β βMatchingEng β β FIX 4.4 TCP β β
β β(built-in) β β client β β
β ββββββββ¬ββββββ ββββββββ¬βββββββ β
β mode=python mode=cpp β
ββββββββββββββββββββββββββββΌβββββββββ
β FIX 4.4 TCP
βΌ
ββββββββββββββββββββββββββββββββββββββββ
β C++ Matching Engine β
β eunex_me (:9001) β
β β
β OEG β MECore β MDG β ClearingHouse β
β FIXAcceptorActor (TCP :9001) β
β Multi-threaded actors β
ββββββββββββββββββββββββββββββββββββββββ
| Mode | Engine | How orders are matched | Use case |
|---|---|---|---|
| Python | Built-in MatchingEngine |
In-process, same Flask app | Demo, learning, no compilation needed |
| C++ | eunex_me via FIX 4.4 |
TCP to C++ actors on port 9001 | Production-like, microsecond latency |
Service Architecture
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β nginx (:7860) β
β Reverse proxy (Docker) β
ββββββββββ¬ββββββββββββββββββββ¬ββββββββββββββββββββ¬βββββββββ
β β β
βΌ βΌ βΌ
βββββββββββββββββββ ββββββββββββββββββββ ββββββββββββββββββββ
β Dashboard β β Clearing House β β FIX Gateway β
β (:8090) β β (:8091) β β (:9001 TCP) β
β β β β β β
β Order Book β β 10 AI Members β β FIX 4.4 Acceptorβ
β Trade Charts β β Leaderboard β β NewOrder/Cancel β
β OHLCV History β β Portfolios β β Amend/ExecRpt β
β SQLite DB β β Settlements β β β
β SSE Streaming β β β β β
β Engine Switch β β LLM Trading β β β
ββββββββββ¬βββββββββ ββββββββββ¬βββββββββ ββββββββββ¬βββββββββ
β β β
βββββββββββββββββββββ΄βββββββββββββββββββββ
β
βΌ
βββββββββββββββββββββββββββββββ
β C++ Matching Engine β
β (eunex_me) β
β Multi-threaded actors β
β Price-time priority β
βββββββββββββββββββββββββββββββ
Quick Start (Linux)
# Install dependency
pip install flask
# Start all services (dashboard + FIX gateway + clearing house)
./run.sh
# Services:
# Dashboard: http://localhost:8090
# Clearing House: http://localhost:8091
# FIX Gateway: localhost:9001 (TCP)
# Stop all
./run.sh stop
# Check status
./run.sh status
Quick Start (Docker β Windows/Linux)
cd docker
docker compose up --build
# All services via nginx:
# Dashboard: http://localhost:7860
# Clearing House: http://localhost:7860/ch/
# Kafka: localhost:9092
Build C++ Engine
cmake -B build -DEUNEX_BUILD_TESTS=ON
cmake --build build --config Release
# Run matching engine (FIX server on port 9001)
./build/Release/eunex_me
# Run all tests (7 suites)
cd build && ctest -C Release
# Use with dashboard: start eunex_me, then toggle "C++" in the dashboard header
With Kafka Persistence
# Compile with Kafka support (requires librdkafka-dev)
cmake -B build -DEUNEX_USE_KAFKA=ON
cmake --build build --config Release
# Run with Kafka (set broker address)
EUNEX_KAFKA_BROKERS=localhost:9092 ./build/Release/eunex_me
# Topics: eunex.orders, eunex.trades, eunex.market-data, eunex.recovery.fragments
Without EUNEX_USE_KAFKA, the engine compiles with a no-op stub and runs standalone.
FIX Gateway
The C++ engine includes a built-in FIX 4.4 acceptor on TCP port 9001. A Python FIX gateway is also available:
python fix_gateway/fix_server.py
python fix_gateway/fix_server.py test
Supports: NewOrderSingle (35=D), OrderCancelRequest (35=F), OrderCancelReplaceRequest (35=G), ExecutionReport (35=8).
Configuration (.env)
All Python services auto-load settings from .env in the project root.
No extra packages needed β shared/config.py parses it at startup.
# .env β LLM and service configuration
LLM_PROVIDER=auto # ollama | groq | hf | auto (try all)
OLLAMA_HOST=http://localhost:11434
OLLAMA_MODEL=llama3.1
HF_MODEL=Qwen/Qwen2.5-7B-Instruct
# HF_TOKEN=hf_... # or auto-discovered from ~/.cache/huggingface/token
# GROQ_API_KEY=gsk_...
| Variable | Default | Description |
|---|---|---|
LLM_PROVIDER |
auto |
LLM backend: ollama, groq, hf, or auto (tries all in order) |
OLLAMA_HOST |
http://localhost:11434 |
Ollama server URL |
OLLAMA_MODEL |
llama3.1 |
Ollama model name |
HF_TOKEN |
(auto-discovered) | HuggingFace API token; reads ~/.cache/huggingface/token if not set |
HF_MODEL |
Qwen/Qwen2.5-7B-Instruct |
HuggingFace model (free tier) |
GROQ_API_KEY |
(empty) | Groq Cloud API key |
GROQ_MODEL |
llama-3.1-8b-instant |
Groq model name |
EUNEX_DASHBOARD_PORT |
8090 |
Dashboard HTTP port |
EUNEX_CH_PORT |
8091 |
Clearing House HTTP port |
EUNEX_FIX_PORT |
9001 |
FIX Gateway TCP port |
EUNEX_KAFKA_BROKERS |
localhost:9092 |
Kafka broker address |
AI Market Analyst
The Dashboard includes an AI-powered market analyst that generates real-time commentary on trading activity. It uses a fallback chain of LLM providers:
- Ollama (local) β best for development, requires Ollama installed
- Groq (cloud) β fast inference, requires
GROQ_API_KEY - HuggingFace (cloud) β free tier with
HF_TOKEN, uses Qwen 2.5 7B
The dashboard shows a green/red status dot and lets you select the active
Ollama model from a dropdown. Set LLM_PROVIDER=auto to try all providers
in order until one succeeds.
Clearing House
10 AI trading members (MBR01-MBR10) with 4 strategies:
- Momentum: follow price trends
- Mean Reversion: fade price moves
- Random: noise trading
- LLM: AI-driven decisions with natural language explanations (uses same provider chain)
Features: capital tracking, holdings per symbol, P&L, leaderboard, strategy selection per member, LLM trading explanations panel.
Project Structure
EuNEx/
βββ src/ # C++ matching engine
β βββ main.cpp # Entry point, actor wiring
β βββ engine/SimplxShim.hpp # Multi-threaded actor engine
β βββ common/
β β βββ Types.hpp # Price, Order, Trade, enums
β β βββ Book.hpp/cpp # Price-time priority matching
β βββ actors/
β β βββ Events.hpp # Inter-actor event types
β β βββ OEGActor.hpp/cpp # Order Entry Gateway
β β βββ MECoreActor.hpp/cpp # Matching Engine core (per symbol)
β β βββ MDGActor.hpp/cpp # Market Data Gateway
β β βββ FIXAcceptorActor.hpp/cpp # FIX 4.4 TCP acceptor
β β βββ ClearingHouseActor.hpp/cpp # Trade clearing & member positions
β β βββ AITraderActor.hpp/cpp # Automated trading members
β βββ net/SocketCompat.hpp # Cross-platform socket abstraction
β βββ persistence/
β β βββ PersistenceStore.hpp # Abstract store + InMemoryStore
β β βββ KafkaBus.hpp # Multi-topic Kafka publisher (Optiq KFK)
β β βββ KafkaStore.hpp # Kafka persistence (optional)
β βββ recovery/RecoveryProxy.hpp/cpp # Recovery Cause/Effect
β βββ iaca/
β βββ Fragment.hpp # IACA fragment definitions
β βββ IacaAggregator.hpp/cpp # Fragment chain aggregation
βββ dashboard/
β βββ app.py # Flask dashboard + matching engine
β βββ database.py # SQLite (orders, trades, OHLCV)
β βββ templates/index.html # Trading UI with Chart.js
βββ fix_gateway/
β βββ fix_server.py # Python FIX 4.4 TCP acceptor
βββ clearing_house/
β βββ app.py # Flask CH portal + API
β βββ ch_database.py # SQLite (members, holdings)
β βββ ch_ai_trader.py # AI trading strategies
β βββ templates/ # CH web UI
βββ .env # LLM and service configuration
βββ shared/config.py # Centralized configuration (auto-loads .env)
βββ docker/
β βββ docker-compose.yml # Kafka + EuNEx (all services)
β βββ Dockerfile # Multi-stage Linux build
β βββ nginx.conf # Reverse proxy configuration
βββ tests/
β βββ test_orderbook.cpp # Book unit tests (26 cases)
β βββ test_matching_engine.cpp # ME integration tests
β βββ test_threaded_engine.cpp # Multi-threaded engine tests
β βββ test_clearing_house.cpp # Clearing house tests (7 cases)
β βββ test_fix_gateway.cpp # FIX gateway tests (5 cases)
β βββ test_ai_trader.cpp # AI trader tests (6 cases)
βββ examples/
β βββ ping_pong.cpp # Actor basics tutorial
β βββ simple_match.cpp # Matching with Recovery + IACA
βββ docs/
βββ developers-guide.md # Detailed developers guide
βββ process-diagram.md # Architecture diagrams
Documentation
- Developers Guide β Detailed architecture, data flow, component reference
- Process Diagram β Optiq architecture diagrams and roadmap
Next Steps
Multi-threaded actor engineβ SimplxShim with mailbox queuesKafka persistenceβ KafkaStore + Docker Compose (KRaft mode)FIX gatewayβ C++ FIXAcceptorActor + Python fallbackClearing Houseβ ClearingHouseActor + AITraderActorMarket simulationβ Realistic AI trading + Dashboard auto-simulationAI Analystβ Ollama/Groq/HuggingFace market commentaryMessage Flow Visualizerβ Developer pipeline tracing toolEngine Mode Switchβ Python β C++ toggle with FIX 4.4 bridge- SBE encoding β replace event structs with SBE-encoded messages
- Master/Mirror failover β implement full Recovery replay on Mirror node
- Trading phases β pre-open, uncrossing, continuous, close, TAL
- Additional order types β Stop, Pegged, Mid-Point, Iceberg