Strasmore Research

Self-Match Prevention and Wash Trades Explained

Self-match prevention dey stop your two orders from trading with each other. See how SMP dey work for matching engine, and where wash trade law begin.

Self-match prevention na matching engine feature wey dey stop two orders from the same firm make dem trade with each other. Orders carry identifier when dem enter, and when two orders wey share that identifier suppose cross, the engine cancel one of dem, or both, before any trade prints. Self-match prevention na venue plumbing wey you switch on, while prohibition on wash trades na law. The two no cover the same ground.

The moment second strategy quote instrument wey your first strategy already quote, this rule don apply to you. Two-ladder grid bot for one symbol face the same rule as bank desk.

How self-match prevention works for matching engine

Every order wey venue receive carry fields wey engine read before matching: side, price, size, time in force. Self-match prevention add two more. The first na identifier, number or string wey show which firm, account, or strategy group the order belong to. The second na instruction wey tell engine wetin to do when two live orders wey carry that identifier dey about to trade with each other.

The check run for the exact moment aggressing order reach the price of resting order wey e fit match. Four outcomes common:

  • Cancel the resting order. Incoming order continue enter the book and fit match anything wey dey behind am for that price.
  • Cancel the incoming order. Resting order keep im queue position, while aggressor disappear.
  • Cancel both orders, na the strictest setting.
  • Decrement and cancel. Engine reduce the bigger order by the size of the smaller one, cancel the smaller order, then leave the balance live.

No trade happen for any of the four. Nothing print for tape, nothing enter fill log, and unsolicited cancel arrive for one leg or both instead.

Queue position na the quiet cost. If cancel-oldest instruction cancel resting order, e lose everything wey e earn by waiting. Under price-time priority, that loss complete: when you enter the order again, e go behind everybody wey join the queue while e dey there. Our guide to estimating queue position explain wetin that place for line worth.

One instrument, many books

The check dey work per venue. Engine compare only orders wey e hold by itself. Two of your orders wey dey rest for two different books no dey see each other, and no US equities mechanism reach across both. One US stock fit quote for many books at the same time. The panel below count distinct quoting and printing venues for six household names during one fifteen minute window for the morning of June 10, 2026.

QueryVenues wey dey quote and print the same stock for one 15-minute window
The exact SQL behind every number
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
Run this yourself

AAPL draw bids from 16 separate venues during that quarter hour, and prints land on 17 of dem. The thinnest name for the panel still draw 11 quoting venues. Smart order router wey split child orders by design go put your two strategies for different books plenty times, where no engine-level check dey apply. Firms close that gap upstream, for order management layer, before anything leave the building. Your own orders wey dey rest for opposite sides at the same price for two books also produce locked or crossed market, wey get im own rules.

How many matches one book make for one session

Self-match check dey inside the path of every match wey engine make, and for liquid name that path busy throughout the day. The panel below divide one full session of one stock into fifteen minute slices and count the prints for each one, keeping slices wey carry at least 200.

QueryPrints per 15-minute bucket, one full session
The exact SQL behind every number
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_time
Run this yourself

At 04:00 ET, that one name print 9402 trades in fifteen minutes, and at 19:45 ET e print 1345, across 64 buckets wey clear the 200 print floor. Each print na one pair of orders wey engine bring together, and the check read identifiers for both sides before e allow dem meet. Every order wey come rest for the book fit later meet another order from the same account that day.

Wetin tape show when self-trade prints

Prevented self-match no leave anything behind. Tape carry only wetin execute, and every print arrive with condition flags: codes wey reporting venue attach to describe how trade happen. The panel below break one full session of one stock into those flags.

QueryTrade condition flags for one full session
The exact SQL behind every number
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
Run this yourself

Odd Lot Trade cover 48.34% of the flagged prints for that session, and panel list the 10 most common flags of the day. Read the list and notice wetin no dey there. No code show say two orders come from one firm. Self-trade wey print look like any other trade for that price, so surveillance for am run from tape, using participant identifiers wey venue hold and account numbers wey orders carry.

Where self-match prevention end and wash trade law begin

Self-match prevention na venue service. You opt into am, configure am, and engine go gladly match your two orders if you never set am up. Wash trade prohibition no be optional and e no depend on any setting.

Section 9(a)(1) of the Securities Exchange Act of 1934 cover transactions in securities wey no change beneficial ownership, when person enter dem to create misleading appearance of active trading. Commodity Exchange Act carry the futures equivalent, and CME Rule 534 restate am for exchange rulebook. FINRA Rule 5210 sit under both for broker-dealers, and im supplementary material address self-trades directly: trades between two unrelated algorithms for one firm no be violation by themselves, and firm suppose keep policies wey review and reduce dem.

Two consequences follow for anybody wey run more than one strategy. Self-cross fit breach the prohibition for venue where you never set any self-match instruction, because rule attach to the transaction and the intention behind am. Self-cross wey self-match prevention stop no breach anything: na to stop am be the whole point.

How operators configure am: CME, ICE, LME, and MiFID II

For CME Globex, self-match prevention run from identifier submitted during order entry. Firms register the identifiers wey dem go use, every order carry one, and paired instruction state which side engine go cancel when two orders wey carry that identifier meet. Orders sent without identifier match normally. Na the trap for new operator: default dey off.

ICE run Self-Trade Prevention Functionality, configured against trading firm identifier instead of order by order, with the same family of cancel outcomes. London Metal Exchange offer Self-Execution Prevention for LMEselect for member trading identifiers. For Europe, MiFID II Article 17 put systems and controls duty on any investment firm wey dey do algorithmic trading, including testing, kill functionality, and prevention of disorderly trading. Article 48 put similar duty on venue itself, and venue-side prevention tools become standard equipment alongside am.

Configuration dey at account or firm level, no be symbol by symbol. The size of one underlying’s option surface show why.

QueryOption contracts wey get volume for one underlying, June 2026
The exact SQL behind every number
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 date
Run this yourself

For 2026-06-01, one underlying carry 1579 separately tradable contracts with volume, spread across 112 strikes, and panel cover 21 sessions with similar shape. Setting rule contract by contract no manageable at that count. Identifier attach to account instead, and e travel with every order wey that account send.

The failure mode your fill logs no go explain

See how e work for practice. Cancel-newest instruction kill the order wey you just send as e arrive, before e fit match. Inside the bot, sequence look like new order followed by cancel wey nobody request. No fill, no reject, and no error string name any reason. So operators wey meet am for first time usually start to look for bug inside their own cancel path.

Two habits make am clear. Log venue order status messages word for word instead of normalized summary, because prevention reason usually dey as field for that message. Set alert for any cancel wey your own code no originate. That alert belong with your automated trading circuit breakers, because failure na the same class: venue change your order state and your process continue as if nothing happen.

FAQ

Wetin be self-match prevention?

Na matching engine check wey stop two orders carrying the same firm or account identifier from trading with each other. When dem suppose match, engine cancel resting order, incoming order, or both, according to instruction attached to the order.

Self-trade na the same thing as wash trade?

No. Self-trade na any execution between two orders from the same beneficial owner. Wash trade na self-trade wey person enter without genuine market risk and with intention to create misleading appearance of activity. Unintentional self-trades between unrelated algorithms dey treated differently from arranged ones, but firms still suppose monitor dem.

Self-match prevention dey work across different exchanges?

No. Each matching engine apply the check only to orders inside im own book. Two orders from one firm wey dey rest for two venues fit trade with each other, so na the firm’s own pre-trade checks above the venues suppose handle that work.

Why venue cancel my order without fill or reason?

Cancel-newest self-match instruction na one possible reason: venue cancel the order as e arrive, before e fit match resting order wey carry your identifier. Reason usually appear as field for venue cancel message instead of rejection.

Which venues require self-match prevention identifier?

Requirements vary by venue and product. CME ask for identifier during order entry, with advance registration, while ICE and London Metal Exchange offer their own firm-level configurations, and European venues carry systems and controls duties under MiFID II. Venue rulebook for the product wey you trade na the authority.


Every panel here carry the SQL wey produce am, so expand any one and read am. To count venues wey dey quote a name wey you trade, or break session into condition flags, ask the question in plain English for Strasmore terminal.

#market structure#matching engine#wash trades#trading bots#exchange rules