# Set stops

Source: https://docs.pipsocket.com/api/set-stops

A position's stop loss and take profit.

All calls: `https://api.pipsocket.com`, with `Authorization: Bearer <your workspace key>`.

## Set stop loss and take profit

`PATCH /v1/accounts/{account}/positions/{position}`

Sets an open position's stop loss and take profit (`TRADE_ACTION_SLTP`). Both are given; 0 removes one.

### Path

- `account` (string, required): The account's id, `acc_` and 26 characters, as the dashboard shows it.
- `position` (integer, required): The position's ticket.

### Headers

- `Idempotency-Key` (string, optional): Your own key for this request, 1 to 128 characters. A request with a key the account has used before (in the last 7 days) is not sent: the first request's answer comes back instead, as it stands now.

### Body

A position's stop loss and take profit. Both are required, as MT5 sets both: give the one you keep as it is.

- `sl` (number, required, MT5 `sl`): Stop loss price; 0 removes it.
- `tp` (number, required, MT5 `tp`): Take profit price; 0 removes it.

### Response

- `request` (string): The request's id (`req_...`): look it up with `GET /requests/{request}`.
- `state` (enum): A trade request's state: `pending` (sent, no answer yet: never sent again), `done` (MT5 answered: filled, placed or rejected, as `result.retcode` says), `unknown` (no answer within 130 seconds; it becomes `done` if the terminal reports the answer later) or `refused` (the terminal did not send it). One of: `pending`, `done`, `unknown`, `refused`.
- `sent` (object): MT5's `MqlTradeRequest`, field for field, exactly as recorded to send to the terminal: the request's `state` and `result` say whether it reached MT5. Fields the call does not use carry MT5's empty values (0, "", `fok`, `gtc`).
  - `action` (enum, MT5 `action`): What the request does. One of: `deal`, `pending`, `sltp`, `modify`, `remove`, `close_by`.
  - `symbol` (string, MT5 `symbol`): The symbol, exactly as the broker names it.
  - `type` (enum, MT5 `type`): The order type. One of: `buy`, `sell`, `buy_limit`, `sell_limit`, `buy_stop`, `sell_stop`, `buy_stop_limit`, `sell_stop_limit`, `close_by`.
  - `volume` (number, MT5 `volume`): Lots.
  - `price` (number, MT5 `price`): The price: a pending order's, or the one instant and request execution trade at.
  - `stoplimit` (number, MT5 `stoplimit`): A stop-limit order's limit price, placed once `price` is reached.
  - `sl` (number, MT5 `sl`): Stop loss price; 0 for none.
  - `tp` (number, MT5 `tp`): Take profit price; 0 for none.
  - `deviation` (integer, MT5 `deviation`): The largest difference from `price` MT5 accepts, in points.
  - `type_filling` (enum, MT5 `type_filling`): How the order may fill. One of: `fok`, `ioc`, `return`, `boc`.
  - `type_time` (enum, MT5 `type_time`): How long a pending order lasts. One of: `gtc`, `day`, `specified`, `specified_day`.
  - `expiration` (integer, MT5 `expiration`): Broker server time, seconds since 1970, as MT5 takes it.
  - `order` (integer, MT5 `order`): The pending order the request is about (modify, remove).
  - `position` (integer, MT5 `position`): The position the request is about (close, stops, close by).
  - `position_by` (integer, MT5 `position_by`): The opposite position, for close by.
  - `magic` (integer, MT5 `magic`): Your own number, kept by MT5 on the order, its deals and its position.
  - `comment` (string, MT5 `comment`): Up to 31 characters, kept by MT5 on the order.
- `result` (object, or null): MT5's `MqlTradeResult` once `done`; why it was not sent once `refused`; otherwise null.
- `message` (string): What the answer means, in a sentence.

### Answers

- 200: MT5's answer: the request is `done` (filled, placed or rejected, as the retcode says), or `unknown` for a repeated key whose first request never got an answer.
- 202: No answer from the trade server within 5 seconds: the request is `pending` and is never sent again. Look it up to see how it ended.
- 400: The ticket in the path is not a whole number. No body.
- 401: - `missing_api_key`: No API key: send it as `Authorization: Bearer <key>`.; `invalid_api_key`: The key is not a workspace's current key (a rolled key stops working within about a minute).
- 404: - `no_such_account`: No such account, or one the key's workspace doesn't have: the two look the same.; `no_such_position`: The account has no open position with that ticket (read fresh from the terminal).
- 422: - `invalid_request`: A field, query parameter or header is missing, malformed or not allowed, or the body is not JSON. Nothing was sent.
- 503: - `account_not_connected`: The account's terminal is not connected to the engine (stopped, starting, or restarting). Nothing was sent, except by the kill switch: engaging it still engages it, and may already have deleted pending orders.; `bridge_outdated`: The account's terminal runs an older bridge that can't trade: restart the account to update it. Nothing was sent.; `account_restarting`: The account's terminal is being replaced. Nothing was sent; try again in a minute.; `engine_busy`: The account's engine host has too many calls in flight (256). Nothing was done; try again.; `engine_unavailable`: The account's engine host is not connected to Pipsocket, or disconnected while the call waited. A trade it already had is still settled: look it up.; a stored request whose state is `refused`: the terminal did not send it (for example `busy`, with 1,000 trades already waiting for the trade server). `result` says why.
- 504: - `terminal_timeout`: The account's terminal did not answer within 5 seconds.; `engine_timeout`: The account's engine did not answer within 30 seconds.

### Example

```bash
# A new key for each new trade; send the same one to retry it.
IDEMPOTENCY_KEY=$(uuidgen)

curl -X PATCH "https://api.pipsocket.com/v1/accounts/acc_01m6tx3k9f2qw8r7bznd5yvh4c/positions/881402311" \
  -H "Authorization: Bearer $PIPSOCKET_KEY" \
  -H "Idempotency-Key: $IDEMPOTENCY_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "sl": 1.079,
    "tp": 1.09
  }'
```

200 done:

```json
{
  "message": "The request was completed.",
  "request": "req_5f0c2a9e41d7b3a8c6e2f190",
  "result": {
    "ask": 1.08412,
    "bid": 1.0841,
    "comment": "Request executed",
    "deal": 0,
    "order": 0,
    "position": 0,
    "price": 0,
    "retcode": 10009,
    "retcode_external": 0,
    "retcode_name": "TRADE_RETCODE_DONE",
    "volume": 0
  },
  "sent": {
    "action": "sltp",
    "comment": "",
    "deviation": 0,
    "expiration": 0,
    "magic": 0,
    "order": 0,
    "position": 881402311,
    "position_by": 0,
    "price": 0,
    "sl": 1.079,
    "stoplimit": 0,
    "symbol": "EURUSD",
    "tp": 1.09,
    "type": "buy",
    "type_filling": "fok",
    "type_time": "gtc",
    "volume": 0
  },
  "state": "done"
}
```

200 rejected:

```json
{
  "message": "The stop loss or take profit is invalid for this symbol or too close to the price.",
  "request": "req_5f0c2a9e41d7b3a8c6e2f190",
  "result": {
    "ask": 1.08412,
    "bid": 1.0841,
    "comment": "Invalid stops",
    "deal": 0,
    "order": 0,
    "position": 0,
    "price": 0,
    "retcode": 10016,
    "retcode_external": 0,
    "retcode_name": "TRADE_RETCODE_INVALID_STOPS",
    "volume": 0
  },
  "sent": {
    "action": "sltp",
    "comment": "",
    "deviation": 0,
    "expiration": 0,
    "magic": 0,
    "order": 0,
    "position": 881402311,
    "position_by": 0,
    "price": 0,
    "sl": 1.079,
    "stoplimit": 0,
    "symbol": "EURUSD",
    "tp": 1.09,
    "type": "buy",
    "type_filling": "fok",
    "type_time": "gtc",
    "volume": 0
  },
  "state": "done"
}
```

202 pending:

```json
{
  "message": "No answer from the trade server yet. The order may still execute; it is not sent again.",
  "request": "req_5f0c2a9e41d7b3a8c6e2f190",
  "result": null,
  "sent": {
    "action": "sltp",
    "comment": "",
    "deviation": 0,
    "expiration": 0,
    "magic": 0,
    "order": 0,
    "position": 881402311,
    "position_by": 0,
    "price": 0,
    "sl": 1.079,
    "stoplimit": 0,
    "symbol": "EURUSD",
    "tp": 1.09,
    "type": "buy",
    "type_filling": "fok",
    "type_time": "gtc",
    "volume": 0
  },
  "state": "pending"
}
```
