Self-Trade Prevention: When Your Own Orders Match
A self-trade is a trade between two orders that belong to the same account, or to accounts in the same trade group. It is easy to create by accident: a market-making loop quotes both sides, a rebalancing script crosses its own resting order, or two strategies share one account. Venues block it with a set of modes that decide which order expires, and the mode that applies is usually the taker's, not the maker's.

Cover artwork: CoinSoso · AI-generated, not a photograph of a real venue, product or market capture.
Key takeaways
- Self-trade prevention compares the two sides of a potential match and expires one or both before a trade is printed.
- Binance documents six modes: NONE, EXPIRE_TAKER, EXPIRE_MAKER, EXPIRE_BOTH, DECREMENT and TRANSFER.
- The taker order's mode normally decides the outcome; the maker's mode is ignored unless both sides specify TRANSFER.
- An order removed by STP carries the status EXPIRED_IN_MATCH, which is different from CANCELED and from EXPIRED.
- OKX exposes three modes, cancel_maker, cancel_taker and cancel_both, defaults to cancel_maker, and rejects cancel_both combined with FOK.
The trade that should not exist
Most matching-engine explanations assume two different participants. One wants to buy, one wants to sell, and the engine finds the price where both are willing. A self-trade breaks that assumption: the same person is on both sides, so the trade moves coins from one pocket to another, pays two fees, and prints volume that no independent counterparty agreed to.
The accidental versions are common. A market-making bot quotes a bid and an ask around a mid price. The market moves, the bot reprices both sides, and for a moment the new ask is at or below its own resting bid. A rebalancing script sends a sell while an older buy from the same script is still resting. Two strategies share one exchange account because the account is the unit of margin, and their orders meet in the book.
Venues treat this as a problem worth solving at the matching layer rather than leaving to the participant. The reason is not only fairness. Self-trades can be used to generate volume for rebates, to wash trades for tax or reporting purposes, or to create the appearance of liquidity. A venue that lets them through inherits the regulatory and reputational cost.
Binance’s six modes
Binance’s Spot API documents six self-trade prevention modes for the selfTradePreventionMode parameter. The definitions are worth reading in full because the differences are operational, not cosmetic.
| Mode | What Binance says it does |
|---|---|
NONE |
“This mode exempts the order from self-trade prevention.” Accounts and trade groups are not compared, no orders are expired, and the trade occurs. |
EXPIRE_TAKER |
“This mode prevents a trade by immediately expiring the taker order’s remaining quantity.” |
EXPIRE_MAKER |
“This mode prevents a trade by immediately expiring the potential maker order’s remaining quantity.” |
EXPIRE_BOTH |
“This mode prevents a trade by immediately expiring both the taker and the potential maker orders’ remaining quantities.” |
DECREMENT |
“This mode increases the prevented quantity of both orders by the amount of the prevented match.” The smaller order expires, or both if they have the same quantity. |
TRANSFER |
For orders from the same account, behaves like DECREMENT. For different accounts sharing a tradeGroupId, the last prevented quantity and its notional are transferred between the accounts. |
The first four are easy to reason about: one side disappears, the other stays. DECREMENT is the one that surprises people. It does not choose a winner. It reduces both orders by the size of the prevented match, so a 10 BTC bid meeting a 4 BTC ask leaves a 6 BTC bid and a 0 BTC ask — the smaller order is gone, and the larger one keeps its remaining size. If the two are equal, both disappear.
TRANSFER is stranger still. It exists for accounts that are related but not identical, and it moves the prevented quantity and notional between them rather than simply deleting the overlap. For most retail and prop clients, TRANSFER is not the mode they want; it is a tool for a specific account structure.
The taker decides
The most important rule in Binance’s FAQ is not in the mode table. It is this: “STP behavior is typically determined by the STP mode of the taker order only.”
That means the resting order’s mode is usually irrelevant. If a maker order was sent with EXPIRE_MAKER and a taker arrives with EXPIRE_TAKER, the taker’s choice governs, and the taker is the one that expires. The maker’s preference does not protect it.
The exception is TRANSFER. For that behaviour to occur, both the maker and the taker must specify TRANSFER. If the taker asks for TRANSFER and the maker specifies something else, Binance says the behaviour falls back to DECREMENT.
For a client, this simplifies the design in one way and complicates it in another. You do not need to coordinate modes across every resting order, because only the incoming order’s mode matters. But you do need to set the mode on the order that is about to take, at the moment you send it, and you need to know what the venue will do to the order that is already resting.
The status that tells you it happened
An order removed by STP is not CANCELED. Binance documents a separate status, EXPIRED_IN_MATCH, described as an order “expired by the exchange due to STP.”
This matters for reconciliation. Three statuses can look similar in a dashboard and mean different things:
CANCELED— the user cancelled the order.EXPIRED— the order was removed by its own type’s rules, such as an IOC remainder, or by the exchange during maintenance or liquidation.EXPIRED_IN_MATCH— the order was removed because it would have self-traded.
A client that maps every non-fill to “cancelled” will lose the distinction between a decision it made, a rule it chose, and a prevention event it may need to investigate. The user data stream carries the execution report that contains the status; the execution report guide explains how to read the fill fields around it.
Trade groups: when two accounts are one participant
STP is not limited to a single account. Binance compares orders that belong to the same account or to accounts with the same tradeGroupId. The FAQ defines a trade group as different accounts sharing that identifier, and says orders from members are eligible for STP according to the taker order’s mode.
A tradeGroupId of -1 means the account has no group set, so STP can only take place between orders of the same account. The value can be read from the account endpoint and appears in prevented-match responses.
This is the part of STP that a multi-account operation has to plan. Two accounts trading the same strategy, with no trade group, can trade with each other and neither venue nor client will call it a self-trade. Whether that is acceptable depends on why the accounts are separate. If they are separate legal entities with separate beneficial owners, it may be legitimate. If they are the same owner’s accounts, the absence of a group is a gap in the control, not a feature.
OKX: three modes and a FOK exception
OKX approaches the same problem with a smaller vocabulary. Its stpMode parameter accepts cancel_maker, cancel_taker and cancel_both. The account-level acctStpMode is used by default, and the documented default value is cancel_maker.
Two details in OKX’s documentation are worth carrying into a client.
First, OKX states that “the STP mode is always taken based on the configuration in the taker order.” That is the same principle as Binance’s taker rule, stated without the TRANSFER exception.
Second, cancel_both does not support FOK. OKX says combining stpMode=cancel_both with ordType=fok returns error 50016. A strategy that uses FOK for all-or-nothing entries and cancel_both for self-trade protection has to choose which guarantee matters more for that order.
OKX also documents that mandatory self-trade prevention does not add latency. That is a claim about implementation rather than a user-facing behaviour, but it matters for anyone who assumed STP was a post-trade check that could be disabled for speed.
Why the default is maker-expiry
Binance’s October 2023 announcement made STP mandatory for all Spot and Margin users and stated that the default mode is for the maker order to expire. That default is a policy choice, and it is worth understanding rather than accepting.
If a taker would self-match, expiring the maker keeps the taker alive. The incoming order can continue matching against other makers at the same price. Expiring the taker would remove the new instruction entirely, which is safer for the resting order but worse for the participant who just sent an order expecting it to work.
Maker-expiry is therefore the compromise that preserves the incoming order’s intent while removing the stale side. It also means a market-making bot can lose its resting quote without ever sending a cancel, which is exactly the kind of event a reconciliation process needs to catch.
What STP does not solve
Self-trade prevention is a matching-engine control, not a complete market-abuse control. Four gaps are worth naming.
It does not identify every related account. Accounts without a shared tradeGroupId are treated as independent. A group is a configuration an operator chooses, and a venue cannot infer beneficial ownership from an API key.
It does not stop wash trading across venues. Two accounts at two different exchanges can trade with each other freely, and no single venue sees both sides. Cross-venue wash trading is a surveillance problem, not a matching-engine problem.
It does not decide the tax treatment. A blocked self-trade produces no fill, so there is no disposal to report. But a self-trade that was allowed under NONE, or that happened across ungrouped accounts, may still be a wash sale or a reportable transaction depending on jurisdiction. The wash sale guide covers the US rules and why crypto is treated differently from securities.
It does not guarantee a better price. Expiring the maker removes liquidity from the book. If the taker was the only order at that price, the remaining book may be worse for the next participant. STP protects the participant from trading with itself; it does not improve the market for anyone else.
A checklist for a client that can self-trade
- Decide the STP mode per strategy, not per account, if the strategy’s behaviour differs.
- Set the mode on the taker order, because that is the one the venue reads.
- Treat
EXPIRED_IN_MATCHas its own event in reconciliation, not as a cancellation. - If two accounts belong to the same owner, decide whether they should share a
tradeGroupId;-1means they do not. - On OKX, check whether any strategy combines
cancel_bothwith FOK; the combination is rejected. - Log the prevented quantity when using
DECREMENTorTRANSFER, because the remaining size is not the size you sent. - Do not use
NONEas a performance optimisation unless the account genuinely has no self-trade risk.
Sources and what they support
- Binance Spot API, Self Trade Prevention FAQ — defines all six modes, states that the taker order’s mode normally governs, defines
EXPIRED_IN_MATCH, and explainstradeGroupIdand the-1value. Read 2026-11-03. - Binance, Enhancing User Protection with Mandatory Self-Trade Prevention (25 October 2023) — states that the requirement applies to all Spot and Margin users and that the default mode is maker expiry. Read 2026-11-03.
- OKX API v5, Place order — defines
stpModevalues, thecancel_makerdefault, the taker-order rule, and the FOK restriction oncancel_both(error 50016). Read 2026-11-03.
Risk note. STP behaviour is set by each venue and can change. The mode names and rules above were read from the venues’ own documentation on 2026-11-03; a production client should verify the status it receives rather than infer it from the request. Nothing here is investment advice.
Sources
How this was researched. Written from primary documentation and the exchange or protocol's own published material, with sources listed at the end of the article.
Primary sources for the factual claims on this page. A date appears only where a human has actually read the source; where it is missing, the check is still outstanding.
Frequently asked questions
What is a self-trade, exactly?
It is a match in which the buyer and the seller are the same account, or two accounts that share a trade group identifier. The orders are genuinely on opposite sides of the book; the problem is that the same beneficial owner is on both sides, so the trade does not transfer economic risk between independent parties.
Which order expires when STP triggers?
It depends on the mode, and normally on the taker order's mode. EXPIRE_TAKER removes the incoming order's remaining quantity, EXPIRE_MAKER removes the resting order's remaining quantity, and EXPIRE_BOTH removes both. DECREMENT reduces both orders by the prevented quantity rather than removing one outright.
Does the maker order's STP setting matter?
Usually no. Binance's FAQ states that STP behaviour is typically determined by the taker order's mode only. The exception is TRANSFER, which requires both the maker and the taker to specify TRANSFER; if the taker asks for TRANSFER and the maker does not, the behaviour falls back to DECREMENT.
What status does an order get when STP removes it?
Binance documents EXPIRED_IN_MATCH, meaning the order was expired by the exchange due to STP. That is distinct from CANCELED, which is a user cancellation, and from EXPIRED, which covers order-type rules such as an IOC remainder.
Can two separate accounts avoid self-trade prevention?
Only if they are placed in the same trade group. Binance compares accounts that share a tradeGroupId; a value of -1 means no group is set, so STP applies only within a single account. Grouping is an account configuration, not something an individual order can assert.
Where to go next
Independent research. Each card shows the platform’s invite code, and its Create Account button is a referral link that may earn us a commission at no extra cost to you. Whether an account can be opened is decided by the platform at sign-up.
Binance

One of the largest global exchanges by traded volume, with a very broad product range.
20% Trading Fee Rebate
Use invite code con888 when signing up to enjoy trading fee benefits.
Download from the exchange's official download service. Verify the source and follow the on-screen installation instructions.
Do not install an APK from an unknown source, or one that has been modified or cannot be checked.
OKX

A large global exchange offering spot, derivatives and a self-custody wallet.
20% Trading Fee Rebate
Enter invite code con888 when signing up to check available trading fee benefits.
Download from the exchange's official download service. Verify the source and follow the on-screen installation instructions.
Do not install an APK from an unknown source, or one that has been modified or cannot be checked.