A professional, modular F1 quant analysis tool with an info-rich dashboard powered by the OpenF1 API. Features data-driven Monte Carlo championship simulations built on 2023-2025 historical race data, bookie-style composite algorithms, auto-season detection, and 2026 regulation change predictions.
- Auto Season Detection - Automatically detects current season phase (pre-season, active, post-season, winter break)
- Multi-View Dashboard - Switch between Live, Historical, and Future prediction views
- Season Switcher - Browse data from any season (2022-2026+)
- Regulation Era Tracking - Distinguishes between 2022-2025 ground effect era and 2026 new regulations
NEW: Historical Data Integration - All simulation parameters are now derived from real 2023-2025 OpenF1 race data:
- Monte Carlo Simulation - 10,000+ iteration championship probability modeling with real-time progress tracking
- Historical Data Collector - Automatically fetches and analyzes 2023-2025 race data from OpenF1:
/race_control- Safety car/VSC probability per circuit/position- First lap position change distributions by grid slot/session_result- DNF rates per driver and team/stints+/laps- Tire degradation curves per circuit/compound
- Circuit-Specific Safety Car Model - Data-driven SC probabilities replace hardcoded values:
- Monaco/Singapore/Baku: Historical ~55% SC rate
- Sakhir/Lusail: Historical ~20% SC rate
- Per-circuit average SC count for realistic multi-SC simulations
- First Lap Position Model - Grid-position-specific distributions built from historical data:
- P1-3: Mean -0.3 positions (slight regression)
- P7-12: Mean +1.0 positions (midfield gains)
- P15+: Mean +2.0 positions (back of grid gains)
- Driver-specific first lap performance blending
- Historical DNF Model - Team and driver-specific DNF rates:
- Per-driver DNF rate from historical finishes
- Correlated DNF factor from team historical data (both cars out same race)
- PU manufacturer correlation for shared component failures
- Bradley-Terry Position Model - Power-law distribution for realistic performance gaps
- Bookie-Style Composite Algorithm - Professional odds calculation (55% car / 45% driver for new regulations)
- True Bayesian Updating - Adaptive credibility based on season progress and data uncertainty
- Multiple Odds Formats - Decimal, fractional, and American odds with dynamic bookie margins
- Complete 2026 Grid - All confirmed driver lineups including:
- Cadillac (NEW) - Valtteri Bottas & Sergio Perez
- Red Bull Racing - Max Verstappen & Isack Hadjar
- Racing Bulls - Liam Lawson & Arvid Lindblad
- Ferrari - Lewis Hamilton & Charles Leclerc
- Mercedes - George Russell & Kimi Antonelli
- Audi - Nico Hulkenberg & Gabriel Bortoleto
- Power Unit Hierarchy - Based on technical analysis:
- Mercedes (420kW, HIGH confidence)
- Honda (410kW, MEDIUM-HIGH)
- Ferrari (408kW, MEDIUM)
- Red Bull-Ford (400kW, MEDIUM-LOW)
- Audi (395kW, LOW confidence)
- Regulation Change Impact - Active aero, Override Mode (replaces DRS), 50/50 power split
- Lap Analysis - Best laps, sector times, theoretical bests, consistency metrics
- Pace Analysis - Race pace, fuel-corrected pace, stint-by-stint breakdown
- Stint Analysis - Tire degradation, compound comparisons, strategy insights
- Race Analysis - Position tracking, overtakes, gap analysis
- Telemetry Analysis - Speed traces, throttle/brake patterns, DRS usage
- Real-Time Progress Bars - SSE streaming for Monte Carlo simulations
- Session Overview - Key metrics at a glance
- Driver Standings - Lap times with consistency indicators
- Pace Comparison - Visual race pace analysis
- Tire Strategy - Stint visualization timeline
- Weather Widget - Track conditions
- Compound Analysis - Tire performance comparison
- Driver Comparison - Head-to-head lap and telemetry comparison
- Odds Widget - Professional betting market integration
pigeonF1/
├── backend/ # Python FastAPI backend
│ ├── src/
│ │ ├── api/ # FastAPI routes
│ │ │ └── routes/ # Endpoint modules
│ │ │ ├── season.py # Season detection & future predictions
│ │ │ ├── standings.py
│ │ │ └── ...
│ │ ├── analytics/ # Quant analysis modules
│ │ │ ├── bookie_predictor.py # Main Monte Carlo engine
│ │ │ ├── historical_data_collector.py # OpenF1 historical data fetcher (NEW)
│ │ │ ├── historical_aggregates.py # Data-driven model structures (NEW)
│ │ │ ├── advanced_predictor.py # Monte Carlo simulation
│ │ │ ├── regulation_predictor.py # 2026 predictions
│ │ │ ├── elo_rating_system.py # Elo-style driver ratings
│ │ │ ├── head_to_head_matrix.py # H2H probability matrix
│ │ │ ├── car_performance_model.py # Detailed 2026 car profiles
│ │ │ ├── driver_performance_model.py # Extended driver attributes
│ │ │ ├── contextual_weights.py # Dynamic weighting system
│ │ │ ├── season_detector.py # Auto season detection
│ │ │ ├── lap_analysis.py
│ │ │ ├── pace_analysis.py
│ │ │ └── ...
│ │ ├── client/ # OpenF1 API client
│ │ ├── models/ # Pydantic data models
│ │ └── config.py # Configuration
│ ├── main.py # Entry point
│ └── requirements.txt
│
├── frontend/ # React + TypeScript frontend
│ ├── src/
│ │ ├── components/
│ │ │ ├── ui/ # Reusable UI components
│ │ │ └── dashboard/ # Dashboard widgets
│ │ │ ├── SeasonBanner.tsx
│ │ │ ├── SeasonSwitcher.tsx
│ │ │ ├── FuturePredictions.tsx # SSE streaming + progress bar
│ │ │ ├── HistoricalExplorer.tsx
│ │ │ ├── RegulationChanges.tsx
│ │ │ └── ...
│ │ ├── context/ # React context providers
│ │ │ └── SeasonContext.tsx
│ │ ├── pages/ # Page components
│ │ ├── lib/ # Utilities & API client
│ │ └── App.tsx
│ ├── package.json
│ └── tailwind.config.js
│
├── .cache/ # Cached historical data
│ └── historical/
│ └── aggregates.json # Pre-computed historical statistics
│
├── restart.sh # Quick start script
└── README.md
- Python 3.10+
- Node.js 18+
- npm or yarn
./restart.shThis starts both backend (port 8000) and frontend (port 5173).
cd backend
# Create virtual environment
python -m venv venv
source venv/bin/activate # On Windows: venv\Scripts\activate
# Install dependencies
pip install -r requirements.txt
# Start the API server
python main.pyThe API will be available at http://localhost:8000
- API docs:
http://localhost:8000/docs - Health check:
http://localhost:8000/health
cd frontend
# Install dependencies
npm install
# Start development server
npm run devThe dashboard will be available at http://localhost:5173
The system automatically collects and caches historical data from OpenF1:
from src.analytics import get_historical_data, BookieStylePredictor
# Collect historical data (cached after first run)
historical_data = await get_historical_data(years=[2023, 2024, 2025])
# Create predictor with data-driven parameters
predictor = BookieStylePredictor(
num_simulations=10000,
historical_data=historical_data,
)
# Predictions now use data-driven SC/DNF/first-lap models
predictions = predictor.predict_championship()| OpenF1 Endpoint | Data Collected | Model Used For |
|---|---|---|
/meetings |
Race weekends per season | Session discovery |
/sessions |
Race session keys | Filtering to Race sessions |
/race_control |
SC/VSC/Red Flag messages | Safety car probability model |
/position |
Position at each timestamp | First lap position changes |
/session_result |
DNF/DSQ status per driver | DNF rate calculation |
/stints |
Tire compound & stint length | Degradation curves |
/laps |
Lap times during stints | Tire degradation rate |
/drivers |
Driver-team mapping | Team correlation analysis |
GET /api/season/status- Current season status with auto-detectionGET /api/season/dashboard-context- Full dashboard context with feature flagsGET /api/season/available-seasons- List of available seasonsGET /api/season/predictions/future?season=2026- Future season Monte Carlo predictionsGET /api/season/regulations/2026- 2026 regulation change detailsGET /api/season/regulations/impact- Team performance impact analysisGET /api/season/driver-grid/{season}- Projected driver lineupsGET /api/season/team-analysis/{season}- Team performance analysis
GET /api/season/predictions/bookie-style- Professional odds with composite algorithmGET /api/season/predictions/bookie-style/stream- SSE streaming with real-time progressGET /api/season/predictions/driver-rating/{driver_code}- Individual driver composite ratingGET /api/season/predictions/team-breakdown/{team_name}- Team analysis with PU breakdown
GET /api/sessions- List sessionsGET /api/sessions/latest- Get latest sessionGET /api/sessions/{session_key}- Session details with drivers and weatherGET /api/sessions/meetings- Race weekend listings
GET /api/standings/drivers?year=2025- Driver championship standingsGET /api/standings/constructors?year=2025- Constructor standingsGET /api/standings/predictions/drivers- Championship scenario analysisGET /api/standings/predictions/advanced- Monte Carlo championship predictions
GET /api/laps?session_key=X- Get lap dataGET /api/laps/summary?session_key=X- Lap timing summaryGET /api/laps/driver/{number}?session_key=X- Driver lap analysisGET /api/laps/compare?session_key=X&driver1=Y&driver2=Z- Compare laps
GET /api/analytics/session-overview?session_key=X- Complete session overviewGET /api/analytics/driver-summary/{number}?session_key=X- Driver analysisGET /api/analytics/pace?session_key=X- Pace comparisonGET /api/analytics/strategy?session_key=X- Tire strategy analysisGET /api/analytics/race-summary?session_key=X- Race results and incidents
GET /api/telemetry/summary/{number}?session_key=X- Telemetry summaryGET /api/telemetry/compare?session_key=X&driver1=Y&driver2=Z- Compare telemetry
GET /api/odds/championship- Championship betting oddsGET /api/odds/race-winner- Race winner oddsGET /api/odds/markets- All available betting markets
Create a .env file in the backend/ directory:
# OpenF1 API (optional - for real-time data)
OPENF1_API_KEY=your_api_key_here
# Cache settings
CACHE_ENABLED=true
CACHE_TTL_SECONDS=300
# Server
HOST=0.0.0.0
PORT=8000
DEBUG=false- FastAPI - Modern async Python web framework
- Pydantic - Data validation and serialization
- httpx - Async HTTP client
- NumPy/Pandas - Data analysis
- diskcache - Response caching
- React 18 - UI framework
- TypeScript - Type safety
- TailwindCSS - Styling
- Recharts - Data visualization
- TanStack Query - Data fetching & caching
- Lucide React - Icons
- React Router - Navigation
- EventSource - SSE streaming for progress updates
The system builds and caches these statistics from 2023-2025 race data:
@dataclass
class CircuitHistoricalStats:
circuit_name: str
race_count: int
sc_probability: float # From race_control messages
vsc_probability: float
avg_safety_cars_per_race: float
red_flag_probability: float
@dataclass
class DriverHistoricalStats:
driver_code: str
dnf_rate: float # From session_result
first_lap_gain_avg: float # From position data
first_lap_gain_std: float
@dataclass
class TeamHistoricalStats:
team_name: str
dnf_rate: float
correlated_dnf_rate: float # Both drivers DNF same race
@dataclass
class FirstLapModel:
position_distributions: Dict[int, Tuple[float, float]] # grid_pos -> (mean, std)
incident_rates: Dict[int, float] # grid_pos -> incident probabilitycomposite = (car_rating × 0.55) + (driver_rating × 0.45) # For 2026 new regs
- Power Unit Rating - ICE output (kW), MGU-K efficiency, reliability
- Aerodynamic Rating - Active aero competency, downforce generation
- Chassis Rating - Weight optimization, suspension performance
- Development Rating - Wind tunnel allocation, personnel, budget
- Raw Pace - Qualifying speed, race pace potential
- Racecraft - Overtaking, defense, wheel-to-wheel skills
- Consistency - Race-to-race reliability, error rate
- Adaptation - Ability to adjust to new regulations (crucial for 2026)
P(A beats B) = rating_A^k / (rating_A^k + rating_B^k) # k=1.4
expected_position = N - sum(P(driver beats opponent) for all opponents)
Creates power-law distribution where top drivers have larger gaps from midfield.
# From historical_data.get_circuit_stats(circuit_name)
if circuit_stats.race_count >= 2:
sc_prob = circuit_stats.sc_probability # Data-driven
avg_sc_count = circuit_stats.avg_safety_cars_per_race
else:
# Fallback to circuit-type defaults
sc_prob = 0.35 # Base# From historical_data.first_lap_model.get_distribution(grid_pos)
mean_change, std_change = first_lap_model.get_distribution(grid_pos)
if driver_code in historical_data.drivers:
# Blend with driver-specific performance
mean_change = 0.7 * mean_change + 0.3 * driver_stats.first_lap_gain_avg# From historical_data.drivers[code] and historical_data.teams[team_key]
if driver_stats.race_count >= 5:
base_prob = 0.6 * driver_stats.dnf_rate + 0.4 * model_prediction
# Team correlation from historical correlated DNF rate
if team_stats.race_count >= 5:
correlated_factor = min(0.5, team_stats.correlated_dnf_rate * 5)margin = base(2%) + uncertainty_premium + time_premium + longshot_premium
- Base: 2% for liquid markets
- Uncertainty Premium: +3% max for high-uncertainty predictions
- Time Premium: +2% early season (decreases as season progresses)
- Longshot Premium: +3% for <2% probability outcomes
Prior: Beta(market_prob × credibility, (1-market_prob) × credibility)
Posterior: Beta(alpha + sim_wins, beta + sim_total - sim_wins)
Adaptive credibility based on season progress and data uncertainty.
The system models the 2026 regulation changes:
- Power Unit Changes: 50/50 ICE/electric split, MGU-H removal, 350kW MGU-K
- Aerodynamic Changes: Active front/rear wings, Override Mode (replaces DRS)
- Chassis Changes: Weight reduction to 768kg, simplified bodywork
- New Entrant: Cadillac (GM) as 11th team with Ferrari power unit
- Driver Market: Hadjar to Red Bull, Lindblad to Racing Bulls (rookie), Bottas/Perez to Cadillac
Inspired by F1-dash with a more professional, info-rich UX including:
- Dark F1-themed color scheme
- Tabular data displays with color-coded indicators
- Interactive charts and visualizations
- Real-time progress bars for long-running simulations
- Tire compound visualization
- Sector time analysis with purple/green/yellow indicators
MIT License - Feel free to use and modify for your own projects.
This project is unofficial and is not associated with Formula 1 companies. F1, FORMULA ONE, FORMULA 1, FIA FORMULA ONE WORLD CHAMPIONSHIP, GRAND PRIX and related marks are trademarks of Formula One Licensing B.V.
Data provided by OpenF1 and Polymarket.