پولی مارکیٹ بوٹ ٹیوٹوریل · 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 بار بار آتے ہیں۔

  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 میں پھر سے دیکھیں گے۔

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

پولی مارکیٹ 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 میں 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 ہے۔