Given the win odds of a horse race are known plus other info such as top 3 place odds, calculate the 2nd/3rd/4th place odds for each horse.

49 Views Asked by At

I have a problem where I am trying to calculate the place odds given win odds and other info such as top 3 place odds.

I have used Harville's method successfully to calc place odds given we know the win odds. However I am struggling completely with how to incorporate other information such as obtaining a more accurate 4th place probability if we know the odds of a horse finishing in the top 3.

Below is my attempt. It seems to be wrong based on my results (they seem off).

let calcPlaceOdds = () => {
let activeRunners = utils.getActiveRunners(odds);
for (let horseNumber of activeRunners) {
    let secondPlaceProbability = 0
    let thirdPlaceProbability = 0
    let fourthPlaceProbability = 0
    let horse = odds[horseNumber]
    const hasTop2 = horse.top2odds > 0
    const hasTop3 = horse.top3odds > 0
    const hasTop4 = horse.top4odds > 0
    for (let otherHorseNumber of activeRunners) {
        let other = odds[otherHorseNumber]
        if (horseNumber != otherHorseNumber && other.winOdds> 0) {
            let secondPlaceProbTemp = (1 / other.winOdds) * (1 / horse.winOdds) / (1 - (1 / other.winOdds));
            if(hasTop2) {
                secondPlaceProbTemp = (1/horse.top2odds - 1/horse.winOdds) / (activeRunners.length -1)
            }
            secondPlaceProbability += secondPlaceProbTemp
            for (let other2HorseNumber of activeRunners) {
                let other2 = odds[other2HorseNumber]
                if (horseNumber != other2HorseNumber && other2HorseNumber != otherHorseNumber && other2.winOdds> 0) {
                    let thirdPlaceProbTemp = secondPlaceProbTemp * (1 / other2.winOdds) / (1 - (1 / other.winOdds) - (1 / other2.winOdds));
                    if(hasTop3) {
                       thirdPlaceProbTemp = ((1 / horse.top3odds - 1 / horse.winOdds) / (Math.pow(activeRunners.length -1,2))) - secondPlaceProbTemp / (activeRunners.length-1)
                    }
                    thirdPlaceProbability += thirdPlaceProbTemp;
                    for (let other3HorseNumber of activeRunners) {
                        let other3 = odds[other3HorseNumber]
                        if (horseNumber !== other3HorseNumber &&
                            other3HorseNumber !== other2HorseNumber &&
                            other3HorseNumber !== otherHorseNumber &&
                            other2HorseNumber !== otherHorseNumber &&
                            other3.winOdds> 0) {
                            let fourthPlaceTemp = thirdPlaceProbTemp * (1 / other3.winOdds) / (1 - (1 / other.winOdds) - (1 / other2.winOdds) - (1 / other3.winOdds));

                            if(hasTop4) {
                               fourthPlaceTemp = ((1/horse.top4odds - 1/horse.winOdds) / (Math.pow(activeRunners.length -1,3))) - (secondPlaceProbTemp / (Math.pow(activeRunners.length -1,2))) - thirdPlaceProbTemp / (activeRunners.length-1);
                            }
                            fourthPlaceProbability += fourthPlaceTemp
                        }
                    }
                }
            }
             placeOdds[horseNumber] = {
               2ndPlaceProb: 1/secondPlaceProbability,
               3rdPlaceProb: 1/thirdPlaceProbability,
               4thPlaceProb: 1/fourthPlaceProbability}
        }
    }