NHL Playoff Odds API — Monte Carlo Simulator & Value Bets avatar

NHL Playoff Odds API — Monte Carlo Simulator & Value Bets

Pricing

from $2.10 / 1,000 team projections

Go to Apify Store
NHL Playoff Odds API — Monte Carlo Simulator & Value Bets

NHL Playoff Odds API — Monte Carlo Simulator & Value Bets

Replays every remaining NHL game thousands of times for playoff, division, wild card and Presidents' Trophy probabilities for all 32 teams, then prices them against live Kalshi contracts with fee-adjusted EV and Kelly sizing.

Pricing

from $2.10 / 1,000 team projections

Rating

0.0

(0)

Developer

ELIO LIBERATORE

ELIO LIBERATORE

Maintained by Community

Actor stats

0

Bookmarked

1

Total users

0

Monthly active users

a day ago

Last modified

Categories

Share

Every remaining game of the NHL season, replayed twenty thousand times, for all 32 clubs. You get a projected points total, the probability each team wins its division, takes a wild card, qualifies for the playoffs at all, and finishes first overall — and the same probabilities priced against the live contracts on Kalshi, so you can see where the model and the market disagree.

No API key. No scraping. No subscription. Standings and schedules come from ESPN's public feeds; prices come from Kalshi's public exchange API.

Keywords: NHL, hockey, playoff odds, Monte Carlo simulation, Stanley Cup, sports analytics, prediction markets, Kalshi, betting odds, expected value, Kelly criterion, sports data API.


Why hockey needs its own model

This is not the football or baseball simulator with the team names swapped. Three things about the NHL break a generic model:

Standings run on points, not wins. A win is two points. Losing in overtime or a shootout is still worth one. Roughly 23% of games go past regulation, so a season hands out about 3,100 points across 1,344 games rather than a tidy two-per-game. A simulator that ranks teams by wins misprices every club that lives in one-goal games. This one awards points the way the league does.

The playoff field is not "the top eight by record". Each conference sends the top three of each of its two divisions — six teams — and then the two best teams left in the conference regardless of division. A fourth-place team in a strong division and a third-place team in a weak one are not interchangeable, and the wild card is exactly where that asymmetry shows up. The simulator applies the real rule on every one of its twenty thousand seasons.

Overtime is close to a coin flip. Three-on-three and the shootout are not sixty minutes of hockey. A stronger team carries much less of its edge into the extra period, so the strength gap is damped there rather than applied in full.

The season is not 82 games any more. The CBA signed in 2025 moved the league to 84 games from 2026-27. This Actor never hardcodes a season length: it counts the games actually on the schedule feed, so it was already right on the first day of the new format and will stay right through the next change.

What comes back

One row per team, with these columns among others:

ColumnWhat it is
projectedPointsMean points total across all simulated seasons
fairPlayoffProbabilityProbability of qualifying, under the real 3+2 rule
fairDivisionProbabilityProbability of finishing first in the division
fairWildCardProbabilityProbability of qualifying as a wild card
fairTopSeedProbabilityProbability of the best record in the conference
fairPresidentsTrophyProbabilityProbability of the best record in the league
trueTalentWinPctStrength estimate after regression, on a .500 scale
marketPlayoffProbabilityThe live Kalshi price, de-vigged
playoffEdgeModel minus market, in probability points
netEVExpected value per contract after Kalshi's fee
recommendationVALUE, WATCH, PASS, NO_MARKET or NO_MODEL
suggestedStakeQuarter-Kelly, clipped by your position and portfolio caps

The playoff probabilities across all 32 rows always sum to exactly 16, because exactly sixteen teams qualify. That is a property of the simulation, not a normalisation applied afterwards, and it is the quickest sanity check you can run on the output.

The market side, done properly

Qualification is not a mutually exclusive race. Sixteen of thirty-two teams make it, so the prices across the field sum to about 16, not to 1. De-vigging that field — dividing every price by the total, the way you would for a division winner market — would divide every probability by sixteen and manufacture enormous fake edges across the whole league. This Actor treats qualification as independent binaries and leaves the mid prices alone, and treats the four division winner races as exclusive fields with the overround stripped out. The fieldSum in the log tells you which one it applied and whether the field came back complete.

Fees are charged where they actually bite. Kalshi's fee peaks at mid price: 1.75 cents per contract at $0.50 against 0.63 cents at $0.90. So a one-and-a-half point edge on a coin-flip contract is a losing position after fees, while the same edge on a heavy favourite is comfortably profitable. netEV and breakEvenProbability are computed net of that fee, per contract, with the rounding applied per order rather than per contract.

Thin markets are not tradable markets. A positive edge on a contract with no open interest and a nine-cent spread is not an opportunity, it is a quote. Those rows come back as WATCH with the reason attached, never as VALUE.

The pre-season gate — read this in September

Before the first puck drops, this model knows exactly one thing: how each club finished last season, shrunk 40% towards average. It does not know who was traded, who got hurt, who signed in July or who changed coach. The market knows all of it.

So in September the biggest apparent "edges" are not edges. They are the offseason. Betting them is betting that the summer did not happen.

Until the league has played minGamesPlayedForValue games per team (10 by default), every edge is still reported in full, but no row is allowed to claim VALUE — they come back as WATCH so you can track how they move. Set it to 0 to override that, deliberately. Once real games are in the books the current-season record takes over from the prior, gradually, at the rate set by regressionGames.

Building your own history

An Apify run's dataset is deleted after a few days. Put a name in archiveToNamedDataset — for example nhl-playoff-odds-history — and every run also appends its rows to a named dataset in your account, which Apify keeps indefinitely. Schedule the Actor daily and by March you own something you cannot buy or reconstruct: the full path of how each team's probability moved across the season, alongside what the market was charging for it on the same day.

Inputs worth knowing about

InputDefaultWhy you would change it
iterations20000Plenty for stable numbers. Raise for smoother tails.
seasoncurrentA season is named by the year it ends: 2026-27 is 2027.
regressionGames25Lower to trust the current record more.
pythagoreanWeight0.6How much comes from goal differential vs the raw record.
overtimeProbability0.23Share of games going past regulation.
overtimeDamping0.50 makes overtime a coin flip, 1 treats it like regulation.
priorCarryover0.6How much of last season survives into the pre-season prior.
minGamesPlayedForValue10Games needed before a VALUE call is allowed.
includeDivisionMarketstrueAlso price the four division winner races.
marketProbabilitiesemptySupply your own prices and skip Kalshi entirely.

Data sources

  • ESPN — standings and full schedules, public endpoints, no key.
  • KalshiKXNHLPLAYOFF for qualification and KXNHLATLANTIC, KXNHLMETROPOLITAN, KXNHLCENTRAL, KXNHLPACIFIC for the division races. Public exchange API, no key, CFTC-regulated.

If Kalshi is unreachable the run still completes: the model columns are filled and the market columns come back null with an explanatory note, rather than the run failing.

What this is not

It is a statistical model and a market comparison, not advice. It does not place orders, it does not know about injuries, goaltending changes, trades or coaching changes, and it will be wrong about individual teams. Its value is in being transparent about why it disagrees with a price, and honest about when it has no business disagreeing at all.