Intro
This course runs you (step-by-step) through the process of building a sports betting bot that will deliver betting signals straight to you via email.
Chapter 1: Query odds data via an API
Chapter 2: Automate query on AWS
Chapter 3: Aggregate and clean raw data
Chapter 4: Create betting bot
Chapter 5: Track betting performance
Chapter 6: Thoughts on Automated Betting and next steps
Prerequisites: Interest in sport betting. You should be comfortable with the basics of Python programming (Pandas dataframes, for loops, if clauses). No prior experience with cloud computing required.
The goal of this course is to set you up with a blueprint to use AWS to automate your sports betting workflow. It is not a fool proof path to getting rich. One large benefit of automation is the time save of not manually reviewing odds information to make decisions.
Cloud computing and automated data pipelines are a great transferable skill set and are becoming more important across various industries. After this course you should be set to apply the learned techniques to other fields you are interested in.
Let’s get started!
Set-up of local Python environment
I am assuming that you already have a local Python installation available to you, including the IDE of your choice. If not you can check out Anaconda for a user-friendly set-up.
Create free Odds API account
In this course we are using Odds API as the source for bookmakers’ odds information. The Odds API scrapes live odds directly from the sports books and makes them available to their users via an easy-to-use API endpoint. Even better: they offer a free tier that allows us to create an account and make first queries without paying a dime.
Let’s head over to the-odds-api.com to create a free account. After signing up you will receive an email with your API key. You can also later view it here.
The API uses this key to keep track of how many requests each user has made each month so we will need to provide it as part of each query. This also means that this key needs to be kept secret so that no unauthorized person can use it without your permission.
We can make sure that our API key works by testing one of the API endpoints that does not count against the quota. Simply replace YOUR_API_KEY with your actual key in the below URL and enter it in your browser.
https://api.the-odds-api.com/v4/sports/?apiKey=YOUR_API_KEY
You should see something similar to the below:
First API call
Next, let’s make sure that we have all necessary packages installed that we need for our first programmatic API call via Python.
At this stage we only need three packages
- requests # Needed for our API query
- json # Needed to write json files
- datetime # Needed to produce current date & time
Make sure that above packages are installed so that below import statements run without issue.
import requests
import json
import datetime
Next we will define our query parameters:
- SPORT: a string parameter defined by Odds API representing a league. The full list can be found here
- BOOKMAKERS: a string parameter with comma-separated bookmaker identifiers. The full list can be found here. You can adjust this list to the bookmakers you are interested in or that are available in your country or state
- MARKETS: the market we are querying. e.g. h2h for moneyline, totals or spreads
- ODDS_FORMAT: the format of the returned odds. e.g. american or decimal
- DATE_FORMAT: the format of the returned timestamps
- API_KEY: this is your API key
The full documentation can be found here.
The query will only return values when the chosen sport or league is in season and upcoming games are covered by the bookmakers. Luckily if no data is returned, the query also won’t use up any quota, so it does not hurt to try.
# Parameters
= 'basketball_nba'
SPORT #SPORT = 'baseball_mlb'
#SPORT = 'americanfootball_nfl'
= 'pinnacle,betfair,betmgm,betrivers,draftkings,fanduel,pointsbetus, \
BOOKMAKERS williamhill_us,wynnbet,circasports'
= 'h2h'
MARKETS = 'decimal'
ODDS_FORMAT = 'iso'
DATE_FORMAT
= 'XXX' API_KEY
Next we are making our API call with the requests package. It helps us to create the URL to query and assigns the returned value to a variable odds_response.
We can further check if the query return any errors (status_code != 200) and if not, extract the json into a list (odds_json). Each element corresponds to one upcoming game in our chosen league/sport.
= requests.get(
odds_response f'https://api.the-odds-api.com/v4/sports/{SPORT}/odds',
={
params'api_key': API_KEY,
'bookmakers': BOOKMAKERS,
'markets': MARKETS,
'oddsFormat': ODDS_FORMAT,
'dateFormat': DATE_FORMAT,
}
)
if odds_response.status_code != 200:
print(f'Failed to get odds: status_code {odds_response.status_code}, \
response body {odds_response.text}')
else:
= odds_response.json() odds_json
Next let’s save this data locally so we have a copy of it. It is usually best practice to include the current datetime into the file name so we have a record of when we pulled this data.
For this we use the datetime package to generate the current date & time. Next we save the data in a local file.
= datetime.utcnow()
current_time = current_time.strftime('%Y')
year = current_time.strftime('%m')
month = current_time.strftime('%d')
day = current_time.strftime('%H')
hour = current_time.strftime('%M')
minute = current_time.strftime('%S')
second
with open(f'odds_{SPORT}_{year}{month}{day}T{hour}{minute}{second}.json', 'w', encoding='utf8') as f:
= True, ensure_ascii=False)) f.write(json.dumps(odds_json, sort_keys
We can now go to our current folder and open this json file in a browser. This will look something like the below:
Putting it all together:
import json
import requests
from datetime import datetime
# Parameters
= 'basketball_nba'
SPORT = 'pinnacle,betfair,betmgm,betrivers,draftkings,fanduel,pointsbetus,\
BOOKMAKERS williamhill_us,wynnbet,circasports'
= 'h2h'
MARKETS = 'decimal'
ODDS_FORMAT = 'iso'
DATE_FORMAT
= 'XXX'
API_KEY
= requests.get(
odds_response f'https://api.the-odds-api.com/v4/sports/{SPORT}/odds',
={
params'api_key': API_KEY,
'bookmakers': BOOKMAKERS,
'markets': MARKETS,
'oddsFormat': ODDS_FORMAT,
'dateFormat': DATE_FORMAT,
}
)
if odds_response.status_code != 200:
print(f'Failed to get odds: status_code {odds_response.status_code}, \
response body {odds_response.text}')
else:
= odds_response.json()
odds_json
= datetime.utcnow()
current_time = current_time.strftime('%Y')
year = current_time.strftime('%m')
month = current_time.strftime('%d')
day = current_time.strftime('%H')
hour = current_time.strftime('%M')
minute = current_time.strftime('%S')
second
= f'odds_{SPORT}_{year}{month}{day}T{hour}{minute}{second}.json'
file_name
with open(file_name, 'w', encoding='utf8') as f:
= True, ensure_ascii=False)) f.write(json.dumps(odds_json, sort_keys
Structure of Odds API data
Below we can see that the odds endpoint returned a list of information for 13 NBA games (0-12). The first element contains data for Miami Heat vs. Charlotte Hornets on February 26th (this is in UTC time; the game actually started at 7:10pm local time on the 25th).
The id data is a unique identifier for each event. This can be used later for table operations. The actual odds data is contained in another nested list called bookmakers.
Details on nested list bookmakers below. Our example call returned odds for ten bookmakers for which we expanded the information from DraftKings.
Full Course
If you liked this first chapter and want to read the rest you can book the full course here