File size: 6,892 Bytes
cc6f35d
 
a4bed59
2cdab74
cc6f35d
8943298
 
 
a4bed59
8943298
2cdab74
8943298
 
 
2ab96f3
 
c193fed
 
 
 
2ab96f3
 
2cdab74
8943298
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
b097c8a
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
8943298
 
2cdab74
2ab96f3
c193fed
4160e47
c193fed
cc6f35d
2ab96f3
 
cc6f35d
 
 
c193fed
d90ddb6
 
4160e47
d90ddb6
c193fed
 
d90ddb6
 
 
 
64f9272
 
 
80aded5
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
64f9272
80aded5
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
4160e47
 
8943298
 
 
 
d90ddb6
c193fed
d90ddb6
4160e47
d90ddb6
 
c193fed
8943298
2ab96f3
4160e47
2ab96f3
d90ddb6
4160e47
c193fed
2cdab74
 
 
d90ddb6
 
 
4160e47
 
 
 
8943298
 
d90ddb6
 
b097c8a
4160e47
 
 
 
 
 
 
 
d90ddb6
4160e47
 
 
 
 
 
 
d90ddb6
4160e47
 
d90ddb6
 
 
 
4160e47
d90ddb6
 
b097c8a
 
 
 
 
 
 
 
 
 
 
 
 
d90ddb6
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
import gradio as gr
import requests
import os
import pandas as pd

# ----------------------------
# ENV VARIABLES
# ----------------------------
API_URL = os.getenv("API_URL")
ODDS_API_KEY = os.getenv("ODDS_API_KEY")

# ----------------------------
# TEAM LIST
# ----------------------------
teams = [
    "Collingwood", "Carlton", "Richmond", "Melbourne",
    "Hawthorn", "Geelong", "Sydney", "Brisbane Lions",
    "Adelaide", "Port Adelaide", "West Coast", "Fremantle",
    "Essendon", "St Kilda", "Western Bulldogs",
    "North Melbourne", "Gold Coast", "GWS"
]

# ----------------------------
# TEAM NAME MAPPING
# ----------------------------
TEAM_MAPPING = {
    "Fremantle": "Fremantle Dockers",
    "West Coast": "West Coast Eagles",
    "Gold Coast": "Gold Coast Suns",
    "GWS": "Greater Western Sydney Giants"
}

def map_team(team):
    return TEAM_MAPPING.get(team, team)

# ----------------------------
# FETCH ODDS
# ----------------------------
def fetch_odds():
    if not ODDS_API_KEY:
        return []

    url = "https://api.the-odds-api.com/v4/sports/aussierules_afl/odds"

    params = {
        "apiKey": ODDS_API_KEY,
        "regions": "au",
        "markets": "h2h"
    }

    try:
        response = requests.get(url, params=params)
        if response.status_code != 200:
            return []
        return response.json()
    except:
        return []

# ----------------------------
# GET MATCH ODDS
# ----------------------------
def get_match_odds(home_team, away_team):
    data = fetch_odds()

    api_home = map_team(home_team)
    api_away = map_team(away_team)

    for match in data:
        if match["home_team"] == api_home and match["away_team"] == api_away:
            prices = {}

            for bookmaker in match["bookmakers"]:
                try:
                    outcomes = bookmaker["markets"][0]["outcomes"]
                    for o in outcomes:
                        prices[o["name"]] = o["price"]
                except:
                    continue

            return prices

    return None

# ----------------------------
# FORMAT ODDS TABLE
# ----------------------------
def format_odds(data):
    rows = []

    for match in data:
        home = match["home_team"]
        away = match["away_team"]

        home_prices = []
        away_prices = []

        for bookmaker in match["bookmakers"]:
            try:
                outcomes = bookmaker["markets"][0]["outcomes"]

                for o in outcomes:
                    if o["name"] == home:
                        home_prices.append(o["price"])
                    elif o["name"] == away:
                        away_prices.append(o["price"])
            except:
                continue

        if home_prices and away_prices:
            rows.append({
                "Match": f"{home} vs {away}",
                "Best Home Odds": max(home_prices),
                "Best Away Odds": max(away_prices),
                "Avg Home Odds": round(sum(home_prices)/len(home_prices), 2),
                "Avg Away Odds": round(sum(away_prices)/len(away_prices), 2)
            })

    return pd.DataFrame(rows)

# ----------------------------
# MAIN PREDICT FUNCTION
# ----------------------------
def predict(home_team, away_team):
    if home_team == away_team:
        return "⚠️ Please select two different teams", "", 0

    payload = {
        "home_team": home_team,
        "away_team": away_team
    }

    try:
        response = requests.post(API_URL, json=payload)

        if response.status_code != 200:
            return f"❌ API Error: {response.status_code}", "", 0

        result = response.json()

        winner = result["winner"]
        confidence = result["confidence"]
        reasons = result.get("reasons", [])

        # ----------------------------
        # GET ODDS
        # ----------------------------
        odds_data = get_match_odds(home_team, away_team)

        odds_text = ""
        ev_text = ""

        if odds_data:
            api_home = map_team(home_team)
            api_away = map_team(away_team)

            home_odds = odds_data.get(api_home)
            away_odds = odds_data.get(api_away)

            if winner == home_team and home_odds:
                ev = (confidence * home_odds) - 1
                selected_odds = home_odds
            elif winner == away_team and away_odds:
                ev = (confidence * away_odds) - 1
                selected_odds = away_odds
            else:
                ev = None
                selected_odds = None

            odds_text = f"""
###  πŸ’° Market Odds
- {home_team}: {home_odds}
- {away_team}: {away_odds}
"""

            if ev is not None:
                recommendation = "🟒 Bet" if ev > 0 else "πŸ”΄ Avoid"

                ev_text = f"""
### πŸ“ˆ Expected Value (EV)

Odds used: {selected_odds}  
EV: **{ev:.2f}**

**Recommendation:** {recommendation}
"""
        else:
            odds_text = "⚠️ No odds data available"

        result_text = f"""
# πŸ† Prediction Result

## **{winner} expected to win**

**Confidence:** {confidence*100:.1f}%

{odds_text}

{ev_text}
"""

        if reasons:
            reasons_text = "### πŸ“Š Model Insights\n"
            for r in reasons:
                reasons_text += f"- {r}\n"
        else:
            reasons_text = ""

        return result_text, reasons_text, confidence

    except Exception as e:
        return f"❌ Error: {str(e)}", "", 0

# ----------------------------
# UI
# ----------------------------
with gr.Blocks(theme=gr.themes.Soft()) as app:

    gr.Markdown("""
# πŸ“Š Betting Intelligence Platform

### Find the edge. Bet with probability, not emotion.

This tool combines machine learning predictions with real-time market odds  
to identify high-value betting opportunities.
""")

    # Prediction Section
    with gr.Group():
        gr.Markdown("### πŸ” Select Match")

        with gr.Row():
            home_team = gr.Dropdown(teams, label="🏠 Home Team")
            away_team = gr.Dropdown(teams, label="✈️ Away Team")

        predict_btn = gr.Button("Run Prediction", variant="primary")

    with gr.Group():
        result_output = gr.Markdown()
        confidence_bar = gr.Slider(
            minimum=0, maximum=1, step=0.01,
            label="Model Confidence",
            interactive=False
        )

    with gr.Group():
        reason_output = gr.Markdown()

    predict_btn.click(
        fn=predict,
        inputs=[home_team, away_team],
        outputs=[result_output, reason_output, confidence_bar]
    )

    # Odds Table Section
    with gr.Group():
        gr.Markdown("### πŸ“Š Live Market Odds (All Matches)")

        odds_btn = gr.Button("Load Market Odds")

        odds_table = gr.Dataframe()

        odds_btn.click(
            fn=lambda: format_odds(fetch_odds()),
            outputs=odds_table
        )

app.launch()