YouMind
Accedi

Grok Bot da zero in una notte: configurazione completa + filtro anti-rug copy-paste

@0xboan
INGLESE17 ott 2026
126K
139
19
20
439

TL;DR

Questa guida illustra come costruire un desk di trading Grok Bot da zero, concentrandosi su un rigoroso filtro anti-rug a 14 passaggi per eliminare i token scam prima dell'esecuzione. Enfatizza un flusso di lavoro 'il codice uccide, Grok legge, tu firmi' con salvaguardie di paper trading.

la maggior parte delle persone scopre Grok Bot tramite lo screenshot del pnl di qualcun altro, lo apre, lo punta su un grafico e perde i primi 50$ su un token che era già morto prima ancora di comprarlo. il problema non era il bot. nessuno gli aveva spiegato che aspetto ha un token morto.

questa è la configurazione che ricostruirei stasera stessa se dovessi ricominciare da zero. un bot, una cartella, dieci piccoli file. non va a caccia di 100x. il suo compito principale è eliminare token, e quei pochi che sopravvivono hanno comunque bisogno che Grok legga X prima che venga mosso un solo dollaro.

i passaggi da 01 a 07 sono la prima serata: il bot, la chiave, i limiti, le uscite. da 08 a 12 c'è il filtro anti-rug, 14 controlli, ognuno scritto sotto forma di codice. il 13 e il 14 mettono tutto in autopilota, prima solo su carta.

se hai letto il mio post sulla desk a otto agenti, queste sono le fondamenta su cui poggia quella desk.

https://x.com/0xboan/status/2092226208234647626

come usarlo: apri il tuo Grok Bot, incolla questo intero articolo e digita "costruisci questa desk in /workspace/desk, modalità paper, chiedimi prima che qualcosa tocchi un wallet." scriverà ogni file da solo, sul suo computer.

la divisione dei ruoli da tenere a mente: il codice elimina, Grok legge X, tu firmi. nessuno sulla desk fa il lavoro di un altro.

01. procurati quattro cose prima di iniziare

quattro cose. per ognuna ti spiego cos'è, cosa devi fare stasera e perché la desk ne ha bisogno.

1. Grok Bot

cos'è. l'app dove assumi bot con un nome. ognuno lavora su un computer cloud dotato di browser, file e terminale, e continua a lavorare anche con il tuo laptop chiuso.

cosa fare. scaricalo da x.ai/bot, accedi, scegli Crea il tuo (Create your own).

perché. l'intera desk vive su quel computer. file, routine, avvisi, tutto in un unico posto che puoi aprire dal telefono.

2. una chiave API xAI

cos'è. accesso a pagamento a Grok tramite codice, con la ricerca su X integrata.

cosa fare. vai su console.x.ai, API Keys, creane una. non incollarla ancora da nessuna parte, il passaggio 03 spiega dove va messa.

perché. una routine non può starsene seduta a riflettere su quaranta token in una chat. uno script che fa una chiamata per token sì, e registra ogni risposta nello stesso formato.

3. Rugcheck e DexScreener

cosa sono. due API pubbliche gratuite. Rugcheck legge il contratto: autorità, LP, holder, insider, il wallet del dev. DexScreener legge il pool: profondità, età, acquisti rispetto alle vendite.

cosa fare. niente. nessuna registrazione, nessuna chiave per le letture.

perché. i fatti vengono prima delle opinioni. un'autorità di mint aperta non è una questione di giudizio, è un fatto, e i fatti eliminano per primi.

4. un burner wallet, ma non stasera

cos'è. un wallet Solana nuovo di zecca che non ha mai contenuto nient'altro.

cosa fare. per ora niente. la prima settimana si opera su carta.

perché. la desk non detiene mai una chiave. quando andrai live, ti dirà cosa comprare e sarai tu a firmare.

02. assumi un bot, non otto

la mia desk ora fa girare otto bot. non ha iniziato così, e nemmeno la tua dovrebbe farlo. otto bot il primo giorno significano otto cose da debuggare contemporaneamente. un bot con un solo compito ti mostrerà di cosa avranno bisogno gli altri sette più avanti.

scegli Crea il tuo (Create your own) e assegnagli questo, parola per parola:

text
1Nome: RUG DESK
2Lavoro: Desk per memecoin Solana, prima solo su carta
3Descrizione: Costruisci e gestisci la desk in /workspace/desk partendo dall'articolo che incollo.
4Ogni token passa attraverso check.py, senza eccezioni, senza scorciatoie.
5Non compri, vendi, firmi o sposti mai fondi. Non modifichi mai config.py a meno che non te lo chieda
6in questa chat. Non abbassi mai il valore di un filtro per far passare un token.
7Segnala ogni eliminazione con il relativo motivo, non la tua opinione sul token.
8Quando una fonte è offline, dimmi quale e saltala. Non indovinare mai un numero mancante.

le ultime due righe contano più delle prime cinque. un bot che tira a indovinare un numero mancante, prima o poi ne indovinerà uno che ti costerà caro.

boan - inline image

03. tieni la chiave fuori dalla chat

tutto ciò che scrivi a un bot finisce in un registro. quindi la chiave va inserita in un file, digitata da te, sul computer del bot.

apri il computer del bot, clicca su Take over (Prendi il controllo), apri il terminale ed esegui questo. chiederà la chiave senza mostrarla a schermo, così non comparirà nemmeno nella cronologia:

bash
1mkdir -p /workspace/desk && cd /workspace/desk
2read -rs -p "xai key: " K && printf 'XAI_API_KEY=%s\n' "$K" > .env && unset K
3chmod 600 .env
4pip install requests

poi dimostra che la chiave funziona prima di fare qualsiasi altra cosa. una sola chiamata, così non confonderai mai una chiave errata con un prompt sbagliato in seguito:

bash
1curl -s https://api.x.ai/v1/responses \
2 -H "Authorization: Bearer $(cut -d= -f2 .env)" \
3 -H "Content-Type: application/json" \
4 -d '{"model":"grok-4.7","input":"reply with OK"}'
5
6-> ... "type":"output_text","text":"OK" ...

clicca su I'm done (Ho finito) e restituisci il computer. da qui in poi il bot potrà gestire la desk, continuando a non vedere mai la chiave nella chat.

boan - inline image

04. visualizza l'intero funnel prima di costruirne una parte

otto passaggi. quelli gratuiti girano per primi. solo ciò che sopravvive ai passaggi gratuiti costa una chiamata a Grok, e solo ciò per cui Grok dice COMPRA costa denaro. questa settimana, nemmeno quello.

text
10. LEAD un CA da qualsiasi parte: una call, un post, scan.py -> un mint
21. LIMITI book.py: perdita giornaliera, slot aperti, cooldown -> gratis, nessuna connessione di rete
32. FATTI rugcheck.py: 10 eliminazioni nette -> mint aperto, LP sbloccato, top 10 troppo concentrato muoiono qui
43. POOL market.py: profondità, età, vendite -> i pool sottili e le honeypot muoiono qui
54. GIUDIZIO grok.py + ricerca X, una chiamata -> COMPRA o SALTA, un motivo, un rischio
65. ESECUZIONE carta: book.py al prezzo live -> live: firmi tu stesso
76. MONITORAGGIO watch.py ogni 10 minuti -> stop, ladder, trail, time stop
87. REPORT report.py alle 21:30 -> cosa è morto, cosa ha pagato, cosa mettere in discussione

un'autorità di mint aperta non è una questione di giudizio. è un fatto, e i fatti sono gratis. Grok vede solo i token che hanno già superato tutti i controlli che uno script può eseguire.

boan - inline image

05. metti tutti i numeri in un unico file

salva come config.py. ogni numero della desk vive qui, così quando ricalibri, modifichi un solo file e nient'altro. questi sono i miei, calibrati per un ticket da 25$. non sono una raccomandazione, sono un punto di partenza che sposterai.

python
1# config.py
2# ogni numero della desk vive qui. quando ricalibri, modifichi questo file e nient'altro.
3
4MODEL = "grok-4.7" # controlla console.x.ai -> Models se l'API lo rifiuta
5PAPER = True # prima settimana: esecuzioni simulate a prezzi reali. cambialo solo dopo aver letto il log
6
7TICKET_USD = 25 # fisso. mai dimensionato in base all'ultima vincita
8MAX_OPEN = 4 # 4 x 25$ = 100$ nel mercato, al massimo
9MAX_ENTRIES_PER_DAY = 6
10DAILY_LOSS_HALT_USD = 50 # se la perdita realizzata oggi raggiunge questo -> nessun nuovo ingresso fino a domani
11COOLDOWN_HOURS = 24 # nessun rientro in un token appena lasciato
12
13FACTS = { # il filtro anti-rug. solo codice, nessun modello
14 "max_risk_score": 40, # score_normalised di rugcheck, 0-100, più alto = più rischioso
15 "min_lp_locked_pct": 90, # pool più grande: LP bloccato o bruciato
16 "max_top10_pct": 30, # top 10 holder, esclusi pool e locker
17 "max_dev_pct": 5, # supply ancora ferma nel wallet del creatore
18 "max_insiders": 0, # holder segnalati come insider + riscontri nel grafico degli insider
19 "min_liquidity_usd": 30000,
20 "max_ticket_share": 0.01, # il tuo ticket non è mai superiore all'1% del pool
21 "min_age_min": 30, # più giovane di così, ogni report sta ancora tirando a indovinare
22 "max_age_hours": 72,
23}
24
25MIN_CONFIDENCE = 0.7 # se Grok dice COMPRA sotto questo valore -> trattato come SALTA
26
27EXIT = {
28 "stop_pct": -35, # stop loss netto dall'ingresso
29 "ladder": [(100, 0.50), (200, 0.25)], # +100% vende metà, +200% vende un quarto
30 "trail_pct": 30, # il resto: esce quando il prezzo scende del 30% dal picco
31 "time_stop_hours": 6, # non sale del 20% dopo 6 ore -> fuori, capitale morto
32 "time_stop_min_pct": 20,
33 "liq_drop_pct": 40, # liquidità del pool scesa del 40% dall'ingresso -> fuori subito
34}
35
36LOG = "checks.csv"
37POSITIONS = "positions.json"
38TRADES = "trades.csv"
text
1TICKET FISSO. la size non cresce solo perché le ultime tre operazioni sono andate bene.
2IL BOT LEGGE config.py, NON LO SCRIVE MAI. un numero cambia solo quando lo cambi tu.
3UN FILTRO SI ALLARGA SOLO PER ISCRITTO. cambi un numero, spieghi perché in chat, lo stesso giorno.

06. fai girare i limiti prima di qualsiasi altra cosa

salva come book.py. il controllo più economico della desk è quello che non chiama mai un'API. se oggi hai già perso 50$, la desk non guarda nemmeno il token. se ci sono quattro posizioni aperte, idem. questo file è anche la memoria della desk: due file che puoi aprire tu stesso, positions.json e trades.csv.

python
1# book.py
2# posizioni, trade, limiti. la memoria della desk vive in due file che puoi aprire tu stesso.
3import csv, json, os, sys, time
4from config import (POSITIONS, TRADES, TICKET_USD, MAX_OPEN, MAX_ENTRIES_PER_DAY,
5 DAILY_LOSS_HALT_USD, COOLDOWN_HOURS)
6
7def load() -> dict:
8 return json.load(open(POSITIONS)) if os.path.exists(POSITIONS) else {}
9
10def save(book: dict):
11 json.dump(book, open(POSITIONS, "w"), indent=2)
12
13def trades() -> list[dict]:
14 return list(csv.DictReader(open(TRADES))) if os.path.exists(TRADES) else []
15
16def record(mint, symbol, action, usd, pnl, reason):
17 new = not os.path.exists(TRADES)
18 with open(TRADES, "a", newline="") as f:
19 w = csv.DictWriter(f, fieldnames=["time", "mint", "symbol", "action", "usd", "pnl", "reason"])
20 if new:
21 w.writeheader()
22 w.writerow({"time": time.strftime("%Y-%m-%d %H:%M"), "mint": mint, "symbol": symbol,
23 "action": action, "usd": round(usd, 2), "pnl": round(pnl, 2), "reason": reason})
24
25def today_pnl() -> float:
26 day = time.strftime("%Y-%m-%d")
27 return sum(float(t["pnl"]) for t in trades() if t["time"].startswith(day))
28
29def guard(mint: str) -> str | None:
30 """I limiti girano prima di qualsiasi chiamata di rete. Un ingresso bloccato non costa nulla."""
31 day = time.strftime("%Y-%m-%d")
32 book = load()
33 if today_pnl() <= -DAILY_LOSS_HALT_USD: return "halted_daily_loss"
34 if mint in book: return "already_open"
35 if len(book) >= MAX_OPEN: return "max_open"
36 opens = [t for t in trades() if t["action"] == "open" and t["time"].startswith(day)]
37 if len(opens) >= MAX_ENTRIES_PER_DAY: return "max_entries_today"
38 cutoff = time.strftime("%Y-%m-%d %H:%M", time.localtime(time.time() - COOLDOWN_HOURS * 3600))
39 if any(t["mint"] == mint and t["action"] == "close" and t["time"] >= cutoff for t in trades()):
40 return "cooldown"
41 return None
42
43def open_position(mint, symbol, price, liq_usd, usd=TICKET_USD):
44 book = load()
45 book[mint] = {"symbol": symbol, "entry": price, "qty0": usd / price, "qty": usd / price,
46 "peak": price, "liq0": liq_usd, "opened": time.time(), "steps": 0}
47 save(book)
48 record(mint, symbol, "open", usd, 0, "entry")
49
50def sell(mint, frac_of_original, price, reason) -> float:
51 """Vende una frazione della size ORIGINALE (1.0 = tutto ciò che resta). Restituisce il pnl realizzato."""
52 book = load()
53 p = book[mint]
54 q = min(p["qty"], p["qty0"] * frac_of_original)
55 pnl = q * (price - p["entry"])
56 p["qty"] -= q
57 action = "close" if p["qty"] <= p["qty0"] * 1e-6 else "partial"
58 record(mint, p["symbol"], action, q * price, pnl, reason)
59 if action == "close":
60 del book[mint]
61 save(book)
62 return pnl
63
64if __name__ == "__main__":
65 # modalità live: dopo aver comprato nel tuo wallet -> python book.py add <mint> <usd> <price> <liq_usd>
66 # dopo aver venduto a mano -> python book.py close <mint> <price>
67 cmd = sys.argv[1]
68 if cmd == "add":
69 mint, usd, price, liq = sys.argv[2], float(sys.argv[3]), float(sys.argv[4]), float(sys.argv[5])
70 open_position(mint, mint[:6], price, liq, usd)
71 elif cmd == "close":
72 print(round(sell(sys.argv[2], 1.0, float(sys.argv[3]), "manual"), 2))

07. scrivi l'uscita prima dell'ingresso

la maggior parte delle persone decide quando vendere mentre fissa una candela verde. è il momento peggiore per decidere qualsiasi cosa. su questa desk ogni uscita esiste prima che il token venga comprato, e il bot si limita a controllarla ogni 10 minuti:

  • liquidità ritirata del 40% dall'ingresso: fuori, tutta, senza fare domande
  • giù del 35%: fuori
  • su del 100%: metà esce, il resto sono soldi del mercato
  • su del 200%: esce un altro quarto
  • dopo il primo take profit, il resto esce quando il prezzo scende del 30% dal picco
  • sei ore senza un +20%: fuori, lo slot vale più della speranza

salva come watch.py:

python
1# watch.py
2# ogni posizione aperta, ogni 10 minuti. non stampa nulla se non è cambiato nulla.
3import time
4from config import EXIT, PAPER
5from market import pool
6import book
7
8def watch() -> list[str]:
9 events = []
10 for mint, p in list(book.load().items()):
11 try:
12 m = pool(mint)
13 except Exception as e:
14 events.append(f"{p['symbol']}: feed del prezzo offline ({e}), mantengo, riproverò")
15 continue
16 if not m or m["price"] <= 0:
17 events.append(f"{p['symbol']}: pool sparito. trattalo come rugged, vendi il possibile")
18 book.sell(mint, 1.0, 0.0, "pool_gone")
19 continue
20
21 price = m["price"]
22 b = book.load(); s = b[mint]
23 s["peak"] = max(s["peak"], price); book.save(b)
24 pct = (price / s["entry"] - 1) * 100
25 hours = (time.time() - s["opened"]) / 3600
26
27 def out(frac, why):
28 pnl = book.sell(mint, frac, price, why)
29 verb = "venduto" if PAPER else "VENDI ORA nel tuo wallet"
30 size = "il resto" if frac >= 1 else f"{int(frac * 100)}%"
31 events.append(f"{s['symbol']}: {verb} {size} a {pct:+.0f}% ({why}), pnl ${pnl:+.2f}")
32
33 if m["liq_usd"] < s["liq0"] * (1 - EXIT["liq_drop_pct"] / 100):
34 out(1.0, "liquidity_pulled"); continue
35 if pct <= EXIT["stop_pct"]:
36 out(1.0, "stop"); continue
37 ladder = EXIT["ladder"]
38 if s["steps"] < len(ladder) and pct >= ladder[s["steps"]][0]:
39 out(ladder[s["steps"]][1], f"take_profit_{ladder[s['steps']][0]}")
40 b = book.load()
41 if mint in b:
42 b[mint]["steps"] += 1; book.save(b)
43 continue
44 if s["steps"] > 0 and price <= s["peak"] * (1 - EXIT["trail_pct"] / 100):
45 out(1.0, "trailing_stop"); continue
46 if hours >= EXIT["time_stop_hours"] and pct < EXIT["time_stop_min_pct"]:
47 out(1.0, "time_stop")
48 return events
49
50if __name__ == "__main__":
51 for e in watch():
52 print(e)
text
1PRIMA LA LIQUIDITÀ. un pool svuotato batte qualsiasi altra regola, anche su una posizione in profitto.
2IL TRAILING STOP SI ATTIVA DOPO IL PRIMO TAKE PROFIT. prima di allora, -35% è l'unico pavimento.
3IL CAPITALE MORTO È COMUNQUE UNA PERDITA. sei ore piatte liberano lo slot per il token successivo.
4IL SILENZIO È UNO STATO. watch.py non stampa nulla se non cambia nulla, quindi una chat silenziosa significa che non devi guardare.
boan - inline image

08. impara i 14 modi in cui un token muore

se dovessi buttare via tutto il resto e tenere una sola cosa, sarebbe questa. funziona anche senza alcun bot: fai gli stessi 14 controlli a mano su rugcheck.xyz e dexscreener prima del tuo prossimo acquisto e salterai la maggior parte dei token di cui stavi per pentirti.

13 dei controlli sono codice. confronti, nessun modello, nessuna opinione. il 14° è l'unico che richiede Grok.

#

controllo

elimina quando

perché

1

già rugged

Rugcheck lo segnala come rugged

qualcuno lo ha già fatto

2

mint authority

ancora aperta

il dev può stampare nuova supply nel tuo bag

3

freeze authority

ancora aperta

il dev può congelare i tuoi token, non puoi vendere

4

segnalazioni di pericolo

qualsiasi rischio di livello danger

Rugcheck ha già visto qualcosa che dovresti smentire

5

risk score

superiore a 40/100

i piccoli avvisi si sommano

6

blocco LP

il pool più grande ha meno del 90% bloccato o bruciato

la liquidità sbloccata è un pulsante per il pull

7

top 10 holder

oltre il 30%, esclusi pool e locker

dieci wallet possono chiudere il tuo trade insieme

8

wallet del dev

il creatore detiene ancora oltre il 5%

il dev è il primo a vendere

9

insider / bundle

qualsiasi holder insider o riscontro nel grafico degli insider

i wallet finanziati insieme vendono insieme

10

profondità del pool

meno di 30k$ di liquidità

saresti l'uscita di qualcun altro

11

quota del ticket

i tuoi 25$ sono oltre l'1% del pool

il tuo stesso acquisto muove il prezzo

12

età

meno di 30 min o più di 72h

troppo fresco per qualsiasi report, oppure il movimento è già avvenuto

13

esistono vendite

20+ acquisti nell'ultima ora, zero vendite

è la forma tipica di una honeypot

14

lettura X (Grok)

nessun post, CA copiato, hype comprata, storico di rug

la parte che nessuna API restituisce

boan - inline image

09. lascia che sia il codice a eliminare quelli ovvi

controlli da 1 a 9. recupera un singolo report e conserva solo i campi che la desk legge. Grok non vede mai il report grezzo, un payload pesante costa token e riduce l'accuratezza.

un dettaglio che molti trascurano: il vault del pool stesso e i locker finiscono nella lista dei top holder. contali e ogni token sembrerà un token da whale. il codice li scarta prima di sommare il top 10.

python
1# rugcheck.py
2# un report per token, ridotto ai campi che la desk legge. Grok non vede mai il report grezzo.
3import requests
4from config import FACTS
5
6RC = "https://api.rugcheck.xyz/v1/tokens"
7
8def report(mint: str) -> dict:
9 r = requests.get(f"{RC}/{mint}/report", timeout=20)
10 r.raise_for_status()
11 d = r.json()
12 token = d.get("token") or {}
13 known = d.get("knownAccounts") or {}
14
15 def is_pool(h): # i vault AMM e i locker sono nei top holder, non sono whale
16 tag = known.get(h.get("owner")) or known.get(h.get("address")) or {}
17 return str(tag.get("type", "")).upper() in ("AMM", "LOCKER")
18
19 holders = [h for h in (d.get("topHolders") or []) if not is_pool(h)]
20 markets = sorted(d.get("markets") or [],
21 key=lambda m: ((m.get("lp") or {}).get("baseUSD") or 0)
22 + ((m.get("lp") or {}).get("quoteUSD") or 0),
23 reverse=True)
24 lp = (markets[0].get("lp") or {}) if markets else {}
25 supply = token.get("supply") or 0
26 risks = d.get("risks") or []
27
28 return {
29 "mint": mint,
30 "symbol": (d.get("tokenMeta") or {}).get("symbol"),
31 "rugged": bool(d.get("rugged")),
32 "risk_score": d.get("score_normalised"),
33 "danger": [x.get("name") for x in risks if x.get("level") == "danger"],
34 "warn": [x.get("name") for x in risks if x.get("level") == "warn"],
35 "mint_authority": token.get("mintAuthority", d.get("mintAuthority")),
36 "freeze_authority": token.get("freezeAuthority", d.get("freezeAuthority")),
37 "lp_locked_pct": lp.get("lpLockedPct", d.get("lpLockedPct")),
38 "top10_pct": round(sum(h.get("pct") or 0 for h in holders[:10]), 2) if holders else None,
39 "dev_pct": round((d.get("creatorBalance") or 0) / supply * 100, 2) if supply else None,
40 "insiders": sum(1 for h in holders if h.get("insider")) + (d.get("graphInsidersDetected") or 0),
41 "holders": d.get("totalHolders"),
42 }
43
44def fact_kill(t: dict) -> str | None:
45 """Confronti semplici. Il primo fallimento vince, il motivo viene registrato."""
46 if t["risk_score"] is None: return "no_report"
47 if t["rugged"]: return "already_rugged"
48 if t["mint_authority"]: return "mint_open"
49 if t["freeze_authority"]: return "freeze_open"
50 if t["danger"]: return "danger:" + t["danger"][0]
51 if t["risk_score"] > FACTS["max_risk_score"]: return "risk_score"
52 if t["lp_locked_pct"] is None or t["lp_locked_pct"] < FACTS["min_lp_locked_pct"]:
53 return "lp_unlocked"
54 if t["top10_pct"] is None or t["top10_pct"] > FACTS["max_top10_pct"]:
55 return "top10_heavy"
56 if t["dev_pct"] is None or t["dev_pct"] > FACTS["max_dev_pct"]:
57 return "dev_holds"
58 if t["insiders"] > FACTS["max_insiders"]: return "insiders"
59 return None
boan - inline image

10. controlla il pool, non solo il contratto

controlli da 10 a 13. un contratto può essere perfetto e il pool potrebbe comunque non lasciarti uscire. questo legge il pool più profondo per il token e pone quattro noiose domande: c'è abbastanza dentro, quanto è grande il mio ticket rispetto ad esso, quanti anni ha, e qualcuno sta davvero vendendo.

python
1# market.py
2# il pool in sé: profondità, età, prezzo e se qualcuno può effettivamente vendere.
3import time
4import requests
5from config import FACTS, TICKET_USD
6
7DS = "https://api.dexscreener.com/tokens/v1/solana"
8
9def pool(mint: str) -> dict | None:
10 r = requests.get(f"{DS}/{mint}", timeout=15)
11 r.raise_for_status()
12 data = r.json()
13 pairs = data if isinstance(data, list) else (data.get("pairs") or [])
14 pairs = [p for p in pairs if (p.get("baseToken") or {}).get("address") == mint]
15 if not pairs:
16 return None
17 p = max(pairs, key=lambda x: (x.get("liquidity") or {}).get("usd") or 0)
18 h1 = (p.get("txns") or {}).get("h1") or {}
19 born = p.get("pairCreatedAt")
20 return {
21 "symbol": (p.get("baseToken") or {}).get("symbol"),
22 "price": float(p.get("priceUsd") or 0),
23 "liq_usd": (p.get("liquidity") or {}).get("usd") or 0,
24 "age_min": round((time.time() * 1000 - born) / 60000) if born else None,
25 "buys_1h": h1.get("buys", 0),
26 "sells_1h": h1.get("sells", 0),
27 "vol_1h": (p.get("volume") or {}).get("h1"),
28 "url": p.get("url"),
29 }
30
31def market_kill(m: dict | None) -> str | None:
32 if not m: return "no_pool"
33 if m["price"] <= 0: return "no_price"
34 if m["liq_usd"] < FACTS["min_liquidity_usd"]: return "thin_pool"
35 if TICKET_USD / m["liq_usd"] > FACTS["max_ticket_share"]: return "ticket_too_big"
36 if m["age_min"] is None or m["age_min"] < FACTS["min_age_min"]:
37 return "too_fresh"
38 if m["age_min"] > FACTS["max_age_hours"] * 60: return "too_old"
39 if m["buys_1h"] >= 20 and m["sells_1h"] == 0: return "nobody_can_sell"
40 return None

11. lascia che Grok legga ciò che il codice non può

controllo 14. questo è il motivo per cui la desk gira su Grok e non su un altro modello: può cercare su X mentre pensa. un token può superare tutti e 13 i controlli ed essere comunque un'imitazione con un indirizzo di contratto diverso, oppure un lancio in cui quaranta account creati la settimana scorsa hanno postato la stessa frase nello stesso minuto. nessuna API lo restituisce. X sì.

salva come grok.py. è l'unico file che legge la chiave e l'unico punto in cui la desk parla con xAI:

python
1# grok.py
2# l'unico file che contiene la chiave e l'unico punto in cui il desk comunica con xAI.
3import os, json, datetime, requests
4from config import MODEL
5
6URL = "https://api.x.ai/v1/responses"
7
8def _key() -> str:
9 k = os.environ.get("XAI_API_KEY")
10 if not k and os.path.exists(".env"):
11 for line in open(".env"):
12 if line.startswith("XAI_API_KEY="):
13 k = line.split("=", 1)[1].strip().strip('"')
14 if not k:
15 raise RuntimeError("nessuna XAI_API_KEY nell'ambiente o in .env")
16 return k
17
18def _text(resp: dict) -> str:
19 if isinstance(resp.get("output_text"), str):
20 return resp["output_text"]
21 parts = []
22 for item in resp.get("output") or []:
23 if item.get("type") == "message":
24 for c in item.get("content") or []:
25 if c.get("type") in ("output_text", "text"):
26 parts.append(c.get("text") or "")
27 return "\n".join(parts)
28
29def ask(system: str, payload: dict, read_x: bool = False) -> dict:
30 """Una chiamata, JSON in ingresso, JSON in uscita. Tutto ciò che non è JSON genera un errore, e un errore significa SKIP a monte."""
31 body = {"model": MODEL,
32 "input": [{"role": "system", "content": system},
33 {"role": "user", "content": json.dumps(payload)}]}
34 if read_x:
35 since = (datetime.date.today() - datetime.timedelta(days=3)).isoformat()
36 body["tools"] = [{"type": "x_search", "from_date": since}]
37 body["max_turns"] = 2 # due round di ricerca, poi deve rispondere
38 r = requests.post(URL, timeout=180, json=body,
39 headers={"Authorization": f"Bearer {_key()}"})
40 r.raise_for_status()
41 text = _text(r.json())
42 start, end = text.find("{"), text.rfind("}")
43 if start == -1:
44 raise ValueError(f"nessun json nella risposta: {text[:200]}")
45 return json.loads(text[start:end + 1])

salva come prompts.py. questo è il file che rileggerai davvero:

python
1# prompts.py
2# l'unico prompt di Grok sul desk. questo è il file che rileggerai davvero.
3
4JUDGE_PROMPT = """
5Sei RUG DESK. Una memecoin su Solana ha appena superato tutti i controlli rigidi nel codice:
6autorità, LP, holder, wallet del dev, insider, profondità della pool, età.
7Non ricontrollare quei numeri. Decidi tu se far entrare un singolo ticket piatto.
8Non dimensionerai mai le posizioni, non sceglierai mai le uscite.
9
10INPUT: {"token": {...dati rugcheck...}, "pool": {...dati dexscreener...}}
11
12STEP 1. Cerca su X il ticker e l'indirizzo del contratto, nelle ultime 72 ore.
13STEP 2. Valuta solo ciò che il codice non può vedere:
14 - i rischi di livello warn si sommano per creare qualcosa di peggio?
15 - chi ha postato per primo: il dev, un account reale con uno storico, oppure un'ondata di account nuovi?
16 - organico o comprato: stesse parole, stesso minuto, account senza passato
17 - l'indirizzo del contratto in quei post è lo stesso dell'INPUT?
18 - questo nome ticker o questo dev sono già stati legati a un rug in passato?
19
20RESTITUISCI SOLO JSON:
21{"verdict": "BUY" | "SKIP", "confidence": 0.0-1.0,
22 "why": "massimo due righe", "x_read": "una riga su come appare X",
23 "main_risk": "una riga"}
24
25Zero post su X è già una risposta: nessuno sa che esiste. SKIP.
26Un altro indirizzo di contratto sotto lo stesso ticker su X: rischio copycat. SKIP.
27NON rispondere MAI BUY quando un campo necessario è null.
28NON menzionare MAI target di prezzo. Non li conosci.
29"""

12. collega tutto in un unico comando

un indirizzo di contratto in ingresso, un verdetto in uscita. limiti, dati, pool, Grok, in quest'ordine, e il primo che dice no chiude tutto:

python
1# check.py
2# un indirizzo di contratto in ingresso, un verdetto in uscita. viene eseguito ogni volta che un token passa dal tuo desk.
3import csv, json, os, sys, time
4from config import LOG, MIN_CONFIDENCE, PAPER, TICKET_USD
5from rugcheck import report, fact_kill
6from market import pool, market_kill
7from grok import ask
8from prompts import JUDGE_PROMPT
9import book
10
11def log(row: dict):
12 new = not os.path.exists(LOG)
13 with open(LOG, "a", newline="") as f:
14 w = csv.DictWriter(f, fieldnames=["time", "mint", "symbol", "stage", "verdict",
15 "confidence", "reason"])
16 if new:
17 w.writeheader()
18 w.writerow({k: row.get(k) for k in w.fieldnames})
19
20def check(mint: str) -> dict:
21 if (g := book.guard(mint)): # limiti, gratis
22 return {"stage": "limits", "verdict": "SKIP", "reason": g}
23
24 try:
25 token = report(mint) # filtro rug, gratis
26 except Exception as e:
27 return {"stage": "facts", "verdict": "SKIP", "reason": f"rugcheck fallito: {e}"}
28 if (k := fact_kill(token)):
29 return {"stage": "facts", "verdict": "SKIP", "reason": k, "symbol": token["symbol"]}
30
31 try:
32 m = pool(mint) # pool, gratis
33 except Exception as e:
34 return {"stage": "pool", "verdict": "SKIP", "reason": f"dexscreener fallito: {e}"}
35 if (k := market_kill(m)):
36 return {"stage": "pool", "verdict": "SKIP", "reason": k, "symbol": token["symbol"]}
37
38 try:
39 ans = ask(JUDGE_PROMPT, {"token": token, "pool": m}, read_x=True) # l'unico passaggio a pagamento
40 except Exception as e:
41 return {"stage": "grok", "verdict": "SKIP", "reason": f"grok fallito: {e}"}
42
43 verdict, conf = ans.get("verdict"), ans.get("confidence") or 0
44 if verdict == "BUY" and conf < MIN_CONFIDENCE:
45 verdict = "SKIP"
46 ans["why"] = f"bassa confidenza {conf}"
47 return {**ans, "stage": "grok", "verdict": verdict, "symbol": m["symbol"] or token["symbol"],
48 "reason": ans.get("why"), "price": m["price"], "liq_usd": m["liq_usd"], "url": m["url"]}
49
50if __name__ == "__main__":
51 mint = sys.argv[1].strip()
52 v = check(mint)
53 log({"time": time.strftime("%Y-%m-%d %H:%M"), "mint": mint, **v})
54 if v["verdict"] == "BUY":
55 if PAPER:
56 book.open_position(mint, v["symbol"], v["price"], v["liq_usd"])
57 v["action"] = f"PAPER BUY ${TICKET_USD} a {v['price']}"
58 else:
59 v["action"] = (f"APPROVAZIONE NECESSARIA: compra ${TICKET_USD} di {v['symbol']} nel tuo wallet, "
60 f"poi esegui: python book.py add {mint} {TICKET_USD} <prezzo di esecuzione> {v['liq_usd']}")
61 print(json.dumps(v, indent=2))

non ti serve uno scanner per usarlo. un CA da un canale di call, un post, il messaggio di un amico: dici al bot "check <CA>" e lui esegue una riga. quello che torna indietro assomiglia a questo (struttura d'esempio, non un token reale):

json
1{
2 "verdict": "SKIP",
3 "confidence": 0.78,
4 "why": "supera tutti i controlli rigidi, ma i primi 30 post provengono da account creati questa settimana, con le stesse parole.",
5 "x_read": "un account reale, un'ondata di account nuovi, nessuna discrepanza sul CA",
6 "main_risk": "hype comprato, i buyer se ne vanno quando smettono di postare",
7 "stage": "grok",
8 "symbol": "ESEMPIO",
9 "reason": "supera tutti i controlli rigidi, ma i primi 30 post provengono da account creati questa settimana, con le stesse parole."
10}
boan - inline image
text
1PRIMA I FATTI, POI LE OPINIONI. Grok non decide mai se un mint è aperto.
2UNA CHIAMATA FALLITA È UNO SKIP. Rugcheck giù, DexScreener giù, Grok giù, JSON errato: SKIP.
3NULL NON SIGNIFICA PULITO. un campo che non è tornato elimina il token, non lo fa mai passare.
4UN VERDETTO PER TOKEN. non rieseguire mai finché non dice BUY. se non sei d'accordo, non sei d'accordo con config.py.
5LEGGI GLI SCARTI, NON I BUY. i buy fanno sentire bene. i motivi degli scarti ti dicono se il filtro funziona.

13. tre routine, una frase ciascuna

nessun workflow builder. spieghi al bot ogni routine una sola volta, in una frase, e lui ti mostra l'esecuzione successiva. queste sono le mie, parola per parola:

text
1Ogni 10 minuti, in /workspace/desk esegui python watch.py.
2Se non stampa nulla, non dire nulla. Se stampa qualcosa, postalo qui parola per parola.
text
1Ogni 30 minuti, in /workspace/desk esegui python scan.py.
2Posta solo i verdetti BUY: symbol, confidence, x_read.
3Se Rugcheck o DexScreener sono giù, dillo una volta sola indicando quale, non a ogni esecuzione.
text
1Ogni giorno alle 21:30, in /workspace/desk esegui python report.py e posta qui l'output.
2Aggiungi una cosa che oggi ha funzionato e un numero in config.py che metteresti in discussione, spiegando perché.
3Non modificare mai quel numero da solo.

i due file che quelle routine eseguono. salva come report.py:

python
1# report.py
2# il report serale. tutto ciò che contiene arriva da checks.csv e trades.csv, niente dalla memoria.
3import csv, os, time
4from collections import Counter
5from config import LOG, PAPER
6import book
7
8day = time.strftime("%Y-%m-%d")
9checks = [r for r in csv.DictReader(open(LOG))] if os.path.exists(LOG) else []
10checks = [r for r in checks if r["time"].startswith(day)]
11done = [t for t in book.trades() if t["time"].startswith(day) and t["action"] != "open"]
12
13by_stage = Counter(r["stage"] for r in checks if r["verdict"] == "SKIP")
14buys = [r for r in checks if r["verdict"] == "BUY"]
15wins = [t for t in done if float(t["pnl"]) > 0]
16reasons = Counter(r["reason"] for r in checks if r["stage"] in ("facts", "pool"))
17
18print(f"REPORT SERALE {day} {'(PAPER)' if PAPER else '(LIVE)'}")
19print(f"controllati: {len(checks)}")
20print(f"eliminati dal filtro rug: {by_stage['facts']} | dalla pool: {by_stage['pool']} | "
21 f"da Grok: {by_stage['grok']} | dai limiti: {by_stage['limits']}")
22print(f"comprati: {len(buys)} | aperti ora: {len(book.load())}")
23print(f"pnl realizzato oggi: ${book.today_pnl():+.2f}")
24if done:
25 print(f"uscite in verde: {len(wins)}/{len(done)}")
26 best = max(done, key=lambda t: float(t["pnl"]))
27 worst = min(done, key=lambda t: float(t["pnl"]))
28 print(f"migliore: {best['symbol']} ${float(best['pnl']):+.2f} | peggiore: {worst['symbol']} ${float(worst['pnl']):+.2f}")
29if reasons:
30 top, n = reasons.most_common(1)[0]
31 print(f"scarto più comune: {top} ({n}x)")

e scan.py, la fonte di lead opzionale. recupera i token Solana appena usciti che hanno appena pagato per un profilo DexScreener. un profilo a pagamento non è un segnale di qualità, significa solo che il dev ha speso soldi. il resto lo decide il filtro:

python
1# scan.py
2# fonte di lead opzionale: token Solana appena usciti che hanno appena pagato per un profilo DexScreener.
3# un profilo a pagamento non è un segnale di qualità, significa solo che il dev ha speso soldi. il filtro decide.
4import csv, os, subprocess, sys
5import requests
6from config import LOG
7
8seen = {r["mint"] for r in csv.DictReader(open(LOG))} if os.path.exists(LOG) else set()
9r = requests.get("https://api.dexscreener.com/token-profiles/latest/v1", timeout=15)
10r.raise_for_status()
11fresh = [t["tokenAddress"] for t in r.json()
12 if t.get("chainId") == "solana" and t.get("tokenAddress") not in seen]
13
14for mint in fresh[:5]: # cinque per esecuzione, così un'ora intensa non prosciuga il budget API
15 subprocess.run([sys.executable, "check.py", mint])

ultima cosa per stasera: Settings, General, Auto-review. aggiungi due regole "Ask first" (Chiedi prima): bloccano l'azione e ti aspettano, indipendentemente da ciò che pensa qualsiasi routine:

text
1Chiedi prima di qualsiasi connessione al wallet, firma, swap o trasferimento.
2Chiedi prima di modificare qualsiasi file chiamato config.py.
boan - inline image
boan - inline image

14. una settimana su carta prima di un singolo dollaro

PAPER = True significa che il desk fa tutto sul serio tranne muovere denaro. token reali, prezzi reali, uscite reali, esecuzioni simulate. dopo sette giorni, apri checks.csv e leggilo come se l'avesse scritto un estraneo.

cosa devi cercare: quale controllo elimina di più, se i BUY sarebbero stati quelli che avresti comprato anche tu, e se qualche motivo di SKIP sembra sbagliato. un'esecuzione simulata avviene al prezzo mostrato a schermo, un'esecuzione live non lo fa mai, quindi tratta il risultato paper come il tetto massimo, non come la previsione.

quando passi al live, cambia PAPER a False e non cambia nient'altro tranne l'ultimo passaggio. check.py smette di comprare e pubblica invece una riga di approvazione: compra tu stesso $25 nel tuo wallet, poi un comando li inserisce nel registro così watch.py inizia a proteggerli.

quando si rompe

questo sistema tocca il denaro, quindi ogni guasto ha una risposta già scritta prima ancora che accada.

text
1401 da xAI -> chiave errata. Prendi il controllo, riscrivi .env, esegui di nuovo il curl dello step 03.
2400 / 404 da xAI -> il nome del modello è cambiato. correggi MODEL in config.py, nient'altro.
3429 da xAI -> rate limit. quel token è uno SKIP, l'esecuzione successiva va avanti. non fare mai loop.
4errore su x_search -> il tuo MODEL non può cercare su X. scegline uno che può farlo su console.x.ai -> Models.
5Grok risponde in prosa -> ValueError, loggato, SKIP. non trasformare mai un paragrafo in un trade.
6rugcheck 404 o vuoto -> troppo recente per essere indicizzato. SKIP. recente non significa pulito.
7lp_unlocked su tutto -> alcuni tipi di pool non hanno proprio alcun token LP. aprine uno tu stesso su rugcheck
8 prima di toccare quel numero, e modificalo per iscritto.
9no_pool -> non ancora scambiato su un DEX, o non è Solana. SKIP.
10le routine si sono zittite -> Grok Bot mette in pausa le routine dopo che sei stato via a lungo.
11 apri Routines e riattivale.

il conto

tutto ciò che precede il giudice è gratuito: i limiti, Rugcheck, DexScreener. l'unico passaggio a pagamento è una chiamata a Grok per ogni token sopravvissuto a tutti i 13 controlli, con la ricerca su X attiva.

text
1costo_per_token = input_tokens / 1_000_000 * prezzo_per_M_input
2 + output_tokens / 1_000_000 * prezzo_per_M_output
3 + post_recuperati / 1_000 * 5 # ricerca X: $5 ogni 1.000 post recuperati
4
5max_turns = 2 mantiene la ricerca a due round, così post_recuperati resta basso.
6ogni risposta riporta il proprio x_posts_fetched, quindi il primo giorno ti dà il numero reale.
7
8prezzo: [prezzo da console.x.ai]

la parte in cui le persone sbagliano: il conto scala con i sopravvissuti, non con lo scanner. scan.py può fornire al desk 240 token al giorno e la maggior parte di essi viene eliminata gratuitamente prima che Grok ne sappia qualcosa.

boan - inline image

parte importante

questa è la mia configurazione, non la tua strategia.

ogni numero in config.py è mio, scelto per un ticket da $25 e per la mia personale tolleranza nel guardare qualcosa andare a zero. la maggior parte delle memecoin finisce a zero, e la maggior parte di chi le tradisce perde soldi. il filtro non rende buono un token. rimuove i modi più ovvi per perdere, e ti costringe a leggere perché ogni token è morto.

fai girare una settimana su carta. leggi gli scarti. sposta per iscritto i numeri con cui non sei d'accordo. copia la struttura, non le costanti. non è consulenza finanziaria.

il codice elimina, Grok legge X, tu firmi. uno script non prende mai decisioni discrezionali, Grok non riceve mai una calcolatrice, e nessuno tranne te mette mai mano al wallet.

salva questo prima del tuo prossimo acquisto. seguimi se hai intenzione di far girare la stessa cosa, ne arriveranno altre 🫶

il mio tg - t.me/+8wAXS0nHWgA2MGEy

il mio github - github.com/0xboan

trada qui - fomo.family/r/0xboan

Salva con un clic

Leggi in profondità gli articoli virali con l’AI di YouMind

Salva la fonte, fai domande mirate, riassumi l’argomentazione e trasforma un articolo virale in note riutilizzabili in un unico spazio di lavoro AI.

Scopri YouMind
Per i creator

Trasforma il tuo Markdown in un articolo 𝕏 pulito

Quando pubblichi i tuoi testi lunghi, formattare immagini, tabelle e blocchi di codice per 𝕏 è una seccatura. YouMind trasforma un'intera bozza Markdown in un articolo 𝕏 pulito e pronto da pubblicare.

Prova Markdown verso 𝕏

Altri pattern da decodificare

Articoli virali recenti

Esplora altri articoli virali