Self-Trade Prevention (STP)
Automatic protection against self-trading.
Overview
When an incoming (taker) order would match against a resting (maker) order from the same wallet, the engine cancels both orders instead of filling them. This prevents wash trading and protects market makers from accidentally crossing their own quotes.
STP is always active. There is no configuration, no opt-out, and no alternative modes.
Behavior
Strategy: Cancel Both
When a self-trade is detected:
- Maker order is cancelled with reason
"Self-trade prevention" - Taker order is rejected (if no prior fills) or cancelled (if partially filled)
No fill is generated between the two orders.
Wallet-Level Matching
STP compares wallet addresses, not agent keys. If you use agent authorization to sign orders from multiple keys, all orders under the same trading wallet are subject to STP against each other.
Partial Fills Are Preserved
If a taker order fills against other counterparties before encountering a self-trade, those fills are kept.
Example: The book has 5 contracts offered by Wallet B, then 5 contracts offered by Wallet A. Wallet A submits a buy for 10 contracts:
| Step | Match Against | Result |
|---|---|---|
| 1 | Wallet B (5 contracts) | Fill: 5 contracts executed |
| 2 | Wallet A (5 contracts) | Self-trade detected |
Outcome:
- Wallet A receives a fill for 5 contracts against Wallet B
- Wallet A's maker order (5 contracts) is cancelled
- Wallet A's taker order is cancelled with
filled_size: 5
Order Status
| Scenario | Taker Status | Reason |
|---|---|---|
| No prior fills | Rejected | "Self-trade prevention" |
| Partial fills before self-trade | Canceled | "Self-trade prevention (partial fill kept)" |
The maker order is always Canceled with reason "Self-trade prevention".
GTC Orders Do Not Rest After Self-Trade
If a GTC taker order triggers STP, the remaining quantity is not added to the book, even if the order would normally rest. The order is fully terminated.
WebSocket Notifications
Both the taker and maker cancellation/rejection are delivered on the order_updates channel. The reason field indicates STP was the cause.
Monitoring
STP events increment the ht_engine_self_trade_prevented_total Prometheus counter.
FAQ
Can I choose a different STP mode (e.g., cancel-newest or decrement)? No. Hypercall uses cancel-both exclusively.
Does STP apply to perp orders? Yes. STP applies to all order types on the matching engine, both options and perps.
Does STP apply to RFQ trades? Yes. If the taker and a quote provider share the same wallet, the quote is rejected.
I'm a market maker quoting both sides. Will my quotes cancel each other? Only if an incoming order would cause them to cross. Resting orders on opposite sides of the book at different prices coexist normally. STP only triggers at match time.