Skip to content

Latest commit

 

History

History
674 lines (576 loc) · 18.2 KB

stp_faq_CN.md

File metadata and controls

674 lines (576 loc) · 18.2 KB

自我交易预防 (Self Trade Prevention - STP) 常见问题

什么是 Self Trade Prevention - STP?

自我交易预防是指阻止订单与来自同一账户或者同一 tradeGroupId 账户的订单交易。

什么是自我交易(self-trade)?

在以下任一情况下都可能发生自我交易:

  • 属于同一账户的订单之间交易。
  • 属于相同 tradeGroupId 的账户的订单之间交易。

STP 触发时会发生什么?

如果订单会触发自我交易,系统将执行四种可能的模式:

NONE - 此模式使订单免于自我交易预防。

EXPIRE_TAKER - 此模式通过立即使吃单者(taker)的剩余数量过期来预防交易。

EXPIRE_MAKER - 此模式通过立即使潜在挂单者(maker)的剩余数量过期来预防交易。

EXPIRE_BOTH - 此模式通过立即同时使吃单和挂单者的剩余数量过期来预防交易。

STP 的发生取决于 Taker 订单 的 STP 模式。
因此,订单薄上的订单的 STP 模式不再有效果,并且将在所有未来的订单处理中被忽略。

什么是交易组 Id(Trade Group Id)?

属于同一 tradeGroupId 的账户被视为同一交易组。相同交易组成员提交的订单有 STP 资格。

每个账户可以从 GET /api/v3/account(REST API)或 account.status(Websocket API)确认账户是否属于同一个 tradeGroupId

tradeGroupId 也存在 GET /api/v3/preventedMatches(Rest API)或 myPreventedMatches(Websocket API)的响应中。

如果该值为 -1,这表示账户未设置 tradeGroupId,因此 STP 只能发生在同一账户的订单之间。

什么是 Prevented Match?

当一个或多个订单因 STP 而过期时,这会创建一个被阻止的撮合交易事务。

通过 Rest API 的 GET /api/v3/preventedMatches 或 Websocket API 的 myPreventedMatches 可以查询到有哪些被阻止的撮合交易。

请求的响应示例:

[
  {
    "symbol": "BTCDUSDT",                       //交易对
    "preventedMatchId": 8,                      //被阻止撮合交易的Id
    "takerOrderId": 12,                         //吃单者的订单Id
    "makerOrderId": 10,                         //挂单者的订单Id
    "tradeGroupId": 1,                          //交易组的Id。(如果账户不属于交易组,则为 -1)
    "selfTradePreventionMode": "EXPIRE_BOTH",   //订单过期的 STP 模式。
    "price": "50.00000000",                     //撮合交易的价格。
    "takerPreventedQuantity": "1.00000000",     //吃单者的剩余数量。 仅在 STP 模式为 EXPIRE_TAKER 或 EXPIRE_BOTH 时出现。
    "makerPreventedQuantity": "10.00000000",    //挂单者的剩余数量。 仅在 STP 模式为 EXPIRE_MAKER 或 EXPIRE_BOTH 时出现。
    "transactTime": 1663190634060               //订单因 STP 而过期的时间。
  }
]

什么是 "prevented quantity"?

STP事件会导致挂单的数量失效; STP的模式 EXPIRE_TAKER, EXPIRE_MAKER 以及 EXPIRE_BOTH 会使挂单中剩余的数量全部失效,从而使整个订单失效。

Prevented quantity 表示订单中因为STP事件失效的数量. 用户WebSocket数据流中可能有如下两个字段:

{
  "A":"3.000000", // Prevented Quantity
  "B":"3.000000"  // Last Prevented Quantity
}

B 代表着 TRADE_PREVENTION 交易类型, 其值表示本次STP事件导致失效的订单数量.

A 代表着某订单因为STP事件导致的累计失效订单数量. 对于 EXPIRE_TAKER, EXPIRE_MAKER 以及 EXPIRE_BOTH 模式, 其值总是和 B 一样.

由于 STP 而过期的订单的 API 响应也将有一个 preventedQuantity 字段,指示在订单由于 STP 而过期的累计数量。

如果订单是处于挂单状态, 如下的公式成立:

executed quantity + prevented quantity < original order quantity
执行的订单数量 + 被过期的数量 < 订单的原始数量

如果订单状态是 EXPIRED_IN_MATCH 或者 FILLED, 如下的等式成立:

executed quantity + prevented quantity = original order quantity
执行的订单数量 + 被过期的数量 = 订单的原始数量

如何知道有那些交易对支持 STP?

交易对可以配置为允许不同的 STP 模式集并采用不同的默认 STP 模式。

defaultSelfTradePreventionMode - 如果用户在下单时不提供,订单将使用此 STP 模式。

allowedSelfTradePreventionModes - 交易对允许的下单 STP 模式集。

例如,如果交易对有以下配置:

"defaultSelfTradePreventionMode": "NONE",
"allowedSelfTradePreventionModes": [
    "NONE",
    "EXPIRE_TAKER",
    "EXPIRE_BOTH"
  ]

这表示如果用户在没有提供 selfTradePreventionMode 的情况下发送订单,发送的订单有 NONE 的值。

如果用户想明确提及模式,可以传 NONEEXPIRE_TAKER,或 EXPIRE_BOTH

如果用户尝试为此交易对的订单指定 EXPIRE_MAKER,将会收到错误消息:

{
    "code": -1013,
    "msg": "This symbol does not allow the specified self-trade prevention mode."
}

如何知道订单因为 STP 而过期?

订单的状态会是 EXPIRED_IN_MATCH.

STP 的一些示例:

假设以下示例的所有订单都是在同一个账户下发送。

情况 A - 用户发送一个带有 selfTradePreventionMode:NONE 的新订单,该订单将与订单薄上已有的另一个订单撮合。

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

结果: : 没有 STP 被触发,订单会撮合。

Maker 订单的状态

{
  "symbol": "BTCUSDT",
  "orderId": 2,
  "orderListId": -1,
  "clientOrderId": "FaDk4LPRxastaICEFE9YTf",
  "price": "1.000000",
  "origQty": "1.000000",
  "executedQty": "1.000000",
  "cummulativeQuoteQty": "1.000000",
  "status": "FILLED",
  "timeInForce": "GTC",
  "type": "LIMIT",
  "side": "BUY",
  "stopPrice": "0.000000",
  "icebergQty": "0.000000",
  "time": 1670217090310,
  "updateTime": 1670217090330,
  "isWorking": true,
  "workingTime": 1670217090310,
  "origQuoteOrderQty": "0.000000",
  "selfTradePreventionMode": "NONE"
}

Taker 订单的状态

{
  "symbol": "BTCUSDT",
  "orderId": 3,
  "orderListId": -1,
  "clientOrderId": "Ay48Vtpghnsvy6w8RPQEde",
  "transactTime": 1670207731263,
  "price": "1.000000",
  "origQty": "1.000000",
  "executedQty": "1.000000",
  "cummulativeQuoteQty": "1.000000",
  "status": "FILLED",
  "timeInForce": "GTC",
  "type": "LIMIT",
  "side": "SELL",
  "workingTime": 1670207731263,
  "fills": [
    {
      "price": "1.000000",
      "qty": "1.000000",
      "commission": "0.000000",
      "commissionAsset": "USDT",
      "tradeId": 1
    }
  ],
  "selfTradePreventionMode": "NONE"
}

情况 B - 用户发送带有 EXPIRE_MAKER 的订单,该订单将与订单薄上已有的订单撮合。

Maker 订单 1: symbol=BTCUSDT side=BUY type=LIMIT quantity=1.2 price=1.2 selfTradePreventionMode=NONE
Maker 订单 2: symbol=BTCUSDT side=BUY type=LIMIT quantity=1.3 price=1.1 selfTradePreventionMode=NONE
Maker 订单 3: symbol=BTCUSDT side=BUY type=LIMIT quantity=8.1 price=1   selfTradePreventionMode=NONE
Taker 订单 1: symbol=BTCUSDT side=SELL type=LIMIT quantity=3 price=1    selfTradePreventionMode=EXPIRE_MAKER

结果: : 由于 STP,订单薄上的订单将会过期,taker 订单将继续在订单薄。

Maker 订单 1

{
  "symbol": "BTCUSDT",
  "orderId": 2,
  "orderListId": -1,
  "clientOrderId": "wpNzhSclc16pV8g5THIOR3",
  "price": "1.200000",
  "origQty": "1.200000",
  "executedQty": "0.000000",
  "cummulativeQuoteQty": "0.000000",
  "status": "EXPIRED_IN_MATCH",
  "timeInForce": "GTC",
  "type": "LIMIT",
  "side": "BUY",
  "stopPrice": "0.000000",
  "icebergQty": "0.000000",
  "time": 1670217957437,
  "updateTime": 1670217957498,
  "isWorking": true,
  "workingTime": 1670217957437,
  "origQuoteOrderQty": "0.000000",
  "selfTradePreventionMode": "NONE",
  "preventedMatchId": 0,
  "preventedQuantity": "1.200000"
}

Maker 订单 2

{
  "symbol": "BTCUSDT",
  "orderId": 3,
  "orderListId": -1,
  "clientOrderId": "ZT9emqia99V7x8B6FW0pFF",
  "price": "1.100000",
  "origQty": "1.300000",
  "executedQty": "0.000000",
  "cummulativeQuoteQty": "0.000000",
  "status": "EXPIRED_IN_MATCH",
  "timeInForce": "GTC",
  "type": "LIMIT",
  "side": "BUY",
  "stopPrice": "0.000000",
  "icebergQty": "0.000000",
  "time": 1670217957458,
  "updateTime": 1670217957498,
  "isWorking": true,
  "workingTime": 1670217957458,
  "origQuoteOrderQty": "0.000000",
  "selfTradePreventionMode": "NONE",
  "preventedMatchId": 1,
  "preventedQuantity": "1.300000"
}

Maker 订单 3

{
  "symbol": "BTCUSDT",
  "orderId": 4,
  "orderListId": -1,
  "clientOrderId": "8QZ3taGcU4gND59TxHAcR0",
  "price": "1.000000",
  "origQty": "8.100000",
  "executedQty": "0.000000",
  "cummulativeQuoteQty": "0.000000",
  "status": "EXPIRED_IN_MATCH",
  "timeInForce": "GTC",
  "type": "LIMIT",
  "side": "BUY",
  "stopPrice": "0.000000",
  "icebergQty": "0.000000",
  "time": 1670217957478,
  "updateTime": 1670217957498,
  "isWorking": true,
  "workingTime": 1670217957478,
  "origQuoteOrderQty": "0.000000",
  "selfTradePreventionMode": "NONE",
  "preventedMatchId": 2,
  "preventedQuantity": "8.100000"
}

Taker 订单的响应

{
  "symbol": "BTCUSDT",
  "orderId": 5,
  "orderListId": -1,
  "clientOrderId": "WRzbhp257NhZsIJW4y2Nri",
  "transactTime": 1670217957498,
  "price": "1.000000",
  "origQty": "3.000000",
  "executedQty": "0.000000",
  "cummulativeQuoteQty": "0.000000",
  "status": "NEW",
  "timeInForce": "GTC",
  "type": "LIMIT",
  "side": "SELL",
  "workingTime": 1670217957498,
  "fills": [],
  "preventedMatches": [
    {
      "preventedMatchId": 0,
      "makerOrderId": 2,
      "price": "1.200000",
      "makerPreventedQuantity": "1.200000"
    },
    {
      "preventedMatchId": 1,
      "makerOrderId": 3,
      "price": "1.100000",
      "makerPreventedQuantity": "1.300000"
    },
    {
      "preventedMatchId": 2,
      "makerOrderId": 4,
      "price": "1.000000",
      "makerPreventedQuantity": "8.100000"
    }
  ],
  "selfTradePreventionMode": "EXPIRE_MAKER"
}

情况 C - 用户发送带有 EXPIRE_TAKER 的订单,该订单将与订单薄上已有的订单撮合。

Maker 订单 1: symbol=BTCUSDT side=BUY type=LIMIT quantity=1.2 price=1.2  selfTradePreventionMode=NONE
Maker 订单 2: symbol=BTCUSDT side=BUY type=LIMIT quantity=1.3 price=1.1  selfTradePreventionMode=NONE
Maker 订单 3: symbol=BTCUSDT side=BUY type=LIMIT quantity=8.1 price=1    selfTradePreventionMode=NONE
Taker 订单 1: symbol=BTCUSDT side=SELL type=LIMIT quantity=3 price=1 selfTradePreventionMode=EXPIRE_TAKER

结果: : 已经在订单薄上的订单将保留,而taker订单将过期。

Maker 订单 1

{
  "symbol": "BTCUSDT",
  "orderId": 2,
  "orderListId": -1,
  "clientOrderId": "NpwW2t0L4AGQnCDeNjHIga",
  "price": "1.200000",
  "origQty": "1.200000",
  "executedQty": "0.000000",
  "cummulativeQuoteQty": "0.000000",
  "status": "NEW",
  "timeInForce": "GTC",
  "type": "LIMIT",
  "side": "BUY",
  "stopPrice": "0.000000",
  "icebergQty": "0.000000",
  "time": 1670219811986,
  "updateTime": 1670219811986,
  "isWorking": true,
  "workingTime": 1670219811986,
  "origQuoteOrderQty": "0.000000",
  "selfTradePreventionMode": "NONE"
}

Maker 订单 2

{
  "symbol": "BTCUSDT",
  "orderId": 3,
  "orderListId": -1,
  "clientOrderId": "TSAmJqGWk4YTB2yA9p04UO",
  "price": "1.100000",
  "origQty": "1.300000",
  "executedQty": "0.000000",
  "cummulativeQuoteQty": "0.000000",
  "status": "NEW",
  "timeInForce": "GTC",
  "type": "LIMIT",
  "side": "BUY",
  "stopPrice": "0.000000",
  "icebergQty": "0.000000",
  "time": 1670219812007,
  "updateTime": 1670219812007,
  "isWorking": true,
  "workingTime": 1670219812007,
  "origQuoteOrderQty": "0.000000",
  "selfTradePreventionMode": "NONE"
}

Maker 订单 3

{
  "symbol": "BTCUSDT",
  "orderId": 4,
  "orderListId": -1,
  "clientOrderId": "L6FmpCJJP6q4hCNv4MuZDG",
  "price": "1.000000",
  "origQty": "8.100000",
  "executedQty": "0.000000",
  "cummulativeQuoteQty": "0.000000",
  "status": "NEW",
  "timeInForce": "GTC",
  "type": "LIMIT",
  "side": "BUY",
  "stopPrice": "0.000000",
  "icebergQty": "0.000000",
  "time": 1670219812026,
  "updateTime": 1670219812026,
  "isWorking": true,
  "workingTime": 1670219812026,
  "origQuoteOrderQty": "0.000000",
  "selfTradePreventionMode": "NONE"
}

Taker 订单的状态

{
  "symbol": "BTCUSDT",
  "orderId": 5,
  "orderListId": -1,
  "clientOrderId": "kocvDAi4GNN2y1l1Ojg1Ri",
  "price": "1.000000",
  "origQty": "3.000000",
  "executedQty": "0.000000",
  "cummulativeQuoteQty": "0.000000",
  "status": "EXPIRED_IN_MATCH",
  "timeInForce": "GTC",
  "type": "LIMIT",
  "side": "SELL",
  "stopPrice": "0.000000",
  "icebergQty": "0.000000",
  "time": 1670219812046,
  "updateTime": 1670219812046,
  "isWorking": true,
  "workingTime": 1670219812046,
  "origQuoteOrderQty": "0.000000",
  "selfTradePreventionMode": "EXPIRE_TAKER",
  "preventedMatchId": 0,
  "preventedQuantity": "3.000000"
}

情况 D - 用户发送带有 EXPIRE_BOTH 的订单,该订单将与订单薄上已有的订单撮合。

Maker 订单: symbol=BTCUSDT side=BUY type=LIMIT quantity=1 price=1 selfTradePreventionMode=NONE
Taker 订单: symbol=BTCUSDT side=SELL type=LIMIT quantity=3 price=1 selfTradePreventionMode=EXPIRE_BOTH

结果: 两个订单都将过期。

Maker 订单

{
  "symbol": "ABCDEF",
  "orderId": 2,
  "orderListId": -1,
  "clientOrderId": "2JPC8xjpLq6Q0665uYWAcs",
  "price": "1.000000",
  "origQty": "1.000000",
  "executedQty": "0.000000",
  "cummulativeQuoteQty": "0.000000",
  "status": "EXPIRED_IN_MATCH",
  "timeInForce": "GTC",
  "type": "LIMIT",
  "side": "BUY",
  "stopPrice": "0.000000",
  "icebergQty": "0.000000",
  "time": 1673842412831,
  "updateTime": 1673842413170,
  "isWorking": true,
  "workingTime": 1673842412831,
  "origQuoteOrderQty": "0.000000",
  "selfTradePreventionMode": "NONE",
  "preventedMatchId": 0,
  "preventedQuantity": "1.000000"
}

Taker 订单

{
  "symbol": "ABCDEF",
  "orderId": 5,
  "orderListId": -1,
  "clientOrderId": "qMaz8yrOXk2iUIz74cFkiZ",
  "transactTime": 1673842413170,
  "price": "1.000000",
  "origQty": "3.000000",
  "executedQty": "0.000000",
  "cummulativeQuoteQty": "0.000000",
  "status": "EXPIRED_IN_MATCH",
  "timeInForce": "GTC",
  "type": "LIMIT",
  "side": "SELL",
  "workingTime": 1673842413170,
  "fills": [],
  "preventedMatches": [
    {
      "preventedMatchId": 0,
      "makerOrderId": 2,
      "price": "1.000000",
      "takerPreventedQuantity": "3.000000",
      "makerPreventedQuantity": "1.000000"
    }
  ],
  "selfTradePreventionMode": "EXPIRE_BOTH",
  "tradeGroupId": 1,
  "preventedQuantity": "3.000000"
}

情况 E - 用户在订单薄上有一个带有 EXPIRE_MAKER 的订单,然后发送一个带有 EXPIRE_TAKER 的新订单,该订单将与订单薄上的订单撮合。

Maker 订单: symbol=BTCUSDT side=BUY type=LIMIT quantity=1 price=1 selfTradePreventionMode=EXPIRE_MAKER
Taker 订单: symbol=BTCUSDT side=SELL type=LIMIT quantity=1 price=1 selfTradePreventionMode=EXPIRE_TAKER

结果: 将使用 taker 订单的 STP 模式,因此 taker 订单将过期。

Maker 订单

{
    "symbol": "ABCDEF",
    "orderId": 0,
    "orderListId": -1,
    "clientOrderId": "jFUap8iFwwgqIpOfAL60GS",
    "price": "1.000000",
    "origQty": "1.000000",
    "executedQty": "0.000000",
    "cummulativeQuoteQty": "0.000000",
    "status": "NEW",
    "timeInForce": "GTC",
    "type": "LIMIT",
    "side": "BUY",
    "stopPrice": "0.000000",
    "icebergQty": "0.000000",
    "time": 1670220769261,
    "updateTime": 1670220769261,
    "isWorking": true,
    "workingTime": 1670220769261,
    "origQuoteOrderQty": "0.000000",
    "selfTradePreventionMode": "EXPIRE_MAKER"
}

Taker 订单

{
    "symbol": "ABCDEF",
    "orderId": 1,
    "orderListId": -1,
    "clientOrderId": "zxrvnNNm1RXC3rkPLUPrc1",
    "transactTime": 1670220800315,
    "price": "1.000000",
    "origQty": "1.000000",
    "executedQty": "0.000000",
    "cummulativeQuoteQty": "0.000000",
    "status": "EXPIRED_IN_MATCH",
    "timeInForce": "GTC",
    "type": "LIMIT",
    "side": "SELL",
    "workingTime": 1670220800315,
    "fills": [],
    "preventedMatches": [
        {
            "preventedMatchId": 0,
            "makerOrderId": 0,
            "price": "1.000000",
            "takerPreventedQuantity": "1.000000"
        }
    ],
    "selfTradePreventionMode": "EXPIRE_TAKER",
    "preventedQuantity": "1.000000"
}

情况 F - 用户发送带有 EXPIRE_MAKER 的市价订单,该订单将与订单薄上已有的订单撮合。

Maker 订单: symbol=ABCDEF side=BUY type=LIMIT quantity=1 price=1  selfTradePreventionMode=NONE
Taker 订单: symbol=ABCDEF side=SELL type=MARKET quantity=1 selfTradePreventionMode=EXPIRE_MAKER

结果: 由于 STP,订单薄上的订单会过期,状态为 EXPIRED_IN_MATCH。 由于订单薄上的流动性低,新订单也已过期但状态为 EXPIRED

Maker 订单

{
  "symbol": "ABCDEF",
  "orderId": 2,
  "orderListId": -1,
  "clientOrderId": "7sgrQQInL69XDMQpiqMaG2",
  "price": "1.000000",
  "origQty": "1.000000",
  "executedQty": "0.000000",
  "cummulativeQuoteQty": "0.000000",
  "status": "EXPIRED_IN_MATCH",
  "timeInForce": "GTC",
  "type": "LIMIT",
  "side": "BUY",
  "stopPrice": "0.000000",
  "icebergQty": "0.000000",
  "time": 1670222557456,
  "updateTime": 1670222557478,
  "isWorking": true,
  "workingTime": 1670222557456,
  "origQuoteOrderQty": "0.000000",
  "selfTradePreventionMode": "NONE",
  "preventedMatchId": 0,
  "preventedQuantity": "1.000000"
}

Taker 订单

{
  "symbol": "ABCDEF",
  "orderId": 3,
  "orderListId": -1,
  "clientOrderId": "zqhsgGDEcdhxy2oza2Ljxd",
  "transactTime": 1670222557478,
  "price": "0.000000",
  "origQty": "1.000000",
  "executedQty": "0.000000",
  "cummulativeQuoteQty": "0.000000",
  "status": "EXPIRED",
  "timeInForce": "GTC",
  "type": "MARKET",
  "side": "SELL",
  "workingTime": 1670222557478,
  "fills": [],
  "preventedMatches": [
    {
      "preventedMatchId": 0,
      "makerOrderId": 2,
      "price": "1.000000",
      "makerPreventedQuantity": "1.000000"
    }
  ],
  "selfTradePreventionMode": "EXPIRE_MAKER"
}