Self-Match Prevention ও Wash Trade আইন
Self-match prevention কীভাবে matching engine-এ একই প্রতিষ্ঠানের অর্ডারের সংঘর্ষ ঠেকায়, আর কোন পর্যায়ে wash trade আইন প্রযোজ্য হয় তা জানুন।
Self-match prevention হলো matching engine-এর একটি ফিচার, যা একই প্রতিষ্ঠানের দুটি অর্ডারকে পরস্পরের সঙ্গে ট্রেড করা থেকে আটকায়। অর্ডার পাঠানোর সময় প্রতিটির সঙ্গে একটি identifier যুক্ত থাকে। একই identifier-যুক্ত দুটি অর্ডার পরস্পরের বিপরীতে গেলে, কোনো trade print হওয়ার আগেই engine একটি অর্ডার বা উভয় অর্ডার cancel করে। Self-match prevention হলো venue-এর একটি plumbing ব্যবস্থা, যা আপনি চালু করেন। অন্যদিকে wash trade নিষিদ্ধ করা আইনগত বিষয়। দুটির আওতা এক নয়।
আপনার প্রথম strategy যে instrument-এ quote দিচ্ছে, দ্বিতীয় strategy সেই instrument-এ quote দেওয়ার সঙ্গে সঙ্গেই এই নিয়ম আপনার ক্ষেত্রে প্রযোজ্য হয়। একটি symbol-এ দুই-ধাপের grid bot চালালেও ব্যাংকের trading desk-এর মতো একই নিয়মের মুখোমুখি হতে হয়।
Matching engine-এ self-match prevention কীভাবে কাজ করে
কোনো venue যে অর্ডার গ্রহণ করে, matching-এর আগে engine সেটির কয়েকটি field পড়ে: side, price, size, time in force। Self-match prevention আরও দুটি field যোগ করে। প্রথমটি হলো identifier—একটি সংখ্যা বা string, যা বলে অর্ডারটি কোন firm, account বা strategy group-এর অন্তর্ভুক্ত। দ্বিতীয়টি হলো একটি instruction, যা জানায় একই identifier-যুক্ত দুটি সক্রিয় অর্ডার পরস্পরের সঙ্গে ট্রেড করতে গেলে engine কী করবে।
কোনো aggressing order এমন দামে পৌঁছানোর মুহূর্তে এই পরীক্ষা চলে, যে দামে সেটি একটি resting order-এর সঙ্গে match করতে পারে। সাধারণত চারটি ফল দেখা যায়:
- Resting order cancel করা। Incoming order book-এ এগিয়ে যায় এবং ওই দামে তার পেছনে থাকা অর্ডারের সঙ্গে match করতে পারে।
- Incoming order cancel করা। Resting order তার queue position ধরে রাখে এবং aggressor অর্ডারটি অদৃশ্য হয়ে যায়।
- উভয় অর্ডার cancel করা। এটি সবচেয়ে কঠোর setting।
- Decrement and cancel। বড় অর্ডারটি ছোট অর্ডারের size অনুযায়ী কমে যায়, ছোট অর্ডারটি cancel হয় এবং অবশিষ্ট অংশ সক্রিয় থাকে।
চার ক্ষেত্রেই কোনো trade হয় না। Tape-এ কোনো print দেখা যায় না, fill log-এ কিছু যায় না। এর পরিবর্তে একটি leg বা দুটি leg-এ unsolicited cancel আসে।
Queue position হলো এর নীরব খরচ। cancel-oldest instruction-এর অধীনে কোনো resting order cancel হলে অপেক্ষা করে অর্জন করা সব সুবিধা হারায়। price-time priority-এর অধীনে এই ক্ষতি সম্পূর্ণ: order-টি পুনরায় পাঠালে অপেক্ষার সময় queue-তে যোগ দেওয়া সবার পেছনে চলে যায়। আমাদের queue position মূল্যায়নের নির্দেশিকা দেখায়, সারিতে ওই অবস্থানের মূল্য কত।
একটি instrument, বহু order book
এই পরীক্ষা venue-ভিত্তিক। একটি engine কেবল তার নিজের কাছে থাকা অর্ডারগুলোর তুলনা করে। দুটি ভিন্ন book-এ resting থাকা আপনার দুটি order একে অপরের কাছে অদৃশ্য থাকে। কোনো US equities mechanism-ও এই দুই book-এর মধ্যে পৌঁছায় না। একটি US stock একই সময়ে বহু book-এ quote হতে পারে। নিচের panel-এ June 10, 2026-এর সকালে একটানা fifteen minute window-তে ছয়টি বহুল পরিচিত নামের জন্য আলাদা quoting এবং printing venue-এর সংখ্যা দেখানো হয়েছে।
প্রতিটি সংখ্যার পেছনের সঠিক SQL
SELECT
q.ticker AS ticker,
q.quoting_venues AS quoting_venues,
t.printing_venues AS printing_venues
FROM
(
SELECT
ticker,
countDistinct(bid_exchange) AS quoting_venues
FROM global_markets.cache_stocks_quotes
WHERE ticker IN ('AAPL', 'MSFT', 'NVDA', 'SPY', 'KO', 'JNJ')
AND sip_timestamp >= toDateTime('2026-06-10 14:00:00', 'UTC')
AND sip_timestamp < toDateTime('2026-06-10 14:15:00', 'UTC')
AND bid_price > 0
GROUP BY ticker
) AS q
INNER JOIN
(
SELECT
ticker,
countDistinct(exchange) AS printing_venues
FROM global_markets.stocks_trades
WHERE ticker IN ('AAPL', 'MSFT', 'NVDA', 'SPY', 'KO', 'JNJ')
AND sip_timestamp >= toDateTime('2026-06-10 14:00:00', 'UTC')
AND sip_timestamp < toDateTime('2026-06-10 14:15:00', 'UTC')
GROUP BY ticker
) AS t ON t.ticker = q.ticker
ORDER BY quoting_venues DESC, tickerওই quarter hour-এ AAPL-এ 16টি আলাদা venue থেকে bid এসেছিল এবং 17টি venue-এ prints হয়েছিল। Panel-এর সবচেয়ে thinly traded নামটিও 11টি quoting venue থেকে bid পেয়েছিল। Smart order router নকশাগতভাবে child order ভাগ করে পাঠালে বেশিরভাগ সময় আপনার দুটি strategy ভিন্ন book-এ চলে যাবে। তখন engine-level check প্রযোজ্য হবে না। Firm-গুলো building-এর বাইরে order পাঠানোর আগেই order management layer-এ upstream-এ এই ব্যবধান বন্ধ করে। একই দামে দুটি book-এ বিপরীত পাশে resting থাকা আপনার নিজের order-গুলো locked বা crossed market-ও তৈরি করতে পারে। এর জন্য আলাদা কিছু নিয়ম প্রযোজ্য।
একটি session-এ এক book কতগুলি match করে
Engine যে প্রতিটি match করে, self-match check তার পথের মধ্যেই থাকে। কোনো liquid name-এ এই পথ সারা দিন সক্রিয় থাকে। নিচের panel-এ একটি stock-এর পুরো session-কে fifteen minute slice-এ ভাগ করে প্রতিটিতে print-এর সংখ্যা গণনা করা হয়েছে। কেবল অন্তত 200টি print থাকা slice রাখা হয়েছে।
প্রতিটি সংখ্যার পেছনের সঠিক SQL
SELECT
formatDateTime(toStartOfInterval(toTimeZone(sip_timestamp, 'America/New_York'), INTERVAL 15 MINUTE), '%H:%i') AS et_time,
count() AS trade_count
FROM global_markets.stocks_trades
WHERE ticker = 'AAPL'
AND sip_timestamp >= toDateTime('2026-06-10 08:00:00', 'UTC')
AND sip_timestamp < toDateTime('2026-06-11 04:00:00', 'UTC')
GROUP BY et_time
HAVING count() >= 200
ORDER BY et_time04:00 ET-এ ওই নামটিতে fifteen minute-এ 9402টি trade print হয়েছিল। 19:45 ET-এ print হয়েছিল 1345টি। মোট 64টি bucket-এ 200 print-এর ন্যূনতম সীমা অতিক্রম করা হয়েছিল। প্রতিটি print হলো engine-এর পরস্পরের সঙ্গে মিলিয়ে দেওয়া এক জোড়া order। অর্ডার দুটিকে match করার আগে engine উভয় পাশের identifier পড়ে। Book-এ resting হওয়া প্রতিটি order দিনের পরবর্তী সময়ে একই account-এর অন্য order-এর সঙ্গে match হওয়ার সম্ভাব্য প্রার্থী।
Self-trade print হলে tape-এ কী দেখা যায়
প্রতিরোধ করা self-match কোনো চিহ্ন রেখে যায় না। Tape-এ কেবল executed trade-ই থাকে। প্রতিটি print-এর সঙ্গে condition flag থাকে। Trade কীভাবে হয়েছে তা বর্ণনা করতে reporting venue এই code যুক্ত করে। নিচের panel-এ একটি stock-এর পূর্ণ session-কে ওই flag অনুযায়ী ভাগ করা হয়েছে।
প্রতিটি সংখ্যার পেছনের সঠিক SQL
SELECT
condition_name,
print_count,
round(100 * print_count / sum(print_count) OVER (), 2) AS share_pct
FROM
(
SELECT
cc.id AS condition_id,
any(cc.name) AS condition_name,
count() AS print_count
FROM
(
SELECT toInt32(arrayJoin(conditions)) AS condition_id
FROM global_markets.stocks_trades
WHERE ticker = 'AAPL'
AND sip_timestamp >= toDateTime('2026-06-10 08:00:00', 'UTC')
AND sip_timestamp < toDateTime('2026-06-11 04:00:00', 'UTC')
) AS f
INNER JOIN
(
SELECT
toInt32(id) AS id,
any(name) AS name
FROM global_markets.stocks_condition_codes
WHERE asset_class = 'stocks'
AND has(data_types, 'trade')
GROUP BY id
) AS cc ON cc.id = f.condition_id
GROUP BY condition_id
)
ORDER BY print_count DESC
LIMIT 10ওই session-এর flagged print-এর 48.34% জুড়ে রয়েছে Odd Lot Trade। Panel-এ দিনের 10টি সবচেয়ে সাধারণ flag দেখানো হয়েছে। তালিকাটি পড়ে অনুপস্থিত বিষয়টি লক্ষ্য করুন। কোনো code-ই বলে না যে দুটি order একই firm থেকে এসেছে। কোনো self-trade print হলে সেটি ওই দামে অন্য যেকোনো trade-এর মতোই দেখায়। তাই এর surveillance tape-এর ওপর, venue-এর কাছে থাকা participant identifier এবং order-এর সঙ্গে থাকা account number-এর ওপর নির্ভর করে।
Self-match prevention কোথায় শেষ হয় এবং wash trade আইন কোথা থেকে শুরু হয়
Self-match prevention হলো venue-এর একটি service। আপনি এতে opt in করেন এবং configuration নির্ধারণ করেন। এটি setup না করলে engine আপনার দুটি order আনন্দের সঙ্গে match করবে। Wash trade নিষেধাজ্ঞা ঐচ্ছিক নয় এবং কোনো setting-এর ওপর নির্ভর করে না।
Securities Exchange Act of 1934-এর Section 9(a)(1) এমন securities transaction-এর ক্ষেত্রে প্রযোজ্য, যেখানে beneficial ownership-এর কোনো পরিবর্তন হয় না এবং সক্রিয় trading-এর একটি বিভ্রান্তিকর চিত্র তৈরি করার উদ্দেশ্যে transaction-এ প্রবেশ করা হয়। Commodity Exchange Act-এ futures-এর সমতুল্য বিধান রয়েছে। CME Rule 534 exchange rulebook-এ সেটি পুনর্ব্যক্ত করেছে। Broker-dealer-দের ক্ষেত্রে FINRA Rule 5210 উভয়ের সঙ্গে সম্পর্কিত। এর supplementary material সরাসরি self-trade নিয়ে আলোচনা করে: একই firm-এর দুটি unrelated algorithm-এর মধ্যে trade নিজে থেকেই নিয়মভঙ্গ নয়। তবে firm-এর এমন policy থাকা প্রত্যাশিত, যা এসব trade পর্যালোচনা এবং কমায়।
একাধিক strategy চালানো ব্যক্তিদের জন্য এর দুটি ফল রয়েছে। কোনো venue-এ self-match instruction একেবারেই সেট না করলেও self-cross নিষেধাজ্ঞা লঙ্ঘন করতে পারে, কারণ নিয়মটি transaction এবং তার অন্তর্নিহিত intent-এর ওপর প্রযোজ্য। Self-match prevention যে self-cross থামিয়ে দিয়েছে, সেটি কোনো নিয়ম লঙ্ঘন করে না। এটি থামানোই self-match prevention-এর উদ্দেশ্য।
অপারেটররা কীভাবে এটি configure করেন: CME, ICE, LME এবং MiFID II
CME Globex-এ self-match prevention order entry-তে পাঠানো identifier-এর ভিত্তিতে কাজ করে। Firm-গুলো ব্যবহারের জন্য identifier নিবন্ধন করে। প্রতিটি order-এ একটি identifier থাকে। একই identifier-যুক্ত দুটি order মিললে engine কোন পাশ cancel করবে, তা একটি paired instruction-এ নির্ধারিত থাকে। Identifier ছাড়া পাঠানো order স্বাভাবিক নিয়মে match হয়। নতুন operator-এর জন্য এটিই ফাঁদ: default অবস্থায় ব্যবস্থা বন্ধ থাকে।
ICE, Self-Trade Prevention Functionality পরিচালনা করে। এটি order-by-order নয়, trading firm identifier-এর ভিত্তিতে configure করা হয়। Cancel outcome-এর একই ধরনের বিকল্প এখানে থাকে। London Metal Exchange সদস্যদের trading identifier-এর জন্য LMEselect-এ Self-Execution Prevention দেয়। Europe-এ MiFID II Article 17 algorithmic trading-এ যুক্ত investment firm-এর ওপর systems and controls-এর দায়িত্ব দেয়। এর মধ্যে testing, kill functionality এবং disorderly trading প্রতিরোধ অন্তর্ভুক্ত। Article 48 venue-এর ওপরও সমান্তরাল দায়িত্ব দেয়। এর পাশাপাশি venue-side prevention tools standard equipment হয়ে উঠেছে।
Configuration symbol ধরে নয়, account বা firm level-এ থাকে। একটি underlying-এর option surface-এর আকারই এর কারণ দেখায়।
প্রতিটি সংখ্যার পেছনের সঠিক SQL
SELECT
toString(date) AS session_date,
countDistinct(ticker) AS contracts_traded,
countDistinct(strike_price) AS strikes_traded
FROM global_markets.options_greeks
WHERE underlying_symbol = 'AAPL'
AND date >= '2026-06-01'
AND date <= '2026-06-30'
AND volume > 0
AND iv_converged = 1
GROUP BY date
ORDER BY date2026-06-01-এ একটি underlying-এ volume-সহ আলাদাভাবে tradable 1579টি contract ছিল। সেগুলো 112টি strike জুড়ে ছড়িয়ে ছিল। Panel-এ একই ধরনের 21টি session অন্তর্ভুক্ত। ওই সংখ্যায় contract ধরে ধরে rule set করা বাস্তবে অসম্ভব। Identifier account-এর সঙ্গে যুক্ত থাকে এবং ওই account পাঠানো প্রতিটি order-এর সঙ্গে যায়।
আপনার fill log যে failure mode ব্যাখ্যা করবে না
বাস্তবে বিষয়টি এভাবে দেখা যায়। cancel-newest instruction সদ্য পাঠানো order-টি আসার সঙ্গে সঙ্গেই বাতিল করে দেয়, match হওয়ার আগেই। Bot-এর ভেতর থেকে sequence-টি দেখা যায় নতুন order-এর পর এমন একটি cancel এসেছে, যা কেউ চায়নি। কোনো fill নেই, reject নেই, এমনকি কারণের নামসহ error string-ও নেই। তাই প্রথমবার এমন ঘটনা দেখলে operator-রা নিজেদের cancel path-এ bug খুঁজতে শুরু করেন।
দুটি অভ্যাস বিষয়টি পরিষ্কার করে। Venue-এর order status message normalized summary-তে রূপান্তর না করে হুবহু log করুন। কারণ prevention-এর কারণ সাধারণত ওই message-এর একটি field হিসেবে আসে। আপনার code তৈরি করেনি এমন যেকোনো cancel-এর জন্য alert দিন। এই alert আপনার automated trading circuit breaker-এর সঙ্গেই থাকা উচিত। কারণ failure-টি একই শ্রেণির: venue আপনার order state বদলে দিয়েছে, কিন্তু আপনার process এমনভাবে চলেছে যেন কিছুই ঘটেনি।
প্রায়শই জিজ্ঞাসিত প্রশ্ন
Self-match prevention কী?
এটি matching engine-এর একটি check, যা একই firm বা account identifier-যুক্ত দুটি order-কে পরস্পরের সঙ্গে trade করা থেকে আটকায়। Order দুটির match হওয়ার কথা থাকলে, order-এর সঙ্গে যুক্ত instruction অনুসারে engine resting order, incoming order বা উভয় order cancel করে।
Self-trade কি wash trade-এর একই বিষয়?
না। Self-trade হলো একই beneficial owner-এর দুটি order-এর মধ্যে যেকোনো execution। Wash trade হলো genuine market risk ছাড়া এবং market activity সম্পর্কে বিভ্রান্তিকর চিত্র তৈরির উদ্দেশ্যে করা self-trade। Unrelated algorithm-এর মধ্যে অনিচ্ছাকৃত self-trade এবং পরিকল্পিত self-trade-কে একভাবে দেখা হয় না। তবুও firm-গুলোর এগুলো monitor করা প্রত্যাশিত।
ভিন্ন exchange-এর মধ্যে self-match prevention কি কাজ করে?
না। প্রতিটি matching engine কেবল তার নিজস্ব book-এর order-এ এই check প্রয়োগ করে। একটি firm-এর দুটি order দুটি venue-এ resting থাকলে সেগুলো পরস্পরের সঙ্গে trade করতে পারে। Venue-এর ওপরের স্তরে firm-এর নিজস্ব pre-trade check-ই তখন এই কাজের দায়িত্ব নেয়।
কোনো fill বা কারণ ছাড়াই আমার order cancel হলো কেন?
cancel-newest self-match instruction একটি সম্ভাব্য কারণ। আপনার identifier-যুক্ত resting order-এর সঙ্গে match হওয়ার আগেই venue order-টি আসার সময় cancel করেছে। কারণটি সাধারণত rejection হিসেবে নয়, venue-এর cancel message-এর একটি field হিসেবে দেখা যায়।
কোন venue self-match prevention identifier চায়?
Venue এবং product অনুযায়ী প্রয়োজনীয়তা ভিন্ন। CME order entry-তে আগে থেকে নিবন্ধিত identifier চায়। ICE এবং London Metal Exchange firm level-এ নিজেদের configuration দেয়। Europe-এর venue-গুলো MiFID II-এর অধীনে systems and controls-এর দায়িত্ব বহন করে। আপনি যে product trade করেন, তার venue rulebook-ই চূড়ান্ত কর্তৃপক্ষ।
এখানে প্রতিটি panel-এর সঙ্গে সেটি তৈরির SQL রয়েছে। যেকোনো একটি expand করে পড়ুন। আপনি যে নাম trade করেন, সেগুলোতে quoting venue গণনা করতে বা একটি session-কে condition flag-এ ভাগ করতে Strasmore terminal-এ plain English-এ প্রশ্ন করুন।