Запобігання самозіставленню та wash trades
Як SMP зупиняє угоди між власними заявками в matching engine, чим відрізняється від заборони wash trades і коли це важливо для grid-бота та trading desk.
Запобігання самозіставленню — це функція matching engine, яка не дає двом заявкам однієї фірми укласти угоду між собою. Під час подання заявка отримує ідентифікатор. Якщо дві заявки з таким ідентифікатором мають перетнутися, engine скасовує одну з них або обидві ще до того, як угода з’явиться у стрічці. Запобігання самозіставленню — це інфраструктурна функція майданчика, яку потрібно активувати. Заборона wash trades встановлена законом, і ці механізми не охоплюють одне й те саме.
Щойно друга стратегія починає котирувати інструмент, який уже котирує перша, це правило стає для вас актуальним. Grid-бот із двома рівнями на одному символі стикається з ним на тих самих умовах, що й банківський trading desk.
Як працює запобігання самозіставленню в matching engine
Кожна заявка, яку отримує майданчик, містить поля, що engine читає до зіставлення: сторону, ціну, розмір і час дії. Запобігання самозіставленню додає ще два поля. Перше — ідентифікатор, число або рядок, який показує, якій фірмі, рахунку чи групі стратегій належить заявка. Друге — інструкція, що визначає дії engine, коли дві активні заявки з таким ідентифікатором мають укласти угоду між собою.
Перевірка запускається в момент, коли агресивна заявка досягає ціни пасивної заявки, з якою вона могла б зіставитися. Найчастіше використовують чотири варіанти:
- Скасувати пасивну заявку. Вхідна заявка продовжує рухатися в книгу і може зіставитися з іншими заявками за цією ціною.
- Скасувати вхідну заявку. Пасивна заявка зберігає свою позицію в черзі, а агресивна зникає.
- Скасувати обидві заявки. Це найсуворіше налаштування.
- Зменшити розмір і скасувати. Розмір більшої заявки зменшується на розмір меншої, менша заявка скасовується, а залишок більшої залишається активним.
У жодному з чотирьох випадків угода не укладається. Вона не з’являється у стрічці, не потрапляє до журналу виконання, а замість цього надходить повідомлення про скасування однієї або двох заявок.
Тиха вартість — це позиція в черзі. Заявка, яку скасували за інструкцією cancel-oldest, втрачає все, що отримала завдяки очікуванню. За правилом пріоритету ціни та часу ця втрата є повною: після повторного подання заявка опиниться позаду всіх, хто приєднався до черги, поки вона перебувала в книзі. У нашому посібнику щодо оцінювання позиції в черзі пояснюється, скільки може коштувати це місце.
Один інструмент, багато книг заявок
Перевірка виконується окремо на кожному майданчику. Engine порівнює лише ті заявки, які зберігає сам. Дві ваші заявки, що перебувають у книгах різних майданчиків, не бачать одна одну, і жоден механізм торгівлі акціями США не поширює цю перевірку між ними. Одна акція США може одночасно котируватися в багатьох книгах. Панель нижче підраховує кількість окремих майданчиків, на яких формувалися котирування та укладалися угоди щодо шести відомих акцій протягом одного п’ятнадцятихвилинного інтервалу вранці 10 червня 2026 року.
Точний 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, tickerAAPL отримував заявки на купівлю з 16 окремих майданчиків протягом цього п’ятнадцятихвилинного інтервалу, а угоди укладалися на 17 із них. Навіть найменш ліквідна акція на панелі отримувала котирування з 11 майданчиків. Smart order router, який за задумом розподіляє дочірні заявки, значну частину часу розміщуватиме заявки двох ваших стратегій у різних книгах, де перевірка на рівні engine не діє. Фірми усувають цю прогалину на попередньому етапі — у системі управління заявками, до того як будь-що залишить компанію. Ваші заявки, що стоять по різні боки ринку за однаковою ціною у двох книгах, також формують заблокований або перехресний ринок, для якого діють окремі правила.
Скільки зіставлень виконує одна книга протягом сесії
Перевірка на самозіставлення відбувається під час кожного зіставлення, яке виконує engine. На ліквідному інструменті цей процес триває протягом усього дня. Панель нижче розподіляє повну сесію однієї акції на п’ятнадцятихвилинні інтервали й підраховує кількість угод у кожному з них, залишаючи інтервали щонайменше з 200 угодами.
Точний 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_timeО 04:00 ET щодо цієї акції було укладено 9402 угод за п’ятнадцять хвилин, а о 19:45 ET — 1345. Загалом було 64 інтервалів, у яких кількість угод перевищила поріг у 200. Кожна угода — це пара заявок, які engine звів між собою. Перед цим перевірка зчитує ідентифікатори з обох сторін. Кожна заявка, яка залишилася в книзі, згодом може зустрітися із заявкою того самого рахунку.
Що показує стрічка, коли відбувається самоугода
Запобігнуте самозіставлення не залишає сліду. У стрічці відображаються лише виконані угоди, і кожна угода містить condition flags — коди, які майданчик додає для опису способу її укладення. Панель нижче розподіляє повну сесію однієї акції за цими кодами.
Точний 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 10Odd Lot Trade охоплює 48.34% угод із кодами за цю сесію, а на панелі наведено 10 найпоширеніших кодів дня. Перегляньте список і зверніть увагу на те, чого в ньому немає. Жоден код не показує, що дві заявки надійшли від однієї фірми. Самоугода, яка все ж відбулася, виглядає як будь-яка інша угода за цією ціною. Тому моніторинг таких угод ґрунтується на даних стрічки, ідентифікаторах учасників, які зберігає майданчик, та номерах рахунків, пов’язаних із заявками.
Де закінчується запобігання самозіставленню і починається законодавство про wash trades
Запобігання самозіставленню — це сервіс майданчика. Ви підключаєте його та налаштовуєте, а engine без нього спокійно зіставить дві ваші заявки, якщо ви не активували цю функцію. Заборона wash trades не є опціональною і не залежить від жодного налаштування.
Розділ 9(a)(1) Securities Exchange Act of 1934 поширюється на операції з цінними паперами, які не передбачають зміни бенефіціарного власника та укладаються для створення оманливого уявлення про активність торгів. Commodity Exchange Act містить еквівалентну норму для ф’ючерсів, а CME Rule 534 повторює її у правилах біржі. FINRA Rule 5210 діє в цій сфері для broker-dealers, а супровідні положення прямо стосуються самоугод: угоди між двома незалежними алгоритмами однієї фірми самі по собі не є порушенням, але від фірми очікується наявність політик для їх виявлення та скорочення.
Для тих, хто використовує кілька стратегій, це має два наслідки. Самоперетин може порушувати заборону на майданчику, де ви взагалі не встановили інструкцію щодо запобігання самозіставленню, оскільки правило стосується самої операції та наміру, який за нею стоїть. Самоперетин, якому запобіг механізм самозіставлення, нічого не порушує: саме для цього цей механізм і призначений.
Як оператори налаштовують механізм: CME, ICE, LME та MiFID II
На CME Globex запобігання самозіставленню працює на основі ідентифікатора, який подається разом із заявкою. Фірми заздалегідь реєструють ідентифікатори, кожна заявка містить один із них, а окрема інструкція визначає, яку сторону engine скасує, якщо дві заявки з таким ідентифікатором зустрінуться. Заявки без ідентифікатора зіставляються у звичайному режимі. Для нового оператора це є пасткою: за замовчуванням функцію вимкнено.
ICE використовує Self-Trade Prevention Functionality, яку налаштовують для ідентифікатора торгової фірми, а не окремо для кожної заявки, із тією самою групою варіантів скасування. London Metal Exchange пропонує Self-Execution Prevention у LMEselect для торгових ідентифікаторів членів біржі. У Європі Article 17 MiFID II покладає на кожну інвестиційну фірму, що здійснює алгоритмічну торгівлю, обов’язок мати системи та засоби контролю. Це охоплює тестування, kill functionality і запобігання безладній торгівлі. Article 48 покладає аналогічний обов’язок на сам майданчик, і його інструменти запобігання стали стандартним обладнанням.
Налаштування застосовуються на рівні рахунку або фірми, а не окремо для кожного символу. Масштаб опціонної поверхні одного базового активу пояснює чому.
Точний 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 dateНа 2026-06-01 один базовий актив мав 1579 окремо торгованих контрактів з обсягом, розподілених між 112 страйками. Панель охоплює 21 сесій подібної структури. Налаштовувати правило для кожного контракту за такої кількості неможливо. Ідентифікатор прив’язується до рахунку й передається разом із кожною заявкою, яку надсилає цей рахунок.
Помилка, яку ваші журнали виконання не пояснять
Ось як це проявляється на практиці. Інструкція cancel-newest скасовує щойно надіслану заявку одразу після її надходження, ще до можливого зіставлення. Усередині бота послідовність виглядає як подання нової заявки, після якого надходить скасування, якого ніхто не ініціював. Виконання немає, відхилення немає, а в тексті помилки не вказано причину. Тому оператори, які стикаються з цим уперше, зазвичай шукають помилку у власній логіці скасування.
Дві звички допомагають зрозуміти ситуацію. Записуйте повідомлення про статус заявки від майданчика дослівно, а не у вигляді нормалізованого підсумку, оскільки причина запобігання зазвичай передається окремим полем у цьому повідомленні. Налаштуйте сповіщення про будь-яке скасування, яке не ініціював ваш код. Таке сповіщення має бути пов’язане з вашими автоматизованими circuit breakers для торгівлі, оскільки це той самий клас збою: майданчик змінив стан вашої заявки, а процес продовжив роботу так, ніби нічого не сталося.
Поширені запитання
Що таке запобігання самозіставленню?
Це перевірка в matching engine, яка не дає двом заявкам з однаковим ідентифікатором фірми або рахунку укласти угоду між собою. Коли вони мають зіставитися, engine скасовує пасивну заявку, вхідну заявку або обидві — відповідно до інструкції, прикріпленої до заявки.
Чи є самоугода тим самим, що й wash trade?
Ні. Самоугода — це будь-яке виконання між двома заявками одного бенефіціарного власника. Wash trade — це самоугода, укладена без реального ринкового ризику та з наміром створити оманливе уявлення про активність торгів. Ненавмисні самоугоди між незалежними алгоритмами розглядаються інакше, ніж організовані, але фірми все одно мають їх моніторити.
Чи працює запобігання самозіставленню між різними біржами?
Ні. Кожен matching engine застосовує перевірку лише до заявок у власній книзі. Дві заявки однієї фірми, що перебувають на двох майданчиках, можуть укласти угоду між собою. Тому цю функцію мають виконувати власні pre-trade перевірки фірми на рівні вище за майданчики.
Чому мою заявку скасували без виконання та пояснення?
Однією з можливих причин є інструкція cancel-newest для запобігання самозіставленню. Майданчик скасував заявку одразу після її надходження, ще до того, як вона могла зіставитися з пасивною заявкою з вашим ідентифікатором. Причина зазвичай міститься в окремому полі повідомлення майданчика про скасування, а не у повідомленні про відхилення.
Які майданчики вимагають ідентифікатор для запобігання самозіставленню?
Вимоги залежать від майданчика та продукту. CME вимагає ідентифікатор під час подання заявки та його попередньої реєстрації, тоді як ICE і London Metal Exchange пропонують власні налаштування на рівні фірми. Європейські майданчики мають обов’язки щодо систем і засобів контролю відповідно до MiFID II. Визначальними є правила майданчика для продукту, яким ви торгуєте.
Кожна панель містить SQL-запит, на основі якого її побудовано. Розгорніть будь-яку панель і перегляньте його. Щоб підрахувати кількість майданчиків, на яких котирується потрібний вам інструмент, або розподілити сесію за condition flags, сформулюйте запит звичайною англійською мовою в терміналі Strasmore.