YouMind
Entrar

Grok Bot do zero em uma noite: configuração completa + filtro de rug pull pronto para copiar e colar

@0xboan
INGLÊS17 de out. de 2026
126K
139
19
20
439

TL;DR

Este guia detalha a construção de uma mesa de negociação com Grok Bot do zero, focando em um rigoroso filtro de rug pull de 14 etapas para eliminar tokens fraudulentos antes da execução. Enfatiza o fluxo de trabalho 'o código mata, o Grok lê, você assina' com salvaguardas de paper trading.

a maioria das pessoas conhece o Grok Bot pelo print de PnL de outra pessoa, abre, aponta para um gráfico e perde os primeiros US$ 50 num token que já estava morto antes da compra. o problema não era o bot. ninguém disse a ele como é um token morto.

essa é a estrutura que eu montaria de novo hoje à noite se precisasse recomeçar. um bot, uma pasta, dez arquivos pequenos. ele não caça 100x. o trabalho principal dele é matar tokens, e os poucos que sobrevivem ainda precisam do Grok lendo o X antes que um único dólar se mova.

os passos 01 a 07 são a primeira noite: o bot, a chave, os limites, as saídas. de 08 a 12 vem o filtro de rug, 14 checagens, cada uma delas escrita em código. 13 e 14 colocam tudo no piloto automático, primeiro só no papel.

se você leu meu post sobre a mesa com oito agentes, esse é o chão onde aquela mesa está apoiada.

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

como usar isso: abra seu Grok Bot, cole este artigo inteiro e diga "monte essa mesa em /workspace/desk, modo paper, me pergunte antes de qualquer coisa tocar uma carteira." ele escreve cada arquivo sozinho, no próprio computador.

a divisão que você precisa guardar: o código mata, o Grok lê o X, você assina. ninguém na mesa faz o trabalho do outro.

01. consiga quatro coisas antes de começar

quatro coisas. cada uma diz o que é, o que você faz hoje à noite e por que a mesa precisa daquilo.

1. Grok Bot

o que é. o app onde você contrata bots com nome. cada um trabalha num computador na nuvem com navegador, arquivos e terminal, e continua funcionando mesmo com seu notebook fechado.

o que você faz. baixe em x.ai/bot, faça login, escolha Create your own.

por quê. a mesa inteira vive naquele computador. arquivos, rotinas, alertas, tudo num lugar só que você pode abrir pelo celular.

2. uma chave de API da xAI

o que é. acesso pago ao Grok via código, com busca no X embutida.

o que você faz. console.x.ai, API Keys, crie uma. não cole em nenhum lugar ainda, o passo 03 diz onde ela entra.

por quê. uma rotina não consegue sentar e pensar sobre quarenta tokens num chat. um script que faz uma chamada por token consegue, e registra cada resposta no mesmo formato.

3. Rugcheck e DexScreener

o que é. duas APIs públicas gratuitas. o Rugcheck lê o contrato: autoridades, LP, holders, insiders, a carteira do dev. o DexScreener lê a pool: profundidade, idade, compras contra vendas.

o que você faz. nada. sem cadastro, sem chave para leituras.

por quê. fatos vêm antes de opiniões. uma autoridade de mint aberta não é questão de julgamento, é um fato, e fatos matam primeiro.

4. uma carteira descartável (burner), mas não hoje

o que é. uma carteira Solana nova que nunca guardou mais nada.

o que você faz. nada por enquanto. a primeira semana roda no papel.

por quê. a mesa nunca guarda uma chave. quando for pra valer, ela te diz o que comprar e você mesmo assina.

02. contrate um bot, não oito

minha mesa roda oito bots agora. não começou assim, e a sua também não deveria. oito bots no primeiro dia são oito coisas para debugar ao mesmo tempo. um bot com uma única tarefa mostra o que os outros sete vão precisar depois.

escolha Create your own e passe isso para ele, palavra por palavra:

text
1Nome: RUG DESK
2Tarefa: Mesa de memecoins Solana, primeiro no modo paper
3Descrição: Monte e rode a mesa em /workspace/desk a partir do artigo que vou colar.
4Todo token passa pelo check.py, sem exceções, sem atalhos.
5Você nunca compra, vende, assina ou move fundos. Você nunca edita o config.py a menos que eu peça
6neste chat. Você nunca abaixa o número de um filtro para deixar um token passar.
7Reporte cada eliminação com o motivo, não com sua opinião sobre o token.
8Quando uma fonte estiver fora do ar, diga qual e pule. Nunca chute um número ausente.

as duas últimas linhas importam mais que as cinco primeiras. um bot que chuta um número ausente vai acabar chutando um que vai te custar caro.

boan - inline image

03. mantenha a chave fora do chat

tudo o que você digita para um bot vira histórico. então a chave vai para um arquivo, digitada por você, no computador do bot.

abra o computador do bot, clique em Take over, abra o terminal e rode isso. ele pede a chave sem ecoar na tela, então ela nunca aparece no histórico também:

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

depois prove que a chave funciona antes de qualquer outra coisa. uma chamada só, para você nunca confundir uma chave ruim com um prompt ruim mais tarde:

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" ...

clique em I'm done e devolva o computador. daqui em diante o bot pode rodar a mesa, e ele continua sem ver a chave no chat.

boan - inline image

04. veja o funil inteiro antes de construir qualquer parte

oito passagens. as gratuitas rodam primeiro. só o que sobrevive às passagens gratuitas custa uma chamada do Grok, e só o que o Grok classifica como BUY custa dinheiro. esta semana, nem isso.

text
10. LEAD um CA de qualquer lugar: uma call, um post, scan.py -> um mint
21. LIMITES book.py: perda diária, slots abertos, cooldown -> grátis, sem rede nenhuma
32. FATOS rugcheck.py: 10 eliminações definitivas -> mint aberto, LP destravado, top 10 gordo morrem aqui
43. POOL market.py: profundidade, idade, vendas -> pools finas e honeypots morrem aqui
54. JUIZ grok.py + busca no X, uma chamada -> BUY ou SKIP, um motivo, um risco
65. PREENCHER paper: book.py no preço real -> ao vivo: você mesmo assina
76. MONITORAR watch.py a cada 10 minutos -> stop, escadinha, trailing, stop por tempo
87. RELATÓRIO report.py às 21:30 -> o que morreu, o que pagou, o que questionar

uma autoridade de mint aberta não é questão de julgamento. é um fato, e fatos são de graça. o Grok só vê tokens que já passaram por todas as checagens que um script consegue fazer.

boan - inline image

05. coloque todos os números num único arquivo

salve como config.py. todo número da mesa vive aqui, então quando você recalibrar, edita um arquivo só e mais nada. esses são os meus, ajustados para um ticket de US$ 25. não são uma recomendação, são um ponto de partida que você vai mudar.

python
1# config.py
2# todo número da mesa vive aqui. quando você recalibrar, edite este arquivo e mais nada.
3
4MODEL = "grok-4.7" # confira em console.x.ai -> Models se a API rejeitar
5PAPER = True # primeira semana: preenchimentos falsos com preços reais. mude só depois de ler o log
6
7TICKET_USD = 25 # fixo. nunca dimensionado com base na última vitória
8MAX_OPEN = 4 # 4 x US$ 25 = US$ 100 no mercado, no máximo
9MAX_ENTRIES_PER_DAY = 6
10DAILY_LOSS_HALT_USD = 50 # perda realizada hoje bate nisso -> sem novas entradas até amanhã
11COOLDOWN_HOURS = 24 # sem reentrada num token que você acabou de sair
12
13FACTS = { # o filtro de rug. só código, sem modelo
14 "max_risk_score": 40, # score_normalised do rugcheck, 0-100, maior = mais arriscado
15 "min_lp_locked_pct": 90, # maior pool: LP travado ou queimado
16 "max_top10_pct": 30, # top 10 holders, excluindo pools e lockers
17 "max_dev_pct": 5, # supply ainda parado na carteira do criador
18 "max_insiders": 0, # holders marcados como insider + acertos no gráfico de insiders
19 "min_liquidity_usd": 30000,
20 "max_ticket_share": 0.01, # seu ticket nunca é mais que 1% da pool
21 "min_age_min": 30, # mais novo que isso, todo relatório ainda é chute
22 "max_age_hours": 72,
23}
24
25MIN_CONFIDENCE = 0.7 # Grok diz BUY abaixo disso -> tratado como SKIP
26
27EXIT = {
28 "stop_pct": -35, # stop definitivo a partir da entrada
29 "ladder": [(100, 0.50), (200, 0.25)], # +100% vende metade, +200% vende um quarto
30 "trail_pct": 30, # o resto: sai quando o preço cai 30% do topo
31 "time_stop_hours": 6, # não subiu 20% depois de 6 horas -> sai, dinheiro morto
32 "time_stop_min_pct": 20,
33 "liq_drop_pct": 40, # liquidez da pool caiu 40% desde a entrada -> sai agora
34}
35
36LOG = "checks.csv"
37POSITIONS = "positions.json"
38TRADES = "trades.csv"
text
1TICKET FIXO. o tamanho nunca cresce porque as três últimas ganharam.
2O BOT LÊ config.py, NUNCA ESCREVE NELE. um número só muda quando você muda.
3FILTRO SÓ É AFROUXADO POR ESCRITO. você muda um número, explica o porquê no chat, no mesmo dia.

06. rode os limites antes de qualquer outra coisa

salve como book.py. a checagem mais barata da mesa é aquela que nunca chama uma API. se hoje já perdeu US$ 50, a mesa nem olha pro token. se quatro posições estão abertas, mesma coisa. este arquivo também é a memória da mesa: dois arquivos que você mesmo pode abrir, positions.json e trades.csv.

python
1# book.py
2# posições, trades, limites. a memória da mesa vive em dois arquivos que você mesmo pode abrir.
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 """Limites rodam antes de qualquer chamada de rede. Uma entrada bloqueada não custa nada."""
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 uma fração do tamanho ORIGINAL (1.0 = tudo o que sobrou). Retorna o pnl realizado."""
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 # modo ao vivo: depois de comprar na sua própria carteira -> python book.py add <mint> <usd> <preço> <liq_usd>
66 # depois de vender manualmente -> python book.py close <mint> <preço>
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. escreva a saída antes da entrada

a maioria das pessoas decide quando vender enquanto encara um candle verde. esse é o pior momento para decidir qualquer coisa. nesta mesa, toda saída existe antes de o token ser comprado, e o bot só confere a cada 10 minutos:

  • liquidez puxada 40% desde a entrada: sai, tudo, sem perguntas
  • queda de 35%: sai
  • alta de 100%: metade vai embora, o resto é dinheiro do mercado
  • alta de 200%: mais um quarto vai embora
  • depois da primeira realização, o resto sai quando o preço cair 30% do topo
  • seis horas sem +20%: sai, o slot vale mais que a esperança

salve como watch.py:

python
1# watch.py
2# cada posição aberta, a cada 10 minutos. não imprime nada quando nada mudou.
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 de preço fora do ar ({e}), segurando, vou tentar de novo")
15 continue
16 if not m or m["price"] <= 0:
17 events.append(f"{p['symbol']}: pool sumiu. trate como rug, venda o que der")
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 = "vendeu" if PAPER else "VENDA AGORA na sua carteira"
30 size = "o 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
1LIQUIDEZ PRIMEIRO. uma pool puxada vence qualquer outra regra, mesmo numa posição no verde.
2O TRAILING SÓ ARMA DEPOIS DA PRIMEIRA REALIZAÇÃO. antes disso, -35% é o único piso.
3DINHEIRO MORTO TAMBÉM É PREJUÍZO. seis horas paradas liberam o slot para o próximo token.
4SILÊNCIO É UM STATUS. watch.py não imprime nada quando nada mudou, então um chat quieto significa que você não precisa olhar.
boan - inline image

08. aprenda as 14 formas de um token morrer

se eu tivesse que jogar fora tudo acima e ficar com uma coisa só, seria isso. também funciona sem nenhum bot: rode as mesmas 14 checagens na mão no rugcheck.xyz e no dexscreener antes da sua próxima compra e você vai pular a maioria dos tokens dos quais ia se arrepender.

13 das checagens são código. comparações, sem modelo, sem opinião. a 14ª é a única que precisa do Grok.

#

checagem

elimina quando

por quê

1

já sofreu rug

Rugcheck marca como rugged

alguém já fez isso

2

autoridade de mint

ainda aberta

o dev pode imprimir novo supply na sua bolsa

3

autoridade de freeze

ainda aberta

o dev pode congelar seus tokens, você não consegue vender

4

sinais de perigo

qualquer risco de nível danger

o Rugcheck já viu algo que você teria que provar estar errado

5

pontuação de risco

acima de 40/100

pequenos avisos se somam

6

trava de LP

maior pool com menos de 90% travado ou queimado

liquidez destravada é um botão de puxada

7

top 10 holders

mais de 30%, excluindo pools e lockers

dez carteiras podem acabar com sua trade juntas

8

carteira do dev

criador ainda segura mais de 5%

o dev é o primeiro vendedor

9

insiders / bundles

qualquer holder insider ou acerto no gráfico de insiders

carteiras financiadas juntas vendem juntas

10

profundidade da pool

menos de US$ 30k de liquidez

você seria a saída de alguém

11

fatia do ticket

seus US$ 25 são mais de 1% da pool

sua própria compra mexe no preço

12

idade

menos de 30 min ou mais de 72h

novo demais para qualquer relatório, ou o movimento já aconteceu

13

existem vendas

20+ compras na última hora, zero vendas

esse é o formato de um honeypot

14

leitura do X (Grok)

sem posts, CA copiado, comprou hype, histórico de rug

a parte que nenhuma API retorna

boan - inline image

09. deixe o código matar os óbvios

checagens 1 a 9. ele busca um relatório e mantém só os campos que a mesa lê. o Grok nunca vê o relatório bruto, um payload gordo custa tokens e custa precisão.

um detalhe que o pessoal deixa passar: o vault da própria pool e os lockers ficam na lista de maiores holders. conte-os e todo token parece token de baleia. o código descarta eles antes de somar o top 10.

python
1# rugcheck.py
2# um relatório por token, cortado para os campos que a mesa lê. o Grok nunca vê o relatório bruto.
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): # vaults AMM e lockers ficam nos top holders, não são baleias
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 """Comparações simples. A primeira falha vence, o motivo é registrado."""
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. cheque a pool, não só o contrato

checagens 10 a 13. um contrato pode ser perfeito e a pool ainda assim não te deixar sair. isso lê a pool mais profunda do token e faz quatro perguntas chatas: tem o suficiente nela, qual o tamanho do meu ticket perto dela, qual a idade, e alguém está realmente vendendo.

python
1# market.py
2# a pool em si: profundidade, idade, preço e se alguém consegue mesmo vender.
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. deixe o Grok ler o que o código não consegue

checagem 14. esse é o motivo de a mesa rodar no Grok e não em qualquer outro modelo: ele consegue buscar no X enquanto pensa. um token pode passar nas 13 checagens e ainda ser uma cópia com endereço de contrato diferente, ou um lançamento onde quarenta contas criadas na semana passada postaram a mesma frase no mesmo minuto. nenhuma API retorna isso. o X retorna.

salve como grok.py. é o único arquivo que lê a chave e o único lugar onde a mesa fala com a xAI:

python
1# grok.py
2# o único arquivo que guarda a chave e o único lugar onde a mesa fala com a 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("no XAI_API_KEY in the environment or 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 """Uma chamada, JSON entra, JSON sai. Qualquer coisa que não seja JSON gera erro, e um erro é um SKIP lá em cima."""
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 # duas rodadas de busca, depois ele tem que responder
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"no json in answer: {text[:200]}")
45 return json.loads(text[start:end + 1])

salve como prompts.py. este é o arquivo que você vai realmente reler:

python
1# prompts.py
2# o único prompt do Grok na mesa. este é o arquivo que você vai realmente reler.
3
4JUDGE_PROMPT = """
5Você é o RUG DESK. Uma memecoin da Solana acabou de passar por todas as verificações rigorosas no código:
6autoridades, LP, holders, carteira do dev, insiders, profundidade da pool, idade.
7Não verifique esses números de novo. Você decide se um ticket fixo entra.
8Você nunca define tamanho de posição, nunca escolhe saídas.
9
10ENTRADA: {"token": {...fatos do rugcheck...}, "pool": {...fatos do dexscreener...}}
11
12PASSO 1. Pesquise no X pelo ticker e pelo endereço do contrato, nas últimas 72 horas.
13PASSO 2. Julgue apenas o que o código não consegue ver:
14 - os riscos de nível warn se acumulam em algo pior juntos?
15 - quem postou primeiro: o dev, uma conta real com histórico ou uma onda de contas novas?
16 - orgânico ou comprado: mesmo texto, mesmo minuto, contas sem passado
17 - o endereço do contrato nessas postagens é o mesmo da ENTRADA?
18 - esse nome de ticker ou esse dev já esteve ligado a algum rug antes?
19
20RETORNE APENAS JSON:
21{"verdict": "BUY" | "SKIP", "confidence": 0.0-1.0,
22 "why": "máximo duas linhas", "x_read": "uma linha sobre como o X está",
23 "main_risk": "uma linha"}
24
25Zero posts no X é uma resposta: ninguém sabe que existe. SKIP.
26Outro endereço de contrato com o mesmo ticker no X: risco de cópia. SKIP.
27NUNCA responda BUY quando um campo necessário for null.
28NUNCA mencione alvos de preço. Você não os conhece.
29"""

12. conecte tudo em um único comando

um endereço de contrato entra, um veredito sai. limites, fatos, pool, Grok, nessa ordem, e o primeiro que disser não encerra o processo:

python
1# check.py
2# um endereço de contrato entra, um veredito sai. roda toda vez que um token passa pela sua mesa.
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)): # limites, grátis
22 return {"stage": "limits", "verdict": "SKIP", "reason": g}
23
24 try:
25 token = report(mint) # filtro de rug, grátis
26 except Exception as e:
27 return {"stage": "facts", "verdict": "SKIP", "reason": f"rugcheck failed: {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, grátis
33 except Exception as e:
34 return {"stage": "pool", "verdict": "SKIP", "reason": f"dexscreener failed: {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) # o único passo pago
40 except Exception as e:
41 return {"stage": "grok", "verdict": "SKIP", "reason": f"grok failed: {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"low confidence {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} at {v['price']}"
58 else:
59 v["action"] = (f"APPROVAL NEEDED: buy ${TICKET_USD} of {v['symbol']} in your own wallet, "
60 f"then run: python book.py add {mint} {TICKET_USD} <fill price> {v['liq_usd']}")
61 print(json.dumps(v, indent=2))

você não precisa de um scanner para usar isso. um CA vindo de um canal de calls, um post, a mensagem de um amigo: diga ao bot "check <CA>" e ele roda uma linha. o que volta se parece com isso (formato de exemplo, não é um token real):

json
1{
2 "verdict": "SKIP",
3 "confidence": 0.78,
4 "why": "passa em todas as verificações rigorosas, mas os primeiros 30 posts vieram de contas criadas esta semana, com o mesmo texto.",
5 "x_read": "uma conta real, uma onda de contas novas, nenhuma divergência de CA",
6 "main_risk": "hype comprado, os compradores somem quando as postagens param",
7 "stage": "grok",
8 "symbol": "EXAMPLE",
9 "reason": "passa em todas as verificações rigorosas, mas os primeiros 30 posts vieram de contas criadas esta semana, com o mesmo texto."
10}
boan - inline image
text
1FATOS ANTES DE OPINIÕES. O Grok nunca decide se um mint está aberto.
2UMA CHAMADA COM FALHA É UM SKIP. Rugcheck fora do ar, DexScreener fora do ar, Grok fora do ar, JSON ruim: SKIP.
3NULL NÃO É LIMPO. Um campo que não voltou elimina o token, nunca aprova.
4UM VEREDITO POR TOKEN. Nunca rode de novo até que diga BUY. Se você discordar, está discordando do config.py.
5LEIA OS KILLS, NÃO OS BUYS. Os buys dão uma sensação boa. Os motivos dos kills mostram se o filtro funciona.

13. três rotinas, uma frase cada

sem construtor de workflow. você diz cada rotina ao bot uma vez, em uma frase, e ele mostra a próxima execução. estas são as minhas, palavra por palavra:

text
1A cada 10 minutos, em /workspace/desk rode python watch.py.
2Se não imprimir nada, não diga nada. Se imprimir qualquer coisa, poste aqui palavra por palavra.
text
1A cada 30 minutos, em /workspace/desk rode python scan.py.
2Poste apenas vereditos BUY: symbol, confidence, x_read.
3Se o Rugcheck ou o DexScreener estiverem fora do ar, diga qual deles uma vez, não em cada execução.
text
1Todos os dias às 21:30, em /workspace/desk rode python report.py e poste a saída aqui.
2Adicione uma coisa que funcionou hoje e um número no config.py que você questionaria, com o motivo.
3Nunca altere esse número por conta própria.

os dois arquivos que essas rotinas executam. salve como report.py:

python
1# report.py
2# o relatório da noite. tudo nele vem de checks.csv e trades.csv, nada da memória.
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"EVENING REPORT {day} {'(PAPER)' if PAPER else '(LIVE)'}")
19print(f"checked: {len(checks)}")
20print(f"killed by rug filter: {by_stage['facts']} | by pool: {by_stage['pool']} | "
21 f"by Grok: {by_stage['grok']} | by limits: {by_stage['limits']}")
22print(f"bought: {len(buys)} | open now: {len(book.load())}")
23print(f"realized pnl today: ${book.today_pnl():+.2f}")
24if done:
25 print(f"green exits: {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"best: {best['symbol']} ${float(best['pnl']):+.2f} | worst: {worst['symbol']} ${float(worst['pnl']):+.2f}")
29if reasons:
30 top, n = reasons.most_common(1)[0]
31 print(f"most common kill: {top} ({n}x)")

e scan.py, a fonte opcional de leads. ele puxa tokens novos da Solana que acabaram de pagar por um perfil no DexScreener. um perfil pago não é sinal de qualidade, só significa que o dev gastou dinheiro. o filtro decide o resto:

python
1# scan.py
2# fonte opcional de leads: tokens novos da Solana que acabaram de pagar por um perfil no DexScreener.
3# um perfil pago não é sinal de qualidade, só significa que o dev gastou dinheiro. o 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]: # cinco por execução, para que uma hora movimentada não esgote o orçamento da API
15 subprocess.run([sys.executable, "check.py", mint])

última coisa de hoje: Settings, General, Auto-review. adicione duas regras "Ask first" (perguntar antes); elas interrompem a ação e esperam por você, não importa o que qualquer rotina ache:

text
1Pergunte antes de qualquer conexão de carteira, assinatura, swap ou transferência.
2Pergunte antes de editar qualquer arquivo chamado config.py.
boan - inline image
boan - inline image

14. uma semana no papel antes de um único dólar

PAPER = True significa que a mesa faz tudo de verdade, exceto mexer no dinheiro. tokens reais, preços reais, saídas reais, preenchimentos falsos. depois de sete dias, abra o checks.csv e leia como se tivesse sido escrito por um estranho.

o que você está procurando: qual verificação mais elimina, se os BUYs seriam aqueles que você compraria, e se algum motivo de SKIP parece errado. um preenchimento no papel acontece no preço da tela, um preenchimento real nunca acontece assim, então trate o resultado no papel como teto, não como previsão.

quando for para o modo real, mude PAPER para False e nada mais muda, exceto o último passo. o check.py para de comprar e posta uma linha de aprovação: compre $25 você mesmo na sua própria carteira, depois um comando coloca isso no livro para que o watch.py comece a proteger.

quando quebrar

isso envolve dinheiro, então cada falha tem uma resposta anotada antes de acontecer.

text
1401 da xAI -> chave ruim. Assuma o controle, reescreva o .env, rode o curl do passo 03 de novo.
2400 / 404 da xAI -> o nome do modelo mudou. corrija o MODEL no config.py, nada mais.
3429 da xAI -> limite de taxa. esse token é um SKIP, a próxima execução segue em frente. nunca faça loop nisso.
4erro sobre x_search -> seu MODEL não pode pesquisar no X. escolha um que possa em console.x.ai -> Models.
5Grok responde em prosa -> ValueError, registrado, SKIP. nunca transforme um parágrafo em uma operação.
6rugcheck 404 ou vazio -> novo demais para indexar. SKIP. novo não é limpo.
7lp_unlocked em tudo -> alguns tipos de pool não têm token de LP nenhum. Abra uma no rugcheck você mesmo
8 antes de mexer nesse número, e altere por escrito.
9no_pool -> ainda não negociado em uma DEX, ou não é Solana. SKIP.
10rotinas ficaram quietas -> o Grok Bot pausa as rotinas depois que você fica muito tempo ausente.
11 abra Routines e ligue-as de novo.

a conta

tudo antes do juiz é grátis: os limites, o Rugcheck, o DexScreener. o único passo pago é uma chamada do Grok por token que sobreviveu a todas as 13 verificações, com a pesquisa no X ativada.

text
1custo_por_token = tokens_de_entrada / 1_000_000 * preco_por_M_entrada
2 + tokens_de_saida / 1_000_000 * preco_por_M_saida
3 + posts_busca / 1_000 * 5 # Busca no X: $5 por 1.000 posts buscados
4
5max_turns = 2 mantém a pesquisa em duas rodadas, então posts_busca continua pequeno.
6cada resposta informa seu próprio x_posts_fetched, então o dia um já te dá o número real.
7
8preço: [preço de console.x.ai]

a parte que as pessoas entendem errado: a conta escala com os sobreviventes, não com o scanner. o scan.py pode alimentar a mesa com 240 tokens por dia e a maioria deles morre de graça antes que o Grok sequer ouça falar neles.

boan - inline image

parte importante

esta é a minha configuração, não a sua estratégia.

cada número no config.py é meu, escolhido para um ticket de $25 e para a minha própria tolerância a ver algo ir a zero. a maioria das memecoins vai a zero, e a maioria das pessoas que as opera perde dinheiro. o filtro não torna um token bom. ele remove as formas óbvias de perder e te obriga a ler por que cada token morreu.

rode uma semana no papel. leia os kills. mude os números onde você discordar, por escrito. copie a estrutura, não as constantes. não é conselho financeiro.

o código elimina, o Grok lê o X, você assina. um script nunca toma uma decisão de julgamento, o Grok nunca ganha uma calculadora, e ninguém além de você chega à carteira.

salve isso antes da sua próxima compra. siga se você planeja rodar a mesma coisa, vem mais disso por aí 🫶

meu tg - t.me/+8wAXS0nHWgA2MGEy

meu github - github.com/0xboan

opere aqui - fomo.family/r/0xboan

Salvar com um clique

Faça leitura profunda de artigos virais com IA no YouMind

Salve a fonte, faça perguntas específicas, resuma o argumento e transforme um artigo viral em notas reutilizáveis em um único espaço de trabalho com IA.

Explorar o YouMind
Para criadores

Transforme seu Markdown em um artigo 𝕏 impecável

Quando você publica seus próprios textos longos, formatar imagens, tabelas e blocos de código para o 𝕏 é uma dor de cabeça. O YouMind transforma um rascunho completo em Markdown em um artigo 𝕏 impecável e pronto para publicar.

Experimente Markdown para 𝕏

Mais padrões para decifrar

Artigos virais recentes

Explorar mais artigos virais