Como Criar um Bot de Apostas Esportivas
Um guia direto, sem enrolação, pra quem quer construir um bot de apostas esportivas do zero usando Python e modelos de IA. Arquitetura, APIs, código funcional e —
Aviso antes de tudo
Como Criar um Bot de Apostas Esportivas. Um guia direto, sem enrolação, pra quem quer construir um bot de apostas esportivas do zero usando Python e modelos de IA. Arquitetura, APIs, código funcional e — claro — os riscos que ninguém conta.
Galera, vou ser direto: construir um bot de apostas esportivas não é tão difícil quanto parece do ponto de vista técnico. Python resolve bem. O difícil mesmo é fazer um bot que não perca dinheiro — e aí a IA entra na jogada.
Nos últimos meses, construí três versões diferentes de bots de apostas. Duas perderam dinheiro. Uma ficou levemente positiva depois de 4 meses de operação. Vou mostrar o caminho completo aqui — incluindo os erros — porque na internet todo mundo finge que deu certo de primeira.
O que é um betting bot e como funciona a arquitetura
Um betting bot é um programa que coleta odds em tempo real, analisa se existe valor nelas e, quando encontra, faz a aposta automaticamente. Tipo um robô trader, só que pra esportes. A diferença é que o mercado de apostas esportivas tem ineficiências enormes — especialmente em ligas menores.
A arquitetura básica tem três camadas. A primeira coleta dados: odds de várias casas, estatísticas dos times, lesões, clima, tudo. A segunda camada é o cérebro — um modelo de IA que pega esses dados e calcula a probabilidade real de cada resultado. A terceira camada compara essa probabilidade com as odds oferecidas e decide se aposta ou não.
- Coletor de Dados: puxa odds de APIs como The Odds API, Betfair Exchange e Pinnacle em intervalos de 30-60 segundos
- Pipeline de Features: limpa, transforma e enriquece os dados com estatísticas históricas dos times
- Modelo Preditivo: recebe as features e cospe probabilidades pra cada outcome (vitória casa, empate, vitória fora)
- Motor de Decisão: compara as probabilidades do modelo com as odds do mercado e identifica value bets
- Executor: quando o motor aprova, faz a aposta via API da casa ou interface automatizada
- Logger: registra tudo — cada aposta, cada decisão, cada centavo. Sem isso, você não consegue melhorar nada
Setup Python — bibliotecas e configuração das APIs
Vamos ao que interessa. O setup em Python é surpreendentemente simples. Você precisa de poucas bibliotecas pra ter algo rodando. O grosso do trabalho não é o código em si — é a qualidade dos dados e do modelo.
pip install requests pandas scikit-learn xgboost schedule python-dotenv loguruRequests pra consumir APIs, Pandas pra manipular dados, scikit-learn e XGBoost pro modelo de IA, schedule pra rodar tarefas em intervalos e loguru porque o logging padrão do Python é sofrível. O python-dotenv é pra guardar suas API keys fora do código.
import os
import requests
import pandas as pd
from dotenv import load_dotenv
from loguru import logger
load_dotenv()
API_KEY = os.getenv("ODDS_API_KEY")
BASE_URL = "https://api.the-odds-api.com/v4"
def get_odds(sport="soccer_brazil_serie_a", regions="eu", markets="h2h"):
"""Puxa odds ao vivo de múltiplas casas."""
url = f"{BASE_URL}/sports/{sport}/odds"
params = {
"apiKey": API_KEY,
"regions": regions,
"markets": markets,
"oddsFormat": "decimal"
}
resp = requests.get(url, params=params, timeout=10)
resp.raise_for_status()
logger.info(f"Coletadas odds de {len(resp.json())} jogos")
return resp.json()Organizando o projeto
Não jogue tudo em um arquivo só. Mesmo pra um projeto pessoal, separe pelo menos em quatro módulos: collector, features, model e executor. Quando algo quebrar às 3 da manhã (e vai quebrar), você precisa saber exatamente onde olhar.
betting-bot/
├── collector/
│ ├── odds_api.py
│ ├── stats_api.py
│ └── cache.py
├── features/
│ ├── builder.py
│ └── historical.py
├── model/
│ ├── train.py
│ ├── predict.py
│ └── backtest.py
├── executor/
│ ├── decision.py
│ └── placer.py
├── config.py
├── main.py
└── .envColetando odds — scraping vs APIs
Aqui tem uma decisão importante. Dá pra coletar odds de duas formas: scraping direto dos sites das casas ou usando APIs oficiais/terceirizadas. Cada caminho tem tradeoffs.
Web Scraping
Extrai dados diretamente dos sites das casas de apostas.
+ Prós
- • Grátis — sem custo de API
- • Acesso a qualquer casa e mercado
- • Dados em tempo real se bem implementado
− Contras
- • Quebra quando o site muda o layout
- • Sites usam anti-bot pesado (Cloudflare, etc.)
- • Pode violar os termos de uso
- • Precisa de proxies e headless browsers
APIs de Odds
Consome dados estruturados de provedores como The Odds API ou Betfair.
+ Prós
- • Dados limpos e estruturados
- • Uptime confiável
- • Legal e dentro dos termos de uso
- • Atualizações automáticas de novos mercados
− Contras
- • Custo mensal (de $0 a $200+)
- • Rate limits podem ser restritivos
- • Nem todas as casas/mercados disponíveis
Minha recomendação? Começa com API. The Odds API tem um plano grátis de 500 requests por mês — dá pra prototipar tranquilo. Só vai pra scraping se precisar de dados que nenhuma API oferece. E se for por esse caminho, leia nosso guia de web scraping de sites de apostas.
Limpeza e normalização dos dados
Odds brutas de diferentes fontes vêm bagunçadas. Nomes de times diferentes, formatos de odds inconsistentes, mercados faltando. Você precisa normalizar tudo antes de alimentar o modelo.
def normalize_odds(raw_games: list) -> pd.DataFrame:
"""Transforma dados brutos da API em DataFrame limpo."""
rows = []
for game in raw_games:
for bookmaker in game.get("bookmakers", []):
for market in bookmaker.get("markets", []):
if market["key"] == "h2h":
outcomes = {o["name"]: o["price"] for o in market["outcomes"]}
rows.append({
"game_id": game["id"],
"home": game["home_team"],
"away": game["away_team"],
"bookmaker": bookmaker["key"],
"home_odds": outcomes.get(game["home_team"]),
"draw_odds": outcomes.get("Draw"),
"away_odds": outcomes.get(game["away_team"]),
"timestamp": bookmaker["last_update"]
})
return pd.DataFrame(rows)Modelo de IA — features, treinamento e backtesting
Agora a parte mais interessante. O modelo de IA precisa responder uma pergunta simples: qual a probabilidade real de cada resultado? Se o modelo diz que o time da casa tem 60% de chance de vencer e a casa tá pagando odds de 2.0 (que implica 50%), você tem um value bet.
Escolhendo as features certas
As features são o combustível do modelo. Coloque lixo, sai lixo. Pra futebol, as features que mais funcionam na prática são estas.
Features que realmente importam
- Expected Goals (xG) dos últimos 10 jogos de cada time
- Forma recente: pontos ganhos nos últimos 5 jogos em casa/fora
- Confronto direto: histórico dos últimos 5 jogos entre os times
- Odds de mercado (consenso): média das odds de 5+ casas de apostas
- Posição na tabela e diferença de gols
- Dias de descanso desde o último jogo
- Jogadores chave ausentes (se conseguir o dado de forma automatizada)
Um detalhe que quase ninguém fala: as odds de mercado são, elas mesmas, uma feature poderosa. Casas de apostas gastam milhões em modelos. Usar as odds delas como input no seu modelo é tipo ter a resposta parcial de graça.
Treinando o modelo com XGBoost
import xgboost as xgb
from sklearn.model_selection import TimeSeriesSplit
from sklearn.calibration import CalibratedClassifierCV
from sklearn.metrics import log_loss
def train_model(df: pd.DataFrame):
"""Treina modelo calibrado pra prever probabilidades."""
features = ["home_xg_avg", "away_xg_avg", "home_form", "away_form",
"h2h_home_wins", "market_home_prob", "market_draw_prob",
"rest_days_diff", "table_position_diff"]
X = df[features]
y = df["result"] # 0=home, 1=draw, 2=away
tscv = TimeSeriesSplit(n_splits=5)
base_model = xgb.XGBClassifier(
n_estimators=300,
max_depth=5,
learning_rate=0.05,
objective="multi:softprob",
eval_metric="mlogloss"
)
# Calibração é obrigatória — XGBoost puro cospe probabilidades ruins
model = CalibratedClassifierCV(base_model, cv=tscv, method="isotonic")
model.fit(X, y)
logger.info(f"Log loss: {log_loss(y, model.predict_proba(X)):.4f}")
return modelPor que calibração é obrigatória
Um modelo que diz '70% de chance de vitória' precisa acertar perto de 70% das vezes quando faz essa previsão. Isso se chama calibração. Sem isso, suas decisões de value betting vão ser baseadas em probabilidades distorcidas.
Use CalibratedClassifierCV do scikit-learn com o método isotonic. Sempre. Não confie nos scores brutos de nenhum classificador pra betting.
Backtesting — antes de gastar um centavo
Backtesting é rodar o modelo em dados históricos pra ver como ele teria performado. Parece óbvio, mas a maioria dos caras pula direto pro dinheiro real. Não faça isso.
O truque é usar TimeSeriesSplit, nunca KFold aleatório. Dados de apostas são temporais — se você treinar com dados de dezembro pra prever outubro, tá trapaceando. O modelo precisa sempre treinar no passado e prever o futuro, exatamente como vai funcionar na prática.
def backtest(df: pd.DataFrame, model, min_edge=0.05):
"""Simula operação real com dados históricos."""
bankroll = 1000.0
bets = []
for _, row in df.iterrows():
probs = model.predict_proba([row[features]])[0]
for outcome_idx, prob in enumerate(probs):
implied_prob = 1 / row[f"odds_{outcome_idx}"]
edge = prob - implied_prob
if edge > min_edge:
# Kelly criterion pra sizing
kelly_fraction = edge / (row[f"odds_{outcome_idx}"] - 1)
stake = bankroll * kelly_fraction * 0.25 # quarter Kelly
stake = min(stake, bankroll * 0.03) # max 3% por aposta
won = row["result"] == outcome_idx
pnl = stake * (row[f"odds_{outcome_idx}"] - 1) if won else -stake
bankroll += pnl
bets.append({"edge": edge, "stake": stake, "pnl": pnl, "bankroll": bankroll})
results = pd.DataFrame(bets)
logger.info(f"Apostas: {len(results)}, ROI: {results['pnl'].sum()/results['stake'].sum()*100:.1f}%")
return resultsAutomação e execução em tempo real
Se o backtest mostrar resultados positivos (e consistentes, não só um mês bom), dá pra partir pra automação. Aqui o bot roda sozinho: coleta odds, gera previsão, avalia valor e executa.
import schedule
import time
def run_cycle():
"""Um ciclo completo: coleta -> análise -> decisão."""
try:
odds = get_odds()
df = normalize_odds(odds)
df = enrich_with_features(df) # adiciona xG, forma, etc.
for _, game in df.iterrows():
probs = model.predict_proba([game[features]])[0]
decision = evaluate_value(probs, game)
if decision["should_bet"]:
logger.info(f"VALUE encontrado: {game['home']} vs {game['away']}")
logger.info(f" Edge: {decision['edge']:.1%}, Stake: R${decision['stake']:.2f}")
# place_bet(decision) # descomente quando estiver pronto
except Exception as e:
logger.error(f"Erro no ciclo: {e}")
schedule.every(2).minutes.do(run_cycle)
while True:
schedule.run_pending()
time.sleep(1)Repara que o place_bet tá comentado. Roda assim por pelo menos duas semanas, só logando as decisões. Compara o que o bot teria apostado com os resultados reais. Se os números baterem com o backtest, aí sim liga o executor. Paciência aqui salva dinheiro.
Riscos e disclaimer legal
Riscos que você precisa aceitar antes de começar
Overfitting: seu modelo pode parecer incrível no backtest e perder dinheiro no real. Sempre use dados out-of-sample.
Casas limitam contas vencedoras: se você lucrar consistentemente, sua conta será restringida. Isso acontece em semanas, não meses.
Latência mata: a diferença entre uma odd de 2.05 e 1.98 é a diferença entre lucro e prejuízo. Seu bot precisa ser rápido.
Regulação: em muitos países, bots de apostas violam os termos de serviço das casas. No Brasil, a regulação de apostas esportivas ainda está evoluindo.
Risco financeiro: mesmo com edge positivo, sequências de perdas longas acontecem. Kelly criterion ajuda, mas não elimina o risco.
Na real, a maioria das pessoas que constroem bots de apostas acaba aprendendo mais sobre data science e Python do que ganhando dinheiro com apostas. E sinceramente? Esse aprendizado já vale muito.
Perguntas frequentes
Preciso de quanto dinheiro pra começar?
Pra desenvolver e testar, zero. Você pode backtestear com dados gratuitos por meses. Pra operar de verdade, o mínimo razoável gira em torno de R$ 1.000-2.000 como bankroll, pra aguentar as oscilações naturais sem quebrar.
Qual linguagem é melhor pra bots de apostas?
Python, sem dúvida. O ecossistema de data science (pandas, scikit-learn, XGBoost) é imbatível. Se precisar de latência ultra-baixa, partes críticas podem ir pra Rust ou C++, mas 99% dos projetos pessoais ficam bem só com Python.
Dá pra viver de bot de apostas?
Na teoria, sim. Na prática, é extremamente difícil. Casas limitam contas, edges diminuem com o tempo, e o estresse emocional é real. A maioria dos profissionais que conheço diversifica entre apostas, trading e consultoria. Não coloque todos os ovos nessa cesta.
O bot funciona pra qualquer esporte?
A arquitetura funciona pra qualquer esporte, mas as features mudam bastante. Futebol e basquete têm mais dados públicos disponíveis. Esportes menores (tipo handball ou vôlei de ligas regionais) podem ter menos dados mas também menos eficiência nas odds — o que é bom pra encontrar valor.