Polymarket Bot Tutorial · অধ্যায় 32 of 32

বাস্তব Polymarket bot ভুল এবং postmortems: phantom fills, sticky-fail dedup, lol-ctg-ccg whipsaw, NegRisk flag bug, premature go-live - প্রতিটি ঠিক করা commits এবং dates সহ।

এই অধ্যায়ে কী আছে

আমাদের production diary-তে থাকা এমন কিছু bug-এর কথা, যেগুলো বাস্তব টাকা খরচ করেছিল। নির্দিষ্ট ঘটনার চেয়ে pattern-টাই বেশি গুরুত্বপূর্ণ - একই ধরনের bug bot-এ বারবার ফিরে আসে, আর সমাধান সাধারণত missing watchdog, better strategy নয়। এই অধ্যায়ের উদ্দেশ্য হলো আপনার 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)

আমাদের trader-এ প্রথম বড় phantom-fill incident, মে 2025-এ। Bot 22টি FOK buy দিয়েছিল, সবগুলোই CLOB-এ matched হয়েছিল। Bot সঙ্গে সঙ্গে 22টি GTC sell post করার চেষ্টা করে। সেগুলোর মধ্যে 8টি "balance: 0 / sum of active orders: 0 / order amount: 10000000." error দিয়ে reject হয়।

Root cause: settlement lag (অধ্যায় 12)। CLOB 100ms-এ match করেছিল, bot 200ms-এ sell post করেছিল, কিন্তু Polygon ERC-1155 transfer-এ প্রায় 2 সেকেন্ড লেগেছিল। Chain-এ তখনও zero balance দেখাচ্ছিল বলে CLOB sell reject করে।

Fix: একই token-এ কোনো successful buy এবং পরের GTC follow-up-এর মধ্যে 5-second blocking wait যোগ করা হয়েছে। Commits e68a087 এবং 8bb7761। তারপর থেকে zero phantom-fill incident।

Lesson: API time এবং chain time আলাদা timeline। যেসব code এগুলোকে synchronous ধরে নেয়, সেগুলো ঠিক এই failure mode-টাই পাবে।

NegRisk flag bug (commit 06deaef)

8 candidate-সহ একটি NegRisk multi-outcome event-এ momentary arb ছিল 1.8c (sum of YES asks = 0.982)। আমাদের arber সব 8টি FOK buy fire করেছিল। এর মধ্যে 6টি filled হয়; 2টি ভুল exchange contract-এ settle হয়।

Root cause: bot flags object-এ negRisk: true সেট না করেই createAndPostOrder কল করছিল। market-এর মধ্যে 2টির historical creation date আলাদা ছিল এবং তাদের flag প্রয়োজন ছিল; বাকি 6টির প্রয়োজন ছিল না, কারণ তাদের underlying contract default-এই NegRisk দিয়ে routing হচ্ছিল।

Fix: প্রতিটি market-এর জন্য Gamma থেকে market.negRisk পড়ে প্রতিটি order call-এ pass করা। Commit 06deaef। আমরা flag set করে arb আবার চালাই; বাকি 2টিও ঠিকভাবে settle হয়।

Lesson: market property কখনো default করবেন না। প্রতিবার source of truth থেকে explicitভাবে পড়ুন।

Sticky-fail dedup (commit 4c0bef1)

Bot 12 সেকেন্ডে failed buy 5 বার retry করেছিল। প্রথম attempt আসলে সফল হয়েছিল (network timeout-এর কারণে bot response দেখতে পায়নি); পরের 4টি retry আরও 4টি additional position তৈরি করে। মোট: আমরা যেখানে 1টি চেয়েছিলাম, একই market-এ 5টি position।

Root cause: idempotent client-order-id ছিল না। Bot-এর retry logic ছিল "failed হলে, নতুন salt দিয়ে আবার চেষ্টা করো।" CLOB-এর কাছে retry-গুলোকে duplicate হিসেবে চেনার কোনো উপায় ছিল না।

Fix: প্রথম attempt-এর আগে intended order প্রতি একটি deterministic UUID generate করা। সব retry একই client-order-id ব্যবহার করে, যাতে CLOB dedup করতে পারে। Commit 4c0bef1।

Lesson: idempotence ছাড়া retry মানে duplicate। প্রতিটি order-এর একটি stable client-side identifier দরকার।

Whipsaw incident: lol-ctg-ccg

একটি esports match (CTG vs CCG)-এ imbalance positive হওয়ায় bot 0.45-এ buy enter করেছিল। 30 সেকেন্ডের মধ্যে imbalance negative হয়ে যায় এবং আমাদের GTC sell 0.50-এ অন্য কারও order দ্বারা hit হয়। PnL: +5c × 10 shares = +$0.50।

10 মিনিট পরে, একই market-এর imbalance আবার positive হয়ে যায়। Bot আবার 0.42-এ enter করে। এবার imbalance আর recover করেনি; mid drift করে 0.18-এ নামে এবং position resolution-এ 0-তে গিয়ে শেষ হয়।

Root cause: strategy-টি imbalance-কে directional signal হিসেবে দেখছিল, কিন্তু বুঝতে পারেনি যে imbalance bounce করছিল - দুটো signal-ই noise ছিল, information নয়। Bot একই market-এ 20 মিনিটের মধ্যে দুইটি failed signal-এর মধ্যে whipsaw হয়ে যায়।

Fix: প্রতি market-এ cooldown - fill-এর পরে একই market-এ 30 মিনিট নতুন entry নয়। Different market-এ multiple entry allowed ছিল, কিন্তু একই market-এ back-to-back নয়।

Lesson: যে signal bounce করে, সেটা signal নয়। Act করার আগে persistence filter করুন।

Premature go-live: 2025 wipe

একটি নতুন market-making strategy 12টি paper trade পাস করেছিল। Builder 30 পর্যন্ত অপেক্ষা করেনি, "ভালোই লাগছে" ধরে live deploy করে দেয় $500 capital দিয়ে। 18 ঘণ্টার মধ্যে wallet $200-এ নেমে আসে।

Root cause: 12টি trade 60% WR আর 35% WR আলাদা করতে যথেষ্ট sample নয়। Strategy-টি বাস্তবে 35% WR ছিল; 12-trade paper window-তে কেবল একটি unrepresentative streak পড়ে গিয়েছিল।

30-trade gate একটি কারণেই আছে। 12-trade sample-এর variance এটাকে "strategy কাজ করছে না" - এর থেকে আলাদা করা যায় না।

Lesson: conviction-এর চেয়ে discipline জিতবে। 30-trade gate negotiable নয়।

Sleep-through-bug: kill switch worked

Bot-এর time-of-day filter-এ off-by-one bug ছিল - 02:00 UTC-এ pause করার কথা, কিন্তু আসলে 03:00 UTC-এ pause করছিল। 02:00-03:00 un-paused hour-এ Polygon RPC আমাদের request অনেক বেশি rate-limit করছিল; bot-এর read path stale data ফেরত দিচ্ছিল।

Bot stale price নিয়ে trading চালিয়ে যাচ্ছিল। Hour-এর PnL: 22টি trade জুড়ে -$3.20। Daily-loss kill switch -5%-এ trigger হয়, bot halt করে, 03:08 UTC-এ Telegram alert পাঠায়। Builder 09:00-এ উঠে দেখে bot halted, মোট ক্ষতি kill threshold-এ সীমাবদ্ধ।

Lesson: bug real ছিল, কিন্তু kill switch কাজ করেছে। -$3.20, -$50.00 নয়। Risk control bug আটকায় না; আপনি যেসব bug দেখতে পাননি, সেগুলোর cost সীমাবদ্ধ করে।

Lessons that generalize

সব postmortem জুড়েই চারটি pattern বারবার দেখা যায়।

  1. API time ≠ chain time. Settlement lag, RPC lag, WebSocket lag - এগুলো সবই gap তৈরি করে, যেগুলো 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 control bug-এর ক্ষতি cap করে। Strategy bug prevent করে না; ধরে নেয় bot ঠিকমতো কাজ করছে। Bot সবসময় ঠিকমতো কাজ করবে না।

এই সিরিজের প্রতিটি অধ্যায়ের কোথাও না কোথাও এই patternগুলোর একটি embedded আছে। এগুলোই production bot-এর load-bearing principle। এগুলো বাদ দিলে নিজের postmortem-এ এগুলো আবার খুঁজে পাবেন।

প্রায়শই জিজ্ঞাসিত প্রশ্ন

সবচেয়ে ব্যয়বহুল Polymarket bot ভুল কী?
30-trade gate পূরণের আগেই live-এ যাওয়া। আমরা এটা করেছি। ভুলটা শুধু টাকা হারানো নয় - controlled environment-এ strategy থেকে শেখার সুযোগ হারানোও। খুব তাড়াতাড়ি live হওয়া bot-গুলো হয় nuked হয়ে abandon হয়, নয়তো re-paper-trading-এর আগে মাসের পর মাস recovery-তে নষ্ট করে।
phantom fill bug কী?
যখন bot মনে করে order fill হয়েছে, কিন্তু exchange সেটিকে এখনও filled হিসেবে রেকর্ড করেনি। লক্ষণ: আপনার bot state-এ position দেখা যায়, কিন্তু on-chain নয়, ফলে retry-তে double-order তৈরি হয়। আমাদের trader-এ তিনটি commit (e68a087, 8bb7761, 06deaef) দিয়ে fix করা হয়েছে: buy-এর জন্য FOK ব্যবহার করুন, matched হওয়া পর্যন্ত status poll করুন, delayed status-কে কখনো filled বলে বিশ্বাস করবেন না।
lol-ctg-ccg whipsaw incident কী?
পাতলা order book-এ একটি esports market, যেখানে আমাদের trader 0.14-এ -$2.55 stop-loss fire করেছিল, তারপর 2 মিনিটের মধ্যে price 0.325-এ recover হতে দেখেছিল। আমরা stop-loss -4 percentage points-এ সেট করেছিলাম, যা পাতলা esports book-এর জন্য খুবই tight। Fix: low-liquidity market-এর জন্য SL -8pp-এ widen করা হয়েছে, আর tight SL শুধু thick book (NBA, high-liquidity soccer)-এর জন্য রাখা হয়েছে। দেখুন memory/trader-sl-wider.md।
NegRisk flag bug কীভাবে প্রকাশ পেয়েছিল?
Bot multi-outcome market-এ neg_risk=true সেট না করেই order দিয়েছিল। Order confusing error message দিয়ে reject হয়, retry-এর আগে multi-second delay হয়, ফলে fill miss হয়। Commit 06deaef-এ fix: market metadata অনুযায়ী সবসময় neg_risk set করুন, কখনো assume করবেন না।
sleep-through-bug incident কী ছিল?
ভোর 4টায় wallet একটি stuck order দিয়ে wedged হয়ে গিয়েছিল। Owner bot-কে halt করার নির্দেশ দেয়; data/halt_autobuy file ছোঁয়া হয়। Bot পরের trade attempt-এর আগে file detect করে order place করতে অস্বীকার করে। Owner ঘুম থেকে উঠে clean state দেখে, খারাপ অবস্থার বদলে। halt-sentinel pattern validate হয়েছে; এখন আমরা এটা প্রতিটি bot-এ default হিসেবে ship করি।
এই postmortem-গুলোর মধ্যে সবচেয়ে generalizable একক lesson কী?
happy path-কে কখনো বিশ্বাস করবেন না। আমরা যেসব bug ship করেছি, সেগুলোর সবই এসেছে এই ধরে নেওয়া থেকে যে request succeed করেছে, fill real ছিল, বা price নড়বে না। Defensively code করুন: ধরে নিন order fail করবে, reconciliation diverge করবে, কোনো market অদ্ভুত কিছু করতে চলেছে। paranoia tax ছোট; এটা বাদ দেওয়ার খরচ হলো পরে লেখা আপনার postmortem।