Contents
- 1. Overview
- 2. Architecture
- 3. Modules
- 4. Database Persistence
- 5. Data Flow Diagrams
- 6. Kafka Topics
- 7. Message Formats
- 8. SSE Events
- 9. Configuration
- 10. Development
1. Overview
StockEx is a real-time trading simulation platform providing complete order-to-trade lifecycle emulation. Built with microservices architecture using Docker containers.
Core Features
- FIX 4.4 protocol gateway
- Price-time priority matching
- Kafka event streaming
- SSE real-time dashboard
- SQLite persistence
Tech Stack
- Python 3.11 / Flask
- QuickFIX/Python
- Apache Kafka 7.5
- Docker Compose
- SQLite
2. System Architecture
┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐
│ FIX UI Client │ │ FIX UI Client │ │ Frontend │
│ (Port 5002) │ │ (Port 5003) │ │ (Port 5000) │
└────────┬────────┘ └────────┬────────┘ └────────┬────────┘
│ FIX 4.4 │ FIX 4.4 │ HTTP/JSON
└───────────────┬───────┴───────────────────────┘
▼
┌───────────────────────────────┐
│ FIX OEG (Port 5001) │
│ QuickFIX Order Gateway │
└───────────────┬───────────────┘
│ JSON
▼
┌────────────────────────────────────────────────────────────────────┐
│ APACHE KAFKA (Port 9092) │
│ ┌──────────┐ ┌──────────┐ ┌──────────┐ │
│ │ orders │ │ trades │ │ snapshots│ │
│ └──────────┘ └──────────┘ └──────────┘ │
└─────┬─────────────────┬─────────────────┬─────────────────────────┘
│ │ │
▼ │ ▼
┌─────────────┐ │ ┌─────────────┐
│ Matcher │─────────┘ │ MD Feeder │
│ (Port 6000) │ │ (MDF) │
│ │ │ │
│ Order Book │◄──────────────────│ Price Sim │
│ Trade Exec │ │ BBO Publish │
└─────────────┘ └─────────────┘
│
▼ REST API
┌─────────────────────────────────────────┐
│ Dashboard (Port 5005) │
│ Orders │ Trades │ Book │ Chart │ Stats │
└─────────────────────────────────────────┘
3. Module Specifications
Kafka Message Broker
9092 29092 (host) Confluent 7.5.0
Central event bus. All order flow distributed via topics. Zookeeper (port 2181) for coordination.
FIX Order Entry Gateway
5001 QuickFIX/Python
FIX 4.4 acceptor. Receives NewOrderSingle (D), OrderCancelRequest (F), OrderCancelReplaceRequest (G). Normalizes to JSON → Kafka orders.
Matcher Engine
6000 Python/Flask/SQLite
Consumes orders, matches with price-time priority, publishes trades. Maintains order book per symbol. SQLite persistence.
| Endpoint | Method | Description |
| /orderbook/<symbol> | GET | Order book depth |
| /trades | GET | Recent trades |
| /health | GET | Health + stats |
Market Data Feeder (MDF)
Python
Simulates market activity. 90% passive orders (book building), 10% aggressive (trades). Publishes BBO snapshots.
Output: orders + snapshots topics
Dashboard
5005 Flask/SSE/JavaScript
Real-time web UI. Consumes Kafka + Matcher API. Server-Sent Events for live streaming. Edit/Cancel order management.
| Endpoint | Method | Description |
| /stream | GET | SSE event stream |
| /data | GET | Polling fallback |
| /order/cancel | POST | Cancel order |
| /order/amend | POST | Amend order |
FIX UI Clients
5002 5003 QuickFIX/Flask
Web-based FIX initiators. Connect to FIX OEG for institutional order submission.
4. Database Persistence
Storage: SQLite database at /app/data/matcher.db
Docker Volume: stockex_matcher_data (survives container restarts)
4.1 Database Schema
order_book — All Orders
| Column | Type | Description |
id | INTEGER | Auto-increment primary key |
cl_ord_id | TEXT | Unique client order ID |
symbol | TEXT | Security (ALPHA, EXAE, etc.) |
side | TEXT | BUY / SELL |
price | REAL | Limit price |
quantity | INTEGER | Original order quantity |
remaining_qty | INTEGER | Unfilled quantity |
status | TEXT | OPEN / FILLED / CANCELLED |
timestamp | REAL | Order entry time (Unix) |
created_at | DATETIME | DB insert timestamp |
trades — Executed Trades
| Column | Type | Description |
id | INTEGER | Auto-increment primary key |
symbol | TEXT | Traded security |
price | REAL | Execution price |
quantity | INTEGER | Traded quantity |
buy_order_id | TEXT | Buyer's cl_ord_id |
sell_order_id | TEXT | Seller's cl_ord_id |
timestamp | REAL | Trade time (Unix) |
created_at | DATETIME | DB insert timestamp |
4.2 Database Functions
| Function | Description |
save_order(order) | Insert new order into order_book |
update_order_quantity(id, qty) | Update remaining_qty after partial fill |
cancel_order(cl_ord_id) | Set status = 'CANCELLED' |
save_trade(trade) | Insert executed trade |
get_open_orders(symbol, side) | Query open orders for matching |
load_order_books() | Restore order books on startup |
get_trades(symbol, limit) | Retrieve recent trades |
delete_filled_orders(days) | Cleanup old filled/cancelled orders |
4.3 Indexes
CREATE INDEX idx_trades_symbol ON trades(symbol);
CREATE INDEX idx_trades_timestamp ON trades(timestamp);
CREATE INDEX idx_orderbook_symbol_side ON order_book(symbol, side);
CREATE INDEX idx_orderbook_status ON order_book(status);
CREATE INDEX idx_orderbook_cl_ord_id ON order_book(cl_ord_id);
5. Data Flow Diagrams
4.1 Order Entry Flow
┌──────────────┐
│ FIX Client │
└──────┬───────┘
│ FIX 4.4 NewOrderSingle (35=D)
▼
┌──────────────┐
│ FIX OEG │ Validate → Normalize → Generate cl_ord_id
└──────┬───────┘
│ JSON
▼
┌──────────────┐
│ Kafka │ Topic: orders
│ [orders] │
└──────┬───────┘
│
┌─────┴─────┐
▼ ▼
┌────────┐ ┌───────────┐
│Matcher │ │ Dashboard │
└────────┘ └───────────┘
4.2 Order Matching Flow
┌─────────────────┐
│ Incoming Order │
│ (from Kafka) │
└────────┬────────┘
│
▼
┌─────────────────┐
│ Parse & Validate│
└────────┬────────┘
│
┌──────────────┴──────────────┐
▼ ▼
┌────────────┐ ┌────────────┐
│ BUY Order │ │ SELL Order │
└──────┬─────┘ └──────┬─────┘
│ │
▼ ▼
┌──────────────────┐ ┌──────────────────┐
│ Check SELL book │ │ Check BUY book │
│ for price ≤ bid │ │ for price ≥ ask │
└────────┬─────────┘ └────────┬─────────┘
│ │
┌──────┴──────┐ ┌──────┴──────┐
▼ ▼ ▼ ▼
┌───────┐ ┌────────┐ ┌───────┐ ┌────────┐
│ Match │ │No Match│ │ Match │ │No Match│
│ Found │ │ │ │ Found │ │ │
└───┬───┘ └───┬────┘ └───┬───┘ └───┬────┘
│ │ │ │
▼ ▼ ▼ ▼
┌───────┐ ┌────────┐ ┌───────┐ ┌────────┐
│Execute│ │Add to │ │Execute│ │Add to │
│ Trade │ │BUY Book│ │ Trade │ │SELLBook│
└───┬───┘ └────────┘ └───┬───┘ └────────┘
│ │
└───────────┬───────────────┘
▼
┌────────────┐
│Kafka:trades│
└────────────┘
4.3 Real-time Dashboard Flow
┌─────────────────────────────────────────────────────────────────┐
│ BROWSER │
│ ┌─────────────────────────────────────────────────────────┐ │
│ │ Dashboard UI │ │
│ │ ┌─────────┐ ┌─────────┐ ┌─────────┐ ┌─────────────────┐│ │
│ │ │ Orders │ │ Trades │ │ Book │ │ Statistics ││ │
│ │ └────▲────┘ └────▲────┘ └────▲────┘ └────────▲────────┘│ │
│ └───────┼───────────┼───────────┼───────────────┼──────────┘ │
│ │ │ │ │ │
│ └───────────┴─────┬─────┴───────────────┘ │
│ │ │
│ ┌───────▼────────┐ │
│ │ EventSource │ SSE Connection │
│ │ /stream │ │
│ └───────┬────────┘ │
└────────────────────────────┼────────────────────────────────────┘
│ HTTP (SSE)
▼
┌────────────────────────────────────────────────────────────────┐
│ DASHBOARD SERVER │
│ │
│ ┌──────────────┐ ┌──────────────┐ ┌────────────┐ │
│ │Kafka Consumer│─────▶│ SSE Broadcast│────▶│ Clients │ │
│ │ (orders, │ │ Queue │ │ Queue[] │ │
│ │ trades, │ └──────────────┘ └────────────┘ │
│ │ snapshots) │ │
│ └──────────────┘ │
│ │
│ ┌──────────────┐ ┌──────────────┐ │
│ │ REST API │◀────▶│ Matcher │ /orderbook, /trades │
│ │ /data │ │ Proxy │ │
│ └──────────────┘ └──────────────┘ │
└────────────────────────────────────────────────────────────────┘
4.4 Complete System Interaction
┌─────────┐ ┌─────────┐ ┌─────────┐
│FIX Cli 1│ │FIX Cli 2│ │Frontend │
└────┬────┘ └────┬────┘ └────┬────┘
│ │ │
└─────┬─────┴───────────┘
│
▼
┌─────────────┐
│ FIX OEG │◄──── FIX 4.4 Protocol
└──────┬──────┘
│
▼
┌────────────────────────────────────┐
│ KAFKA CLUSTER │
│ ┌────────┐┌────────┐┌──────────┐ │
│ │orders ││trades ││snapshots │ │
│ └───┬────┘└───▲────┘└────▲─────┘ │
└──────┼─────────┼──────────┼───────┘
│ │ │
┌─────┼─────────┼──────────┼─────┐
│ ▼ │ │ │
│ ┌────────┐ │ │ │
│ │MATCHER │────┘ │ │
│ │ │ │ │
│ │ Book │ │ │
│ │ Match │ │ │
│ │ Trade │ │ │
│ └────────┘ │ │
│ ▲ │ │
│ │ REST │ │
│ │ │ │
│ ┌───┴────────────────────┴──┐ │
│ │ DASHBOARD │ │
│ │ (SSE + Kafka Consumer) │ │
│ └───────────────────────────┘ │
│ │
│ ┌───────────────────────────┐ │
│ │ MD FEEDER (MDF) │──┘
│ │ Orders + Snapshots │
│ └───────────────────────────┘
│ DOCKER NETWORK
└────────────────────────────────┘
4.5 Message Sequence: New Order to Trade
FIX Client FIX OEG Kafka Matcher Dashboard
│ │ │ │ │
│──35=D────▶│ │ │ │
│NewOrder │ │ │ │
│ │──JSON────▶│ │ │
│ │ [orders] │ │ │
│ │ │──consume──▶│ │
│ │ │ │ │
│ │ │ │──match() │
│ │ │ │ │
│ │ │◀──trade────│ │
│ │ │ [trades] │ │
│ │ │ │ │
│ │ │──────────────consume───▶│
│ │ │ │ │
│ │ │ │ render()
│ │ │ │ │
6. Kafka Topics
| Topic | Producers | Consumers | Content |
orders | FIX OEG, MDF, Frontend | Matcher, Dashboard | New/Cancel/Amend orders |
trades | Matcher | Dashboard, Consumer | Executed trades |
snapshots | MDF | Dashboard | BBO updates |
7. Message Formats
Order (New)
{
"symbol": "ALPHA",
"side": "BUY",
"price": 25.50,
"quantity": 100,
"cl_ord_id": "MDF-1234567890-1",
"timestamp": 1234567890.123,
"source": "MDF"
}
Order (Cancel)
{
"type": "cancel",
"orig_cl_ord_id": "MDF-1234567890-1",
"symbol": "ALPHA",
"timestamp": 1234567890.456
}
Order (Amend)
{
"type": "amend",
"orig_cl_ord_id": "MDF-1234567890-1",
"cl_ord_id": "amend-1234567890",
"symbol": "ALPHA",
"quantity": 150,
"price": 25.45,
"timestamp": 1234567890.789
}
Trade
{
"symbol": "ALPHA",
"price": 25.50,
"quantity": 100,
"buy_order_id": "order-123",
"sell_order_id": "order-456",
"timestamp": 1234567890.123
}
Snapshot (BBO)
{
"symbol": "ALPHA",
"best_bid": 25.45,
"best_ask": 25.55,
"bid_size": 500,
"ask_size": 300,
"timestamp": 1234567890.123,
"source": "MDF"
}
8. SSE Events
| Event | Data | Trigger |
connected | {status} | Client connects |
init | {orders, bbos, trades} | Initial state dump |
order | Order JSON | New order received |
trade | Trade JSON | Trade executed |
snapshot | BBO JSON | Price update |
9. Configuration
| Variable | Default | Description |
KAFKA_BOOTSTRAP | kafka:9092 | Broker address |
MATCHER_URL | http://matcher:6000 | Matcher API |
TICK_SIZE | 0.05 | Min price increment |
ORDERS_PER_MIN | 8 | MDF rate |
KAFKA_RETRIES | 30 | Connection retries |
Securities (shared_data/securities.txt)
#SYMBOL start_price current_price
ALPHA 25.00 25.00
EXAE 42.00 42.00
PEIR 18.50 18.50
QUEST 12.75 12.75
10. Development Commands
Build & Run
docker compose up --build # Start all
docker compose up -d --build # Background
docker compose logs -f dashboard # Follow logs
docker compose down # Stop all
Reset Data
docker compose down
docker volume rm stockex_matcher_data
docker compose up -d
Container Access
docker exec -it matcher bash
docker exec -it dashboard bash
docker logs matcher --tail 50
API Testing
curl http://localhost:6000/orderbook/ALPHA
curl http://localhost:6000/trades
curl http://localhost:5005/data
StockEx Trading Dashboard - Real-time Market View