订单状态
币安挂单没撤却显示已过期:自己的买单碰上自己的卖单会怎样
自成交保护是挂单过期的一种原因。默认 EXPIRE_MAKER 模式会结束旧挂单的剩余部分;先查过期原因,再决定要不要重新下单。

没点撤单,币安挂着的限价单却显示已过期,可能是自成交保护(Self-Trade Prevention,简称 STP)拦住了自己的买卖单相互成交。比如旧卖单还挂着,新买单撮合到它时,系统按 STP 模式处理。仅凭“已过期”三个字不能认定原因;查到 EXPIRED_IN_MATCH 或对应的自成交拦截记录,才有直接依据。
币安公告说明,默认的 EXPIRE_MAKER 模式会让旧挂单的全部剩余数量过期,新单继续处理。旧单此前的成交保留,未成交部分占用的资产解除锁定。如果接口下单时选了其他 STP 模式,结束的可能是新单或两张单,要按记录里的实际模式判断。
没点撤单,旧挂单为什么会结束
币安现货接口文档的自成交保护常见问题这样定义:“自我交易预防是指阻止订单与来自同一账户或者同一 tradeGroupId 账户的订单交易。”tradeGroupId 是把几个账户编成同一交易组的设置;没有设置时,这条规则只在同一个账户内部生效。

是否结束旧单,要看这次撮合使用的模式。先分清这三种会使剩余数量全部过期的模式:
- EXPIRE_MAKER:让订单簿上原本挂着、等着被成交的那张单(挂单方)的剩余数量立刻过期。
- EXPIRE_TAKER:让新来的、主动去吃单的那张(吃单方)的剩余数量过期。
- EXPIRE_BOTH:两张的剩余数量都过期。
BTCUSDT 的公开交易规则在 2026 年 10 月返回的 defaultSelfTradePreventionMode 是 EXPIRE_MAKER;allowedSelfTradePreventionModes 还列有 DECREMENT 和 TRANSFER,不能把所有模式都理解成“旧单全过期”。查其他交易对时,把链接里的 BTCUSDT 换成对应代码,查找这两个字段。
币安在 2023 年 10 月 11 日的上线公告中明确写了默认 EXPIRE_MAKER,并说明 API 用户可以另选模式。下面两例都按这个默认模式讲。若你用接口或交易程序下单,先核实实际传入的 selfTradePreventionMode;对于这里列出的三种过期模式,以新来的吃单所选模式为准。
默认模式下,两种买卖单相遇的例子
假设一:你在 AAA/USDT 挂着卖出 10 AAA、价格 1.20 的限价单,此刻它处在盘口最低卖价,并且排在该价位队列的最前面。你改了主意,又下了一张市价买单,或者价格不低于 1.20 的限价买单。新买单最先碰到的是你自己的卖单,于是这张卖单剩下的 10 AAA 全部过期,不是只过期和买单重叠的那几个。
假设二:你挂着 0.95 买入 50 AAA 的限价单,排在买盘最前面,接着用市价卖出手里另外的 AAA。卖单先碰到的是自己那张买单,于是买单过期,原本给它锁着的 USDT 回到可用余额。
两例中的旧单过期后,新单继续处理:能匹配别人的单就成交;剩余数量只有在订单类型和有效方式允许挂单时才留在订单簿上,例如 GTC 限价单。市价单、IOC 或 FOK 不会因为避开了自己的旧单就自动变成普通挂单。
价格能匹配只是条件之一,还要轮到这两张单实际撮合。假如新单先被别人的订单全部成交,就不会再碰到自己的旧单;旧单价格不在新单可成交范围内,两张单也不会互相触发 STP。
自成交保护过期后,已成交部分和锁定余额怎么处理
文档对三种模式的写法都是让订单的“剩余数量”过期。所以一张旧单如果之前已经成交了一部分,假设原委托 10 AAA,已卖出 3 AAA,剩余数量 = 10 − 3 = 7 AAA。此前 3 AAA 的成交和手续费记录保留;按 EXPIRE_MAKER 处理时,过期的是剩下的 7 AAA。
被拦下的这一段没有成交,就不会出现在成交历史里,也不会为这一段扣成交手续费。挂单原本锁着的那部分资产,卖单锁的是 AAA,买单锁的是 USDT,在订单结束后应当回到可用余额。若订单已经结束,可用余额仍与预期不符,见总资产有钱却不能下单:可用余额和锁定余额怎么看继续排查。
怎么确认是自成交保护,而不是别的原因
在币安网页或 App 的现货订单历史里,筛选交易对和下单日期,打开旧单详情,再找出那张反方向订单对照。不同版本菜单名称可能不同,重点看三处:
- 状态与原因:查看详情是否写明自成交保护。如果只显示“已过期”,还不能区分 STP 和其他过期原因。
- 结束时间:与反方向订单触发撮合的时间对照。时间接近是排查线索,不足以单独证明原因。
- 已成交数量:区分正常成交与被拦下的数量;STP 阻止的那部分不算成交,同一次撮合过程中仍可能有与其他订单的正常成交。
通过接口查订单的话,这种过期有专门的状态码 EXPIRED_IN_MATCH,和普通的 EXPIRED 分开;被拦下的数量记在 preventedQuantity,每次拦截还能用 preventedMatches 接口查到。如果只用网页或 App,详情又没有列出原因,就保留两张订单号与交易对,请官方客服核对,别只按时间相近下结论。
订单显示已过期,还有哪几种原因
过期不只有这一种来源。三处对不上的,按下面几种再排一遍:
- 委托有效方式:IOC 未立即成交的剩余数量会结束;FOK 若不能立即全部成交,整张单都不成交。这些有效方式本身也可能使订单过期,见部分成交以后撤单剩下什么。
- 价格规则:撮合时的成交价超出允许的成交范围,可能使订单过期;这和提交时委托价未通过价格过滤、直接被拒是两回事,见限价单价格超出范围。
- 交易对暂停或下架:交易对状态变了,挂单可能按规则结束,见交易对暂停时的挂单。
如果自己没有手动下反方向单,还要看看交易程序是否下了单,以及有没有属于同一 tradeGroupId 的其他账户。最终仍以订单过期原因和被阻止的撮合记录判断,不能仅凭“当时没操作”排除 STP。
想改价成交时,先撤旧单再下新单
如果只是想调整卖价,应当修改或撤掉原卖单;另下一张买单是在改变买卖方向。你确实想换方向时,先决定旧单要不要保留。直接用反方向新单去碰旧单,在 EXPIRE_MAKER 模式下会结束旧单全部剩余数量,不一定合你的意。
更稳的顺序是:先在当前委托里撤掉旧单,等它在订单历史里变成已撤销、锁定的余额回到可用,再下新单。撤单请求发出后也可能先有成交,所以要以最终订单状态和成交数量为准,再计算新单需要买卖多少。
如果 STP 已经触发,先看旧单剩余数量是否结束,再看新单是已成交、仍在挂单还是也已结束,避免重复下单。记下两张订单号,核对记录的整套顺序可以对照第一次现货交易后怎么看成交和到账。