> For the complete documentation index, see [llms.txt](https://docs.hello.trade/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.hello.trade/developer-tools/websocket-api/trading-operations.md).

# Trading Operations

All trading operations require authentication. See [Connection Management](/developer-tools/websocket-api/connection-management.md) for authentication details.

***

## Error Responses

Any operation can return an error frame instead of its success response:

```json
{
  "type": "error",
  "code": 4100,
  "message": "Insufficient margin: required 1000, available 500",
  "traderOrderId": 1705600000001,
  "orderId": 123456789,
  "instrument": "NVDA"
}
```

`traderOrderId`, `orderId`, and `instrument` echo back whatever the originating request carried, so a client with multiple in-flight requests can match an error to the request that caused it. Each field is present only when the request supplied it, and omitted entirely (never sent as `null`) otherwise:

| Operation           | `traderOrderId` | `orderId`            | `instrument`     |
| ------------------- | --------------- | -------------------- | ---------------- |
| `placeOrder`        | if supplied     | — (not yet assigned) | yes              |
| `cancelOrder`       | if supplied     | if supplied          | yes              |
| `replaceOrder`      | if supplied     | if supplied          | yes              |
| `cancelAll`         | —               | —                    | if scoped to one |
| auth / parse errors | —               | —                    | —                |

These same correlation fields are also echoed on the **success** responses (`orderPlaced`, `orderReplaced`, `orderCanceled`, `massCanceled`), so you can correlate without relying on response ordering. Do not rely on response ordering: requests are pipelined per (wallet, instrument) lane and replies are emitted as each operation completes, so replies can arrive out of request order. Always correlate by `traderOrderId`/`orderId`.

***

## placeOrder

Place a new order.

**Authentication Required:** Yes

### Request

```json
{
  "type": "placeOrder",
  "traderOrderId": 1705600000001,
  "orderType": "Limit",
  "side": "Buy",
  "instrument": "NVDA",
  "quantity": "100",
  "timeInForce": "GTC",
  "limitPrice": "500.00",
  "stopPrice": null,
  "expiryDate": null,
  "marginMode": "Cross",
  "signature": {
    "sig": "0x...",
    "payload": "0x00000000000000000000000000742d35cc6634c0532925a3b844bc9e7595f12345..."
  }
}
```

**Note:** The `payload` field contains the encoded Order struct (see [Signatures - V2 Signature Format](/developer-tools/signatures.md#v2-signature-format)).

**Stop-Loss & Take-Profit Orders:**

SL/TP orders support two modes via the `closePosition` parameter:

**Managed Orders** (`closePosition: true`):

```json
{
  "type": "placeOrder",
  "traderOrderId": 1705600000002,
  "orderType": "StopLoss",
  "side": "Sell",
  "instrument": "NVDA",
  "quantity": null,
  "closePosition": true,
  "timeInForce": "IOC",
  "stopPrice": "490.00",
  "marginMode": "Cross",
  "signature": {
    "sig": "0x...",
    "payload": "0x00..."
  }
}
```

**Unmanaged Orders** (`closePosition: false`):

```json
{
  "type": "placeOrder",
  "traderOrderId": 1705600000003,
  "orderType": "StopLoss",
  "side": "Sell",
  "instrument": "NVDA",
  "quantity": "10",
  "closePosition": false,
  "timeInForce": "IOC",
  "stopPrice": "490.00",
  "marginMode": "Cross",
  "signature": {
    "sig": "0x...",
    "payload": "0x00..."
  }
}
```

**Signature Rules:**

* **Managed** (`closePosition: true`): Sign Order struct with `size: "0"`, `flags` with managed bit set (see [Order Flags](/developer-tools/signatures.md#order-flags))
* **Unmanaged** (`closePosition: false`): Sign Order struct with actual signed quantity, `flags` without managed bit
* Order struct must include `deadline` and `flags` fields (see [Signatures - Orders](/developer-tools/signatures.md#orders))

See [Order Types](/about/trading/order-types.md) for managed vs unmanaged behavior, OCO, and auto-cancellation.

### Request Fields

| Field           | Type    | Required    | Description                                                                                              |
| --------------- | ------- | ----------- | -------------------------------------------------------------------------------------------------------- |
| `traderOrderId` | u64     | No          | Optional client-supplied order identifier. Max **36 bits** (≤ `68,719,476,735`)                          |
| `orderType`     | string  | Yes         | `Limit`, `StopLimit`, `StopLoss`, `TakeProfit`                                                           |
| `side`          | string  | Yes         | `Buy` or `Sell`                                                                                          |
| `instrument`    | string  | Yes         | Instrument symbol (e.g., NVDA)                                                                           |
| `quantity`      | string  | Conditional | Order quantity (null for managed SL/TP, required otherwise)                                              |
| `closePosition` | boolean | SL/TP: Yes  | SL/TP only, required for SL/TP orders: `true` = managed (auto-sync qty), `false` = unmanaged (fixed qty) |
| `timeInForce`   | string  | Yes         | `GTC`, `GTD`, `IOC`, `FOK`, `DAY`                                                                        |
| `limitPrice`    | string  | Yes         | Required for every order type (all orders carry a price bound)                                           |
| `stopPrice`     | string  | Conditional | Required for `StopLimit`, `StopLoss`, `TakeProfit`                                                       |
| `expiryDate`    | i64     | Conditional | Required for `GTD` (Unix timestamp in milliseconds)                                                      |
| `marginMode`    | string  | Yes         | `Cross` or `Isolated`. Must match the signed order's margin flag (bit 0).                                |
| `signature`     | Object  | Yes         | EIP-712 signed order payload                                                                             |

### Order Type Requirements

| Order Type   | `limitPrice` | `stopPrice` | `timeInForce`           |
| ------------ | ------------ | ----------- | ----------------------- |
| `Limit`      | Required     | -           | GTC, GTD, IOC, FOK, DAY |
| `StopLimit`  | Required     | Required    | GTC, GTD, IOC, FOK, DAY |
| `StopLoss`   | Required     | Required    | IOC, FOK                |
| `TakeProfit` | Required     | Required    | IOC, FOK                |

These are the only accepted order types — every order carries a price bound. For market-style immediate execution, place a crossing `Limit` `IOC` with your slippage tolerance as the limit price; for a stop-market, use `StopLimit` with an aggressive limit price.

Minimum order size: **$5** notional.

For signature construction, see [Signatures - Orders](/developer-tools/signatures.md#orders).

### Success Response

```json
{
  "type": "orderPlaced",
  "traderOrderId": 1705600000001,
  "orderId": 123456789,
  "orderStatus": "Pending"
}
```

`traderOrderId` is echoed back only when it was supplied on the request (see [Error Responses](#error-responses) for correlation details).

### Common Errors

| Code  | Cause                                                               |
| ----- | ------------------------------------------------------------------- |
| 4000  | Invalid request (missing required fields, invalid order parameters) |
| 4001  | Signature verification failed                                       |
| 4002  | Invalid nonce                                                       |
| 4029  | Rate limit exceeded                                                 |
| 4030  | Invalid order type                                                  |
| 4031  | Invalid time in force                                               |
| 4032  | Invalid or missing price                                            |
| 4100  | Insufficient margin                                                 |
| 4101  | Order too small (below $5 minimum notional)                         |
| 4102  | Max leverage exceeded                                               |
| 4103  | OI cap exceeded                                                     |
| 5000  | Internal error                                                      |
| 5001+ | Exchange error (5001 + exchange code)                               |
| 5002  | Risk engine unavailable                                             |

***

## replaceOrder

Atomically cancel existing order and place new one.

**Authentication Required:** Yes

### Request

```json
{
  "type": "replaceOrder",
  "orderId": 123456789,
  "instrument": "NVDA",
  "quantity": "200",
  "timeInForce": "GTC",
  "limitPrice": "510.00",
  "stopPrice": null,
  "expiryDate": null,
  "marginMode": "Cross",
  "signature": {
    "sig": "0x...",
    "payload": "0x00..."
  }
}
```

**Note:** The `payload` field contains the encoded Order struct with new order parameters.

### Request Fields

| Field           | Type   | Required    | Description                                                                                                            |
| --------------- | ------ | ----------- | ---------------------------------------------------------------------------------------------------------------------- |
| `orderId`       | u64    | Conditional | Exchange order ID to replace (required if `traderOrderId` omitted)                                                     |
| `traderOrderId` | u64    | Conditional | Client-supplied order ID of the order to replace (required if `orderId` omitted). Max **36 bits** (≤ `68,719,476,735`) |
| `instrument`    | string | Yes         | Instrument symbol                                                                                                      |
| `quantity`      | string | Yes         | New order quantity                                                                                                     |
| `timeInForce`   | string | Yes         | New time in force                                                                                                      |
| `limitPrice`    | string | Conditional | New limit price (if applicable)                                                                                        |
| `stopPrice`     | string | Conditional | New stop price (if applicable)                                                                                         |
| `expiryDate`    | i64    | Conditional | New expiry date for GTD                                                                                                |
| `marginMode`    | string | Yes         | `Cross` or `Isolated` (must match the original order and the signed order's margin flag).                              |
| `signature`     | Object | Yes         | EIP-712 signed order payload (same format as placeOrder)                                                               |

**Notes:**

* At least one of `orderId` or `traderOrderId` must be provided to identify the order being replaced
* Signature authorizes the **new** order parameters (same format as `placeOrder`)
* Side and order type are inherited from the original order
* Only resting orders can be replaced; immediate-execution orders (`Limit` IOC/FOK, `StopLoss`, `TakeProfit` legs in flight) cannot

For signature construction, see [Signatures - Orders](/developer-tools/signatures.md#orders).

### Success Response

```json
{
  "type": "orderReplaced",
  "traderOrderId": 1705600000001,
  "orderId": 123456789
}
```

`traderOrderId` is echoed back only when it was supplied on the request.

**Replace Managed Stop-Loss:**

```json
{
  "type": "replaceOrder",
  "orderId": 123456789,
  "instrument": "NVDA",
  "quantity": null,
  "stopPrice": "495.00",
  "timeInForce": "IOC",
  "marginMode": "Cross",
  "signature": {
    "sig": "0x...",
    "payload": "0x00..."
  }
}
```

**Replace Unmanaged Stop-Loss:**

```json
{
  "type": "replaceOrder",
  "orderId": 123456790,
  "instrument": "NVDA",
  "quantity": "15",
  "stopPrice": "495.00",
  "timeInForce": "IOC",
  "marginMode": "Cross",
  "signature": {
    "sig": "0x...",
    "payload": "0x00..."
  }
}
```

**Important:**

* **Managed SL/TP**: Use `quantity: null` and sign Order struct with `size: "0"` and managed flag set
* **Unmanaged SL/TP**: Provide `quantity` and sign Order struct with actual signed quantity and managed flag unset
* **The `closePosition` mode cannot be changed on replace** - you must use the same signing pattern (flags) as the original order

### Common Errors

| Code  | Cause                                                              |
| ----- | ------------------------------------------------------------------ |
| 4000  | Invalid request (order not owned by wallet)                        |
| 4041  | Order not found                                                    |
| 4001  | Signature verification failed                                      |
| 4002  | Invalid nonce                                                      |
| 4029  | Rate limit exceeded                                                |
| 4030  | Invalid order type (unsupported type, or order cannot be replaced) |
| 4031  | Invalid time in force                                              |
| 4032  | Invalid or missing price                                           |
| 4100  | Insufficient margin                                                |
| 4102  | Max leverage exceeded                                              |
| 4103  | OI cap exceeded                                                    |
| 5000  | Internal error                                                     |
| 5001+ | Exchange error                                                     |
| 5002  | Risk engine unavailable                                            |

***

## cancelOrder

Cancel an existing order.

**Authentication Required:** Yes

### Request

```json
{
  "type": "cancelOrder",
  "orderId": 123456789,
  "traderOrderId": 1705600000001,
  "instrument": "NVDA",
  "signature": {
    "sig": "0x...",
    "payload": "0x01..."
  }
}
```

**Note:** The `payload` field contains the encoded OrderCancel struct (type discriminator `0x01`). See [Signatures - Cancel Order](/developer-tools/signatures.md#cancel-order) for struct details.

### Request Fields

| Field           | Type   | Required    | Description                                                                            |
| --------------- | ------ | ----------- | -------------------------------------------------------------------------------------- |
| `orderId`       | u64    | Conditional | Exchange order ID (required if `traderOrderId` not provided)                           |
| `traderOrderId` | u64    | Conditional | Client order ID (optional if `orderId` provided). Max **36 bits** (≤ `68,719,476,735`) |
| `instrument`    | string | Yes         | Instrument symbol                                                                      |
| `signature`     | Object | Yes         | EIP-712 signed cancel payload                                                          |

**Notes:** At least one of `orderId` or `traderOrderId` must be provided. Order ownership is validated before cancellation. Please sign the same identifier sent in the cancel request.

For signature construction, see [Signatures - Cancel Order](/developer-tools/signatures.md#cancel-order).

### Success Response

```json
{
  "type": "orderCanceled",
  "traderOrderId": 1705600000001,
  "orderId": 123456789
}
```

`traderOrderId` is echoed back only when it was supplied on the request.

### Common Errors

| Code  | Cause                                                         |
| ----- | ------------------------------------------------------------- |
| 4000  | Invalid request (order not owned by wallet, missing order ID) |
| 4041  | Order not found                                               |
| 4001  | Signature verification failed                                 |
| 4002  | Invalid nonce                                                 |
| 4029  | Rate limit exceeded                                           |
| 5000  | Internal error                                                |
| 5001+ | Exchange error                                                |

***

## cancelAll

Cancel all orders, optionally filtered by instrument.

**Authentication Required:** Yes

### Request

**Cancel all orders across all instruments:**

```json
{
  "type": "cancelAll",
  "targetScope": "All",
  "signature": {
    "sig": "0x...",
    "payload": "0x02..."
  }
}
```

**Cancel orders for specific instrument:**

```json
{
  "type": "cancelAll",
  "instrument": "NVDA",
  "targetScope": "Instrument",
  "signature": {
    "sig": "0x...",
    "payload": "0x02..."
  }
}
```

**Note:** The `payload` field contains the encoded SimpleSignaturePayload (type discriminator `0x02`). See [Signatures - Mass Cancel](/developer-tools/signatures.md#mass-cancel) for struct details.

### Request Fields

| Field         | Type   | Required    | Description                                                                     |
| ------------- | ------ | ----------- | ------------------------------------------------------------------------------- |
| `targetScope` | string | Yes         | `All` to cancel all orders, or `Instrument` to cancel only specified instrument |
| `instrument`  | string | Conditional | Instrument symbol (REQUIRED if `targetScope` is `Instrument`)                   |
| `signature`   | Object | Yes         | EIP-191 signed auth payload (same format as `authenticate`)                     |

**Important:** `targetScope` is required. Use `"All"` to cancel all orders across all instruments, or `"Instrument"` with an `instrument` to cancel orders for a specific instrument only.

For signature construction, see [Signatures - Mass Cancel](/developer-tools/signatures.md#mass-cancel).

### Success Response

```json
{
  "type": "massCanceled",
  "numberOfOrders": 5,
  "instrument": "NVDA",
  "targetScope": "Instrument"
}
```

`instrument` and `targetScope` are echoed from the request so a client with several in-flight `cancelAll`s can tell which one this answers. `instrument` is omitted for an all-instruments cancel (`targetScope: "All"`).

### Common Errors

| Code  | Cause                         |
| ----- | ----------------------------- |
| 4000  | Invalid request               |
| 4001  | Signature verification failed |
| 4002  | Invalid nonce                 |
| 4029  | Rate limit exceeded           |
| 5000  | Internal error                |
| 5001+ | Exchange error                |

***

## transferMargin

Move collateral between cross margin and a market's isolated margin, without leaving the WebSocket session. Identical semantics to [`POST /api/margin/transfer`](/developer-tools/rest-api/authenticated-endpoints.md#post-apimargintransfer).

### Request

```json
{
  "type": "transferMargin",
  "amount": "250.00",
  "instrument": "BTC",
  "direction": "crossToIsolated",
  "signature": {
    "sig": "0x...",
    "payload": "0x08..."
  }
}
```

### Request Fields

| Field        | Type   | Required | Description                                                                                                                                                                             |
| ------------ | ------ | -------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `amount`     | string | Yes      | Transfer amount (human-readable)                                                                                                                                                        |
| `instrument` | string | Yes      | Instrument symbol of the isolated market                                                                                                                                                |
| `direction`  | string | Yes      | `crossToIsolated` or `isolatedToCross`                                                                                                                                                  |
| `signature`  | Object | Yes      | EIP-712 MarginTransfer signature, type `0x08` — flag bit 0 carries the **source** account's mode (see [Signatures - Margin Transfers](/developer-tools/signatures.md#margin-transfers)) |

### Success Response

```json
{
  "type": "marginTransferred",
  "commandId": 100004
}
```

The ack only means the transfer was submitted. The settlement result arrives asynchronously as a `TransferMargin` message on the [Execution Reports](/developer-tools/websocket-api/execution-reports.md) stream.

***

## Trader Order ID

`traderOrderId` is an **optional** client-supplied identifier for an order.

### Requirements

* **Maximum width: 36 bits** — any `u64` up to `68,719,476,735` (`2^36 − 1`) is accepted. Values larger than this are rejected. Within that range, choose whatever encoding you prefer (monotonic counter, timestamp-derived, random, etc.).
* Optional on `placeOrder`.
* If supplied, the value must be unique across your own active and historical orders (you cannot reuse a `traderOrderId` you have previously submitted from the same wallet).

### Using `traderOrderId` for subsequent operations

Once an order is placed with a `traderOrderId`, that value can be used in place of the exchange `orderId` when:

* Cancelling via `cancelOrder` (see [cancelOrder](#cancelorder))
* Replacing via `replaceOrder` (see [replaceOrder](#replaceorder))
* Filtering historic orders and trades (see [REST API](/developer-tools/rest-api/public-endpoints.md))

***
