YouMind
Увійти

Grok Bot з нуля за одну ніч: повне налаштування + фільтр для виявлення шахрайських токенів (копіюй і вставляй)

@0xboan
АНГЛІЙСЬКА17 жовт. 2026 р.
126K
139
19
20
439

Коротко

У цьому посібнику детально описано створення торгового терміналу Grok Bot з нуля, з акцентом на суворому 14-етапному фільтрі для усунення шахрайських токенів перед виконанням угод. Підкреслюється робочий процес «код вбиває, Grok читає, ви підписуєте» із захистом через паперову торгівлю.

більшість людей знайомляться з Grok Bot через чийсь скріншот PnL, відкривають його, наводять на графік і втрачають перші $50 на токені, який помер ще до того, як вони його купили. проблема була не в боті. йому просто ніхто не пояснив, як виглядає «мертвий».

ось цей сетап я б зібрав знову сьогодні ввечері, якби довелося починати спочатку. один бот, одна папка, десять маленьких файлів. він не полює на 100x. його головна робота — вбивати токени, а ті кілька, що виживають, все одно потребують, щоб Grok прочитав X, перш ніж хоча б долар кудись рушить.

кроки з 01 по 07 — це перший вечір: бот, ключ, ліміти, виходи. з 08 по 12 — фільтр рагпулів, 14 перевірок, кожна з яких прописана кодом. 13 і 14 переводять усе на автопілот, спершу лише на папері.

якщо ви читали мій пост про стіл із восьми агентів, то ось фундамент, на якому той стіл стоїть.

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

як цим користуватися: відкрийте свій Grok Bot, вставте всю цю статтю і скажіть «збери цей стіл у /workspace/desk, паперовий режим, питай мене, перш ніж щось торкнеться гаманця». він сам напише кожен файл на своєму комп'ютері.

головне правило, якого треба триматися: код вбиває, Grok читає X, ти підписуєш. ніхто за столом не виконує чужу роботу.

01. підготуйте чотири речі перед стартом

чотири речі. для кожної пояснюю, що це, що з нею зробити сьогодні ввечері й навіщо вона потрібна столу.

1. Grok Bot

що це. додаток, де ви наймаєте іменованих ботів. кожен працює на хмарному комп'ютері з браузером, файлами та терміналом і продовжує працювати, навіть коли ваш ноутбук закритий.

що робити. завантажте його на x.ai/bot, увійдіть, оберіть Create your own.

навіщо. весь стіл живе на тому комп'ютері. файли, рутини, алерти — усе в одному місці, яке можна відкрити з телефону.

2. API-ключ xAI

що це. платний доступ до Grok із коду, з вбудованим пошуком по X.

що робити. console.x.ai, API Keys, створіть один. поки нікуди його не вставляйте, у кроці 03 сказано, куди він іде.

навіщо. рутина не може сидіти й думати про сорок токенів у чаті. скрипт, який робить один виклик на токен — може, і він логує кожну відповідь в одному форматі.

3. Rugcheck і DexScreener

що це. два безкоштовні публічні API. Rugcheck читає контракт: повноваження на емісію (mint authority), LP, холдерів, інсайдерів, гаманець розробника. DexScreener читає пул: глибину, вік, покупки проти продажів.

що робити. нічого. ніякої реєстрації, ніяких ключів для читання.

навіщо. факти йдуть перед думками. відкрите право на емісію — це не питання оцінки, це факт, а факти вбивають першими.

4. одноразовий гаманець (burner wallet), але не сьогодні

що це. свіжий Solana-гаманець, на якому ніколи нічого не лежало.

що робити. поки нічого. перший тиждень працюємо на папері.

навіщо. стіл ніколи не зберігає ключ. коли ви перейдете в лайв, він скаже вам, що купувати, а ви підпишете транзакцію самі.

02. найміть одного бота, а не вісьмох

мій стіл зараз тримає вісім ботів. так було не з самого початку, і у вас теж не має бути. вісім ботів у перший день — це вісім речей, які треба дебажити одночасно. один бот з одним завданням покаже вам, що знадобиться решті сімом пізніше.

оберіть Create your own і дайте йому це, слово в слово:

text
1Ім'я: RUG DESK
2Робота: Стіл для Solana-мемкоїнів, спершу на папері
3Опис: Збери та запусти стіл у /workspace/desk зі статті, яку я вставлю.
4Кожен токен проходить через check.py, без винятків, без скорочень.
5Ти ніколи не купуєш, не продаєш, не підписуєш і не переміщуєш кошти. Ти ніколи не редагуєш config.py, якщо я не попрошу
6в цьому чаті. Ти ніколи не занижуєш параметри фільтра, щоб пропустити токен.
7Повідомляй про кожне «вбивство» з причиною, а не зі своєю думкою про токен.
8Якщо джерело впало, скажи яке саме і пропусти. Ніколи не вгадуй відсутню цифру.

останні два рядки важливіші за перші п'ять. бот, який вгадує відсутню цифру, рано чи пізно вгадає ту, що коштуватиме вам грошей.

boan - inline image

03. тримайте ключ подалі від чату

усе, що ви пишете боту, потрапляє в лог. тому ключ іде у файл, набраний вами, на комп'ютері бота.

відкрийте комп'ютер бота, натисніть Take over, відкрийте термінал і запустіть це. команда запитає ключ, не виводячи його на екран, тому він ніколи не з'явиться в історії:

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

потім переконайтеся, що ключ працює, перш ніж робити щось інше. один виклик, щоб потім ніколи не плутати поганий ключ із поганим промптом:

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

натисніть I'm done і поверніть комп'ютер боту. відтепер він може керувати столом, і при цьому досі не бачить ключа в чаті.

boan - inline image

04. побачте всю воронку, перш ніж будувати її

вісім проходів. безкоштовні йдуть першими. лише те, що виживе після них, коштує виклику Grok, і лише те, що Grok назве BUY, коштує грошей. цього тижня — навіть не це.

text
10. ЛІД CA звідусіль: з поради, поста, scan.py -> один mint
21. ЛІМІТИ book.py: денний збиток, відкриті слоти, кулдаун -> безкоштовно, взагалі без мережі
32. ФАКТИ rugcheck.py: 10 жорстких відсівів -> відкритий mint, розблокований LP, жирний топ-10 гинуть тут
43. ПУЛ market.py: глибина, вік, продажі -> тонкі пули та ханіпоти гинуть тут
54. СУДДЯ grok.py + пошук по X, один виклик -> BUY або SKIP, одна причина, один ризик
65. ВХІД папір: book.py за живою ціною -> лайв: ви підписуєте самі
76. НАГЛЯД watch.py кожні 10 хвилин -> стоп, драбинка, трейлінг, часовий стоп
87. ЗВІТ report.py о 21:30 -> що загинуло, що заплатило, що варто поставити під сумнів

відкрите право на емісію — це не питання оцінки. це факт, а факти безкоштовні. Grok бачить лише ті токени, які вже пройшли всі перевірки, здатні виконати скрипти.

boan - inline image

05. помістіть усі цифри в один файл

збережіть як config.py. кожна цифра на столі живе тут, тому коли ви переналаштовуєте, ви редагуєте один файл і більше нічого. це мої налаштування, заточені під тікет у $25. вони не є рекомендацією, це лише стартова точка, яку ви будете рухати.

python
1# config.py
2# кожна цифра на столі живе тут. коли ви переналаштовуєте, ви редагуєте цей файл і більше нічого.
3
4MODEL = "grok-4.7" # перевірте console.x.ai -> Models, якщо API його відхиляє
5PAPER = True # перший тиждень: фейкові угоди за реальними цінами. перемикайте лише після прочитання логу
6
7TICKET_USD = 25 # фіксовано. розмір ніколи не залежить від останнього виграшу
8MAX_OPEN = 4 # 4 x $25 = максимум $100 у ринку
9MAX_ENTRIES_PER_DAY = 6
10DAILY_LOSS_HALT_USD = 50 # реалізований збиток за день досяг цього -> нових входів немає до завтра
11COOLDOWN_HOURS = 24 # без повторного входу в токен, який ви щойно залишили
12
13FACTS = { # фільтр рагпулів. тільки код, без моделі
14 "max_risk_score": 40, # rugcheck score_normalised, 0-100, вище = ризикованіше
15 "min_lp_locked_pct": 90, # найбільший пул: LP заблоковано або спалено
16 "max_top10_pct": 30, # топ-10 холдерів, без урахування пулів і локерів
17 "max_dev_pct": 5, # саплай, що досі лежить у гаманці творця
18 "max_insiders": 0, # холдери з прапорцем інсайдерів + збіги в графі інсайдерів
19 "min_liquidity_usd": 30000,
20 "max_ticket_share": 0.01, # ваш тікет ніколи не перевищує 1% пулу
21 "min_age_min": 30, # молодше за це — будь-який звіт ще лише вгадує
22 "max_age_hours": 72,
23}
24
25MIN_CONFIDENCE = 0.7 # якщо Grok каже BUY нижче цього -> вважається SKIP
26
27EXIT = {
28 "stop_pct": -35, # жорсткий стоп від точки входу
29 "ladder": [(100, 0.50), (200, 0.25)], # +100% продає половину, +200% продає чверть
30 "trail_pct": 30, # решта: вихід, коли ціна падає на 30% від піку
31 "time_stop_hours": 6, # немає +20% через 6 годин -> вихід, мертві гроші
32 "time_stop_min_pct": 20,
33 "liq_drop_pct": 40, # ліквідність пулу впала на 40% від входу -> негайний вихід
34}
35
36LOG = "checks.csv"
37POSITIONS = "positions.json"
38TRADES = "trades.csv"
text
1ФІКСОВАНИЙ ТІКЕТ. розмір ніколи не зростає через те, що останні три були прибутковими.
2БОТ ЧИТАЄ config.py, АЛЕ НІКОЛИ ЙОГО НЕ ПИШЕ. цифра змінюється лише тоді, коли ви її змінюєте.
3ПОСЛАБЛЕННЯ ФІЛЬТРА ФІКСУЄТЬСЯ ПИСЬМОВО. ви змінили цифру — поясніть чому в чаті того ж дня.

06. запускайте ліміти перш за все

збережіть як book.py. найдешевша перевірка на столі — та, яка взагалі не звертається до API. якщо сьогодні вже втрачено $50, стіл навіть не дивиться на токен. якщо відкрито чотири позиції — те саме. цей файл також є пам'яттю столу: два файли, які ви можете відкрити самі, positions.json і trades.csv.

python
1# book.py
2# позиції, угоди, ліміти. пам'ять столу живе у двох файлах, які ви можете відкрити самі.
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 """Ліміти спрацьовують до будь-якого мережевого виклику. Заблокований вхід нічого не коштує."""
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 """Продає частку від ПОЧАТКОВОГО розміру (1.0 = усе, що лишилося). Повертає реалізований PnL."""
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 # лайв-режим: після того, як ви купили у своєму гаманці -> python book.py add <mint> <usd> <price> <liq_usd>
66 # після того, як ви продали вручну -> 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. пропишіть вихід до входу

більшість людей вирішують, коли продавати, дивлячись на зелену свічку. це найгірший момент для будь-яких рішень. за цим столом кожен вихід існує ще до того, як токен куплено, а бот просто перевіряє його кожні 10 хвилин:

  • ліквідність впала на 40% від входу: вихід, усе, без питань
  • падіння на 35%: вихід
  • зростання на 100%: половина йде, решта — гроші ринку
  • зростання на 200%: іде ще чверть
  • після першого тейк-профіту решта виходить, коли ціна падає на 30% від піку
  • шість годин без +20%: вихід, слот вартий більше, ніж надія

збережіть як watch.py:

python
1# watch.py
2# кожна відкрита позиція, кожні 10 хвилин. нічого не друкує, якщо нічого не змінилося.
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']}: прайс-фід впав ({e}), тримаємо, спробуємо ще раз")
15 continue
16 if not m or m["price"] <= 0:
17 events.append(f"{p['symbol']}: пул зник. вважати рагпулом, продавайте що можете")
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 = "продано" if PAPER else "ПРОДАВАЙ ЗАРАЗ у своєму гаманці"
30 size = "решту" if frac >= 1 else f"{int(frac * 100)}%"
31 events.append(f"{s['symbol']}: {verb} {size} на {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
1ЛІКВІДНІСТЬ ПЕРША. витягнутий пул б'є будь-яке інше правило, навіть якщо позиція в плюсі.
2ТРЕЙЛІНГ АКТИВУЄТЬСЯ ПІСЛЯ ПЕРШОГО ТЕЙКУ. до цього -35% — єдина підлога.
3МЕРТВІ ГРОШІ — ЦЕ ТЕЖ ЗБИТОК. шість годин без руху звільняють слот для наступного токена.
4ТИША — ЦЕ СТАТУС. watch.py нічого не друкує, якщо нічого не змінилося, тому тихий чат означає, що туди не треба дивитися.
boan - inline image

08. вивчіть 14 способів, якими гине токен

якби мені довелося викинути все вищесказане й залишити одну річ, це була б вона. вона також працює без жодного бота: пройдіть ті самі 14 перевірок вручну на rugcheck.xyz і dexscreener перед наступною покупкою, і ви пропустите більшість токенів, про які потім шкодували б.

13 перевірок — це код. порівняння, без моделі, без думок. 14-та — єдина, якій потрібен Grok.

#

перевірка

вбиває, коли

чому

1

вже рагнули

Rugcheck позначає його як rugged

хтось уже це зробив

2

право на емісію (mint authority)

досі відкрите

дев може надрукувати новий саплай прямо у ваш мішок

3

право на заморозку (freeze authority)

досі відкрите

дев може заморозити ваші токени, ви не зможете продати

4

прапорці небезпеки

будь-який ризик рівня danger

Rugcheck уже побачив те, що вам доведеться спростовувати

5

оцінка ризику

вище 40/100

дрібні попередження накопичуються

6

блокування LP

найбільший пул заблокований або спалений менш ніж на 90%

розблокована ліквідність — це кнопка для рагпулу

7

топ-10 холдерів

понад 30%, без урахування пулів і локерів

десять гаманців можуть разом закінчити вашу угоду

8

гаманець дева

творець досі тримає понад 5%

дев — перший продавець

9

інсайдери / бандли

будь-який холдер-інсайдер або збіг у графі інсайдерів

гаманці, профінансовані разом, продають разом

10

глибина пулу

ліквідність менше $30k

ви станете чиїмось виходом

11

частка тікета

ваші $25 — це понад 1% пулу

ваша власна покупка рухає ціну

12

вік

менше 30 хв або більше 72 год

занадто свіжий для будь-якого звіту, або рух уже відбувся

13

продажі існують

20+ покупок за останню годину, нуль продажів

це форма ханіпоту

14

читання X (Grok)

немає постів, скопійований CA, куплений хайп, історія рагпулів

та частина, яку не поверне жоден API

boan - inline image

09. дозвольте коду вбити очевидних

перевірки з 1 по 9. він тягне один звіт і залишає лише ті поля, які читає стіл. Grok ніколи не бачить сирий звіт: великий пейлоад коштує токенів і знижує точність.

одна деталь, яку люди пропускають: власне сховище пулу та локери сидять у списку топ-холдерів. порахуйте їх, і кожен токен виглядатиме як китовий. код відкидає їх, перш ніж підсумовувати топ-10.

python
1# rugcheck.py
2# один звіт на токен, обрізаний до полів, які читає стіл. Grok ніколи не бачить сирий звіт.
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-сховища та локери сидять у топ-холдерах, вони не кити
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 """Прості порівняння. Перша невдача перемагає, причина логірується."""
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. перевіряйте пул, а не лише контракт

перевірки з 10 по 13. контракт може бути ідеальним, але пул усе одно не випустить вас. цей код читає найглибший пул для токена і ставить чотири нудні запитання: чи достатньо в ньому грошей, наскільки великий мій тікет порівняно з ним, скільки йому років і чи хтось взагалі продає.

python
1# market.py
2# сам пул: глибина, вік, ціна і чи може хтось взагалі продати.
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. дозвольте Grok читати те, чого не може код

перевірка 14. саме тому стіл працює на Grok, а не на будь-якій іншій моделі: він може шукати в X, поки думає. токен може пройти усі 13 перевірок і все одно виявитися копією з іншою адресою контракту, або запуском, де сорок акаунтів, створених минулого тижня, опублікували одне й те саме речення в одну й ту саму хвилину. жоден API цього не поверне. X — повертає.

збережіть як grok.py. це єдиний файл, який читає ключ, і єдине місце, де стіл спілкується з xAI:

python
1# grok.py
2# єдиний файл, що містить ключ, і єдине місце, де термінал спілкується з 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 """Один виклик, JSON на вході, JSON на виході. Усе, що не є JSON, викликає помилку, а помилка означає 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 # два раунди пошуку, потім модель має відповісти
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])

збережи як prompts.py. це той файл, який ти насправді будеш перечитувати:

python
1# prompts.py
2# єдиний промпт для Grok на терміналі. саме цей файл ти будеш перечитувати.
3
4JUDGE_PROMPT = """
5Ти — RUG DESK. Solana-мемкоїн щойно пройшов усі жорсткі перевірки в коді:
6права доступу, LP, холдери, гаманець розробника, інсайдери, глибина пулу, вік.
7Не перепровіряй ці цифри. Ти вирішуєш, чи заходить один фіксований тікет.
8Ти ніколи не визначаєш розмір позиції й ніколи не обираєш точки виходу.
9
10ВХІДНІ ДАНІ: {"token": {...факти з rugcheck...}, "pool": {...факти з dexscreener...}}
11
12КРОК 1. Пошукай у X тікер та адресу контракту за останні 72 години.
13КРОК 2. Оцінюй лише те, чого код не бачить:
14 - чи складаються ризики рівня warn у щось гірше разом
15 - хто запостив першим: розробник, реальний акаунт з історією чи хвиля свіжих акаунтів
16 - органічно чи куплено: однакові формулювання, однакова хвилина, акаунти без минулого
17 - чи збігається адреса контракту в цих постах із тією, що у ВХІДНИХ ДАНИХ
18 - чи був цей тікер або цей розробник раніше пов'язаний з рагпулом
19
20ПОВЕРТАЙ ЛИШЕ JSON:
21{"verdict": "BUY" | "SKIP", "confidence": 0.0-1.0,
22 "why": "максимум два рядки", "x_read": "один рядок про те, як виглядає X",
23 "main_risk": "один рядок"}
24
25Нуль постів у X — це теж відповідь: ніхто не знає, що він існує. SKIP.
26Інша адреса контракту під тим самим тікером у X: ризик копії. SKIP.
27НІКОЛИ не відповідай BUY, якщо потрібне тобі поле дорівнює null.
28НІКОЛИ не згадуй цільові ціни. Ти їх не знаєш.
29"""

12. зв'яжи все в одну команду

одна адреса контракту на вході, один вердикт на виході. ліміти, факти, пул, Grok — саме в такому порядку, і перший, хто скаже «ні», все зупиняє:

python
1# check.py
2# одна адреса контракту на вході, один вердикт на виході. запускається щоразу, коли токен потрапляє на твій термінал.
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)): # ліміти, безкоштовно
22 return {"stage": "limits", "verdict": "SKIP", "reason": g}
23
24 try:
25 token = report(mint) # раг-фільтр, безкоштовно
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) # пул, безкоштовно
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) # єдиний платний крок
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))

тобі не потрібен сканер, щоб цим користуватися. CA з кол-каналу, посту чи повідомлення друга: скажи боту "check <CA>", і він виконає один рядок. результат виглядатиме приблизно так (приклад структури, а не реальний токен):

json
1{
2 "verdict": "SKIP",
3 "confidence": 0.78,
4 "why": "проходить усі жорсткі перевірки, але перші 30 постів були від акаунтів, створених цього тижня, з однаковими формулюваннями.",
5 "x_read": "один реальний акаунт, хвиля свіжих, розбіжностей у CA немає",
6 "main_risk": "куплений хайп, покупці підуть, щойно пости припиняться",
7 "stage": "grok",
8 "symbol": "EXAMPLE",
9 "reason": "проходить усі жорсткі перевірки, але перші 30 постів були від акаунтів, створених цього тижня, з однаковими формулюваннями."
10}
boan - inline image
text
1ФАКТИ ПЕРЕДУЮТЬ ДУМКАМ. Grok ніколи не вирішує, чи відкритий мінт.
2НЕВДАЛИЙ ВИКЛИК — ЦЕ SKIP. Rugcheck ліг, DexScreener ліг, Grok ліг, кривий JSON: SKIP.
3NULL — ЦЕ НЕ ЧИСТО. поле, яке не повернулося, вбиває токен, а не пропускає його.
4ОДИН ВЕРДИКТ НА ТОКЕН. ніколи не перезапускай, поки не побачиш BUY. якщо ти не згоден — ти не згоден із config.py.
5ЧИТАЙ ПРИЧИНИ ВБИВСТВ, А НЕ ПОКУПОК. покупки тішать. причини відсіювання показують, чи працює фільтр.

13. три рутини, по одному реченню кожна

ніякого конструктора воркфлоу. ти один раз описуєш боту кожну рутину одним реченням, і він показує тобі наступний запуск. ось мої, слово в слово:

text
1Кожні 10 хвилин у /workspace/desk запускай python watch.py.
2Якщо нічого не виводить — нічого не кажи. Якщо щось виводить — опублікуй це тут слово в слово.
text
1Кожні 30 хвилин у /workspace/desk запускай python scan.py.
2Публікуй лише вердикти BUY: символ, впевненість, x_read.
3Якщо Rugcheck або DexScreener лежить, скажи який саме один раз, а не при кожному запуску.
text
1Щодня о 21:30 у /workspace/desk запускай python report.py і публікуй результат тут.
2Додай одну річ, яка сьогодні спрацювала, і одне значення в config.py, яке ти б поставив під сумнів, із поясненням чому.
3Ніколи не змінюй це значення самостійно.

два файли, які запускають ці рутини. збережи як report.py:

python
1# report.py
2# вечірній звіт. усе в ньому береться з checks.csv і trades.csv, нічого — з пам'яті.
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)")

і scan.py — необов'язкове джерело лідів. він витягує свіжі токени Solana, які щойно оплатили профіль на DexScreener. оплачений профіль — не сигнал якості, це лише означає, що розробник витратив гроші. решту вирішує фільтр:

python
1# scan.py
2# необов'язкове джерело лідів: свіжі токени Solana, які щойно оплатили профіль на DexScreener.
3# оплачений профіль — не сигнал якості, це лише означає, що розробник витратив гроші. фільтр вирішує.
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]: # п'ять за запуск, щоб одна активна година не вичерпала ліміт API
15 subprocess.run([sys.executable, "check.py", mint])

останнє на сьогодні: Settings, General, Auto-review. додай два правила Ask first — вони зупиняють дію і чекають на тебе незалежно від того, що думає будь-яка рутина:

text
1Спершу питай перед будь-яким підключенням гаманця, підписом, свопом або переказом.
2Спершу питай перед редагуванням будь-якого файлу з назвою config.py.
boan - inline image
boan - inline image

14. тиждень на папері перед першим доларом

PAPER = True означає, що термінал робить усе по-справжньому, окрім грошей. реальні токени, реальні ціни, реальні виходи, фейкові виконання. через сім днів відкрий checks.csv і прочитай його так, ніби його написав незнайомець.

що шукати: яка перевірка вбиває найчастіше, чи купив би ти ті токени, що отримали BUY, і чи не виглядає хибною якась причина SKIP. паперове виконання відбувається за ціною на екрані, реальне — ніколи, тому сприймай паперовий результат як стелю, а не як прогноз.

коли перейдеш на лайв, зміни PAPER на False, і нічого не зміниться, окрім останнього кроку. check.py перестає купувати й натомість виводить рядок для підтвердження: купи $25 самостійно у своєму гаманці, а потім одна команда додасть це в книгу, щоб watch.py почав це охороняти.

коли все ламається

це стосується грошей, тому для кожного збою відповідь має бути записана ще до того, як він станеться.

text
1401 від xAI -> невірний ключ. Перехоп керування, перепиши .env, запусти curl із кроку 03 ще раз.
2400 / 404 від xAI -> змінилася назва моделі. виправ MODEL у config.py, більше нічого не чіпай.
3429 від xAI -> rate limit. цей токен — SKIP, наступний запуск піде далі. ніколи не зациклюй.
4помилка щодо x_search -> твоя MODEL не може шукати в X. обери ту, що може, у console.x.ai -> Models.
5Grok відповідає текстом -> ValueError, логується, SKIP. ніколи не перетворюй абзац на угоду.
6rugcheck 404 або порожньо -> занадто свіжий для індексації. SKIP. свіже не означає чисте.
7lp_unlocked на всьому -> деякі типи пулів взагалі не мають LP-токена. відкрий один на rugcheck самостійно,
8 перш ніж чіпати це значення, і змінюй його лише письмово.
9no_pool -> ще не торгується на DEX або не Solana. SKIP.
10рутини замовкли -> Grok Bot призупиняє рутини, якщо тебе довго не було.
11 відкрий Routines і увімкни їх назад.

рахунок

усе до судді безкоштовне: ліміти, Rugcheck, DexScreener. єдиний платний крок — один виклик Grok на токен, який пережив усі 13 перевірок, із увімкненим пошуком у X.

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: $5 за 1000 знайдених постів
4
5max_turns = 2 обмежує пошук двома раундами, тому posts_fetched залишається малим.
6кожна відповідь звітує власне x_posts_fetched, тож перший же день покаже тобі реальну цифру.
7
8ціна: [ціна з console.x.ai]

те, що люди розуміють неправильно: рахунок масштабується від кількості тих, хто вижив, а не від сканера. scan.py може подавати на термінал 240 токенів на день, і більшість із них гине безкоштовно ще до того, як Grok про них дізнається.

boan - inline image

важлива частина

це мій сетап, а не твоя стратегія.

кожна цифра в config.py — моя, підібрана під тікет у $25 і мою власну готовність дивитися, як щось летить у нуль. більшість мемкоїнів справді летить у нуль, і більшість людей, які ними торгують, втрачають гроші. фільтр не робить токен хорошим. він прибирає очевидні способи втратити гроші й змушує тебе читати, чому помер кожен токен.

попрацюй тиждень на папері. читай причини відсіювання. змінюй цифри там, де не згоден, і тільки письмово. копіюй структуру, а не константи. це не фінансова порада.

код вбиває, Grok читає X, ти підписуєш. скрипт ніколи не приймає суб'єктивних рішень, Grok ніколи не отримує калькулятор, і ніхто, крім тебе, не торкається гаманця.

збережи це перед наступною покупкою. підписуйся, якщо плануєш запускати щось подібне, далі буде більше такого 🫶

мій tg - t.me/+8wAXS0nHWgA2MGEy

мій github - github.com/0xboan

торгуй тут - fomo.family/r/0xboan

Збереження в один клік

Використовуйте YouMind для AI-глибокого читання віральних статей

Зберігайте джерела, ставте цілеспрямовані запитання, підсумовуйте аргументи та перетворюйте віральні статті на корисні нотатки в одному AI-робочому просторі.

Дослідити YouMind
Для авторів

Перетворіть свій Markdown на охайну статтю для 𝕏

Коли ви публікуєте власні лонгріди, зображення, таблиці та блоки коду роблять форматування в 𝕏 складним. YouMind перетворює повну чернетку в Markdown на чисту статтю для 𝕏, готову до публікації.

Спробувати Markdown для 𝕏

Більше патернів для аналізу

Останні віральні статті

Переглянути більше віральних статей