This project is part of a complete end-to-end trading system:
- Main Repository: fpga-trading-systems
- Project Number: 26 of 30
- Category: C++ Application
- Dependencies: Project 25 (Market Maker - order input)
Platform: Linux Technology: C++20, LMAX Disruptor, spdlog, nlohmann/json Status: Completed
Project 26 implements a simulated order execution engine that consumes trading orders from Project 25 (Market Maker FSM) via Disruptor IPC and generates simulated fills with configurable latency. This provides a complete trading loop for testing without real exchange connectivity.
Data Flow:
Project 25 (Market Maker)
↓ Disruptor IPC (/dev/shm/order_ring_mm)
Project 26 (Order Execution) ← YOU ARE HERE
↓ Simulated Fill (configurable latency)
↓ Disruptor IPC (/dev/shm/fill_ring_oe)
Project 25 (Position Update)
Key Features:
- Disruptor-Only IPC: Pure shared memory, no TCP/network dependencies
- Configurable Latency: Simulate real exchange latency (default 50 μs)
- Fill Probability: Configure fill ratio and partial fill probability
- Lock-Free: LMAX Disruptor pattern for ultra-low-latency IPC
┌─────────────────────────────────────────────────────────────────┐
│ Project 25 (Market Maker FSM) │
│ Disruptor Consumer ← Quote Generation → Order Producer │
└────────────────────────┬────────────────────────────────────────┘
│
POSIX Shared Memory (/dev/shm/order_ring_mm)
Ring Buffer: 1024 entries × 128 bytes = 131 KB
Lock-Free IPC: Atomic sequence numbers (~0.50 μs)
Contains: OrderRequest (symbol, side, price, qty)
│
┌────────────────────────┴────────────────────────────────────────┐
│ Project 26: Order Execution Engine │
│ │
│ ┌────────────────┐ ┌──────────────────────────┐ │
│ │ Order │────→│ Order Validator │ │
│ │ Consumer │ │ (Check symbol, price) │ │
│ │ (Disruptor) │ │ │ │
│ └────────────────┘ └──────────┬───────────────┘ │
│ │ │
│ ↓ │
│ ┌──────────────────┐ │
│ │ Simulated Fill │ │
│ │ Generator │ │
│ │ (50 μs latency) │ │
│ └──────────┬───────┘ │
│ │ │
│ ↓ │
│ ┌──────────────────┐ │
│ │ Fill Producer │ │
│ │ (Disruptor) │ │
│ └──────────┬───────┘ │
│ │ │
└────────────────────────────────────┼─────────────────────────────┘
│
POSIX Shared Memory (/dev/shm/fill_ring_oe)
Ring Buffer: 1024 entries × 128 bytes = 131 KB
Lock-Free IPC: Fills back to Project 25
│
┌────────────────────────────────────┼─────────────────────────────┐
│ ↓ │
│ Project 25: Position & PnL Update │
└──────────────────────────────────────────────────────────────────┘
Reads orders from Project 25 via Disruptor:
- Input:
OrderRequestfrom/dev/shm/order_ring_mm - Validation: Check symbol, price, quantity
- Latency: ~0.5 μs (lock-free poll)
Generates realistic fills with configurable behavior:
- Latency: Configurable delay (default 50 μs)
- Fill Probability: 100% by default (always fills)
- Partial Fills: Optional 10% partial fill probability
- Price: Uses order price (limit orders) or last market price
Simulation Modes:
- Full Fill: Order is completely filled at requested price
- Partial Fill: Order partially filled, remainder cancelled
- Reject: Order rejected (configurable reject rate)
Publishes fill notifications back to Project 25:
- Output:
FillNotificationto/dev/shm/fill_ring_oe - Contents: Order ID, fill quantity, fill price, timestamp
- Latency: ~0.5 μs (lock-free publish)
config.json:
{
"log_level": "info",
"disruptor": {
"order_queue_path": "order_ring_mm",
"fill_queue_path": "fill_ring_oe"
},
"simulation": {
"latency_us": 50,
"fill_probability": 1.0,
"partial_fill_probability": 0.1
},
"performance": {
"enable_rt": false,
"cpu_cores": [6, 7]
}
}| Parameter | Type | Description | Default |
|---|---|---|---|
log_level |
string | Log level: trace, debug, info, warn, error | info |
disruptor.order_queue_path |
string | Shared memory path for order input | order_ring_mm |
disruptor.fill_queue_path |
string | Shared memory path for fill output | fill_ring_oe |
simulation.latency_us |
int | Simulated exchange latency in microseconds | 50 |
simulation.fill_probability |
float | Probability of order being filled (0.0-1.0) | 1.0 |
simulation.partial_fill_probability |
float | Probability of partial fill (0.0-1.0) | 0.1 |
performance.enable_rt |
bool | Enable real-time scheduling | false |
performance.cpu_cores |
array | CPU cores for thread affinity | [6, 7] |
- Linux (Ubuntu 22.04+ recommended)
- GCC 11+ or Clang 14+ (C++20 support)
- CMake 3.20+
# Install vcpkg dependencies
vcpkg install spdlog nlohmann-jsoncd 26-order-execution
mkdir build
cd build
cmake ..
make -j$(nproc)order_execution_engine: Main execution engine
# Run with default config.json
./order_execution_engine
# Run with custom config file
./order_execution_engine /path/to/config.json
# With RT optimizations (requires CAP_SYS_NICE)
sudo setcap cap_sys_nice=eip ./order_execution_engine
./order_execution_enginestruct OrderRequest {
char order_id[32]; // Unique order ID
char symbol[16]; // Symbol (e.g., "AAPL")
char side; // 'B' = Buy, 'S' = Sell
char order_type; // 'L' = Limit, 'M' = Market
double price; // Limit price
uint32_t quantity; // Shares
int64_t timestamp_ns; // Creation timestamp
bool valid;
};struct FillNotification {
char order_id[32]; // Original order ID
char exec_id[32]; // Execution ID
char symbol[16]; // Symbol
char side; // 'B' = Buy, 'S' = Sell
uint32_t fill_qty; // Shares filled
double fill_price; // Fill price
int64_t transact_time; // Fill timestamp
bool is_complete; // Fully filled?
bool valid;
};| Stage | Latency | Notes |
|---|---|---|
| Order Consumer (Disruptor poll) | ~0.5 μs | Lock-free read |
| Order Validation | < 0.1 μs | Simple checks |
| Simulated Latency | 50 μs | Configurable |
| Fill Generation | < 0.1 μs | Simple logic |
| Fill Producer (Disruptor publish) | ~0.5 μs | Lock-free write |
| Total Processing | ~51 μs | With default latency |
| Path | Latency | Notes |
|---|---|---|
| P25 → P26 (Order IPC) | ~0.5 μs | Disruptor |
| P26 Processing | ~51 μs | With 50 μs sim latency |
| P26 → P25 (Fill IPC) | ~0.5 μs | Disruptor |
| Total Round-Trip | ~52 μs | Order to fill |
[info] Order Execution Engine starting...
[info] Loaded config from config.json
[info] Simulation latency: 50 μs
[info] Fill probability: 100%
[info] Partial fill probability: 10%
[info] Connected to order ring: /dev/shm/order_ring_mm
[info] Connected to fill ring: /dev/shm/fill_ring_oe
[info] Order Execution Engine running...
[debug] Received order: ORD001 BUY 100 AAPL @ 150.50
[debug] Simulating 50 μs exchange latency...
[info] Generated fill: ORD001 BUY 100 AAPL @ 150.50 (FULL)
[debug] Published fill to ring buffer
[debug] Received order: ORD002 SELL 200 TSLA @ 275.00
[debug] Simulating 50 μs exchange latency...
[info] Generated fill: ORD002 SELL 180 TSLA @ 275.00 (PARTIAL)
[debug] Published fill to ring buffer
^C
[info] Shutdown signal received
[info] Processed 1,000 orders, 1,000 fills
[info] Order Execution Engine stopped
26-order-execution/
├── config.json # Configuration file
├── CMakeLists.txt # Build configuration
├── src/
│ └── order_execution_engine.cpp # Main execution engine
├── include/
│ └── (uses common/ headers)
└── vcpkg.json # Dependency manifest
Common Files (Shared with P25):
common/
├── order_data.h # OrderRequest, FillNotification
└── disruptor/
├── OrderRingBuffer.h # Order IPC
└── FillRingBuffer.h # Fill IPC
- 23-order-book/ - FPGA order book (PCIe source)
- 24-order-gateway/ - Order Gateway (BBO + XGBoost)
- 25-market-maker/ - Market Maker FSM (order producer)
- 28-complete-system/ - System Orchestrator
FPGA (Project 23)
↓ PCIe Gen2 x4 (/dev/xdma0_c2h_0)
Project 24 (Order Gateway)
├─ PCIeListener (56-byte BBO packets with magic header)
├─ BBOValidator (filter invalid data)
└─ Disruptor Producer (raw BBO)
↓ Disruptor IPC (/dev/shm/bbo_ring_gateway)
↓ Raw BBO Data
Project 25 (Market Maker FSM)
├─ Disruptor Consumer (raw BBO)
├─ XGBoost GPU Predictor (81% accuracy, ~10-100μs)
├─ Fair Value Calculation
├─ Quote Generation (with prediction-based edge)
├─ Risk Management
└─ Order Producer → P26
↓ Disruptor IPC (/dev/shm/order_ring_mm)
Project 26 (Order Execution) ← YOU ARE HERE
↓ Simulated Fills
↓ Disruptor IPC (/dev/shm/fill_ring_oe)
Project 25 (receives fills)
└─ Position & PnL Updates
Phase 1 (Current):
- Simulated fills with configurable latency
- Disruptor IPC integration
- Full/partial fill support
Phase 2 (Planned):
- FPGA-based order execution
- Real exchange connectivity (FIX protocol)
- Multi-venue support
Build Time: ~10 seconds Hardware Status: Tested with P25 order producer