YouMind
Anmelden

Grok Bot von null in einer Nacht: Vollständiges Setup + Copy-Paste Rug-Filter

@0xboan
ENGLISCH17. Okt. 2026
126K
139
19
20
439

TL;DR

Dieser Leitfaden beschreibt den Aufbau eines Grok Bot Trading Desks von Grund auf, mit Fokus auf einen strengen 14-stufigen Rug-Filter zur Eliminierung von Scam-Token vor der Ausführung. Er betont einen Workflow nach dem Prinzip 'Code tötet, Grok liest, du signierst' mit Paper-Trading-Sicherheitsvorkehrungen.

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:

text
1Name: RUG DESK
2Job: Solana-Memecoin-Desk, zuerst im Paper-Modus
3Description: 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 bitte
6in 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.

boan - inline image

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:

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

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:

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

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.

boan - inline image

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.

text
10. LEAD eine CA von irgendwoher: ein Call, ein Post, scan.py -> ein Mint
21. LIMITS book.py: Tagesverlust, offene Slots, Cooldown -> kostenlos, ganz ohne Netzwerk
32. FACTS rugcheck.py: 10 harte Kills -> offener Mint, ungesperrte LP, fette Top 10 sterben hier
43. POOL market.py: Tiefe, Alter, Verkäufe -> dünne Pools und Honeypots sterben hier
54. JUDGE grok.py + X-Suche, ein Call -> BUY oder SKIP, ein Grund, ein Risiko
65. FILL Papier: book.py zum Live-Preis -> Live: du signierst es selbst
76. WATCH watch.py alle 10 Minuten -> Stop, Ladder, Trail, Time-Stop
87. 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.

boan - inline image

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.

python
1# config.py
2# jede zahl am desk lebt hier. wenn du nachjustierst, bearbeitest du diese datei und sonst nichts.
3
4MODEL = "grok-4.7" # prüfe console.x.ai -> Models, falls die API ihn ablehnt
5PAPER = True # woche eins: fake-fills zu echten preisen. erst umschalten, wenn du das log gelesen hast
6
7TICKET_USD = 25 # fix. nie basierend auf dem letzten gewinn berechnet
8MAX_OPEN = 4 # 4 x 25 $ = maximal 100 $ im markt
9MAX_ENTRIES_PER_DAY = 6
10DAILY_LOSS_HALT_USD = 50 # realisierter verlust heute erreicht das -> keine neuen entries bis morgen
11COOLDOWN_HOURS = 24 # kein re-entry in einen token, den du gerade verlassen hast
12
13FACTS = { # der rug-filter. nur code, kein modell
14 "max_risk_score": 40, # rugcheck score_normalised, 0-100, höher = riskanter
15 "min_lp_locked_pct": 90, # größter pool: LP gesperrt oder verbrannt
16 "max_top10_pct": 30, # top-10-holder, pools und locker ausgeschlossen
17 "max_dev_pct": 5, # supply, der noch in der creator-wallet liegt
18 "max_insiders": 0, # als insider markierte holder + insider-graph-treffer
19 "min_liquidity_usd": 30000,
20 "max_ticket_share": 0.01, # dein ticket ist nie mehr als 1 % des pools
21 "min_age_min": 30, # jünger als das, da rät jeder report noch
22 "max_age_hours": 72,
23}
24
25MIN_CONFIDENCE = 0.7 # wenn Grok darunter BUY sagt -> wird als SKIP behandelt
26
27EXIT = {
28 "stop_pct": -35, # hard stop ab entry
29 "ladder": [(100, 0.50), (200, 0.25)], # +100 % verkauft die hälfte, +200 % ein viertel
30 "trail_pct": 30, # der rest: raus, wenn der preis 30 % vom peak fällt
31 "time_stop_hours": 6, # nach 6 stunden nicht +20 % -> raus, totes kapital
32 "time_stop_min_pct": 20,
33 "liq_drop_pct": 40, # pool-liquidität 40 % unter entry -> sofort raus
34}
35
36LOG = "checks.csv"
37POSITIONS = "positions.json"
38TRADES = "trades.csv"
text
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.

python
1# book.py
2# positionen, trades, limits. das gedächtnis des desks lebt in zwei dateien, die du selbst öffnen kannst.
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 """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 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 """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"] -= 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 # 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:

python
1# watch.py
2# jede offene position, alle 10 minuten. gibt nichts aus, wenn sich nichts geändert hat.
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']}: Preisfeed down ({e}), halte, versuche es erneut")
15 continue
16 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 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 = "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}")
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
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.
boan - inline image

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

boan - inline image

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.

python
1# rugcheck.py
2# ein report pro token, gekürzt auf die felder, die der desk liest. Grok sieht nie den rohen report.
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): # AMM-vaults und locker stehen bei den top-holdern, sie sind keine whales
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 """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
boan - inline image

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?

python
1# market.py
2# der pool selbst: tiefe, alter, preis und ob überhaupt jemand verkaufen kann.
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. 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:

python
1# grok.py
2# die einzige Datei, die den Schlüssel enthält, und der einzige Ort, an dem der Desk mit xAI spricht.
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("kein XAI_API_KEY in der Umgebung oder 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 """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 werden
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"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:

python
1# prompts.py
2# der eine Grok-Prompt auf dem Desk. Das ist die Datei, die du tatsächlich noch einmal lesen wirst.
3
4JUDGE_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.
9
10INPUT: {"token": {...rugcheck-Fakten...}, "pool": {...dexscreener-Fakten...}}
11
12SCHRITT 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 Schlimmerem
15 - wer hat zuerst gepostet: der Dev, ein echtes Konto mit Historie oder eine Welle frischer Konten
16 - organisch oder gekauft: gleicher Wortlaut, gleiche Minute, Konten ohne Vergangenheit
17 - ist die Contract-Adresse in diesen Posts dieselbe wie im INPUT
18 - wurde dieser Ticker-Name oder dieser Dev schon einmal mit einem Rug in Verbindung gebracht
19
20GIB 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"}
24
25Null 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:

python
1# check.py
2# eine Contract-Adresse rein, ein Urteil raus. läuft jedes Mal, wenn ein Token deinen Desk kreuzt.
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)): # Limits, kostenlos
22 return {"stage": "limits", "verdict": "SKIP", "reason": g}
23
24 try:
25 token = report(mint) # Rug-Filter, kostenlos
26 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"]}
30
31 try:
32 m = pool(mint) # Pool, kostenlos
33 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"]}
37
38 try:
39 ans = ask(JUDGE_PROMPT, {"token": token, "pool": m}, read_x=True) # der einzige kostenpflichtige Schritt
40 except Exception as e:
41 return {"stage": "grok", "verdict": "SKIP", "reason": f"grok fehlgeschlagen: {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"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"]}
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} 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):

json
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}
boan - inline image
text
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:

text
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.
text
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.
text
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:

python
1# report.py
2# der Abendbericht. alles darin kommt aus checks.csv und trades.csv, nichts aus dem Gedächtnis.
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"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:

python
1# scan.py
2# 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, 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]: # fünf pro Lauf, damit eine hektische Stunde das API-Budget nicht leert
15 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:

text
1Frage zuerst vor jeder Wallet-Verbindung, Signatur, jedem Swap oder Transfer.
2Frage zuerst vor dem Bearbeiten einer Datei namens config.py.
boan - inline image
boan - inline image

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.

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

text
1cost_per_token = input_tokens / 1_000_000 * price_per_M_input
2 + output_tokens / 1_000_000 * price_per_M_output
3 + posts_fetched / 1_000 * 5 # X-Suche: 5 $ pro 1.000 abgerufene Posts
4
5max_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.
7
8Preis: [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.

boan - inline image

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

Mit einem Klick speichern

Virale Artikel mit YouMind per KI tief lesen

Speichere die Quelle, stelle gezielte Fragen, fasse die Argumentation zusammen und verwandle einen viralen Artikel in wiederverwendbare Notizen in einem einzigen KI-Arbeitsbereich.

YouMind entdecken
Für Creator

Verwandle dein Markdown in einen sauberen 𝕏-Artikel

Wenn du eigene Langtexte veröffentlichst, wird die 𝕏-Formatierung von Bildern, Tabellen und Codeblöcken mühsam. YouMind macht aus einem ganzen Markdown-Entwurf einen sauberen, sofort postbaren 𝕏-Artikel.

Markdown zu 𝕏 testen

Mehr Muster zum Entschlüsseln

Aktuelle virale Artikel

Mehr virale Artikel entdecken