Initial
This commit is contained in:
3
.gitignore
vendored
Normal file
3
.gitignore
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
__pycache__
|
||||
venv
|
||||
.idea
|
||||
58
logic.py
Normal file
58
logic.py
Normal file
@@ -0,0 +1,58 @@
|
||||
from typing import Iterable, Generator
|
||||
import time
|
||||
import requests
|
||||
|
||||
BASE_URL = "https://api.the-odds-api.com/v4"
|
||||
|
||||
|
||||
def get_sports(key: str) -> set[str]:
|
||||
url = f"{BASE_URL}/sports/"
|
||||
querystring = {"apiKey": key}
|
||||
|
||||
response = requests.get(url, params=querystring)
|
||||
return {item["group"] for item in response.json()}
|
||||
|
||||
|
||||
def get_data(key: str, sport: str, region: str = "eu"):
|
||||
url = f"{BASE_URL}/sports/{sport}/odds/"
|
||||
querystring = {
|
||||
"apiKey": key,
|
||||
"regions": region,
|
||||
"oddsFormat": "decimal",
|
||||
"dateFormat": "unix"
|
||||
}
|
||||
|
||||
response = requests.get(url, params=querystring)
|
||||
return response.json()
|
||||
|
||||
|
||||
def process_data(matches: Iterable, include_started_matches: bool = True) -> Generator[dict, None, None]:
|
||||
"""Extracts all matches that are available and calculates some things about them, such as the time to start and
|
||||
the best available implied odds."""
|
||||
for match in matches:
|
||||
start_time = int(match["commence_time"])
|
||||
if not include_started_matches and start_time < time.time():
|
||||
continue
|
||||
|
||||
best_odd_per_outcome = {}
|
||||
for bookmaker in match["bookmakers"]:
|
||||
bookie_name = bookmaker["title"]
|
||||
for outcome in bookmaker["markets"][0]["outcomes"]:
|
||||
outcome_name = outcome["name"]
|
||||
odd = outcome["price"]
|
||||
if outcome_name not in best_odd_per_outcome.keys() or \
|
||||
odd > best_odd_per_outcome[outcome_name][1]:
|
||||
best_odd_per_outcome[outcome_name] = (bookie_name, odd)
|
||||
|
||||
total_implied_odds = sum(1/i[1] for i in best_odd_per_outcome.values())
|
||||
match_name = f"{match['home_team']} v. {match['away_team']}"
|
||||
time_to_start = (start_time - time.time())/3600
|
||||
league = match["sport_key"]
|
||||
yield {
|
||||
"match_name": match_name,
|
||||
"match_start_time": start_time,
|
||||
"time_to_start": time_to_start,
|
||||
"league": league,
|
||||
"best_outcome_odds": best_odd_per_outcome,
|
||||
"total_implied_odds": total_implied_odds,
|
||||
}
|
||||
25
main.py
Normal file
25
main.py
Normal file
@@ -0,0 +1,25 @@
|
||||
from logic import *
|
||||
import os
|
||||
from itertools import chain
|
||||
from dotenv import load_dotenv
|
||||
from rich import print
|
||||
|
||||
|
||||
load_dotenv()
|
||||
|
||||
|
||||
def main():
|
||||
key = os.environ.get("API_KEY")
|
||||
|
||||
sports = get_sports(key)
|
||||
data = chain.from_iterable(get_data(key, sport) for sport in sports)
|
||||
data = filter(lambda x: x != "message", data)
|
||||
results = process_data(data)
|
||||
|
||||
arbitrage_opportunities = filter(lambda x: x["total_implied_odds"] < 1, results)
|
||||
for i in arbitrage_opportunities:
|
||||
print(i)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
2
requirements.txt
Normal file
2
requirements.txt
Normal file
@@ -0,0 +1,2 @@
|
||||
requests~=2.28.1
|
||||
python-dotenv~=0.21.0
|
||||
Reference in New Issue
Block a user