A comprehensive trade capture and risk management system built with Spring Boot, Kafka, and React.
┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐
│ React │ │ Spring Boot │ │ Kafka │
│ Dashboard │◄──►│ Backend │◄──►│ Message Bus │
└─────────────────┘ └─────────────────┘ └─────────────────┘
│
▼
┌─────────────────┐
│ H2 Database │
│ (In-Memory) │
└─────────────────┘
- Trade Capture Service: REST API to record trades
- Risk & Limits Engine: Real-time exposure and PnL calculation
- Alerts Service: Store and query risk alerts
- Real-time Dashboard: WebSocket-powered React frontend
- Position Management: Track trader positions across symbols
- Limit Monitoring: Position, PnL, counterparty, and concentration limits
- Java 21+
- Maven 3.6+
- Kafka (local or Docker)
Using Docker:
docker run -p 9092:9092 apache/kafka:3.6.0Or using local Kafka installation:
# Start Zookeeper
bin/zookeeper-server-start.sh config/zookeeper.properties
# Start Kafka
bin/kafka-server-start.sh config/server.properties# Navigate to project directory
cd sentinel
# Build the project
mvn clean install
# Run the application
mvn spring-boot:runThe application will start on http://localhost:8080
Open your browser and navigate to:
- Dashboard: http://localhost:8080
- H2 Console: http://localhost:8080/h2-console
- JDBC URL:
jdbc:h2:mem:testdb - Username:
sa - Password: (leave empty)
- JDBC URL:
- Start the application (see Setup above)
- Run the test script:
chmod +x test-trades.sh ./test-trades.sh
curl -X POST http://localhost:8080/trades \
-H "Content-Type: application/json" \
-d '{
"trader": "alice",
"symbol": "AAPL",
"quantity": 100,
"price": 150.50,
"side": "BUY",
"counterparty": "broker1"
}'curl http://localhost:8080/api/alertscurl http://localhost:8080/api/positionsPOST /trades- Create a new tradeGET /trades- List all trades
GET /api/alerts- Get all alertsPUT /api/alerts/{id}/acknowledge- Acknowledge an alert
GET /api/positions- Get all positions
risk.position.limit=1000 # Max position size
risk.daily.stoploss=-100000 # Daily stop loss threshold
risk.counterparty.limit=10000000 # Max counterparty exposure
risk.concentration.max=0.4 # Max symbol concentrationtrade-created- New trades published herelimit-breached- Risk limit breaches published here
id,trader,symbol,quantity,priceside(BUY/SELL),timestamp,tradeId,counterparty
id,trader,symbol,quantity
id,breachId,limitType,trader,symbolactualValue,threshold,status,severity
- Trade Creation: Trade posted to
/tradesendpoint - Event Publishing:
TradeCreatedevent published to Kafka - Risk Processing: Risk engine processes trade and calculates exposures
- Limit Checking: System checks against configured risk limits
- Alert Generation: Limit breaches published as
LimitBreachedevents - Real-time Updates: Dashboard receives alerts via WebSocket
- Position Limit: Maximum position size per symbol
- PnL Stop Loss: Daily loss threshold
- Counterparty Exposure: Maximum exposure to any counterparty
- Concentration Limit: Maximum percentage in any single symbol
- LOW: Minor limit exceedance
- MEDIUM: Moderate limit exceedance
- HIGH: Significant limit exceedance
- CRITICAL: Severe limit exceedance
- This is a demo system - not production ready
- H2 database is in-memory and resets on restart
- No authentication/authorization implemented
- Kafka topics are not secured
-
Kafka Connection Failed
- Ensure Kafka is running on localhost:9092
- Check if Kafka topics exist
-
WebSocket Connection Failed
- Verify application is running on port 8080
- Check browser console for errors
-
No Alerts Generated
- Verify risk limits are configured correctly
- Check if trades are being processed
Check application logs for detailed error information:
tail -f logs/spring.logThis project is for educational/demo purposes.
Sentinel provides automatic real-time updates without requiring manual refresh:
- Trades: New trades appear instantly via WebSocket
- Positions: Position changes update immediately when trades execute
- Risk Alerts: New alerts appear in real-time when limits are breached
- Market Data: Refreshes automatically every 30 seconds
- Risk Metrics: Recalculates automatically when alerts/positions change
- STOMP over SockJS: Full-duplex communication with Spring Boot
- Auto-reconnection: Handles connection drops gracefully
- Topic subscriptions:
/topic/trades,/topic/positions,/topic/alerts - Real-time status: Header shows connection status (Connected/Disconnected)
Each dashboard section still includes refresh buttons (↻) for manual updates:
- Force fresh market data (bypasses cache)
- Refresh specific sections on demand
- Visual feedback with spinning icons