Professional-grade sports analytics system for football clubs
Real-time tactical insights from pitch to iPad in under 100ms
This platform transforms raw Opta F24 event data into actionable tactical intelligence for coaching staff during live matches. It monitors team performance against your club's "Style of Play" and alerts coaches when players drift from tactical instructions.
- Real-time Processing: Ingest Opta events at 25Hz with <50ms latency
- Tactical Intelligence: Automatically detect pressing breakdowns, verticality drops, and system drift
- Style-Fit Scoring: Evaluate potential signings against your tactical philosophy (0-100 scale)
- Live Visualization: Interactive 3D pitch map with player highlighting and tactical heatmaps
- Bench Integration: Push critical alerts directly to coaching staff's iPads
- Open-Source Data: Integrated StatsBomb, DataHub, and FBref data sources for analysis
- ML-Powered Analytics: Expected Goals (xG) models and tactical pattern recognition
Elite football clubs spend $100k+ annually on Opta data feeds, yet most tactical insights are lost in spreadsheets. This system bridges that gap by:
- Automating tactical analysis that previously required hours of manual video review
- Providing instant feedback to coaches during critical match moments
- Standardizing evaluation across scouts, analysts, and coaching staff
- Leveraging free data sources for comprehensive historical analysis
- Delivering insights at the speed of the game - not post-match analysis
The Tactical Intelligence Platform is a microservices architecture built for the demands of professional football analytics. It combines real-time event processing, machine learning models, and interactive visualizations to transform raw football data into actionable coaching insights.
┌─────────────────────────────────────────────────────────────┐
│ DATA LAYER │
│ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │
│ │ Opta F24 │ │ StatsBomb │ │ DataHub │ │
│ │ (Live) │ │ (Historical)│ │ (Results) │ │
│ └──────┬──────┘ └──────┬──────┘ └──────┬──────┘ │
└─────────┼────────────────┼────────────────┼─────────────────┘
│ │ │
▼ ▼ ▼
┌─────────────────────────────────────────────────────────────┐
│ PROCESSING LAYER │
│ ┌───────────────────────────────┐ ┌─────────────────────┐ │
│ │ GOLANG TACTICAL ENGINE │ │ PYTHON ANALYTICS │ │
│ │ • Real-time event processing │ │ • xG models │ │
│ │ • Tactical alert generation │ │ • Style-fit scoring │ │
│ │ • WebSocket streaming │ │ • ML predictions │ │
│ └──────────┬────────────────────┘ └─────────────────────┘ │
└─────────┼───────────────────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────┐
│ PRESENTATION LAYER │
│ ┌───────────────────────────────┐ ┌─────────────────────┐ │
│ │ REACT DASHBOARD │ │ MOBILE CLIENTS │ │
│ │ • 3D pitch visualization │ │ • iPad alerts │ │
│ │ • Live tactical metrics │ │ • Push notifications│ │
│ │ • Alert timeline │ │ • Quick insights │ │
│ └─────────────────────────────────┘ └─────────────────────┘ │
└─────────────────────────────────────────────────────────────┘
Backend Services:
- Go 1.25.6 - High-performance tactical engine with <50ms event processing
- Python 3.11+ - ML models using scikit-learn, pandas, and FastAPI
- TimescaleDB - Time-series database optimized for event data
- NATS JetStream - Real-time message broker for alert distribution
Frontend:
- React 18.3.1 with TypeScript 5.9.3 - Type-safe UI components
- Vite 8.0 - Lightning-fast development and builds
- TailwindCSS 4.0 - Utility-first styling with dark mode
- Three.js 0.171.0 - Interactive 3D pitch visualizations
- TanStack Query - Server state management and caching
Infrastructure:
- Docker & Docker Compose - Container orchestration
- Makefile - Service management and development workflows
- GitHub Actions - CI/CD pipeline for automated testing and deployment
The platform supports multiple data sources to provide comprehensive tactical analysis:
| Data Source | Type | Coverage | Cost | Use Case |
|---|---|---|---|---|
| Opta F24 | Live Events | All leagues, real-time | $100k+/year | Live match analysis |
| StatsBomb | Historical Events | 3,000+ matches | Free | Model training, historical analysis |
| DataHub | Match Results | 5 leagues (1993-2025) | Free | Season trends, opponent analysis |
| FBref | Advanced Stats | 50+ leagues | Free | Player scouting, team comparison |
| Metric | Performance | Target |
|---|---|---|
| Event Processing Latency | 12ms (p50), 48ms (p99) | <50ms |
| Alert Generation | 8ms average | <10ms |
| WebSocket Throughput | 500+ concurrent clients | 1000+ |
| Database Write Rate | 25,000 events/sec | 50,000+ |
| xG Calculation | 180ms per shot | <200ms |
| Style-Fit Score | 220ms per player | <250ms |
Real-Time Monitoring:
- Pressing Intensity - Track defensive line height and PPDA
- Verticality Analysis - Monitor forward pass ratios and angles
- System Adherence - Compare actual play vs tactical philosophy
- Player Performance - Individual tactical metrics and alerts
Historical Analysis:
- Pattern Recognition - Identify recurring tactical behaviors
- Opponent Scouting - Analyze opponent systems and weaknesses
- Trend Analysis - Track performance evolution over seasons
- Comparative Metrics - Benchmark against similar teams/styles
Scouting & Recruitment:
- Style-Fit Scoring - 0-100 grade on tactical alignment
- Position-Specific Analysis - Role-based performance metrics
- Transfer Market Intelligence - Data-driven player recommendations
- Squad Planning - Tactical balance and depth analysis
- Docker 24.0+ and Docker Compose 2.20+
- Bun 1.0+ or Node.js 20+ (for dashboard development)
- Go 1.25+ (for backend development)
- Python 3.11+ with uv (for analytics development)
# Clone repository
git clone https://github.com/nutcas3/tactical-system.git
cd tactical-system
# Configure environment
cp .env.example .env
# Start all services
docker-compose up -d
# Or use Makefile
make docker-up
# Verify deployment
docker-compose ps
# Access dashboard
open http://localhost:3000That's it! The system is now ready to receive event data.
tactical-system/
├── services/
│ ├── tactical-engine/ # Golang tactical processor
│ │ ├── cmd/api/main.go # Application entry point
│ │ ├── internal/ # Private implementation
│ │ │ ├── server.go # HTTP server and routing
│ │ │ ├── models/ # Data models (alerts, events)
│ │ │ ├── config/ # Configuration management
│ │ │ ├── processor/ # Tactical analysis engine
│ │ │ ├── ingestor/ # Event ingestion
│ │ │ ├── natsbridge/ # NATS publishing
│ │ │ ├── websocket/ # WebSocket server
│ │ │ └── datasource/ # Data source management
│ │ ├── pkg/ # Public API
│ │ │ ├── client/ # HTTP client library
│ │ │ └── models/ # Re-exported models
│ │ └── Dockerfile
│ │
│ ├── analytics/ # Python ML analytics
│ │ ├── main.py # FastAPI service
│ │ ├── services/ # Business logic
│ │ │ ├── models/ # ML models (xG, style-fit)
│ │ │ └── data/ # Data loaders (StatsBomb, FBref)
│ │ ├── routes/ # API endpoints
│ │ └── Dockerfile
│ │
│ └── dash/ # React dashboard
│ ├── src/
│ │ ├── components/ # UI components
│ │ │ ├── pitch3d/ # 3D pitch visualization
│ │ │ ├── AlertFeed.tsx
│ │ │ └── TacticalGauge.tsx
│ │ ├── hooks/ # React hooks
│ │ └── types/ # TypeScript types
│ ├── package.json
│ └── Dockerfile
│
├── config/
│ └── styles/ # Tactical style definitions (JSON)
├── db/
│ └── init.sql # TimescaleDB schema
├── Makefile # Service orchestration
├── docker-compose.yml # Container orchestration
└── .env.example # Environment template
Go Best Practices:
internal/packages for private implementation detailspkg/for public APIs and client libraries- Clean architecture with clear separation of concerns
- Dependency injection for testability and modularity
Python Best Practices:
- Layered architecture with services, models, and routes
- FastAPI for automatic API documentation and validation
- uv for fast dependency management
- Type hints throughout the codebase
React Best Practices:
- Component composition with reusable UI elements
- TypeScript for type safety and better developer experience
- TanStack Query for server state management
- Three.js integration for 3D visualizations
# Single event
curl -X POST http://localhost:8080/api/v1/events \
-H "Content-Type: application/json" \
-d '{
"id": 12345,
"type_id": 1,
"player_id": 10,
"team_id": 42,
"x": 45.0,
"y": 50.0,
"timestamp": "2024-02-15T20:45:32Z",
"qualifiers": [
{"qualifier_id": 140, "value": "55.0"},
{"qualifier_id": 141, "value": "70.0"}
]
}'curl -X POST http://localhost:8000/api/v1/style-fit \
-H "Content-Type: application/json" \
-d '{
"style": "gegenpressing",
"player": {
"player_id": 1001,
"player_name": "Target Midfielder",
"position": "CM",
"minutes_played": 2700,
"sprint_distance": 850.0,
"pressures": 280,
"progressive_passes": 180,
"avg_defensive_line": 62.0
}
}'curl -X POST http://localhost:8000/api/v1/xg \
-H "Content-Type: application/json" \
-d '{
"x": 95.0,
"y": 36.0,
"body_part": "right_foot",
"shot_type": "open_play",
"is_first_time": true,
"defenders_in_cone": 1
}'Edit config/styles/your_style.json:
{
"name": "High-Intensity Press",
"verticality_threshold": 15.0,
"pressing_height": 65.0,
"directness_index": 0.70,
"alert_thresholds": {
"pressing_breakdown": {
"metric": "defensive_line",
"value": 55.0,
"severity": "HIGH"
}
}
}Load custom style:
export DEFAULT_STYLE=your_style
docker-compose up -d| Metric | Description | Good Value |
|---|---|---|
| Verticality | % of passes moving ball forward (angle <45°) | >60% for direct styles |
| Pressing Height | Average Y-coordinate of defensive actions | >60m for high press |
| PPDA | Passes Per Defensive Action | <8 for intense press |
| Directness Index | Ratio of forward passes to total passes | 0.65+ for vertical play |
| Style Fit Score | 0-100 grade on system alignment | 85+ for starters |
┌─────────────────────────────────────────────────────────────┐
│ OPTA F24 FEED (XML/JSON) │
└────────────────────────┬────────────────────────────────────┘
│
▼
┌───────────────────────────────┐
│ GOLANG TACTICAL ENGINE │
│ • Parse Opta events │
│ • Calculate metrics │
│ • Generate alerts │
└──────────┬────────────────────┘
│
▼
┌─────────────────────┐
│ NATS JETSTREAM │
│ Pub/Sub Broker │
└──────┬──────────────┘
│
┌───────┴───────┐
▼ ▼
┌────────────┐ ┌──────────────────┐
│ TIMESCALE │ │ PYTHON ANALYTICS │
│ DATABASE │ │ • xG models │
│ • Events │ │ • Style scoring │
│ • Metrics │ │ • ML predictions │
└────────────┘ └──────────────────┘
│
▼
┌──────────────────────────────┐
│ REACT DASHBOARD │
│ • Live pitch map │
│ • Alert timeline │
│ • System adherence gauge │
└──────────────────────────────┘
Tactical Engine (Go):
cd services/tactical-engine
go mod download
go run cmd/api/main.goAnalytics Engine (Python):
cd services/analytics
uv sync # Fast dependency management
uv run python main.pyDashboard (React):
cd services/dash
bun install # or npm install
bun run dev # or npm run dev# Start all services with Makefile
make dev
# Start individual services
make start-tactical-engine
make start-analytics
make start-dashboard
# View logs
make logs-tactical-engine
make logs-analytics
make logs-dashboard
# Run tests
make test
make test-go
make test-python
make test-frontend
# Build for production
make build
make deployGo:
# Format and lint
cd services/tactical-engine
go fmt ./...
go vet ./...
golangci-lint run
# Run tests
go test ./... -v -race
go test ./... -coverPython:
# Format and lint
cd services/analytics
uv run ruff format .
uv run ruff check .
uv run mypy .
# Run tests
uv run pytest tests/ -v --covTypeScript/React:
# Type checking
cd services/dash
bun run type-check
# Linting
bun run lint
# Tests
bun run testBase URL: http://localhost:8080
POST /api/v1/events
Content-Type: application/json
{
"id": "12345",
"type": "pass",
"player_id": "10",
"team_id": "42",
"x": 45.0,
"y": 50.0,
"end_x": 65.0,
"end_y": 55.0,
"timestamp": "2024-02-15T20:45:32Z"
}GET /api/v1/data/sources # List available sources
GET /api/v1/data/competitions # Get competitions
GET /api/v1/data/matches?competition_id=1&season_id=2023
GET /api/v1/data/events?match_id=12345GET /health # Service health
GET /api/v1/stats # Processing statisticsBase URL: http://localhost:8000
POST /api/v1/style-fit
Content-Type: application/json
{
"style": "gegenpressing",
"player": {
"player_id": 1001,
"player_name": "Target Midfielder",
"position": "CM",
"minutes_played": 2700,
"sprint_distance": 850.0,
"pressures": 280,
"progressive_passes": 180,
"avg_defensive_line": 62.0
}
}POST /api/v1/xg
Content-Type: application/json
{
"x": 95.0,
"y": 36.0,
"body_part": "right_foot",
"shot_type": "open_play",
"is_first_time": true,
"defenders_in_cone": 1
}GET /api/v1/data/sources # Available data sources
GET /api/v1/data/competitions # Competitions from all sources
GET /api/v1/data/compare?player_id=123 # Compare player across sourcesConnect to live alerts:
const ws = new WebSocket('ws://localhost:8080/match/12345');
ws.onmessage = (event) => {
const alert = JSON.parse(event.data);
console.log('Tactical Alert:', alert);
};Alert format:
{
"match_id": "12345",
"alert": {
"id": "alert_123",
"severity": "high",
"alert_type": "low_pressing",
"message": "Defensive action at 32.1m - pressing height target: 65.0m",
"timestamp": "2024-02-15T20:45:32Z",
"metric_value": 32.1,
"threshold": 65.0,
"player_ids": [10, 15]
}
}cd services/analytics
python style_fit.pycd services/analytics
python xg_model.pycd services/dashboard
npm run dev
# Open http://localhost:3000| Metric | Performance | Target | Environment |
|---|---|---|---|
| Event Processing Latency | 12ms (p50), 48ms (p99) | <50ms | Go tactical engine |
| Alert Generation | 8ms average | <10ms | Real-time analysis |
| NATS Publish Latency | 3ms (p50), 15ms (p99) | <20ms | Message broker |
| Database Write Rate | 25,000 events/sec | 50,000+ | TimescaleDB |
| WebSocket Concurrent Clients | 500+ per instance | 1000+ | Live dashboard |
| Style-Fit Calculation | 180ms per player | <200ms | Python ML |
| xG Model Inference | 45ms per shot | <50ms | Scikit-learn |
| 3D Pitch Rendering | 60 FPS stable | 30+ FPS | Three.js |
Horizontal Scaling:
- Tactical Engine: Stateless, can run multiple instances behind load balancer
- Analytics Service: CPU-bound, scale based on ML workload
- Dashboard: Client-side rendering, CDN-friendly
- Database: TimescaleDB with automatic sharding
Resource Requirements:
- Tactical Engine: 2 CPU, 4GB RAM per instance
- Analytics Service: 4 CPU, 8GB RAM for ML workloads
- Database: 8 CPU, 16GB RAM, SSD storage
- Dashboard: Static assets, CDN distribution
- TLS 1.3 for all external connections
- JWT authentication for API access
- API rate limiting to prevent abuse
- Network isolation via Docker networks
- Input validation on all endpoints
- SQL injection protection via parameterized queries
- CORS configuration for cross-origin requests
- GDPR compliance for player data
- Data encryption at rest and in transit
- Audit logs for all tactical alerts and data access
- Role-based access control (RBAC)
- Data retention policies for historical analysis
# Example production security configuration
security:
authentication:
type: "JWT"
secret: "${JWT_SECRET}"
expiry: "24h"
rate_limiting:
events: "1000/minute"
analytics: "100/minute"
websocket: "10/second"
cors:
origins: ["https://your-club.com"]
methods: ["GET", "POST", "OPTIONS"]
headers: ["Content-Type", "Authorization"]Docker Compose (Production):
# Deploy with production configuration
docker-compose -f docker-compose.prod.yml up -d
# Scale services
docker-compose -f docker-compose.prod.yml up -d --scale tactical-engine=3
# Health check
docker-compose -f docker-compose.prod.yml psKubernetes Deployment:
# Example Kubernetes configuration
apiVersion: apps/v1
kind: Deployment
metadata:
name: tactical-engine
spec:
replicas: 3
selector:
matchLabels:
app: tactical-engine
template:
spec:
containers:
- name: tactical-engine
image: tactical-engine:latest
ports:
- containerPort: 8080
env:
- name: LOG_LEVEL
value: "info"
- name: NATS_URL
value: "nats://nats:4222"Metrics Collection:
- Prometheus for system metrics
- Grafana for visualization
- Jaeger for distributed tracing
- ELK Stack for log aggregation
Key Metrics to Monitor:
- Event processing latency
- Alert generation rate
- WebSocket connection count
- Database query performance
- Memory and CPU usage
- Error rates by service
Health Checks:
# Service health endpoints
curl http://localhost:8080/health
curl http://localhost:8000/health
curl http://localhost:3000/api/healthWe welcome contributions! Here's how to get started:
# Fork and clone
git clone https://github.com/your-username/tactical-system.git
cd tactical-system
# Set up development environment
make dev-setup
# Create feature branch
git checkout -b feature/your-feature
# Make changes and test
make test
make lint
# Submit pull request
git push origin feature/your-feature- Go: Follow standard Go conventions, use
gofmtandgolangci-lint - Python: Use
rufffor formatting and linting, include type hints - TypeScript: Use
prettierandeslint, strict TypeScript mode - Documentation: Update README and API docs for new features
- Unit tests: >80% coverage required
- Integration tests: For API endpoints
- Performance tests: For critical paths
- Security tests: For authentication and data handling
- Documentation: Check this README and service-specific docs
- Issues: Open an issue on GitHub for bugs or feature requests
- Discussions: Use GitHub Discussions for questions and ideas
- Email: tactical-system@your-club.com for enterprise support
- Slack: Join our community Slack workspace
- Twitter: Follow @TacticalSystem for updates
- Blog: Read our technical blog for deep dives
- Webinars: Monthly community webinars and demos
For enterprise clubs requiring:
- 24/7 support with SLA guarantees
- Custom development for specific tactical needs
- On-premises deployment and training
- Data migration from existing systems
Contact: enterprise@tactical-system.com
MIT License - See LICENSE file for details.
- Go: BSD 3-Clause
- Python packages: Various open-source licenses
- React: MIT
- Three.js: MIT
- TimescaleDB: Apache 2.0
Built for elite-level football analytics with contributions from:
- Data Providers: Opta, StatsBomb, DataHub, FBref
- Open Source Community: Go, Python, React ecosystems
- Football Analytics Community: Insights and feedback from professional clubs
- Academic Research: Sports analytics and machine learning research
⚡ Transforming football data into tactical intelligence, one event at a time.