Skip to content

Commit 21539eb

Browse files
authored
Merge pull request #6 from ian-shepherd/development
1.1.3 added new functions and Implied Odds and Probability enhancement
2 parents ba5b626 + 310b7bd commit 21539eb

17 files changed

+1014
-44
lines changed

CHANGELOG.md

+6
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,11 @@
11
# Change Log
22

3+
### 1.1.3 2023-06-09 Added new functionality to implied_odds() and implied_prob()
4+
* added functionality to pass various methods to account for margin of bookmaker
5+
6+
### 1.1.2 2023-06-07 Added expected value function
7+
* added expected_value_calc() calculates the expected value of given odds based on implied probability
8+
39
### 1.1.1 2023-05-29 Added unit tests and fixed bugs
410
* Added unit tests for all functions
511
* Reduced complexity of convert_odds()

__init__.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
1-
__version__ = "1.1.2"
1+
__version__ = "1.1.3"
22

33
from .pybettor import * # noqa: F401, F403

pybettor/__init__.py

+5-1
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,15 @@
1-
__version__ = "1.1.2"
1+
__version__ = "1.1.3"
22

33
from .bet_calc import bet_calc # noqa: F401
44
from .bet_prob import bet_prob # noqa: F401
55
from .break_even import break_even # noqa: F401
6+
from .clv_calc import clv_calc # noqa: F401
67
from .convert_odds import convert_odds # noqa: F401
8+
from .edge_calc import edge_calc # noqa: F401
79
from .expected_value_calc import expected_value_calc # noqa: F401
810
from .fair_odds import fair_odds # noqa: F401
11+
from .hold_calc import hold_calc # noqa: F401
12+
from .hfa_calc import hfa_calc # noqa: F401
913
from .implied_odds import implied_odds # noqa: F401
1014
from .implied_prob import implied_prob # noqa: F401
1115
from .kelly_bet import kelly_bet # noqa: F401

pybettor/clv_calc.py

+35
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
from .implied_prob import implied_prob
2+
3+
4+
def clv_calc(
5+
bet_odds: int or float, close_odds: int or float, category: str = "us"
6+
) -> float:
7+
"""Calculate Closing Line Value
8+
This function calculates the closing line value (CLV) for a given bet.
9+
10+
Args:
11+
bet_odds (int, float): Odds or Implied Win Probability for the bet
12+
close_odds (int, float): Closing Odds or Implied Win Probability for the bet
13+
category (str, optional): type of odds. Defaults to "us". \n
14+
'us', American Odds \n
15+
'dec', Decimal Odds \n
16+
'frac', Fractional Odds
17+
18+
Returns:
19+
float: Closing Line Value (CLV) of a bet
20+
"""
21+
22+
assert isinstance(bet_odds, (int, float)), "bet_odds must be numeric"
23+
assert isinstance(close_odds, (int, float)), "close_odds must be numeric"
24+
assert category in [
25+
"us",
26+
"frac",
27+
"dec",
28+
], "input category must be either: ('us', 'dec', 'frac')"
29+
30+
bet_prob = implied_prob(bet_odds, category=category)[0]
31+
close_prob = implied_prob(close_odds, category=category)[0]
32+
33+
clv = (close_prob - bet_prob) / bet_prob
34+
35+
return clv

pybettor/convert_odds.py

+5-2
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
from typing import Union
12
from fractions import Fraction
23
from .implied_odds import implied_odds
34
from .implied_prob import implied_prob
@@ -44,12 +45,14 @@ def _convert_frac_to_frac(odds):
4445
return frac
4546

4647

47-
def convert_odds(odds, cat_in="us", cat_out="all") -> list or dict:
48+
def convert_odds(
49+
odds: Union[int, float, list], cat_in="us", cat_out="all"
50+
) -> list or dict:
4851
"""Odds Converter
4952
This function converts any odds or probability.
5053
5154
Args:
52-
odds (float): Odds, or lines, for a given bet(s) (-115, -105)
55+
odds (int, float, list): Odds, or lines, for a given bet(s) (-115, -105)
5356
cat_in (str, optional): \n
5457
'us', American Odds \n
5558
'dec', Decimal Odds \n

pybettor/edge_calc.py

+30
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
from .implied_prob import implied_prob
2+
3+
4+
def edge_calc(
5+
win_prob: int or float, odds: int or float, category: str = "us"
6+
) -> float:
7+
"""Calculate the edge of a bet given the win probability and odds.
8+
9+
Args:
10+
win_prob (intorfloat): _description_
11+
odds (intorfloat): _description_
12+
category (str, optional): _description_. Defaults to "us".
13+
14+
Returns:
15+
float: edge of the bet
16+
"""
17+
18+
assert isinstance(win_prob, (int, float)), "win_prob must be numeric"
19+
assert 0 <= win_prob <= 1, "win_prob must be in the range of 0 to 1 inclusive"
20+
assert isinstance(odds, (int, float)), "odds must be numeric"
21+
assert category in [
22+
"us",
23+
"frac",
24+
"dec",
25+
"prob",
26+
], "input category must be either: ('us', 'dec', 'frac', 'prob')"
27+
28+
edge = win_prob - implied_prob(odds, category=category)[0]
29+
30+
return edge

pybettor/hfa_calc.py

+30
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
import numpy as np
2+
3+
4+
def hfa_calc(win_p_neutral: int or float, win_p_leag_hm: int or float) -> float:
5+
"""Calculate Home Field Advantage
6+
This function calculates the home field advantage (HFA) for a given bet.
7+
8+
Args:
9+
win_p_neutral (int, float): Win Probability Neutral Site
10+
win_p_leag_hm (int, float): Win Probability League Home
11+
12+
Returns:
13+
float: Home Field Advantage (HFA) of a bet
14+
"""
15+
16+
assert isinstance(win_p_neutral, (int, float)), "win_p_neutral must be numeric"
17+
assert (
18+
0 <= win_p_neutral <= 1
19+
), "win_p_neutral must be in the range of 0 to 1 inclusive"
20+
assert isinstance(win_p_leag_hm, (int, float)), "win_p_leag_hm must be numeric"
21+
assert (
22+
0 <= win_p_leag_hm <= 1
23+
), "win_p_leag_hm must be in the range of 0 to 1 inclusive"
24+
25+
log_odds_tm = np.log(win_p_neutral) - np.log(1 - win_p_neutral)
26+
log_odds_lg = np.log(win_p_leag_hm) - np.log(1 - win_p_leag_hm)
27+
28+
hfa = np.exp(log_odds_tm + log_odds_lg) / (1 + np.exp(log_odds_tm + log_odds_lg))
29+
30+
return hfa

pybettor/hold_calc.py

+31
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
from typing import Union # noqa: F401
2+
from .implied_prob import implied_prob
3+
4+
5+
def hold_calc(odds, category: str = "us", **kwargs) -> float:
6+
"""Sportsbook Hold Calculator
7+
This function calculates the hold perrcentage that the sportsbook has for the given bet.
8+
9+
Args:
10+
odds int, float, list): odds of an event
11+
category (str, optional): type of odds. Defaults to "us". \n
12+
'us', American Odds \n
13+
'dec', Decimal Odds \n
14+
'frac', Fractional Odds
15+
**kwargs: keyword arguments to pass to implied_prob
16+
17+
Returns:
18+
float: hold percentage of odds
19+
"""
20+
21+
# Error handling
22+
if not all(isinstance(line, (int, float)) for line in odds):
23+
raise ValueError("Lines must be numeric")
24+
25+
imp_probs = implied_prob(odds, category=category, **kwargs)
26+
if isinstance(imp_probs, dict):
27+
hold = imp_probs.get("margin")
28+
else:
29+
hold = 1 - (1 / sum(imp_probs))
30+
31+
return hold

0 commit comments

Comments
 (0)