From d03391c2710b13332924e0076b0edbd24bf28155 Mon Sep 17 00:00:00 2001 From: Daan Koning Date: Sun, 22 Jan 2023 22:15:58 +0100 Subject: [PATCH] Change to spaces for indentation --- logic.py | 100 +++++++++++++++++++++++++++---------------------------- main.py | 96 ++++++++++++++++++++++++++-------------------------- 2 files changed, 98 insertions(+), 98 deletions(-) diff --git a/logic.py b/logic.py index 6d24ed5..cf470e8 100644 --- a/logic.py +++ b/logic.py @@ -6,74 +6,74 @@ BASE_URL = "https://api.the-odds-api.com/v4" class AuthenticationException(RuntimeError): - pass + pass class RateLimitException(RuntimeError): - pass + pass def handle_faulty_response(response: requests.Response): - if response.status_code == 401: - raise AuthenticationException("Failed to authenticate with the API. is the API key valid?") - elif response.status_code == 429: - raise RateLimitException("Encountered API rate limit.") + if response.status_code == 401: + raise AuthenticationException("Failed to authenticate with the API. is the API key valid?") + elif response.status_code == 429: + raise RateLimitException("Encountered API rate limit.") def get_sports(key: str) -> set[str]: - url = f"{BASE_URL}/sports/" - querystring = {"apiKey": key} + url = f"{BASE_URL}/sports/" + querystring = {"apiKey": key} - response = requests.get(url, params=querystring) - if not response: - handle_faulty_response(response) + response = requests.get(url, params=querystring) + if not response: + handle_faulty_response(response) - return {item["group"] for item in response.json()} + 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" - } + url = f"{BASE_URL}/sports/{sport}/odds/" + querystring = { + "apiKey": key, + "regions": region, + "oddsFormat": "decimal", + "dateFormat": "unix" + } - response = requests.get(url, params=querystring) - if not response: - handle_faulty_response(response) + response = requests.get(url, params=querystring) + if not response: + handle_faulty_response(response) - return response.json() + 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 + """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) + 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, - "hours_to_start": time_to_start, - "league": league, - "best_outcome_odds": best_odd_per_outcome, - "total_implied_odds": total_implied_odds, - } \ No newline at end of file + 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, + "hours_to_start": time_to_start, + "league": league, + "best_outcome_odds": best_odd_per_outcome, + "total_implied_odds": total_implied_odds, + } \ No newline at end of file diff --git a/main.py b/main.py index 3d4b957..38d026a 100644 --- a/main.py +++ b/main.py @@ -11,60 +11,60 @@ from rich import print def main(): - load_dotenv() + load_dotenv() - parser = argparse.ArgumentParser( - prog="Arbitrage Finder", - description=__doc__ - ) - parser.add_argument( - "-k", "--key", - default=os.environ.get("API_KEY"), - help="The API key from The Odds API. If left blank it will default to the value of $API_KEY." - ) - parser.add_argument( - "-r", "--region", - choices=["eu", "us", "au", "uk"], - default="eu", - help="The region in which to look for arbitrage opportunities." - ) - parser.add_argument( - "-u", "--unformatted", - action="store_true", - help="If set, turn output into the json dump from the opportunities." - ) - parser.add_argument( - "-c", "--cutoff", - type=float, - default=0, - help="The minimum profit margin required for an arb to be displayed. Inputted as a percentage." + parser = argparse.ArgumentParser( + prog="Arbitrage Finder", + description=__doc__ ) - args = parser.parse_args() + parser.add_argument( + "-k", "--key", + default=os.environ.get("API_KEY"), + help="The API key from The Odds API. If left blank it will default to the value of $API_KEY." + ) + parser.add_argument( + "-r", "--region", + choices=["eu", "us", "au", "uk"], + default="eu", + help="The region in which to look for arbitrage opportunities." + ) + parser.add_argument( + "-u", "--unformatted", + action="store_true", + help="If set, turn output into the json dump from the opportunities." + ) + parser.add_argument( + "-c", "--cutoff", + type=float, + default=0, + help="The minimum profit margin required for an arb to be displayed. Inputted as a percentage." + ) + args = parser.parse_args() - key = args.key - region = args.region - print_unformatted = args.unformatted - cutoff = args.cutoff/100 + key = args.key + region = args.region + print_unformatted = args.unformatted + cutoff = args.cutoff/100 - # logic - sports = get_sports(key) - data = chain.from_iterable(get_data(key, sport, region=region) 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-cutoff, results) + # logic + sports = get_sports(key) + data = chain.from_iterable(get_data(key, sport, region=region) 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-cutoff, results) - if print_unformatted: - print(arbitrage_opportunities) - else: - arbitrage_opportunities = list(arbitrage_opportunities) - print(f"{len(arbitrage_opportunities)} arbitrage opportunities found {':money-mouth_face:' if len(arbitrage_opportunities) > 0 else ':man_shrugging:'}") + if print_unformatted: + print(arbitrage_opportunities) + else: + arbitrage_opportunities = list(arbitrage_opportunities) + print(f"{len(arbitrage_opportunities)} arbitrage opportunities found {':money-mouth_face:' if len(arbitrage_opportunities) > 0 else ':man_shrugging:'}") - for arb in arbitrage_opportunities: - print(f"\t[italic]{arb['match_name']} in {arb['league']} [/italic]") - print(f"\t\tTotal implied odds: {arb['total_implied_odds']} with these odds:") - for key, value in arb['best_outcome_odds'].items(): - print(f"\t\t[bold red]{key}[/bold red] with [green]{value[0]}[/green] for {value[1]}") + for arb in arbitrage_opportunities: + print(f"\t[italic]{arb['match_name']} in {arb['league']} [/italic]") + print(f"\t\tTotal implied odds: {arb['total_implied_odds']} with these odds:") + for key, value in arb['best_outcome_odds'].items(): + print(f"\t\t[bold red]{key}[/bold red] with [green]{value[0]}[/green] for {value[1]}") if __name__ == '__main__': - main() \ No newline at end of file + main() \ No newline at end of file