آموزش Polymarket Bot · فصل 30 از 32
کد production-grade برای مدیریت ریسک در botهای Polymarket: position cap، daily loss limit، halt sentinel، fill-rate watchdog، reconcile-on-restart، retryهای idempotent. الگوهای کدنویسی از یک real production trader.
این فصل چه چیزهایی را پوشش میدهد
کد risk بیشترِ یک trading bot production است. منطق strategy بخش سادهتر ماجراست؛ capها، haltها، watchdogها و reconcilerها هستند که تعیین میکنند bot از اولین هفته بدش جان سالم به در میبرد یا نه. این فصل الگوی risk در سطح production است.
- چرا کد risk بخش اصلی یک real trading bot است
- Position capها (per-market، per-strategy، total)
- Daily loss kill switch
- Halt sentinelها (emergency stop مبتنی بر فایل)
- Fill-rate watchdog
- Reconcile کردن diary با on-chain هنگام restart
- Code: production-grade halt-aware loop
چرا کد risk بخش اصلی یک real trading bot است
یک اندازهگیری که روی codebase bot خودمان انجام دادیم: 60% از LOC مربوط به کد risk است (capها، haltها، watchdogها، reconciliation). 30% strategy است. 10% glue است.
این نسبت درست است. Strategy بخش ساده ماجراست - توضیح اینکه چه زمانی وارد شویم و چه زمانی خارج شویم، در چند ده خط جا میشود. کد risk همه چیزِ دیگر است: وقتی قیمت سریعتر از انتظار علیه شما حرکت میکند چه باید کرد، وقتی fillها دیگر انجام نمیشوند چه باید کرد، وقتی WebSocket قطع میشود چه باید کرد، وقتی معلوم میشود strategy سودآور نیست چه باید کرد.
بیشتر داستانهای شکست builderها شکل مشابهی دارند: strategy کار میکرد، اما bot بهخاطر نبودن halt در مواجهه با تغییر regime همچنان معامله میکرد. haltها را قبل از strategy بنویسید.
Position capها (per-market، per-strategy، total)
سه cap که در code enforce میشوند.
- Per-market cap: حداکثر $X برای هر market، صرفنظر از confidence در edge. معمولاً: $25-100 برای botهای کوچک، $200-500 برای production. این cap دامنه آسیبِ یک تصمیم اشتباه در یک market را محدود میکند.
- Per-strategy cap: اگر چند strategy را اجرا میکنید، هرکدام سهمی از total capital میگیرند. معمولاً: 30-50% برای هر strategy. اجازه نمیدهد روز بدِ یک strategy سرمایه بقیه را مصرف کند.
- Total cap: حداکثر درصدی از wallet balance که همزمان deploy شده است. معمولاً: 50-70%. سرمایهای برای فرصتهای غیرمنتظره یا برای گرفتن خطاهای bookkeeping خود bot باقی میگذارد.
هر سه cap باید داخل order-placement function enforce شوند، نه فقط در منطق strategy. strategy ممکن است bug داشته باشد؛ gate مربوط به order-placement آخرین خط دفاعی است.
Daily loss kill switch
مهمترین کنترل ریسک منفرد: یک daily-loss kill switch.
قانون: اگر realized + unrealized PnL از نیمهشب UTC پایینتر از -X% از starting daily balance بیاید، bot دیگر position جدید باز نمیکند و (در صورت نیاز) positionهای موجود را flat میکند. X معمولاً 5-10% است.
ریاضی ماجرا: botی با win rate مورد انتظار 60% شاید 5% احتمال داشته باشد که 10 معامله پشتسرهم ببازد. بدون kill switch، این باختها روی هم جمع میشوند: $200 ضرر → bot به معامله ادامه میدهد → $200 ضرر دیگر → wallet 40% پایین میآید. با فعال شدن switch در -10%، روز بد در $200 محدود میشود و فردا bot با شرایط تازه شروع میکند.
این switch باید server-side enforce شود: یک halt file بنویسید یا database flag را تنظیم کنید که trading loop در هر iteration آن را چک کند. فقط بعد از manual review دوباره restart کنید.
Halt sentinelها (emergency stop مبتنی بر فایل)
سادهترین مکانیزم halt ممکن: bot در هر iteration حلقه فایل مشخصی را بررسی میکند (مثلاً /opt/pmt/HALT) و اگر فایل وجود داشته باشد، trading را متوقف میکند.
def trading_loop():
while True:
if os.path.exists("/opt/pmt/HALT"):
log("HALT file detected, sleeping")
time.sleep(30)
continue
run_one_iteration()
time.sleep(5)
برای halt فوری از هرجا (SSH، Telegram bot، یا یک monitoring system): touch /opt/pmt/HALT. برای resume: rm /opt/pmt/HALT.
رویکرد مبتنی بر فایل عمداً low-tech است، چون در شرایطی که مکانیزمهای پیچیدهتر halt شکست میخورند کار میکند: وقتی bot نیمه-crash شده، وقتی database در دسترس نیست، وقتی API key rate-limited شده است. دسترسی به file-system همیشه در دسترس است.
Fill-rate watchdog
Strategy فرض میکند orderهای FOK با یک نرخ مشخص fill میشوند (اغلب 60-80%). وقتی این نرخ بهطور محسوس افت میکند، یعنی چیزی عوض شده: market makerها کنار کشیدهاند، strategy شما شناسایی شده، یا یک API outage در جریان است. هر دلیل که داشته باشد، فرضی که محاسبه PnL strategy را جلو میبرده، دیگر درست نیست.
منطق watchdog: شمارش rolling 24-hour fill-rate. اگر < 30% باشد (یا 50% از مقدار expected)، alert + auto-halt. فقط بعد از manual review resume شود.
Watchdog همچنین برای diagnosis مفید است. افت ناگهانی fill-rate معمولاً با یک event بیرونی همبستگی دارد (Polymarket deploy، congestion در Polygon، rate-limited شدن IP شما) که صرفنظر از اثرش روی trading، بهتر است از آن باخبر باشید.
Reconcile کردن diary با on-chain هنگام restart
Bot یک diary از positionهایی که فکر میکند دارد نگه میدارد. Chain حقیقت را نگه میدارد. این دو باید همیشه با هم منطبق باشند؛ وقتی نیستند، bot بر اساس یک باور اشتباه کار میکند و اشتباه trade خواهد کرد.
منطق reconciliation: در هر restart و هر یک ساعت در طول عملیات عادی، on-chain balances همه tokenهایی را که bot با آنها درگیر بوده fetch کنید. آنها را با diary مقایسه کنید؛ اگر balance هر token بیش از tolerance مربوط به rounding تفاوت داشت، alert + halt کنید.
رایجترین علت divergence این است که یک order موفق شده اما API call bot آن را از دست داده است (timeout، یا retryیی که هیچوقت ثبت نشده). chain position را دارد؛ bot فکر میکند ندارد. بدون reconciliation، bot خروج take-profit را ثبت نمیکند و position تا زمان resolution باقی میماند.
Code: production-grade halt-aware loop
Reference: trading loop production با تمام کنترلهای risk که به آن متصل شدهاند.
def production_loop():
while True:
# Halt checks
if os.path.exists("/opt/pmt/HALT"):
sleep_with_log(30); continue
if daily_pnl_below_threshold():
create_halt("daily PnL kill"); continue
# Reconcile every hour
if now() - last_reconcile > 3600:
ok = reconcile_diary_vs_chain()
last_reconcile = now()
if not ok: create_halt("reconciliation failed"); continue
# Fill-rate watchdog
if recent_fill_rate() < 0.30:
create_halt("fill rate collapse"); continue
# Strategy
try:
run_strategy_once()
except Exception as e:
log_exception(e)
if consecutive_exceptions >= 5:
create_halt(f"exceptions: {e}"); continue
time.sleep(5)
الگو این است: هر iteration از gate عبور میکند. با طراحی درست، bugهای strategy نمیتوانند از کنترلها عبور کنند.





