> This page is for Taurus PRIME.

> For clean Markdown of any page, append .md to the page URL.
> For a complete documentation index, see https://taurushq.ferndocs.com/llms.txt.
> For AI client integration (Claude Code, Cursor, etc.), connect to the MCP server at https://taurushq.ferndocs.com/_mcp/server.

# Trading

# Trading Domain

The trading domain handles order management, trade execution, and OTC workflows.

## Trading Venues

| Venue        | Description                                                          | Order Types                                                                     |
| ------------ | -------------------------------------------------------------------- | ------------------------------------------------------------------------------- |
| **Exchange** | Central limit order book                                             | Limit, Market                                                                   |
| **OTC**      | Request-for-quote with external dealers (PRIME acts as intermediary) | [RFQ](/prime/docs/api-doma-trad-rfq), Limit, Market, TWAP, Stop\*, Stop Limit\* |

\*Stop and Stop Limit orders are created by adding `stopParams` to a Limit or Market order. See [OTC Trading](/prime/docs/api-usec-05-otc-trading#stop-order-example).

## Order Lifecycle

```
PENDING → OPEN → [PARTIALLY_FILLED] → FILLED
            │         │
            └─────────└─→ CANCELLED
```

## Key Concepts

### Pair Constraints

Every order must respect the pair's constraints:

| Constraint         | Description                |
| ------------------ | -------------------------- |
| `minOrderQuantity` | Minimum order size         |
| `maxOrderQuantity` | Maximum order size         |
| `quantityTicks`    | Minimum quantity increment |
| `priceTicks`       | Minimum price increment    |

### Side

| Value       | Description              |
| ----------- | ------------------------ |
| `SIDE_BUY`  | Purchase base instrument |
| `SIDE_SELL` | Sell base instrument     |

---

## Exchange Trading

Exchange trading uses a central limit order book where orders are matched automatically.

### Exchange Order Types

| Value            | Description                                  |
| ---------------- | -------------------------------------------- |
| `TYPE_LIMIT`     | Execute at specified price or better         |
| `TYPE_MARKET`    | Execute immediately at best available        |
| `TYPE_POST_ONLY` | Add liquidity only (rejected if would match) |

### Exchange Time in Force

| Value               | Description                   |
| ------------------- | ----------------------------- |
| `TIME_IN_FORCE_DAY` | Cancel at end of trading day  |
| `TIME_IN_FORCE_GTC` | Good 'til cancelled           |
| `TIME_IN_FORCE_IOC` | Immediate or cancel           |
| `TIME_IN_FORCE_FOK` | Fill or kill (all or nothing) |

### Exchange Endpoints

All endpoints below are relative to `/api/rest/v1`.

| Endpoint                                                 | Method | Description                                          |
| -------------------------------------------------------- | ------ | ---------------------------------------------------- |
| `/orders`                                                | POST   | Create order                                         |
| `/orders/by-sub-account/{subAccountId}`                  | GET    | List orders for sub-account                          |
| `/orders/by-sub-account/{subAccountId}/{id}`             | GET    | Order details                                        |
| `/orders/by-sub-account/{subAccountId}/{orderId}`        | DELETE | Cancel order                                         |
| `/orders/by-sub-account/{subAccountId}/by-pair/{pairId}` | DELETE | Cancel all orders for pair                           |
| `/trades`                                                | GET    | Trade history (filter by `subAccountId` query param) |
| `/trades/{id}`                                           | GET    | Get specific trade by ID                             |
| `/marketplace/trades`                                    | GET    | Anonymized public trades                             |

### Exchange Order Request Schema

> **Note**
>
> **Exchange Orders Only**
>
> The following request schema applies to Exchange orders (`POST /orders`). For OTC order schemas, see [OTC Trading](/prime/docs/api-usec-05-otc-trading).

#### Required Fields

| Field           | Type      | Description                                                                        |
| --------------- | --------- | ---------------------------------------------------------------------------------- |
| `clientOrderId` | string    | Unique identifier generated by the client (max 36 chars, UUID format recommended)  |
| `subAccountId`  | UUID      | Sub-account the order belongs to                                                   |
| `symbol`        | string    | Pair symbol (e.g., "BTC/CHF")                                                      |
| `side`          | enum      | `SIDE_BUY` or `SIDE_SELL`                                                          |
| `type`          | enum      | `TYPE_LIMIT`, `TYPE_MARKET`, or `TYPE_POST_ONLY`                                   |
| `quantity`      | decimal   | Maximum quantity to fill                                                           |
| `minQuantity`   | decimal   | Minimum quantity per fill                                                          |
| `price`         | decimal   | Limit price (required for LIMIT orders)                                            |
| `timeInForce`   | enum      | `TIME_IN_FORCE_DAY`, `TIME_IN_FORCE_GTC`, `TIME_IN_FORCE_IOC`, `TIME_IN_FORCE_FOK` |
| `transactTime`  | timestamp | Client transaction time (ISO 8601 format)                                          |

#### Order Request Example

```json
{
  "clientOrderId": "9739d2bf-ddb3-4458-ab1f-98eb63279fb0",
  "subAccountId": "7376524e-6b6b-4137-9719-7e07a7709804",
  "symbol": "BTC/CHF",
  "side": "SIDE_BUY",
  "type": "TYPE_LIMIT",
  "quantity": "1.5",
  "minQuantity": "0.001",
  "price": "45000.00",
  "timeInForce": "TIME_IN_FORCE_DAY",
  "transactTime": "2024-01-15T10:30:00Z"
}
```

### Dry-Run Mode

To validate an order without actually placing it, set `dry: true` in the request:

```json
{
  "clientOrderId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
  "subAccountId": "7376524e-6b6b-4137-9719-7e07a7709804",
  "symbol": "BTC/CHF",
  "side": "SIDE_BUY",
  "type": "TYPE_LIMIT",
  "quantity": "1.5",
  "minQuantity": "0.001",
  "price": "45000.00",
  "timeInForce": "TIME_IN_FORCE_DAY",
  "transactTime": "2024-01-15T10:30:00Z",
  "dry": true
}
```

Dry-run mode performs all validation checks (balance, constraints, permissions) without creating the order. Use this to verify orders before submission.

### Exchange Order Response Schema

When creating or retrieving an order, the response contains the full order object:

```json
{
  "result": {
    "id": "2312bb39-a624-4785-aaf7-49b09034b560",
    "subAccountId": "7376524e-6b6b-4137-9719-7e07a7709804",
    "clientAccountId": "8aee564e-2eb1-4a57-b686-05476c2cfd93",
    "userId": "c43f7356-ad91-48bf-b647-96aa3ec59cf2",
    "pairId": "7a3fae7e-5a17-4931-821c-54b021f643da",
    "clientOrderId": "my-order-123",
    "side": "SIDE_BUY",
    "quantity": "1.5",
    "minQuantity": "0.001",
    "executedQuantity": "0",
    "reservedFunds": "67500.00",
    "price": "45000.00",
    "status": "STATUS_NEW",
    "type": "TYPE_LIMIT",
    "symbol": "BTC/CHF",
    "timeInForce": "TIME_IN_FORCE_DAY",
    "transactTime": "2024-01-15T10:30:00Z",
    "createdAt": "2024-01-15T10:30:00Z",
    "updatedAt": "2024-01-15T10:30:00Z"
  }
}
```

### Order Fields

| Field                    | Type      | Description                                            |
| ------------------------ | --------- | ------------------------------------------------------ |
| `id`                     | UUID      | Unique order identifier                                |
| `subAccountId`           | UUID      | Sub-account the order belongs to                       |
| `clientAccountId`        | UUID      | Client account ID                                      |
| `userId`                 | UUID      | User who created the order                             |
| `pairId`                 | UUID      | Trading pair ID                                        |
| `clientOrderId`          | string    | Client-provided unique identifier                      |
| `side`                   | enum      | `SIDE_BUY` or `SIDE_SELL`                              |
| `quantity`               | decimal   | Maximum quantity to fill                               |
| `minQuantity`            | decimal   | Minimum quantity per fill                              |
| `executedQuantity`       | decimal   | Quantity already executed                              |
| `reservedFunds`          | decimal   | Funds reserved for the order (null if not applicable)  |
| `price`                  | decimal   | Limit price (for LIMIT orders)                         |
| `status`                 | enum      | Order status (see below)                               |
| `type`                   | enum      | `TYPE_LIMIT`, `TYPE_MARKET`, `TYPE_POST_ONLY`          |
| `symbol`                 | string    | Pair symbol (may be empty for legacy orders)           |
| `timeInForce`            | enum      | Order duration policy                                  |
| `clientCreationTime`     | timestamp | Client-side creation time                              |
| `transactTime`           | timestamp | Server transaction time (null if not yet processed)    |
| `createdAt`              | timestamp | Order creation time                                    |
| `updatedAt`              | timestamp | Last update time                                       |
| `averagePrice`           | decimal   | Average fill price (null until partially/fully filled) |
| `rejectionCause`         | string    | Reason for rejection (empty if not rejected)           |
| `reservedTransactionFee` | decimal   | Reserved transaction fee (null if not applicable)      |
| `reservedSwissStampTax`  | decimal   | Reserved Swiss stamp tax (null if not applicable)      |
| `settleInstrumentId`     | UUID      | Settlement instrument ID (null if not applicable)      |

### Order Status Values

| Status                    | Description                          |
| ------------------------- | ------------------------------------ |
| `STATUS_PENDING`          | Order submitted, awaiting processing |
| `STATUS_NEW`              | Order accepted, on order book        |
| `STATUS_PARTIALLY_FILLED` | Some quantity executed               |
| `STATUS_FILLED`           | Fully executed                       |
| `STATUS_CANCELED`         | Canceled by user or system           |
| `STATUS_REJECTED`         | Rejected (see `rejectionCause`)      |
| `STATUS_REPLACED`         | Replaced by another order            |

### Time in Force Values

| Value               | Description                   |
| ------------------- | ----------------------------- |
| `TIME_IN_FORCE_DAY` | Cancel at end of trading day  |
| `TIME_IN_FORCE_GTC` | Good 'til cancelled           |
| `TIME_IN_FORCE_IOC` | Immediate or cancel           |
| `TIME_IN_FORCE_FOK` | Fill or kill (all or nothing) |

### Exchange Order List Filtering

When listing orders via `GET /orders/by-sub-account/{subAccountId}`, the response is paginated. See [Making Requests](/prime/docs/api-gett-making-requests#pagination) for pagination details.

#### Available Filters

| Filter           | Description                |
| ---------------- | -------------------------- |
| `status`         | Filter by order status     |
| `type`           | Filter by order type       |
| `time_in_force`  | Filter by time in force    |
| `pair_id`        | Filter by trading pair     |
| `created_after`  | Orders created after date  |
| `created_before` | Orders created before date |

#### Sorting

| Sort Key          | Description            |
| ----------------- | ---------------------- |
| `created_at-asc`  | Oldest first           |
| `created_at-desc` | Newest first (default) |

---

## OTC Trading

OTC (Over-the-Counter) trading enables trades with external dealers where PRIME acts as an intermediary. OTC trading offers two distinct approaches:

| Method                      | Protocol  | Use Case                                            |
| --------------------------- | --------- | --------------------------------------------------- |
| **RFQ (Request for Quote)** | WebSocket | Real-time quote negotiation with dealers            |
| **OTC Orders**              | REST      | Direct limit, market, TWAP, or stop order placement |

### OTC Trading Methods

#### RFQ (Request for Quote)

RFQ is a real-time WebSocket workflow for negotiating quotes with external dealers. The investor requests quotes, dealers respond with prices, and the investor can accept a quote to execute the trade.

For complete RFQ documentation including WebSocket message formats and workflows, see [RFQ (Request for Quote)](/prime/docs/api-doma-trad-rfq).

> **Warning**
>
> **Field Naming Convention**
>
> RFQ WebSocket messages use **PascalCase** field names (`RfqID`, `Quantity`, `Token`), while OTC REST endpoints use **camelCase** (`pairId`, `quantity`).

#### OTC Orders

OTC Orders use the REST API for placing orders that execute with external dealers. Unlike Exchange orders, OTC orders support additional order types like TWAP (Time-Weighted Average Price) and can include scheduling parameters.

For complete OTC order schemas and workflows, see [OTC Trading Use Case](/prime/docs/api-usec-05-otc-trading).

### OTC Endpoints

All endpoints below are relative to `/api/rest/v1`.

| Endpoint                                              | Method | Description          |
| ----------------------------------------------------- | ------ | -------------------- |
| `/otc/orders/by-sub-account/{subAccountId}`           | GET    | List OTC orders      |
| `/otc/orders/by-sub-account/{subAccountId}/{orderId}` | GET    | OTC order details    |
| `/otc/orders`                                         | POST   | Create OTC order     |
| `/otc/orders/by-sub-account/{subAccountId}/{orderId}` | DELETE | Cancel OTC order     |
| `/otc/trades/by-sub-account/{subAccountId}`           | GET    | OTC trades           |
| `/otc/listings/{pairId}`                              | GET    | OTC listing for pair |
| `/quotes/by-sub-account/{subAccountId}`               | GET    | Accepted RFQ quotes  |

---

## Balance Impact

When placing orders:

1. **Buy Order**: Quote currency reserved (price × quantity)
2. **Sell Order**: Base currency reserved (quantity)

Reserved funds become available again if order is cancelled.

## WebSocket Events

### Exchange WebSocket Topics

| Topic                    | Events                                |
| ------------------------ | ------------------------------------- |
| `{id}@subaccount-orders` | Exchange order updates                |
| `{pair}@trades`          | Public trades (Exchange)              |
| `{pair}@depth@{speed}`   | Order book (speed: `100ms`, `1000ms`) |

### OTC WebSocket Topics

OTC trading uses WebSocket for the RFQ workflow. See [RFQ (Request for Quote)](/prime/docs/api-doma-trad-rfq) for complete WebSocket message formats.

## Related

* [RFQ (Request for Quote)](/prime/docs/api-doma-trad-rfq) - OTC trading via RFQ workflow
* [Trading Data Use Case](/prime/docs/api-usec-04-trading-data)
* [OTC Trading Use Case](/prime/docs/api-usec-05-otc-trading)