> For the complete documentation index, see [llms.txt](https://agentdex.gitbook.io/agentdex-docs/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://agentdex.gitbook.io/agentdex-docs/trading/liquidations.md).

# Liquidations

When a position's equity falls below the maintenance margin, AgentDex closes it for you. The procedure is intentionally staged: first try to avoid liquidation by pulling free balance into the position; then try a market close; only if both fail does **auto-deleveraging (ADL)** kick in. The insurance fund absorbs residual losses where possible.

### When liquidation triggers

The engine evaluates the trigger against **mark price**, on every state change. A position is a liquidation candidate if **any** of:

1. Position margin falls below maintenance margin.
2. Mark price has crossed the position's liquidation price.
3. Funding payments would drive margin below zero.
4. Leverage exceeds the per-instrument cap (e.g. after a config change).

The `liquidator` service watches a read-only replica of engine state and dispatches a `LiquidateMessage` for each candidate. Deduplication via pending tracking and a 3-second response timeout keeps repeats out of the queue.

### The 3-step flow

The engine runs one step per `LiquidateMessage`, persists progress on the position, and waits for the next tick:

{% code title="Liquidation flow" %}

```
LiquidateMessage → step 1 (Avoiding) → step 2 (Liquidation) → step 3 (ADL)
```

{% endcode %}

Any step can `abort` early if the position is no longer in trouble (recovered, closed, or its margin became sufficient again).

#### Step 1 — Avoiding

For **cross-margin** positions:

1. Compute `needed = required_margin(mark) − position.margin`. If ≤ 0, abort.
2. If your free `available` ≥ `needed`, transfer it into the position margin and abort.
3. If not enough, cancel all open orders on the instrument (their margin returns to available), retry the transfer, and abort if it now covers.
4. Still not enough → cancel stop-orders, advance to step 2.

For **isolated-margin** positions, the engine never spills wallet balance into position margin. It cancels orders and stops, then advances.

You'll see a `ExtraMarginAddedToFuturePosition` event with `reason: Liquidation` when step 1 saves a position.

#### Step 2 — Market close

1. Cancel all the trader's orders and stops on the instrument.
2. Place a market order on the full position size in the opposite direction.
3. If the book has liquidity, fills come back. The engine computes `excess = margin_after_close − loss`.
4. **Excess positive** — surplus margin (minus a small bonus part) goes to the **insurance fund**.
5. **Excess negative** — the loss exceeds what the position's margin can cover. The insurance fund covers the gap, subject to a per-liquidation cap. If the fund can't cover (low balance or cap exceeded), the position advances to step 3.
6. **No liquidity at all** — book is empty on the close side; advance to step 3.

The fill prices, fees, and the insurance-fund flow are emitted as a `PositionLiquidatedMessage` plus normal trade messages.

#### Step 3 — Auto-deleveraging (ADL)

If a position can't be closed against the book and can't be covered by the insurance fund, the engine closes it against the most profitable counter-side positions:

1. Compute the **bankruptcy price** — the price at which margin equals just the fee reserve.
2. Place an IOC limit order at bankruptcy price for the full size. Any fills against the book count as a normal close.
3. For any remaining size, rank counter-side positions by **PnL %** (most profitable first). Generate matching orders against a virtual book at bankruptcy price.
4. Fire a FillOrKill order against the virtual book. ADL counterparties are notified with `PositionADLMessage`.

ADL is a last-resort mechanism. It guarantees the venue stays solvent without socialising losses across all users, at the cost of forcibly closing some profitable positions at bankruptcy price.

{% hint style="warning" %}
The displayed liquidation price for cross margin can be optimistic if free `available` gets consumed by losses elsewhere.
{% endhint %}

### Liquidation price

For an isolated position (or cross with no spare balance):

```
LiquidationPrice = ClosePrice(
    value, base_volume,
    max_loss = margin - maintenance_margin,
    total_paid, price_step, contract_size,
    reversed
)
```

For cross with available balance, the **displayed** liquidation price treats free `available` as extra margin:

```
LiquidationPriceForCross(available) = ClosePrice(
    ..., max_loss = (margin - MM) + available, ...
)
```

That gives a friendlier number on the UI. However: the **engine trigger** still uses the isolated formula. If your free balance gets eaten by another position's losses, the cross display can be optimistic — see the warning in the cross-margin section of [Margin and leverage](/agentdex-docs/trading/margin-and-leverage.md).

### Bankruptcy price

The price at which margin is exhausted (less a fee reserve):

```
BankruptcyPrice = ClosePrice(
    value, base_volume,
    max_loss = margin - fee_reserve,
    total_paid, price_step, contract_size,
    reversed
)
```

This is the reference for step-2 insurance-fund accounting and step-3 ADL.

### Maintenance margin rate

A single protocol parameter governs the maintenance-margin floor:

| Environment                   | `maintenance_margin_rate` |
| ----------------------------- | ------------------------- |
| Production / staging / dev    | 0.5                       |
| Other environments (defaults) | 0.3                       |

The full MM formula is in [Margin and leverage](/agentdex-docs/trading/margin-and-leverage.md). Per-instrument margin tiers (size-dependent MM) are on the roadmap but not currently active.

### Insurance fund

A dedicated internal account. It receives surplus margin from successful step-2 closes and pays out when step-2 closes leave a gap. Two parameters guard against abuse:

* **`MaximumInsuranceFundUsagePerLiquidation`** (per-instrument): caps how much the fund can pay on a single liquidation.
* **Fund balance**: if the fund cannot cover, the engine routes to ADL.

The fund balance and recent inflows/outflows are visible on the public stats surface (planned — currently exposed only to internal tooling).

### Practical implications

* Get liquidated and you lose your position margin plus the realised loss; the insurance fund absorbs the rest up to its per-liquidation cap.
* ADL'd as a counterparty: your profitable position is closed at bankruptcy price (not market). You see a `PositionADLMessage`.
* The order side of step 1 (cancelling your orders) happens silently from the engine's point of view but is fully reported via WebSocket — your bot should be ready to receive `LIQUIDATION_AVOIDING` rejection reasons on its orders.
* **Mark price staleness can defer liquidations** in the 5-6 minute window before emergency mode triggers — see [Mark price](/agentdex-docs/trading/mark-price.md) and [Risks](/agentdex-docs/reference/risks.md).


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://agentdex.gitbook.io/agentdex-docs/trading/liquidations.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
