StockEx Trading Platform

Developer & Technical Guide

Version 1.0 | Euronext OPTIQ Inspired

Contents

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.

EndpointMethodDescription
/orderbook/<symbol>GETOrder book depth
/tradesGETRecent trades
/healthGETHealth + 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.

EndpointMethodDescription
/streamGETSSE event stream
/dataGETPolling fallback
/order/cancelPOSTCancel order
/order/amendPOSTAmend 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

ColumnTypeDescription
idINTEGERAuto-increment primary key
cl_ord_idTEXTUnique client order ID
symbolTEXTSecurity (ALPHA, EXAE, etc.)
sideTEXTBUY / SELL
priceREALLimit price
quantityINTEGEROriginal order quantity
remaining_qtyINTEGERUnfilled quantity
statusTEXTOPEN / FILLED / CANCELLED
timestampREALOrder entry time (Unix)
created_atDATETIMEDB insert timestamp

trades — Executed Trades

ColumnTypeDescription
idINTEGERAuto-increment primary key
symbolTEXTTraded security
priceREALExecution price
quantityINTEGERTraded quantity
buy_order_idTEXTBuyer's cl_ord_id
sell_order_idTEXTSeller's cl_ord_id
timestampREALTrade time (Unix)
created_atDATETIMEDB insert timestamp

4.2 Database Functions

FunctionDescription
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

TopicProducersConsumersContent
ordersFIX OEG, MDF, FrontendMatcher, DashboardNew/Cancel/Amend orders
tradesMatcherDashboard, ConsumerExecuted trades
snapshotsMDFDashboardBBO 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

EventDataTrigger
connected{status}Client connects
init{orders, bbos, trades}Initial state dump
orderOrder JSONNew order received
tradeTrade JSONTrade executed
snapshotBBO JSONPrice update

9. Configuration

VariableDefaultDescription
KAFKA_BOOTSTRAPkafka:9092Broker address
MATCHER_URLhttp://matcher:6000Matcher API
TICK_SIZE0.05Min price increment
ORDERS_PER_MIN8MDF rate
KAFKA_RETRIES30Connection 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 Dashboard

StockEx Trading Dashboard - Real-time Market View