Skip to content

gWAR Calculation Service #170

@grovecj

Description

@grovecj

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions