Change to spaces for indentation

This commit is contained in:
Daan Koning
2023-01-22 22:15:58 +01:00
parent 94e9e2d7a3
commit d03391c271
2 changed files with 98 additions and 98 deletions

100
logic.py
View File

@@ -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,
}
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,
}

96
main.py
View File

@@ -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()
main()