معظم الناس يتعرفون على Grok Bot من خلال لقطة شاشة لأرباح وخسائر (pnl) شخص آخر، يفتحونه، يوجهونه نحو رسم بياني، ويخسرون أول 50 دولارًا في توكن كان ميتًا قبل أن يشتروه. لم تكن المشكلة في البوت؛ بل إن أحدًا لم يخبره كيف يبدو التوكن الميت.
هذا هو الإعداد الذي سأبنيه مرة أخرى الليلة إذا اضطررت للبدء من الصفر. بوت واحد، مجلد واحد، عشرة ملفات صغيرة. لا يبحث عن أرباح بنسبة 100x. مهمته الأساسية هي تصفية التوكنات، والقليل منها الذي ينجو لا يزال يحتاج إلى Grok ليقرأ منصة X قبل أن يتحرك دولار واحد.
الخطوات من 01 إلى 07 تمثل الليلة الأولى: البوت، المفتاح، الحدود، والمخارج. ومن 08 إلى 12 هي مرشح الاحتيال (rug filter)، 14 فحصًا، كل واحد منها مكتوب ككود برمجي. أما 13 و14 فتضع النظام على الطيار الآلي، ورقيًا في البداية.
إذا قرأت منشوري السابق عن مكتب الثمانية وكلاء، فهذا هو الأساس الذي يقف عليه ذلك المكتب.
https://x.com/0xboan/status/2092226208234647626
كيفية الاستخدام: افتح Grok Bot الخاص بك، الصق هذا المقال بالكامل، وقل له "ابنِ هذا المكتب في /workspace/desk، الوضع الورقي، اسألني قبل أن يلمس أي شيء المحفظة." سيقوم بكتابة كل ملف بنفسه، على حاسوبه الخاص.
القاعدة التي يجب أن تتمسك بها: الكود يصفي، Grok يقرأ X، وأنت توقع. لا أحد في المكتب يقوم بعمل شخص آخر.
01. جهّز أربعة أشياء قبل البدء
أربعة أشياء. يوضح كل منها ماهيته، وما ستفعله الليلة، ولماذا يحتاجه المكتب.
1. Grok Bot
ماهيته. التطبيق الذي تستأجر من خلاله بوتات بأسماء محددة. يعمل كل منها على حاسوب سحابي مزود بمتصفح وملفات وطرفية (terminal)، ويستمر في العمل حتى لو أغلقت حاسوبك المحمول.
ما ستفعله. حمّله من x.ai/bot، سجّل الدخول، واختر Create your own (أنشئ خاصتك).
لماذا. المكتب بأكمله يعيش على ذلك الحاسوب. الملفات، الروتينات، التنبيهات، كلها في مكان واحد يمكنك فتحه من هاتفك.
2. مفتاح واجهة برمجة تطبيقات xAI (API key)
ماهيته. وصول مدفوع إلى Grok عبر الكود، مع بحث X مدمج فيه.
ما ستفعله. اذهب إلى console.x.ai، ثم API Keys، وأنشئ واحدًا. لا تلصقه في أي مكان بعد، الخطوة 03 توضح أين يوضع.
لماذا. لا يمكن لروتين أن يجلس ويفكر في أربعين توكنًا داخل محادثة. لكن السكربت الذي يجري استدعاءً واحدًا لكل توكن يستطيع ذلك، ويسجل كل إجابة بالتنسيق نفسه.
3. Rugcheck و DexScreener
ماهيتهما. واجهتا برمجة تطبيقات (APIs) عامتان ومجانيتان. يقرأ Rugcheck العقد الذكي: الصلاحيات، السيولة (LP)، الحاملين، المطلعين الداخليين، ومحفظة المطور. بينما يقرأ DexScreener المجمع: العمق، العمر، عمليات الشراء مقابل البيع.
ما ستفعله. لا شيء. لا تسجيل، ولا مفتاح للقراءة.
لماذا. الحقائق تسبق الآراء. صلاحية السك المفتوحة ليست مسألة تقديرية، بل حقيقة، والحقائق هي من يصفي أولاً.
4. محفظة مؤقتة (burner wallet)، ولكن ليس الليلة
ماهيته. محفظة Solana جديدة تمامًا لم تحتفظ بأي شيء آخر من قبل.
ما ستفعله. لا شيء حتى الآن. الأسبوع الأول يعمل ورقيًا.
لماذا. المكتب لا يحتفظ أبدًا بمفتاح. عندما تنتقل للتداول الفعلي، سيخبرك بما تشتريه وأنت توقع بنفسك.
02. استأجر بوتًا واحدًا، وليس ثمانية
مكتبي يشغل ثمانية بوتات الآن. لكنه لم يبدأ هكذا، ولا ينبغي لمكتبك أن يبدأ كذلك. ثمانية بوتات في اليوم الأول تعني ثمانية أشياء تحتاج إلى إصلاح أخطاء في وقت واحد. بوت واحد بمهمة واحدة سيُريك ما سيحتاجه السبعة الآخرون لاحقًا.
اختر Create your own وأعطه هذا النص حرفيًا:
1الاسم: RUG DESK2المهمة: مكتب تداول عملات memecoin على Solana، التداول الورقي أولاً3الوصف: قم ببناء وتشغيل المكتب في /workspace/desk بناءً على المقال الذي ألصقه.4يجب أن يمر كل توكن عبر check.py، بلا استثناءات، وبلا اختصارات.5لا تقم أبدًا بالشراء أو البيع أو التوقيع أو نقل الأموال. لا تعدّل config.py إلا إذا طلبت منك ذلك6في هذه المحادثة. لا تقم أبدًا بتخفيض رقم أي مرشح للسماح بمرور توكن.7أبلغ عن كل عملية تصفية مع ذكر سببها، وليس رأيك الشخصي في التوكن.8عند تعطل أحد المصادر، حدد أيها وتجاوزه. لا تخمن أبدًا رقمًا مفقودًا.
السطران الأخيران أهم من الأسطر الخمسة الأولى. البوت الذي يخمن رقمًا مفقودًا سيخمن في النهاية رقمًا يكلفك خسارتك.

03. أبعد المفتاح عن المحادثة
كل ما تكتبه للبوت يُحفظ في سجل المحادثة. لذلك يوضع المفتاح في ملف، تكتبه أنت بنفسك، على حاسوب البوت.
افتح حاسوب البوت، انقر على Take over، افتح الطرفية ونفذ هذا الأمر. سيطلب المفتاح دون عرضه على الشاشة، لذا لن يظهر أبدًا في سجل الأوامر أيضًا:
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
ثم أثبت أن المفتاح يعمل قبل أي شيء آخر. استدعاء واحد فقط، حتى لا تخلط أبدًا بين مفتاح خاطئ وأمر خاطئ لاحقًا:
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" ...
انقر على I'm done وأعد الحاسوب. من هنا فصاعدًا، يمكن للبوت تشغيل المكتب، ومع ذلك لن يرى المفتاح أبدًا في المحادثة.

04. افهم مسار الترشيح بالكامل قبل أن تبني أي جزء منه
ثماني مراحل. المجانية تُنفذ أولاً. فقط ما ينجو من المراحل المجانية يكلف استدعاءً لـ Grok، وفقط ما يقرر Grok شراءه (BUY) يكلف مالاً. هذا الأسبوع، ولا حتى ذلك.
10. LEAD عنوان عقد (CA) من أي مكان: مكالمة، منشور، scan.py -> سك واحد21. LIMITS book.py: الخسارة اليومية، الفتحات المفتوحة، فترة التهدئة -> مجاني، بدون شبكة إطلاقًا32. FACTS rugcheck.py: 10 عمليات تصفية صارمة -> السك المفتوح، السيولة غير المقفلة، كبار العشرة الحاملين يموتون هنا43. POOL market.py: العمق، العمر، عمليات البيع -> المجمعات الرقيقة وفخاخ العسل (honeypots) تموت هنا54. JUDGE grok.py + بحث X، استدعاء واحد -> BUY أو SKIP، سبب واحد، مخاطرة واحدة65. FILL ورقي: book.py بالسعر الفعلي -> فعلي: أنت توقع بنفسك76. WATCH watch.py كل 10 دقائق -> إيقاف خسارة، بيع متدرج، تتبع، إيقاف زمني87. REPORT report.py الساعة 21:30 -> ما مات، ما دفع، وما يستوجب التساؤل
صلاحية السك المفتوحة ليست مسألة تقديرية. إنها حقيقة، والحقائق مجانية. لا يرى Grok أبدًا سوى التوكنات التي اجتازت بالفعل كل فحص يمكن لسكربت القيام به.

05. ضع كل الأرقام في ملف واحد
احفظه باسم config.py. كل رقم في المكتب يعيش هنا، لذا عند إعادة الضبط، ستعدل ملفًا واحدًا ولا شيء غيره. هذه هي أرقامي، مضبوطة لتذكرة بقيمة 25 دولارًا. إنها ليست توصية، بل نقطة انطلاق ستقوم بتعديلها.
1# config.py2# كل رقم في المكتب يعيش هنا. عند إعادة الضبط، ستعدل هذا الملف ولا شيء غيره.34MODEL = "grok-4.7" # تحقق من console.x.ai -> Models إذا رفضته واجهة برمجة التطبيقات5PAPER = True # الأسبوع الأول: تنفيذ وهمي بأسعار حقيقية. غيّره فقط بعد قراءة السجل67TICKET_USD = 25 # ثابت. لا يتم تحديد الحجم أبدًا بناءً على آخر ربح8MAX_OPEN = 4 # 4 × 25 دولارًا = 100 دولار في السوق كحد أقصى9MAX_ENTRIES_PER_DAY = 610DAILY_LOSS_HALT_USD = 50 # إذا وصلت الخسارة المحققة اليوم لهذا الرقم -> لا صفقات جديدة حتى الغد11COOLDOWN_HOURS = 24 # عدم إعادة الدخول في توكن خرجت منه للتو1213FACTS = { # مرشح الاحتيال. كود فقط، بدون نموذج ذكاء اصطناعي14 "max_risk_score": 40, # score_normalised من rugcheck، من 0-100، أعلى = أكثر خطورة15 "min_lp_locked_pct": 90, # أكبر مجمع: السيولة مقفلة أو محروقة16 "max_top10_pct": 30, # كبار العشرة حاملين، باستثناء المجمعات والخزنات المقفلة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}2425MIN_CONFIDENCE = 0.7 # إذا قال Grok BUY بثقة أقل من هذا -> يُعامل كـ SKIP2627EXIT = {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}3536LOG = "checks.csv"37POSITIONS = "positions.json"38TRADES = "trades.csv"
1تذكرة ثابتة. الحجم لا يزيد أبدًا لأن الصفقات الثلاث الأخيرة كانت رابحة.2البوت يقرأ config.py، ولا يكتبه أبدًا. الرقم لا يتحرك إلا عندما تحركه أنت.3أي تخفيف للمرشح يكون كتابيًا. إذا غيّرت رقمًا، يجب أن تشرح السبب في المحادثة، في نفس اليوم.
06. نفّذ الحدود قبل أي شيء آخر
احفظه باسم book.py. أرخص فحص في المكتب هو الذي لا يستدعي أي واجهة برمجة تطبيقات. إذا خسر اليوم 50 دولارًا بالفعل، فلن ينظر المكتب حتى إلى التوكن. إذا كانت هناك أربع صفقات مفتوحة، فالأمر كذلك. هذا الملف هو أيضًا ذاكرة المكتب: ملفان يمكنك فتحهما بنفسك، positions.json و trades.csv.
1# book.py2# الصفقات، العمليات، الحدود. ذاكرة المكتب تعيش في ملفين يمكنك فتحهما بنفسك.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 """تُنفذ الحدود قبل أي استدعاء شبكي. الدخول المحظور لا يكلف شيئًا."""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 """يبيع جزءًا من الحجم الأصلي (1.0 = كل ما تبقى). يعيد الربح/الخسارة المحقق."""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 # الوضع الفعلي: بعد الشراء في محفظتك الخاصة -> 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:
1# watch.py2# كل صفقة مفتوحة، كل 10 دقائق. لا يطبع شيئًا إذا لم يتغير شيء.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']}: تغذية السعر معطلة ({e})، الاحتفاظ بالمركز، ستتم المحاولة مجددًا")15 continue16 if not m or m["price"] <= 0:17 events.append(f"{p['symbol']}: المجمع اختفى. تعامل معه كاحتيال، بِع ما تستطيع")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 = "تم البيع" 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:+.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)
1السيولة أولاً. المجمع المسحوب يتغلب على كل قاعدة أخرى، حتى لو كانت الصفقة رابحة.2التتبع يتفعل بعد جني الأرباح الأول. قبل ذلك، -35% هو الحد الأدنى الوحيد.3الأموال الميتة هي خسارة أيضًا. ست ساعات مسطحة تحرر الفتحة للتوكن التالي.4الصمت هو حالة. watch.py لا يطبع شيئًا إذا لم يتغير شيء، لذا فالمحادثة الهادئة تعني أنك لست مضطرًا للنظر.

08. تعلّم الطرق الـ 14 التي يموت بها التوكن
لو اضطررت للتخلي عن كل ما سبق والاحتفاظ بشيء واحد، فسيكون هذا. وهو يعمل أيضًا بدون أي بوت: نفّذ نفس الفحوصات الـ 14 يدويًا على rugcheck.xyz و dexscreener قبل شرائك التالي، وستتجنب معظم التوكنات التي كنت ستندم عليها.
13 فحصًا منها عبارة عن كود. مقارنات، بدون نموذج ذكاء اصطناعي، وبدون آراء. والفحص الرابع عشر هو الوحيد الذي يحتاج إلى Grok.
#
الفحص
يُصفّي عندما
السبب
1
احتيال مؤكد
Rugcheck يُعلمه كاحتيال
شخص ما فعلها بالفعل
2
صلاحية السك (mint authority)
لا تزال مفتوحة
يمكن للمطور طباعة عرض جديد في حقيبتك
3
صلاحية التجميد (freeze authority)
لا تزال مفتوحة
يمكن للمطور تجميد توكناتك، ولن تتمكن من البيع
4
علامات الخطر
أي مخاطرة بمستوى خطر
Rugcheck رأى بالفعل شيئًا سيتعين عليك إثبات خطئه
5
درجة المخاطرة
أعلى من 40/100
التحذيرات الصغيرة تتراكم
6
قفل السيولة (LP lock)
أكبر مجمع مقفل أو محروق بنسبة أقل من 90%
السيولة غير المقفلة هي زر سحب
7
كبار العشرة حاملين
أكثر من 30%، باستثناء المجمعات والخزنات المقفلة
عشر محافظ يمكنها إنهاء صفقتك معًا
8
محفظة المطور
المنشئ لا يزال يحتفظ بأكثر من 5%
المطور هو أول بائع
9
المطلعون الداخليون / الحزم
أي حامل مُعلم كمطلع داخلي أو تطابق في الرسم البياني
المحافظ الممولة معًا تبيع معًا
10
عمق المجمع
سيولة أقل من 30 ألف دولار
ستكون مخرجًا لشخص آخر
11
حصة التذكرة
تذكرتك البالغة 25 دولارًا تمثل أكثر من 1% من المجمع
شراؤك الخاص يحرك السعر
12
العمر
أقل من 30 دقيقة أو أكثر من 72 ساعة
حديث جدًا لأي تقرير، أو أن الحركة قد حدثت بالفعل
13
وجود عمليات بيع
أكثر من 20 عملية شراء في الساعة الماضية، وصفر مبيعات
هذا هو شكل فخ العسل (honeypot)
14
قراءة X (Grok)
لا توجد منشورات، عنوان عقد مقلد، شراء مبني على ضجيج، تاريخ احتيال
الجزء الذي لا توفره أي واجهة برمجة تطبيقات

09. دع الكود يُصفّي الحالات الواضحة
الفحوصات من 1 إلى 9. تجلب تقريرًا واحدًا وتحتفظ فقط بالحقول التي يقرأها المكتب. لا يرى Grok التقرير الخام أبدًا، فالحمولة الكبيرة تكلف توكنات وتكلف دقة.
تفصيلة يغفل عنها الكثيرون: خزنة المجمع نفسها والخزنات المقفلة تظهر في قائمة كبار الحاملين. احسبها وسيبدو كل توكن وكأنه توكن حيتان. الكود يستبعدها قبل جمع نسب كبار العشرة.
1# rugcheck.py2# تقرير واحد لكل توكن، مقتطع للحقول التي يقرأها المكتب. لا يرى Grok التقرير الخام أبدًا.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 والخزنات المقفلة تظهر ضمن كبار الحاملين، وهي ليست حيتانًا16 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 """مقارنات بسيطة. أول فشل يفوز، ويتم تسجيل السبب."""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. افحص المجمع، وليس العقد فقط
الفحوصات من 10 إلى 13. قد يكون العقد مثاليًا ومع ذلك لا يسمح لك المجمع بالخروج. يقرأ هذا الجزء أعمق مجمع للتوكن ويطرح أربعة أسئلة مملة: هل يوجد فيه ما يكفي؟ ما حجم تذكرتي مقارنة به؟ ما عمره؟ وهل يبيع أحد فعليًا؟
1# market.py2# المجمع نفسه: العمق، العمر، السعر، وما إذا كان بإمكان أحد البيع فعليًا.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. دع Grok يقرأ ما لا يستطيع الكود قراءته
الفحص 14. هذا هو السبب في أن المكتب يعمل على Grok وليس على أي نموذج آخر: يمكنه البحث في X أثناء تفكيره. قد يجتاز التوكن جميع الفحوصات الـ 13 ومع ذلك يكون نسخة مقلدة بعنوان عقد مختلف، أو إطلاقًا قامت فيه أربعون حسابًا أُنشئت الأسبوع الماضي بنشر الجملة نفسها في الدقيقة ذاتها. لا توفر أي واجهة برمجة تطبيقات ذلك. لكن X يفعل.
احفظه باسم grok.py. إنه الملف الوحيد الذي يقرأ المفتاح والمكان الوحيد الذي يتحدث فيه المكتب مع xAI:
1# grok.py2# الملف الوحيد الذي يحتوي على المفتاح والمكان الوحيد الذي يتواصل فيه المكتب مع xAI.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("no XAI_API_KEY in the environment or 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 """استدعاء واحد، إدخال 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. هذا هو الملف الذي ستعيد قراءته فعليًا:
1# prompts.py2# موجه Grok الوحيد الموجود في المكتب. هذا هو الملف الذي ستعيد قراءته فعليًا.34JUDGE_PROMPT = """5أنت RUG DESK. عملة ميم كوين على Solana اجتازت للتو كل الفحوصات الصارمة في الكود:6الصلاحيات، السيولة (LP)، الحاملين، محفظة المطور، المطلعين، عمق المجمع، العمر.7لا تعد فحص تلك الأرقام. أنت تقرر ما إذا كانت تذكرة واحدة مسطحة ستدخل أم لا.8أنت لا تحدد الحجم أبدًا، ولا تختار نقاط الخروج أبدًا.910الإدخال: {"token": {...حقائق rugcheck...}, "pool": {...حقائق dexscreener...}}1112الخطوة 1. ابحث في X عن رمز التذكرة وعن عنوان العقد، خلال آخر 72 ساعة.13الخطوة 2. احكم فقط على ما لا يستطيع الكود رؤيته:14 - هل تتراكم المخاطر بمستوى التحذير لتشكل شيئًا أسوأ معًا؟15 - من نشر أولًا: المطور، حساب حقيقي له تاريخ، أم موجة من الحسابات الجديدة16 - عضوي أم مدفوع: نفس الصياغة، نفس الدقيقة، حسابات بلا ماضٍ17 - هل عنوان العقد في تلك المنشورات هو نفسه الموجود في الإدخال18 - هل ارتبط اسم هذا الرمز أو هذا المطور بعملية احتيال (rug) سابقًا1920أعِد JSON فقط:21{"verdict": "BUY" | "SKIP", "confidence": 0.0-1.0,22 "why": "سطران كحد أقصى", "x_read": "سطر واحد عن شكل X",23 "main_risk": "سطر واحد"}2425صفر منشورات على X هي إجابة: لا أحد يعرف بوجودها. تخطَّ (SKIP).26عنوان عقد آخر تحت نفس الرمز على X: خطر تقليد. تخطَّ (SKIP).27لا تجب بـ BUY أبدًا عندما يكون حقل تحتاجه فارغًا (null).28لا تذكر أهداف الأسعار أبدًا. أنت لا تعرفها.29"""
12. اربط كل شيء في أمر واحد
عنوان عقد واحد يدخل، وحكم واحد يخرج. الحدود، الحقائق، المجمع، Grok، بهذا الترتيب، وأول من يقول "لا" ينهي العملية:
1# check.py2# عنوان عقد واحد يدخل، وحكم واحد يخرج. يعمل في كل مرة تعبر فيها عملة مكتبك.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)): # الحدود، مجانية22 return {"stage": "limits", "verdict": "SKIP", "reason": g}2324 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"]}3031 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"]}3738 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}"}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"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"]}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} 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>" وسينفذ سطرًا واحدًا. ما يعود إليك يبدو هكذا (شكل مثال، وليس عملة حقيقية):
1{2 "verdict": "SKIP",3 "confidence": 0.78,4 "why": "يجتاز كل الفحوصات الصارمة، لكن أول 30 منشورًا جاءت من حسابات أُنشئت هذا الأسبوع، بنفس الصياغة.",5 "x_read": "حساب حقيقي واحد، وموجة من الحسابات الجديدة، لا يوجد تعارض في عنوان العقد",6 "main_risk": "ضجيج مدفوع، المشترون سيغادرون عند توقف النشر",7 "stage": "grok",8 "symbol": "EXAMPLE",9 "reason": "يجتاز كل الفحوصات الصارمة، لكن أول 30 منشورًا جاءت من حسابات أُنشئت هذا الأسبوع، بنفس الصياغة."10}

1الحقائق قبل الآراء. Grok لا يقرر أبدًا ما إذا كان الـ mint مفتوحًا.2الاستدعاء الفاشل هو تخطٍّ (SKIP). تعطل Rugcheck، تعطل DexScreener، تعطل Grok، JSON سيئ: تخطَّ.3الفارغ (NULL) ليس نظيفًا. الحقل الذي لم يعد يقتل العملة، ولا يمررها أبدًا.4حكم واحد لكل عملة. لا تعد التشغيل أبدًا حتى تقول BUY. إذا كنت غير موافق، فأنت غير موافق مع config.py.5اقرأ أسباب الرفض، لا عمليات الشراء. عمليات الشراء تمنحك شعورًا جيدًا. أسباب الرفض تخبرك ما إذا كان الفلتر يعمل.
13. ثلاث روتينات، جملة واحدة لكل منها
لا يوجد منشئ سير عمل. تخبر البوت بكل روتين مرة واحدة، في جملة، ويظهر لك التشغيل التالي. هذه روتيناتي، كلمة بكلمة:
1كل 10 دقائق، في /workspace/desk شغّل python watch.py.2إذا لم يطبع شيئًا، فلا تقل شيئًا. إذا طبع أي شيء، فانشره هنا كلمة بكلمة.
1كل 30 دقيقة، في /workspace/desk شغّل python scan.py.2انشر أحكام BUY فقط: الرمز، الثقة، x_read.3إذا كان Rugcheck أو DexScreener متعطلًا، قل أيهما مرة واحدة، وليس في كل تشغيل.
1كل يوم في الساعة 21:30، في /workspace/desk شغّل python report.py وانشر المخرجات هنا.2أضف شيئًا واحدًا نجح اليوم ورقمًا واحدًا في config.py قد تشكك فيه، مع السبب.3لا تغير ذلك الرقم بنفسك أبدًا.
الملفان اللذان تشغلهما هاتان الروتينتان. احفظ باسم report.py:
1# report.py2# التقرير المسائي. كل شيء فيه يأتي من checks.csv و trades.csv، لا شيء من الذاكرة.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"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. الملف المدفوع ليس إشارة جودة، بل يعني فقط أن المطور أنفق مالًا. الفلتر هو من يقرر الباقي:
1# scan.py2# مصدر فرص اختياري: عملات Solana جديدة دفعت للتو مقابل ملف تعريف على DexScreener.3# الملف المدفوع ليس إشارة جودة، بل يعني فقط أن المطور أنفق مالًا. الفلتر هو من يقرر.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]: # خمسة لكل تشغيل، حتى لا تستنزف ساعة مزدحمة واحدة ميزانية API15 subprocess.run([sys.executable, "check.py", mint])
آخر شيء الليلة: الإعدادات (Settings)، عام (General)، المراجعة التلقائية (Auto-review). أضف قاعدتين من نوع "اسأل أولًا"، فهما توقفان الإجراء وتنتظرانك بغض النظر عما تعتقده أي روتين:
1اسأل أولًا قبل أي اتصال بالمحفظة، أو توقيع، أو مبادلة، أو تحويل.2اسأل أولًا قبل تعديل أي ملف باسم config.py.


14. أسبوع وهمي قبل دولار واحد حقيقي
PAPER = True تعني أن المكتب يفعل كل شيء بشكل حقيقي باستثناء المال. عملات حقيقية، أسعار حقيقية، مخارج حقيقية، تنفيذ وهمي. بعد سبعة أيام، افتح checks.csv واقرأه وكأن شخصًا غريبًا كتبه.
ما تبحث عنه: أي فحص يرفض أكثر العملات، وهل كانت قرارات BUY هي ما كنت ستشتريه حقًا، وهل يبدو أي سبب لـ SKIP خاطئًا. التنفيذ الوهمي يحدث بسعر الشاشة، بينما التنفيذ الحقيقي لا يحدث بذلك أبدًا، لذا تعامل مع النتيجة الوهمية كسقف أعلى، وليس كتوقع.
عندما تنتقل للتداول الحقيقي، غيّر PAPER إلى False ولن يتغير شيء سوى الخطوة الأخيرة. يتوقف check.py عن الشراء وينشر سطر موافقة بدلًا من ذلك: اشترِ 25 دولارًا بنفسك في محفظتك الخاصة، ثم أمر واحد يضعها في السجل ليبدأ watch.py في حمايتها.
عندما يتعطل النظام
هذا يتعلق بالمال، لذا كل فشل له إجابة واحدة مكتوبة قبل حدوثه.
1خطأ 401 من xAI -> مفتاح سيئ. تولَّ الأمر، أعد كتابة .env، وشغّل أمر curl من الخطوة 03 مرة أخرى.2خطأ 400 / 404 من xAI -> تغير اسم النموذج. صحّح MODEL في config.py، ولا شيء آخر.3خطأ 429 من xAI -> حد معدل الاستدعاءات. تلك العملة تُتخطى (SKIP)، والتشغيل التالي يمضي قدمًا. لا تدخل في حلقة تكرار أبدًا.4خطأ بخصوص x_search -> نموذجك (MODEL) لا يمكنه البحث في X. اختر واحدًا يستطيع ذلك من console.x.ai -> Models.5إجابة Grok بنص عادي -> ValueError، يُسجل، ويُتخطى. لا تحول فقرة أبدًا إلى صفقة.6خطأ 404 أو فارغ من rugcheck -> أحدث من أن تتم فهرستها. تخطَّ. الجديد ليس نظيفًا.7lp_unlocked على كل شيء -> بعض أنواع المجمعات ليس لها رمز LP على الإطلاق. افتح واحدة على rugcheck بنفسك8 قبل أن تلمس ذلك الرقم، وغيّره كتابيًا.9no_pool -> لا يتم تداولها على DEX بعد، أو ليست على Solana. تخطَّ.10صمتت الروتينات -> يوقف Grok Bot الروتينات بعد غيابك لفترة طويلة.11 افتح Routines وأعد تشغيلها.
الفاتورة
كل شيء قبل القاضي مجاني: الحدود، Rugcheck، DexScreener. الخطوة المدفوعة الوحيدة هي استدعاء Grok واحد لكل عملة نجت من جميع الفحوصات الـ 13، مع تفعيل البحث في X.
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: 5 دولارات لكل 1000 منشور يتم جلبه45max_turns = 2 يحصر البحث في جولتين، لذا يبقى posts_fetched صغيرًا.6كل استجابة تبلغ عن x_posts_fetched الخاص بها، لذا اليوم الأول يخبرك بالرقم الحقيقي.78السعر: [السعر من console.x.ai]
الجزء الذي يخطئ فيه الناس: الفاتورة تتناسب مع العملات الناجية، وليس مع الماسح الضوئي. يمكن لـ scan.py تغذية المكتب بـ 240 عملة يوميًا ومعظمها يُرفض مجانًا قبل أن يسمع Grok عنها.

الجزء المهم
هذا إعدادي أنا، وليس استراتيجيتك أنت.
كل رقم في config.py هو رقمي، اخترته لتذكرة بقيمة 25 دولارًا ولتحملّي الشخصي لمشاهدة شيء يصل إلى الصفر. معظم عملات الميم تصل إلى الصفر، ومعظم من يتداولونها يخسرون المال. الفلتر لا يجعل العملة جيدة. إنه يزيل الطرق الواضحة للخسارة، ويجبرك على قراءة سبب رفض كل عملة.
شغّل أسبوعًا وهميًا. اقرأ حالات الرفض. حرّك الأرقام التي لا توافق عليها، كتابيًا. انسخ الهيكل، وليس الثوابت. هذه ليست نصيحة مالية.
الكود يرفض، Grok يقرأ X، وأنت توقّع. السكريبت لا يحصل أبدًا على صلاحية اتخاذ قرار تقديري، و Grok لا يحصل أبدًا على آلة حاسبة، ولا أحد سواك يحصل على المحفظة.
احفظ هذا قبل عملية شرائك القادمة. تابعني إذا كنت تخطط لتشغيل نفس الشيء، المزيد من هذا قادم 🫶
حسابي على تيليجرام - t.me/+8wAXS0nHWgA2MGEy
حسابي على جيتهاب - github.com/0xboan
تداول هنا - fomo.family/r/0xboan





