Pular para o conteúdo
Programacao

Apostas Esportivas com Python: Automacao

Monitorar odds manualmente em dezenas de casas nao escala. Com Python, da pra automatizar a coleta, calcular arbitragem em tempo real e receber alertas antes de todo mundo.

Quem aposta com seriedade sabe que a vantagem nao esta em palpites — esta na velocidade e na escala de analise. Uma oportunidade de arbitragem dura minutos. Odds com valor positivo desaparecem quando o mercado ajusta. Monitorar tudo isso manualmente e impossivel acima de tres casas de apostas.

Python resolve esse problema. Da pra coletar odds de dezenas de casas via API, calcular arbitragem automaticamente e receber uma mensagem no Telegram quando uma oportunidade aparece. Neste artigo voce vai ver o codigo completo para fazer isso. Antes de partir para o codigo, vale entender como funciona a matematica por tras das apostas.

Por que automatizar com codigo

Arbitragem, EV positivo e middle betting dependem de identificar diferencas de odds entre casas antes que elas sejam corrigidas. Isso normalmente leva segundos a minutos. Um humano monitorando manualmente ve uma faixa muito pequena de jogos e casas ao mesmo tempo.

Com um script rodando a cada 2 minutos, voce monitora 20 casas em 5 ligas simultaneamente. Quando os criterios sao atingidos, voce recebe o alerta e decide se aposta. A decisao ainda e humana — a automacao e so o radar.

O que da pra automatizar com Python

Apostas Esportivas com Python: Automacao. Monitorar odds manualmente em dezenas de casas nao escala. Com Python, da pra automatizar a coleta, calcular arbitragem em tempo real e receber alertas antes de todo mundo. Aqui esta o codigo para fazer isso.

Coletando odds com Python via The Odds API

The Odds API agrega odds de dezenas de casas em um endpoint REST simples. O plano gratuito da 500 requests por mes. Para comecar, crie uma conta em the-odds-api.com e pegue sua API key.

python
import requests
import json
from datetime import datetime

API_KEY = 'sua_api_key_aqui'
BASE_URL = 'https://api.the-odds-api.com/v4'

def get_odds(sport='soccer_brazil_campeonato', regions='eu,us', markets='h2h'):
    """
    Retorna odds de multiplas casas para um esporte.
    sport: codigo do esporte (soccer_brazil_campeonato, basketball_nba, etc)
    regions: eu (casas europeias), us (americanas), uk, au
    markets: h2h (1X2), spreads (handicap), totals (over/under)
    """
    url = f'{BASE_URL}/sports/{sport}/odds'
    params = {
        'apiKey': API_KEY,
        'regions': regions,
        'markets': markets,
        'oddsFormat': 'decimal',
        'dateFormat': 'iso'
    }
    
    response = requests.get(url, params=params)
    
    if response.status_code != 200:
        print(f'Erro na API: {response.status_code} - {response.text}')
        return []
    
    # A API informa quantas requests ainda restam no header
    remaining = response.headers.get('x-requests-remaining', 'desconhecido')
    print(f'Requests restantes no plano: {remaining}')
    
    return response.json()

def formatar_jogo(jogo):
    """Extrai os dados relevantes de um jogo da resposta da API."""
    resultado = {
        'id': jogo['id'],
        'inicio': jogo['commence_time'],
        'casa': jogo['home_team'],
        'fora': jogo['away_team'],
        'odds_por_casa': {}
    }
    
    for bookmaker in jogo.get('bookmakers', []):
        nome_casa = bookmaker['key']
        for market in bookmaker['markets']:
            if market['key'] == 'h2h':
                outcomes = {o['name']: o['price'] for o in market['outcomes']}
                resultado['odds_por_casa'][nome_casa] = outcomes
    
    return resultado

# Executar coleta
jogos = get_odds()
for jogo_raw in jogos[:3]:  # Mostrar os 3 primeiros
    jogo = formatar_jogo(jogo_raw)
    print(f"\n{jogo['casa']} vs {jogo['fora']}")
    for casa, odds in jogo['odds_por_casa'].items():
        print(f"  {casa}: {odds}")

Esse script retorna as odds de cada casa para o mercado 1X2 do Campeonato Brasileiro. O proximo passo e passar esses dados para o calculador de arbitragem.

Calculadora de arbitragem em Python

Arbitragem acontece quando a soma das probabilidades implicitas das melhores odds de cada resultado e menor que 100%. O pulo do gato esta em pegar a MELHOR odd de cada resultado entre todas as casas, nao as odds de uma casa so.

python
def calcular_probabilidade_implicita(odd_decimal):
    """Converte odd decimal para probabilidade implicita."""
    return 1 / odd_decimal

def encontrar_melhores_odds(jogo_formatado):
    """
    Para cada resultado possivel, encontra a maior odd entre todas as casas.
    Retorna dict com {resultado: (odd, nome_da_casa)}
    """
    melhores = {}
    
    for casa, odds in jogo_formatado['odds_por_casa'].items():
        for resultado, odd in odds.items():
            if resultado not in melhores or odd > melhores[resultado][0]:
                melhores[resultado] = (odd, casa)
    
    return melhores

def calcular_arbitragem(jogo_formatado, bankroll=1000):
    """
    Verifica se existe oportunidade de arbitragem e calcula os stakes.
    Retorna None se nao houver arbitragem.
    """
    melhores = encontrar_melhores_odds(jogo_formatado)
    
    if not melhores:
        return None
    
    # Soma das probabilidades implicitas das melhores odds
    soma_prob = sum(
        calcular_probabilidade_implicita(odd)
        for odd, _ in melhores.values()
    )
    
    # Se soma < 1, existe arbitragem
    if soma_prob >= 1:
        return None  # Sem oportunidade
    
    margem_arb = (1 - soma_prob) * 100  # Lucro garantido em %
    
    # Calcular quanto apostar em cada resultado
    stakes = {}
    for resultado, (odd, casa) in melhores.items():
        prob = calcular_probabilidade_implicita(odd)
        stake = bankroll * (prob / soma_prob)
        retorno = stake * odd
        stakes[resultado] = {
            'casa': casa,
            'odd': odd,
            'stake': round(stake, 2),
            'retorno_se_ganhar': round(retorno, 2)
        }
    
    lucro_garantido = (bankroll / soma_prob) - bankroll
    
    return {
        'jogo': f"{jogo_formatado['casa']} vs {jogo_formatado['fora']}",
        'inicio': jogo_formatado['inicio'],
        'margem_arbitragem_pct': round(margem_arb, 3),
        'lucro_garantido': round(lucro_garantido, 2),
        'retorno_garantido': round(bankroll / soma_prob, 2),
        'stakes': stakes
    }

# Escanear todos os jogos
def escanear_arbitragem(jogos_raw, bankroll=1000):
    oportunidades = []
    
    for jogo_raw in jogos_raw:
        jogo = formatar_jogo(jogo_raw)
        resultado = calcular_arbitragem(jogo, bankroll)
        if resultado:
            oportunidades.append(resultado)
    
    # Ordenar por margem de arbitragem (maior primeiro)
    oportunidades.sort(key=lambda x: x['margem_arbitragem_pct'], reverse=True)
    return oportunidades

# Exemplo de uso
jogos = get_odds()
oportunidades = escanear_arbitragem(jogos, bankroll=1000)

if not oportunidades:
    print('Nenhuma oportunidade de arbitragem no momento.')
else:
    print(f'{len(oportunidades)} oportunidade(s) encontrada(s):')
    for arb in oportunidades:
        print(f"\n{arb['jogo']}")
        print(f"  Margem: {arb['margem_arbitragem_pct']}%")
        print(f"  Lucro garantido: R${arb['lucro_garantido']}")
        for resultado, dados in arb['stakes'].items():
            print(f"  Apostar R${dados['stake']} em '{resultado}' na {dados['casa']} (odd {dados['odd']})")

Sistema de alertas via Telegram

De nada adianta o script rodar se voce precisa ficar olhando o terminal. O ideal e receber uma mensagem automatica quando uma oportunidade aparece. Telegram e a opcao mais simples: crie um bot com o BotFather, pegue o token e o chat_id.

python
import requests
import time

TELEGRAM_TOKEN = 'seu_bot_token'
CHAT_ID = 'seu_chat_id'

def enviar_alerta_telegram(mensagem):
    url = f'https://api.telegram.org/bot{TELEGRAM_TOKEN}/sendMessage'
    payload = {
        'chat_id': CHAT_ID,
        'text': mensagem,
        'parse_mode': 'HTML'
    }
    response = requests.post(url, json=payload)
    return response.status_code == 200

def formatar_mensagem_arbitragem(arb):
    linhas = [
        f'<b>Arbitragem encontrada!</b>',
        f'Jogo: {arb["jogo"]}',
        f'Margem: {arb["margem_arbitragem_pct"]}%',
        f'Lucro garantido: R${arb["lucro_garantido"]}',
        ''
    ]
    for resultado, dados in arb['stakes'].items():
        linhas.append(
            f'{resultado}: R${dados["stake"]} na {dados["casa"]} (odd {dados["odd"]})'
        )
    return '\n'.join(linhas)

def monitorar_e_alertar(intervalo_segundos=120, bankroll=1000):
    """Roda em loop, verifica arbitragem a cada X segundos."""
    print(f'Monitorando a cada {intervalo_segundos}s...')
    alertas_enviados = set()  # Evitar alertas duplicados
    
    while True:
        try:
            jogos = get_odds()
            oportunidades = escanear_arbitragem(jogos, bankroll)
            
            for arb in oportunidades:
                chave = f"{arb['jogo']}_{arb['inicio']}"
                if chave not in alertas_enviados:
                    mensagem = formatar_mensagem_arbitragem(arb)
                    enviado = enviar_alerta_telegram(mensagem)
                    if enviado:
                        alertas_enviados.add(chave)
                        print(f'Alerta enviado: {arb["jogo"]}')
            
            time.sleep(intervalo_segundos)
        
        except KeyboardInterrupt:
            print('Monitoramento interrompido.')
            break
        except Exception as e:
            print(f'Erro: {e}')
            time.sleep(30)  # Espera antes de tentar de novo

# Para rodar: monitorar_e_alertar(intervalo_segundos=120, bankroll=500)

Esse loop roda ate voce interromper com Ctrl+C. A logica de alertas_enviados evita que voce receba a mesma oportunidade repetidas vezes enquanto ela ainda esta aberta.

Backtesting com historico de odds

Antes de apostar dinheiro real com qualquer sistema, o caminho certo e testar com dados historicos. The Odds API tem um endpoint de historico que retorna como as odds estavam em um momento especifico do passado.

python
def salvar_snapshot_odds(sport, filename=None):
    """Salva as odds atuais em arquivo JSON para backtest futuro."""
    import json
    from datetime import datetime
    
    jogos = get_odds(sport=sport)
    timestamp = datetime.utcnow().isoformat()
    
    snapshot = {
        'timestamp': timestamp,
        'sport': sport,
        'jogos': jogos
    }
    
    if not filename:
        filename = f'odds_{sport}_{timestamp[:10]}.json'
    
    with open(filename, 'w', encoding='utf-8') as f:
        json.dump(snapshot, f, ensure_ascii=False, indent=2)
    
    print(f'{len(jogos)} jogos salvos em {filename}')
    return filename

def backtest_arbitragem(arquivo_snapshot, bankroll=1000):
    """Analisa um snapshot salvo e reporta as oportunidades que existiam."""
    import json
    
    with open(arquivo_snapshot, encoding='utf-8') as f:
        snapshot = json.load(f)
    
    print(f"Backtest: {snapshot['sport']} em {snapshot['timestamp']}")
    oportunidades = escanear_arbitragem(snapshot['jogos'], bankroll)
    
    print(f'Oportunidades encontradas: {len(oportunidades)}')
    for arb in oportunidades:
        print(f"  {arb['jogo']}: {arb['margem_arbitragem_pct']}% margem")
    
    return oportunidades

A ideia e rodar o script de salvar snapshots durante alguns dias e depois analisar quantas oportunidades apareceram, qual foi a margem media e quanto tempo elas ficaram abertas.

Limites legais e praticos dos bots de apostas

Antes de colocar tudo isso em producao, algumas realidades praticas que o entusiasmo com o codigo as vezes esconde.

O que saber antes de automatizar apostas

A maioria das casas proibe bots que apostam automaticamente em seus termos de uso — risco de conta banida

Monitorar e analisar odds com Python e geralmente tolerado; automatizar o clique de apostar nao e

Arbitrageurs sao identificados e limitados pelas casas mesmo fazendo tudo manualmente

A Lei 14.790/2023 regulamenta apostas no Brasil — use apenas casas licenciadas pelo governo

O sistema funciona melhor como radar que te avisa, e a decisao final fica com voce

O uso mais seguro desse tipo de automacao e como ferramenta de analise e alerta, nao como bot que aposta sozinho. Voce recebe o alerta, avalia a oportunidade e executa manualmente. Isso te da velocidade sem o risco de banimento automatico.

Para entender melhor o contexto legal das apostas no Brasil em 2026, veja o guia de arbitragem esportiva com as regulamentacoes atuais.

Conclusao

Python transforma apostas esportivas de uma atividade manual e limitada em algo escalavel. Voce nao vai se tornar rico automaticamente — o codigo e so o radar. As oportunidades existem, mas sao pequenas e desaparecem rapido. A automacao te da a velocidade que o olho humano nao tem.

O proximo passo depois de entender o codigo: calibrar os criterios de alerta para evitar falsos positivos, testar com bankroll pequeno e medir os resultados reais antes de escalar.

Perguntas frequentes

Preciso de muita experiencia em Python para rodar esses scripts?

Conhecimento intermediario e suficiente: instalar bibliotecas, trabalhar com dicionarios e listas, e entender funcoes basicas. Os exemplos usam requests, json e datetime da stdlib, sem frameworks complexos.

The Odds API e gratuita?

Tem um plano gratuito com 500 requests por mes, o que e suficiente para testar e aprender. Para uso em producao monitorando varias ligas em tempo real, provavelmente vai precisar de um plano pago. Existem alternativas como a API da Betfair para mercados de exchange.

Usar bots para apostar e proibido pelas casas?

A maioria das casas de apostas proibe explicitamente bots que fazem apostas automatizadas em seus termos de uso. Usar Python para monitorar e analisar odds e geralmente tolerado, mas automatizar o ato de apostar e um risco de ter a conta suspensa. Verifique os termos de cada casa antes de automatizar qualquer acao.

Por que automatizar com codigo

Arbitragem, EV positivo e middle betting dependem de identificar diferencas de odds entre casas antes que elas sejam corrigidas. Isso normalmente leva segundos a minutos. Um humano monitorando manualmente ve uma faixa muito pequena de jogos e casas ao mesmo tempo. Com um script rodando a cada 2 minutos, voce monitora 20 casas em 5 ligas simultaneamente. Quando os criterios sao atingidos, voce recebe o alerta e decide se aposta. A decisao ainda e humana — a automacao e so o radar.