-
Notifications
You must be signed in to change notification settings - Fork 0
Open
Description
Overview
Implement the core gWAR (Grove WAR) calculation service that computes our transparent, simplified WAR metric.
Parent Issue
Part of #94 (WAR and Advanced Stats)
gWAR Formula
gWAR = (Batting + Baserunning + Fielding + Positional + Replacement) / 10
Batting = wRAA = ((wOBA - lgwOBA) / wOBAScale) × PA
Baserunning = wSB = (SB × 0.2) + (CS × -0.41)
Fielding = OAA × 0.9 (from Baseball Savant)
Positional = Position lookup × (games / 162)
Replacement = PA × (20.5 / 600)
Positional Adjustments (per 162 games)
| Position | Adjustment |
|---|---|
| C | +12.5 |
| SS | +7.5 |
| 2B | +3.0 |
| CF | +2.5 |
| 3B | +2.5 |
| LF | -7.5 |
| RF | -7.5 |
| 1B | -12.5 |
| DH | -17.5 |
Pitcher gWAR (FIP-based)
pitchingRuns = (lgFIP - FIP) / 9 × IP
replacement = IP × 0.03
gWAR = (pitchingRuns + replacement) / runsPerWin
Files to Create
domain/gwar/GwarCalculationService.java
@Service
public class GwarCalculationService {
public void calculateAndApply(PlayerBattingStats stats, String position);
public void calculateAndApply(PlayerPitchingStats stats);
private BigDecimal calculateWraa(BigDecimal woba, int pa, LeagueConstants lc);
private BigDecimal calculateWsb(int sb, int cs);
private BigDecimal calculateFieldingRuns(Integer oaa);
private BigDecimal calculatePositional(String position, int games);
private BigDecimal calculateReplacement(int pa);
}domain/gwar/GwarComponents.java
Record for component values.
Test Cases
- Known player produces expected gWAR (within tolerance)
- DH gets correct -17.5/162 positional adjustment
- Player without OAA gets fielding = 0
- Edge cases: 0 PA, null wOBA, null position
- Pitcher FIP-based calculation
Acceptance Criteria
- Calculation matches expected values for test players
- All component values stored on entity
- Handles missing data gracefully (nulls)
- Unit tests cover all calculation paths
Dependencies
- gWAR Schema: League Constants and Component Fields #169 (gWAR Schema)
Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
No labels