Trading
Order management, trade execution, and OTC workflows
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, 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.
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
Exchange Orders Only The following request schema applies to Exchange orders (POST /orders). For OTC order schemas, see 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
{
"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:
{
"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:
{
"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 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).
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.
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:
- Buy Order: Quote currency reserved (price × quantity)
- 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) for complete WebSocket message formats.
Related
- RFQ (Request for Quote) - OTC trading via RFQ workflow
- Trading Data Use Case
- OTC Trading Use Case
Updated 5 days ago
