Polymarket Bot Tutorial · Capítulo 30 de 32

Código de gestão de risco em nível de produção para bots da Polymarket: limites de posição, limites de perda diária, sentinelas de halt, watchdogs de fill-rate, reconciliação ao reiniciar, retries idempotentes. Padrões de código de um trader real em produção.

O que este capítulo cobre

Código de risco é a maior parte de um bot de trading em produção. A lógica de estratégia é a parte fácil; os limites, halts, watchdogs e reconcilers ao redor dela são o que determinam se o bot sobrevive à sua primeira semana ruim. Este capítulo é o padrão de risco em nível de produção.

  • Por que o código de risco é a maior parte de um bot de trading real
  • Limites de posição (por mercado, por estratégia, total)
  • Kill switch de perda diária
  • Sentinelas de halt (emergency stop baseado em arquivo)
  • Watchdog de fill-rate
  • Reconciliar diário vs on-chain ao reiniciar
  • Código: loop com awareness de halt em nível de produção

Por que o código de risco é a maior parte de um bot de trading real

Uma medição que fizemos na base de código do nosso próprio bot: 60% das LOC são código de risco (limites, halts, watchdogs, reconciliação). 30% é estratégia. 10% é cola.

Essa proporção está correta. Estratégia é a parte fácil - descrever quando entrar e quando sair cabe em algumas dezenas de linhas. Código de risco é todo o resto: o que fazer quando o preço se move contra você mais rápido do que o esperado, o que fazer quando os fills param de acontecer, o que fazer quando o WebSocket cai, o que fazer quando a estratégia se mostra não lucrativa.

A maioria das histórias de falha de builders tem a mesma forma: a estratégia funcionou, mas o bot continuou operando durante uma mudança de regime porque nenhum halt disparou. Escreva os halts antes de escrever a estratégia.

Limites de posição (por mercado, por estratégia, total)

Três limites, aplicados no código.

  • Limite por mercado: máximo de $X por mercado, independentemente da confiança no edge. Típico: $25-100 para bots pequenos, $200-500 para produção. Limita o raio de impacto de uma decisão errada em um único mercado.
  • Limite por estratégia: se você roda várias estratégias, cada uma recebe uma fatia do capital total. Típico: 30-50% por estratégia. Evita que um dia ruim de uma estratégia consuma o capital das outras.
  • Limite total: máximo de % do saldo da wallet deployado simultaneamente. Típico: 50-70%. Deixa capital para oportunidades inesperadas ou para pegar bugs de bookkeeping do próprio bot.

Os três limites devem ser aplicados dentro da função de envio de ordens, e não apenas na lógica da estratégia. A estratégia pode ter um bug; a barreira de envio de ordens é a última linha de defesa.

Kill switch de perda diária

O controle de risco mais importante: um kill switch de perda diária.

Regra: se o PnL realizado + não realizado desde a meia-noite UTC cair abaixo de -X% do saldo diário inicial, o bot para de abrir novas posições e, opcionalmente, zera as posições existentes. X típico: 5-10%.

A matemática: um bot com taxa de acerto esperada de 60% talvez tenha 5% de chance de uma sequência de 10 perdas. Sem o kill switch, essa sequência compõe: perda de $200 → o bot continua operando → mais perda de $200 → wallet cai 40%. Com o switch disparando em -10%, o dia ruim se limita a $200, e amanhã o bot recomeça do zero.

O switch é aplicado no servidor: escreva um arquivo de halt ou defina uma flag no banco que o loop de trading verifica a cada iteração. Reinicie apenas após revisão manual.

Sentinelas de halt (emergency stop baseado em arquivo)

O mecanismo de halt mais simples possível: o bot verifica a existência de um arquivo (por exemplo, /opt/pmt/HALT) a cada iteração do loop e para de operar se o arquivo existir.

def trading_loop():
    while True:
        if os.path.exists("/opt/pmt/HALT"):
            log("HALT file detected, sleeping")
            time.sleep(30)
            continue
        run_one_iteration()
        time.sleep(5)

Para parar imediatamente de qualquer lugar (SSH, bot do Telegram, sistema de monitoramento): touch /opt/pmt/HALT. Para retomar: rm /opt/pmt/HALT.

A abordagem baseada em arquivo é intencionalmente simples porque funciona em condições em que mecanismos de halt mais sofisticados falham: quando o bot travou parcialmente, quando o banco de dados está inacessível, quando a API key está com rate limit. Acesso ao sistema de arquivos está sempre disponível.

Watchdog de fill-rate

A estratégia assume que ordens FOK preenchem a uma certa taxa (muitas vezes 60-80%). Quando a taxa cai significativamente, algo mudou: market makers saíram, sua estratégia foi identificada, ou há uma indisponibilidade na API. Qualquer que seja o motivo, a premissa que sustentava a matemática de PnL da estratégia está quebrada.

Lógica do watchdog: contagem móvel de fill-rate de 24 horas. Se for < 30% (ou 50% do esperado), alerta + auto-halt. Retome somente após revisão manual.

O watchdog também é útil como diagnóstico. Uma queda súbita no fill-rate geralmente se correlaciona com um evento externo (deploy da Polymarket, congestionamento na Polygon, seu IP sofrendo rate limit) que você gostaria de saber independentemente do impacto no trading.

Reconciliar diário vs on-chain ao reiniciar

O bot mantém um diário das posições que acredita possuir. A chain mantém a verdade. Eles devem sempre concordar; quando não concordam, o bot está operando com uma crença errada e vai tradar de forma incorreta.

Lógica de reconciliação: em todo reinício e uma vez por hora durante a operação normal, busque os saldos on-chain de cada token que o bot já tocou. Compare com o diário; alerte + faça halt se o saldo de qualquer token diferir do diário além da tolerância de arredondamento.

A causa mais comum de divergência é uma ordem bem-sucedida que a chamada de API do bot não registrou (timeout, retry nunca gravado). A chain tem a posição; o bot acha que não. Sem reconciliação, o bot não publica a saída de take-profit e a posição vai até a resolução.

Código: loop com awareness de halt em nível de produção

Referência: o loop de trading de produção com todos os controles de risco conectados.

def production_loop():
    while True:
        # Halt checks
        if os.path.exists("/opt/pmt/HALT"):
            sleep_with_log(30); continue
        if daily_pnl_below_threshold():
            create_halt("daily PnL kill"); continue

        # Reconcile every hour
        if now() - last_reconcile > 3600:
            ok = reconcile_diary_vs_chain()
            last_reconcile = now()
            if not ok: create_halt("reconciliation failed"); continue

        # Fill-rate watchdog
        if recent_fill_rate() < 0.30:
            create_halt("fill rate collapse"); continue

        # Strategy
        try:
            run_strategy_once()
        except Exception as e:
            log_exception(e)
            if consecutive_exceptions >= 5:
                create_halt(f"exceptions: {e}"); continue
        time.sleep(5)

O padrão: cada iteração passa pela barreira. Bugs da estratégia não conseguem burlar os controles, por construção.

Perguntas frequentes

O que é uma sentinela de halt?
Um arquivo (por exemplo, data/halt_autobuy) que o bot verifica antes de cada ordem. Se o arquivo existir, o bot recusa enviar ordens mesmo que a estratégia diga para fazê-lo. Permite parar o bot no meio de um incidente com um único comando touch. Adicionamos exatamente esse padrão ao nosso trader de produção depois de um incidente de fill travado em abril de 2026.
Quais limites de posição eu devo definir?
Por mercado: 1-5% do bankroll. Por estratégia: 10-20%. Exposição aberta total: 50-70% do bankroll (mantenha uma reserva de caixa). Limite UMA única ordem em 1-2% do bankroll, independentemente da estratégia - uma ordem digitada errado nunca deve ter o tamanho de uma conta.
Como implemento um kill switch de perda diária?
Acompanhe PnL realizado + não realizado por dia UTC. Se o PnL diário cair abaixo de -3 a -5% do bankroll, defina a sentinela de halt e se notifique. O bot para novas ordens; posições existentes são gerenciadas manualmente. Reinicie diariamente às 00:00 UTC.
O que o bot deve fazer ao reiniciar após um crash?
Três passos: (1) Reconciliar ordens abertas via SDK contra seu diário local. (2) Verificar posições abertas on-chain contra seu estado local. (3) Se algo divergir, faça halt no bot e exija revisão manual. Nunca retome automaticamente em um estado inconsistente.
Como evito que um único bug zere minha conta?
Limites em camadas: limite de posição em nível de código, limite de tamanho de ordem em nível de código, sentinela de halt em nível de arquivo, limites implícitos mínimos/máximos em nível de exchange (Polymarket), alertas de monitoramento que te chamam em caso de taxa de ordens incomum. Nenhuma camada isolada é suficiente - elas se multiplicam.
O bot deve operar se o logging falhar?
Não. Se o bot não consegue escrever no diário, ele não consegue reconciliar ao reiniciar, o que significa que um crash leva a um estado inconsistente. Faça hard-fail do bot se o logging falhar. Bots de produção saudáveis são paranoicos com a própria observabilidade.