Czym jest zapobieganie transakcjom własnym (STP)?

2023-08-29 07:03

Czym jest zapobieganie transakcjom własnym (STP)?

Self Trade Prevention (STP) to mechanizm stosowany przez platformy handlowe w celu zapobiegania nieumyślnemu składaniu przez użytkowników zleceń przeciwnych do własnych zleceń. Do sytuacji zwanej self-tradingiem dochodzi wtedy, gdy własne zlecenia użytkownika są ze sobą zgodne w księdze zleceń. Mechanizm STM ma szczególne znaczenie w utrzymaniu uczciwego i przejrzystego środowiska handlowego, ponieważ ułatwia zapobieganie manipulacjom cen rynkowych i daje pewność, że aktywność handlowa dokładnie odzwierciedla rzeczywiste interesy rynku.

Mechanizm zapobiegania transakcjom własnym (STP) na platformie Binance zapobiega składaniu przez użytkowników lub identyfikator użytkownika „tradeGroupId” zleceń przeciwnych do własnych zleceń.

Co jest uznawane za self-trade?

Self-trade może wystąpić w następujących scenariuszach:

  • Zlecenie przeciwne złożone na tym samym koncie.
  • Zlecenie przeciwne złożone na koncie z tym samym identyfikatorem „tradeGroupId”.

Co się dzieje w przypadku uruchomienia mechanizmu STP?

Istnieją cztery możliwe tryby działania podejmowane przez system w przypadku zlecenia, które może stanowić przypadek self-trade.

  • NONE: ten tryb wyklucza zlecenia z mechanizmu zapobiegania transakcjom własnym. Konta i identyfikatory „tradeGroupId” nie będą porównywane, żadne zlecenia nie zostaną wycofane, a transakcje będą realizowane.
  • EXPIRE_TAKER: ten tryb zapobiega realizacji transakcji poprzez natychmiastowe wycofanie pozostałej kwoty zlecenia takera.
  • EXPIRE_MAKER: ten tryb zapobiega realizacji transakcji poprzez natychmiastowe wycofanie pozostałej kwoty zlecenia potencjalnego makera.
  • EXPIRE_BOTH: ten tryb zapobiega zawarciu transakcji poprzez natychmiastowe wycofanie pozostałych kwot zlecenia takera i potencjalnego makera.

Zdarzenie STP wystąpi w zależności od trybu STP zlecenia takera. W związku z tym tryb STP zlecenia, które trafia do księgi, nie jest istotny i będzie ignorowany w przypadku przetwarzania wszystkich przyszłych zleceń.

Jak ustawić tryb STP dla zlecenia?

Mechanizm STP można ustawić tylko za pomocą pola „selfTradePreventionMode” w punktach końcowych API poniżej:

  • POST /fapi/v1/order
  • POST /fapi/v1/batchOrders

Co to jest identyfikator „tradeGroupId”?

Różne konta z tym samym identyfikatorem „tradeGroupId” są uznawane za część tej samej „grupy handlowej”. Zlecenia złożone przez członków grupy handlowej podlegają zasadom STP na podstawie trybu STP zlecenia takera.

Użytkownik może potwierdzić, czy jego konta mają ten sam identyfikator „tradeGroupId”, z poziomu API lub z poziomu GET fapi/v2/account (REST API).

Jeśli wartość wynosi –1, identyfikator „tradeGroupId” nie został ustawiony dla danego konta, a mechanizm STP może być zastosowany tylko między zleceniami dotyczącymi tego samego konta.

Które symbole obsługują mechanizm STP?

Mechanizm STP obsługują wszystkie symbole w GET fapi/v1/exchangeInfo.

Jakie typy zleceń obsługują mechanizm STP?

Następujące typy zleceń obsługują mechanizm STP, gdy wartość Time in Force (timeInForce) jest ustawiona na GTC/IOC/GTD:

  • Zlecenie Limit
  • Zlecenie Market
  • Zlecenie take profit
  • Zlecenie Stop Market
  • Zlecenie take profit market
  • Zlecenie trailing stop market

Należy pamiętać, że mechanizm STP nie będzie stosowany w przypadku wartości Time in Force (timeInForce) w FOK lub GTX.

Czy funkcja Modyfikuj zlecenie obsługuje mechanizm STP?

Nie. Funkcja Modyfikuj zlecenie nie obsługuje mechanizmu STP.

Skąd wiadomo, czy zlecenie zostało wycofane z powodu mechanizmu STP?

Wyświetli się status zlecenia „EXPIRED_IN_MATCH”. Jeśli zlecenie zostało wycofane z powodu mechanizmu STP, w zdarzeniu strumienia danych użytkownika „ORDER_TRADE_UPDATE” pole X będzie miało wartość „EXPIRED_IN_MATCH”.

{  "e":"ORDER_TRADE_UPDATE",      // Event Type  "E":1568879465651,             // Event Time  "T":1568879465650,             // Transaction Time  "o":{                                "s":"BTCUSDT",               // Symbol    "c":"TEST",                  // Client Order Id      // special client order id:      // starts with "autoclose-": liquidation order      // "adl_autoclose": ADL auto close order      // "settlement_autoclose-": settlement order for delisting or delivery    "S":"SELL",                  // Side    "o":"TRAILING_STOP_MARKET",  // Order Type    "f":"GTC",                   // Time in Force    "q":"0.001",                 // Original Quantity    "p":"0",                     // Original Price    "ap":"0",                    // Average Price    "sp":"7103.04",              // Stop Price. Please ignore with TRAILING_STOP_MARKET order    "x":"EXPIRED",               // Execution Type    "X":"EXPIRED_IN_MATCH",      // Order Status    "i":8886774,                 // Order Id    "l":"0",                     // Order Last Filled Quantity    "z":"0",                     // Order Filled Accumulated Quantity    "L":"0",                     // Last Filled Price    "N":"USDT",                  // Commission Asset, will not push if no commission    "n":"0",                     // Commission, will not push if no commission    "T":1568879465650,           // Order Trade Time    "t":0,                       // Trade Id    "b":"0",                     // Bids Notional    "a":"9.91",                  // Ask Notional    "m":false,                   // Is this trade the maker side?    "R":false,                   // Is this reduce only    "wt":"CONTRACT_PRICE",       // Stop Price Working Type    "ot":"TRAILING_STOP_MARKET", // Original Order Type    "ps":"LONG",                 // Position Side    "cp":false,                  // If Close-All, pushed with conditional order    "AP":"7476.89",              // Activation Price, only pushed with TRAILING_STOP_MARKET order    "cr":"5.0",                  // Callback Rate, only pushed with TRAILING_STOP_MARKET order    "pP": false,                 // ignore    "si": 0,                     // ignore    "ss": 0,                     // ignore    "rp":"0"                     // Realized Profit of the trade    "V": "NONE".                 // selfTradePreventionMode    "pm":"QUEUE"                 // price match type    "gtd":1768879465650          // good till date   }}

Przykłady użycia mechanizmu STP

We wszystkich tych przypadkach należy założyć, że wszelkie zlecenia w tych przykładach są składane z tego samego konta.

Scenariusz A: użytkownik wysyła nowe zlecenie z wartością „selfTradePreventionMode:NONE”, które jest zgodne z innym zleceniem znajdującym się już w księdze zleceń.

Maker Order: symbol=BTCUSDT side=BUY  type=LIMIT quantity=1 price=20000 selfTradePreventionMode=NONE Taker Order: symbol=BTCUSDT side=SELL type=LIMIT quantity=1 price=20000 selfTradePreventionMode=NONE

Wynik: mechanizm STP nie jest aktywowany i zlecenia będą ze sobą zgodne.

Status zlecenia makera:

{    "orderId": 292864713,    "symbol": "BTCUSDT",    "status": "FILLED",    "clientOrderId": "43N239GaUaqshfG7825184",    "price": "20000",    "avgPrice": "20000",    "origQty": "1",    "executedQty": "1",    "cumQty": "1",    "cumQuote": "20000",    "timeInForce": "GTC",    "type": "LIMIT",    "reduceOnly": false,    "closePosition": false,    "side": "BUY",    "positionSide": "BOTH",    "stopPrice": "0",    "workingType": "CONTRACT_PRICE",    "priceMatch": "NONE",    "selfTradePreventionMode": "NONE",    "goodTillDate": 0,    "priceProtect": false,    "origType": "LIMIT",    "updateTime": 1692849639460}

Status zlecenia takera:

{    "orderId": 292864714,    "symbol": "BTCUSDT",    "status": "FILLED",    "clientOrderId": "43N239GaUaqshfG7825184",    "price": "20000",    "avgPrice": "20000",    "origQty": "1",    "executedQty": "1",    "cumQty": "1",    "cumQuote": "20000",    "timeInForce": "GTC",    "type": "LIMIT",    "reduceOnly": false,    "closePosition": false,    "side": "SELL",    "positionSide": "BOTH",    "stopPrice": "0",    "workingType": "CONTRACT_PRICE",    "priceMatch": "NONE",    "selfTradePreventionMode": "NONE",    "goodTillDate": 0,    "priceProtect": false,    "origType": "LIMIT",    "updateTime": 1692849639460}

Scenariusz B: użytkownik wysyła zlecenie z wartością „EXPIRE_MAKER”, które będzie zgodne z jego zleceniami znajdującymi się w księdze.

Maker Order 1: symbol=BTCUSDT side=BUY  type=LIMIT quantity=1 price=20002 selfTradePreventionMode=NONE Maker Order 2: symbol=BTCUSDT side=BUY  type=LIMIT quantity=1 price=20001 selfTradePreventionMode=NONE Taker Order 1: symbol=BTCUSDT side=SELL type=LIMIT quantity=1 price=20000 selfTradePreventionMode=EXPIRE_MAKER

Wynik: zlecenia, które już znajdowały się w księdze, zostaną wycofane z powodu mechanizmu STP, a zlecenie takera trafi do księgi.

Zlecenie makera 1:

{    "orderId": 292864710,    "symbol": "BTCUSDT",    "status": "FILLED",    "clientOrderId": "testMaker1",    "price": "20002",    "avgPrice": "20002",    "origQty": "1",    "executedQty": "1",    "cumQuote": "20002",    "timeInForce": "GTC",    "type": "LIMIT",    "reduceOnly": false,    "closePosition": false,    "side": "BUY",    "positionSide": "BOTH",    "stopPrice": "0",    "workingType": "CONTRACT_PRICE",    "priceMatch": "NONE",    "selfTradePreventionMode": "NONE",    "goodTillDate": 0,    "priceProtect": false,    "origType": "LIMIT",    "time": 1692849639460,    "updateTime": 1692849639460}

Zlecenie makera 2:

{    "orderId": 292864711,    "symbol": "BTCUSDT",    "status": "EXPIRED_IN_MATCH",    "clientOrderId": "testMaker2",    "price": "20001",    "avgPrice": "0.0000",    "origQty": "1",    "executedQty": "0",    "cumQuote": "0",    "timeInForce": "GTC",    "type": "LIMIT",    "reduceOnly": false,    "closePosition": false,    "side": "BUY",    "positionSide": "BOTH",    "stopPrice": "0",    "workingType": "CONTRACT_PRICE",    "priceMatch": "NONE",    "selfTradePreventionMode": "NONE",    "goodTillDate": 0,    "priceProtect": false,    "origType": "LIMIT",    "time": 1692849639460,    "updateTime": 1692849639460}

Wynik zlecenia takera:

{    "orderId": 292864712,    "symbol": "BTCUSDT",    "status": "PARTIALLY_FILLED",    "clientOrderId": "testTaker1",    "price": "20000",    "avgPrice": "20002",    "origQty": "2",    "executedQty": "1",    "cumQuote": "20002",    "timeInForce": "GTC",    "type": "LIMIT",    "reduceOnly": false,    "closePosition": false,    "side": "SELL",    "positionSide": "BOTH",    "stopPrice": "0",    "workingType": "CONTRACT_PRICE",    "priceMatch": "NONE",    "selfTradePreventionMode": "EXPIRE_MAKER",    "goodTillDate": 0,    "priceProtect": false,    "origType": "LIMIT",    "time": 1692849639460,    "updateTime": 1692849639460}

Scenariusz C: użytkownik wysyła zlecenie z wartością „EXPIRE_TAKER”, które będzie zgodne z jego zleceniami znajdującymi się w księdze.

Maker Order 1: symbol=BTCUSDT side=BUY  type=LIMIT quantity=1 price=20002  selfTradePreventionMode=NONE Maker Order 2: symbol=BTCUSDT side=BUY  type=LIMIT quantity=1 price=20001  selfTradePreventionMode=NONE Taker Order 1: symbol=BTCUSDT side=SELL type=LIMIT quantity=2 price=20000      selfTradePreventionMode=EXPIRE_TAKER

Wynik: zlecenia, które są już w księdze, pozostaną, a zlecenie takera wygaśnie.

Zlecenie makera 1:

{    "orderId": 292864710,    "symbol": "BTCUSDT",    "status": "NEW",    "clientOrderId": "testMaker1",    "price": "20002",    "avgPrice": "0.0000",    "origQty": "1",    "executedQty": "0",    "cumQuote": "0",    "timeInForce": "GTC",    "type": "LIMIT",    "reduceOnly": false,    "closePosition": false,    "side": "BUY",    "positionSide": "BOTH",    "stopPrice": "0",    "workingType": "CONTRACT_PRICE",    "priceMatch": "NONE",    "selfTradePreventionMode": "NONE",    "goodTillDate": 0,    "priceProtect": false,    "origType": "LIMIT",    "time": 1692849639460,    "updateTime": 1692849639460}

Zlecenie makera 2:

{    "orderId": 292864711,    "symbol": "BTCUSDT",    "status": "NEW",    "clientOrderId": "testMaker2",    "price": "20001",    "avgPrice": "0.0000",    "origQty": "1",    "executedQty": "0",    "cumQuote": "0",    "timeInForce": "GTC",    "type": "LIMIT",    "reduceOnly": false,    "closePosition": false,    "side": "BUY",    "positionSide": "BOTH",    "stopPrice": "0",    "workingType": "CONTRACT_PRICE",    "priceMatch": "NONE",    "selfTradePreventionMode": "NONE",    "goodTillDate": 0,    "priceProtect": false,    "origType": "LIMIT",    "time": 1692849639460,    "updateTime": 1692849639460}

Wynik zlecenia takera:

{    "orderId": 292864712,    "symbol": "BTCUSDT",    "status": "EXPIRED_IN_MATCH",    "clientOrderId": "testTaker1",    "price": "20000",    "avgPrice": "0.0000",    "origQty": "3",    "executedQty": "0",    "cumQuote": "0",    "timeInForce": "GTC",    "type": "LIMIT",    "reduceOnly": false,    "closePosition": false,    "side": "SELL",    "positionSide": "BOTH",    "stopPrice": "0",    "workingType": "CONTRACT_PRICE",    "priceMatch": "NONE",    "selfTradePreventionMode": "EXPIRE_TAKER",    "goodTillDate": 0,    "priceProtect": false,    "origType": "LIMIT",    "time": 1692849639460,    "updateTime": 1692849639460}

Scenariusz D: użytkownik ma zlecenie w księdze, a następnie wysyła zlecenie z wartością „EXPIRE_BOTH”, które jest zgodne z istniejącym zleceniem.

Maker Order: symbol=BTCUSDT side=BUY  type=LIMIT quantity=1 price=20002 selfTradePreventionMode=NONETaker Order: symbol=BTCUSDT side=SELL type=LIMIT quantity=3 price=20000 selfTradePreventionMode=EXPIRE_BOTH

Wynik: obydwa zlecenia wygasną.

Zlecenie makera:

{    "orderId": 292864710,    "symbol": "BTCUSDT",    "status": "EXPIRED_IN_MATCH",    "clientOrderId": "testMaker1",    "price": "20002",    "avgPrice": "0.0000",    "origQty": "1",    "executedQty": "0",    "cumQuote": "0",    "timeInForce": "GTC",    "type": "LIMIT",    "reduceOnly": false,    "closePosition": false,    "side": "BUY",    "positionSide": "BOTH",    "stopPrice": "0",    "workingType": "CONTRACT_PRICE",    "priceMatch": "NONE",    "selfTradePreventionMode": "NONE",    "goodTillDate": 0,    "priceProtect": false,    "origType": "LIMIT",    "time": 1692849639460,    "updateTime": 1692849639460}

Zlecenie takera:

{    "orderId": 292864712,    "symbol": "BTCUSDT",    "status": "EXPIRED_IN_MATCH",    "clientOrderId": "testTaker1",    "price": "20000",    "avgPrice": "0.0000",    "origQty": "3",    "executedQty": "0",    "cumQuote": "0",    "timeInForce": "GTC",    "type": "LIMIT",    "reduceOnly": false,    "closePosition": false,    "side": "SELL",    "positionSide": "BOTH",    "stopPrice": "0",    "workingType": "CONTRACT_PRICE",    "priceMatch": "NONE",    "selfTradePreventionMode": "EXPIRE_BOTH",    "goodTillDate": 0,    "priceProtect": false,    "origType": "LIMIT",    "time": 1692849639460,    "updateTime": 1692849639460}

Scenariusz E: użytkownik ma zlecenie w księdze z wartością „EXPIRE_MAKER”, a następnie wysyła nowe zlecenie z wartością „EXPIRE_TAKER”, które jest zgodne z istniejącym zleceniem.

Maker Order: symbol=BTCUSDT side=BUY  type=LIMIT quantity=1 price=20002 selfTradePreventionMode=EXPIRE_MAKER Taker Order: symbol=BTCUSDT side=SELL type=LIMIT quantity=1 price=20000 selfTradePreventionMode=EXPIRE_TAKER

Wynik: uruchomiony zostanie tryb STP zlecenia takera i zlecenie takera wygaśnie.

Zlecenie makera:

{    "orderId": 292864710,    "symbol": "BTCUSDT",    "status": "NEW",    "clientOrderId": "testMaker1",    "price": "20002",    "avgPrice": "0.0000",    "origQty": "1",    "executedQty": "0",    "cumQuote": "0",    "timeInForce": "GTC",    "type": "LIMIT",    "reduceOnly": false,    "closePosition": false,    "side": "BUY",    "positionSide": "BOTH",    "stopPrice": "0",    "workingType": "CONTRACT_PRICE",    "priceMatch": "NONE",    "selfTradePreventionMode": "EXPIRE_MAKER",    "goodTillDate": 0,    "priceProtect": false,    "origType": "LIMIT",    "time": 1692849639460,    "updateTime": 1692849639460}

Zlecenie takera:

{    "orderId": 292864712,    "symbol": "BTCUSDT",    "status": "EXPIRED_IN_MATCH",    "clientOrderId": "testTaker1",    "price": "20000",    "avgPrice": "0.0000",    "origQty": "1",    "executedQty": "0",    "cumQuote": "0",    "timeInForce": "GTC",    "type": "LIMIT",    "reduceOnly": false,    "closePosition": false,    "side": "SELL",    "positionSide": "BOTH",    "stopPrice": "0",    "workingType": "CONTRACT_PRICE",    "priceMatch": "NONE",    "selfTradePreventionMode": "EXPIRE_TAKER",    "goodTillDate": 0,    "priceProtect": false,    "origType": "LIMIT",    "time": 1692849639460,    "updateTime": 1692849639460}

Scenariusz F: użytkownik wysyła zlecenie rynkowe z wartością „EXPIRE_MAKER”, które jest zgodne z istniejącym zleceniem.

Maker Order: symbol=BTCUSDT side=BUY  type=LIMIT  quantity=1 price=20002  selfTradePreventionMode=NONE Taker Order: symbol=BTCUSDT side=SELL type=MARKET quantity=3 selfTradePreventionMode=EXPIRE_MAKER

Wynik: istniejące zlecenie ze statusem „EXPIRED_IN_MATCH” wygasa z powodu mechanizmu STP. Nowe zlecenie ze statusem „EXPIRED” również zostanie wycofane, ale z powodu niskiej płynności w księdze zleceń.

Zlecenie makera:

{    "orderId": 292864710,    "symbol": "BTCUSDT",    "status": "EXPIRED_IN_MATCH",    "clientOrderId": "testMaker1",    "price": "20002",    "avgPrice": "0.0000",    "origQty": "1",    "executedQty": "0",    "cumQuote": "0",    "timeInForce": "GTC",    "type": "LIMIT",    "reduceOnly": false,    "closePosition": false,    "side": "BUY",    "positionSide": "BOTH",    "stopPrice": "0",    "workingType": "CONTRACT_PRICE",    "priceMatch": "NONE",    "selfTradePreventionMode": "EXPIRE_MAKER",    "goodTillDate": 0,    "priceProtect": false,    "origType": "LIMIT",    "time": 1692849639460,    "updateTime": 1692849639460}

Zlecenie takera:

{    "orderId": 292864712,    "symbol": "BTCUSDT",    "status": "EXPIRED",    "clientOrderId": "testTaker1",    "price": "20000",    "avgPrice": "0.0000",    "origQty": "3",    "executedQty": "0",    "cumQuote": "0",    "timeInForce": "GTC",    "type": "MARKET",    "reduceOnly": false,    "closePosition": false,    "side": "SELL",    "positionSide": "BOTH",    "stopPrice": "0",    "workingType": "CONTRACT_PRICE",    "priceMatch": "NONE",    "selfTradePreventionMode": "EXPIRED",    "goodTillDate": 0,    "priceProtect": false,    "origType": "LIMIT",    "time": 1692849639460,    "updateTime": 1692849639460}