Bot di arbitraggio automatico con due strategie indipendenti, entrambe "a rischio di mercato zero" per costruzione: il profitto non dipende dalla direzione del mercato, solo dal fatto che lo spread rilevato copra le fee.
| Strategia | Mercato | Entry point | Stato |
|---|---|---|---|
| Polymarket updown arb | Mercati "Bitcoin Up or Down" (finestre 5 min) | main.py |
Dry-run / produzione (opt-in) |
| Binance triangular arb | Spot Binance (ccxt) |
main_binance.py |
Solo dry-run (Fase 2 bloccata in codice) |
Le due strategie sono completamente separate (moduli, config, entry point) e condividono solo l'infrastruttura comune: logging strutturato, alert e reportistica Telegram.
Sui mercati "BTC Up or Down" ogni finestra da 5 minuti ha due esiti
complementari (Up / Down) quotati separatamente. Quando la somma dei
prezzi ask di entrambi i lati scende sotto una soglia (max_entry_sum), comprare
entrambi i lati contemporaneamente garantisce un payout di $1 a fine
finestra qualunque sia l'esito — il profitto è la differenza tra $1 e il
costo dei due lati, al netto della fee Polymarket (2%).
MarketScanner (Gamma API) → ArbDetector (soglie + filtro simmetria) →
PairExecutor → OrderExecutor (ordini FOK paralleli sui due lati, via
py-clob-client) → PositionTracker (segue la risoluzione della finestra:
open → settling → resolved/expired) → CapitalManager (P&L, reinvestimento).
pip install -r requirements.txt
# Dry-run (nessun ordine reale, default se DRY_RUN=true in .env)
python main.py --dry-run
# Un solo ciclo di scan, poi esce
python main.py --once
# Stato: balance, pair aperti, P&L di sessione
python main.py --balance
python main.py --status
# Produzione (richiede credenziali reali + conferma esplicita a schermo)
python main.pyL'avvio in produzione chiede di digitare YES I UNDERSTAND THE RISKS
prima di piazzare ordini reali. Per la procedura completa di messa in
produzione (wallet, private key, credenziali API L2, allowance on-chain,
ordine di test) vedi GUIDA_PRODUZIONE.md.
python main.py --backtest --days 30 [--slippage 0.005] [--fill-prob 0.80]
python backtest_runner.py --start 2026-01-01 --end 2026-02-01Simula slippage e probabilità di fill FOK sui dati storici scaricati
(data/download_historical.py, backtest/local_fetcher.py).
Configurazione — config/settings.yaml
| Sezione | Parametri chiave |
|---|---|
markets |
pattern slug (btc-updown-5m), intervallo di scan |
arb |
max_entry_sum (0.970), min_profit_pct, fee, filtro simmetria max_price_asymmetry |
execution |
ordine FOK, buffer sul prezzo limite, modalità pair parallela |
sizing |
leg_size_usdc, max_open_pairs, esposizione massima |
risk |
perdita massima giornaliera, drawdown massimo, balance minimo |
resolution |
timeout risoluzione veloce/lenta della finestra |
capital |
percentuale di reinvestimento del profitto |
| File | Ruolo |
|---|---|
data/gamma_api.py |
Client Gamma/CLOB API — market data, risoluzione esiti |
data/market_scanner.py |
Individua le finestre attive da monitorare |
core/arb_detector.py |
Rileva le opportunità (soglie + simmetria) |
core/pair_executor.py |
Orchestrazione dell'esecuzione della coppia |
broker/clob_client.py |
Wrapper py-clob-client (autenticazione L1/L2, ordini) |
broker/order_executor.py |
Piazzamento ordini FOK sui due lati |
broker/position_tracker.py |
Ciclo di vita della posizione fino alla risoluzione |
core/capital_manager.py |
Saldo operativo, P&L, reinvestimento |
core/risk_manager.py |
Limiti di rischio (perdita giornaliera, drawdown, halt) |
core/tier_manager.py |
Scaling del sizing in base al capitale disponibile |
monitoring/* |
Logger strutturato, dashboard CLI, alert, reporter Telegram, API REST/WebSocket |
/status /recap /balance /tier /stats /capital /set /withdraw
/deposit /halt /help
- Margini sottili nel backtest (~1% sopra il break-even fee del 2%).
- Il fill rate reale può essere inferiore a quello simulato in backtest.
- Polymarket può modificare le fee in qualsiasi momento.
- Non investire più di quanto si è disposti a perdere.
Alternativa aggiunta per operare su un exchange crypto regolare (Polymarket
bloccato in Italia da ADM). Sfrutta lo stesso principio: se un ciclo di 3
conversioni (es. USDT → BTC → ETH → USDT) torna con più capitale di quanto
impiegato — dopo tre commissioni — il profitto è garantito indipendentemente
dalla direzione del mercato. Il codice Polymarket non viene toccato: strategia
completamente separata che riusa solo l'infrastruttura comune.
profitto netto = start * rate1 * rate2 * rate3 * (1 - fee)^3 / start - 1
Ogni ciclo viene valutato in entrambe le direzioni (orario e antiorario).
python main_binance.py --dry-run # loop continuo, nessun ordine reale
python main_binance.py --once # un solo ciclo di scan, poi esce
python main_binance.py --balance # stampa i saldi (tracciati e reali), esceConfig: config/settings_binance.yaml
(cicli, fee, soglie di profitto, sizing).
Su Polymarket i due lati si comprano in modo (quasi) atomico. Qui le 3 leg
non sono atomiche: sono tre trade spot in sequenza. Prima di ogni leg
l'executor ri-legge il book e, se il tasso è peggiorato oltre
max_slippage_pct, aborta; se una leg fallisce dopo che le precedenti sono
già state eseguite, le leg completate vengono ricomposte (unwind) verso
l'asset di partenza, così non si resta mai su una posizione intermedia
scoperta.
| File | Ruolo |
|---|---|
data/binance_client.py |
Wrapper ccxt async: order book top-of-book, saldo (read-only) |
core/triangular_arb_detector.py |
Matematica del ciclo, soglie profitto, confidence HIGH/MEDIUM/LOW |
broker/binance_order_executor.py |
Esecuzione sequenziale delle 3 leg con abort/unwind (dry-run) |
core/binance_capital_manager.py |
Saldo per-asset del ciclo, P&L realizzato |
- Fase 1 (attuale): solo detection + dry-run. Nessun ordine reale. Le chiavi API Binance, se impostate, devono avere solo permessi di lettura.
- Fase 2 (trading reale): non abilitata. L'executor blocca
deliberatamente la modalità live (
dry_run=Falsesolleva un errore) finché non viene autorizzata esplicitamente.
Dettagli completi in BINANCE_ARB.md.
py-clob-client>=0.14.0 web3>=6.0.0 pyyaml>=6.0
ccxt>=4.0.0 httpx>=0.27.0 python-dotenv>=1.0.0
tenacity>=8.2.0 rich>=13.7.0 pandas>=2.2.0
numpy>=1.26.0 aiohttp>=3.9.0 pytest / pytest-asyncio
pip install -r requirements.txtCopiare .env.example in .env e compilare (mai committare .env):
POLY_PRIVATE_KEY / POLY_FUNDER_ADDRESS / POLY_API_KEY / POLY_API_SECRET / POLY_API_PASSPHRASE
DRY_RUN=true
DRY_RUN_INITIAL_BALANCE=100.0 # capitale simulato Polymarket
REINVEST_PCT=1.0 # quota di profitto reinvestita
BINANCE_API_KEY / BINANCE_API_SECRET # opzionali, SOLO lettura in Fase 1
DRY_RUN_INITIAL_BALANCE_USDT=1000.0 # capitale simulato Binance
TELEGRAM_BOT_TOKEN / TELEGRAM_CHAT_ID / TELEGRAM_RECAP_HOUR
BOT_API_HOST / BOT_API_PORT / BOT_API_KEY # API REST+WebSocket di controllo
pytestGestione_Bot.bat avvia un pannello di controllo interattivo
(gestione_bot.ps1): stato del bot/watchdog, balance, posizioni aperte,
avvio/arresto processo. Pensato per l'esecuzione continua come Scheduled Task
Windows (riavvio automatico, resiliente a sleep/logoff).
poly-arb/
├── main.py # entry point Polymarket
├── main_binance.py # entry point Binance triangular arb
├── backtest_runner.py # CLI backtest Polymarket
├── config/ # settings.yaml, settings_binance.yaml
├── core/ # detector, capital/risk/tier manager
├── broker/ # client CLOB, executor, position tracker
├── data/ # market data, storico, cache
├── monitoring/ # logger, dashboard, alert, Telegram, API server
├── backtest/ # simulatore e fetcher storici
├── tests/ # suite pytest
├── GUIDA_PRODUZIONE.md # procedura messa in produzione Polymarket
└── BINANCE_ARB.md # dettagli strategia Binance