跳到主要内容

常见问题

U本位合约 API 常见问题解答。

什么是 Self Trade Prevention - STP?

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

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

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

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

STP 触发时会发生什么?

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

  • EXPIRE_TAKER - 此模式通过立即使吃单者(taker)的剩余数量过期来预防交易。
  • EXPIRE_MAKER - 此模式通过立即使潜在挂单者(maker)的剩余数量过期来预防交易。
  • EXPIRE_BOTH - 此模式通过立即同时使吃单和挂单者的剩余数量过期来预防交易。

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

如何在订单上设置自我交易预防?

自我交易预防可以通过下单接口的参数 selfTradePreventionMode 设置,相关接口如下:

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

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

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

每个账户可以从 GET /fapi/v1/accountConfig(REST API)确认账户是否属于同一个 tradeGroupId。

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

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

我们将在之后的更新提供将子账户设置为同一 tradeGroupId 的功能。

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

所有 GET fapi/v1/exchangeInfo 中的交易对都支持 selfTradePreventionMode

哪些订单类型支持 STP?

LIMIT / MARKET / STOP / TAKE_PROFIT / STOP_MARKET / TAKE_PROFIT_MARKET / TRAILING_STOP_MARKET 在 Time in force(timeInForce) 设置为 GTC / IOC / GTD 时支持 STP。

当 Time in force(timeInForce) 为 FOKGTX 时订单 STP 设置不生效。

改单是否支持 STP?

目前不支持。改单会将订单的 selfTradePreventionMode 重置为 NONE

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

订单的状态会是 EXPIRED_IN_MATCH

在用户信息流推送 ORDER_TRADE_UPDATE,如果订单因为 STP 过期字段 X 会显示 EXPIRED_IN_MATCH

{
"e": "ORDER_TRADE_UPDATE",
"E": 1568879465651,
"T": 1568879465650,
"o": {
"s": "BTCUSDT",
"c": "TEST",
"S": "SELL",
"o": "TRAILING_STOP_MARKET",
"f": "GTC",
"q": "0.001",
"p": "0",
"ap": "0",
"sp": "7103.04",
"x": "EXPIRED",
"X": "EXPIRED_IN_MATCH",
"i": 8886774,
"l": "0",
"z": "0",
"L": "0",
"N": "USDT",
"n": "0",
"T": 1568879465650,
"t": 0,
"b": "0",
"a": "9.91",
"m": false,
"R": false,
"wt": "CONTRACT_PRICE",
"ot": "TRAILING_STOP_MARKET",
"ps": "LONG",
"cp": false,
"AP": "7476.89",
"cr": "5.0",
"pP": false,
"si": 0,
"ss": 0,
"rp": "0",
"V": "EXPIRE_MAKER",
"pm": "QUEUE",
"gtd": 1768879465650
}
}

STP 的一些示例

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

情况 A - EXPIRE_MAKER 模式

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

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

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

Maker 订单 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": "EXPIRE_MAKER",
"goodTillDate": "null",
"priceProtect": false,
"origType": "LIMIT",
"time": 1692849639460,
"updateTime": 1692849639460
}

Maker 订单 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": "EXPIRE_MAKER",
"goodTillDate": "null",
"priceProtect": false,
"origType": "LIMIT",
"time": 1692849639460,
"updateTime": 1692849639460
}

Taker 订单的响应:

{
"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": "null",
"priceProtect": false,
"origType": "LIMIT",
"time": 1692849639460,
"updateTime": 1692849639460
}

情况 B - EXPIRE_TAKER 模式

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

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

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

Maker 订单 1:

{
"orderId": 292864710,
"symbol": "BTCUSDT",
"status": "FILLED",
"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": "null",
"priceProtect": false,
"origType": "LIMIT",
"time": 1692849639460,
"updateTime": 1692849639460
}

Maker 订单 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": "EXPIRE_MAKER",
"goodTillDate": "null",
"priceProtect": false,
"origType": "LIMIT",
"time": 1692849639460,
"updateTime": 1692849639460
}

Taker 订单的状态:

{
"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": "null",
"priceProtect": false,
"origType": "LIMIT",
"time": 1692849639460,
"updateTime": 1692849639460
}

情况 C - EXPIRE_BOTH 模式

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

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

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

Maker 订单:

{
"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": "null",
"priceProtect": false,
"origType": "LIMIT",
"time": 1692849639460,
"updateTime": 1692849639460
}

Taker 订单:

{
"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": "null",
"priceProtect": false,
"origType": "LIMIT",
"time": 1692849639460,
"updateTime": 1692849639460
}

情况 D - Taker 使用 EXPIRE_TAKER,Maker 使用 EXPIRE_MAKER

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

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

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

Maker 订单:

{
"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": "null",
"priceProtect": false,
"origType": "LIMIT",
"time": 1692849639460,
"updateTime": 1692849639460
}

Taker 订单:

{
"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": "null",
"priceProtect": false,
"origType": "LIMIT",
"time": 1692849639460,
"updateTime": 1692849639460
}

情况 E - 市价订单与 EXPIRE_MAKER

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

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

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

Maker 订单:

{
"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": "null",
"priceProtect": false,
"origType": "LIMIT",
"time": 1692849639460,
"updateTime": 1692849639460
}

Taker 订单:

{
"orderId": 292864712,
"symbol": "BTCUSDT",
"status": "EXPIRED",
"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_MAKER",
"goodTillDate": "null",
"priceProtect": false,
"origType": "LIMIT",
"time": 1692849639460,
"updateTime": 1692849639460
}