Take profit, stop loss, TWAP and scale orders
Trigger orders wait for the mark price, then send an ordinary order with a worst price; TWAP and scale orders split one decision into many limit orders.
None of these orders guarantees you a fill. Each ends as ordinary orders on the book, so each order’s worst price and the book on arrival decide what you get. A stop acts when the price gets there, not when you do.
Trigger orders fire on the mark price
Section titled “Trigger orders fire on the mark price”When the mark price (oracles) crosses the trigger, the order goes to the book as a limit order at its limit price, the worst fill you accept. A market trigger uses 10 per cent slippage instead.
| Order | Used for | Trigger must be |
|---|---|---|
| Stop market, stop limit | Entering or exiting on a breakout | Above the mid price for a buy, below it for a sell |
| Take market, take limit | Acting at a better price than now | Below the mid price for a buy, above it for a sell |
| Take profit (TP), stop loss (SL) | Closing a position at a target or a limit | On the profit or loss side of the position |
The docs’ example: you’re long with a stop at trigger $10, limit $10. If the mark gaps from $11 to $9 the sell most likely rests unfilled; with an $8 limit it most likely fills between $9 and $8.
| Position | Order | Trigger | Limit | After the trigger |
|---|---|---|---|---|
| Long | SL | $10 | $10 | Sells at $10 or better; in a gap below $10 it may not fill |
| Long | TP | $12 | $11.80 | Sells at $11.80 or better; never below $11.80 |
| Short | SL | $11 | $11 | Buys at $11 or better; in a spike above $11 it may not fill |
| Short | TP | $9 | $9.20 | Buys at $9.20 or better; never above $9.20 |
TP/SL on a position, and TP/SL on an order
Section titled “TP/SL on a position, and TP/SL on an order”- From the position: covers the whole position by default and tries to close all of it at the trigger. A size you give is fixed.
- From the order form: TP and SL are children of a parent order, fixed at its size and untriggered until it resolves. When one child fills, the other is cancelled.
Trailing stops follow the mark in your favour
Section titled “Trailing stops follow the mark in your favour”It fires a market order on a set retracement. Its watermark is the highest mark since activation for a sell (closing a long or opening a short), the lowest for a buy; an optional activation price delays tracking.
sell trailing stop: trigger = watermark - distance or watermark * (1 - rate)buy trailing stop: trigger = watermark + distance or watermark * (1 + rate)The trigger moves only on a new watermark, never back.
| Mark price | Highest mark | Trigger (distance 10) | What happens |
|---|---|---|---|
| 100 | 100 | 90 | Tracking starts |
| 110 | 110 | 100 | New high raises the trigger |
| 105 | 110 | 100 | Trigger unchanged |
| 120 | 120 | 110 | New high raises it again |
| 110 | 120 | 110 | Market sell fires, closing the long |
TWAP spreads one order over time
Section titled “TWAP spreads one order over time”Suborders go out at a fixed interval, targeting elapsed time / total time * total size. Later ones make up shortfalls (for example on a wide spread), up to 3 x the normal size (total size / number of suborders); too many and it ends short.
| Order | Running time | Suborders | Each | Sent every |
|---|---|---|---|---|
| $10,000 | 1 hour | about 121 | about $83 | 30 seconds |
| $10,000 | 4 days | about 1,000 | about $10 | about 6 minutes |
The second row is consistent with the interval stretching to keep suborders near the $10 minimum. The app can also make a TWAP wait for a trigger price and stop at a mark price bound.
Scale orders place one limit per level
Section titled “Scale orders place one limit per level”One order action covers the whole price range. Each level gets its own status: a rejection does not cancel the rest, unless the batch fails validation before matching.
Chase orders reprice to stay a maker
Section titled “Chase orders reprice to stay a maker”A post-only order the app reprices to one tick inside the best bid (buy) or ask (sell), or at the best price on a one-tick spread. It always fills as a maker, and runs in the browser tab that created it.
The numbers
Section titled “The numbers”| Parameter | Value |
|---|---|
| Trigger source | Mark price |
| Market TP/SL slippage tolerance | 10% |
| TWAP running time | 5 minutes to 7 days |
| TWAP minimum total size | $100 |
| TWAP suborder interval | at least 30 seconds |
| TWAP slippage cap per suborder | 3% |
| TWAP catch-up cap | 3 x the normal suborder size |
| TWAP randomisation | up to 20% of suborder size, either way |
| Chase orders active at once | 5 |
| Trailing stops | perps only |
Where each order can fail you
Section titled “Where each order can fail you”- A market TP/SL always sends, but a TP triggered in profit can close at a loss in a thin book. A limit TP/SL may miss a gap: for a stop that must close, set the limit well beyond the trigger.
- A wick in trades does not fire a stop unless the mark price follows it.
- Cancelling a partly filled parent removes its TP and SL: re-protect the fill by hand.
- A TWAP on a thin market can fall behind for good. Like market orders, its suborders do not fill during a network upgrade’s post-only period.
- A chase order ends when the tab closes or refreshes, you switch address or disconnect, the address connects in another browser, you modify its order by hand, or an order it places is rejected (below the minimum value or short of margin).
Trigger and TWAP orders in code
Section titled “Trigger and TWAP orders in code”A stop loss attached to a position, closing a long (orders):
{ "type": "order", "orders": [{ "a": 0, "b": false, "p": "90000", "s": "0.01", "r": true, "t": { "trigger": { "isMarket": false, "triggerPx": "91000", "tpsl": "sl" } } }], "grouping": "positionTpsl"}A trigger order carries p even with isMarket: true: the worst acceptable fill.
| Item | Value |
|---|---|
grouping |
na plain orders; normalTpsl a parent and its TP/SL children in one action (fixed size); positionTpsl TP/SL on the position (SDK code: adjusts with position size) |
| Placement statuses | resting, filled, waitingForTrigger, waitingForFill |
Later orderStatus states |
include triggered, siblingFilledCanceled |
| Bad trigger price | badTriggerPxRejected (“Invalid TP/SL price”) |
| TWAP order | {"type":"twapOrder","twap":{"a":0,"b":true,"s":"1.5","r":false,"m":60,"t":false}}; m minutes, t randomise; no trigger or price-bound fields (app options) |
| TWAP reply, cancel | {"running":{"twapId":...}}; {"type":"twapCancel","a":0,"t":<twapId>} |
| TWAP fills | userTwapSliceFills: at most 2,000, each with an all-zero hash |
| TWAP WebSocket | channels twapStates, userTwapSliceFills, userTwapHistory; states activated, terminated, finished, error |
There is no trailing-stop or chase action. Bots chase with post-only orders and modify (one production bot reprices at most every 1,200 ms); modify returns a new order id, so reconcile timed-out actions by client order id.
What the docs leave unclear
Section titled “What the docs leave unclear”- Dragging a TP/SL on the chart to a price that fires at once is refused; close the position directly.
- The error docs reject non-reduce-only TP/SL before matching, yet the official order types page describes stops that open positions. How the app encodes an opening stop is undocumented.
- The docs do not say where trailing stops are evaluated; unlike chase orders, they are not described as running in the tab.
- The docs allow TWAPs of up to 7 days, with a 4-day example; one production codebase validates 5 to 1,440 minutes. The protocol’s upper bound is unprobed.
For the orders every trigger and slice ends in, see Order types. For what a stop protects you from, see Liquidation.