Polymarket Bot Tutorial · Chapter 32 of 32

حقیقی Polymarket bot کی غلطیاں اور postmortems: phantom fills، sticky-fail dedup، lol-ctg-ccg whipsaw، NegRisk flag bug، قبل از وقت go-live - ان commits اور dates کے ساتھ جنہوں نے ہر مسئلہ ٹھیک کیا۔

اس chapter میں کیا شامل ہے

ہماری اپنی production diary of bugs جو حقیقی پیسہ لے گئے۔ اصل چیز specific details سے زیادہ pattern ہے - bug کی وہی classes bots میں بار بار آتی ہیں، اور علاج عموماً کوئی missing watchdog ہوتا ہے، نہ کہ بہتر strategy۔ اس chapter کا مقصد آپ کی tuition بچانا ہے۔

  • Phantom fills (commits e68a087, 8bb7761)
  • NegRisk flag bug (commit 06deaef)
  • Sticky-fail dedup (commit 4c0bef1)
  • Whipsaw incident: lol-ctg-ccg
  • Premature go-live: 2025 wipe
  • Sleep-through-bug: kill switch worked
  • Lessons that generalize

Phantom fills (commits e68a087, 8bb7761)

May 2025 میں ہمارے trader پر پہلا بڑا phantom-fill incident۔ Bot نے 22 FOK buys place کیے، اور سب CLOB پر matched ہو گئے۔ Bot نے فوراً 22 GTC sells post کرنے کی کوشش کی۔ ان میں سے 8 نے "balance: 0 / sum of active orders: 0 / order amount: 10000000." کے ساتھ reject کر دیا۔

Root cause: settlement lag (chapter 12). CLOB نے 100ms میں match کیا، bot نے 200ms میں sell post کر دی، لیکن Polygon ERC-1155 transfer میں تقریباً 2 seconds لگے۔ CLOB نے sell reject کر دی کیونکہ chain پر ابھی تک zero balance دکھ رہا تھا۔

Fix: کسی بھی successful buy اور اسی token پر آنے والی GTC follow-up کے درمیان 5-second blocking wait insert کریں۔ Commits e68a087 اور 8bb7761۔ تب سے zero phantom-fill incidents۔

Lesson: API time اور chain time دو مختلف timelines ہیں۔ جو code یہ assume کرے کہ یہ synchronous ہیں، وہ اسی exact failure mode سے ٹکرائے گا۔

NegRisk flag bug (commit 06deaef)

8 candidates والے NegRisk multi-outcome event میں 1.8c کا momentary arb تھا (sum of YES asks = 0.982)۔ ہمارے arber نے 8 کے 8 FOK buys fire کیے۔ 6 fill ہو گئے؛ 2 غلط exchange contract میں settle ہو گئے۔

Root cause: bot createAndPostOrder call کر رہا تھا مگر flags object میں negRisk: true set نہیں کر رہا تھا۔ دو markets کی historical creation date مختلف تھی اور انہیں flag کی ضرورت تھی؛ باقی چھ کو اس کی ضرورت نہیں تھی کیونکہ ان کا underlying contract پہلے ہی default طور پر NegRisk کے ذریعے route ہو رہا تھا۔

Fix: ہر market کے لیے Gamma سے market.negRisk پڑھیں، اور ہر order call میں pass کریں۔ Commit 06deaef۔ ہم نے flag set کر کے arb دوبارہ run کیا؛ باقی 2 درست طریقے سے settle ہو گئے۔

Lesson: کبھی بھی market property کو default نہ کریں۔ ہر بار source of truth سے explicitly پڑھیں۔

Sticky-fail dedup (commit 4c0bef1)

Bot نے 12 seconds میں failed buy کو 5 بار retry کیا۔ پہلی attempt دراصل succeed ہو گئی تھی (network timeout کی وجہ سے bot response نہ دیکھ سکا)؛ اگلے 4 retries نے 4 اضافی positions create کر دیں۔ Total: اسی market پر 5 positions جب ہمیں 1 چاہیے تھی۔

Root cause: idempotent client-order-id موجود نہیں تھا۔ Bot کی retry logic یہ تھی: "اگر fail ہوا، تو نئے salt کے ساتھ دوبارہ کوشش کرو۔" CLOB کے پاس retries کو duplicates سمجھنے کا کوئی طریقہ نہیں تھا۔

Fix: پہلی attempt سے پہلے intended order کے لیے deterministic UUID generate کریں۔ تمام retries same client-order-id استعمال کریں، تاکہ CLOB dedup کر سکے۔ Commit 4c0bef1۔

Lesson: idempotence کے بغیر retries، duplicates ہیں۔ ہر order کے لیے ایک stable client-side identifier چاہیے۔

Whipsaw incident: lol-ctg-ccg

ایک esports match (CTG vs CCG) میں imbalance positive ہوتے ہی bot نے 0.45 پر buy enter کی۔ 30 seconds کے اندر imbalance negative ہو گیا اور 0.50 پر ہماری GTC sell کسی اور کے order سے hit ہو گئی۔ PnL: +5c × 10 shares = +$0.50۔

10 minutes بعد اسی market کا imbalance پھر positive ہو گیا۔ Bot نے دوبارہ 0.42 پر entry لی۔ اس بار imbalance recover نہیں ہوا؛ mid 0.18 تک drift کر گیا اور position resolution تک 0 پر چلی گئی۔

Root cause: strategy نے imbalance کو directional signal سمجھا، مگر یہ track نہیں کیا کہ imbalance bounce کر رہا تھا - دونوں signals noise تھے، information نہیں۔ Bot ایک ہی market میں 20 minutes کے اندر دو failed signals کے درمیان whipsaw ہو گیا۔

Fix: ہر market کے لیے cooldown - fill کے بعد اسی market میں 30 minutes تک کوئی نئی entry نہیں۔ مختلف markets میں multiple entries allowed تھیں، مگر ایک ہی market میں back-to-back نہیں۔

Lesson: جو signal bounce کرے، وہ signal نہیں۔ عمل کرنے سے پہلے persistence کے لیے filter کریں۔

Premature go-live: 2025 wipe

ایک نئی market-making strategy نے 12 paper trades پاس کیں۔ Builder نے 30 کا انتظار نہیں کیا، "looking good" سمجھا، اور $500 capital کے ساتھ live deploy کر دیا۔ 18 hours کے اندر wallet $200 پر آ گیا۔

Root cause: 12 trades اتنا sample نہیں کہ 60% WR اور 35% WR میں فرق کیا جا سکے۔ اصل میں strategy 35% WR تھی؛ 12-trade paper window بس ایک غیر نمائندہ streak نکلی۔

30-trade gate ایک وجہ سے موجود ہے۔ 12-trade sample کی variance اسے "strategy کام نہیں کرتی" سے الگ پہچاننا مشکل بنا دیتی ہے۔

Lesson: discipline، conviction سے بہتر ہے۔ 30-trade gate پر سمجھوتہ نہیں کیا جا سکتا۔

Sleep-through-bug: kill switch worked

Bot کے time-of-day filter میں off-by-one تھا - 02:00 UTC پر pause کرنا تھا، مگر اصل میں 03:00 UTC پر pause ہو رہا تھا۔ 02:00-03:00 کے un-paused hour کے دوران Polygon RPC ہماری requests کو بہت زیادہ rate-limit کر رہا تھا؛ bot کا read path stale data واپس کر رہا تھا۔

Bot stale prices پر trade کرتا رہا۔ اس hour کا PnL: 22 trades پر -$3.20۔ daily-loss kill switch -5% پر trigger ہوا، bot کو halt کیا، اور 03:08 UTC پر Telegram alert بھیجی۔ Builder 09:00 پر ایک halted bot پر جاگا؛ total damage kill threshold تک محدود رہا۔

Lesson: bug real تھا مگر kill switch نے کام کیا۔ -$3.20، -$50.00 کے بجائے۔ Risk controls bugs کو prevent نہیں کرتے؛ وہ ان bugs کی cost cap کرتے ہیں جنہیں آپ نے آتے ہوئے نہیں دیکھا۔

Lessons that generalize

تمام postmortems میں چار patterns بار بار آتے ہیں۔

  1. API time ≠ chain time. Settlement lag، RPC lag، WebSocket lag - یہ سب gaps introduce کرتے ہیں جنہیں bot code کو explicitly handle کرنا چاہیے۔
  2. Retries need idempotence. Client-order-id کے بغیر retry duplicate-order risk ہے۔ ہمیشہ۔
  3. ہر market property explicitly پڑھیں. NegRisk flag، tick size، expiration۔ کبھی default نہ کریں؛ ہمیشہ source of truth سے پڑھیں۔
  4. Kill switch floor ہے، feature نہیں. Risk controls bugs پر losses cap کرتے ہیں۔ Strategies bugs prevent نہیں کرتیں؛ وہ assume کرتی ہیں کہ bot درست کام کر رہا ہے۔ Bot ہمیشہ درست کام نہیں کرے گا۔

اس series کے ہر chapter میں ان میں سے کوئی نہ کوئی pattern کہیں نہ کہیں embedded ہے۔ یہ production bot کے load-bearing principles ہیں۔ انہیں skip کریں، اور آپ انہیں اپنی postmortems میں پھر سے دیکھیں گے۔

اکثر پوچھے جانے والے سوالات

Polymarket bot کی سب سے مہنگی غلطی کیا ہے؟
Paper-trading کے 30-trade gate تک پہنچنے سے پہلے live ہو جانا۔ ہم نے یہ کیا ہے۔ غلطی صرف پیسہ کھونا نہیں ہے - controlled environment میں strategy سے سیکھنے کا موقع بھی کھو دینا ہے۔ جو bots بہت جلد live ہو جاتے ہیں وہ یا تو nuked ہو کر چھوڑ دیے جاتے ہیں، یا دوبارہ paper-trading سے پہلے مہینوں recovery میں ضائع کرتے ہیں۔
Phantom fill bug کیا ہے؟
جب bot سمجھتا ہے کہ order fill ہو گیا ہے مگر exchange نے اسے ابھی fill نہیں کیا ہوتا۔ علامات: position bots state میں دکھائی دیتی ہے مگر on-chain نہیں، جس سے retry پر double-orders بن جاتے ہیں۔ ہمارے trader میں تین commits (e68a087, 8bb7761, 06deaef) کے ذریعے fix ہوا: buys کے لیے FOK استعمال کریں، status matched ہونے تک poll کریں، اور کبھی status=delayed کو filled نہ سمجھیں۔
lol-ctg-ccg whipsaw incident کیا ہے؟
ایک thin order book والا esports market جہاں ہمارے trader نے 0.14 پر -$2.55 stop-loss fire کیا، پھر 2 minutes کے اندر price کو 0.325 تک recover ہوتے دیکھا۔ ہم نے stop-loss کو -4 percentage points پر configure کیا تھا، جو thin esports books کے لیے بہت tight ہے۔ Fix: low-liquidity markets کے لیے SL کو -8pp تک widen کیا، اور tighter SL صرف thick books (NBA، high-liquidity soccer) کے لیے رکھا۔ دیکھیں memory/trader-sl-wider.md۔
NegRisk flag bug کیسے ظاہر ہوا؟
Bot نے multi-outcome markets پر neg_risk=true set کیے بغیر orders place کیں۔ Orders confusing error messages کے ساتھ reject ہوئیں، جس سے retry سے پہلے multi-second delays آئیں، اور fills miss ہو گئے۔ Commit 06deaef میں fix: ہمیشہ market metadata کے مطابق neg_risk set کریں، کبھی assume نہ کریں۔
Sleep-through-bug incident کیا تھا؟
Wallet 4am پر stuck order کے ساتھ wedged ہو گیا تھا۔ Owner نے bot کو halt کرنے کی ہدایت دی؛ data/halt_autobuy file کو touch کیا۔ Bot نے next trade attempt سے پہلے file detect کی اور orders place کرنے سے انکار کر دیا۔ Owner بہتر حالت کے بجائے صاف state پر جاگا۔ halt-sentinel pattern validate ہوا؛ اب ہم اسے ہر bot میں default طور پر ship کرتے ہیں۔
ان postmortems سے ایک سب سے generalizable lesson کیا ہے؟
Happy path پر کبھی trust نہ کریں۔ ہم نے جو بھی bug ship کیا، وہ اس assumption سے آیا کہ request succeed ہو گئی، fill real تھا، یا price move نہیں کرے گا۔ Defensive code لکھیں: assume کریں orders fail ہوں گے، reconciliations diverge ہوں گی، کوئی نہ کوئی market کچھ عجیب کرنے والا ہے۔ Paranoia tax کم ہے؛ اسے skip کرنے کی cost بعد میں لکھا جانے والا postmortem ہے۔