پولی مارکیٹ بوٹ ٹیوٹوریل · 32 میں سے باب 32
حقیقی پولی مارکیٹ bot کی غلطیاں اور postmortems: phantom fills، sticky-fail dedup، lol-ctg-ccg whipsaw، NegRisk flag bug، قبل از وقت go-live - ان commits اور dates کے ساتھ جنہوں نے ہر مسئلہ ٹھیک کیا۔
اس باب میں کیا شامل ہے
ہماری اپنی production diary of bugs جو حقیقی پیسہ لے گئے۔ اصل چیز specific details سے زیادہ pattern ہے - bug کی وہی classes bots میں بار بار آتی ہیں، اور علاج عموماً کوئی missing watchdog ہوتا ہے، نہ کہ بہتر strategy۔ اس chapter کا مقصد آپ کی tuition بچانا ہے۔
- فینٹم فِلز (commits e68a087، 8bb7761)
- NegRisk flag bug (commit)
- Sticky-fail dedup (commit)
- وہپ سا واقعہ: lol-ctg-ccg
- قبل از وقت لائیو ہونا: 2025 wipe
- نیند میں گزر جانے والا bug: کِل سوئچ نے کام کیا
- وہ اسباق جو عام طور پر لاگو ہوتے ہیں
فینٹم فِلز (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)
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۔ ہم نے flag set کر کے arb دوبارہ run کیا؛ باقی 2 درست طریقے سے settle ہو گئے۔
Lesson: کبھی بھی market property کو default نہ کریں۔ ہر بار source of truth سے explicitly پڑھیں۔
Sticky-fail dedup (commit)
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۔
Lesson: idempotence کے بغیر retries، duplicates ہیں۔ ہر order کے لیے ایک stable client-side identifier چاہیے۔
وہپ سا واقعہ: 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 کریں۔
قبل از وقت لائیو ہونا: 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 پر سمجھوتہ نہیں کیا جا سکتا۔
نیند میں گزر جانے والا bug: کِل سوئچ نے کام کیا
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 کرتے ہیں جنہیں آپ نے آتے ہوئے نہیں دیکھا۔
وہ اسباق جو عام طور پر لاگو ہوتے ہیں
تمام postmortems میں چار patterns بار بار آتے ہیں۔
- API time ≠ chain time. Settlement lag، RPC lag، WebSocket lag - یہ سب gaps introduce کرتے ہیں جنہیں bot code کو explicitly handle کرنا چاہیے۔
- Retries need idempotence. Client-order-id کے بغیر retry duplicate-order risk ہے۔ ہمیشہ۔
- ہر market property explicitly پڑھیں. NegRisk flag، tick size، expiration۔ کبھی default نہ کریں؛ ہمیشہ source of truth سے پڑھیں۔
- 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 میں پھر سے دیکھیں گے۔


