brackt/app/services/simulations/golf-simulator.ts
Chris Parsons c6ba59b0e6
User/chris/ev f1 framework (#93)
* feat: EV simulation framework with F1 Monte Carlo simulator

- Add EV snapshot tables (participant_ev_snapshots, team_ev_snapshots) and simulation_status column on sports seasons
- Add ev-snapshot model with upsert and history query functions
- Add simulator framework: types, bracket/F1/golf simulators, registry
- F1 simulator: vig-removed ICM weighted draw (pre-season) + race-by-race Monte Carlo from current standings (in-season); per-position column normalization to prevent floating-point EV drift
- Add admin simulate route and Run Simulation button on sports season page
- Rework futures-odds admin page to save odds then run simulation in one action
- Remove recalculate-probabilities route (superseded by simulate route)
- Remove EV trend chart panel and associated DB queries

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat: map simulators to sports via simulatorType field

Adds a `simulator_type` enum column to the `sports` table so each sport
can be assigned a specific simulation algorithm rather than deriving it
from the sports season's scoring pattern.

- Add `simulatorTypeEnum` (f1_standings, indycar_standings,
  golf_qualifying_points, playoff_bracket) + `simulatorType` nullable
  column on `sports` table; migration 0037
- Rewrite simulator registry to key off `SimulatorType` instead of
  `ScoringPattern`; indycar_standings shares F1Simulator for now
- `findSportsSeasonById` now returns `SportsSeasonWithSport` so callers
  have typed access to `sport.simulatorType`
- Simulate and futures-odds actions read `sport.simulatorType`; guard
  fires before setting `simulationStatus: running`
- Admin sport edit page gains a Simulator Type dropdown

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-09 15:34:31 -07:00

32 lines
1.3 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/**
* Golf / Qualifying Points Simulator
*
* TODO: Port the Python golf/majors simulator here.
*
* Input data available:
* - Current QP standings: getQPStandings(sportsSeasonId)
* Returns { participant.id, participant.name, totalQualifyingPoints, eventsScored }
* - Remaining majors: sportsSeason.totalMajors - sportsSeason.majorsCompleted
* - Per-major QP config: qualifyingPointConfig table (points per placement for each major)
*
* Expected output: SimulationResult[] — one entry per participant with
* probabilities (01) for finishing 1st through 8th in the final QP standings.
*
* Algorithm sketch (replace with the Python model logic):
* 1. Get current QP totals for all participants
* 2. For each remaining major, model each participant's probability of
* finishing at each placement (using world rankings, recent form, etc.)
* 3. Monte Carlo: simulate remaining majors N times, add QP, tally final standings
* 4. Convert tally counts → probabilities
*/
import type { Simulator, SimulationResult } from "./types";
export class GolfSimulator implements Simulator {
async simulate(_sportsSeasonId: string): Promise<SimulationResult[]> {
throw new Error(
"GolfSimulator not yet implemented. " +
"Port the Python golf/majors model to TypeScript and implement this method."
);
}
}