Skip to content

Commit

Permalink
Expected Value (#7)
Browse files Browse the repository at this point in the history
* Math for expected value of bet. Need to implement

* Added research to notes

* Updated notes

* Working ev with updated readme
  • Loading branch information
kyleskom authored Oct 20, 2021
1 parent b48b57e commit 2e0001a
Show file tree
Hide file tree
Showing 13 changed files with 102 additions and 8 deletions.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@ Use Python 3.8. In particular the packages/libraries used are...

## Usage

<img src="https://github.com/kyleskom/NBA-Machine-Learning-Sports-Betting/blob/master/Screenshots/Expected_value.png" width="1010" height="292" />

Make sure all packages above are installed.

```bash
Expand Down
Binary file added Screenshots/Expected_value.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
37 changes: 37 additions & 0 deletions Tests/Expected_Value_Test.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
import unittest
from src.Utils import Expected_Value


class TestExpectedValue(unittest.TestCase):

def test_expected_value_1(self):
result = Expected_Value.expected_value(.76, -200)
self.assertEqual(result, 14)

def test_expected_value_2(self):
result = Expected_Value.expected_value(.3, -500)
self.assertEqual(result, -64)

def test_expected_value_3(self):
result = Expected_Value.expected_value(.6, 250)
self.assertEqual(result, 110)

def test_expected_value_4(self):
result = Expected_Value.expected_value(.2, -200)
self.assertEqual(result, -70)

def test_expected_value_5(self):
result = Expected_Value.expected_value(.8137, -200)
self.assertEqual(result, 22.05)

def test_expected_value_6(self):
result = Expected_Value.expected_value(.2175, -550)
self.assertEqual(result, -74.30)

def test_expected_value_7(self):
result = Expected_Value.expected_value(.5298, 1000)
self.assertEqual(result, 482.78)

def test_expected_value_8(self):
result = Expected_Value.expected_value(.638, 275)
self.assertEqual(result, 139.25)
18 changes: 12 additions & 6 deletions main.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,11 +19,17 @@
def createTodaysGames(games, df):
match_data = []
todays_games_uo = []
home_team_odds = []
away_team_odds = []

for game in games:
home_team = game[0]
away_team = game[1]
todays_games_uo.append(input(home_team + ' vs ' + away_team + ': '))

home_team_odds.append(input(home_team + ' odds: '))
away_team_odds.append(input(away_team + ' odds: '))

home_team_series = df.iloc[team_index_current.get(home_team)]
away_team_series = df.iloc[team_index_current.get(away_team)]
stats = home_team_series.append(away_team_series)
Expand All @@ -36,31 +42,31 @@ def createTodaysGames(games, df):
data = frame_ml.values
data = data.astype(float)

return data, todays_games_uo, frame_ml
return data, todays_games_uo, frame_ml, home_team_odds, away_team_odds


def main():
data = get_todays_games_json(todays_games_url)
games = create_todays_games(data)
data = get_json_data(data_url)
df = to_data_frame(data)
data, todays_games_uo, frame_ml = createTodaysGames(games, df)
data, todays_games_uo, frame_ml, home_team_odds, away_team_odds = createTodaysGames(games, df)
if args.nn:
print("------------Neural Network Model Predictions-----------")
data = tf.keras.utils.normalize(data, axis=1)
NN_Runner.nn_runner(data, todays_games_uo, frame_ml, games)
NN_Runner.nn_runner(data, todays_games_uo, frame_ml, games, home_team_odds, away_team_odds)
print("-------------------------------------------------------")
if args.xgb:
print("---------------XGBoost Model Predictions---------------")
XGBoost_Runner.xgb_runner(data, todays_games_uo, frame_ml, games)
XGBoost_Runner.xgb_runner(data, todays_games_uo, frame_ml, games, home_team_odds, away_team_odds)
print("-------------------------------------------------------")
if args.A:
print("---------------XGBoost Model Predictions---------------")
XGBoost_Runner.xgb_runner(data, todays_games_uo, frame_ml, games)
XGBoost_Runner.xgb_runner(data, todays_games_uo, frame_ml, games, home_team_odds, away_team_odds)
print("-------------------------------------------------------")
data = tf.keras.utils.normalize(data, axis=1)
print("------------Neural Network Model Predictions-----------")
NN_Runner.nn_runner(data, todays_games_uo, frame_ml, games)
NN_Runner.nn_runner(data, todays_games_uo, frame_ml, games, home_team_odds, away_team_odds)
print("-------------------------------------------------------")


Expand Down
1 change: 1 addition & 0 deletions notes.txt
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
https://arxiv.org/pdf/1710.02824.pdf
https://www.sportsbookreviewsonline.com/scoresoddsarchives/nba/nbaoddsarchives.htm
https://www.youtube.com/watch?v=wQ8BIBpya2k
Random Forrest
Expand Down
21 changes: 20 additions & 1 deletion src/Predict/NN_Runner.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,13 @@
import tensorflow as tf
from colorama import Fore, Style
from tensorflow.keras.models import load_model
from src.Utils import Expected_Value

model = load_model('Models/NN_Models/Trained-Model-ML')
ou_model = load_model("Models/NN_Models/Trained-Model-OU")


def nn_runner(data, todays_games_uo, frame_ml, games):
def nn_runner(data, todays_games_uo, frame_ml, games, home_team_odds, away_team_odds):
ml_predictions_array = []

for row in data:
Expand Down Expand Up @@ -55,3 +56,21 @@ def nn_runner(data, todays_games_uo, frame_ml, games):
print(Fore.RED + home_team + Style.RESET_ALL + ' vs ' + Fore.GREEN + away_team + Style.RESET_ALL + Fore.CYAN + f" ({winner_confidence}%)" + Style.RESET_ALL + ': ' +
Fore.BLUE + 'OVER ' + Style.RESET_ALL + str(todays_games_uo[count]) + Style.RESET_ALL + Fore.CYAN + f" ({un_confidence}%)" + Style.RESET_ALL)
count += 1

print("--------------------Expected Value---------------------")
count = 0
for game in games:
home_team = game[0]
away_team = game[1]
ev_home = float(Expected_Value.expected_value(ml_predictions_array[count][0][1], int(home_team_odds[count])))
ev_away = float(Expected_Value.expected_value(ml_predictions_array[count][0][0], int(away_team_odds[count])))
if ev_home > 0:
print(home_team + ' EV: ' + Fore.GREEN + str(ev_home) + Style.RESET_ALL)
else:
print(home_team + ' EV: ' + Fore.RED + str(ev_home) + Style.RESET_ALL)

if ev_away > 0:
print(away_team + ' EV: ' + Fore.GREEN + str(ev_away) + Style.RESET_ALL)
else:
print(away_team + ' EV: ' + Fore.RED + str(ev_away) + Style.RESET_ALL)
count += 1
20 changes: 19 additions & 1 deletion src/Predict/XGBoost_Runner.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
import pandas as pd
import xgboost as xgb
from colorama import Fore, Style
from src.Utils import Expected_Value

# from src.Utils.Dictionaries import team_index_current
# from src.Utils.tools import get_json_data, to_data_frame, get_todays_games_json, create_todays_games
Expand All @@ -16,7 +17,7 @@
xgb_uo.load_model('Models/XGBoost_Models/XGBoost_58.9%_UO-6.json')


def xgb_runner(data, todays_games_uo, frame_ml, games):
def xgb_runner(data, todays_games_uo, frame_ml, games, home_team_odds, away_team_odds):
ml_predictions_array = []

for row in data:
Expand Down Expand Up @@ -69,3 +70,20 @@ def xgb_runner(data, todays_games_uo, frame_ml, games):
Fore.BLUE + 'OVER ' + Style.RESET_ALL + str(
todays_games_uo[count]) + Style.RESET_ALL + Fore.CYAN + f" ({un_confidence}%)" + Style.RESET_ALL)
count += 1
print("--------------------Expected Value---------------------")
count = 0
for game in games:
home_team = game[0]
away_team = game[1]
ev_home = float(Expected_Value.expected_value(ml_predictions_array[count][0][1], int(home_team_odds[count])))
ev_away = float(Expected_Value.expected_value(ml_predictions_array[count][0][0], int(away_team_odds[count])))
if ev_home > 0:
print(home_team + ' EV: ' + Fore.GREEN + str(ev_home) + Style.RESET_ALL)
else:
print(home_team + ' EV: ' + Fore.RED + str(ev_home) + Style.RESET_ALL)

if ev_away > 0:
print(away_team + ' EV: ' + Fore.GREEN + str(ev_away) + Style.RESET_ALL)
else:
print(away_team + ' EV: ' + Fore.RED + str(ev_away) + Style.RESET_ALL)
count += 1
11 changes: 11 additions & 0 deletions src/Utils/Expected_Value.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
def expected_value(Pwin, odds):
Ploss = 1 - Pwin
Mwin = payout(odds)
return round((Pwin * Mwin) - (Ploss * 100), 2)


def payout(odds):
if odds > 0:
return odds
else:
return (100 / (-1 * odds)) * 100

0 comments on commit 2e0001a

Please sign in to comment.