# Strategia di Grid Trading — Versione Corretta > Documento di specifica della strategia. Descrive *cosa* deve fare il bot e *perché*, > non l'implementazione. È il riferimento da cui partire per riscrivere il codice in > modo sicuro e testabile. --- ## 1. Obiettivo Estrarre profitto dalla **volatilità di un asset all'interno di un intervallo di prezzo (range)**, comprando automaticamente quando il prezzo scende e vendendo quando risale, secondo livelli predefiniti (la "griglia"). La griglia **non prevede** la direzione del mercato: monetizza le oscillazioni. Funziona quando il prezzo oscilla; perde quando il prezzo prende un trend deciso. Tutta la progettazione che segue serve a massimizzare il primo caso e a limitare i danni nel secondo. --- ## 2. Principi corretti (cosa cambia rispetto al bot originale) | Aspetto | Bot originale (sbagliato) | Versione corretta | |---|---|---| | Asset | Shitcoin illiquida (LAND) | Coppia liquida (es. ETH/USDT, BNB/USDT) | | Passo griglia | Assoluto in USDT (`GRID_STEP=3`) | **Percentuale** sul prezzo | | Livelli | Mobili, inseguono il prezzo | **Fissi** dentro un range definito | | Protezione perdite | Nessuna | **Stop-loss** sotto il range + **take-profit** sopra | | Slippage | `amountOutMin = 0` (nessuna) | Calcolato da `getAmountsOut` − tolleranza | | Break-even fee | Ignorato | Passo griglia **> costo round-trip** | | Capitale | Tutto, senza limiti | Allocazione fissa, suddivisa per livello | | Chiave privata | In chiaro nel `.env` | Keystore cifrato o input a runtime | | Validazione | Nessuna | **Backtest** + **testnet** prima del capitale reale | --- ## 3. Definizione della griglia ### 3.1 Parametri di ingresso | Parametro | Significato | Esempio | |---|---|---| | `PAIR` | Coppia da tradare (base/quote) | `ETH/USDT` | | `RANGE_LOW` | Estremo inferiore del range | `2800` | | `RANGE_HIGH` | Estremo superiore del range | `3400` | | `GRID_LEVELS` | Numero di livelli nella griglia | `12` | | `CAPITAL_QUOTE` | Capitale totale in quote (USDT) | `1200` | | `STOP_LOSS` | Prezzo sotto cui il bot chiude tutto e si ferma | `2650` | | `TAKE_PROFIT` | Prezzo sopra cui il bot chiude tutto e si ferma | `3550` | | `SLIPPAGE_BPS` | Tolleranza slippage in basis point (50 = 0,5%) | `50` | | `FEE_BPS` | Fee del DEX in basis point (PancakeSwap = 25) | `25` | ### 3.2 Costruzione dei livelli (griglia geometrica) I livelli vanno spaziati in **percentuale**, non in valore assoluto. Una griglia geometrica mantiene lo stesso rendimento percentuale per ogni gradino, indipendentemente dal prezzo. ``` ratio = (RANGE_HIGH / RANGE_LOW) ^ (1 / GRID_LEVELS) livello[i] = RANGE_LOW * ratio ^ i per i = 0 .. GRID_LEVELS ``` Esempio (`RANGE_LOW=2800`, `RANGE_HIGH=3400`, `GRID_LEVELS=12`): `ratio ≈ 1,0163` → passo di circa **1,63% per gradino**. ### 3.3 Capitale per livello ``` quote_per_livello = CAPITAL_QUOTE / GRID_LEVELS ``` Ogni livello di acquisto impegna `quote_per_livello`. Il capitale è suddiviso in anticipo: il bot **non** può comprare più di quanto allocato, e non scende mai sotto zero. --- ## 4. Vincolo di break-even (regola anti-fee) Una griglia con passi troppo fitti perde: le fee di ogni round-trip (compra + vendi) si mangiano il profitto. **Il passo percentuale della griglia deve superare il costo totale di un round-trip.** ``` costo_round_trip ≈ 2 * (FEE_BPS + SLIPPAGE_BPS) / 10000 (in frazione) passo_griglia = ratio - 1 VINCOLO: passo_griglia > costo_round_trip * margine_sicurezza (margine ≥ 1,5) ``` Esempio con `FEE_BPS=25`, `SLIPPAGE_BPS=50`: `costo_round_trip ≈ 2 * (25+50)/10000 = 1,5%`. Con margine 1,5 → il passo deve essere **≥ 2,25%**. Se la griglia geometrica dà 1,63%, **è troppo fitta**: vanno ridotti i `GRID_LEVELS` o allargato il range finché il vincolo è rispettato. Il bot deve rifiutarsi di partire se il vincolo non è soddisfatto. --- ## 5. Logica operativa ### 5.1 Inizializzazione 1. Validare i parametri: `RANGE_LOW < prezzo_attuale < RANGE_HIGH`, vincolo di break-even rispettato, capitale disponibile sul wallet. 2. Verificare la coppia: liquidità sufficiente, contratto non honeypot (controllo obbligatorio, non opzionale), token con decimali noti. 3. Costruire i livelli (§3.2) e marcare ognuno come `attivo`/`riempito`. 4. Allocare il capitale (§3.3). ### 5.2 Ciclo principale A ogni tick (es. ogni nuovo blocco, o ogni N secondi): ``` prezzo = prezzo_corrente(PAIR) # --- guardie di uscita: hanno priorità su tutto --- SE prezzo <= STOP_LOSS: vendi_tutta_la_posizione() # con slippage protetto ferma il bot, log "STOP-LOSS" SE prezzo >= TAKE_PROFIT: vendi_tutta_la_posizione() ferma il bot, log "TAKE-PROFIT" # --- logica griglia --- PER ogni livello L: SE prezzo attraversa L verso il basso E L non è ancora riempito: compra quote_per_livello # con amountOutMin protetto marca L come riempito SE prezzo attraversa L verso l'alto E il livello sotto è riempito: vendi la quantità di quel livello # con amountOutMin protetto marca quel livello come libero ``` I livelli sono **fissi** (calcolati una volta), non inseguono il prezzo. Questo rende il comportamento prevedibile e backtestabile. ### 5.3 Calcolo `amountOutMin` (protezione slippage — obbligatoria) Mai passare `0`. Prima di ogni swap: ``` atteso = router.getAmountsOut(amountIn, path)[ultimo] amountOutMin = atteso * (10000 - SLIPPAGE_BPS) / 10000 ``` Se la transazione non rientra nella tolleranza, deve **fallire** (revert), non eseguire a qualsiasi prezzo. --- ## 6. Gestione del rischio 1. **Stop-loss obbligatorio** sotto `RANGE_LOW`. È la differenza tra "strategia" e "gambling": senza stop-loss un trend ribassista svuota il wallet. 2. **Take-profit** sopra `RANGE_HIGH` per chiudere quando il prezzo esce dal range al rialzo (la griglia avrebbe già venduto tutto; il take-profit evita di restare esposti). 3. **Capitale segregato**: usare un wallet dedicato, con solo il capitale destinato alla strategia. Mai il wallet principale. 4. **Limite di gas e prezzo gas** ragionevoli, ricalcolati dinamicamente (no valori fissi obsoleti). 5. **Kill-switch manuale**: comando per fermare il bot e liquidare in qualsiasi momento. 6. **Idempotenza/recupero**: se il bot si riavvia, deve ricostruire lo stato dei livelli (riempiti/liberi) dal saldo on-chain, non ripartire da zero. --- ## 7. Validazione prima del capitale reale Nessun fondo reale prima di aver superato, in ordine: 1. **Backtest** su dati storici della coppia (almeno alcuni mesi, includendo sia fasi laterali sia un trend marcato), misurando: PnL netto **dopo** fee e slippage, max drawdown, numero di trade, comportamento allo stop-loss. 2. **Paper trading / simulazione** in tempo reale, senza eseguire ordini veri. 3. **Testnet** (BSC testnet) con la stessa logica e router di test, per verificare l'esecuzione on-chain end-to-end. 4. **Mainnet con capitale minimo** (es. l'equivalente di pochi euro) per la prima settimana, poi scalare solo se i risultati combaciano col backtest. --- ## 8. Quando NON usare questa strategia - Asset illiquido o a rischio rug-pull/honeypot. - Mercato in trend forte e prolungato (la griglia perde: lo stop-loss limita il danno ma non genera profitto). - Passo griglia che non rispetta il vincolo di break-even (§4). - Capitale che non puoi permetterti di perdere. --- ## 9. Parametri di esempio (configurazione di partenza prudente) ``` PAIR = BNB/USDT # coppia liquida su PancakeSwap RANGE_LOW = 580 RANGE_HIGH = 720 GRID_LEVELS = 8 # passo ≈ 2,7% > break-even CAPITAL_QUOTE = 400 # USDT, su wallet dedicato STOP_LOSS = 545 # ~6% sotto RANGE_LOW TAKE_PROFIT = 760 # ~5,5% sopra RANGE_HIGH SLIPPAGE_BPS = 50 # 0,5% FEE_BPS = 25 # PancakeSwap v2 ``` Verifica break-even: passo ≈ 2,7% > `1,5 × (2×0,75%) = 2,25%` ✅ --- *Questo documento descrive la strategia. L'implementazione (ethers v6, gestione sicura della chiave, calcolo slippage, stato persistente, backtester) va sviluppata a parte, con test, e validata secondo §7 prima di qualsiasi capitale reale.*