> ## Documentation Index
> Fetch the complete documentation index at: https://docs.intention.xyz/llms.txt
> Use this file to discover all available pages before exploring further.

# Self-Trade Prevention

> Intention's matching engine prevents any order from matching another order owned by the same account by cancelling the resting maker.

Self-Trade Prevention (STP) stops an account's taker order from matching against its own resting maker order. It is a baseline market-integrity mechanism on every modern exchange: without STP, users could manufacture fake volume and liquidity by crossing their own orders, and algo traders would get accidental self-fills when their strategies happen to overlap.

Intention enables STP by default for every user and every contract. No configuration is required.

## How it works

When a taker order enters matching, the engine checks the account on each resting maker order it is about to fill. If both orders belong to the same user:

<Steps>
  <Step title="Cancel the maker">
    The resting maker is removed from the book. Its status becomes `EXPIRED_BY_STP`. No fill is recorded and no fee is charged.
  </Step>

  <Step title="Skip, do not fill">
    The taker is neither cancelled nor modified. It continues to the next resting order in the book.
  </Step>

  <Step title="Repeat">
    If the next resting maker is also from the same user, the same thing happens again. This loop continues until the taker either matches a different user's maker, fills completely, or runs out of acceptable price levels.
  </Step>
</Steps>

## Walked example

Suppose the ask side of the BTC book looks like this:

* 101: 1 BTC (User A)
* 102: 2 BTC (User B)
* 103: 3 BTC (User C)

User A submits a market buy for 5 BTC.

1. The taker meets 1 BTC @ 101 from User A. Same user → STP triggers. The 1 BTC @ 101 maker is cancelled with status `EXPIRED_BY_STP`. No fill.
2. The taker continues with 5 BTC to buy and meets 2 BTC @ 102 from User B. Different user → normal fill. Taker has 3 BTC remaining.
3. The taker meets 3 BTC @ 103 from User C. Different user → normal fill. Taker fully filled.

User A ends with 5 BTC bought at an average price of `(2 × 102 + 3 × 103) / 5 = 102.6`, and its own maker order is cleanly expired.

## Scope

STP operates at the **individual account** level. In the current implementation, sub-accounts under the same master are treated as different users — a taker in a sub-account can match a maker in the parent account, for example. A future iteration may introduce user-configurable trade groups to extend STP across related accounts.

## API surfaces

Every interface that exposes order status — REST, WebSocket, and historical queries — reflects the `EXPIRED_BY_STP` status so clients can distinguish STP cancellations from regular cancellations and from fills. Integrators should update any code that enumerates terminal order states to handle this new value.

<Note>
  STP is always on. There is no API flag to disable it. This matches the approach taken by several major perp venues and simplifies market-integrity audits.
</Note>

## Why Intention picked this design

Intention uses the simplest STP flavor ("cancel maker") for the initial release, following the pattern that has worked well on other on-chain perps. It is easy to reason about, easy for algo traders to handle, and avoids edge cases where a large taker could be cancelled midway due to a small accidental overlap. More flexible STP modes — for example, cancel-taker or cancel-both, and cross-account trade groups — are planned as a later enhancement.
