EPA (Expected Points Added) analytics platform for FIRST Tech Challenge (FTC).
FTCStats provides predictive statistics, team rankings, match predictions, and visualizations for FTC competitions.
- EPA Rankings - Team rankings based on Expected Points Added, normalized across seasons
- Match Predictions - Win probability predictions for upcoming matches
- Team Analytics - Detailed breakdowns of auto, driver-controlled, and endgame performance
- Event Insights - Event-level statistics and team performance tracking
- Historical Data - Coverage from 2019 (Skystone) through current season
- Python API - Programmatic access to all FTCStats data
| Component | Technology | Description |
|---|---|---|
| Backend | Python, FastAPI | EPA calculations, REST API |
| Frontend | Next.js, TypeScript | Interactive dashboards and visualizations |
| Database | PostgreSQL | Team, event, and match data storage |
| Data Source | FTC Scout API | Match scores and event data |
- Python 3.11+
- Node.js 18+
- PostgreSQL (or SQLite for development)
cd backend
pip install -e ".[dev]"
# Set up database
export DATABASE_URL="postgresql://localhost/ftcstats"
alembic upgrade head
# Sync data and calculate EPA
ftcstats sync --season 2024
ftcstats epa --season 2024
# Start API server
ftcstats server --reloadcd frontend
npm install
npm run devThe frontend runs at http://localhost:3000 and the API at http://localhost:8000.
ftcstats/
├── backend/ # Python backend
│ ├── src/
│ │ ├── data/ # Data fetching & sync
│ │ │ └── ftc_scout/ # FTC Scout API client
│ │ ├── db/ # Database models
│ │ ├── models/epa/ # Core EPA algorithm
│ │ └── site/ # API routes
│ ├── tests/ # Backend tests
│ └── alembic/ # Database migrations
├── frontend/ # Next.js frontend
│ ├── src/
│ │ ├── pages/ # Page routes
│ │ ├── components/ # React components
│ │ ├── api/ # API client functions
│ │ └── types/ # TypeScript types
└── api/ # Python package for PyPI
└── ftcstats/ # Public API client
The backend provides a CLI for data management:
ftcstats server [--reload] # Start API server
ftcstats sync --season 2024 # Sync data from FTC Scout
ftcstats epa --season 2024 # Calculate EPA values
ftcstats update --season 2024 # Sync + EPA + postprocess
ftcstats update --all # Update all seasons
ftcstats stats # Show database statisticsInstall the Python package to access FTCStats data programmatically:
pip install ftcstatsimport ftcstats
# Get team data
team = ftcstats.get_team(12345)
print(f"Team {team.number}: {team.name}")
print(f"Normalized EPA: {team.norm_epa.current}")
# Get top teams for a season
response = ftcstats.get_team_seasons(2024, limit=10)
for ts in response.team_seasons:
print(f"{ts.team_number}: EPA {ts.epa.total:.1f}")
# Get match predictions
matches = ftcstats.get_event_matches(2024, "USWATACO")
for match in matches:
if match.pred.red_win_prob:
print(f"{match.match_id}: Red {match.pred.red_win_prob:.0%}")See api/README.md for full API documentation.
EPA (Expected Points Added) measures a team's contribution to alliance scores, adapted for FTC's 2-team alliances:
- Attribution: Score error is split between 2 teams (not 3 as in FRC)
- Components: Total, Auto, Driver-Controlled, Endgame, plus season-specific breakdowns
- Normalization: Cross-season EPA normalized to 1500-scale for comparison
- Win Probability: Based on EPA difference with logistic function
| Component | Description |
|---|---|
| Total EPA | Overall contribution to alliance score |
| Auto EPA | Autonomous period contribution |
| DC EPA | Driver-controlled period contribution |
| Endgame EPA | Ascent/park points contribution |
| Norm EPA | Normalized to 1500-scale across seasons |
| Year | Game | Status |
|---|---|---|
| 2025 | Decode | Active |
| 2024 | Into The Deep | Complete |
| 2023 | CenterStage | Complete |
| 2022 | Power Play | Complete |
| 2021 | Freight Frenzy | Complete |
| 2020 | Ultimate Goal | Complete |
| 2019 | Skystone | Complete |
cd backend
# Run tests
pytest tests/ -v
# Lint and format
ruff check src/
black src/cd frontend
# Lint
npm run lint
# Build
npm run buildThe backend exposes a REST API at /v1/site/:
GET /team/{number}- Team details with EPAGET /teams- Paginated team listGET /team_seasons/{year}- Teams ranked by EPA
GET /events/{year}- Events for a seasonGET /event/{year}/{code}- Event detailsGET /event/{year}/{code}/matches- Event matches
GET /match/{year}/{event}/{match_id}- Match detailsGET /matches- Paginated match list
GET /seasons- All seasonsGET /season/{year}- Season statistics
cd frontend
vercel --prodcd backend
railway upRequired environment variables:
DATABASE_URL- PostgreSQL connection stringFTC_SCOUT_BASE_URL- FTC Scout API base URL
- FTC Scout API - https://api.ftcscout.org/rest/v1/
- FTC Events API - https://ftc-events.firstinspires.org/api (official)