Strasmore Research
Analizy Matt ConnorAutor: Matt Connor

Self-match prevention a wash trades definicja

Mechanizm zapobiegania transakcjom własnym w silniku dopasowującym a regulacje prawne dotyczące wash trades. Analiza różnic między narzędziami technicznymi a prawem.

Mechanizm zapobiegania transakcjom własnym (self-match prevention) to funkcja silnika dopasowującego, która uniemożliwia zawarcie transakcji między dwoma zleceniami pochodzącymi od tej samej firmy. Zlecenia posiadają identyfikator przypisany w momencie wprowadzenia; gdy dwa zlecenia o tym samym identyfikatorze miałyby się spotkać, silnik anuluje jedno z nich lub oba, zanim dojdzie do zawarcia transakcji. Zapobieganie transakcjom własnym to narzędzie techniczne udostępniane przez platformę obrotu, podczas gdy zakaz tzw. wash trades (transakcji pozornych) wynika z przepisów prawa; oba te pojęcia nie są tożsame.

W momencie, gdy druga strategia zaczyna kwotować instrument, który jest już kwotowany przez pierwszą strategię, zasada ta staje się wiążąca. Bot typu grid z dwoma poziomami kwotowań na jednym instrumencie podlega tym samym regułom, co dział bankowy.

Jak działa zapobieganie transakcjom własnym w silniku dopasowującym

Każde zlecenie otrzymane przez platformę zawiera pola, które silnik odczytuje przed dopasowaniem: stronę, cenę, wielkość oraz czas ważności (time in force). Mechanizm zapobiegania transakcjom własnym dodaje dwa kolejne. Pierwszym jest identyfikator – liczba lub ciąg znaków określający, do której firmy, rachunku lub grupy strategii należy zlecenie. Drugim jest instrukcja określająca, co silnik ma zrobić, gdy dwa aktywne zlecenia z tym samym identyfikatorem mają zostać dopasowane.

Weryfikacja następuje w momencie, gdy zlecenie agresywne osiąga cenę zlecenia oczekującego, z którym mogłoby zostać dopasowane. Powszechnie stosuje się cztery rozwiązania:

  • Anulowanie zlecenia oczekującego (resting order). Zlecenie przychodzące trafia do arkusza i może zostać dopasowane do kolejnych zleceń znajdujących się za nim po tej samej cenie.
  • Anulowanie zlecenia przychodzącego (incoming order). Zlecenie oczekujące zachowuje swoją pozycję w kolejce, a zlecenie agresywne zostaje usunięte.
  • Anulowanie obu zleceń – jest to najbardziej restrykcyjne ustawienie.
  • Zmniejszenie i anulowanie. Większe zlecenie zostaje pomniejszone o wielkość mniejszego, mniejsze zlecenie zostaje anulowane, a pozostała część większego zlecenia pozostaje aktywna.

W żadnym z tych czterech przypadków nie dochodzi do zawarcia transakcji. Żadna transakcja nie pojawia się na taśmie (tape), nie trafia do rejestru transakcji, a zamiast tego wysyłane jest niezamówione anulowanie dla jednej lub obu stron.

Pozycja w kolejce to ukryty koszt. Zlecenie oczekujące anulowane zgodnie z instrukcją anulowania najstarszego zlecenia traci wszystko, co zyskało dzięki oczekiwaniu. W przypadku priorytetu ceny i czasu strata ta jest całkowita: ponowne wprowadzenie zlecenia ustawia je za wszystkimi, którzy dołączyli do kolejki w czasie jego nieobecności. Nasz przewodnik po szacowaniu pozycji w kolejce wyjaśnia, jaką wartość ma to miejsce w linii.

Jeden instrument, wiele arkuszy

Weryfikacja odbywa się na poziomie platformy. Silnik porównuje tylko te zlecenia, które sam posiada. Dwa zlecenia oczekujące w różnych arkuszach są dla siebie niewidoczne, a żaden mechanizm dla amerykańskich akcji nie obejmuje ich łącznie. Pojedyncza akcja z rynku USA jest kwotowana w wielu arkuszach jednocześnie. Poniższy panel przedstawia liczbę odrębnych platform kwotujących i realizujących transakcje dla sześciu znanych spółek w ciągu piętnastominutowego okna w dniu 10 czerwca 2026 roku.

ZapytaniePlatformy kwotujące i realizujące transakcje na tym samym instrumencie w oknie 15-minutowym
Dokładny kod SQL dla każdej liczby
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 przyciągnęło zlecenia kupna z 16 oddzielnych platform w ciągu tego kwadransa, a transakcje zostały zawarte na 17 z nich. Nawet najmniej płynny instrument w zestawieniu był kwotowany na 11 platformach. Inteligentny router zleceń (smart order router), który z założenia dzieli zlecenia nadrzędne na podzlecenia, w większości przypadków umieści Twoje dwie strategie w różnych arkuszach, gdzie weryfikacja na poziomie silnika nie ma zastosowania. Firmy eliminują tę lukę na wcześniejszym etapie, w warstwie zarządzania zleceniami, zanim jakiekolwiek zlecenie opuści system. Twoje własne zlecenia oczekujące po przeciwnych stronach przy tej samej cenie w dwóch arkuszach również tworzą rynek zablokowany lub skrzyżowany, co podlega odrębnym zasadom.

Ile dopasowań wykonuje jeden arkusz w trakcie sesji

Weryfikacja transakcji własnych znajduje się na ścieżce każdego dopasowania wykonywanego przez silnik, a w przypadku płynnych instrumentów ścieżka ta jest zajęta przez cały dzień. Poniższy panel dzieli pełną sesję jednego instrumentu na piętnastominutowe odcinki i zlicza transakcje w każdym z nich, uwzględniając tylko te odcinki, w których odnotowano co najmniej 200 transakcji.

ZapytanieLiczba transakcji w interwałach 15-minutowych, pełna sesja
Dokładny kod SQL dla każdej liczby
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

O godzinie 04:00 czasu ET ten instrument odnotował 9402 transakcji w ciągu piętnastu minut, a o 19:45 ET odnotował 1345 transakcji w 64 przedziałach, które przekroczyły próg 200 transakcji. Każda transakcja to para zleceń, które silnik połączył, a weryfikacja sprawdza identyfikatory po obu stronach, zanim pozwoli na ich spotkanie. Każde zlecenie, które trafia do arkusza, może zostać dopasowane do innego zlecenia z tego samego rachunku w późniejszym czasie tego samego dnia.

Co pokazuje taśma, gdy dochodzi do transakcji własnej

Zapobieżona transakcja własna nie pozostawia śladu. Taśma zawiera tylko to, co zostało zrealizowane, a każda transakcja posiada flagi warunkowe: kody, które platforma przypisuje w celu opisania sposobu zawarcia transakcji. Poniższy panel dzieli pełną sesję jednego instrumentu według tych flag.

ZapytanieOznaczenia warunków transakcji, pełna sesja
Dokładny kod SQL dla każdej liczby
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 obejmuje 48.34% oznaczonych transakcji w tej sesji, a panel wymienia 10 najczęstszych flag dnia. Przejrzyj listę i zwróć uwagę na to, czego brakuje. Brak kodu oznacza, że dwa zlecenia pochodziły od jednej firmy. Transakcja własna, która zostaje zarejestrowana, wygląda jak każda inna transakcja po tej cenie, dlatego nadzór nad nimi odbywa się na podstawie danych z taśmy, identyfikatorów uczestników posiadanych przez platformę oraz numerów rachunków przypisanych do zleceń.

Gdzie kończy się zapobieganie transakcjom własnym, a zaczyna prawo dotyczące wash trades

Zapobieganie transakcjom własnym to usługa platformy. Możesz z niej skorzystać i skonfigurować ją, a silnik bez problemu dopasuje Twoje dwa zlecenia, jeśli tego nie zrobisz. Zakaz zawierania transakcji pozornych (wash trades) nie jest opcjonalny i nie zależy od żadnych ustawień.

Sekcja 9(a)(1) ustawy Securities Exchange Act z 1934 roku dotyczy transakcji na papierach wartościowych, które nie wiążą się ze zmianą właściciela ekonomicznego i są zawierane w celu stworzenia mylnego wrażenia aktywnego obrotu. Ustawa Commodity Exchange Act zawiera odpowiednik dla kontraktów terminowych, a reguła CME 534 powtarza to w regulaminie giełdy. Reguła FINRA 5210 odnosi się do obu tych przepisów w kontekście domów maklerskich, a jej materiały uzupełniające bezpośrednio odnoszą się do transakcji własnych: transakcje między dwoma niezależnymi algorytmami w ramach jednej firmy nie są same w sobie naruszeniem, jednak oczekuje się, że firma będzie utrzymywać politykę ich przeglądu i ograniczania.

Dla każdego, kto uruchamia więcej niż jedną strategię, wynikają z tego dwie konsekwencje. Transakcja własna może naruszyć zakaz na platformie, na której nie ustawiono żadnej instrukcji zapobiegania transakcjom własnym, ponieważ zasada ta dotyczy samej transakcji i intencji, która za nią stoi. Transakcja własna, której zapobiegł mechanizm, nie stanowi naruszenia: jej zatrzymanie jest głównym celem tego mechanizmu.

Jak operatorzy konfigurują to narzędzie: CME, ICE, LME i MiFID II

Na platformie CME Globex zapobieganie transakcjom własnym działa w oparciu o identyfikator przesyłany przy wprowadzaniu zlecenia. Firmy rejestrują używane identyfikatory, każde zlecenie zawiera jeden z nich, a sparowana instrukcja określa, którą stronę silnik anuluje, gdy spotkają się dwa zlecenia z tym identyfikatorem. Zlecenia wysłane bez identyfikatora są dopasowywane normalnie, co stanowi pułapkę dla nowego operatora: ustawieniem domyślnym jest brak ochrony.

ICE stosuje funkcjonalność Self-Trade Prevention, konfigurowaną dla identyfikatora firmy handlowej, a nie dla każdego zlecenia z osobna, z taką samą gamą wyników anulowania. London Metal Exchange oferuje funkcję Self-Execution Prevention na platformie LMEselect dla identyfikatorów członkowskich. W Europie artykuł 17 dyrektywy MiFID II nakłada obowiązek kontroli systemowych na każdą firmę inwestycyjną zajmującą się handlem algorytmicznym, obejmujący testowanie, funkcje „kill” oraz zapobieganie nieuporządkowanemu obrotowi. Artykuł 48 nakłada równoległy obowiązek na samą platformę, a narzędzia zapobiegania po stronie platformy stały się standardowym wyposażeniem.

Konfiguracja odbywa się na poziomie rachunku lub firmy, a nie poszczególnych instrumentów. Wielkość powierzchni opcji dla jednego instrumentu bazowego pokazuje, dlaczego tak jest.

ZapytanieKontrakty opcyjne z wolumenem dla jednego instrumentu bazowego, czerwiec 2026
Dokładny kod SQL dla każdej liczby
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

W dniu 2026-06-01 jeden instrument bazowy posiadał 1579 oddzielnie zbywalnych kontraktów z wolumenem, rozproszonych na 112 cenach wykonania, a panel obejmuje 21 sesji o podobnej charakterystyce. Ustawianie reguły dla każdego kontraktu z osobna jest niemożliwe przy takiej liczbie. Identyfikator jest przypisany do rachunku i towarzyszy każdemu zleceniu wysyłanemu z tego rachunku.

Tryb awaryjny, którego nie wyjaśnią rejestry transakcji

Oto jak wygląda to w praktyce. Instrukcja anulowania najnowszego zlecenia (cancel-newest) usuwa zlecenie, które właśnie wysłałeś, w momencie jego dotarcia, zanim zdąży zostać dopasowane. Z perspektywy bota sekwencja wygląda jak nowe zlecenie, po którym następuje anulowanie, o które nikt nie prosił. Brak jest realizacji, brak odrzucenia i brak komunikatu o błędzie z podaniem przyczyny, więc operatorzy spotykający się z tym po raz pierwszy zazwyczaj szukają błędu we własnej ścieżce anulowania.

Dwa nawyki czynią to zjawisko zrozumiałym. Rejestruj komunikaty o statusie zlecenia z platformy w formie dosłownej, a nie jako znormalizowane podsumowanie, ponieważ przyczyna zapobiegania zazwyczaj znajduje się w polu tego komunikatu. Ustaw alerty dla każdego anulowania, którego nie zainicjował Twój własny kod. Taki alert powinien być częścią Twoich zautomatyzowanych wyłączników bezpieczeństwa (circuit breakers), ponieważ awaria należy do tej samej klasy: platforma zmieniła stan Twojego zlecenia, a Twój proces działał tak, jakby nic się nie stało.

FAQ

Czym jest zapobieganie transakcjom własnym?

To weryfikacja silnika dopasowującego, która uniemożliwia zawarcie transakcji między dwoma zleceniami posiadającymi ten sam identyfikator firmy lub rachunku. Gdy zlecenia miałyby zostać dopasowane, silnik anuluje zlecenie oczekujące, przychodzące lub oba, zgodnie z instrukcją przypisaną do zlecenia.

Czy transakcja własna to to samo co wash trade?

Nie. Transakcja własna to każda realizacja między dwoma zleceniami od tego samego właściciela ekonomicznego. Wash trade to transakcja własna zawarta bez rzeczywistego ryzyka rynkowego i z intencją stworzenia mylnego wrażenia aktywności. Niezamierzone transakcje własne między niezależnymi algorytmami są traktowane inaczej niż te zaaranżowane, a firmy nadal mają obowiązek ich monitorowania.

Czy zapobieganie transakcjom własnym działa między różnymi giełdami?

Nie. Każdy silnik dopasowujący stosuje weryfikację tylko do zleceń w swoim własnym arkuszu. Dwa zlecenia od jednej firmy oczekujące na dwóch różnych platformach mogą zostać ze sobą dopasowane, co pozostawia to zadanie własnym kontrolom przedtransakcyjnym firmy.

Dlaczego moje zlecenie zostało anulowane bez realizacji i bez podania przyczyny?

Instrukcja „cancel-newest” jest jednym z powodów: platforma anulowała zlecenie w momencie jego dotarcia, zanim mogło zostać dopasowane do zlecenia oczekującego z Twoim identyfikatorem. Przyczyna zazwyczaj pojawia się jako pole w komunikacie o anulowaniu z platformy, a nie jako odrzucenie.

Które platformy wymagają identyfikatora do zapobiegania transakcjom własnym?

Wymogi różnią się w zależności od platformy i produktu. CME wymaga identyfikatora przy wprowadzaniu zlecenia, zarejestrowanego z wyprzedzeniem, podczas gdy ICE i London Metal Exchange oferują własne konfiguracje na poziomie firmy, a platformy europejskie podlegają obowiązkom kontroli systemowych wynikającym z MiFID II. Wiążący jest regulamin platformy dla produktu, którym handlujesz.


Każdy panel zawiera kod SQL, który go wygenerował, więc rozwiń dowolny z nich i zapoznaj się z nim. Aby policzyć platformy kwotujące instrument, którym handlujesz, lub podzielić sesję na flagi warunkowe, zadaj pytanie prostym językiem w terminalu Strasmore.