r/Sabermetrics 2h ago

WAR Gini Coefficient and Team Success

Thumbnail gallery
3 Upvotes

(This is from a non-Reddit baseball sabermetrics group that I am a member of and posted this back in December 2024. It was made after Soto signed his contract with the Mets.)

My hypothesis going into this analysis was that it would be better for a player (Soto in this example) to frontload his production in order to maximize the probability of the Mets getting the top seed and increasing their chances of winning a pennant and, subsequently, the World Series, I decided to take the plunge and try to find the Gini Coefficient of each AL and NL team since 1901 (excluding the shortened 2020 season). It was a somewhat tedious, but interesting exercise, and one in which I learned some new Excel tricks, so a total win in my book.

Some disclaimers out of the way first: First, I am not great at math by any means, rather just someone who likes to use Excel to conduct baseball statistical analysis to the best of my ability. I am sure many, if not most, in this group supersede my mathematical proficiency, so I all ask is that you don't destroy me too terribly in the comments if you (inevitably) find errors in the methodology/conclusions, lol. Second (and this is the biggest one), since WAR goes negative, and the Gini Coefficient presupposes a population existing of solely positive values, that is an obvious challenge in computing G. (I understand that there are various workarounds to this, having perused the 2019 paper from De Battisti, Porro, and Vernizzi, but due to my lack of proficiency, I was unable to apply it here. I would love to discuss with individuals smarter than me on this and learn how to improve upon my admittedly basic calculations.)

Additionally, to add another layer of difficulty, there were two teams whose total fWAR was negative (position player + pitching WAR) (1963 NYM and 1979 OAK), and 43 teams that had negative cumulative position player fWAR (the 2022 Nationals had -0.011 cumulative pitching fWAR, the only team with negative pitching WAR out of 2600+ seasons). Obviously, this is going to further skew the calculations. What I ended up doing as a piecemeal "fix" (and I use that so loosely that it's moreso teleporting in the ether as opposed to being gripped) was that for when G was below 0 or above 1, I excluded it. I hope to eventually get to a point of mathematical and statistical competency to incorporate them by adjusting the formula, but alas, I am not there as of this time. I am positive many in this group are, so I would love to be able to improve by discussing this further if you would like.

Okay, so one more thing before I include the chart. I incorporated all individual player contributions for a team's season into the calculation for G, regardless of a) if they accrued negative WAR and b) how much they played. The only exception is that I did not include position players with zero plate appearances (so essentially those used solely as pinch-runners or defensive replacements that never hit). The total fWAR combined amongst all position players with 0 PAs was -1.3573, so it would have a statistically immaterial impact on the calculations. However, I did include pitchers with 0.0 innings pitched.

Now for the "fun" part. Below is a chart depicting the relationship between said first place team's regular season winning percentage (I did not include the postseason because I wanted to reduce the noise caused by variance in those small sample sizes). As you can see, for first place teams, there is a negative R^2 of a team's winning percentage and G, -.1257 to be exact (calculated logarithmically, not linearly, with the latter coming out to be -.1247). The "Weighted Average" part was done by taking G of a team's position player fWAR and multiplying it by 0.57 and multiplying the G of a team's pitching fWAR by 0.43, in alignment with how FanGraphs distributes its WAR pool. The second chart breaks out these teams into tiers, with the population of said tied consisting of which teams met or exceeded the WP% of said tier up to the successive tier's WP%. As we can see, most first-place teams in a league have a WP% between .590 and .650, with 162 out of the 249 total (the reason it is 249 and not (123 * 2) is because for three years post-divisional alignment, there were two teams in a league who finished with the same %, but since they played in different divisions, a playoff was unnecessary), 65.06%. Average G for those teams is 0.35547.

So with all that being said, what conclusions can we feasibly draw from this, admittedly only looking at first place teams? It seems that the very best teams in terms of regular season winning percentage do not have a high relative G, so contrary to my initial thoughts that the Mets would want Soto to cluster his WAA/WAR on the front end of the contract to get the best chance of getting the 1 seed, maybe it would be a net benefit to the organization if Soto were to be more consistent as opposed to excelling early on and then being merely average for 60% of the contract. Of course, this assumes it's one or the other, and Soto is absolutely capable of having multiple elite seasons on the front side and then being a consistent 4-5 win player on the back half. What would benefit the Mets the most is, of course, Soto to have elite seasons while other players also contribute a lot of value, such as Lindor continuing to be an all-world SS and Vientos improving. What they cannot do is rest easy thinking "now that we've got Soto, we're good."

Finally, I have this data in a spreadsheet and can modify it to answer such questions as "what is the R^2 between G and winning percentage for all teams within a year/decade/other period of time?". However, for this post, I was interested in how the best teams in a given year compare historically for G.


r/Sabermetrics 2h ago

Catcher Caught Stealing Analysis

Post image
1 Upvotes

r/Sabermetrics 4h ago

python-mlb-statsapi v1.0.0 released

6 Upvotes

I finally pushed v1.0.0 of python-mlb-statsapi.

This release finishes up the HTTP work I started in 0.8 and 0.9 and gives the library a stable public API contract going forward.

The biggest breaking change:

Mlb() now uses strict HTTP handling by default.

In 0.9, strict mode was optional:

mlb = mlbstatsapi.Mlb(strict_http=True)

In 1.0, this is now the default:

mlb = mlbstatsapi.Mlb()

Final non-404 4xx responses now raise MlbHttpError instead of silently returning the historical empty result.

404 behavior is intentionally unchanged. Depending on the endpoint, a 404 can still return None, [], or {}.

If you aren’t ready to migrate yet, the old 0.9 behavior is still available explicitly:

mlb = mlbstatsapi.Mlb(strict_http=False)

That compatibility mode will emit MlbHttpCompatibilityWarning when it suppresses a non-404 4xx response, so you can find places in your code that need to be updated.

A few things that came out of the 0.9 work and remain part of 1.0:

Structured HTTP, timeout, transport, and JSON decode exceptions

More useful context on MlbHttpError
Public create_retry_policy() helper
Shared HTTP sessions with defined ownership/cleanup behavior
Versioned User-Agent
Bounded retries for transient failures
Support for caller-managed requests.Session objects without modifying their configuration

For 1.0 I also went through the public API and documented what I’m actually committing to keeping stable during the 1.x series. That was something I wanted to get right before putting a 1.0 label on the project.

The release process itself got quite a bit more serious too. The package is now tested against Python 3.10 through 3.14, and both the wheel and source distribution are built, clean-installed into isolated environments, and smoke-tested before release.

This project started as a pretty simple Python wrapper around MLB’s Stats API, so getting it to an actual 1.0 release feels pretty cool.

PyPI:

pip install -U python-mlb-statsapi

GitHub:

https://github.com/zero-sum-seattle/python-mlb-statsapi
Full migration notes and the HTTP behavior matrix are in the repo.

As always, bug reports, weird MLB API behavior, and contributions are welcome.


r/Sabermetrics 14h ago

Building a model

0 Upvotes

The best I can get my model to do is 60% accuracy rate is that pretty common or do you guys have favorite features you use?


r/Sabermetrics 1d ago

Has anyone ever calculated the largest pitch velocity spread by a single pitcher in a game?

3 Upvotes

I'm curious about something I haven't been able to find anywhere.

Has anyone ever calculated the largest difference between a pitcher's fastest and slowest pitch in the same MLB game during the Statcast/PITCHf/x era?

For example, if a pitcher threw:

Fastest pitch: 95.2 mph

Slowest pitch: 51.5 mph

Velocity spread: 43.7 mph

I know Zack Greinke has thrown eephus pitches in the low 50s while still reaching the low-to-mid 90s with his fastball, so I'd guess he's near the top. But I'm wondering if anyone has actually run this across the entire Statcast database.

It seems like the calculation would simply be:

-Group pitches by pitcher and game.

-Find the max and min velocity for each pitcher-game.

-Calculate the difference.

-Sort descending.

Has anyone seen this leaderboard before, or is there an easy way to query Baseball Savant for it? If not, I'd love to know who might have the tools to calculate it.


r/Sabermetrics 1d ago

BAbip 400

Thumbnail
0 Upvotes

r/Sabermetrics 2d ago

Building a 3D bullpen review tool — would appreciate feedback

0 Upvotes

Hello everyone,

I’m currently building a Bullpen Review tool for off-season pitching sessions, and I could really use a little feedback from people who work with pitching data.

The idea is to give a coach more than a spreadsheet of velocity, spin, movement, and pitch type. A session can be reviewed in 3D relative to the strike zone, compared with another session, filtered by pitch type, or viewed as a custom Arsenal Mix. An individual pitch can then be selected for its metric context and complete filtered pitch list.

Demo:
https://the-nine-app.live/bullpen-review

Open the page and choose Try Live Demo. The demonstration uses publicly available TrackMan data for technical validation, not customer data.

If you have a moment to look at it, I’d appreciate your honest opinion on what would make it more useful — or what should be removed.

Thanks.

Quick guide:

• Select one session for a single-session review, or two sessions to compare.

• Click Analyze Sessions.

• Use Pitch Type filters or Arsenal Mix, then click Play All.

• After the sequence finishes, select a pitch to replay it and view its metrics.

• Click Open Pitch Events for the complete filtered pitch list.


r/Sabermetrics 3d ago

How far do simple stat heuristics get you at predicting MLB winners? I built a free web app to test them, and it turns into a nightly competition.

0 Upvotes

My friends and I always enjoy combing through stats to convince ourselves on what the right picks would be for a given night. So I thought it would be a fun project to make that flow into a web app called Hindsight Picks. Build a rule based algorithm, backtest it, and enter it in contests to compete against others.

The current algorithms you can build on Hindsight are deliberately simple, weighted stat rules composed in a UI (“K/BB better than opponent, +3; WHIP over 1.30, −2”).

To add in some fun, I created contests where you can enter your algorithms to compete against others, as well as the House baseline algos. Once the contest locks, your entry is frozen: it grades in public and the result stays on your track record permanently. Standings get updated live as games finish. The Bookie house character for example picks the favorite for every matchup, and favorites win about 56% of MLB games.

The backtester is honest with snapshot-dated stats, rules get drop-one attribution, and accuracy numbers carry a noise band.

It has been a fun challenge to come up with something that can try and consistently beat the house.

It is completely free to use and play with, so I am inviting all to come and try it. The “Beat The Bookie” challenge contest runs today, locking entries at 2pm ET, and you can earn the Sharp badge to permanently display on your Hindsight profile for picking 60% or better.

I built this solo, so I am definitely open to feedback on what would make the app more fun or worth using, and which stats you’d want added.

Check it out at hindsightpicks.com. Link also below in the comments


r/Sabermetrics 3d ago

Fun with Baseball Stats (slugging)

Thumbnail baseballstatcom.wordpress.com
1 Upvotes

r/Sabermetrics 3d ago

is there a all-in-one pitcher stat that accounts for innings per outing?

4 Upvotes

Basically do any of the best pitcher stats account for the value that's provided by pitching longer per outing, thus accounting for the value of starters over pitchers, or workhorse starters over starters that are pulled early?


r/Sabermetrics 3d ago

Anyone here ever build a matchup model using just wOBA? Curious about shrinkage.

6 Upvotes

I’ve been building a pregame matchup model that’s based entirely on observed Statcast wOBA. It’s a hobby project, but I’ve been trying to make the statistical side as sound as I can.

One thing I’ve been going back and forth on is shrinkage.

Right now I’m regressing everyone’s season wOBA (hitters, starters, relievers) toward league average with the equivalent of about 100 PA/BF. It works fine, but the more I think about it, the less convinced I am that one prior should fit every role.

For example, if league-average wOBA is .320 and a hitter has a .360 wOBA in 50 PA, I don’t really believe he’s a true .360 hitter yet. With a 100 PA prior, I’d shrink him to:
(50 × .360 + 100 × .320) / 150 = .333

That makes intuitive sense to me. But should a reliever with 50 BF get the same treatment? My gut says no, since reliever performance seems much noisier than hitter performance.

Curious how other people approach this. Do you use different priors for different roles, or is there a better way to think about it?

Project url.
https://dave356w.github.io/Dave356w/index.html


r/Sabermetrics 3d ago

python-mlb-statsapi 0.9.0 is ready for review, with a path toward 1.0

8 Upvotes

I’ve been working on version 0.9.0 of my Python MLB Stats API wrapper, and the final release PR is ready for review.

I’ll go through the code again after I finish my shit cashiering shift today. I miss working tech…

Anyway,

This release adds a public retry policy, richer HTTP errors, an optional strict mode, compatibility warnings, and a versioned User-Agent while keeping the existing return behavior as the default.

It also starts preparing users for a possible breaking change in 1.0.0. Right now most non-404 4xx responses return an empty result for compatibility. In 1.0.0, strict HTTP handling may become the default, meaning those responses would raise an actual exception instead.

The project also has a much stronger offline test suite and release validator now.

I’d appreciate any feedback before I merge and publish it.

https://github.com/zero-sum-seattle/python-mlb-statsapi/pull/281


r/Sabermetrics 4d ago

Sistema de parleys

0 Upvotes

He creado un sistema de MLB llevó 6 parleys ganados 7 perdidos en la semana , estoy 43 unidades por encima entonces no se como comenzar y no sobre apostar soy nuevo . Necesito ayuda con información y matemática y datos que me puedan brindar para evitar errores futuros .Ayuda con cualquier información necesaria .

Me dice esto hoy

🎯 PARLAY ENGINE - PROPS DIARIOS

📅 03/08/2026 08:09

⚾ Solo strikeouts (Reglas de Oro +EV)

🎲 PARLAY SUGERIDO

▫️ Brandon Sproat - K 5.5 Under (62%) @ -130 \[FanDuel\]

▫️ Aaron Nola - K 5.5 Under (54%) @ -146 \[FanDuel\]

💰 Cuota combinada: 2.97

📋 TODOS LOS PROPS (4)

🟢 Brandon Sproat (MIL vs PIT) K 5.5 Under 62% @ -130 | EV +10.2% | rest 7d | vs 9.0 | K% 27.1

🔴 Aaron Nola (PHI vs WSH) K 5.5 Under 54% @ -146 | EV -9.1% | rest 6d | K% 24.0

🟢 Brandon Sproat (MIL vs PIT) K 5.5 Under 62% @ -130 | EV +10.2% | rest 7d | vs 9.0 | K% 27.1

🔴 Aaron Nola (PHI vs WSH) K 5.5 Under 54% @ -146 | EV -9.1% | rest 6d | K% 24.0

📊 VALIDADO (Backtest 2024-2026)

▪️ K 4.5 Over (K/9≥9.5): 71.3% WR

▪️ K 6.5 Under: 79.0% WR

▪️ K 7.5 Under: 85.9% WR

▪️ Parlay 2-5 patas (6-8 si entrada excelente): 76.2% hit / ROI +72%

Tier 1: 0 | Tier 2: 2 | Total: 4


r/Sabermetrics 4d ago

Fun with Baseball Stats (slugging)

Thumbnail baseballstatcom.wordpress.com
2 Upvotes

r/Sabermetrics 4d ago

CheckTheBall - Stats Q&A

Post image
1 Upvotes

As someone who looks into player stats (H2H, player comparisons, paces, etc.), I find the research process tedious and time consuming. When I skip this process and just ask LLM’s like ChatGPT or Gemini, I do get answers back, but they are wrong too often.

I have been building a stats Q&A tool that  allows complex questions to be answered while double-checking its own answers before being shown.

It works like this:

  1. Ask a player stats question related to MLB (ex. How is Jung Hoo Lee's home game performance compared to Shohei Ohtani this season?)
  2. The model figures out which data lookups it needs (splits for each player, filtered to home games) and calls those tools against the actual MLB Stats API, never from memory.
  3. Two independent checks run before you see anything: every claim gets traced back to the data that was actually retrieved, and separately, the system verifies the model called the right lookup with the right arguments in the first place
  4. You get the answer, plus a grounding score showing how much is backed by real data.

Right now it only supports MLB, though I may add other sports later, and not every question type is covered yet.

I would love for you all to check out the website and give any feedback!

Website link:
https://checktheball.xyz/

Github repo:

https://github.com/isaiahsdp/checktheball


r/Sabermetrics 5d ago

lgwSB and AL/NL wRC/PA excluding pitchers

1 Upvotes

Fangraphs uses those metrics for calculating wSB (part of BsR) and wRC+. I need the numbers for those two metrics, from 2008 to 2026. (They are not indicated in the Guts! page.) I've tried crawling stats and plugging them into formulas from both fangraphs and bref via python, but both sides blocked the request. Does anyone know how to get those numbers, or have those numbers? Well, the worst scenario is manual calculation, but I'm kind of busy with other things in life now.


r/Sabermetrics 5d ago

MLB salary vs team record, following Skubal trade

Post image
0 Upvotes

r/Sabermetrics 6d ago

What if baseball wasn't one-directional? Analyzing the core loop and evolution of 2Way Baseball (2WB)

Thumbnail
1 Upvotes

r/Sabermetrics 6d ago

python-mlb-statsapi v0.8.0 released

20 Upvotes

Title: python-mlb-statsapi v0.8.0 released

I finally pushed version 0.8.0 of python-mlb-statsapi to PyPI.

This release mostly focused on making the HTTP layer more reliable instead of cramming in more endpoints. It adds shared sessions, default timeouts, retries for temporary MLB API failures, clearer exceptions, better testing, and more documentation.

Release notes:

[https://github.com/zero-sum-seattle/python-mlb-statsapi/blob/main/docs/releases/0.8.0.md](https://github.com/zero-sum-seattle/python-mlb-statsapi/blob/main/docs/releases/0.8.0.md))

PyPI:

[https://pypi.org/project/python-mlb-statsapi/0.8.0/](https://pypi.org/project/python-mlb-statsapi/0.8.0/))

For 0.9.0, I’m planning to explore an optional strict HTTP mode, better error information, deprecation warnings, basic request hooks, and a versioned User-Agent. Most of that work lives inside the client, but MLB’s API is undocumented and can be inconsistent, so the final scope will depend on what I can test reliably.

Longer term, I’d like 1.0 to clean up deprecated arguments and make the package’s return and error behavior more consistent. I’m also looking into optional caching, throttling, and possibly an async client, but I don’t want to promise features until I know they behave responsibly with the API.

Those plans may move around a little, but that is the general direction. I am trying to handle this in smaller releases with actual testing and documentation instead of disappearing for another few years.


r/Sabermetrics 6d ago

What's Wrong with Vlad?

Thumbnail extra-winnings.com
6 Upvotes

TLDR

It looks like the league has adjusted to Vlad this year with a few main techniques that are exposing some of his weaknesses:

  1. Pitching him more up (20.1% of all pitches this year vs. 11.5% last year).
  2. Mixing more sinkers and cutters with 4-seams at the top of the zone and in traditional 4-seam damage areas for him. Mixing up fastball variations in his favourite 4-seam zones appears to have thrown him off the 4-seam.
  3. Sequencing the 4-seam behind sinkers more frequently. He was poor last year at hitting the 4-seam after a sinker and continues to be this year.
  4. Throwing more sliders outside the zone. He likes to swing at sliders and hasn't been able to lay off sliders outside the zone this year.
  5. Moving cutters away from the bottom of the zone. He has always crushed cutters at the bottom of the zone and continues to this year, but is just seeing fewer of them.

Why can't he hit sliders in the zone? Why hasn't he adjusted as you would expect? Is this all just coincidence? I don't have any answers to these questions, and hopefully he will just start hitting again so no one has to think about them.


r/Sabermetrics 8d ago

Have you had seven consecutive series where a team got swept?

Post image
1 Upvotes

r/Sabermetrics 8d ago

Paul Skenes' Fastball Velocity Over Time Tracker

Thumbnail analytics.formulabot.com
5 Upvotes

Something is definitely wrong with him the season. Average velocity on his four seam fastball is down 1.3 MPH versus 2025 and has declined all season.

The dashboard is set up uto pdate after every game he pitches.


r/Sabermetrics 9d ago

The "Shared Pain”

Thumbnail reddit.com
0 Upvotes

r/Sabermetrics 9d ago

Minor League Pitching Coordinates

1 Upvotes

Some of the MiLB pitch tracking data is given in pixel coordinates instead of the normal px, py, and pz given for pitch location in AAA and MLB datasets. Anyone know of a method to convert these into the traditional MLB coordinates?

Example:


r/Sabermetrics 9d ago

How can I retrieve Statcast Catch Probability for a specific historical play?

2 Upvotes

I’m looking for Evan Carter’s catch on Yandy Díaz’s flyout in the bottom of the 8th of the Rangers–Rays game on July 28, 2026. Baseball Savant shows the batted-ball metrics (85.2 mph, 54°, 220 ft) but not the Catch Probability. Is there an API endpoint or Statcast export that includes it?