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:

Example output for the Odds Api sports end-point

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

  1. requests # Needed for our API query
  2. json # Needed to write json files
  3. 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:

  1. SPORT: a string parameter defined by Odds API representing a league. The full list can be found here
  2. 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
  3. MARKETS: the market we are querying. e.g. h2h for moneyline, totals or spreads
  4. ODDS_FORMAT: the format of the returned odds. e.g. american or decimal
  5. DATE_FORMAT: the format of the returned timestamps
  6. 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

SPORT = 'basketball_nba'
#SPORT = 'baseball_mlb'
#SPORT = 'americanfootball_nfl'
BOOKMAKERS = 'pinnacle,betfair,betmgm,betrivers,draftkings,fanduel,pointsbetus, \
              williamhill_us,wynnbet,circasports'
MARKETS = 'h2h'
ODDS_FORMAT = 'decimal'
DATE_FORMAT = 'iso'

API_KEY = 'XXX'

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.

odds_response = requests.get(
    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_json = odds_response.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.

current_time = datetime.utcnow()
year = current_time.strftime('%Y')
month = current_time.strftime('%m')
day = current_time.strftime('%d')
hour = current_time.strftime('%H')
minute = current_time.strftime('%M')
second = current_time.strftime('%S')

with open(f'odds_{SPORT}_{year}{month}{day}T{hour}{minute}{second}.json', 'w', encoding='utf8') as f:
    f.write(json.dumps(odds_json, sort_keys = True, ensure_ascii=False))

We can now go to our current folder and open this json file in a browser. This will look something like the below:

Example output for the Odds API odds end-point

Putting it all together:

import json
import requests
from datetime import datetime

# Parameters

SPORT = 'basketball_nba'
BOOKMAKERS = 'pinnacle,betfair,betmgm,betrivers,draftkings,fanduel,pointsbetus,\
              williamhill_us,wynnbet,circasports'
MARKETS = 'h2h'
ODDS_FORMAT = 'decimal'
DATE_FORMAT = 'iso'

API_KEY = 'XXX'

odds_response = requests.get(
    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_json = odds_response.json()

    current_time = datetime.utcnow()
    year = current_time.strftime('%Y')
    month = current_time.strftime('%m')
    day = current_time.strftime('%d')
    hour = current_time.strftime('%H')
    minute = current_time.strftime('%M')
    second = current_time.strftime('%S')

    file_name = f'odds_{SPORT}_{year}{month}{day}T{hour}{minute}{second}.json'

    with open(file_name, 'w', encoding='utf8') as f:
        f.write(json.dumps(odds_json, sort_keys = True, ensure_ascii=False))

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.

Structure for one upcoming game

Details on nested list bookmakers below. Our example call returned odds for ten bookmakers for which we expanded the information from DraftKings.

JSON structure for one upcoming game

Full Course

If you liked this first chapter and want to read the rest you can book the full course here