Friday, August 01, 2025

DMDA Probability Thresholds

WCMI DMDA Probability Thresholds

A Weekend Warrior's approach to sustainable speculation using probability thresholds and illustrated with a Taleb's Barbell Strategy example


In our previous posts, we introduced the Dual-Metric Decision Algorithm (DMDA) as a framework combining Expected Value (EV) and Likely Profit (LP) for sports betting decisions. While EV measures average profit per bet, LP captures the expected geometric growth rate of our bankroll - the multiplicative reality facing bettors with limited capital.

This post extends that work by deriving the precise probability thresholds required for positive EV and LP, using the Rugby World Cup 2023 as a worked example of Taleb's Barbell Strategy in practice.

Mathematical Framework

For a bet with stake fraction F, decimal odds O, and bettor's estimated win probability P, the DMDA calculates win-balance and loss-balance multipliers:

  • Win-Balance Multiplier: W B = 1 + F ( O 1 ) WB = 1 + F(O-1)
  • Loss-Balance Multiplier: L B = 1 F LB = 1-F

From these, we derive:

  • Expected Value: E V = ( W B × P ) + ( L B × ( 1 P ) ) 1 EV = (WB \times P) + (LB \times (1-P)) - 1
  • Likely Profit: L P = W B P × L B ( 1 P ) 1 LP = WB^P \times LB^{(1-P)} - 1

Probability Thresholds

EV = 0 Threshold

Setting E V = 0 EV = 0 and solving for P gives:

P EV = 1 L B W B L B = F F × O = 1 O P_{\text{EV}} = \frac{1-LB}{WB-LB} = \frac{F}{F \times O} = \frac{1}{O}

Elegantly, a bet has non-negative expected value only if our probability estimate exceeds the market's implied probability 1 / O 1/O .

LP = 0 Threshold

Setting L P = 0 LP = 0 yields:

P LP = ln ( 1 / L B ) ln ( W B / L B ) P_{\text{LP}} = \frac{\ln(1/LB)}{\ln(WB/LB)}

This boundary is stricter than the EV threshold because geometric growth is more sensitive to downside volatility.

Canonical Example

We will focus initially on this canonical betting example:

Parameter Value
Total Bankroll (B) $10000
Markets (M) 1
Decimal Odds (O) 1.9091
Win Probability (P) 55.00%
Stake Fraction (F) 1.00%

Market Conditions:

  • Implied probability: 52.38% (decimal odds 1.9091)
  • Warrior assessment: >=55.00% (conservative minimum)

Threshold Calculations:

  • F = 0.01 F = 0.01
  • O = 1.9091 O = 1.9091
  • L B = 1 0.01 = 0.99 LB = 1 - 0.01 = 0.99
  • W B = 1 + 0.01 ( 1.9091 1 ) = 1.00909 WB = 1 + 0.01(1.9091-1) = 1.00909

Results:

  • P EV = 1 / 1.9091 = 0.5238 P_{\text{EV}} = 1/1.9091 = 0.5238 (52.38%)
  • P LP = ln ( 1 / 0.99 ) ln ( 1.00909 / 0.99 ) 0.52622 P_{\text{LP}} = \frac{\ln(1/0.99)}{\ln(1.00909/0.99)} \approx 0.52622 (52.62%)

Decision: Warrior assessment of 55% exceeds both thresholds and an effective lower bound s set at 53%.

Rugby World Cup 2023: Worked Example

Consider a Weekend Warrior's barbell allocation:

  • Total Bankroll: $10,000
  • Total Stake: $500 (5% of bankroll)
  • Safe Allocation: $450 (4.5% of bankroll, 90% of stake)
  • Risky Allocation: $50 (0.5% of bankroll, 10% of stake)

Safe Allocation (Favs)

Market Conditions:

  • Implied probability: 80% (decimal odds 1.25)
  • Warrior assessment: >=85% (conservative minimum)

Threshold Calculations:

  • F = 0.045 F = 0.045
  • O = 1.25 O = 1.25
  • L B = 1 0.045 = 0.955 LB = 1 - 0.045 = 0.955
  • W B = 1 + 0.045 ( 1.25 1 ) = 1.01125 WB = 1 + 0.045(1.25-1) = 1.01125

Results:

  • P EV = 1 / 1.25 = 0.80 P_{\text{EV}} = 1/1.25 = 0.80 (80%)
  • P LP = ln ( 1 / 0.955 ) ln ( 1.01125 / 0.955 ) 0.8045 P_{\text{LP}} = \frac{\ln(1/0.955)}{\ln(1.01125/0.955)} \approx 0.8045 (80.45%)

Decision: Warrior assessment of 85% exceeds both thresholds

Some Insights

Conservative Estimates as Lower Bounds

The warrior assessments function as conservative minimum thresholds rather than precise probability estimates. This approach provides safety margins: if actual probability assessments exceed these minimums (likely), returns will surpass calculated expectations.

LP Threshold Criticality

The LP threshold being consistently higher than the EV threshold demonstrates why stake sizing matters even for positive-EV bets. Excessive stakes can create negative geometric growth despite positive expected value - a critical insight for bankroll survival.

Real-World Application

South Africa's victory in the Rugby World Cup 2023 validated the safe allocation approach, while maintaining exposure to potential Black Swan events preserved optionality for extreme outsiders. The mathematical framework translated effectively to practical application.


Note: The final draft of this post was sanity checked by Claude.

# https://vendire-ludorum.blogspot.com/

<#
.SYNOPSIS
    DMDA Probability Thresholds Calculator
    
.DESCRIPTION
    Calculates the probability thresholds for positive Expected Value (EV) and 
    positive Likely Profit (LP) based on the Dual-Metric Decision Algorithm (DMDA).
    
.PARAMETER DecimalOdds
    The decimal odds offered by the market (e.g., 1.25, 50.0)
    
.PARAMETER StakeFraction
    The fraction of bankroll being staked (e.g., 0.045 for 4.5%)
    
.EXAMPLE
    .\DMDA-Thresholds.ps1 -DecimalOdds 1.25 -StakeFraction 0.045
    
.EXAMPLE
    .\DMDA-Thresholds.ps1 -DecimalOdds 50.0 -StakeFraction 0.005
#>

param(
    [Parameter(Mandatory=$true)]
    [ValidateRange(1.01, [double]::MaxValue)]
    [double]$DecimalOdds,
    
    [Parameter(Mandatory=$true)]
    [ValidateRange(0.001, 0.999)]
    [double]$StakeFraction
)

# Calculate multipliers based on DMDA framework
$LossBalanceMultiplier = 1 - $StakeFraction
$WinBalanceMultiplier = 1 + $StakeFraction * ($DecimalOdds - 1)

# Calculate probability thresholds
$P_EV = 1 / $DecimalOdds
$P_LP = [Math]::Log(1 / $LossBalanceMultiplier) / [Math]::Log($WinBalanceMultiplier / $LossBalanceMultiplier)

# Output results
Write-Host ""
Write-Host "DMDA Probability Thresholds Calculator" -ForegroundColor Cyan
write-Host "(https://vendire-ludorum.blogspot.com/)" -ForegroundColor Cyan
Write-Host "======================================" -ForegroundColor Cyan
Write-Host ""
Write-Host "Input Parameters:" -ForegroundColor Yellow
Write-Host "  Decimal Odds (O): $DecimalOdds"
Write-Host "  Stake Fraction (F): $StakeFraction ($($StakeFraction * 100)%)"
Write-Host ""
Write-Host "Calculated Multipliers:" -ForegroundColor Yellow
Write-Host "  Loss-Balance Multiplier (LB): $($LossBalanceMultiplier.ToString('F6'))"
Write-Host "  Win-Balance Multiplier (WB): $($WinBalanceMultiplier.ToString('F6'))"
Write-Host ""
Write-Host "Probability Thresholds:" -ForegroundColor Green
Write-Host "  P(EV) = $($P_EV.ToString('F6')) ($($($P_EV * 100).ToString('F4'))%)"
Write-Host "  P(LP) = $($P_LP.ToString('F6')) ($($($P_LP * 100).ToString('F4'))%)"
Write-Host ""
Write-Host "Market Implied Probability: $($($P_EV * 100).ToString('F2'))%" -ForegroundColor Cyan
Write-Host "Positive Bankroll Growth Probability: $($($P_LP * 100).ToString('F2'))%" -ForegroundColor Cyan
Write-Host ""

# Validation check
if ($P_LP -gt $P_EV) {
    Write-Host "LP threshold exceeds EV threshold" -ForegroundColor Green
} else {
    Write-Host "Warning: LP threshold does not exceed EV threshold" -ForegroundColor Red
}

Write-Host ""
Write-Host "For a bet to be considered sustainable (bankroll growth), "
Write-Host "our estimated win probability should be greater than both P(EV) and P(LP)."
Write-Host "As shown, the P(LP) threshold is always stricter than the P(EV) threshold." -ForegroundColor Cyan
Write-Host ""


# Example usage:

<# 
.\DMDA_Probability_Thresholds.ps1 -DecimalOdds 1.9091 -StakeFraction 0.01

DMDA Probability Thresholds Calculator
(https://vendire-ludorum.blogspot.com/)
======================================

Input Parameters:
  Decimal Odds (O): 1.9091
  Stake Fraction (F): 0.01 (1%)

Calculated Multipliers:
  Loss-Balance Multiplier (LB): 0.990000
  Win-Balance Multiplier (WB): 1.009091

Probability Thresholds:
  P(EV) = 0.523807 (52.3807%)
  P(LP) = 0.526188 (52.6188%)

Market Implied Probability: 52.38%
Positive Bankroll Growth Probability: 52.62%

LP threshold exceeds EV threshold

For a bet to be considered sustainable (bankroll growth),
our estimated win probability should be greater than both P(EV) and P(LP).
As shown, the P(LP) threshold is always stricter than the P(EV) threshold.

#>

Tuesday, May 20, 2025

TF Pace-Map EPF Scenarios

WCMI Timeform Pace Maps: Early Position Scenarios

Timeform Pace Maps


If you subscribe to Timeform, you will most likely be familiar with its Flat-Racing Pace-Maps (see the first image below, horse names blurred out). The map aims to reflect the most likely early position scenarios for a specific race.

🔍 NOTE: The pace map and the Monte-Carlo simulations model early race positions (typically after two furlongs), not finishing positions. They help predict how the race will unfold tactically, not which horse will ultimately win.

Timeform Racecard Pace Map


Pace Map EPF Probability Analyzer

I confess that converting colour gradations into probability estimates is not my strong suit, but I wondered if my neighbourhood Large Language Model (LLM) might have such expertise.

Early Position Figures (EPFs) indicate where a horse is likely to be positioned in the early stages of a race. In Timeform's system, EPF 1 represents a horse that leads/front-runner, while higher numbers (up to 9) indicate horses that will be positioned further back in the field.

We can analyze these pace maps, as follows:

  1. Image Encoding and Preparation:

    The pace map, typically provided as an image (screenshot), is first converted into a base64-encoded string suitable for analysis.

def encode_image_to_base64(image_path):
    """Convert image to base64 string for API submission"""
    with open(image_path, "rb") as image_file:
        return base64.b64encode(image_file.read()).decode('utf-8')  
...  
def prepare_image(state: dict) -> dict:
    """Prepare the image for API submission"""
    new_state = state.copy()
    try:
        base64_image = encode_image_to_base64(new_state['image_path'])
        new_state['base64_image'] = base64_image
        print(f"Successfully encoded image for API submission")
    except Exception as e:
        print(f"Error encoding image: {str(e)}")
        raise
    return new_state
  1. LLM-based Image Analysis:

    Utilising a state-of-the-art Large Language Model (LLM) from an external API, the analyser decodes the graphical data. It identifies the predicted positions (marked with black dots) and interprets the colour intensities (shades of red) as probability distributions for each horse's Early Position Figure (EPF). Darker shades of red indicate higher probability, while lighter shades represent lower probability of a horse taking that position.

def analyze_with_llm(state: dict) -> dict:
    """Send the image to LLM API for analysis"""
    new_state = state.copy()
    
    client = llm.LLM(api_key=LLM_API_KEY)
    
    # Prepare the system prompt
    system_prompt = """
    You are an expert in analyzing horse racing pace maps. You will analyze the uploaded "Pace Map" image and extract Early Position Figure (EPF) data.
    
    For each horse, identify:
    1. The predicted EPF position (where the black dot is located)
    2. The probability distribution (from color intensity)
    
    Convert this data into parameters for a triangular probability distribution with:
    - EPFProbMin: the minimum probability estimate based on color intensity
    - EPFProbMode: the peak probability at the predicted position (black dot)
    - EPFProbMax: the maximum probability estimate
    
    Return results in CSV format with header: Horse;EPF;EPFProbMin;EPFProbMode;EPFProbMax
    Only include the CSV data in your response, no additional text or explanations.
    """
    
    # Prepare the user prompt
    user_prompt = "Using the attached 'Pace Map' for the horse race, analyze each horse's Early Position Figure (EPF) data and convert it into parameters for a triangular probability distribution. The black dots indicate predicted positions, while the heat map colors show probability densities. Please output only the CSV data with the following fields: Horse;EPF;EPFProbMin;EPFProbMode;EPFProbMax"
    
    try:
        # Create the message with the image
        response = client.messages.create(
            model="llm-3",
            system=system_prompt,
            max_tokens=6144, # 4096,
            messages=[
                {
                    "role": "user",
                    "content": [
                        {
                            "type": "image",
                            "source": {
                                "type": "base64",
                                "media_type": "image/jpeg",
                                "data": new_state['base64_image']
                            }
                        },
                        {
                            "type": "text",
                            "text": user_prompt
                        }
                    ]
                }
            ]
        )
        
        new_state['llm_response'] = response.content[0].text
        print("Successfully received analysis from LLM API")
    except Exception as e:
        print(f"Error calling LLM API: {str(e)}")
        raise

    return new_state
  1. Probability Distribution Generation:
    The program then translates the graphical data into parameters suitable for a triangular probability distribution. A triangular distribution is a simple probability model that uses three points - minimum, maximum, and most likely (mode) - making it ideal for this kind of analysis where we have limited information but can estimate these three key values. For each horse, it identifies:
    • EPFProbMin: the minimum likely probability,
    • EPFProbMode: the peak probability (indicated by the black dot),
    • EPFProbMax: the maximum likely probability.
def process_llm_response(state: dict) -> dict:
    """Extract and process CSV data from LLM's response"""
    new_state = state.copy()
    try:
        # Extract just the CSV data (removing any markdown formatting)
        response_text = new_state['llm_response']
        
        # Handle potential markdown code blocks
        if "```" in response_text:
            csv_data = response_text.split("```")[1]
            if csv_data.startswith("csv"):
                csv_data = csv_data[3:].strip()
        else:
            csv_data = response_text.strip()
            
        # Parse CSV data into a DataFrame
        df = pd.read_csv(io.StringIO(csv_data), sep=';')
        new_state['epf_results'] = df
        
        print(f"Successfully processed data for {len(df)} horses")
        print("\nPreview of parsed data:")
        print(tabulate(df.head(11), headers='keys', tablefmt='psql', showindex=False))
        
    except Exception as e:
        print(f"Error processing LLM response: {str(e)}")
        raise
        
    return new_state
  1. Structured Data Output:
    The final insights are presented in a clear CSV format, enabling easy integration with further analysis or betting models. The second image below shows this structured output, with each horse's EPF and associated probability parameters clearly displayed.

  2. Data Preparation for Simulation:
    Once we have the structured EPF data generated previously (minimum, mode, and maximum probabilities for each horse's predicted early position), we can load and prepare this data for a Monte Carlo simulation. This bridges our pace map analysis to a more dynamic model of race positioning.

def prepare_simulation_data(state: dict) -> dict:
    """ Prepare data for Monte Carlo simulation by organizing horse data. """

    new_state = state.copy()
    df = new_state['csv_results']
    
    # Create a data structure for each horse with its parameters
    horses_data = []
    for _, row in df.iterrows():
        horse_data = {
            'Horse': row['Horse'],
            'EPF': row['EPF'],
            'EPFProbMin': row['EPFProbMin'],
            'EPFProbMode': row['EPFProbMode'],
            'EPFProbMax': row['EPFProbMax']
        }
        horses_data.append(horse_data)
    
    new_state['horses_data'] = horses_data
    print(f"Prepared simulation data for {len(horses_data)} horses.")
    
    return new_state
  1. Executing the Simulation:

Each horse's early position is simulated numerous times (e.g., 100,000 iterations) using a triangular probability distribution. Each iteration introduces slight random variations, reflecting real-world uncertainties in how races unfold.

def run_monte_carlo_simulation(state: dict) -> dict:
    """ Run Monte Carlo simulation to predict early position running order. """
    
    new_state = state.copy()
    horses_data = new_state['horses_data']
    num_simulations = new_state.get('num_simulations', 10000)
    
    # Storage for all simulation results
    all_orders = []
    
    for sim in range(num_simulations):
        horse_positions = []
        
        for horse in horses_data:
            # Sample from triangular distribution to get certainty level
            certainty = np.random.triangular(
                horse['EPFProbMin'],
                horse['EPFProbMode'],
                horse['EPFProbMax']
            )
            
            # Calculate maximum possible variation based on certainty
            # Higher certainty = less variation
            max_variation = 3.0 * (1.0 - certainty)
            
            # Generate random variation within the max range
            variation = np.random.uniform(-max_variation, max_variation)
            
            # Calculate realized position
            realized_position = horse['EPF'] + variation
            
            horse_positions.append({
                'Horse': horse['Horse'],
                'EPF': horse['EPF'],
                'RealizedPosition': realized_position
            })
        
        # Sort horses by realized position (ascending)
        sorted_horses = sorted(horse_positions, key=lambda x: x['RealizedPosition'])
        
        # Extract the running order
        running_order = [horse['Horse'] for horse in sorted_horses]
        all_orders.append(running_order)
    
    new_state['simulation_results'] = all_orders
    print(f"Completed {num_simulations} Monte Carlo simulations.")
    
    return new_state
  1. Analyzing Simulation Results:
    • All simulated outcomes are aggregated, identifying the most frequent early running orders.
    • The method calculates the probability of each horse occupying each possible early position, delivering clear insights into each horse's likely early placement.
def analyze_simulation_results(state: dict) -> dict:
    """ Analyze the results of Monte Carlo simulations. """
    
    new_state = state.copy()
    all_orders = new_state['simulation_results']
    
    # Count frequency of each running order
    order_counter = Counter(tuple(order) for order in all_orders)
    total_simulations = len(all_orders)
    
    # Convert to probability and sort by frequency
    order_probabilities = [
        {
            'Running Order': order,
            'Count': count,
            'Probability': count / total_simulations
        }
        for order, count in order_counter.items()
    ]
    
    # Sort by probability (descending)
    order_probabilities.sort(key=lambda x: x['Probability'], reverse=True)
    
    # Take top N most likely running orders
    top_n = min(10, len(order_probabilities))
    top_orders = order_probabilities[:top_n]
    
    # Also analyze position probabilities for each horse
    horse_positions = {horse['Horse']: [0] * len(new_state['horses_data']) for horse in new_state['horses_data']}
    
    for order in all_orders:
        for position, horse in enumerate(order):
            horse_positions[horse][position] += 1
    
    # Convert to probabilities
    for horse in horse_positions:
        for position in range(len(horse_positions[horse])):
            horse_positions[horse][position] /= total_simulations
    
    # Store results
    new_state['top_running_orders'] = top_orders
    new_state['horse_position_probabilities'] = horse_positions
    
    print(f"Analyzed simulation results. Found {len(order_probabilities)} unique running orders.")
    
    return new_state
  1. Early Position Probabilities Ultimately, we display the detailed position probabilities for each horse in a comprehensive table, as shown in the third image below. The green highlighted values indicate the most likely position for each horse. For example, horse "India" has a 0.757 (75.7%) probability of taking the first position (EP-1), while "Golf" has a 0.4386 (43.86%) probability of starting in position 9 (EP-9).

Practical Applications

These probability distributions can be extremely valuable for handicappers and bettors who consider race dynamics in their analysis. For instance:

  • Identifying potential pace scenarios to spot races likely to favor frontrunners or closers
  • Finding horses that might be disadvantaged by their running style given the expected pace
  • Looking for overlays where a horse's tactical position might give it an advantage not fully reflected in its odds
  • Constructing exotic wagers (exactas, trifectas) based on likely early running positions

As ever, the code snippets are only a starting point for your own explorations. Tread carefully.

Enjoy!


Note: The final draft of this post was sanity checked by ChatGPT.

Monday, April 21, 2025

Expected Value and Likely Profit II: Different Playbooks

WCMI Expected Value and Likely Profit II: Different Playbooks

'EV' vs. 'EV+LP'

For the Bookmaker, EV adds up. For the Bettor, EV+LP goes forth and multiplies!

In our original post, we introduced Likely Profit (LP) as a complementary metric to Expected Value (EV). To recap clearly:

  • Expected Value (EV) measures the average profit per bet. It is an additive metric, suited to the bookmaker's scenario of multiple parallel bets.
  • Likely Profit (LP) measures the expected geometric (logarithmic) growth rate of our bankroll. It is a multiplicative metric, reflecting the bettor's sequential reality and limited bankroll.

Mathematically, these metrics are defined as follows:

E V = ( W B × P ) + ( L B × ( 1 P ) ) 1 \begin{align} \tag{a} EV = (WB \times P) + (LB \times (1 - P)) - 1 \end{align}

L P = ( W B P × L B ( 1 P ) ) 1 \begin{align} \tag{b} LP = (WB^{P} \times LB^{(1 - P)}) - 1 \end{align}

Where:

  • WB (Win-Balance multiplier) is the bankroll multiplier if the bet wins (e.g., W B = ( 1 + ( F ( O 1 ) ) ) WB = (1 + (F * (O - 1))) ).
  • LB (Loss-Balance multiplier) is the bankroll multiplier if the bet loses (e.g., L B = ( 1 F ) LB = (1 - F) ).
  • F is the stake.
  • O is the decimal odds.
  • P is the probability of winning.

Bookmaker's Additive World: Why EV is King

Take a small edge from every bet and let volume do the rest.

Bookmakers handle hundreds or thousands of bets simultaneously, each priced with a built-in margin ("vig"), ensuring each bet has a positive expected value from the bookmaker's perspective. With effectively unlimited bankroll and diversified action, bookmakers invoke the law of large numbers, ensuring actual profits converge closely to the expected profits.

In the bookmaker's additive world, EV is the definitive metric because:

  • Volume smooths out variance, making EV directly translate into predictable profits.
  • Bankroll size is enormous, meaning the bookmaker does not worry about short-term fluctuations from individual outcomes.
  • Profitability is guaranteed over time, given a positive EV across many bets.

Thus, bookmakers focus exclusively on EV, setting odds to guarantee their additive advantage. They care about aggregate profit, not about individual outcomes.

Bettor's Sequential Reality: Why EV Needs LP

Maximize bankroll growth, not just average payout.

Now, switch seats to a bettor's perspective. Unlike bookmakers, bettors cannot make thousands of simultaneous bets. Instead, bettors sequentially place bets over time with limited bankrolls. Each bet outcome directly influences future betting capacity, making their reality multiplicative rather than additive. The multiplicative effect means that the order and size of wins and losses matter a lot.

Here is where Likely Profit (LP) becomes essential:

  • LP measures the expected geometric (logarithmic) growth rate of our bankroll.
  • LP is closely related to the Kelly criterion, well-known in finance and betting for maximizing long-run bankroll growth.
  • LP effectively considers that bankroll growth is multiplicative, and thus, variance and bet sizing matter greatly for survivor bias and long-term wealth accumulation.

While EV alone indicates average profit per bet, LP indicates how our bankroll is expected to compound over time. A bet with positive EV but negative LP could lead to significant bankroll volatility, potentially resulting in ruin before the theoretical EV manifests.

Practical Example: EV vs EV+LP in Action

Scenario: You have a $1,000 bankroll and have decided to stake $100 (10% of our bankroll) on one of two bets. Both bets have the same EV (+$10), but differ significantly in risk and profile:

  • Bet X (High-risk, high-reward bet):

    • Odds: +1000 (decimal 11.0)
    • Our estimated true probability: 10% (implied odds = 9.1%)
    • Crucially, LP is negative, indicating expected bankroll shrinkage over repeated bets of this type at this stake fraction.
  • Bet Y (Lower-risk, moderate-reward bet):

    • Odds: +100 (decimal 2.0)
    • Our estimated true probability: 55% (implied odds = -122)
    • LP is positive, indicating expected bankroll growth over repeated sequential bets of this type.

Both bets have identical EV, yet Bet Y clearly outshines Bet X when evaluated holistically using EV+LP. Bet Y's positive LP means it's better suited for sustainable bankroll growth, lower variance, and greater certainty of survival.

This example starkly highlights that as a bettor, we must consider LP as well as EV to intelligently balance profit potential, risk, and bankroll longevity.

Different Goals, Different Metrics

Bookmakers and bettors have fundamentally different goals and constraints:

  • Bookmakers operate in an additive world with massive diversity and bankroll, making EV sufficient.
  • Bettors face multiplicative outcomes with limited bankrolls, making EV necessary but insufficient. They must also consider LP to ensure survival through inevitable volatility and to maximize bankroll growth.

Thus, the metrics they optimize diverge:

Perspective Metric Goal
Bookmaker EV (additive) Maximize total profit
Bettor EV + LP (multiplicative) Maximize long-term bankroll growth

Playing Correct Perspective

In sum, to succeed as a bettor, we must combine the mathematical rigor of EV identification with the strategic prudence of LP-based bankroll management. Selecting only positive-EV bets is necessary but not sufficient. We must also size our bets to ensure positive LP, aligning our strategy with geometric bankroll growth and survival.

In short:

  • EV answers: "How much do I win on average per bet?"
  • LP answers: "How will my bankroll realistically grow over many sequential bets?"

A savvy bettor understands both and uses them in tandem, ensuring a profitable journey not just theoretically, but practically.

By clearly understanding these dual metrics, we can meaningfully improve our betting strategy, aligning our actions with our real-world constraints and maximizing our probability of success in the long run.

Enjoy!


Note: The final draft of this post was sanity checked by ChatGPT.

Wednesday, March 12, 2025

Cheltenham (2025-03-13) - Selections

WCMI Cheltenham Live-Longshot Selections (Gallop Poll)

Cheltenham (2025-03-13) - Selections


Throwing caution to the wind and letting our private LLM bot loose on the hallowed Cheltenham turf to see how it performs. It made the following selections, and we have not curated its choices or supporting evidence.

Tread carefully!

Gallop Poll Selections and Supporting Evidence


Result:


1. Doddiethegreat, 27.0

2. Jeriko Du Reponet, 8.80

Sunday, February 23, 2025

Neigh Sayers and Gallop Polls

WCMI Neigh Sayers and Gallop Polls

Neigh Sayers


Imagine the scenario: "Two horses abreast heading for the final hurdle in a major handicap race of the Cheltenham Festival and one of those contenders ('Neigh Sayer') has £20 each-way of your hard-earned cash pinned on its success at 20/1. You can already anticipate congratulations from your mates on this successful convex bet..." As Weekend Warriors, we all dream of such improbable successes!

Live Longshot:


Now consider asking a ChatGPT-like private LLM bot to select (and justify) those bets for you. For the upcoming Cheltenham Festival, we are hopeful (though not guaranteeing) that we will provide some recommendations (from our Live-Longshot bot) for a few of the more challenging races!

Taster:


Here is a taster...

Enjoy!

Tuesday, December 24, 2024

Ensemble vs Time: Betting Strategy Simulation

WCMI Ensemble vs Time: Betting Strategy Simulation

Ensemble vs Time: Betting Strategy Simulation


Imagine a lively casino brimming with daydreamers hoping to spin meagre coins into great fortunes one bet at a time. Others position themselves on the sidelines, cheerfully tallying the incoming bets. The daydreamers are the players, and the sideliners are the house.


Volatility Drag

In the bustling arena of sports trading, a hidden force exists called volatility drag: the mathematical difference between geometric and arithmetic averages. This difference resembles a tax due to the mathematics, which imposes a lower compound return when returns vary over time. This difference between the average outcome that a bookmaker tallies (from countless eager bettors) and a single bettor's actual lived experience can become very wide.

To illustrate, we have created a Betting Strategy Simulator that reveals how luck may bolster or batter your bankroll.


Two Sides of the Same Bet

  1. Time Perspective (Median)
    Regard this perspective as the lone trader, placing multiple bets in sequence. Each triumph or tumble weighs heavily on their well-being. Over many tries, their median final bankroll can suffer from volatility drag, meaning a few unlucky tumbles may gouge deeper than occasional victories can heal.
  2. Ensemble Perspective (Mean)
    Consider the bookmaker presiding over a torrent of simultaneous wagers. In that swirling chaos, all results average out. While heartbreak and jubilation strike individuals, the house sees a calm, aggregated mean that, if well-calculated, coasts along in a far more stable fashion than a single bankroll can hope for.

Key Parameters

  • Probability of Winning: A Percentage.
  • Odds: For example, odds of 2.30 yield the stake plus 130% more if we win.
  • Stake: The size of each bet (percentage).
  • Number of Bets: Length of the trader's journey or the repeated steps over which the bookmaker aggregates.
  • Number of Simulations: Number of scenario replications.

Running Simulation

  1. Inputs
    • Enter probability, odds, stake, and so on.
  2. Process
    • Click on Run Simulation to launch the simulation.
  3. Outputs
    • Monte Carlo (Time) Results: The Median Final Bankroll for the solitary trader forging through a sequence of wagers. The geometric rise (or descent!) becomes evident here.
    • Monte Carlo (Ensemble) Results: The Mean Final Bankroll from the vantage of the house. With each bet in parallel, the chaos yields a predictable average - an expected value.

Under the Hood

  • Time: We line up (N)(N) traders, each living out (M)(M) consecutive bets. Their final bankrolls vary widely, but the median is the honest sentinel of their fortunes.
  • Ensemble: We replicate (N)(N) parallel bets for each of (M)(M) rounds, calculate the mean outcome each time, and watch the bankroll grow in that aggregated manner.
  • Volatility Drag: If there is one lesson to learn, it is that a 50% dip requires a 100% surge to climb out of the pit. The bigger the stake, the more each stumble stings and volatility seldom shows mercy.


Reading Results

  1. Single Bettor's Plight
    The median bankroll can unravel if luck sends you through a rough patch. Even with a favourable win probability, sustained drawdowns hurt more than fleeting upticks help.

  2. Parallel Paradise
    The bookmaker's many concurrent bets form a serene environment where the mean bankroll (averaged across countless outcomes) marches forward in lockstep with the basic mathematics of expected value.

  3. Practical Wisdom

    • As a punter, carefully consider the violent power of sequential losses. Bankroll management becomes your shield, lest a string of flops knock you out.
    • As the house or aggregator of bets, relax behind a wide net of players, diluting the wilder swings of misfortune.

Looking Forward

Volatility drag is a subtle and cunning opponent that shrinks big dreams. The simulator reminds us that mean vs. median can diverge drastically. The sports trader sees the ephemeral illusions of large short-term gains, recognising the risk that a run of losses can carve away capital faster than big wins can restore it. Meanwhile, the bookmaker basks in the calm assurance of ensembles: a stable accumulation of profits gleaned from the grand churn of wagers.

If nothing else, remember that early wins are crucial in the time dimension but not so in the Ensemble dimension!

Enjoy!


Note: An LLM generated the first draft of this post based on our simulator code listing.