Skip to main content

Overview

The StakeCalculator provides methods for calculating optimal stakes across multiple arbitrage betting strategies, including standard arbitrages, risk-free high/low returns, and LAY betting on exchanges.

StakeCalculator

Standard Arbitrage

Calculate stakes for guaranteed equal profit regardless of outcome.
from PROPPR.PropprArbBot.core.calculator.stake_calculator import StakeCalculator

result = StakeCalculator.calculate_standard_arb(
    total_stake=100.0,
    legs=[
        {"bookmaker": "Bet365", "side": "over", "odds": "2.10"},
        {"bookmaker": "Pinnacle", "side": "under", "odds": "2.05"}
    ],
    exchange_commission=0.02
)
total_stake
float
required
Total amount to stake across all legs
legs
array
required
List of bet legs with bookmaker, side, and odds
exchange_commission
float
default:"0.02"
Exchange commission rate (default 2% for Betfair)
type
string
Calculation type (“standard”)
total_stake
float
Total stake amount
profit_margin
float
Profit margin percentage
guaranteed_profit
float
Guaranteed profit amount
stakes
array
Individual stake calculations
[
    {
        "bookmaker": "Bet365",
        "side": "over",
        "odds": 2.10,
        "stake": 48.78,
        "potential_return": 102.44
    },
    {
        "bookmaker": "Pinnacle",
        "side": "under",
        "odds": 2.05,
        "stake": 51.22,
        "potential_return": 105.00
    }
]

LAY Betting

Standard LAY Arbitrage

result = StakeCalculator.calculate_standard_arb(
    total_stake=100.0,
    legs=[
        {
            "bookmaker": "Bet365",
            "side": "over",
            "odds": "2.10",
            "is_lay": False
        },
        {
            "bookmaker": "Betfair Exchange",
            "side": "over",
            "odds": "2.15",
            "is_lay": True
        }
    ],
    exchange_commission=0.02
)
is_lay_arb
boolean
Whether this is a LAY arbitrage
exchange_commission
float
Commission percentage charged by exchange
stakes
array
Stake calculations including LAY details
[
    {
        "bookmaker": "Bet365",
        "odds": 2.10,
        "stake": 47.62,
        "potential_return": 100.00,
        "is_lay": False
    },
    {
        "bookmaker": "Betfair Exchange",
        "odds": 2.15,
        "lay_stake": 46.51,
        "stake": 46.51,
        "liability": 53.49,
        "commission": 2.0,
        "potential_return": 45.58,
        "is_lay": True
    }
]

LAY Mechanics

When you LAY a bet:
  • You act as the bookmaker
  • If selection wins: You pay liability = stake × (odds - 1)
  • If selection loses: You win stake × (1 - commission)
  • Commission only charged on winnings, not losses

Risk-Free Strategies

RF High (Maximize Upside)

Break even on lower odds outcome, maximize profit on higher odds.
result = StakeCalculator.calculate_rf_high(
    total_stake=100.0,
    legs=[
        {"bookmaker": "Bet365", "side": "home", "odds": "1.95"},
        {"bookmaker": "Pinnacle", "side": "away", "odds": "3.20"}
    ]
)
type
string
“rf_high”
low_return
float
Return if lower odds outcome wins (break even)
low_roi
float
ROI percentage for lower odds outcome (~0%)
high_return
float
Return if higher odds outcome wins
high_roi
float
ROI percentage for higher odds outcome (high profit)

RF Low (Minimize Risk)

Break even on higher odds outcome, moderate profit on lower odds.
result = StakeCalculator.calculate_rf_low(
    total_stake=100.0,
    legs=[
        {"bookmaker": "Bet365", "side": "home", "odds": "1.95"},
        {"bookmaker": "Pinnacle", "side": "away", "odds": "3.20"}
    ]
)
type
string
“rf_low”
low_return
float
Return if higher odds outcome wins (break even)
high_return
float
Return if lower odds outcome wins (moderate profit)

3-Way Markets

RF High (3-Way)

For 1X2 markets (Home/Draw/Away).
result = StakeCalculator.calculate_3way_rf_high(
    total_stake=100.0,
    legs=[
        {"bookmaker": "Bet365", "side": "home", "odds": "2.10"},
        {"bookmaker": "Pinnacle", "side": "draw", "odds": "3.40"},
        {"bookmaker": "Betfair", "side": "away", "odds": "4.50"}
    ]
)
profit_outcome
string
The outcome with profit potential
break_even_outcomes
array
Outcomes that break even
["home", "draw"]
profit_amount
float
Profit if profit outcome wins
profit_roi
float
ROI percentage for profit outcome

RF Mid (3-Way)

Break even on highest and lowest odds, profit on mid odds.
result = StakeCalculator.calculate_3way_rf_mid(
    total_stake=100.0,
    legs=[
        {"bookmaker": "Bet365", "side": "home", "odds": "2.10"},
        {"bookmaker": "Pinnacle", "side": "draw", "odds": "3.40"},
        {"bookmaker": "Betfair", "side": "away", "odds": "4.50"}
    ]
)

RF Low (3-Way)

Break even on highest odds only, profit on both lower odds.
result = StakeCalculator.calculate_3way_rf_low(
    total_stake=100.0,
    legs=[
        {"bookmaker": "Bet365", "side": "home", "odds": "2.10"},
        {"bookmaker": "Pinnacle", "side": "draw", "odds": "3.40"},
        {"bookmaker": "Betfair", "side": "away", "odds": "4.50"}
    ]
)
profit_outcomes
array
Outcomes with profit potential
["home", "draw"]
break_even_outcome
string
The outcome that breaks even (“away”)

All Scenarios

Calculate All Strategies

result = StakeCalculator.calculate_all_scenarios(
    total_stake=100.0,
    legs=[
        {"bookmaker": "Bet365", "side": "over", "odds": "2.10"},
        {"bookmaker": "Pinnacle", "side": "under", "odds": "2.05"}
    ],
    exchange_commission=0.02
)
standard
object
Standard arbitrage calculation
rf_high
object
RF High calculation
rf_low
object
RF Low calculation
rf_mid
object
RF Mid calculation (3-way only)

Market Display

Format Market Display

market_display = StakeCalculator.format_market_display(
    market={"name": "Totals", "hdp": 2.5},
    event={"sport": "Football", "home": "Man Utd", "away": "Liverpool"}
)
# Returns: "Over/Under 2.5 Goals"

Sport-Specific Units

# Football: Goals
"Over/Under 2.5 Goals"

# Basketball: Points
"Over/Under 215.5 Points"

# American Football: Points
"Over/Under 45.5 Points"

# Counter-Strike: Rounds
"Over/Under 26.5 Rounds"

# Dota 2: Towers
"Over/Under 15.5 Towers"

Format Side Display

side_display = StakeCalculator.format_side_display("over", "Totals")
# Returns: "Over"

side_display = StakeCalculator.format_side_display("home", "Moneyline")
# Returns: "Home"

Fixed Stake Calculation

Calculate with One Fixed Leg

result = StakeCalculator.calculate_with_fixed_stake(
    fixed_stake=50.0,
    fixed_leg_index=0,
    legs=[
        {"bookmaker": "Bet365", "side": "over", "odds": "2.10"},
        {"bookmaker": "Pinnacle", "side": "under", "odds": "2.05"}
    ]
)
fixed_stake
float
required
Fixed stake amount for one leg
fixed_leg_index
integer
required
Index of leg with fixed stake (0 or 1)
standard
object
Standard arb with recalculated total stake
rf_high
object
RF High with fixed leg
rf_low
object
RF Low with fixed leg

Example Usage

Complete Arbitrage Calculation

# Define arbitrage opportunity
arb_data = {
    "id": "arb_12345",
    "profitMargin": 3.73,
    "legs": [
        {"bookmaker": "Bet365", "side": "over", "odds": "2.10"},
        {"bookmaker": "Pinnacle", "side": "under", "odds": "2.05"}
    ]
}

# Calculate all strategies
total_stake = 100.0
results = StakeCalculator.calculate_all_scenarios(
    total_stake=total_stake,
    legs=arb_data["legs"]
)

# Display results
print(f"Standard: {results['standard']['guaranteed_profit']:.2f}")
print(f"RF High: {results['rf_high']['high_return']:.2f} / {results['rf_high']['low_return']:.2f}")
print(f"RF Low: {results['rf_low']['high_return']:.2f} / {results['rf_low']['low_return']:.2f}")

References

Build docs developers (and LLMs) love