API
Here is the API documentation for the pybet package.
- class pybet.market.Market
A betting market represented by a dictionary of runners and odds
- Attributes:
places: The number of winning places in the market (default 1, i.e. win only).
- Example:
>>> runners = ['Frankel', 'Sea The Stars', 'Nijinsky', 'Mill Reef', 'Quixall Crossett'] >>> odds = [Odds(x) for x in [2, 4, 5, 10, 1000]] >>> market = Market(zip(runners, odds), places=2)
- apply_margin(margin: Decimal) Market
Applies the specified margin to each runner’s underlying price, and thus to the overround. It is not applied cumulatively, i.e. a 10% margin applied to a market with a 105% overround, will become a 110% market, not 115%.
- Parameters:
margin (Decimal) – The margin to apply to the market
- Returns:
A revised market with the specified margin built in
- Return type:
- Example:
>>> market = Market({'Frankel': Odds(3), 'Sea The Stars': Odds(3), 'Nijinsky': Odds(3)}) >>> market.apply_margin(20).get('Frankel') Decimal('2.5')
- derive(places: int, *, discounts: list[float] | None = None) Market
Derives a place market from a win market using the Harville formula (see https://en.wikipedia.org/wiki/Harville_formula) applying a specified discounted version of that formula if required
- Parameters:
places (int) – The number of places to derive the market for
discounts (List[float], optional) – A list of discounts to apply to the probability of each horse in the market, defaults to None
- Raises:
ValueError – If the number of places is invalid
ValueError – If the market is not a win market
- Returns:
A revised market with the specified number of places
- Return type:
- Example:
>>> market = Market({'Frankel': Odds(3), 'Sea The Stars': Odds(3), 'Nijinsky': Odds(3)}) >>> market.derive(2).get('Frankel') Decimal('1.5')
- equalise() Market
Resets a market so that all runners have equal odds with no overround
- Returns:
A revised market with no margin built in
- Return type:
- Example:
>>> market = Market({'Frankel': Odds(2.5), 'Sea The Stars': Odds(2.5), 'Nijinsky': Odds(2.5), 'Dancing Brave': Odds(2.5)}) >>> market.equalise().get('Frankel') Decimal('4')
- property favourites: list[Any]
Returns list of runners that are favourite for the event Note: Will be a list even if there is only one favourite
- Returns:
A list of market favourites
- Return type:
List[Any]
- fill(margin: Decimal = Decimal('0')) Market
Fills out any missing odds in the market proportionately so that the specified margin is achieved
- Parameters:
margin (Decimal, optional) – The margin to build into the market, defaults to zero
- Raises:
ValueError – if there is already a larger margin built into the market
- Returns:
A market with all missing odds filled in
- Return type:
- Example:
>>> market = Market({'Frankel': Odds(4), 'Sea The Stars': Odds(4), 'Nijinsky': Odds(4), 'Dancing Brave': None}) >>> market.fill().get('Dancing Brave') Decimal('4')
- property is_fair: bool
Whether the market has no bias in favour of backer or layer
- Returns:
True if there is no inbuilt margin, false otherwise
- Return type:
bool
- property is_overbroke: bool
Whether the market has no bias in favour of bettor or layer
- Returns:
True if market as a whole in backer’s favour, false otherwise
- Return type:
bool
- property is_overround: bool
Whether the market is overround or not
- Returns:
True if market as a whole in layer’s favour, false otherwise
- Return type:
bool
- meld(other: Market, other_percentage: float = 50) Market
Melds two markets together so that the odds for each runner are a weighted average of the two markets
- Parameters:
other (Market) – The market to meld with
other_percentage (float, optional) – The percentage of the melded market that should be made up of the other market, defaults to 50
- Raises:
ValueError – if the two markets do not have the same runners
- Returns:
A market with the weighted average odds of the two markets
- property overround_per_runner: Decimal
Excess market percentage divided by number of runners
- Returns:
The overround per runner
- Return type:
Decimal
- property percentage: Decimal
The total market percentage of all runners
- Returns:
The percentage market
- Return type:
Decimal
- places: int = 1
- wipe() Market
Wipe market so that none of the runners have any odds
- Returns:
An empty market
- Return type:
- Example:
>>> market = Market({'Frankel': Odds(4), 'Sea The Stars': Odds(4), 'Nijinsky': Odds(4), 'Dancing Brave': Odds(4)}) >>> list(market.wipe().values()) [None, None, None, None]
- without(runners: list[Any]) Market
Create a new market with the specified runners removed
- Parameters:
runners (List[Any]) – Runners to remove from the market
- Returns:
A new market without the specified runners
- Return type:
- Example:
>>> market = Market({'Frankel': Odds(4), 'Sea The Stars': Odds(4), 'Nijinsky': Odds(4), 'Dancing Brave': Odds(4)}) >>> new_market = market.without(['Frankel']) >>> list(new_market.keys()) ['Sea The Stars', 'Nijinsky', 'Dancing Brave']
- class pybet.odds.FractionalOddsSets
Constant lists of fractional odds for use in Odds instances to determine the proximate fractional odds to any particular value
- STANDARD = ['1/1', '2/1', '3/1', '4/1', '5/1', '6/1', '7/1', '8/1', '9/1', '10/1', '12/1', '14/1', '16/1', '18/1', '20/1', '22/1', '25/1', '33/1', '40/1', '50/1', '66/1', '80/1', '100/1', '150/1', '200/1', '250/1', '500/1', '1000/1', '5/2', '7/2', '9/2', '11/2', '13/2', '15/2', '5/4', '9/4', '11/8', '13/8', '15/8', '10/3', '6/4', '11/10', '1/2', '1/3', '1/4', '1/5', '1/6', '1/7', '1/8', '1/9', '1/10', '1/12', '1/14', '1/16', '1/18', '1/20', '1/22', '1/25', '1/33', '1/40', '1/50', '1/66', '1/80', '1/100', '1/150', '1/200', '1/250', '1/500', '1/1000', '2/5', '2/7', '2/9', '2/11', '2/13', '2/15', '4/5', '4/9', '8/11', '8/13', '8/15', '3/10', '4/6', '10/11']
- odds_against = ['1/1', '2/1', '3/1', '4/1', '5/1', '6/1', '7/1', '8/1', '9/1', '10/1', '12/1', '14/1', '16/1', '18/1', '20/1', '22/1', '25/1', '33/1', '40/1', '50/1', '66/1', '80/1', '100/1', '150/1', '200/1', '250/1', '500/1', '1000/1', '5/2', '7/2', '9/2', '11/2', '13/2', '15/2', '5/4', '9/4', '11/8', '13/8', '15/8', '10/3', '6/4', '11/10']
- class pybet.odds.Odds(value='0', context=None)
A class that allows decimal odds to be created from and converted to a range of other odds formats
- classmethod evens() Odds
Convenience constructor for creating an Odds value of evens
- Returns:
An Odds instance equal to evens
- Return type:
- classmethod fractional(arg: Fraction) Odds
- classmethod fractional(arg: str) Odds
- classmethod fractional(arg1: int, arg2: int) Odds
Creates an Odds instance from fraction-like input, including typical odds strings like ‘9/4’, ‘9-4’, ‘9:4’
- Returns:
An Odds instance equal to the value of the fraction passed in
- Return type:
- Example:
>>> Odds.fractional(Fraction(9, 4)) Decimal('3.25') >>> Odds.fractional('9/4') Decimal('3.25') >>> Odds.fractional(9, 4) Decimal('3.25')
- classmethod inverted(value: Decimal) Odds
Creates an Odds instance that is the inverse of the input value, i.e. turns an odds on value into odds against and vice versa
- Parameters:
value (Decimal) – A decimal representation of the odds to invert
- Returns:
An odds instance representing the inverse of the value passed in
- Return type:
- Example:
>>> Odds.inverted(5) Decimal('1.25')
- property is_odds_against: bool
Whether the Odds instance is odds against
- Returns:
True for odds greater than evens, false otherwise
- Return type:
bool
- Example:
>>> Odds(3).is_odds_against True >>> Odds(0.33).is_odds_against False
- property is_odds_on: bool
Whether the Odds instance is odds against
- Returns:
True for odds less than evens, false otherwise
- Return type:
bool
- Example:
>>> Odds(0.33).is_odds_on True >>> Odds(3).is_odds_on False
- lengthen(percentage_points: Decimal) Decimal
Increases the chance represented by the current Odds instance by the specified number of percentage points and returns a new Odds instance with that value, i.e. “lengthening” the odds
- Parameters:
percentage_points (Decimal) – Number of percentage points by which to increase the chance represented by the Odds
- Returns:
A new Odds instance
- Return type:
Decimal
- Example:
>>> Odds(4).lengthen(5) Decimal('5')
- classmethod moneyline(value: str | int) Odds
Creates an Odds instance from an American moneyline value
- Parameters:
value (Union[str, int]) – A representation of the moneyline value, e.g. -90
- Raises:
ValueError – if the value is between the bounds of -100 and 100 and not suitable for moneyline values
- Returns:
An odds instance representing the moneyline value passed in
- Return type:
- Example:
>>> Odds.moneyline(100) Decimal('2.0') >>> Odds.moneyline('-125') Decimal('1.8')
- classmethod percentage(value: Decimal) Odds
Creates an Odds instance from an equivalent percentage chance > 0 and < 100
- Parameters:
value (Decimal) – A representation of the odds as a percentage
- Raises:
ValueError – if the value is not between 0 and 100%
- Returns:
An odds instance representing the percentage value passed in
- Return type:
- Example:
>>> Odds.percentage(40) Decimal('2.5')
- classmethod probability(value: Decimal) Odds
Creates an Odds instance from an equivalent probability > 0 and < 1
- Parameters:
value (Decimal) – A representation of the odds as a probability
- Raises:
ValueError – if the value is not between 0 and 1
- Returns:
An odds instance representing the probability passed in
- Return type:
- Example:
>>> Odds.probability(0.4) Decimal('2.5')
- shorten(percentage_points: Decimal) Odds
Decreases the chance represented by the current Odds instance by the specified number of percentage points and returns a new Odds instance with that value, i.e. “shortening” the odds
- Parameters:
percentage_points (Decimal) – Number of percentage points by which to decrease the chance represented by the Odds
- Returns:
A new Odds instance
- Return type:
Decimal
- Example:
>>> Odds(5).shorten(5) Decimal('4')
- to_fractional(fractional_set: list[str], delim: str) str
- to_fractional(fractional_set: list[Fraction], delim: str) str
- to_fractional(fractional_set: list[tuple[int, int]], delim: str) str
Returns an Odds instance as a fractional string with the given delimiter (default ‘/’). The return value will be the closest equivalent value found in the given fractional_set.
- Parameters:
fractional_set (List[str], optional) – A set of fractional odds to select from, defaults to standard UK fractionals
delim (str, optional) – A delimiter for the odds string, defaults to “/”
- Raises:
ValueError – if the odds set provided is empty
- Returns:
A string representation of the odds in fractional form
- Return type:
str
- Example:
>>> odds_set = ['3/1', '10/3', '7/2'] >>> Odds(4.27).to_fractional(odds_set) '10/3' >>> odds_set = ['3/1', '13/4', '10/3', '7/2'] >>> Odds(4.27).to_fractional(odds_set, '-') '13-4'
- to_moneyline() str
Returns an Odds instance as a string moneyline value
- Returns:
An Odds instance in moneyline format
- Return type:
str
- Example:
>>> Odds.evens().to_moneyline() '-100'
- to_one() Decimal
Returns Odds instance as a value “to one”, i.e. like fractional odds, but the numerator can be a decimal
- Returns:
The Odds instance adjusted to a “to one” value
- Return type:
Decimal
- Example:
>>> Odds(5).to_one() Decimal('4')
- to_percentage() Decimal
Returns an Odds instance as an equivalent percentage chance
- Returns:
The Odds instance as a percentage
- Return type:
Decimal
- Example:
>>> Odds(5).to_percentage() Decimal('20')
- to_probability() Decimal
Returns an Odds instance as an equivalent probability
- Returns:
The Odds instance as a probability
- Return type:
Decimal
- Example:
>>> Odds(5).to_probability() Decimal('0.2')
- class pybet.bets.Accumulator(stake: float | Decimal | str, bet_list: list[tuple[Odds | str, Callable[[...], bool], Callable[[...], bool] | None]], *, bog: bool = False)
- class pybet.bets.Bet(stake: float | ~decimal.Decimal | str, odds: ~pybet.odds.Odds | ~typing.Literal['SP'], win_condition: ~typing.Callable[[...], bool], end_condition: ~typing.Callable[[...], bool] = <function Bet.<lambda>>, *, bog: bool = False)
A class to represent a bet.
- Attributes:
stake: The stake of the bet. odds: The odds of the bet. win_condition: The callback that will determine whether the bet is currently a winner or a loser. end_condition: The callback that will determine whether the bet can be settled.
- Example:
>>> bradford_city = {'position': 1} >>> games_played = 45 >>> bradford_win_league = lambda: bradford_city['position'] == 1 >>> season_over = lambda: games_played == 46 >>> bet = Bet(2.00, Odds(21), bradford_win_league, season_over)
- class Status(value, names=None, *, module=None, qualname=None, type=None, start=1, boundary=None)
An enum to represent the status of a bet.
- LOST = 2
- OPEN = 0
- VOID = 3
- WON = 1
- settle(*, sp: Odds | None = None, rf: int | Decimal = 0) Decimal
Returns the returns of the bet.
- Returns:
The returns of the bet to 2 decimal places
- Return type:
Decimal
- Raises:
ValueError – If the bet is still open
- Example:
>>> bet = Bet(2.00, Odds(21), bradford_win_league, season_over) >>> bet.settle() ValueError: Bet is still open >>> games_played = 46 >>> bet.settle() 42.00 >>> bradford_city['position'] = 2 >>> bet.settle() 0
- property status: Status
Returns the status of the bet.
- Returns:
The status of the bet
- Return type:
- Example:
>>> bet = Bet(2.00, Odds(21), bradford_win_league, season_over) >>> bet.status <Status.OPEN: 0> >>> games_played = 46 <Status.WON: 1> >>> bradford_city['position'] = 2 <Status.LOST: 2>
- void() None
Voids the bet.
- Returns:
None
- class pybet.bets.Double(stake: float | Decimal | str, bet_list: list[tuple[Odds | str, Callable[[...], bool], Callable[[...], bool] | None]], *, bog: bool = False)
- class pybet.bets.Treble(stake: float | Decimal | str, bet_list: list[tuple[Odds | str, Callable[[...], bool], Callable[[...], bool] | None]], *, bog: bool = False)
- pybet.staking.kelly(true_odds: Odds, market_odds: Odds, bank: Decimal, percentage_commission: Decimal = Decimal('0')) Decimal
Calculates the stake that should be placed according to the Kelly Criterion [https://en.wikipedia.org/wiki/Kelly_criterion], i.e. edge over odds for any given true odds at any given market odds for any given bank size
- Parameters:
- Returns:
The stake to place according to the Kelly criterion
- Return type:
Decimal
- Example:
>>> kelly(Odds(4), Odds(5), 100) Decimal('6.25') >>> kelly(Odds(5), Odds(4), 100) Decimal('0.00')