<!-- Generated from TradeReady.io docs. Visit https://tradeready.io/docs for the full experience. -->

---
title: Trading
description: Place market, limit, stop-loss, and take-profit orders. Manage open orders and view trade history.
---

# Trading

All trading endpoints require authentication. Orders are validated through an 8-step risk chain before execution. Market orders fill immediately against the live price; limit, stop-loss, and take-profit orders are queued as pending and matched by a background task.

> **Info:**
> **Rate limit:** 100 orders per minute. This applies to `POST /trade/order` and `DELETE` cancel endpoints combined. Read endpoints (`GET /trade/orders`, `GET /trade/history`) count against the standard 600/min account limit.

---

## Order Types

| Type | Behavior | Required Fields |
|------|----------|-----------------|
| `market` | Fills immediately at current price + slippage | `symbol`, `side`, `quantity` |
| `limit` | Queues until price reaches your target | `symbol`, `side`, `quantity`, `price` |
| `stop_loss` | Auto-sells when price drops to trigger | `symbol`, `side`, `quantity`, `trigger_price` |
| `take_profit` | Auto-sells when price rises to trigger | `symbol`, `side`, `quantity`, `trigger_price` |

---

## Place Order

### `POST /api/v1/trade/order`

Place a market, limit, stop-loss, or take-profit order. The request passes through an 8-step risk validation chain: balance check, position size limit (25% of equity per coin), daily loss circuit breaker, max open orders limit (50), minimum notional value, and more.

**Authentication:** API Key or JWT

**Request Body:**

| Field | Type | Required | Description |
|-------|------|----------|-------------|
| `symbol` | string | Yes | Trading pair symbol (e.g., `"BTCUSDT"`) — case-insensitive |
| `side` | string | Yes | `"buy"` or `"sell"` |
| `type` | string | Yes | `"market"`, `"limit"`, `"stop_loss"`, or `"take_profit"` |
| `quantity` | string | Yes | Order quantity in base asset (e.g., `"0.001"` for 0.001 BTC) |
| `price` | string | For `limit` | Limit price — required for limit orders |
| `trigger_price` | string | For `stop_loss`/`take_profit` | Trigger price for conditional orders |

> **Warning:**
> Send all `quantity`, `price`, and `trigger_price` values as **decimal strings** (e.g., `"0.001"` not `0.001`). This preserves 8-decimal precision. The Python SDK handles conversion automatically.

**Example Requests:**

**curl:**

```bash
# Market buy — executes immediately
curl -X POST https://api.tradeready.io/api/v1/trade/order \
  -H "Content-Type: application/json" \
  -H "X-API-Key: ak_live_..." \
  -d '{"symbol": "BTCUSDT", "side": "buy", "type": "market", "quantity": "0.001"}'

# Limit buy — waits for BTC to drop to $63,000
curl -X POST https://api.tradeready.io/api/v1/trade/order \
  -H "Content-Type: application/json" \
  -H "X-API-Key: ak_live_..." \
  -d '{"symbol": "BTCUSDT", "side": "buy", "type": "limit", "quantity": "0.5", "price": "63000.00"}'

# Stop-loss — auto-sells if BTC drops to $62,000
curl -X POST https://api.tradeready.io/api/v1/trade/order \
  -H "Content-Type: application/json" \
  -H "X-API-Key: ak_live_..." \
  -d '{"symbol": "BTCUSDT", "side": "sell", "type": "stop_loss", "quantity": "0.5", "trigger_price": "62000.00"}'

# Take-profit — auto-sells if BTC rises to $70,000
curl -X POST https://api.tradeready.io/api/v1/trade/order \
  -H "Content-Type: application/json" \
  -H "X-API-Key: ak_live_..." \
  -d '{"symbol": "BTCUSDT", "side": "sell", "type": "take_profit", "quantity": "0.5", "trigger_price": "70000.00"}'
```
**Python SDK:**

```python
from decimal import Decimal
from agentexchange import AgentExchangeClient

client = AgentExchangeClient(api_key="ak_live_...")

# Market buy
order = client.place_market_order("BTCUSDT", "buy", Decimal("0.001"))
print(order.status)          # "filled"
print(order.executed_price)  # Decimal('64525.18000000')
print(order.fee)             # Decimal('0.06453')

# Limit buy
limit = client.place_limit_order("BTCUSDT", "buy", Decimal("0.5"), price=Decimal("63000.00"))
print(limit.status)          # "pending"
print(limit.locked_amount)   # Decimal('31563.00000000')

# Stop-loss
stop = client.place_order(
    symbol="BTCUSDT",
    side="sell",
    order_type="stop_loss",
    quantity=Decimal("0.5"),
    trigger_price=Decimal("62000.00"),
)

# Take-profit
tp = client.place_order(
    symbol="BTCUSDT",
    side="sell",
    order_type="take_profit",
    quantity=Decimal("0.5"),
    trigger_price=Decimal("70000.00"),
)
```

**Example Response — Market Order (HTTP 201, status `"filled"`):**

```json
{
  "order_id": "660e8400-e29b-41d4-a716-446655440001",
  "status": "filled",
  "symbol": "BTCUSDT",
  "side": "buy",
  "type": "market",
  "requested_quantity": "0.001",
  "executed_quantity": "0.00100000",
  "executed_price": "64525.18000000",
  "slippage_pct": "0.00600000",
  "fee": "0.06453",
  "total_cost": "64.58971",
  "filled_at": "2026-03-19T10:00:01.234Z"
}
```

**Example Response — Limit Order (HTTP 201, status `"pending"`):**

```json
{
  "order_id": "770f9511-f3ac-52e5-b827-557766551112",
  "status": "pending",
  "symbol": "BTCUSDT",
  "side": "buy",
  "type": "limit",
  "quantity": "0.50000000",
  "price": "63000.00000000",
  "locked_amount": "31563.00000000",
  "created_at": "2026-03-19T10:00:01.234Z"
}
```

`locked_amount` is the USDT held as collateral for a buy limit order. For sell orders, the base asset quantity is locked instead.

**Error Responses:**

| Code | HTTP | Condition |
|------|------|-----------|
| `ORDER_REJECTED` | 400 | Failed risk validation (see `message` for specific reason) |
| `INSUFFICIENT_BALANCE` | 400 | Not enough free balance |
| `INVALID_SYMBOL` | 404 | Trading pair not found or inactive |
| `INVALID_QUANTITY` | 400 | Quantity is zero, negative, or below `min_qty` |
| `POSITION_LIMIT_EXCEEDED` | 400 | Order would cause this coin to exceed the 25% equity limit |
| `DAILY_LOSS_LIMIT` | 403 | Daily loss circuit breaker is tripped |
| `PRICE_NOT_AVAILABLE` | 503 | No live price for market order execution |
| `RATE_LIMIT_EXCEEDED` | 429 | 100 orders/min limit exceeded |

---

## Get Order

### `GET /api/v1/trade/order/{order_id}`

Fetch a single order by its UUID. The order must belong to the authenticated account or agent.

**Authentication:** API Key or JWT

**Path Parameters:**

| Parameter | Type | Description |
|-----------|------|-------------|
| `order_id` | UUID | Order UUID from `POST /trade/order` response |

**Example Request:**

**curl:**

```bash
curl https://api.tradeready.io/api/v1/trade/order/660e8400-e29b-41d4-a716-446655440001 \
  -H "X-API-Key: ak_live_..."
```
**Python SDK:**

```python
from agentexchange import AgentExchangeClient

client = AgentExchangeClient(api_key="ak_live_...")
order = client.get_order_status("660e8400-e29b-41d4-a716-446655440001")
print(order.status)    # "filled", "pending", "cancelled", etc.
```

**Example Response:**

```json
{
  "order_id": "660e8400-e29b-41d4-a716-446655440001",
  "status": "filled",
  "symbol": "BTCUSDT",
  "side": "buy",
  "type": "market",
  "quantity": "0.00100000",
  "price": null,
  "executed_price": "64525.18000000",
  "executed_qty": "0.00100000",
  "slippage_pct": "0.00600000",
  "fee": "0.06453",
  "created_at": "2026-03-19T10:00:01.234Z",
  "filled_at": "2026-03-19T10:00:01.235Z"
}
```

Order statuses: `"pending"`, `"filled"`, `"partially_filled"`, `"cancelled"`, `"rejected"`.

**Error Responses:**

| Code | HTTP | Condition |
|------|------|-----------|
| `ORDER_NOT_FOUND` | 404 | Order does not exist or belongs to a different account |

---

## List Orders

### `GET /api/v1/trade/orders`

List all orders for the authenticated account with optional filters and pagination.

**Authentication:** API Key or JWT

**Query Parameters:**

| Parameter | Type | Required | Default | Description |
|-----------|------|----------|---------|-------------|
| `status` | string | No | — | Filter: `"pending"`, `"filled"`, `"cancelled"`, `"rejected"` |
| `symbol` | string | No | — | Filter by trading pair (e.g., `"BTCUSDT"`) |
| `limit` | integer | No | `100` | Page size (1–500) |
| `offset` | integer | No | `0` | Pagination offset |

**Example Request:**

**curl:**

```bash
curl "https://api.tradeready.io/api/v1/trade/orders?status=filled&symbol=BTCUSDT&limit=50" \
  -H "X-API-Key: ak_live_..."
```
**Python SDK:**

```python
from agentexchange import AgentExchangeClient

client = AgentExchangeClient(api_key="ak_live_...")
orders = client.list_orders(status="filled", symbol="BTCUSDT", limit=50)
for order in orders.orders:
    print(order.order_id, order.executed_price, order.fee)
```

**Example Response:**

```json
{
  "orders": [
    {
      "order_id": "660e8400-...",
      "status": "filled",
      "symbol": "BTCUSDT",
      "side": "buy",
      "type": "market",
      "quantity": "0.00100000",
      "price": null,
      "executed_price": "64525.18000000",
      "executed_qty": "0.00100000",
      "slippage_pct": "0.00600000",
      "fee": "0.06453",
      "created_at": "2026-03-19T10:00:01Z",
      "filled_at": "2026-03-19T10:00:01Z"
    }
  ],
  "total": 1,
  "limit": 50,
  "offset": 0
}
```

---

## List Open Orders

### `GET /api/v1/trade/orders/open`

List all open (pending or partially filled) orders. Equivalent to `GET /trade/orders?status=pending` but also includes `partially_filled` orders.

**Authentication:** API Key or JWT

**Query Parameters:**

| Parameter | Type | Required | Default | Description |
|-----------|------|----------|---------|-------------|
| `limit` | integer | No | `100` | Page size (1–200) |
| `offset` | integer | No | `0` | Pagination offset |

**Example Request:**

**curl:**

```bash
curl https://api.tradeready.io/api/v1/trade/orders/open \
  -H "X-API-Key: ak_live_..."
```
**Python SDK:**

```python
from agentexchange import AgentExchangeClient

client = AgentExchangeClient(api_key="ak_live_...")
open_orders = client.get_open_orders()
print(f"You have {open_orders.total} open orders")
for order in open_orders.orders:
    print(order.symbol, order.type, order.quantity)
```

Returns the same response structure as `GET /trade/orders`.

---

## Cancel Order

### `DELETE /api/v1/trade/order/{order_id}`

Cancel a single pending order and release its locked collateral. Only `"pending"` and `"partially_filled"` orders can be cancelled.

**Authentication:** API Key or JWT

**Path Parameters:**

| Parameter | Type | Description |
|-----------|------|-------------|
| `order_id` | UUID | UUID of the order to cancel |

**Example Request:**

**curl:**

```bash
curl -X DELETE \
  https://api.tradeready.io/api/v1/trade/order/770f9511-f3ac-52e5-b827-557766551112 \
  -H "X-API-Key: ak_live_..."
```
**Python SDK:**

```python
from agentexchange import AgentExchangeClient

client = AgentExchangeClient(api_key="ak_live_...")
result = client.cancel_order("770f9511-f3ac-52e5-b827-557766551112")
print(result.unlocked_amount)  # USDT returned to available balance
```

**Example Response:**

```json
{
  "order_id": "770f9511-f3ac-52e5-b827-557766551112",
  "status": "cancelled",
  "unlocked_amount": "31563.00000000",
  "cancelled_at": "2026-03-19T10:05:00Z"
}
```

**Error Responses:**

| Code | HTTP | Condition |
|------|------|-----------|
| `ORDER_NOT_FOUND` | 404 | Order does not exist or belongs to a different account |
| `ORDER_NOT_CANCELLABLE` | 409 | Order is already filled, cancelled, or rejected |

---

## Cancel All Open Orders

### `DELETE /api/v1/trade/orders/open`

Cancel all open orders in a single atomic operation. Useful before a strategy reset or when you need to free up all locked collateral quickly.

**Authentication:** API Key or JWT

**Example Request:**

**curl:**

```bash
curl -X DELETE https://api.tradeready.io/api/v1/trade/orders/open \
  -H "X-API-Key: ak_live_..."
```
**Python SDK:**

```python
from agentexchange import AgentExchangeClient

client = AgentExchangeClient(api_key="ak_live_...")
result = client.cancel_all_orders()
print(f"Cancelled {result.cancelled_count} orders")
print(f"Unlocked {result.total_unlocked} USDT")
```

**Example Response:**

```json
{
  "cancelled_count": 3,
  "total_unlocked": "45230.00000000"
}
```

---

## Get Trade History

### `GET /api/v1/trade/history`

Get a paginated list of executed trade fills (fills only — not pending orders). Returns newest-first.

**Authentication:** API Key or JWT

**Query Parameters:**

| Parameter | Type | Required | Default | Description |
|-----------|------|----------|---------|-------------|
| `symbol` | string | No | — | Filter by trading pair |
| `side` | string | No | — | Filter by side: `"buy"` or `"sell"` |
| `limit` | integer | No | `50` | Page size (1–500) |
| `offset` | integer | No | `0` | Pagination offset |

**Example Request:**

**curl:**

```bash
curl "https://api.tradeready.io/api/v1/trade/history?symbol=BTCUSDT&limit=20" \
  -H "X-API-Key: ak_live_..."
```
**Python SDK:**

```python
from agentexchange import AgentExchangeClient

client = AgentExchangeClient(api_key="ak_live_...")
history = client.get_trade_history(symbol="BTCUSDT", limit=20)

total_fees = sum(float(t.fee) for t in history.trades)
print(f"Total fees paid on BTCUSDT: {total_fees:.4f} USDT")
```

**Example Response:**

```json
{
  "trades": [
    {
      "trade_id": "aa1b2c3d-e4f5-6789-abcd-ef0123456789",
      "order_id": "660e8400-e29b-41d4-a716-446655440001",
      "symbol": "BTCUSDT",
      "side": "buy",
      "quantity": "0.00100000",
      "price": "64525.18000000",
      "fee": "0.06453",
      "total": "64.52518",
      "executed_at": "2026-03-19T10:00:01Z"
    }
  ],
  "total": 1,
  "limit": 20,
  "offset": 0
}
```

---

## Slippage

Market orders do not fill at exactly the quoted price. Slippage simulates real-market conditions:

| Order Size vs. Daily Volume | Approximate Slippage |
|----------------------------|----------------------|
| Small (< 0.01% of daily volume) | ~0.01% |
| Medium (0.01–0.1%) | ~0.05–0.1% |
| Large (> 0.1%) | ~0.1–0.5% |

Buy orders pay slightly above the listed price; sell orders receive slightly below. Every filled order response includes `slippage_pct` showing the exact slippage applied.

---

## Common Trading Workflows

**Buy with immediate stop-loss protection:**

```python
from decimal import Decimal
from agentexchange import AgentExchangeClient

client = AgentExchangeClient(api_key="ak_live_...")

# 1. Check current price
price = client.get_price("SOLUSDT")
entry = float(price.price)

# 2. Buy at market
order = client.place_market_order("SOLUSDT", "buy", Decimal("10"))

# 3. Immediately place stop-loss at 5% below entry
stop_price = str(round(entry * 0.95, 2))
client.place_order(
    symbol="SOLUSDT",
    side="sell",
    order_type="stop_loss",
    quantity=Decimal("10"),
    trigger_price=Decimal(stop_price),
)
```

For more workflow examples, see [Account Management](/docs/api/account).
