Tutorial sui bot di Polymarket · Capitolo 30 di 32

Codice di gestione del rischio di livello produzione per Polymarket bot: tetto di posizione, limite di perdita giornaliero, halt sentinel, fill-rate watchdog, reconcile-on-restart, retry idempotenti. Pattern di codice da un vero trader in produzione.

Cosa copre questo capitolo

Il codice di rischio è la maggior parte di un trading bot di produzione. La logica di strategia è la parte facile; i tetti, gli halt, i watchdog e i reconciler che la circondano sono ciò che determina se il bot sopravvive alla sua prima settimana negativa. Questo capitolo è il pattern di rischio di livello produzione.

Questo è il capitolo 30 della nostra serie in 32 parti su come costruire un Polymarket trading bot. Trattiamo l’argomento in profondità nelle sezioni qui sotto. Il corpo di ogni sezione viene scritto e pubblicato capitolo per capitolo; le risposte della FAQ e i riferimenti sono già completi e riflettono l’esperienza di produzione maturata gestendo il nostro trader.

  • Perché il codice di rischio è la parte più importante di un vero trading bot
  • Tetto di posizione (per mercato, per strategia, totale)
  • Kill switch per perdita giornaliera
  • Halt sentinel (arresto di emergenza basato su file)
  • Fill-rate watchdog
  • Riconciliazione del diario vs on-chain al riavvio
  • Codice: loop di livello produzione con consapevolezza degli halt

Perché il codice di rischio è la parte più importante di un vero trading bot

Una misurazione che abbiamo fatto sul codebase del nostro bot: il 60% delle LOC è codice di rischio (tetti, halt, watchdog, riconciliazione). Il 30% è strategia. Il 10% è codice di collegamento.

Quel rapporto è corretto. La strategia è la parte facile - descrivere quando entrare e quando uscire sta in poche decine di righe. Il codice di rischio è tutto il resto: cosa fare quando il prezzo si muove contro di te più velocemente del previsto, cosa fare quando i fill smettono di arrivare, cosa fare quando il WebSocket cade, cosa fare quando la strategia si rivela non profittevole.

Le storie di fallimento degli sviluppatori hanno quasi sempre la stessa forma: la strategia funzionava, ma il bot ha continuato a tradare durante un cambio di regime perché non è scattato nessun halt. Scrivi gli halt prima di scrivere la strategia.

Tetto di posizione (per mercato, per strategia, totale)

Tre tetti, applicati nel codice.

  • Tetto per mercato: massimo $X per mercato indipendentemente dalla fiducia nel vantaggio. Tipico: $25-100 per bot piccoli, $200-500 per la produzione. Limita il raggio d’impatto di una singola chiamata errata su un mercato.
  • Tetto per strategia: se esegui più strategie, ciascuna riceve una quota del capitale totale. Tipico: 30-50% per strategia. Impedisce che una giornata storta di una strategia consumi il capitale delle altre.
  • Tetto totale: massima % del saldo wallet impiegata simultaneamente. Tipico: 50-70%. Lascia capitale per opportunità inattese o per intercettare i bug di contabilità del bot stesso.

Tutti e tre i tetti devono essere applicati dentro la funzione di piazzamento degli ordini, non solo nella logica della strategia. La strategia può avere un bug; il gate di piazzamento degli ordini è l’ultima linea di difesa.

Kill switch per perdita giornaliera

Il singolo controllo di rischio più importante: un kill switch per perdita giornaliera.

Regola: se il PnL realizzato + non realizzato da mezzanotte UTC scende sotto -X% del saldo giornaliero iniziale, il bot smette di aprire nuove posizioni e, opzionalmente, chiude quelle esistenti. X tipico: 5-10%.

La matematica: un bot con win rate atteso del 60% ha forse una probabilità del 5% di una serie perdente di 10 trade. Senza kill switch, quella serie si compone: perdita di $200 → il bot continua a tradare → un’altra perdita di $200 → wallet a -40%. Con lo switch che scatta a -10%, la giornata negativa si ferma a $200, e domani il bot riparte da zero.

Lo switch viene applicato lato server: scrivi un file di halt o imposta un flag in database che il trading loop controlla a ogni iterazione. Riavvia solo dopo una revisione manuale.

Halt sentinel (arresto di emergenza basato su file)

Il meccanismo di halt più semplice possibile: il bot controlla la presenza di un file (per esempio /opt/pmt/HALT) a ogni iterazione del loop e smette di tradare se il file esiste.

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)

Per fermare immediatamente da qualsiasi punto (SSH, Telegram bot, sistema di monitoraggio): touch /opt/pmt/HALT. Per riprendere: rm /opt/pmt/HALT.

L’approccio basato su file è volutamente essenziale perché funziona in condizioni in cui meccanismi di halt più sofisticati falliscono: quando il bot è parzialmente crashato, quando il database non è raggiungibile, quando la API key è soggetta a rate limit. L’accesso al filesystem è sempre disponibile.

Fill-rate watchdog

La strategia assume che gli ordini FOK vengano filled a un certo tasso (spesso 60-80%). Quando il tasso scende in modo significativo, qualcosa è cambiato: i market maker si sono ritirati, la tua strategia è stata identificata, c’è un’interruzione dell’API in corso. Qualunque sia il motivo, l’assunzione che guidava la matematica del PnL della strategia è rotta.

Logica del watchdog: conteggio mobile del fill-rate nelle ultime 24 ore. Se < 30% (o 50% dell’atteso), avviso + auto-halt. Riprendi solo dopo una revisione manuale.

Il watchdog è utile anche come diagnostica. Un calo improvviso del fill-rate di solito è correlato a un evento esterno (deploy di Polymarket, congestione di Polygon, il tuo IP che viene rate-limited) che vorresti comunque conoscere, indipendentemente dall’impatto sul trading.

Riconciliazione del diario vs on-chain al riavvio

Il bot mantiene un diario delle posizioni che pensa di detenere. La chain mantiene la verità. Dovrebbero sempre coincidere; quando non coincidono, il bot sta operando con una convinzione errata e tradarà in modo sbagliato.

Logica di riconciliazione: a ogni riavvio e una volta all’ora durante il normale funzionamento, recupera i saldi on-chain per ogni token che il bot ha toccato. Confrontali con il diario; avviso + halt se il saldo di un token differisce dal diario oltre la tolleranza di arrotondamento.

La causa più comune della divergenza è un ordine riuscito che la chiamata API del bot si è persa (timeout, retry mai registrato). La chain ha la posizione; il bot pensa di no. Senza riconciliazione, il bot non pubblicherà l’uscita take-profit e la posizione andrà fino alla risoluzione.

Codice: loop di livello produzione con consapevolezza degli halt

Riferimento: il trading loop di produzione con tutti i controlli di rischio collegati.

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)

Il pattern: ogni iterazione passa attraverso il gate. I bug della strategia non possono bypassare i controlli, per costruzione.

Domande frequenti

Che cos’è un halt sentinel?
Un file (per esempio, data/halt_autobuy) che il bot controlla prima di ogni ordine. Se il file esiste, il bot rifiuta di piazzare ordini anche se la strategia lo richiede. Ti permette di fermare il bot nel mezzo di un incidente con un semplice comando touch. Abbiamo aggiunto esattamente questo pattern al nostro trader di produzione dopo un incidente di wedged-fill nell’aprile 2026.
Che tetto di posizione dovrei impostare?
Per mercato: 1-5% del bankroll. Per strategia: 10-20%. Esposizione aperta totale: 50-70% del bankroll (mantieni una riserva di liquidità). Limita un SINGOLO ordine all’1-2% del bankroll indipendentemente dalla strategia - un ordine piazzato per errore non dovrebbe mai avere dimensione da account.
Come implemento un kill switch per perdita giornaliera?
Traccia il PnL realizzato + non realizzato per giorno UTC. Se il PnL giornaliero scende sotto -3% o -5% del bankroll, imposta il halt sentinel e inviati una notifica. Il bot smette di inviare nuovi ordini; le posizioni esistenti vengono gestite manualmente. Reset ogni giorno alle 00:00 UTC.
Cosa dovrebbe fare il bot al riavvio dopo un crash?
Tre passaggi: (1) Riconciliazione degli ordini aperti tramite SDK rispetto al tuo diario locale. (2) Controllo delle posizioni aperte on-chain rispetto allo stato locale. (3) Se qualcosa diverge, halt del bot e revisione manuale obbligatoria. Non riprendere mai automaticamente in uno stato inconsistente.
Come evito che un singolo bug svuoti il mio account?
Limiti a più livelli: tetto di posizione a livello di codice, tetto sulla dimensione dell’ordine a livello di codice, halt sentinel a livello di file, minimo/massimo implicito a livello di exchange (Polymarket), avvisi di monitoraggio che ti segnalano frequenze di ordini insolite. Nessun singolo livello è sufficiente - si moltiplicano.
Il bot dovrebbe tradare se il logging fallisce?
No. Se il bot non può scrivere nel proprio diario, non può fare riconciliazione al riavvio, il che significa che un crash porta a uno stato inconsistente. Fai hard-fail del bot se il logging fallisce. I bot di produzione sani sono paranoici riguardo alla propria osservabilità.