die meisten leute lernen Grok Bot über den pnl-screenshot von jemand anderem kennen, öffnen ihn, richten ihn auf einen chart und verlieren die ersten 50 $ an einen token, der schon tot war, bevor sie ihn gekauft haben. der bot war nicht das problem. niemand hat ihm gesagt, wie „tot" aussieht.
das ist das setup, das ich heute abend wieder bauen würde, wenn ich von null anfangen müsste. ein bot, ein ordner, zehn kleine dateien. es jagt keinen 100x. seine hauptaufgabe ist es, tokens zu killen, und die wenigen, die überleben, brauchen immer noch Grok, um X zu lesen, bevor auch nur ein einziger dollar fließt.
die schritte 01 bis 07 sind der erste abend: der bot, der key, die limits, die exits. 08 bis 12 sind der rug-filter, 14 checks, jeder einzelne davon als code niedergeschrieben. 13 und 14 schalten alles auf autopilot – erst mal nur auf dem papier.
wenn du meinen beitrag zum eight-agent desk gelesen hast: das hier ist das fundament, auf dem dieser desk steht.
https://x.com/0xboan/status/2092226208234647626
so nutzt du das: öffne deinen Grok Bot, füge diesen ganzen artikel ein und sag „baue diesen desk in /workspace/desk, paper mode, frag mich, bevor irgendetwas eine wallet berührt." er schreibt jede datei selbst, auf seinem eigenen computer.
die aufteilung, an die du dich halten musst: code killt, Grok liest X, du signierst. niemand am desk macht den job eines anderen.
01. besorge vier dinge, bevor du startest
vier dinge. bei jedem steht, was es ist, was du heute abend damit machst und warum der desk es braucht.
1. Grok Bot
was es ist. die app, in der du namentlich genannte bots anheuerst. jeder arbeitet auf einem cloud-computer mit browser, dateien und terminal – und arbeitet weiter, auch wenn dein laptop zu ist.
was du tust. lade ihn unter x.ai/bot herunter, logge dich ein, wähle Create your own.
warum. der gesamte desk lebt auf diesem computer. dateien, routinen, alerts – alles an einem ort, den du vom handy aus öffnen kannst.
2. ein xAI API key
was es ist. kostenpflichtiger zugriff auf Grok aus dem code heraus, mit eingebauter X-suche.
was du tust. console.x.ai, API Keys, erstelle einen. füge ihn noch nirgends ein, in schritt 03 steht, wo er hingehört.
warum. eine routine kann sich nicht in einen chat setzen und über vierzig tokens nachdenken. ein skript, das einen call pro token macht, kann das – und es loggt jede antwort im selben format.
3. Rugcheck und DexScreener
was es ist. zwei kostenlose öffentliche APIs. Rugcheck liest den contract: authorities, LP, holder, insider, die dev-wallet. DexScreener liest den pool: tiefe, alter, käufe gegen verkäufe.
was du tust. nichts. kein signup, kein key für lesezugriffe.
warum. fakten kommen vor meinungen. eine offene mint authority ist keine interpretationsfrage, sondern ein fakt – und fakten killen zuerst.
4. eine burner wallet, aber nicht heute abend
was es ist. eine frische Solana-wallet, in der nie etwas anderes lag.
was du tust. vorerst nichts. woche eins läuft auf papier.
warum. der desk hält niemals einen key. wenn du live gehst, sagt er dir, was du kaufen sollst, und du signierst es selbst.
02. heuere einen bot an, nicht acht
mein desk läuft mittlerweile mit acht bots. so hat es nicht angefangen, und deins sollte es auch nicht. acht bots an tag eins bedeuten acht dinge, die du gleichzeitig debuggen musst. ein bot mit einer einzigen aufgabe zeigt dir, was die anderen sieben später brauchen werden.
wähle Create your own und gib ihm das hier, wort für wort:
1Name: RUG DESK2Job: Solana-Memecoin-Desk, zuerst im Paper-Modus3Description: Baue und betreibe den Desk in /workspace/desk anhand des Artikels, den ich einfüge.4Jeder Token läuft durch check.py, keine Ausnahmen, keine Abkürzungen.5Du kaufst, verkaufst, signierst oder bewegst niemals Gelder. Du bearbeitest config.py nie, außer ich bitte6in diesem Chat darum. Du senkst niemals einen Filterwert, um einen Token durchzulassen.7Melde jeden Kill mit Begründung, nicht mit deiner Meinung zum Token.8Wenn eine Quelle offline ist, sag welche und überspringe sie. Rate niemals einen fehlenden Wert.
die letzten beiden zeilen sind wichtiger als die ersten fünf. ein bot, der fehlende werte rät, wird irgendwann einen raten, der dich geld kostet.

03. halte den key aus dem chat raus
alles, was du einem bot schreibst, landet in einem protokoll. also kommt der key in eine datei, von dir getippt, auf dem computer des bots.
öffne den computer des bots, klicke auf Take over, öffne das terminal und führe das hier aus. es fragt nach dem key, ohne ihn anzuzeigen, sodass er auch nie im verlauf auftaucht:
1mkdir -p /workspace/desk && cd /workspace/desk2read -rs -p "xai key: " K && printf 'XAI_API_KEY=%s\n' "$K" > .env && unset K3chmod 600 .env4pip install requests
beweise dann, dass der key funktioniert, bevor du irgendetwas anderes tust. ein call, damit du später nie einen kaputten key mit einem schlechten prompt verwechselst:
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"}'56-> ... "type":"output_text","text":"OK" ...
klicke auf I'm done und gib den computer zurück. ab jetzt kann der bot den desk betreiben, und er sieht den key trotzdem nie im chat.

04. sieh den gesamten funnel, bevor du irgendetwas davon baust
acht durchläufe. die kostenlosen laufen zuerst. nur was die gratis-checks überlebt, kostet einen Grok-call, und nur was Grok mit BUY bewertet, kostet geld. diese woche nicht einmal das.
10. LEAD eine CA von irgendwoher: ein Call, ein Post, scan.py -> ein Mint21. LIMITS book.py: Tagesverlust, offene Slots, Cooldown -> kostenlos, ganz ohne Netzwerk32. FACTS rugcheck.py: 10 harte Kills -> offener Mint, ungesperrte LP, fette Top 10 sterben hier43. POOL market.py: Tiefe, Alter, Verkäufe -> dünne Pools und Honeypots sterben hier54. JUDGE grok.py + X-Suche, ein Call -> BUY oder SKIP, ein Grund, ein Risiko65. FILL Papier: book.py zum Live-Preis -> Live: du signierst es selbst76. WATCH watch.py alle 10 Minuten -> Stop, Ladder, Trail, Time-Stop87. REPORT report.py um 21:30 -> was gestorben ist, was gezahlt hat, was man hinterfragen muss
eine offene mint authority ist keine interpretationsfrage. sie ist ein fakt, und fakten sind kostenlos. Grok sieht immer nur tokens, die bereits jeden check bestanden haben, den ein skript machen kann.

05. pack jede zahl in eine einzige datei
speichere als config.py. jede zahl am desk lebt hier. wenn du also nachjustierst, bearbeitest du eine datei und sonst nichts. das sind meine, abgestimmt auf ein 25-$-ticket. sie sind keine empfehlung, sondern ein startpunkt, den du verschieben wirst.
1# config.py2# jede zahl am desk lebt hier. wenn du nachjustierst, bearbeitest du diese datei und sonst nichts.34MODEL = "grok-4.7" # prüfe console.x.ai -> Models, falls die API ihn ablehnt5PAPER = True # woche eins: fake-fills zu echten preisen. erst umschalten, wenn du das log gelesen hast67TICKET_USD = 25 # fix. nie basierend auf dem letzten gewinn berechnet8MAX_OPEN = 4 # 4 x 25 $ = maximal 100 $ im markt9MAX_ENTRIES_PER_DAY = 610DAILY_LOSS_HALT_USD = 50 # realisierter verlust heute erreicht das -> keine neuen entries bis morgen11COOLDOWN_HOURS = 24 # kein re-entry in einen token, den du gerade verlassen hast1213FACTS = { # der rug-filter. nur code, kein modell14 "max_risk_score": 40, # rugcheck score_normalised, 0-100, höher = riskanter15 "min_lp_locked_pct": 90, # größter pool: LP gesperrt oder verbrannt16 "max_top10_pct": 30, # top-10-holder, pools und locker ausgeschlossen17 "max_dev_pct": 5, # supply, der noch in der creator-wallet liegt18 "max_insiders": 0, # als insider markierte holder + insider-graph-treffer19 "min_liquidity_usd": 30000,20 "max_ticket_share": 0.01, # dein ticket ist nie mehr als 1 % des pools21 "min_age_min": 30, # jünger als das, da rät jeder report noch22 "max_age_hours": 72,23}2425MIN_CONFIDENCE = 0.7 # wenn Grok darunter BUY sagt -> wird als SKIP behandelt2627EXIT = {28 "stop_pct": -35, # hard stop ab entry29 "ladder": [(100, 0.50), (200, 0.25)], # +100 % verkauft die hälfte, +200 % ein viertel30 "trail_pct": 30, # der rest: raus, wenn der preis 30 % vom peak fällt31 "time_stop_hours": 6, # nach 6 stunden nicht +20 % -> raus, totes kapital32 "time_stop_min_pct": 20,33 "liq_drop_pct": 40, # pool-liquidität 40 % unter entry -> sofort raus34}3536LOG = "checks.csv"37POSITIONS = "positions.json"38TRADES = "trades.csv"
1FIXES TICKET. die größe wächst nie, nur weil die letzten drei gewonnen haben.2DER BOT LIEST config.py, ER SCHREIBT ES NIE. eine zahl ändert sich nur, wenn du sie änderst.3EIN FILTER WIRD SCHRIFTLICH GELOCKERT. du änderst eine zahl, du sagst am selben tag im chat warum.
06. lass die limits vor allem anderen laufen
speichere als book.py. der günstigste check am desk ist der, der nie eine API aufruft. wenn heute schon 50 $ verloren gingen, schaut der desk den token gar nicht erst an. wenn vier positionen offen sind, dasselbe. diese datei ist auch das gedächtnis des desks: zwei dateien, die du selbst öffnen kannst, positions.json und trades.csv.
1# book.py2# positionen, trades, limits. das gedächtnis des desks lebt in zwei dateien, die du selbst öffnen kannst.3import csv, json, os, sys, time4from config import (POSITIONS, TRADES, TICKET_USD, MAX_OPEN, MAX_ENTRIES_PER_DAY,5 DAILY_LOSS_HALT_USD, COOLDOWN_HOURS)67def load() -> dict:8 return json.load(open(POSITIONS)) if os.path.exists(POSITIONS) else {}910def save(book: dict):11 json.dump(book, open(POSITIONS, "w"), indent=2)1213def trades() -> list[dict]:14 return list(csv.DictReader(open(TRADES))) if os.path.exists(TRADES) else []1516def 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})2425def 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))2829def guard(mint: str) -> str | None:30 """Limits laufen vor jedem netzwerkaufruf. Ein blockierter entry kostet nichts."""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 None4243def 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")4950def sell(mint, frac_of_original, price, reason) -> float:51 """Verkauft einen anteil der URSPRÜNGLICHEN größe (1.0 = alles was übrig ist). Gibt realisierten pnl zurück."""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"] -= q57 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 pnl6364if __name__ == "__main__":65 # live-modus: nachdem du in deiner eigenen wallet gekauft hast -> python book.py add <mint> <usd> <price> <liq_usd>66 # nachdem du manuell verkauft hast -> 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. schreib den exit vor dem entry
die meisten leute entscheiden, wann sie verkaufen, während sie auf eine grüne kerze starren. das ist der schlechteste moment, um überhaupt etwas zu entscheiden. an diesem desk existiert jeder exit, bevor der token gekauft wird, und der bot prüft ihn einfach alle 10 minuten:
- liquidität um 40 % vom entry abgezogen: raus, alles, keine fragen
- minus 35 %: raus
- plus 100 %: die hälfte geht, der rest ist geld des marktes
- plus 200 %: ein weiteres viertel geht
- nach dem ersten take-profit geht der rest, wenn der preis 30 % vom peak fällt
- sechs stunden ohne +20 %: raus, der slot ist mehr wert als die hoffnung
speichere als watch.py:
1# watch.py2# jede offene position, alle 10 minuten. gibt nichts aus, wenn sich nichts geändert hat.3import time4from config import EXIT, PAPER5from market import pool6import book78def 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']}: Preisfeed down ({e}), halte, versuche es erneut")15 continue16 if not m or m["price"] <= 0:17 events.append(f"{p['symbol']}: Pool weg. Als Rugged behandeln, verkaufe was geht")18 book.sell(mint, 1.0, 0.0, "pool_gone")19 continue2021 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) * 10025 hours = (time.time() - s["opened"]) / 36002627 def out(frac, why):28 pnl = book.sell(mint, frac, price, why)29 verb = "verkauft" if PAPER else "JETZT VERKAUFEN in deiner Wallet"30 size = "der Rest" if frac >= 1 else f"{int(frac * 100)}%"31 events.append(f"{s['symbol']}: {verb} {size} bei {pct:+.0f}% ({why}), PnL ${pnl:+.2f}")3233 if m["liq_usd"] < s["liq0"] * (1 - EXIT["liq_drop_pct"] / 100):34 out(1.0, "liquidity_pulled"); continue35 if pct <= EXIT["stop_pct"]:36 out(1.0, "stop"); continue37 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 continue44 if s["steps"] > 0 and price <= s["peak"] * (1 - EXIT["trail_pct"] / 100):45 out(1.0, "trailing_stop"); continue46 if hours >= EXIT["time_stop_hours"] and pct < EXIT["time_stop_min_pct"]:47 out(1.0, "time_stop")48 return events4950if __name__ == "__main__":51 for e in watch():52 print(e)
1LIQUIDITÄT ZUERST. ein abgezogener pool schlägt jede andere regel, sogar bei einer position im plus.2DER TRAIL WIRD NACH DEM ERSTEN TAKE SCHARF GESCHALTET. vorher ist -35 % der einzige boden.3TOTES KAPITAL IST AUCH EIN VERLUST. sechs flache stunden machen den slot für den nächsten token frei.4STILLE IST EIN STATUS. watch.py gibt nichts aus, wenn sich nichts geändert hat – ein ruhiger chat heißt also, dass du nicht hinsehen musst.

08. lerne die 14 arten, wie ein token stirbt
wenn ich alles obige wegwerfen und nur eine sache behalten müsste, wäre es das hier. es funktioniert auch ganz ohne bot: mach dieselben 14 checks vor deinem nächsten kauf manuell auf rugcheck.xyz und dexscreener, und du wirst die meisten tokens überspringen, die du sonst bereut hättest.
13 der checks sind code. vergleiche, kein modell, keine meinung. der 14. ist der einzige, der Grok braucht.
#
Check
killt, wenn
warum
1
bereits rugged
Rugcheck markiert ihn als rugged
jemand anderes war schon schneller
2
mint authority
noch offen
der dev kann neuen supply in deine bag drucken
3
freeze authority
noch offen
der dev kann deine tokens einfrieren, du kannst nicht verkaufen
4
danger flags
irgendein risiko auf danger-level
Rugcheck hat schon etwas gesehen, das du erst widerlegen müsstest
5
risk score
über 40/100
kleine warnungen summieren sich
6
LP lock
größter pool zu unter 90 % gesperrt oder verbrannt
ungesperrte liquidität ist ein pull-button
7
top 10 holder
über 30 %, pools und locker ausgeschlossen
zehn wallets können deinen trade gemeinsam beenden
8
dev wallet
creator hält noch über 5 %
der dev ist der erste verkäufer
9
insider / bundles
irgendein insider-holder oder insider-graph-treffer
wallets, die zusammen finanziert wurden, verkaufen zusammen
10
pool-tiefe
unter 30k $ liquidität
du wärst der exit von jemand anderem
11
ticket-anteil
deine 25 $ sind über 1 % des pools
dein eigener kauf bewegt den preis
12
alter
unter 30 min oder über 72 h
zu frisch für jeden report, oder der move ist schon passiert
13
verkäufe fehlen
20+ käufe in der letzten stunde, null verkäufe
das ist die form eines honeypots
14
X-read (Grok)
keine posts, copycat-CA, gekaufter hype, rug-historie
der teil, den keine API liefert

09. lass den code die offensichtlichen killen
checks 1 bis 9. es holt einen report und behält nur die felder, die der desk liest. Grok sieht nie den rohen report – ein fettes payload kostet tokens und kostet genauigkeit.
ein detail, das viele übersehen: der vault des pools selbst und die locker stehen in der liste der top-holder. zähl sie mit, und jeder token sieht aus wie ein whale-token. der code wirft sie raus, bevor er die top 10 zusammenrechnet.
1# rugcheck.py2# ein report pro token, gekürzt auf die felder, die der desk liest. Grok sieht nie den rohen report.3import requests4from config import FACTS56RC = "https://api.rugcheck.xyz/v1/tokens"78def 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 {}1415 def is_pool(h): # AMM-vaults und locker stehen bei den top-holdern, sie sind keine whales16 tag = known.get(h.get("owner")) or known.get(h.get("address")) or {}17 return str(tag.get("type", "")).upper() in ("AMM", "LOCKER")1819 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 026 risks = d.get("risks") or []2728 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 }4344def fact_kill(t: dict) -> str | None:45 """Einfache vergleiche. Der erste fehler gewinnt, der grund wird geloggt."""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

10. prüf den pool, nicht nur den contract
checks 10 bis 13. ein contract kann perfekt sein und der pool lässt dich trotzdem nicht raus. das hier liest den tiefsten pool für den token und stellt vier langweilige fragen: ist genug drin, wie groß ist mein ticket im vergleich dazu, wie alt ist er, und verkauft überhaupt jemand?
1# market.py2# der pool selbst: tiefe, alter, preis und ob überhaupt jemand verkaufen kann.3import time4import requests5from config import FACTS, TICKET_USD67DS = "https://api.dexscreener.com/tokens/v1/solana"89def 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 None17 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 }3031def 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. lass Grok lesen, was code nicht kann
check 14. das ist der grund, warum der desk auf Grok läuft und nicht auf einem anderen modell: er kann X durchsuchen, während er nachdenkt. ein token kann alle 13 checks bestehen und trotzdem ein copycat mit einer anderen contract-adresse sein – oder ein launch, bei dem vierzig letzte woche erstellte accounts im selben moment denselben satz gepostet haben. keine API liefert das. X schon.
speichere als grok.py. es ist die einzige datei, die den key liest, und der einzige ort, an dem der desk mit xAI spricht:
1# grok.py2# die einzige Datei, die den Schlüssel enthält, und der einzige Ort, an dem der Desk mit xAI spricht.3import os, json, datetime, requests4from config import MODEL56URL = "https://api.x.ai/v1/responses"78def _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("kein XAI_API_KEY in der Umgebung oder in .env")16 return k1718def _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)2829def ask(system: str, payload: dict, read_x: bool = False) -> dict:30 """Ein Aufruf, JSON rein, JSON raus. Alles, was kein JSON ist, löst einen Fehler aus, und ein Fehler bedeutet upstream SKIP."""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 # zwei Suchrunden, dann muss geantwortet werden38 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"kein JSON in der Antwort: {text[:200]}")45 return json.loads(text[start:end + 1])
Speichere das als prompts.py. Das ist die Datei, die du tatsächlich noch einmal lesen wirst:
1# prompts.py2# der eine Grok-Prompt auf dem Desk. Das ist die Datei, die du tatsächlich noch einmal lesen wirst.34JUDGE_PROMPT = """5Du bist RUG DESK. Ein Solana-Memecoin hat gerade jeden harten Check im Code bestanden:6Authorities, LP, Holder, Dev-Wallet, Insider, Pool-Tiefe, Alter.7Prüfe diese Zahlen nicht noch einmal. Du entscheidest, ob ein Flat-Ticket reingeht.8Du bestimmst nie die Positionsgröße, du wählst nie die Exits.910INPUT: {"token": {...rugcheck-Fakten...}, "pool": {...dexscreener-Fakten...}}1112SCHRITT 1. Suche auf X nach dem Ticker und der Contract-Adresse, letzte 72 Stunden.13SCHRITT 2. Beurteile nur das, was der Code nicht sehen kann:14 - summieren sich die Warn-Risiken zu etwas Schlimmerem15 - wer hat zuerst gepostet: der Dev, ein echtes Konto mit Historie oder eine Welle frischer Konten16 - organisch oder gekauft: gleicher Wortlaut, gleiche Minute, Konten ohne Vergangenheit17 - ist die Contract-Adresse in diesen Posts dieselbe wie im INPUT18 - wurde dieser Ticker-Name oder dieser Dev schon einmal mit einem Rug in Verbindung gebracht1920GIB NUR JSON ZURÜCK:21{"verdict": "BUY" | "SKIP", "confidence": 0.0-1.0,22 "why": "maximal zwei Zeilen", "x_read": "eine Zeile dazu, wie X aussieht",23 "main_risk": "eine Zeile"}2425Null Posts auf X ist eine Antwort: niemand weiß, dass er existiert. SKIP.26Eine andere Contract-Adresse unter demselben Ticker auf X: Copycat-Risiko. SKIP.27Antworte NIEMALS mit BUY, wenn ein Feld, das du brauchst, null ist.28Erwähne NIEMALS Kursziele. Du kennst sie nicht.29"""
12. alles in einem Befehl verdrahten
Eine Contract-Adresse rein, ein Urteil raus. Limits, Fakten, Pool, Grok – in dieser Reihenfolge, und das erste Nein beendet alles:
1# check.py2# eine Contract-Adresse rein, ein Urteil raus. läuft jedes Mal, wenn ein Token deinen Desk kreuzt.3import csv, json, os, sys, time4from config import LOG, MIN_CONFIDENCE, PAPER, TICKET_USD5from rugcheck import report, fact_kill6from market import pool, market_kill7from grok import ask8from prompts import JUDGE_PROMPT9import book1011def 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})1920def check(mint: str) -> dict:21 if (g := book.guard(mint)): # Limits, kostenlos22 return {"stage": "limits", "verdict": "SKIP", "reason": g}2324 try:25 token = report(mint) # Rug-Filter, kostenlos26 except Exception as e:27 return {"stage": "facts", "verdict": "SKIP", "reason": f"rugcheck fehlgeschlagen: {e}"}28 if (k := fact_kill(token)):29 return {"stage": "facts", "verdict": "SKIP", "reason": k, "symbol": token["symbol"]}3031 try:32 m = pool(mint) # Pool, kostenlos33 except Exception as e:34 return {"stage": "pool", "verdict": "SKIP", "reason": f"dexscreener fehlgeschlagen: {e}"}35 if (k := market_kill(m)):36 return {"stage": "pool", "verdict": "SKIP", "reason": k, "symbol": token["symbol"]}3738 try:39 ans = ask(JUDGE_PROMPT, {"token": token, "pool": m}, read_x=True) # der einzige kostenpflichtige Schritt40 except Exception as e:41 return {"stage": "grok", "verdict": "SKIP", "reason": f"grok fehlgeschlagen: {e}"}4243 verdict, conf = ans.get("verdict"), ans.get("confidence") or 044 if verdict == "BUY" and conf < MIN_CONFIDENCE:45 verdict = "SKIP"46 ans["why"] = f"geringe Konfidenz {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"]}4950if __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} bei {v['price']}"58 else:59 v["action"] = (f"FREIGABE ERFORDERLICH: kaufe ${TICKET_USD} von {v['symbol']} in deiner eigenen Wallet, "60 f"führe dann aus: python book.py add {mint} {TICKET_USD} <fill price> {v['liq_usd']}")61 print(json.dumps(v, indent=2))
Du brauchst keinen Scanner, um es zu nutzen. Eine CA aus einem Call-Channel, einem Post oder einer Nachricht eines Freundes: Sag dem Bot „check <CA>“ und er führt eine Zeile aus. Was zurückkommt, sieht so aus (Beispielstruktur, kein echter Token):
1{2 "verdict": "SKIP",3 "confidence": 0.78,4 "why": "besteht jeden harten Check, aber die ersten 30 Posts kamen von Konten, die diese Woche erstellt wurden, gleicher Wortlaut.",5 "x_read": "ein echtes Konto, eine Welle frischer Konten, keine CA-Abweichung",6 "main_risk": "gekaufter Hype, die Käufer verschwinden, wenn das Posten aufhört",7 "stage": "grok",8 "symbol": "EXAMPLE",9 "reason": "besteht jeden harten Check, aber die ersten 30 Posts kamen von Konten, die diese Woche erstellt wurden, gleicher Wortlaut."10}

1FAKTEN VOR MEINUNGEN. Grok entscheidet nie, ob ein Mint offen ist.2EIN FEHLGESCHLAGENER AUFRUF IST EIN SKIP. Rugcheck down, DexScreener down, Grok down, fehlerhaftes JSON: SKIP.3NULL IST NICHT SAUBER. Ein Feld, das nicht zurückkam, killt den Token, es lässt ihn nie durch.4EIN URTEIL PRO TOKEN. Führe es nie erneut aus, bis es BUY sagt. Wenn du anderer Meinung bist, bist du mit config.py anderer Meinung.5LIES DIE KILLS, NICHT DIE BUYS. Die Buys fühlen sich gut an. Die Kill-Gründe zeigen dir, ob der Filter funktioniert.
13. drei Routinen, jeweils ein Satz
Kein Workflow-Builder. Du sagst dem Bot jede Routine einmal in einem Satz, und er zeigt dir den nächsten Lauf. Das sind meine, Wort für Wort:
1Führe alle 10 Minuten in /workspace/desk python watch.py aus.2Wenn nichts ausgegeben wird, sag nichts. Wenn etwas ausgegeben wird, poste es hier Wort für Wort.
1Führe alle 30 Minuten in /workspace/desk python scan.py aus.2Poste nur BUY-Urteile: Symbol, Confidence, x_read.3Wenn Rugcheck oder DexScreener down ist, sag einmal welcher, nicht bei jedem Lauf.
1Führe jeden Tag um 21:30 Uhr in /workspace/desk python report.py aus und poste die Ausgabe hier.2Füge eine Sache hinzu, die heute funktioniert hat, und eine Zahl in config.py, die du hinterfragen würdest, mit Begründung.3Ändere diese Zahl niemals selbst.
Die beiden Dateien, die diese Routinen ausführen. Speichere als report.py:
1# report.py2# der Abendbericht. alles darin kommt aus checks.csv und trades.csv, nichts aus dem Gedächtnis.3import csv, os, time4from collections import Counter5from config import LOG, PAPER6import book78day = 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"]1213by_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"))1718print(f"ABENDBERICHT {day} {'(PAPER)' if PAPER else '(LIVE)'}")19print(f"geprüft: {len(checks)}")20print(f"gekillt durch Rug-Filter: {by_stage['facts']} | durch Pool: {by_stage['pool']} | "21 f"durch Grok: {by_stage['grok']} | durch Limits: {by_stage['limits']}")22print(f"gekauft: {len(buys)} | aktuell offen: {len(book.load())}")23print(f"heute realisierter PnL: ${book.today_pnl():+.2f}")24if done:25 print(f"grüne 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"bester: {best['symbol']} ${float(best['pnl']):+.2f} | schlechtester: {worst['symbol']} ${float(worst['pnl']):+.2f}")29if reasons:30 top, n = reasons.most_common(1)[0]31 print(f"häufigster Kill: {top} ({n}x)")
Und scan.py, die optionale Lead-Quelle. Sie zieht frische Solana-Token, die gerade für ein DexScreener-Profil bezahlt haben. Ein bezahltes Profil ist kein Qualitätssignal, es bedeutet nur, dass der Dev Geld ausgegeben hat. Der Rest entscheidet der Filter:
1# scan.py2# optionale Lead-Quelle: frische Solana-Token, die gerade für ein DexScreener-Profil bezahlt haben.3# ein bezahltes Profil ist kein Qualitätssignal, es bedeutet nur, dass der Dev Geld ausgegeben hat. der Filter entscheidet.4import csv, os, subprocess, sys5import requests6from config import LOG78seen = {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]1314for mint in fresh[:5]: # fünf pro Lauf, damit eine hektische Stunde das API-Budget nicht leert15 subprocess.run([sys.executable, "check.py", mint])
Letzte Sache für heute Abend: Settings, General, Auto-review. Füge zwei „Ask first“-Regeln hinzu. Sie stoppen die Aktion und warten auf dich, egal was eine Routine denkt:
1Frage zuerst vor jeder Wallet-Verbindung, Signatur, jedem Swap oder Transfer.2Frage zuerst vor dem Bearbeiten einer Datei namens config.py.


14. eine Woche auf Papier vor dem ersten Dollar
PAPER = True bedeutet, dass der Desk alles echt macht – außer das Geld. Echte Token, echte Preise, echte Exits, Fake-Fills. Öffne nach sieben Tagen checks.csv und lies es, als hätte es ein Fremder geschrieben.
Wonach du suchst: Welcher Check killt am meisten, ob die BUYs solche gewesen wären, die du auch gekauft hättest, und ob irgendein SKIP-Grund falsch aussieht. Ein Paper-Fill passiert zum Bildschirmkurs, ein Live-Fill nie – behandle das Paper-Ergebnis also als Obergrenze, nicht als Prognose.
Wenn du live gehst, stell PAPER auf False, und nichts ändert sich außer dem letzten Schritt. check.py kauft nicht mehr, sondern postet stattdessen eine Freigabezeile: Kaufe selbst 25 $ in deiner eigenen Wallet, dann packt ein Befehl es ins Buch, damit watch.py anfängt, es zu bewachen.
wenn es kaputtgeht
Das hier berührt Geld, also steht für jeden Fehler die eine Antwort schon fest, bevor er passiert.
1401 von xAI -> falscher Key. Übernimm, schreib .env neu, führe den curl aus Schritt 03 nochmal aus.2400 / 404 von xAI -> Modellname geändert. Korrigiere MODEL in config.py, sonst nichts.3429 von xAI -> Rate Limit. Dieser Token ist ein SKIP, der nächste Lauf geht weiter. Niemals loopen.4Fehler wegen x_search -> dein MODEL kann nicht auf X suchen. Wähle eins, das es kann, unter console.x.ai -> Models.5Grok antwortet in Prosa -> ValueError, geloggt, SKIP. Mach nie aus einem Absatz einen Trade.6rugcheck 404 oder leer -> zu frisch zum Indexieren. SKIP. Frisch heißt nicht sauber.7lp_unlocked bei allem -> manche Pool-Typen haben gar keinen LP-Token. Öffne selbst einen auf rugcheck,8 bevor du an diese Zahl gehst, und ändere sie schriftlich.9no_pool -> handelt noch nicht auf einer DEX oder ist kein Solana. SKIP.10Routinen wurden still -> Grok Bot pausiert Routinen, wenn du lange weg warst.11 Öffne Routines und schalte sie wieder ein.
die Rechnung
Alles vor dem Richter ist kostenlos: die Limits, Rugcheck, DexScreener. Der einzige kostenpflichtige Schritt ist ein Grok-Aufruf pro Token, der alle 13 Checks überlebt hat, mit aktivierter X-Suche.
1cost_per_token = input_tokens / 1_000_000 * price_per_M_input2 + output_tokens / 1_000_000 * price_per_M_output3 + posts_fetched / 1_000 * 5 # X-Suche: 5 $ pro 1.000 abgerufene Posts45max_turns = 2 hält die Suche bei zwei Runden, sodass posts_fetched klein bleibt.6Jede Antwort meldet ihr eigenes x_posts_fetched, also zeigt dir Tag eins die echte Zahl.78Preis: [Preis von console.x.ai]
Der Teil, den Leute falsch verstehen: Die Rechnung skaliert mit den Überlebenden, nicht mit dem Scanner. scan.py kann dem Desk 240 Token am Tag füttern, und die meisten sterben kostenlos, bevor Grok überhaupt von ihnen hört.

das Wichtigste
Das ist mein Setup, nicht deine Strategie.
Jede Zahl in config.py ist meine, gewählt für ein 25-$-Ticket und meine eigene Toleranz dabei zuzusehen, wie etwas auf null geht. Die meisten Memecoins gehen auf null, und die meisten Leute, die sie handeln, verlieren Geld. Der Filter macht einen Token nicht gut. Er entfernt die offensichtlichen Wege zu verlieren, und er zwingt dich zu lesen, warum jeder Token gestorben ist.
Lass es eine Woche auf Papier laufen. Lies die Kills. Verschiebe die Zahlen, bei denen du anderer Meinung bist – schriftlich. Kopiere die Struktur, nicht die Konstanten. Keine Finanzberatung.
Code killt, Grok liest X, du signierst. Ein Skript bekommt nie eine Ermessensentscheidung, Grok bekommt nie einen Taschenrechner, und niemand außer dir bekommt jemals die Wallet.
Speicher das vor deinem nächsten Kauf. Folg mir, wenn du vorhast, dasselbe zu betreiben – da kommt noch mehr 🫶
Mein TG – t.me/+8wAXS0nHWgA2MGEy
Mein GitHub – github.com/0xboan
Handle hier – fomo.family/r/0xboan





