Skip to content

Commit

Permalink
Games from odds (#57)
Browse files Browse the repository at this point in the history
* use scraped data if available

* skip games without odds

* update table format
  • Loading branch information
nkgilley authored Jan 26, 2023
1 parent a4781dc commit 19f565a
Show file tree
Hide file tree
Showing 6 changed files with 100 additions and 36 deletions.
16 changes: 13 additions & 3 deletions Flask/app.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
from datetime import date
from flask import Flask, render_template
from functools import lru_cache
import subprocess
Expand All @@ -23,8 +24,9 @@ def fetch_betmgm(ttl_hash=None):
def fetch_game_data(sportsbook="fanduel"):
cmd = ["python", "main.py", "-xgb", f"-odds={sportsbook}"]
stdout = subprocess.check_output(cmd, cwd="../").decode()
data_re = re.compile(r'\n(?P<away_team>[\w ]+)(\((?P<away_confidence>[\d+\.]+)%\))? vs (?P<home_team>[\w ]+)(\((?P<home_confidence>[\d+\.]+)%\))?: (?P<ou_pick>OVER|UNDER) (?P<ou_value>[\d+\.]+) (\((?P<ou_confidence>[\d+\.]+)%\))?', re.MULTILINE)
data_re = re.compile(r'\n(?P<home_team>[\w ]+)(\((?P<home_confidence>[\d+\.]+)%\))? vs (?P<away_team>[\w ]+)(\((?P<away_confidence>[\d+\.]+)%\))?: (?P<ou_pick>OVER|UNDER) (?P<ou_value>[\d+\.]+) (\((?P<ou_confidence>[\d+\.]+)%\))?', re.MULTILINE)
ev_re = re.compile(r'(?P<team>[\w ]+) EV: (?P<ev>[-\d+\.]+)', re.MULTILINE)
odds_re = re.compile(r'(?P<away_team>[\w ]+) \((?P<away_team_odds>-?\d+)\) @ (?P<home_team>[\w ]+) \((?P<home_team_odds>-?\d+)\)', re.MULTILINE)
games = []
for match in data_re.finditer(stdout):
game_dict = {'away_team': match.group('away_team').strip(),
Expand All @@ -35,11 +37,16 @@ def fetch_game_data(sportsbook="fanduel"):
'ou_value': match.group('ou_value'),
'ou_confidence': match.group('ou_confidence')}
for ev_match in ev_re.finditer(stdout):
print(ev_match.group('team'), game_dict['home_team'])
if ev_match.group('team') == game_dict['away_team']:
game_dict['away_team_ev'] = ev_match.group('ev')
if ev_match.group('team') == game_dict['home_team']:
game_dict['home_team_ev'] = ev_match.group('ev')
for odds_match in odds_re.finditer(stdout):
if odds_match.group('away_team') == game_dict['away_team']:
game_dict['away_team_odds'] = odds_match.group('away_team_odds')
if odds_match.group('home_team') == game_dict['home_team']:
game_dict['home_team_odds'] = odds_match.group('home_team_odds')

print(game_dict)
games.append(game_dict)
return games
Expand All @@ -51,10 +58,13 @@ def get_ttl_hash(seconds=600):


app = Flask(__name__)
app.jinja_env.add_extension('jinja2.ext.loopcontrols')


@app.route("/")
def index():
fanduel = fetch_fanduel(ttl_hash=get_ttl_hash())
draftkings = fetch_draftkings(ttl_hash=get_ttl_hash())
betmgm = fetch_betmgm(ttl_hash=get_ttl_hash())
return render_template('index.html', data={"fanduel": fanduel, "draftkings": draftkings, "betmgm": betmgm})

return render_template('index.html', today=date.today(), data={"fanduel": fanduel, "draftkings": draftkings, "betmgm": betmgm})
83 changes: 60 additions & 23 deletions Flask/templates/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -8,34 +8,67 @@
<style>
.green {color: green}
.red {color: red}
td {padding: 2px;}
td.numbers { width: 40px; text-align: right;}
table {margin-bottom: 6px;}
th {text-align: center;}
</style>
</head>
<body>
<main class="container">
<h1>NBA Machine Learning Picks</h1>
<div class="grid">
{% for sportsbook in ["fanduel", "draftkings", "betmgm"] %}
<div>
<h3>{{sportsbook}}</h3>
<table role="grid">
{% for game in data.get(sportsbook) %}
<h1>NBA Machine Learning Picks ({{today}})</h1>
<table role="grid">
<thead>
<th>Teams</th>
<th>Fanduel</th>
<th>Draftkings</th>
<th>Betmgm</th>
</thead>
<tbody>
<tr>
{% for game in data.get('fanduel') %}
{% set game_idx = loop.index0 %}
<tr>
<td width="180px;">
<table>
<tbody>
<tr>
<td>
{% if game.away_confidence %}<b>{{ game.away_team }} ({{game.away_confidence}}%)</b>{% else %}{{ game.away_team }}{% endif %}
<br>
{% if game.home_confidence %}<b>{{ game.home_team }} ({{game.home_confidence}}%)</b>{% else %}{{ game.home_team }}{% endif %}
</td>
<td style="text-align: right">
<span class="ev-value">{{ game.away_team_ev }}</span><br>
<span class="ev-value">{{ game.home_team_ev }}</span>
</td>
<td>{{ game.ou_pick }} {{ game.ou_value }} (<span class="ou-confidence">{{game.ou_confidence}}%</span>)</td>
<td>{{ game.away_team }}</td>
</tr>
<tr>
<td>{{ game.home_team }}</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
{% endfor %}
</div>
</td>
{% for sportsbook in ['fanduel', 'draftkings', 'betmgm'] %}
{% set sbgame = data.get(sportsbook)[game_idx] %}
{% if not sbgame or not sbgame.away_team or not sbgame.home_team %}{% continue %}{%endif%}
<td>
<table>
<tbody>
<tr>
<td class="numbers">{% if sbgame.away_team_odds|int > 0 %}+{%endif%}{{ sbgame.away_team_odds }}{% if sbgame.away_confidence %} <span class="ev-confidence">({{sbgame.away_confidence}}%)</span>{% endif %}</td>
<td class="numbers">
<span class="ev-value">{{ sbgame.away_team_ev }}</span>
</td>
<td class="numbers">{% if sbgame.ou_pick == 'OVER' %}O{%else%}U{%endif%} {{ sbgame.ou_value }}</td>
</tr>
<tr>
<td class="numbers">{% if sbgame.home_team_odds|int > 0 %}+{%endif%}{{ sbgame.home_team_odds }}{% if sbgame.home_confidence %} <span class="ev-confidence">({{sbgame.home_confidence}}%)</span>{% endif %}</td>
<td class="numbers">
<span class="ev-value">{{ sbgame.home_team_ev }}</span>
</td>
<td class="numbers"><span class="ou-confidence">{{sbgame.ou_confidence}}%</span></td>
</tr>
</tbody>
</table>
</td>
{% endfor %}
</tr>
{%endfor%}
</tbody>
</table>
</main>
<script>
function perc2color(perc,min,max) {
Expand All @@ -57,12 +90,16 @@ <h3>{{sportsbook}}</h3>
return '#' + ('000000' + h.toString(16)).slice(-6);
}
evs = document.getElementsByClassName("ev-value")
evconfs = document.getElementsByClassName("ev-confidence")
ous = document.getElementsByClassName("ou-confidence")
for (var i = 0; i < evs.length; i++) {
evs[i].style.color = perc2color(parseFloat(evs[i].textContent)+100,0,200)
evs[i].style.color = perc2color(parseFloat(evs[i].textContent.replace('(','').replace(')',''))+100,0,200)
}
for (var i = 0; i < evconfs.length; i++) {
evconfs[i].style.color = perc2color(parseFloat(evconfs[i].textContent.replace('(','').replace(')','')),0,100)
}
for (var i = 0; i < ous.length; i++) {
ous[i].style.color = perc2color(parseFloat(ous[i].textContent),0,100)
ous[i].style.color = perc2color(parseFloat(ous[i].textContent.replace('(','').replace(')','')),0,100)
}
</script>
</body>
Expand Down
12 changes: 7 additions & 5 deletions main.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
import tensorflow as tf
from src.Predict import NN_Runner, XGBoost_Runner
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
from src.Utils.tools import create_todays_games_from_odds, get_json_data, to_data_frame, get_todays_games_json, create_todays_games
from src.DataProviders.SbrOddsProvider import SbrOddsProvider


Expand Down Expand Up @@ -58,12 +58,9 @@ def createTodaysGames(games, df, odds):

def main():
odds = None
data = get_todays_games_json(todays_games_url)
games = create_todays_games(data)
data = get_json_data(data_url)
df = to_data_frame(data)
if args.odds:
odds = SbrOddsProvider(sportsbook=args.odds).get_odds()
games = create_todays_games_from_odds(odds)
if((games[0][0]+':'+games[0][1]) not in list(odds.keys())):
print(games[0][0]+':'+games[0][1])
print(Fore.RED, "--------------Games list not up to date for todays games!!! Scraping disabled until list is updated.--------------")
Expand All @@ -74,6 +71,11 @@ def main():
for g in odds.keys():
home_team, away_team = g.split(":")
print(f"{away_team} ({odds[g][away_team]['money_line_odds']}) @ {home_team} ({odds[g][home_team]['money_line_odds']})")
else:
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, home_team_odds, away_team_odds = createTodaysGames(games, df, odds)
if args.nn:
print("------------Neural Network Model Predictions-----------")
Expand Down
11 changes: 8 additions & 3 deletions src/DataProviders/SbrOddsProvider.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,12 +26,17 @@ def get_odds(self):
home_team_name = game['home_team'].replace("Los Angeles Clippers", "LA Clippers")
away_team_name = game['away_team'].replace("Los Angeles Clippers", "LA Clippers")

money_line_home_value = money_line_away_value = totals_value = None

# Get money line bet values
money_line_home_value = game['home_ml'][self.sportsbook]
money_line_away_value = game['away_ml'][self.sportsbook]
if self.sportsbook in game['home_ml']:
money_line_home_value = game['home_ml'][self.sportsbook]
if self.sportsbook in game['away_ml']:
money_line_away_value = game['away_ml'][self.sportsbook]

# Get totals bet value
totals_value = game['total'][self.sportsbook]
if self.sportsbook in game['total']:
totals_value = game['total'][self.sportsbook]

dict_res[home_team_name + ':' + away_team_name] = {
'under_over_odds': totals_value,
Expand Down
6 changes: 4 additions & 2 deletions src/Predict/XGBoost_Runner.py
Original file line number Diff line number Diff line change
Expand Up @@ -76,8 +76,10 @@ def xgb_runner(data, todays_games_uo, frame_ml, games, home_team_odds, away_team
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])))
ev_home = ev_away = 0
if home_team_odds[count] and away_team_odds[count]:
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:
Expand Down
8 changes: 8 additions & 0 deletions src/Utils/tools.py
Original file line number Diff line number Diff line change
Expand Up @@ -50,3 +50,11 @@ def create_todays_games(input_list):
away_team = away.get('tc') + ' ' + away.get('tn')
games.append([home_team, away_team])
return games


def create_todays_games_from_odds(input_dict):
games = []
for game in input_dict.keys():
home_team, away_team = game.split(":")
games.append([home_team, away_team])
return games

0 comments on commit 19f565a

Please sign in to comment.