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.





