If you read my sports betting post, I wrote an R function called oddsFinderDec to find implied percentages of events occurring given betting prices. Here I will present how likely each team is to win the finals based on pinnacle prices of 2.55 for the Mavericks and 1.581 for the Heat.
> oddsFinderDec(c(2.55,1.581))
[1] 0.3827160 0.6172840
This means the Mavericks have about a 38.27% chance of winning the finals.
What about an exact series results breakdown? They have prices for each possible result (as in, Mavs 4-0, Mavs 4-1...Heat 4-3). Let's check out those percentages.
> exactSeriesResult=oddsFinderDec(c(20.72,8.35,8.5,7.85,10.42,7.89,4.47,4.02))
> exactSeriesResult
[1] 0.04354880 0.10806362 0.10615661 0.11494665 0.08659609 0.11436391 0.20186381 0.22446050
Those eight probabilities are for each result. The first four are for the Mavs winning in order from 4-0 to 4-3, then the Heat winning in order from 4-0 to 4-3. So, just to be clear there should be about a 20.19% chance the Heat win 4-2. If I sum up each Mavs winning scenario percent, it should add up to the percent of the Mavs winning the whole series.
> sum(exactSeriesResult[1:4])
[1] 0.3727157
Similar, but about 1% off. I could force the exact series results percentages to add up so that the sum of each result in which the Mavs win adds up to the percent that the Mavs win the series.
> adjExactSeriesResult=exactSeriesResult
> adjExactSeriesResult[1:4]=exactSeriesResult[1:4]*oddsFinderDec(c(2.55,1.581))[1]/sum(exactSeriesResult[1:4])
> adjExactSeriesResult[5:8]=exactSeriesResult[5:8]*sum(exactSeriesResult[1:4])/oddsFinderDec(c(2.55,1.581))[1]
> adjExactSeriesResult
[1] 0.04471726 0.11096308 0.10900491 0.11803079 0.08433333 0.11137558 0.19658911 0.21859536
There are also over/unders on the length of the series.
Here's the 4.5 games series length over/under.
> ou4p5=oddsFinderDec(c(1.117,7.02))
> ou4p5
[1] 0.8627258 0.1372742
There's about an 86.27% chance the series lasts more than 4.5 games.
> ou5p5=oddsFinderDec(c(1.467,2.92))
> ou6p5=oddsFinderDec(c(2.77,1.508))
From the over/unders and using the power of subtraction, I can find implied chances of each total game result.
> fourG=ou4p5[2]
> fiveG=ou5p5[2]-ou4p5[2]
> sixG=ou5p5[1]-ou6p5[1]
> sevenG=ou6p5[1]
> exactGames=c(fourG,fiveG,sixG,sevenG)
> exactGames
[1] 0.1372742 0.1971229 0.3131017 0.3525012
I wonder how these match up with those from the exact series result chances. What I'm doing here is just adding the Mavs 4-0 to the Heat 4-0 to get the chance of a 4 game series and the same for 4-1, 4-2, and 4-3.
> exactGames2=exactSeriesResult[1:4]+exactSeriesResult[5:8]
> exactGames3=adjExactSeriesResult[1:4]+adjExactSeriesResult[5:8]
> exactGames2
[1] 0.1301449 0.2224275 0.3080204 0.3394072
> exactGames3
[1] 0.1290506 0.2223387 0.3055940 0.3366262
There are some large differences for 5 and 7 games.
What about game 1? The Heat are at home.
> oddsFinderDec(c(2.75,1.513))
[1] 0.3549144 0.6450856
The Mavs have about a 35.49% chance of winning game 1.
If we assume the Heat are equally likely to win game 2 at home and their chances of winning games 3 and 4 on the road are the same, then we can make a prediction of the Heat's chances of winning on the road using their chance of sweeping we estimated earlier.
> heatHome=oddsFinderDec(c(2.75,1.513))[2]
> heatAway=sqrt(adjExactSeriesResult[5]/heatHome^2)
> heatHome
[1] 0.6450856
> heatAway
[1] 0.4501759
Alright!
Now that I have this info, I might as well simulate the series 100000 times.
> exactSeriesResult4=numeric(8);
> for(i in 1:100000){
+ h=0; m=0; bool=T;
+ while(bool){
+ if(runif(1,0,1)<heatHome){h=h+1} else{m=m+1}
+ if(runif(1,0,1)<heatHome){h=h+1} else{m=m+1}
+ if(runif(1,0,1)<heatAway){h=h+1} else{m=m+1}
+ if(runif(1,0,1)<heatAway){h=h+1} else{m=m+1}
+ if(h==4){exactSeriesResult4[5]=exactSeriesResult4[5]+1; break} else{
+ if(m==4){exactSeriesResult4[1]=exactSeriesResult4[1]+1; break}}
+ if(runif(1,0,1)<heatAway){h=h+1} else{m=m+1}
+ if(h==4){exactSeriesResult4[6]=exactSeriesResult4[6]+1; break} else{
+ if(m==4){exactSeriesResult4[2]=exactSeriesResult4[2]+1; break}}
+ if(runif(1,0,1)<heatHome){h=h+1} else{m=m+1}
+ if(h==4){exactSeriesResult4[7]=exactSeriesResult4[7]+1; break} else{
+ if(m==4){exactSeriesResult4[3]=exactSeriesResult4[3]+1; break}}
+ if(runif(1,0,1)<heatHome){h=h+1} else{m=m+1}
+ if(h==4){exactSeriesResult4[8]=exactSeriesResult4[8]+1; break} else{
+ if(m==4){exactSeriesResult4[4]=exactSeriesResult4[4]+1; break}}
+ }}
> exactSeriesResult4=exactSeriesResult4/sum(exactSeriesResult4)
> exactSeriesResult4
[1] 0.03830 0.10898 0.10671 0.10969 0.08498 0.13295 0.21587 0.20252
Here are the exact series results in the order they appeared before when we looked at the percentages implied by the betting prices.
How do they compare to those percentages?
> exactSeriesResult
[1] 0.04354880 0.10806362 0.10615661 0.11494665 0.08659609 0.11436391 0.20186381 0.22446050
There are a couple modest differences.
How often did the Mavs win the series in this sim?
> sum(exactSeriesResult4[1:4])
[1] 0.36368
That's nearly 2% off from the series prices. I don't like how big that difference is. I could do an adjustment similar to the one I did earlier.
> adjExactSeriesResult4=exactSeriesResult4
> adjExactSeriesResult4[1:4]=exactSeriesResult4[1:4]*oddsFinderDec(c(2.55,1.581))[1]/sum(exactSeriesResult4[1:4])
> adjExactSeriesResult4[5:8]=exactSeriesResult4[5:8]*sum(exactSeriesResult4[1:4])/oddsFinderDec(c(2.55,1.581))[1]
> adjExactSeriesResult4
[1] 0.04030473 0.11468432 0.11229551 0.11543149 0.08075315 0.12633715 0.20513277 0.19244679
Of course, this is a stupid way to do it because the chances of each series result should not increase proportionally by making the Mavericks better. Regardless, look at this:
> exactGames4=adjExactSeriesResult4[1:4]+adjExactSeriesResult4[5:8]
> exactGames4
[1] 0.1210579 0.2410215 0.3174283 0.3078783
Now, recall this:
> exactGames
[1] 0.1372742 0.1971229 0.3131017 0.3525012
.3525 vs. .3079
That is huge! We may have a +EV bet if we bet on the under 6.5 games! But hold your horses, I'm going to redo the 10000 series simulations with a slightly higher Mavs road winning percent.
> heatAway=sqrt(adjExactSeriesResult4[5]/heatHome^2)
> heatAway
[1] 0.4405167
Here are the results of the simulation using updated Heat road win percent based on new sweep chances.
> exactSeriesResult5
[1] 0.03914 0.11405 0.10642 0.11290 0.08171 0.12988 0.21383 0.20207
Note that the Mavs won more, but not enough more.
> sum(exactSeriesResult5[1:4])
[1] 0.37251
I'll do this one more time, but now I will choose the Heat road win percent based on linear logic. Here is middle school math at it's most tedious.
> heatAway=(oddsFinderDec(c(2.55,1.581))[1]-sum(exactSeriesResult[1:4]))/((sum(exactSeriesResult[1:4])-sum(exactSeriesResult4[1:4]))/(heatAway-sqrt(adjExactSeriesResult[5]/heatHome^2)))+heatAway
> heatAway
[1] 0.4298262
Look at how long that first equation is!
Here is the simulation one more time with the new Heat road winning percent.
> exactSeriesResult6
[1] 0.04224 0.12187 0.10968 0.11226 0.07713 0.12150 0.21214 0.20318
> sum(exactSeriesResult6[1:4])
[1] 0.38605
I actually overshot it a little, with the Mavs now winning too often.
> exactGames6=exactSeriesResult6[1:4]+exactSeriesResult6[5:8]
> exactGames6
[1] 0.11937 0.24337 0.32182 0.31544
Even with me giving the Mavs a little too much credit, the series only went to 7 games 31.54% of the time.
So should we take the under on 6.5 games for the series?
Here's a new function:
> profOddsDec=function(odds){
+ 1/odds}
It'll tell you what you need the chances to be for a bet to have positive expected value.
Here it is for the under on 6.5 games.
> profOddsDec(1.508)
[1] 0.66313
What did my sim find?
> 1-exactGames6[4]
[1] 0.68456
and that was while giving the Mavs too much credit.
So I say go for it! Bet your life savings!
> (1-exactGames6[4])*1.508
[1] 1.032316
You can expect a whopping 3.2% return on investment if you make a bunch of assumptions about game independence and accuracy of betting prices.
The case may be that refs (whether intentionally or not) may have a slight bias toward the team that is losing the series to make it go longer. That may be the reason for this.
I would also like to point out that in the world of sports betting, much like the world of stock market investing, you should live by the following rule. If you think something is priced incorrectly, it's not because it's priced wrong, it's because those who made it the price it is know something that you don't. Of course, there are exceptions to this rule.
