references/event-commands.md
# Event Contract Commands — Full Parameter Reference
## Naming — CLI vs MCP tool
This CLI uses **space-separated subcommands** (`okx event place`). The MCP tool names surfaced to AI agents use a **single underscored identifier** (`event_place_order`). They are the same feature on two different surfaces. Mapping examples:
| CLI command | MCP tool name |
|---|---|
| `okx event browse` | `event_browse` |
| `okx event series` | `event_get_series` |
| `okx event events` | `event_get_events` |
| `okx event markets` | `event_get_markets` |
| `okx event place` | `event_place_order` |
| `okx event amend` | `event_amend_order` |
| `okx event cancel` | `event_cancel_order` |
| `okx event orders` | `event_get_orders` |
| `okx event fills` | `event_get_fills` |
**Do NOT convert MCP tool names to hyphen-joined CLI commands.** `okx event place-order` is **not** a valid command — the CLI will reject it with "Unknown command". Use `okx event place` instead.
## Outcome Values
| User input | Meaning | Applies to |
|------------|---------|------------|
| `UP` | Price rises during the period | `price_up_down` series |
| `DOWN` | Price falls during the period | `price_up_down` series |
| `YES` | Condition met (price above/touches strike) | `price_above`, `price_once_touch` series |
| `NO` | Condition not met | `price_above`, `price_once_touch` series |
- Check `settlement.method` from `event_get_series` to determine which values apply.
- `px` is the **event contract price** (`0.01–0.99`), NOT the underlying asset price.
- When the contract is actively trading, `px` reflects the market-implied probability. Example: `px=0.6` means the market is pricing the event at roughly 60%.
## Product Types (settlement.method)
| method | Description | outcome values |
|--------|-------------|----------------|
| `price_up_down` | Does price rise or fall within the period? | `UP` / `DOWN` |
| `price_above` | Is price above the strike at expiry? | `YES` / `NO` |
| `price_once_touch` | Does price ever touch the strike level? | `YES` / `NO` |
Response `outcome` field (from `event_get_markets` with `state=expired`): live/pending → empty; `"1"` → `YES`/`UP`; `"2"` → `NO`/`DOWN`.
---
## Query Commands (API key required)
### `okx event series`
```bash
okx event series [--seriesId <id>] [--json]
```
| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `seriesId` | string | No | Filter by series ID |
**Output fields**: Series ID, Title, Frequency, Category, Settlement method, Underlying
---
### `okx event events <seriesId>`
List events in a series. Each event corresponds to one expiry.
```bash
okx event events <seriesId> [--eventId <id>] [--state <preopen|live|settling|expired>] [--limit <n>] [--json]
```
| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `seriesId` | string | Yes | Series ID (positional or `--seriesId`) |
| `--eventId` | string | No | Filter by specific event ID |
| `--state` | string | No | `preopen`, `live`, `settling`, or `expired` |
| `--limit` | number | No | Max results (default 100) |
State lifecycle: preopen → live → settling → expired
Use `state=preopen` to discover upcoming events not yet available for trading. Contracts in `preopen` state cannot be traded yet — wait until state transitions to `live`.
**Output fields**: Event ID, Series ID, State, Expiry time
---
### `okx event markets <seriesId>`
List markets (instruments) in a series. Use `--state expired` to see settlement results.
```bash
okx event markets <seriesId> [--eventId <id>] [--state <preopen|live|settling|expired>] [--limit <n>] [--json]
```
| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `seriesId` | string | Yes | Series ID (positional or `--seriesId`) |
| `--eventId` | string | No | Filter by event ID |
| `--instId` | string | No | Filter by instrument ID |
| `--state` | string | No | `preopen`, `live`, `settling`, or `expired` |
| `--limit` | number | No | Max results (default 100) |
**Output fields**: Contract, Target price, Price (event contract price 0.01–0.99, not the underlying asset price; reflects market-implied probability when actively trading), Outcome (expired: translated as `YES`/`NO` or `UP`/`DOWN`; live/pending: `—`), Settlement value (expired only)
- **CLI**: use `--state expired` to get settlement outcome; there is no `event ended` command in the CLI.
- **MCP**: use `event_get_markets(seriesId, state="expired")` instead.
- Use `state=preopen` to discover upcoming contracts not yet available for trading (no live quote/px yet). Do NOT attempt to place orders on preopen contracts.
---
## instId Format
Event contract instIds are obtained from `okx event markets <seriesId>`. Never guess or use placeholders.
| Series type | instId format | Example |
|-------------|--------------|---------|
| `price_above` / `price_once_touch` | `{UNDERLYING}-{TYPE}-{YYMMDD}-{HHMM}-{STRIKE}` | `BTC-ABOVE-DAILY-260224-1600-70000` |
| `price_up_down` | `{UNDERLYING}-{TYPE}-{YYMMDD}-{START}-{END}` | `BTC-UPDOWN-15MIN-260224-1600-1615` |
Recommended workflow to obtain instId:
1. `okx event series` → select a seriesId (e.g. `BTC-ABOVE-DAILY`)
2. `okx event events <seriesId> --state live` → see active events and their eventId
3. `okx event markets <seriesId> --state live` → see each tradeable instId
4. Use the instId from step 3 in place / amend / cancel commands
## Write Commands (API key required)
### `okx event place` ⚠️ WRITE
Places a real order.
```bash
okx event place <instId> <side> <outcome> <sz> \
[--px <prob>] [--ordType <market|limit|post_only>] [--json]
```
| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `instId` | string | Yes | Instrument ID (positional) |
| `side` | string | Yes | `buy` = open, `sell` = close (positional) |
| `outcome` | string | Yes | `UP`, `YES`, `DOWN`, or `NO` (positional) |
| `sz` | string | Yes | For limit/post_only: number of contracts. For market: quote currency amount |
| `--px` | string | No | Event contract price (0.01–0.99); required when `ordType=limit`; omit for market orders |
| `--ordType` | string | No | `market` (default), `limit`, or `post_only` |
- `tdMode` is always `isolated` — auto-set by the system, do not pass it.
- `speedBump` is auto-set for non-post_only orders — do not pass it.
**Output**: Order number, error message (empty on success). Success signal: order number non-empty + error message empty.
---
### `okx event cancel` ⚠️ WRITE
Cancel a pending order.
```bash
okx event cancel <instId> <ordId> [--json]
```
| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `instId` | string | Yes | Instrument ID (positional) |
| `ordId` | string | Yes | Order ID to cancel (positional or `--ordId`) |
---
### `okx event amend` ⚠️ WRITE
Amend a pending limit or post-only order.
```bash
okx event amend <instId> <ordId> [--px <prob>] [--sz <n>] [--json]
```
| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `instId` | string | Yes | Instrument ID (positional) |
| `ordId` | string | Yes | Order ID to amend (positional or `--ordId`) |
| `--px` | string | No | New event contract price (0.01–0.99) |
| `--sz` | string | No | New number of contracts |
---
### `okx event orders`
```bash
okx event orders [--status <open|history|archive>] [--instId <id>] [--ordType <type>] [--state <canceled|filled>] [--after <id>] [--before <id>] [--begin <ms>] [--end <ms>] [--limit <n>] [--json]
```
| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `--status` | string | No | `history` (default, 7d); `open` = active; `archive` = 3mo |
| `--instId` | string | No | Filter by instrument ID |
| `--ordType` | string | No | Order type filter |
| `--state` | string | No | `canceled` or `filled` (only for history/archive) |
| `--after` | string | No | Cursor: older than this order ID |
| `--before` | string | No | Cursor: newer than this order ID |
| `--begin` | string | No | Start time (ms) |
| `--end` | string | No | End time (ms) |
| `--limit` | number | No | Max results (default 100) |
**Output fields**: Order number, Contract, Direction, Outcome, Order type, Price, Size, Filled, Status
---
### `okx event fills`
```bash
okx event fills [--archive] [--instId <id>] [--ordId <id>] [--after <id>] [--before <id>] [--begin <ms>] [--end <ms>] [--limit <n>] [--json]
```
| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `--archive` | boolean | No | `true` = up to 3mo; default = last 3d |
| `--instId` | string | No | Filter by instrument ID |
| `--ordId` | string | No | Filter by order ID |
| `--after` | string | No | Cursor: older than this bill ID |
| `--before` | string | No | Cursor: newer than this bill ID |
| `--begin` | string | No | Start time (ms) |
| `--end` | string | No | End time (ms) |
| `--limit` | number | No | Max results (default 100, 20 for archive) |
**Output fields**: Trade ID, Order number, Contract, Direction, Outcome, Fill price, Fill size, Time
---
## Outcome Quick Reference
| User intent | Series method | `outcome` input | Response outcome |
|-------------|--------------|-----------------|-----------------|
| "Buy Yes" / "Bet Yes" | `price_above` / `price_once_touch` | `YES` | `"1"` = YES won |
| "Buy No" / "Bet No" | `price_above` / `price_once_touch` | `NO` | `"2"` = NO won |
| "Buy Up" / "Bet Up" | `price_up_down` | `UP` | `"1"` = UP won |
| "Buy Down" / "Bet Down" | `price_up_down` | `DOWN` | `"2"` = DOWN won |
| Sell / close | Any | Same outcome as when opened | — |
references/event-workflows.md
# Event Contract Workflows — Multi-Step Trading Scenarios
> **Display rule**: When presenting tool results to users, always use user-facing labels
> (e.g., "Order number", "Contract", "Fill price"), not raw API field names
> (e.g., `ordId`, `instId`, `fillPx`).
> **Category naming rule**: When summarizing contract types in user-facing text,
> do not use internal category names like `above`, `up/down`.
> Use product language: "Price Above Target" contracts, "Price Direction (Up/Down)" contracts.
## Scenario 1: Discover Available Markets
> User: "What BTC event contracts are available?"
```
Step 1: okx event browse --underlying BTC-USD
→ Preferred entry point: returns active contracts grouped by product type
Step 2: if the user wants one specific series, refine with:
okx event markets BTC-ABOVE-DAILY --state live
→ Returns Contract, Target price, Probability, Outcome, and settlement context
→ If live `px` is present, it is the event contract price (0.01–0.99), not the underlying asset price — reflects the market-implied probability when actively trading
Step 3:
→ Present the available contracts directly from event results
→ If multiple strikes/periods exist, explain the expiry window and what YES/NO or UP/DOWN means
→ Only show a probability number when a live `px`/quote is actually available from the response
```
Trading card format:
```
Will BTC close above the following prices today? (Expires: 2026-03-20 16:00, 3h 20min remaining)
Strike 69,700: Probability 54.8% Buy YES @ 0.548 | Buy NO @ ~0.452
Strike 69,800: Probability 45.2% Buy YES @ 0.452 | Buy NO @ ~0.548
Strike 69,900: No live quote available
Buy YES = bet that BTC > strike at expiry; max gain per contract is (1 − entry price), max loss is entry price.
```
`Probability 54.8%` above is derived from `px=0.548`. For event contracts, `px` is the event contract price (0.01–0.99), not the underlying asset price. When actively trading, it reflects the market-implied probability.
---
## Scenario 2: Place Above Contract Order (YES/NO)
> User: "I want to buy 10 contracts of BTC above 69,700 (YES), limit price 0.6"
```
Step 1: Show summary before placing:
→ Cost = sz × px (e.g. 10 × 0.6 = 6)
→ Max gain = sz × (1 − px) (e.g. 10 × 0.4 = 4)
→ Max loss = cost (e.g. 6)
Step 2: [user confirms]
okx event place BTC-ABOVE-DAILY-260320-1600-69700 buy YES 10 --px 0.6 --ordType limit
```
After success: check Status, Order number, order type, and offer to check fill status (`okx event orders --status open`).
---
## Scenario 3: Direction Analysis (UP/DOWN Contracts)
> Trigger: user asks about UP/DOWN contracts without specifying direction, or asks "should I buy UP or DOWN?"
Extract the underlying from the seriesId (e.g. `BTC-UPDOWN-15MIN` → `BTC-USDT`) and fetch candle data in parallel:
```
Step 1 (parallel):
okx market index-candles BTC-USDT --bar 15m --limit 20 → recent 20 candles of 15m OHLCV
okx market index-candles BTC-USDT --bar 1H --limit 8 → 8 candles of 1H for trend context
```
Analyze the raw OHLCV data and present:
- Overall trend direction (based on recent closes and highs/lows pattern)
- Short-term momentum (last few candles)
- Recommended direction: **UP** or **DOWN**
- Confidence: High / Medium / Low
- Brief reasoning (2–3 sentences)
Then ask: "Based on the analysis, I recommend **{UP/DOWN}** ({confidence}). Would you like to place the order in that direction, or choose differently?"
This is a data-driven suggestion — the user makes the final call.
---
## Scenario 4: Check Order Status After Placing
> User: "Has my order been filled?"
```
Step 1: okx event orders --instId <instId> --status open
→ found: "Still resting in the order book"
→ empty: filled or cancelled
Step 2: okx event fills --instId <instId> --limit 5
→ fill found: confirm Fill size, Fill price, Time
→ no fill: order was cancelled
```
Response includes: Fill price, Fill size, timestamp, and a next-step offer (hold or set exit target).
---
## Scenario 5: Place 15min Contract (UP/DOWN)
> User: "Bet that BTC rises in the next 15 minutes — buy 5 contracts, market order"
```
Step 1: okx event markets BTC-UPDOWN-15MIN --state live
→ Find current live 15min event and its instrument ID
Step 2: [user confirms]
okx event place BTC-UPDOWN-15MIN-260320-1600-1615 buy UP 5 --ordType market
→ For market orders, sz is quote currency amount (e.g. 5)
```
For market orders: note that they fill immediately; offer to confirm via `okx event fills`.
---
## Scenario 6: Check Positions and Context
> User: "What event contract positions do I currently have?"
```
okx account positions --instType EVENTS
```
**Expiry check (MANDATORY before displaying anything):**
- Infer expiry from the instrument ID (`instId`, API field):
- `price_above` / `price_once_touch`: `YYMMDD-HHMM` → e.g. `260320-1600` = 2026-03-20 16:00 UTC+8
- `price_up_down`: `YYMMDD-START-END` → expiry is the `END` time
- If expired → **immediately run without asking**:
```
okx event markets <seriesId> --state expired
```
Include settlement result in the same response. Never say "I can check for you" — just check.
If no data yet: "Settlement data not yet available — please retry in a few minutes."
- If expires within 1 hour → mark 🔴 Settling soon
Active position response includes: entry price, current market price, unrealized PnL, exit value, breakeven, time remaining, expiry condition.
Expired position response includes: ⚠️ warning, settlement price, outcome (YES/NO/UP/DOWN), expected payout.
> User: "Close my YES position"
```
Step 1: [user confirms]
okx event place BTC-ABOVE-DAILY-260320-1600-69700 sell YES 10 --ordType market
```
Use the same outcome that the position was opened with. Do not pass extra exchange-internal fields such as `reduceOnly`, `tdMode`, or `speedBump`.
---
## Scenario 7: Check Settlement Result
> User: "Has today's BTC contract settled? What was the outcome?"
```
okx event markets BTC-ABOVE-DAILY --state expired [--limit 5]
→ Outcome field: CLI returns translated "YES"/"NO"/"UP"/"DOWN"
```
Present as a table with date, strike, settlement price, and outcome (✅/❌).
---
## Scenario 8: Cancel Order
> User: "Cancel order EVT-ORDER-001" / "Cancel my order 800000024"
`okx event cancel` requires both the instrument ID and Order number. If the user only provides the Order number, look up the instrument ID first — never ask the user for it.
```
Step 1: okx event orders --status open
→ if Order number found: use that row's instrument ID
→ if not found: okx event orders [history, no --state flag]
→ find matching Order number, extract instrument ID
Step 2: okx event cancel <instId> <ordId>
→ if cancellation fails because the order no longer exists, it was likely filled or already cancelled
→ offer to check fills or current positions
```
If Order number not found in any order list: explain it may be outside history range or the ID may be incorrect; ask the user for strike price and expiry date to help locate it.
Never show `sCode`. Always give a next step.
---
## Scenario 9: Order History and Fills
---
## Scenario 10: Discover Upcoming Events (state=preopen)
> User: "Are there any BTC contracts opening soon?" / "What's coming up in event contracts?"
Use `state=preopen` to find contracts that exist but are **not yet open for trading**.
This is different from `event_browse` / `okx event browse`, which only returns **active (live) contracts**.
```
Step 1: okx event series [--underlying BTC-USD]
→ Identify relevant seriesId values (e.g. BTC-ABOVE-DAILY, BTC-UPDOWN-15MIN)
Step 2: okx event events <seriesId> --state preopen
→ Returns upcoming expiry periods not yet open for trading
→ Output fields: Event ID, State (preopen), Expiry time
Step 3: okx event markets <seriesId> --state preopen
→ Returns upcoming individual contracts (strikes/directions) for each preopen event
→ No live quote (px) available yet — contracts are not tradeable until state turns live
```
Use `state=preopen` to:
- Warn the user before a contract expires and the next session is preopen
- Help users plan ahead — they can see upcoming strike levels before trading opens
- Distinguish from `event_browse`: browse only shows **currently tradeable** contracts; preopen shows **upcoming** contracts that cannot be traded yet
**Do NOT attempt to place orders on preopen contracts** — they will fail with "instrument not found". Wait until state transitions to `live`.
---
> User: "Show my recent event contract fills"
```
okx event fills [--limit 10]
```
> User: "Any pending orders?"
```
okx event orders --status open
→ if empty: "No open orders at the moment."
```
---
## Key Rules for AI Agents
1. **Place directly after user confirms** — no pre-flight check required.
2. **Check settlement.method**: determines which outcomes apply (UP/DOWN for `price_up_down`; YES/NO for `price_above`/`price_once_touch`).
3. **Confirm outcome with user** if unclear.
4. **px is event contract price, not underlying asset price**: range 0.01–0.99. When actively trading, it reflects the market-implied probability (e.g. 0.55 ≈ 55%). Always explain this.
5. **Present markets as trading cards**: strike + probability + what winning means + time to expiry.
6. **Translate all errors to user language**: never show `sCode`, `code`, or internal field names. Always give a next step.
7. **After every place/cancel/close**, distinguish order type in the follow-up:
- market order → "typically filled immediately — would you like me to confirm the fill?"
- limit / post_only → "may still be resting in the order book — would you like me to check? (`okx event orders --status open`)"
8. **Positions show PnL context**: current exit value + breakeven + time remaining + expiry condition.
9. **Never expose implementation details**: outcome codes, speedBump, tdMode, MCP internals.
10. **Settled results**: use `okx event markets <seriesId> --state expired` (CLI) or `event_get_markets(seriesId, state="expired")` (MCP) — there is no separate `event ended` command.
11. **Always append next-step suggestion**: every response ends with a concrete offer for what to do next.
12. **Never expose raw CLI commands to users**: use natural language instead.
13. **Expired positions**: always check expiry before displaying; front-load ⚠️ warning and auto-fetch settlement via `okx event markets <seriesId> --state expired`.
14. **Never substitute across products**: OKX CEX event contracts are a distinct product from other prediction markets. Scope = what `okx event browse` / `series` actually returns; if the user's target isn't there, say so rather than offering a "closest match". Overrides Rule 11.
references/futures-commands.md
# Futures / Delivery Command Reference
## Naming — CLI vs MCP tool
This CLI uses **space-separated subcommands** (`okx futures algo place`). The MCP tool names surfaced to AI agents use a **single underscored identifier** (`futures_place_algo_order`). They are the same feature on two different surfaces. Mapping examples:
| CLI command | MCP tool name |
|---|---|
| `okx futures place` | `futures_place_order` |
| `okx futures algo place` | `futures_place_algo_order` |
| `okx futures algo trail` | `futures_place_move_stop_order` (deprecated alias) / `futures_place_algo_order` w/ `ordType=move_order_stop` |
| `okx futures cancel` | `futures_cancel_order` |
| `okx futures algo cancel` | `futures_cancel_algo_orders` |
| `okx futures amend` | `futures_amend_order` |
| `okx futures algo amend` | `futures_amend_algo_order` |
| `okx futures close` | `futures_close_position` |
| `okx futures leverage` | `futures_set_leverage` |
| `okx futures get-leverage` | `futures_get_leverage` |
| `okx futures orders` | `futures_get_orders` |
| `okx futures positions` | `futures_get_positions` |
| `okx futures fills` | `futures_get_fills` |
| `okx futures batch` | `futures_batch_orders` |
**Do NOT convert MCP tool names to hyphen-joined CLI commands.** `okx futures place-algo` is **not** a valid command — the CLI will reject it with "Unknown command". Use `okx futures algo place` instead.
## Futures — Place Order
```bash
okx futures place --instId <id> --side <buy|sell> --ordType <type> --sz <n> \
--tdMode <cross|isolated> \
[--tgtCcy <base_ccy|quote_ccy|margin>] \
[--posSide <long|short>] [--px <price>] [--reduceOnly] \
[--tpTriggerPx <p>] [--tpOrdPx=<p|-1>] \
[--slTriggerPx <p>] [--slOrdPx=<p|-1>] \
[--clOrdId <id>] [--json]
```
| Param | Required | Default | Description |
|---|---|---|---|
| `--instId` | Yes | - | Futures instrument (format: `BTC-USDT-<YYMMDD>`, e.g. `BTC-USDT-260328`) |
| `--side` | Yes | - | `buy` or `sell` |
| `--ordType` | Yes | - | `market`, `limit`, `post_only`, `fok`, `ioc` |
| `--sz` | Yes | - | Order size — unit depends on `--tgtCcy` |
| `--tdMode` | Yes | - | `cross` or `isolated` |
| `--tgtCcy` | No | base_ccy | `base_ccy`: sz in contracts; `quote_ccy`: sz in USDT notional value; `margin`: sz in USDT margin cost (position = sz * leverage) |
| `--posSide` | Cond. | - | `long` or `short` — required in hedge mode |
| `--px` | Cond. | - | Price — required for limit orders |
| `--reduceOnly` | No | false | Close-only; will not open a new position |
| `--tpTriggerPx` | No | - | Attached take-profit trigger price |
| `--tpOrdPx` | No | - | TP order price; use `-1` for market execution (must use `=` form: `--tpOrdPx=-1`) |
| `--tpOrdKind` | No | condition | `condition`: trigger-based TP (default); `limit`: immediate limit-order TP (no trigger phase) |
| `--tpTriggerPxType` | No | last | Price source for TP trigger: `last` (default), `index`, `mark` |
| `--slTriggerPx` | No | - | Attached stop-loss trigger price |
| `--slOrdPx` | No | - | SL order price; use `-1` for market execution (must use `=` form: `--slOrdPx=-1`) |
| `--slTriggerPxType` | No | last | Price source for SL trigger: `last` (default), `index`, `mark` |
| `--stpMode` | No | - | Self-trade prevention: `cancel_maker`, `cancel_taker`, `cancel_both` |
| `--clOrdId` | No | - | Client-assigned order ID (max 32 chars alphanumeric + `-` `_`) |
`--instId` format: `BTC-USDT-<YYMMDD>` (delivery date suffix).
---
## Futures — Cancel Order
```bash
okx futures cancel --instId <id> [--ordId <id>] [--clOrdId <id>] [--json]
```
At least one of `--ordId` or `--clOrdId` is required.
---
## Futures — Amend Order
```bash
okx futures amend --instId <id> [--ordId <id>] [--clOrdId <id>] \
[--newSz <n>] [--newPx <p>] [--json]
```
Must provide at least one of `--newSz` or `--newPx`.
---
## Futures — Close Position
```bash
okx futures close --instId <id> --mgnMode <cross|isolated> \
[--posSide <long|short>] [--autoCxl] [--json]
```
| Param | Required | Default | Description |
|---|---|---|---|
| `--instId` | Yes | - | Futures instrument (e.g., `BTC-USDT-260328`) |
| `--mgnMode` | Yes | - | `cross` or `isolated` |
| `--posSide` | Cond. | - | `long` or `short` — required in hedge mode |
| `--autoCxl` | No | false | Auto-cancel pending orders before closing |
Closes the **entire** position at market price.
---
## Futures — Set Leverage
```bash
okx futures leverage --instId <id> --lever <n> --mgnMode <cross|isolated> \
[--posSide <long|short>] [--json]
```
| Param | Required | Default | Description |
|---|---|---|---|
| `--instId` | Yes | - | Futures instrument |
| `--lever` | Yes | - | Positive number, e.g., `10`. Max allowed depends on the instrument (query `okx market instruments`). |
| `--mgnMode` | Yes | - | `cross` or `isolated` |
| `--posSide` | Cond. | - | `long` or `short` — required for `isolated` in hedge (`long_short_mode`) pos mode. Each side must be set **separately** (setting `long` does NOT auto-apply to `short`). Omit for net mode or for `cross`. |
**Not supported**: Portfolio-margin accounts cannot adjust `cross` leverage for FUTURES — OKX always rejects. If unsure of account mode, run `okx account config` first and check `acctLv`.
---
## Futures — Get Leverage
```bash
okx futures get-leverage --instId <id> --mgnMode <cross|isolated> [--json]
```
Returns table: `instId`, `mgnMode`, `posSide`, `lever`.
---
## Futures — List Orders
```bash
okx futures orders [--instId <id>] [--status <open|history|archive>] [--json]
```
| `--status` | Effect |
|---|---|
| `open` | Active/pending orders (default) |
| `history` | Recent completed/cancelled |
| `archive` | Older history |
---
## Futures — Positions
```bash
okx futures positions [<instId>] [--json]
```
Returns: `instId`, `side`, `pos`, `avgPx`, `upl`, `lever`.
---
## Futures — Fills
```bash
okx futures fills [--instId <id>] [--ordId <id>] [--archive] [--json]
```
---
## Futures — Get Order
```bash
okx futures get --instId <id> [--ordId <id>] [--clOrdId <id>] [--json]
```
---
## Futures — Place Algo (TP/SL / Trail)
```bash
okx futures algo place --instId <id> --side <buy|sell> \
--ordType <oco|conditional|move_order_stop> --sz <n> \
--tdMode <cross|isolated> \
[--clOrdId <id>] \
[--tgtCcy <base_ccy|quote_ccy|margin>] \
[--posSide <long|short>] [--reduceOnly] \
[--tpTriggerPx <p>] [--tpOrdPx=<p|-1>] [--tpOrdKind <condition|limit>] [--tpTriggerPxType <last|index|mark>] \
[--slTriggerPx <p>] [--slOrdPx=<p|-1>] [--slTriggerPxType <last|index|mark>] \
[--stpMode <cancel_maker|cancel_taker|cancel_both>] [--cxlOnClosePos] \
[--callbackRatio <r>] [--callbackSpread <s>] [--activePx <p>] \
[--json]
```
| Param | Required | Default | Description |
|---|---|---|---|
| `--instId` | Yes | - | Futures instrument (e.g., `BTC-USDT-<YYMMDD>`) |
| `--side` | Yes | - | `buy` or `sell` |
| `--ordType` | Yes | - | `oco`, `conditional`, or `move_order_stop` |
| `--sz` | Yes | - | Number of contracts |
| `--tdMode` | Yes | - | `cross` or `isolated` |
| `--clOrdId` | No | - | Client-assigned algo order ID (max 32 chars alphanumeric + `-` `_`) |
| `--tgtCcy` | No | base_ccy | `base_ccy`: sz in contracts; `quote_ccy`: sz in USDT notional value; `margin`: sz in USDT margin cost (position = sz * leverage) |
| `--posSide` | Cond. | - | `long` or `short` — required in hedge mode |
| `--reduceOnly` | No | false | Close-only; will not open a new position if one doesn't exist |
| `--tpTriggerPx` | Cond. | - | Take-profit trigger price |
| `--tpOrdPx` | Cond. | - | TP order price; use `-1` for market execution (must use `=` form: `--tpOrdPx=-1`) |
| `--tpOrdKind` | No | condition | `condition`: trigger-based TP (default); `limit`: immediate limit-order TP (no trigger phase) |
| `--tpTriggerPxType` | No | last | Price source for TP trigger: `last` (default), `index`, `mark` |
| `--slTriggerPx` | Cond. | - | Stop-loss trigger price |
| `--slOrdPx` | Cond. | - | SL order price; use `-1` for market execution (must use `=` form: `--slOrdPx=-1`) |
| `--slTriggerPxType` | No | last | Price source for SL trigger: `last` (default), `index`, `mark` |
| `--stpMode` | No | - | Self-trade prevention: `cancel_maker`, `cancel_taker`, `cancel_both` |
| `--cxlOnClosePos` | No | false | Auto-cancel this algo order when the position is closed |
| `--callbackRatio` | Cond. | - | Trailing callback as a ratio (e.g., `0.02` = 2%); cannot be combined with `--callbackSpread` |
| `--callbackSpread` | Cond. | - | Trailing callback as fixed price distance; cannot be combined with `--callbackRatio` |
| `--activePx` | No | - | Price at which trailing stop becomes active |
`--instId` format: `BTC-USDT-<YYMMDD>` (e.g., `BTC-USDT-250328`). For `move_order_stop`: provide `--callbackRatio` or `--callbackSpread` (one required).
**Example — Immediate limit-order TP (tpOrdKind limit):**
```bash
okx futures algo place --instId BTC-USDT-260328 --side sell --ordType conditional \
--sz 1 --tdMode cross --posSide long \
--tpTriggerPx 105000 --tpOrdPx 105000 --tpOrdKind limit
```
**Example — Self-trade prevention (stpMode cancel_maker):**
```bash
okx futures algo place --instId BTC-USDT-260328 --side sell --ordType conditional \
--sz 1 --tdMode cross --posSide long \
--tpTriggerPx 105000 --tpOrdPx=-1 --stpMode cancel_maker
```
**Example — Auto-cancel on position close (cxlOnClosePos):**
```bash
okx futures algo place --instId BTC-USDT-260328 --side sell --ordType conditional \
--sz 1 --tdMode cross --posSide long \
--tpTriggerPx 105000 --tpOrdPx=-1 --cxlOnClosePos
```
---
## Futures — Place Trailing Stop
```bash
okx futures algo trail --instId <id> --side <buy|sell> --sz <n> \
--tdMode <cross|isolated> \
[--posSide <long|short>] [--reduceOnly] \
[--callbackRatio <ratio>] [--callbackSpread <spread>] \
[--activePx <price>] \
[--json]
```
| Param | Required | Default | Description |
|---|---|---|---|
| `--callbackRatio` | Cond. | - | Trailing callback as a ratio (e.g., `0.02` = 2%); cannot be combined with `--callbackSpread` |
| `--callbackSpread` | Cond. | - | Trailing callback as fixed price distance; cannot be combined with `--callbackRatio` |
| `--activePx` | No | - | Price at which trailing stop becomes active |
---
## Futures — Phase 2 Algo ordTypes (trigger / chase / iceberg / twap)
### Pending Order (trigger)
```bash
# Buy 1 BTC-USDT-250926 when price drops to 50000:
okx futures algo place --instId BTC-USDT-250926 --side buy --ordType trigger \
--sz 1 --tdMode cross \
--triggerPx 50000 --orderPx 50100
```
### Chase Order (chase)
```bash
# Chase-sell at distance 1 tick, max distance 5 ticks:
okx futures algo place --instId BTC-USDT-250926 --side sell --ordType chase \
--sz 2 --tdMode cross --posSide long \
--chaseType distance --chaseVal 1 --maxChaseType distance --maxChaseVal 5
```
### Iceberg Order (iceberg)
```bash
# Sell 10 contracts in 1-contract chunks every 15s, price ceiling 51000:
okx futures algo place --instId BTC-USDT-250926 --side sell --ordType iceberg \
--sz 10 --tdMode cross --posSide long \
--szLimit 1 --pxLimit 51000 --timeInterval 15 --pxVar 0.002
```
### TWAP Order (twap)
```bash
# Buy 5 contracts over time (1 per 30s, price cap 50500):
okx futures algo place --instId BTC-USDT-250926 --side buy --ordType twap \
--sz 5 --tdMode cross \
--szLimit 1 --pxLimit 50500 --timeInterval 30 --pxSpread 30
```
---
## Futures — Amend Algo
```bash
okx futures algo amend --instId <id> --algoId <id> \
[--newSz <n>] [--newTpTriggerPx <p>] [--newTpOrdPx <p>] \
[--newSlTriggerPx <p>] [--newSlOrdPx <p>] [--json]
```
> **Note**: Use this to modify TP/SL orders attached when placing the main order. Run `okx futures algo orders` first to find the `algoId`.
---
## Futures — Cancel Algo
```bash
okx futures algo cancel --instId <id> --algoId <id> [--json]
```
---
## Futures — Algo Orders
```bash
okx futures algo orders [--instId <id>] [--history] [--ordType <type>] [--json]
```
---
## Edge Cases — Futures / Delivery
- **sz unit**: number of contracts (default), USDT notional value (`--tgtCcy quote_ccy`), or USDT margin cost (`--tgtCcy margin`). If the user specifies a USDT amount, clarify whether it is notional value or margin cost, then pass directly as `--sz` with the appropriate `--tgtCcy` — do NOT manually convert to contracts. With `margin` mode, the system queries current leverage and calculates: `contracts = floor(margin * lever / (ctVal * lastPx))`
- **Linear vs inverse**: `BTC-USDT-<YYMMDD>` is linear; `BTC-USD-<YYMMDD>` is inverse (USD face value, BTC settlement). For inverse, use `--tgtCcy quote_ccy` or `--tgtCcy margin` to specify a USD amount (note: `quote_ccy` = USD, not USDT for inverse instruments); warn the user that margin and P&L are settled in BTC
- **instId format**: delivery futures use date suffix: `BTC-USDT-<YYMMDD>` (e.g., `BTC-USDT-260328` for March 28, 2026 expiry)
- **Expiry**: futures expire on the delivery date — all positions auto-settle; do not hold through expiry unless intended
- **Close position**: use `futures close` to close the **entire** position at market price — same semantics as `swap close`; to partial close, use `futures place` with `--reduceOnly`
- **Leverage**: `futures leverage` sets leverage for a futures instrument, same constraints as swap; max leverage varies by instrument and account level. **If set-leverage fails with "Cancel cross-margin TP/SL … or stop bots"**: this means pending algo orders or active trading bots exist on that instrument under cross margin. Troubleshoot in order: (1) `okx futures algo-orders --instId <id> --status pending` — check for TP/SL, trailing, trigger, chase orders (most common cause); (2) only if no algo orders found, check bots: `okx bot grid-orders --type contract_grid --status active`. **Never automatically cancel algo orders or stop bots** — show findings to the user and let them decide which to cancel/stop
- **Trailing stop**: use either `--callbackRatio` (relative, e.g., `0.02`) or `--callbackSpread` (absolute price), not both; same parameters as swap — `--tdMode` and `--posSide` required in hedge mode
- **Algo on close side**: always set `--side` opposite to position (e.g., long position → `sell` algo)
references/options-commands.md
# Options Command Reference
## Naming — CLI vs MCP tool
This CLI uses **space-separated subcommands** (`okx option place`). The MCP tool names surfaced to AI agents use a **single underscored identifier** (`option_place_order`). They are the same feature on two different surfaces. Mapping examples:
| CLI command | MCP tool name |
|---|---|
| `okx option place` | `option_place_order` |
| `okx option algo place` | `option_place_algo_order` |
| `okx option cancel` | `option_cancel_order` |
| `okx option algo cancel` | `option_cancel_algo_orders` |
| `okx option batch-cancel` | `option_batch_cancel` |
| `okx option amend` | `option_amend_order` |
| `okx option algo amend` | `option_amend_algo_order` |
| `okx option orders` | `option_get_orders` |
| `okx option get` | `option_get_order` |
| `okx option positions` | `option_get_positions` |
| `okx option fills` | `option_get_fills` |
| `okx option instruments` | `option_get_instruments` |
| `okx option greeks` | `option_get_greeks` |
**Do NOT convert MCP tool names to hyphen-joined CLI commands.** `okx option place-order` is **not** a valid command — the CLI will reject it with "Unknown command". Use `okx option place` instead.
## USDT Amount for Options — Use `--tgtCcy quote_ccy` or `--tgtCcy margin`
Options (`*-USD-YYMMDD-strike-C/P`) support two USDT-based sizing modes:
| `--tgtCcy` | sz meaning | Conversion formula |
|---|---|---|
| `quote_ccy` | USDT notional value | `floor(sz / (ctVal * lastPx))` |
| `margin` | USDT margin cost | `floor(sz * lever / (ctVal * lastPx))` |
```bash
# Buy BTC call option with 200,000 USDT notional — system converts to contracts automatically
okx option place --instId BTC-USD-260405-90000-C --side buy \
--ordType market --tdMode cash --sz 200000 --tgtCcy quote_ccy
# Sell BTC call option with 50,000 USDT margin (leverage-aware)
okx option place --instId BTC-USD-260405-90000-C --side sell \
--ordType limit --tdMode cross --sz 50000 --tgtCcy margin --px 0.005
```
**Conversion formulas** (for reference):
- `quote_ccy`: `contracts = floor(usdtAmt / (ctVal × lastPx))`
- `margin`: `contracts = floor(marginAmt × lever / (ctVal × lastPx))`
Example — BTC option (ctVal=1 BTC, lastPx=84000):
- 200,000 USDT notional → floor(200000 / (1 × 84000)) = floor(2.38) = **2 contracts**
- 50,000 USDT margin at 3x → floor(50000 × 3 / (1 × 84000)) = floor(1.78) = **1 contract**
⚠ If the USDT amount is too small for even 1 contract, the command will return an error.
⚠ Always show both the USDT input and resulting contract count to the user.
⚠ Seller margin is in BTC — remind user of liquidation risk.
---
## Option — Get Instruments (Option Chain)
```bash
okx option instruments --uly <underlying> [--expTime <YYMMDD>] [--json]
```
| Param | Required | Description |
|---|---|---|
| `--uly` | Yes | Underlying, e.g. `BTC-USD` or `ETH-USD` |
| `--expTime` | No | Filter by expiry date, e.g. `250328` |
Returns: `instId`, `uly`, `expTime`, `stk` (strike), `optType` (C/P), `state`.
Run this **before placing any option order** to get the exact `instId`.
---
## Option — Get Greeks
```bash
okx option greeks --uly <underlying> [--expTime <YYMMDD>] [--json]
```
Returns IV (`markVol`) and BS Greeks (`deltaBS`, `gammaBS`, `thetaBS`, `vegaBS`) plus `markPx` for each contract.
---
## Option — Place Order
```bash
okx option place --instId <id> --side <buy|sell> --ordType <type> \
--tdMode <cash|cross|isolated> --sz <n> \
[--tgtCcy <quote_ccy|margin>] [--px <price>] [--reduceOnly] [--clOrdId <id>] \
[--tpTriggerPx <p>] [--tpOrdPx=<p|-1>] [--tpOrdKind <condition|limit>] [--tpTriggerPxType <last|index|mark>] \
[--slTriggerPx <p>] [--slOrdPx=<p|-1>] [--slTriggerPxType <last|index|mark>] \
[--stpMode <cancel_maker|cancel_taker|cancel_both>] [--json]
```
| Param | Required | Default | Description |
|---|---|---|---|
| `--instId` | Yes | - | e.g. `BTC-USD-250328-95000-C` (call) or `...-P` (put) |
| `--side` | Yes | - | `buy` or `sell` |
| `--ordType` | Yes | - | `market`, `limit`, `post_only`, `fok`, `ioc` |
| `--tdMode` | Yes | - | `cash` = buyer (full premium); `cross`/`isolated` = seller (margin) |
| `--sz` | Yes | - | Number of contracts (default), or USDT amount when `--tgtCcy` is set |
| `--tgtCcy` | No | - | `quote_ccy`: sz is USDT notional value; `margin`: sz is USDT margin cost (position = sz * leverage). Both auto-convert to contracts |
| `--px` | Cond. | - | Required for `limit`, `post_only`, `fok`, `ioc` |
| `--reduceOnly` | No | false | Close-only; do not open a new position |
| `--tpTriggerPx` | No | - | Attached take-profit trigger price |
| `--tpOrdPx` | No | - | TP order price; use `-1` for market execution (must use `=` form: `--tpOrdPx=-1`) |
| `--tpOrdKind` | No | condition | `condition`: trigger-based TP (default); `limit`: immediate limit-order TP (no trigger phase) |
| `--tpTriggerPxType` | No | last | Price source for TP trigger: `last` (default), `index`, `mark` |
| `--slTriggerPx` | No | - | Attached stop-loss trigger price |
| `--slOrdPx` | No | - | SL order price; use `-1` for market execution (must use `=` form: `--slOrdPx=-1`) |
| `--slTriggerPxType` | No | last | Price source for SL trigger: `last` (default), `index`, `mark` |
| `--stpMode` | No | - | Self-trade prevention: `cancel_maker`, `cancel_taker`, `cancel_both` |
**tdMode rules:**
- Buyer (`side=buy`): always use `cash` — pay full premium, no margin call risk
- Seller (`side=sell`): use `cross` or `isolated` — margin required, liquidation risk
**Example — Immediate limit-order TP (tpOrdKind limit):**
```bash
okx option place --instId BTC-USD-260328-100000-C --side buy \
--ordType limit --tdMode cash --sz 1 --px 0.005 \
--tpTriggerPx 0.01 --tpOrdPx 0.01 --tpOrdKind limit
```
**Example — Self-trade prevention (stpMode cancel_maker):**
```bash
okx option place --instId BTC-USD-260328-100000-C --side buy \
--ordType limit --tdMode cash --sz 1 --px 0.005 \
--stpMode cancel_maker
```
---
## Option — Cancel Order
```bash
okx option cancel --instId <id> [--ordId <id>] [--clOrdId <id>] [--json]
```
---
## Option — Amend Order
```bash
okx option amend --instId <id> [--ordId <id>] [--clOrdId <id>] \
[--newSz <n>] [--newPx <p>] [--json]
```
Must provide at least one of `--newSz` or `--newPx`. To modify attached TP/SL, use `okx option algo amend` instead.
---
## Option — Amend Algo
```bash
okx option algo amend --instId <id> --algoId <id> \
[--newSz <n>] [--newTpTriggerPx <p>] [--newTpOrdPx <p>] \
[--newSlTriggerPx <p>] [--newSlOrdPx <p>] [--json]
```
> **Note**: Use this to modify TP/SL orders attached when placing the main order. Run `okx option algo orders` first to find the `algoId`.
---
## Option — Batch Cancel
```bash
okx option batch-cancel --orders '<JSON>' [--json]
```
`--orders` is a JSON array of up to 20 objects, each `{"instId":"...","ordId":"..."}`:
```bash
okx option batch-cancel --orders '[{"instId":"BTC-USD-250328-95000-C","ordId":"123"},{"instId":"BTC-USD-250328-90000-P","ordId":"456"}]'
```
---
## Option — List Orders
```bash
okx option orders [--instId <id>] [--uly <underlying>] [--history] [--archive] [--json]
```
| Flag | Effect |
|---|---|
| *(default)* | Live/pending orders |
| `--history` | Historical (7d) |
| `--archive` | Older archive (3mo) |
---
## Option — Get Order
```bash
okx option get --instId <id> [--ordId <id>] [--clOrdId <id>] [--json]
```
Returns: `ordId`, `instId`, `side`, `ordType`, `px`, `sz`, `fillSz`, `avgPx`, `state`, `cTime`.
---
## Option — Positions
```bash
okx option positions [--instId <id>] [--uly <underlying>] [--json]
```
Returns: `instId`, `posSide`, `pos`, `avgPx`, `upl`, `deltaPA`, `gammaPA`, `thetaPA`, `vegaPA`. Only non-zero positions shown.
---
## Option — Fills
```bash
okx option fills [--instId <id>] [--ordId <id>] [--archive] [--json]
```
`--archive`: access fills beyond the default 3-day window (up to 3 months).
---
## Edge Cases — Options
- **sz unit**: number of contracts by default; use `--tgtCcy quote_ccy` for USDT notional value or `--tgtCcy margin` for USDT margin cost — the system auto-converts. For `quote_ccy`: `sz = floor(usdtAmt / (ctVal × lastPx))`; for `margin`: `sz = floor(marginAmt × lever / (ctVal × lastPx))`. For inverse options (BTC-USD), `ctVal` is in BTC; the conversion uses the BTC-USDT last price automatically.
- **instId format**: `{uly}-{YYMMDD}-{strike}-{C|P}` — e.g. `BTC-USD-250328-95000-C`; always run `okx option instruments --uly BTC-USD` first to confirm the exact contract exists
- **tdMode**: buyers always use `cash` (full premium paid upfront, no liquidation); sellers use `cross` or `isolated` (margin required, liquidation risk)
- **px unit**: quoted in base currency for inverse options (e.g. `0.005` = 0.005 BTC premium per contract); always show equivalent USDT value to the user
- **Expiry**: options expire at 08:00 UTC on the expiry date; in-the-money options are auto-exercised; do not hold through expiry unless intended
- **No TP/SL algo on options**: the `swap algo` / `spot algo` commands do not apply to option positions; manage risk by cancelling/amending option orders directly
- **Greeks in positions**: `okx option positions` returns live portfolio Greeks (`deltaPA`, `gammaPA`, etc.) from the account's position-level calculation, while `okx option greeks` returns BS model Greeks per contract
references/spot-commands.md
# Spot Command Reference
## Naming — CLI vs MCP tool
This CLI uses **space-separated subcommands** (`okx spot algo place`). The MCP tool names surfaced to AI agents use a **single underscored identifier** (`spot_place_algo_order`). They are the same feature on two different surfaces. Mapping examples:
| CLI command | MCP tool name |
|---|---|
| `okx spot place` | `spot_place_order` |
| `okx spot algo place` | `spot_place_algo_order` |
| `okx spot algo trail` | `spot_place_algo_order` w/ `ordType=move_order_stop` |
| `okx spot cancel` | `spot_cancel_order` |
| `okx spot algo cancel` | `spot_cancel_algo_order` |
| `okx spot amend` | `spot_amend_order` |
| `okx spot algo amend` | `spot_amend_algo_order` |
| `okx spot orders` | `spot_get_orders` |
| `okx spot fills` | `spot_get_fills` |
| `okx spot batch` | `spot_batch_orders` |
| `okx spot leverage` | `spot_set_leverage` |
**Do NOT convert MCP tool names to hyphen-joined CLI commands.** `okx spot place-order` is **not** a valid command — the CLI will reject it with "Unknown command". Use `okx spot place` instead.
## Order Type Reference
| `--ordType` | Description | Requires `--px` |
|---|---|---|
| `market` | Fill immediately at best price | No |
| `limit` | Fill at specified price or better | Yes |
| `post_only` | Limit order; cancelled if it would be a taker | Yes |
| `fok` | Fill entire order immediately or cancel | Yes |
| `ioc` | Fill what's available immediately, cancel rest | Yes |
| `conditional` | Algo: single TP or SL trigger | No (set trigger px) |
| `oco` | Algo: TP + SL together (one cancels other) | No (set both trigger px) |
| `move_order_stop` | Trailing stop (spot/swap/futures) | No (set callback) |
---
## Spot — Place Order
```bash
okx spot place --instId <id> --side <buy|sell> --ordType <type> --sz <n> \
[--tgtCcy <base_ccy|quote_ccy>] [--px <price>] \
[--tpTriggerPx <p>] [--tpOrdPx=<p|-1>] \
[--slTriggerPx <p>] [--slOrdPx=<p|-1>] \
[--clOrdId <id>] [--json]
```
| Param | Required | Default | Description |
|---|---|---|---|
| `--instId` | Yes | - | Spot instrument (e.g., `BTC-USDT`) |
| `--side` | Yes | - | `buy` or `sell` |
| `--ordType` | Yes | - | `market`, `limit`, `post_only`, `fok`, `ioc` |
| `--sz` | Yes | - | Order size — unit depends on `--tgtCcy` |
| `--tgtCcy` | No | base_ccy | `base_ccy`: sz in base currency (e.g. SOL amount); `quote_ccy`: sz in quote currency (e.g. USDT amount) |
| `--px` | Cond. | - | Price — required for `limit`, `post_only`, `fok`, `ioc` |
| `--tpTriggerPx` | No | - | Attached take-profit trigger price |
| `--tpOrdPx` | No | - | TP order price; use `-1` for market execution (must use `=` form: `--tpOrdPx=-1`) |
| `--tpOrdKind` | No | condition | `condition`: trigger-based TP (default); `limit`: immediate limit-order TP (no trigger phase) |
| `--tpTriggerPxType` | No | last | Price source for TP trigger: `last` (default), `index`, `mark` |
| `--slTriggerPx` | No | - | Attached stop-loss trigger price |
| `--slOrdPx` | No | - | SL order price; use `-1` for market execution (must use `=` form: `--slOrdPx=-1`) |
| `--slTriggerPxType` | No | last | Price source for SL trigger: `last` (default), `index`, `mark` |
| `--stpMode` | No | - | Self-trade prevention: `cancel_maker`, `cancel_taker`, `cancel_both` |
| `--clOrdId` | No | - | Client-assigned order ID (max 32 chars alphanumeric + `-` `_`) |
---
## Spot — Cancel Order
```bash
okx spot cancel --instId <id> [--ordId <id>] [--clOrdId <id>] [--json]
```
At least one of `--ordId` or `--clOrdId` is required.
---
## Spot — Amend Order
```bash
okx spot amend --instId <id> [--ordId <id>] [--clOrdId <id>] \
[--newSz <n>] [--newPx <p>] [--json]
```
Must provide at least one of `--newSz` or `--newPx`.
---
## Spot — Place Algo (TP/SL / Trail)
```bash
okx spot algo place --instId <id> --side <buy|sell> \
--ordType <oco|conditional|move_order_stop> --sz <n> \
[--clOrdId <id>] \
[--tgtCcy <base_ccy|quote_ccy>] \
[--tpTriggerPx <p>] [--tpOrdPx=<p|-1>] [--tpOrdKind <condition|limit>] [--tpTriggerPxType <last|index|mark>] \
[--slTriggerPx <p>] [--slOrdPx=<p|-1>] [--slTriggerPxType <last|index|mark>] \
[--stpMode <cancel_maker|cancel_taker|cancel_both>] \
[--callbackRatio <r>] [--callbackSpread <s>] [--activePx <p>] \
[--json]
```
| Param | Required | Default | Description |
|---|---|---|---|
| `--instId` | Yes | - | Spot instrument (e.g., `BTC-USDT`) |
| `--side` | Yes | - | `buy` or `sell` |
| `--ordType` | Yes | - | `oco`, `conditional`, or `move_order_stop` |
| `--sz` | Yes | - | Order size in base currency |
| `--clOrdId` | No | - | Client-assigned algo order ID (max 32 chars alphanumeric + `-` `_`) |
| `--tgtCcy` | No | base_ccy | `base_ccy`: sz in base currency; `quote_ccy`: sz in quote currency (e.g. USDT) |
| `--tpTriggerPx` | Cond. | - | Take-profit trigger price |
| `--tpOrdPx` | Cond. | - | TP order price; use `-1` for market execution (must use `=` form: `--tpOrdPx=-1`) |
| `--tpOrdKind` | No | condition | `condition`: trigger-based TP (default); `limit`: immediate limit-order TP (no trigger phase) |
| `--tpTriggerPxType` | No | last | Price source for TP trigger: `last` (default), `index`, `mark` |
| `--slTriggerPx` | Cond. | - | Stop-loss trigger price |
| `--slOrdPx` | Cond. | - | SL order price; use `-1` for market execution (must use `=` form: `--slOrdPx=-1`) |
| `--slTriggerPxType` | No | last | Price source for SL trigger: `last` (default), `index`, `mark` |
| `--stpMode` | No | - | Self-trade prevention: `cancel_maker`, `cancel_taker`, `cancel_both` |
| `--callbackRatio` | Cond. | - | Trailing callback as a ratio (e.g., `0.02` = 2%); cannot be combined with `--callbackSpread` |
| `--callbackSpread` | Cond. | - | Trailing callback as fixed price distance; cannot be combined with `--callbackRatio` |
| `--activePx` | No | - | Price at which trailing stop becomes active |
For `oco`: provide both TP and SL params. For `conditional`: provide only TP or only SL. For `move_order_stop`: provide `--callbackRatio` or `--callbackSpread` (one required).
**Example — Immediate limit-order TP (tpOrdKind limit):**
```bash
okx spot algo place --instId BTC-USDT --side sell --ordType conditional \
--sz 0.01 \
--tpTriggerPx 105000 --tpOrdPx 105000 --tpOrdKind limit
```
**Example — Self-trade prevention (stpMode cancel_maker):**
```bash
okx spot algo place --instId BTC-USDT --side sell --ordType conditional \
--sz 0.01 \
--tpTriggerPx 105000 --tpOrdPx=-1 --stpMode cancel_maker
```
---
## Spot — Phase 2 Algo ordTypes (trigger / chase / iceberg / twap)
### Pending Order (trigger)
```bash
# Buy BTC when price drops to 30000 (limit at 30050):
okx spot algo place --instId BTC-USDT --side buy --ordType trigger \
--sz 0.01 --triggerPx 30000 --orderPx 30050
```
### Chase Order (chase)
```bash
# Chase-buy at ratio 0.001, max ratio 0.01:
okx spot algo place --instId BTC-USDT --side buy --ordType chase \
--sz 0.01 --chaseType ratio --chaseVal 0.001 --maxChaseType ratio --maxChaseVal 0.01
```
### Iceberg Order (iceberg)
```bash
# Sell 1 BTC in 0.1 BTC chunks every 5 seconds, price ceiling 31000:
okx spot algo place --instId BTC-USDT --side sell --ordType iceberg \
--sz 1 --szLimit 0.1 --pxLimit 31000 --timeInterval 5 --pxVar 0.001
```
### TWAP Order (twap)
```bash
# Buy 0.5 BTC over time (0.1 BTC per 20s, price cap 30500):
okx spot algo place --instId BTC-USDT --side buy --ordType twap \
--sz 0.5 --szLimit 0.1 --pxLimit 30500 --timeInterval 20 --pxSpread 20
```
---
## Spot — Amend Algo
```bash
okx spot algo amend --instId <id> --algoId <id> \
[--newSz <n>] [--newTpTriggerPx <p>] [--newTpOrdPx <p>] \
[--newSlTriggerPx <p>] [--newSlOrdPx <p>] [--json]
```
> **Note**: Use this to modify TP/SL orders attached when placing the main order. Run `okx spot algo orders` first to find the `algoId`.
---
## Spot — Cancel Algo
```bash
okx spot algo cancel --instId <id> --algoId <id> [--json]
```
---
## Spot — Place Trailing Stop
```bash
okx spot algo trail --instId <id> --side <buy|sell> --sz <n> \
[--callbackRatio <ratio>] [--callbackSpread <spread>] \
[--activePx <price>] \
[--json]
```
| Param | Required | Default | Description |
|---|---|---|---|
| `--instId` | Yes | - | Spot instrument (e.g., `BTC-USDT`) |
| `--side` | Yes | - | `buy` or `sell` — use `sell` to protect a long spot position |
| `--sz` | Yes | - | Order size in base currency |
| `--callbackRatio` | Cond. | - | Trailing callback as a ratio (e.g., `0.02` = 2%); cannot be combined with `--callbackSpread` |
| `--callbackSpread` | Cond. | - | Trailing callback as fixed price distance; cannot be combined with `--callbackRatio` |
| `--activePx` | No | - | Price at which trailing stop becomes active |
> Spot trailing stop does not require `--tdMode` or `--posSide` (spot has no margin mode or position side concept).
---
## Spot — List Orders
```bash
okx spot orders [--instId <id>] [--history] [--json]
```
| Flag | Effect |
|---|---|
| *(default)* | Open/pending orders |
| `--history` | Historical (filled, cancelled) orders |
---
## Spot — Get Order
```bash
okx spot get --instId <id> [--ordId <id>] [--clOrdId <id>] [--json]
```
Returns: `ordId`, `instId`, `side`, `ordType`, `px`, `sz`, `fillSz`, `avgPx`, `state`, `cTime`.
---
## Spot — Fills
```bash
okx spot fills [--instId <id>] [--ordId <id>] [--json]
```
Returns: `instId`, `side`, `fillPx`, `fillSz`, `fee`, `ts`.
---
## Spot — Algo Orders
```bash
okx spot algo orders [--instId <id>] [--history] [--ordType <type>] [--json]
```
Returns: `algoId`, `instId`, type, `side`, `sz`, `tpTrigger`, `slTrigger`, `state`.
---
## Spot — Set Leverage (margin trading)
```bash
okx spot leverage ( --instId <pair> | --ccy <ccy> ) --lever <n> --mgnMode <cross|isolated> [--json]
```
Use this to set leverage for spot **margin** (borrowing) trading. Pass **exactly one** of `--instId` (pair-level) or `--ccy` (currency-level cross).
| Param | Required | Description |
|---|---|---|
| `--instId` | Cond. | Pair-level leverage, e.g. `BTC-USDT`. Works with `isolated` or `cross`. Mutually exclusive with `--ccy`. |
| `--ccy` | Cond. | Currency-level leverage, e.g. `BTC`. Only for borrow-enabled spot / multi-ccy margin / portfolio margin accounts. Requires `--mgnMode cross`. |
| `--lever` | Yes | Positive number (e.g. `3`). Max depends on the pair / account policy. |
| `--mgnMode` | Yes | `cross` or `isolated`. Must be `cross` when `--ccy` is used. |
Scenarios (mirror OKX `POST /api/v5/account/set-leverage`):
- `--instId + --mgnMode isolated` → pair-level isolated margin
- `--instId + --mgnMode cross` → pair-level cross margin (contract-mode account)
- `--ccy + --mgnMode cross` → currency-level cross (spot-with-borrow / multi-ccy / portfolio margin)
For SWAP / FUTURES leverage see `okx swap leverage` / `okx futures leverage`.
---
## Edge Cases — Spot
- **Market order size**: default `--sz` is in base currency (e.g., BTC amount). If user specifies a USDT amount, use `--tgtCcy quote_ccy` and pass the USDT value as `--sz` directly — do NOT manually convert
- **Insufficient balance**: check `okx-cex-portfolio account balance` before placing
- **Price not required**: `market` orders don't need `--px`; `limit` / `post_only` / `fok` / `ioc` do
- **Algo oco**: provide both `tpTriggerPx` and `slTriggerPx`; price `-1` means market execution at trigger
- **Fills vs orders**: `fills` shows executed trades; `orders --history` shows all orders including cancelled
- **Trailing stop**: use either `--callbackRatio` (relative, e.g., `0.02`) or `--callbackSpread` (absolute price), not both; `--tdMode` and `--posSide` are not required for spot
- **Algo on close side**: always set `--side` opposite to position direction (e.g., long spot holding → `sell` algo, short spot → `buy` algo)
references/swap-commands.md
# Swap / Perpetual Command Reference
## Naming — CLI vs MCP tool
This CLI uses **space-separated subcommands** (`okx swap algo place`). The MCP tool names surfaced to AI agents use a **single underscored identifier** (`swap_place_algo_order`). They are the same feature on two different surfaces. Mapping examples:
| CLI command | MCP tool name |
|---|---|
| `okx swap place` | `swap_place_order` |
| `okx swap algo place` | `swap_place_algo_order` |
| `okx swap algo trail` | `swap_place_move_stop_order` (deprecated alias) / `swap_place_algo_order` w/ `ordType=move_order_stop` |
| `okx swap cancel` | `swap_cancel_order` |
| `okx swap algo cancel` | `swap_cancel_algo_order` |
| `okx swap amend` | `swap_amend_order` |
| `okx swap algo amend` | `swap_amend_algo_order` |
**Do NOT convert MCP tool names to hyphen-joined CLI commands.** `okx swap place-algo` is **not** a valid command — the CLI will reject it with "Unknown command". Use `okx swap algo place` instead.
## Swap — Place Order
```bash
okx swap place --instId <id> --side <buy|sell> --ordType <type> --sz <n> \
--tdMode <cross|isolated> \
[--tgtCcy <base_ccy|quote_ccy|margin>] \
[--posSide <long|short>] [--px <price>] [--reduceOnly] \
[--tpTriggerPx <p>] [--tpOrdPx=<p|-1>] \
[--slTriggerPx <p>] [--slOrdPx=<p|-1>] \
[--clOrdId <id>] [--json]
```
| Param | Required | Default | Description |
|---|---|---|---|
| `--instId` | Yes | - | Swap instrument (e.g., `BTC-USDT-SWAP`) |
| `--side` | Yes | - | `buy` or `sell` |
| `--ordType` | Yes | - | `market`, `limit`, `post_only`, `fok`, `ioc` |
| `--sz` | Yes | - | Order size — unit depends on `--tgtCcy` |
| `--tdMode` | Yes | - | `cross` or `isolated` |
| `--tgtCcy` | No | base_ccy | `base_ccy`: sz in contracts; `quote_ccy`: sz in USDT notional value; `margin`: sz in USDT margin cost (position = sz * leverage) |
| `--posSide` | Cond. | - | `long` or `short` — required in hedge mode |
| `--px` | Cond. | - | Price — required for limit orders |
| `--reduceOnly` | No | false | Close-only; will not open a new position if one doesn't exist |
| `--tpTriggerPx` | No | - | Attached take-profit trigger price |
| `--tpOrdPx` | No | - | TP order price; use `-1` for market execution (must use `=` form: `--tpOrdPx=-1`) |
| `--tpOrdKind` | No | condition | `condition`: trigger-based TP (default); `limit`: immediate limit-order TP (no trigger phase) |
| `--tpTriggerPxType` | No | last | Price source for TP trigger: `last` (default), `index`, `mark` |
| `--slTriggerPx` | No | - | Attached stop-loss trigger price |
| `--slOrdPx` | No | - | SL order price; use `-1` for market execution (must use `=` form: `--slOrdPx=-1`) |
| `--slTriggerPxType` | No | last | Price source for SL trigger: `last` (default), `index`, `mark` |
| `--stpMode` | No | - | Self-trade prevention: `cancel_maker`, `cancel_taker`, `cancel_both` |
| `--clOrdId` | No | - | Client-assigned order ID (max 32 chars alphanumeric + `-` `_`) |
---
## Swap — Cancel Order
```bash
okx swap cancel --instId <id> [--ordId <id>] [--clOrdId <id>] [--json]
```
At least one of `--ordId` or `--clOrdId` is required.
---
## Swap — Amend Order
```bash
okx swap amend --instId <id> [--ordId <id>] [--clOrdId <id>] \
[--newSz <n>] [--newPx <p>] [--json]
```
---
## Swap — Close Position
```bash
okx swap close --instId <id> --mgnMode <cross|isolated> \
[--posSide <long|short>] [--autoCxl] [--json]
```
| Param | Required | Default | Description |
|---|---|---|---|
| `--instId` | Yes | - | Swap instrument |
| `--mgnMode` | Yes | - | `cross` or `isolated` |
| `--posSide` | Cond. | - | `long` or `short` — required in hedge mode |
| `--autoCxl` | No | false | Auto-cancel pending orders before closing |
Closes the **entire** position at market price.
---
## Swap — Set Leverage
```bash
okx swap leverage --instId <id> --lever <n> --mgnMode <cross|isolated> \
[--posSide <long|short>] [--json]
```
| Param | Required | Default | Description |
|---|---|---|---|
| `--instId` | Yes | - | Swap instrument |
| `--lever` | Yes | - | Positive number, e.g., `10`. Max allowed depends on the instrument (query `okx market instruments`). |
| `--mgnMode` | Yes | - | `cross` or `isolated` |
| `--posSide` | Cond. | - | `long` or `short` — required for `isolated` in hedge (`long_short_mode`) pos mode. Each side must be set **separately** (setting `long` does NOT auto-apply to `short`). Omit for net mode or for `cross`. |
**Not supported**: Portfolio-margin accounts cannot adjust `cross` leverage for SWAP — OKX always rejects. If unsure of account mode, run `okx account config` first and check `acctLv`.
> ⚠ **Stock tokens** (e.g., `TSLA-USDT-SWAP`): maximum leverage is **5x**. The exchange will reject `--lever` values above 5 for stock token instruments.
---
## Swap — Get Leverage
```bash
okx swap get-leverage --instId <id> --mgnMode <cross|isolated> [--json]
```
Returns table: `instId`, `mgnMode`, `posSide`, `lever`.
---
## Swap — Place Algo (TP/SL / Trail)
```bash
okx swap algo place --instId <id> --side <buy|sell> \
--ordType <oco|conditional|move_order_stop> --sz <n> \
--tdMode <cross|isolated> \
[--clOrdId <id>] \
[--tgtCcy <base_ccy|quote_ccy|margin>] \
[--posSide <long|short>] [--reduceOnly] \
[--tpTriggerPx <p>] [--tpOrdPx=<p|-1>] [--tpOrdKind <condition|limit>] [--tpTriggerPxType <last|index|mark>] \
[--slTriggerPx <p>] [--slOrdPx=<p|-1>] [--slTriggerPxType <last|index|mark>] \
[--stpMode <cancel_maker|cancel_taker|cancel_both>] [--cxlOnClosePos] \
[--callbackRatio <r>] [--callbackSpread <s>] [--activePx <p>] \
[--json]
```
| Param | Required | Default | Description |
|---|---|---|---|
| `--instId` | Yes | - | Swap instrument (e.g., `BTC-USDT-SWAP`) |
| `--side` | Yes | - | `buy` or `sell` |
| `--ordType` | Yes | - | `oco`, `conditional`, or `move_order_stop` |
| `--sz` | Yes | - | Number of contracts |
| `--tdMode` | Yes | - | `cross` or `isolated` |
| `--clOrdId` | No | - | Client-assigned algo order ID (max 32 chars alphanumeric + `-` `_`) |
| `--tgtCcy` | No | base_ccy | `base_ccy`: sz in contracts; `quote_ccy`: sz in USDT notional value; `margin`: sz in USDT margin cost (position = sz * leverage) |
| `--posSide` | Cond. | - | `long` or `short` — required in hedge mode |
| `--reduceOnly` | No | false | Close-only; will not open a new position if one doesn't exist |
| `--tpTriggerPx` | Cond. | - | Take-profit trigger price |
| `--tpOrdPx` | Cond. | - | TP order price; use `-1` for market execution (must use `=` form: `--tpOrdPx=-1`) |
| `--tpOrdKind` | No | condition | `condition`: trigger-based TP (default); `limit`: immediate limit-order TP (no trigger phase) |
| `--tpTriggerPxType` | No | last | Price source for TP trigger: `last` (default), `index`, `mark` |
| `--slTriggerPx` | Cond. | - | Stop-loss trigger price |
| `--slOrdPx` | Cond. | - | SL order price; use `-1` for market execution (must use `=` form: `--slOrdPx=-1`) |
| `--slTriggerPxType` | No | last | Price source for SL trigger: `last` (default), `index`, `mark` |
| `--stpMode` | No | - | Self-trade prevention: `cancel_maker`, `cancel_taker`, `cancel_both` |
| `--cxlOnClosePos` | No | false | Auto-cancel this algo order when the position is closed |
| `--callbackRatio` | Cond. | - | Trailing callback as a ratio (e.g., `0.02` = 2%); cannot be combined with `--callbackSpread` |
| `--callbackSpread` | Cond. | - | Trailing callback as fixed price distance; cannot be combined with `--callbackRatio` |
| `--activePx` | No | - | Price at which trailing stop becomes active |
For `move_order_stop`: provide `--callbackRatio` or `--callbackSpread` (one required).
**Example — TP/SL worth 500 USDT notional on BTC perp (auto-convert to contracts):**
```bash
okx swap algo place --instId BTC-USDT-SWAP --side sell --ordType conditional \
--sz 500 --tgtCcy quote_ccy --tdMode cross --posSide long \
--slTriggerPx 60000 --slOrdPx=-1
```
**Example — TP/SL with 500 USDT margin cost (leverage-aware, e.g. 10x → 5000 USDT notional):**
```bash
okx swap algo place --instId BTC-USDT-SWAP --side sell --ordType conditional \
--sz 500 --tgtCcy margin --tdMode cross --posSide long \
--slTriggerPx 60000 --slOrdPx=-1
```
**Example — Immediate limit-order TP (tpOrdKind limit) — exits at a specific price without waiting for a trigger phase:**
```bash
okx swap algo place --instId BTC-USDT-SWAP --side sell --ordType conditional \
--sz 1 --tdMode cross --posSide long \
--tpTriggerPx 105000 --tpOrdPx 105000 --tpOrdKind limit
```
**Example — Self-trade prevention (stpMode cancel_maker) — cancel maker side on self-trade:**
```bash
okx swap algo place --instId BTC-USDT-SWAP --side sell --ordType conditional \
--sz 1 --tdMode cross --posSide long \
--tpTriggerPx 105000 --tpOrdPx=-1 --stpMode cancel_maker
```
**Example — Auto-cancel on position close (cxlOnClosePos):**
```bash
okx swap algo place --instId BTC-USDT-SWAP --side sell --ordType conditional \
--sz 1 --tdMode cross --posSide long \
--tpTriggerPx 105000 --tpOrdPx=-1 --cxlOnClosePos
```
---
## Swap — Place Trailing Stop
```bash
okx swap algo trail --instId <id> --side <buy|sell> --sz <n> \
--tdMode <cross|isolated> \
[--posSide <long|short>] [--reduceOnly] \
[--callbackRatio <ratio>] [--callbackSpread <spread>] \
[--activePx <price>] \
[--json]
```
| Param | Required | Default | Description |
|---|---|---|---|
| `--callbackRatio` | Cond. | - | Trailing callback as a ratio (e.g., `0.02` = 2%); cannot be combined with `--callbackSpread` |
| `--callbackSpread` | Cond. | - | Trailing callback as fixed price distance; cannot be combined with `--callbackRatio` |
| `--activePx` | No | - | Price at which trailing stop becomes active |
---
## Swap — Phase 2 Algo ordTypes (trigger / chase / iceberg / twap)
### Pending Order (trigger)
Submits a limit order when the market price crosses `--triggerPx`.
```bash
# Buy 1 BTC-USDT-SWAP when price drops to 50000 (limit at 50100):
okx swap algo place --instId BTC-USDT-SWAP --side buy --ordType trigger \
--sz 1 --tdMode cross \
--triggerPx 50000 --orderPx 50100
# Market-fill when triggered (orderPx -1); mark price as trigger source:
okx swap algo place --instId BTC-USDT-SWAP --side buy --ordType trigger \
--sz 1 --tdMode cross \
--triggerPx 50000 --orderPx -1 --triggerPxType mark
```
### Chase Order (chase)
Smart-follows best bid/ask within configurable bounds.
```bash
# Chase buy at distance 0.5 ticks, max distance 2 ticks:
okx swap algo place --instId BTC-USDT-SWAP --side buy --ordType chase \
--sz 1 --tdMode cross \
--chaseType distance --chaseVal 0.5 --maxChaseType distance --maxChaseVal 2
```
### Iceberg Order (iceberg)
Splits a large order into child orders to minimize market impact.
```bash
# Sell 10 BTC-USDT-SWAP in 0.5-contract chunks every 10s, price ceiling 51000:
okx swap algo place --instId BTC-USDT-SWAP --side sell --ordType iceberg \
--sz 10 --tdMode cross \
--szLimit 0.5 --pxLimit 51000 --timeInterval 10 --pxVar 0.001
```
### TWAP Order (twap)
Time-weighted average price split — same params as iceberg.
```bash
# Buy 5 BTC-USDT-SWAP over time (1 contract per 30s, price cap 50500):
okx swap algo place --instId BTC-USDT-SWAP --side buy --ordType twap \
--sz 5 --tdMode cross \
--szLimit 1 --pxLimit 50500 --timeInterval 30 --pxSpread 50
```
---
## Swap — Amend Algo
```bash
okx swap algo amend --instId <id> --algoId <id> \
[--newSz <n>] [--newTpTriggerPx <p>] [--newTpOrdPx <p>] \
[--newSlTriggerPx <p>] [--newSlOrdPx <p>] [--json]
```
> **Note**: Use this to modify TP/SL orders attached when placing the main order. Run `okx swap algo orders` first to find the `algoId`.
---
## Swap — Cancel Algo
```bash
okx swap algo cancel --instId <id> --algoId <id> [--json]
```
---
## Swap — List Orders
```bash
okx swap orders [--instId <id>] [--history] [--json]
```
---
## Swap — Get Order
```bash
okx swap get --instId <id> [--ordId <id>] [--clOrdId <id>] [--json]
```
Returns: `ordId`, `instId`, `side`, `posSide`, `ordType`, `px`, `sz`, `fillSz`, `avgPx`, `state`, `cTime`.
---
## Swap — Positions
```bash
okx swap positions [<instId>] [--json]
```
Returns: `instId`, `side`, `size`, `avgPx`, `upl`, `uplRatio`, `lever`. Only non-zero positions.
---
## Swap — Fills
```bash
okx swap fills [--instId <id>] [--ordId <id>] [--archive] [--json]
```
`--archive`: access older fills beyond the default window.
---
## Swap — Algo Orders
```bash
okx swap algo orders [--instId <id>] [--history] [--ordType <type>] [--json]
```
---
## Edge Cases — Swap / Perpetual
- **sz unit**: number of contracts (default), USDT notional value (`--tgtCcy quote_ccy`), or USDT margin cost (`--tgtCcy margin`). If the user specifies a USDT amount, clarify whether it is notional value or margin cost, then pass directly as `--sz` with the appropriate `--tgtCcy` — do NOT manually convert to contracts. With `margin` mode, the system queries current leverage and calculates: `contracts = floor(margin * lever / (ctVal * lastPx))`
- **Linear vs inverse**: `BTC-USDT-SWAP` is linear (USDT-margined); `BTC-USD-SWAP` is inverse (BTC-margined). For inverse, warn the user that margin and P&L are settled in BTC
- **posSide**: required in hedge mode (`long_short_mode`); omit in net mode. Check `okx account config` for `posMode`
- **tdMode**: use `cross` for cross-margin, `isolated` for isolated margin
- **Close position**: `swap close` closes the **entire** position; to partial close, use `swap place` with a reduce-only algo
- **Leverage**: max leverage varies by instrument and account level; exchange rejects if exceeded. **If set-leverage fails with "Cancel cross-margin TP/SL … or stop bots"**: this means pending algo orders or active trading bots exist on that instrument under cross margin. Troubleshoot in order: (1) `okx swap algo-orders --instId <id> --status pending` — check for TP/SL, trailing, trigger, chase orders (most common cause); (2) only if no algo orders found, check bots: `okx bot grid-orders --type contract_grid --status active`. **Never automatically cancel algo orders or stop bots** — show findings to the user and let them decide which to cancel/stop
- **Trailing stop**: use either `--callbackRatio` (relative, e.g., `0.02`) or `--callbackSpread` (absolute price), not both
- **Algo on close side**: always set `--side` opposite to position (e.g., long position → sell algo)
- **Stock tokens (instCategory=3)**: instruments like `TSLA-USDT-SWAP`, `NVDA-USDT-SWAP` follow the same linear SWAP flow (USDT-margined, sz in contracts). Key differences: (1) max leverage **5x** — check with `swap get-leverage` before placing, set with `swap leverage --lever <n≤5>`; (2) `--posSide` is always required; (3) trading restricted to stock market hours (US stocks: Mon–Fri ~09:30–16:00 ET) — confirm live ticker before placing. Use `okx market stock-tokens` to list available instruments
references/templates.md
# MCP Tool Reference & Output Conventions
## MCP Tool Reference
| Tool | Description |
|---|---|
| `spot_place_order` | Place spot order |
| `spot_cancel_order` | Cancel spot order |
| `spot_amend_order` | Amend spot order |
| `spot_place_algo_order` | Place spot TP/SL algo |
| `spot_amend_algo_order` | Amend spot algo |
| `spot_cancel_algo_order` | Cancel spot algo |
| `spot_get_orders` | List spot orders |
| `spot_get_order` | Get single spot order |
| `spot_get_fills` | Spot fill history |
| `spot_get_algo_orders` | List spot algo orders |
| `swap_place_order` | Place swap order |
| `swap_cancel_order` | Cancel swap order |
| `swap_amend_order` | Amend swap order |
| `swap_close_position` | Close swap position |
| `swap_set_leverage` | Set swap leverage |
| `swap_place_algo_order` | Place swap TP/SL algo |
| `swap_place_move_stop_order` | Place trailing stop (swap/futures) |
| `swap_amend_algo_order` | Amend swap algo |
| `swap_cancel_algo_orders` | Cancel swap algo |
| `swap_get_positions` | Swap positions |
| `swap_get_orders` | List swap orders |
| `swap_get_order` | Get single swap order |
| `swap_get_fills` | Swap fill history |
| `swap_get_leverage` | Get swap leverage |
| `swap_get_algo_orders` | List swap algo orders |
| `futures_place_order` | Place futures order |
| `futures_cancel_order` | Cancel futures order |
| `futures_amend_order` | Amend futures order |
| `futures_close_position` | Close futures position |
| `futures_set_leverage` | Set futures leverage |
| `futures_place_algo_order` | Place futures TP/SL algo |
| `futures_place_move_stop_order` | Place futures trailing stop |
| `futures_amend_algo_order` | Amend futures algo |
| `futures_cancel_algo_orders` | Cancel futures algo |
| `futures_get_orders` | List futures orders |
| `futures_get_positions` | Futures positions |
| `futures_get_fills` | Futures fill history |
| `futures_get_order` | Get single futures order |
| `futures_get_leverage` | Get futures leverage |
| `futures_get_algo_orders` | List futures algo orders |
| `option_get_instruments` | Option chain (list available contracts) |
| `option_get_greeks` | IV and Greeks by underlying |
| `option_place_order` | Place option order |
| `option_cancel_order` | Cancel option order |
| `option_amend_order` | Amend option order |
| `option_batch_cancel` | Batch cancel up to 20 option orders |
| `option_get_orders` | List option orders |
| `option_get_order` | Get single option order |
| `option_get_positions` | Option positions with live Greeks |
| `option_get_fills` | Option fill history |
---
## Output Conventions
- Always pass `--json` to list/query commands and render results as a Markdown table — never paste raw terminal output
- Every command result includes a `[profile: <name>]` tag for audit reference
- `--json` returns raw OKX API v5 response
## tgtCcy Rule
**Spot**: when user specifies a quote-currency amount (e.g. "30 USDT worth"), MUST use `--tgtCcy quote_ccy` and pass the USDT amount as `--sz`. Do NOT manually calculate base currency quantity — let the API handle the conversion.
**Swap / Futures / Options**: two USDT-based modes:
- `--tgtCcy quote_ccy`: sz is USDT **notional value** (position value). Formula: `contracts = floor(sz / (ctVal * lastPx))`.
- `--tgtCcy margin`: sz is USDT **margin cost**. The system queries current leverage and computes: `contracts = floor(sz * lever / (ctVal * lastPx))`.
When user says "500U" for a leveraged instrument, this is **ambiguous** — ask whether they mean notional value or margin cost before proceeding. Do NOT manually calculate contract count.
When user specifies contract count, omit `--tgtCcy` (defaults to `base_ccy`).
## Order Amount Safety Rules
- **Order amount mismatch**: If the order would execute at a significantly different amount than the user requested (e.g. due to minSz or conversion), STOP and inform the user. Never auto-adjust order size without explicit user confirmation.
- **No follow-up orders**: After an order executes, if the filled amount materially differs from what the user requested (beyond normal rounding or minimum lot size differences), STOP immediately. Inform the user of the actual filled amount and the discrepancy. Do NOT place any additional orders to compensate for the shortfall or overfill. Wait for explicit user instruction before taking further action.
references/workflows.md
# Trade Workflows & Examples
## Cross-Skill Workflows
### Spot market buy
> User: "Buy $500 worth of ETH at market"
```
1. okx-cex-portfolio okx account balance USDT → confirm available funds ≥ $500
↓ user approves
2. okx-cex-trade okx spot place --instId ETH-USDT --side buy --ordType market --sz 500 --tgtCcy quote_ccy
3. okx-cex-trade okx spot fills --instId ETH-USDT → confirm fill price and size
```
### Open long BTC perp with TP/SL
> User: "Long 5 contracts BTC perp at market, TP at $105k, SL at $88k"
```
1. okx-cex-portfolio okx account balance USDT → confirm margin available
2. okx-cex-portfolio okx account max-size --instId BTC-USDT-SWAP --tdMode cross → confirm size ok
↓ user approves
3. okx-cex-trade okx swap place --instId BTC-USDT-SWAP --side buy \
--ordType market --sz 5 --tdMode cross --posSide long \
--tpTriggerPx 105000 --tpOrdPx=-1 \
--slTriggerPx 88000 --slOrdPx=-1
4. okx-cex-trade okx swap positions → confirm position opened
```
> **Note:** TP/SL is attached directly to the order via `--tpTriggerPx`/`--slTriggerPx` — no separate `swap algo place` step needed. Use `swap algo place` only when adding TP/SL to an **existing** position.
### Adjust leverage then place order
> User: "Set BTC perp to 5x leverage then go long 10 contracts"
```
1. okx-cex-trade okx swap get-leverage --instId BTC-USDT-SWAP --mgnMode cross → check current lever
↓ user approves change
2. okx-cex-trade okx swap leverage --instId BTC-USDT-SWAP --lever 5 --mgnMode cross
↓ if fails with "Cancel cross-margin TP/SL … or stop bots":
2a. okx-cex-trade okx swap algo-orders --instId BTC-USDT-SWAP --status pending
→ check for TP/SL, trailing, trigger, chase orders (most common cause)
2b. (only if 2a returns nothing)
okx-cex-trade okx bot grid-orders --type contract_grid --status active
→ check for active trading bots
2c. Show results to user — NEVER auto-cancel orders or stop bots.
Ask user which orders/bots to cancel/stop, then retry leverage.
3. okx-cex-trade okx swap place --instId BTC-USDT-SWAP --side buy \
--ordType market --sz 10 --tdMode cross --posSide long
4. okx-cex-trade okx swap positions → confirm position + leverage
```
### Place trailing stop on open position
> User: "Set a 3% trailing stop on my open position"
Spot example (no margin mode needed):
```
1. okx-cex-portfolio okx account balance BTC → confirm spot BTC holdings
2. okx-cex-market okx market ticker BTC-USDT → current price reference
↓ user approves
3. okx-cex-trade okx spot algo trail --instId BTC-USDT --side sell \
--sz <spot_sz> --callbackRatio 0.03
4. okx-cex-trade okx spot algo orders --instId BTC-USDT → confirm trail order placed
```
Swap/Perpetual example:
```
1. okx-cex-trade okx swap positions → confirm size of open long
2. okx-cex-market okx market ticker BTC-USDT-SWAP → current price reference
↓ user approves
3. okx-cex-trade okx swap algo trail --instId BTC-USDT-SWAP --side sell \
--sz <pos_size> --tdMode cross --posSide long --callbackRatio 0.03
4. okx-cex-trade okx swap algo orders --instId BTC-USDT-SWAP → confirm trail order placed
```
Futures/Delivery example:
```
1. okx-cex-trade okx futures positions → confirm size of open long
2. okx-cex-market okx market ticker BTC-USDT-<YYMMDD> → current price reference
↓ user approves
3. okx-cex-trade okx futures algo trail --instId BTC-USDT-<YYMMDD> --side sell \
--sz <pos_size> --tdMode cross --posSide long --callbackRatio 0.03
4. okx-cex-trade okx futures algo orders --instId BTC-USDT-<YYMMDD> → confirm trail order placed
```
### Trade a stock token (TSLA / NVDA / AAPL)
> User: "I want to long TSLA with 500 USDT"
```
1. okx-cex-market okx market stock-tokens → confirm TSLA-USDT-SWAP is available
2. okx-cex-market okx market ticker TSLA-USDT-SWAP → current price (e.g., markPx=310 USDT)
3. okx-cex-market okx market instruments --instType SWAP --instId TSLA-USDT-SWAP --json
→ ctVal=1, minSz=1, lotSz=1
Agent computes: sz = floor(500 / (310 × 1)) = 1 contract (~310 USDT)
Agent shows conversion summary and asks to confirm
↓ user confirms
4. okx-cex-portfolio okx account balance USDT → confirm margin available
5. okx-cex-trade okx swap get-leverage --instId TSLA-USDT-SWAP --mgnMode cross
→ check current leverage; must be ≤ 5x
(if not set or > 5x) okx swap leverage --instId TSLA-USDT-SWAP --lever 5 --mgnMode cross
6. okx-cex-trade okx swap place --instId TSLA-USDT-SWAP --side buy --ordType market \
--sz 1 --tdMode cross --posSide long
7. okx-cex-trade okx swap positions TSLA-USDT-SWAP → confirm position opened
```
> ⚠ **Stock token constraints**: max leverage **5x** (exchange rejects > 5x). `--posSide` is required. Trading follows stock market hours — confirm live ticker before placing.
---
### Open linear swap by USDT amount
> User: "用 200 USDT 做多 ETH 永续 (cross margin)"
```
1. okx-cex-market okx market instruments --instType SWAP --instId ETH-USDT-SWAP --json
→ ctVal=0.1 ETH, minSz=1, lotSz=1
2. okx-cex-market okx market mark-price --instType SWAP --instId ETH-USDT-SWAP --json
→ markPx=2000 USDT
3. Agent computes: sz = floor(200 / (2000 × 0.1)) = 1 contract (~200 USDT)
Agent informs user of conversion summary and asks to confirm
↓ user confirms
4. okx-cex-trade okx swap place --instId ETH-USDT-SWAP --side buy --ordType market \
--sz 1 --tdMode cross --posSide long
5. okx-cex-trade okx swap positions ETH-USDT-SWAP → confirm position opened
```
### Open inverse swap by USDT amount
> User: "用 500 USDT 开一个 BTC 币本位永续多单"
```
1. okx-cex-market okx market instruments --instType SWAP --instId BTC-USD-SWAP --json
→ ctVal=100 USD, minSz=1
2. Agent computes: sz = floor(500 / 100) = 5 contracts
Agent warns: "BTC-USD-SWAP 是币本位合约,保证金和盈亏以 BTC 结算,非 USDT。
请确认账户有足够 BTC 作为保证金。"
Agent shows conversion summary and asks to confirm
↓ user confirms
3. okx-cex-trade okx swap place --instId BTC-USD-SWAP --side buy --ordType market \
--sz 5 --tdMode cross --posSide long
4. okx-cex-trade okx swap positions BTC-USD-SWAP → confirm position opened
```
### Modify existing TP/SL (take-profit / stop-loss)
> User: "把我 BTC 永续的止损改到 $85k" / "Change my BTC swap stop-loss to $85,000"
TP/SL orders attached at placement time (via `--tpTriggerPx`/`--slTriggerPx`) are algo orders in OKX. To modify them, find the `algoId` first, then use `algo amend`.
```
1. okx-cex-trade okx swap algo orders --instId BTC-USDT-SWAP
→ find TP/SL algo order → algoId (e.g. ALGO789012)
↓ confirm which order to modify
2. okx-cex-trade okx swap algo amend --instId BTC-USDT-SWAP --algoId ALGO789012 \
--newSlTriggerPx 85000 --newSlOrdPx=-1
3. okx-cex-trade okx swap algo orders --instId BTC-USDT-SWAP
→ confirm TP/SL updated
```
> **Key insight**: `amend` (regular) modifies price/size of the main order; `algo amend` modifies TP/SL trigger prices. Use `algo orders` to look up the `algoId` first.
For spot, the pattern is the same:
```
1. okx-cex-trade okx spot algo orders --instId BTC-USDT
→ find TP/SL algo order → algoId
2. okx-cex-trade okx spot algo amend --instId BTC-USDT --algoId <id> \
--newSlTriggerPx <price> --newSlOrdPx=-1
3. okx-cex-trade okx spot algo orders --instId BTC-USDT
→ confirm TP/SL updated
```
### Cancel all open spot orders
> User: "Cancel all my open BTC spot orders"
```
1. okx-cex-trade okx spot orders → list open orders
2. okx-cex-trade (for each ordId) okx spot cancel --instId BTC-USDT --ordId <id>
3. okx-cex-trade okx spot orders → confirm all cancelled
```
### Buy a BTC call option
> User: "Buy 2 BTC call options at strike 95000 expiring end of March"
```
1. okx-cex-trade okx option instruments --uly BTC-USD --expTime 250328
→ find exact instId (e.g. BTC-USD-250328-95000-C)
2. okx-cex-trade okx option greeks --uly BTC-USD --expTime 250328
→ check IV, delta, and markPx to assess fair value
3. okx-cex-portfolio okx account balance → confirm enough USDT/BTC for premium
↓ user approves
4. okx-cex-trade okx option place --instId BTC-USD-250328-95000-C \
--side buy --ordType limit --tdMode cash --sz 2 --px 0.005
5. okx-cex-trade okx option orders → confirm order is live
```
### Check option portfolio Greeks
> User: "What's my total delta exposure from options?"
```
1. okx-cex-trade okx option positions → live positions with per-contract Greeks
2. okx-cex-market okx market ticker BTC-USD → current spot price for context
```
---
## Input / Output Examples
**"Buy 0.05 BTC at market"**
```bash
okx spot place --instId BTC-USDT --side buy --ordType market --sz 0.05
# → Order placed: 7890123456 (OK)
```
**"Set a limit sell for 0.1 ETH at $3500"**
```bash
okx spot place --instId ETH-USDT --side sell --ordType limit --sz 0.1 --px 3500
# → Order placed: 7890123457 (OK)
```
**"Show my open spot orders"**
```bash
okx spot orders
# → table: ordId, instId, side, type, price, size, filled, state
```
**"Long 10 contracts BTC perp at market (cross margin)"**
```bash
okx swap place --instId BTC-USDT-SWAP --side buy --ordType market --sz 10 \
--tdMode cross --posSide long
# → Order placed: 7890123458 (OK)
```
**"Long 10 contracts BTC perp with TP at $105k and SL at $88k"**
```bash
okx swap place --instId BTC-USDT-SWAP --side buy --ordType market --sz 10 \
--tdMode cross --posSide long \
--tpTriggerPx 105000 --tpOrdPx=-1 --slTriggerPx 88000 --slOrdPx=-1
# → Order placed: 7890123459 (OK) — TP/SL attached via attachAlgoOrds
```
**"Set take profit at $105k and stop loss at $88k on an existing BTC perp long"**
```bash
okx swap algo place --instId BTC-USDT-SWAP --side sell --ordType oco --sz 10 \
--tdMode cross --posSide long \
--tpTriggerPx 105000 --tpOrdPx=-1 \
--slTriggerPx 88000 --slOrdPx=-1
# → Algo order placed: ALGO456789 (OK)
```
**"Close my ETH perp position"**
```bash
okx swap close --instId ETH-USDT-SWAP --mgnMode cross --posSide long
# → Position closed: ETH-USDT-SWAP long
```
**"Set BTC perp leverage to 5x (cross)"**
```bash
okx swap leverage --instId BTC-USDT-SWAP --lever 5 --mgnMode cross
# → Leverage set: 5x BTC-USDT-SWAP
```
**"Long 1 contract TSLA stock token at market (cross margin)"**
```bash
okx swap place --instId TSLA-USDT-SWAP --side buy --ordType market --sz 1 \
--tdMode cross --posSide long
# → Order placed: 7890123461 (OK) [profile: live]
```
**"Open short on NVDA, 2 contracts"**
```bash
okx swap place --instId NVDA-USDT-SWAP --side sell --ordType market --sz 2 \
--tdMode cross --posSide short
# → Order placed: 7890123462 (OK) [profile: live]
```
**"Place a 2% trailing stop on my BTC perp long"**
```bash
okx swap algo trail --instId BTC-USDT-SWAP --side sell --sz 10 \
--tdMode cross --posSide long --callbackRatio 0.02
# → Trailing stop placed: TRAIL123 (OK)
```
**"Place a 3% trailing stop on my spot BTC"**
```bash
okx spot algo trail --instId BTC-USDT --side sell --sz 0.01 --callbackRatio 0.03
# → Trailing stop placed: TRAIL456 (OK)
```
**"Place a 2% trailing stop on my BTC futures long"**
```bash
okx futures algo trail --instId BTC-USDT-<YYMMDD> --side sell --sz 5 \
--tdMode cross --posSide long --callbackRatio 0.02
# → Trailing stop placed: TRAIL789 (OK)
```
**"Close my BTC futures long position"**
```bash
okx futures close --instId BTC-USDT-260328 --mgnMode cross --posSide long
# → Position closed: BTC-USDT-260328 long
```
**"Set BTC futures leverage to 10x (cross)"**
```bash
okx futures leverage --instId BTC-USDT-260328 --lever 10 --mgnMode cross
# → Leverage set: 10x BTC-USDT-260328
```
**"Place a TP at $105k and SL at $88k on my ETH futures long"**
```bash
okx futures algo place --instId ETH-USDT-260328 --side sell --ordType oco --sz 5 \
--tdMode cross --posSide long \
--tpTriggerPx 105000 --tpOrdPx=-1 \
--slTriggerPx 88000 --slOrdPx=-1
# → Algo order placed: ALGO789012 (OK)
```
**"Show my open swap positions"**
```bash
okx swap positions
# → table: instId, side, size, avgPx, upl, uplRatio, lever
```
**"What are my recent fill trades for BTC spot?"**
```bash
okx spot fills --instId BTC-USDT
# → table: instId, side, fillPx, fillSz, fee, ts
```
**"Show me the BTC option chain expiring March 28"**
```bash
okx option instruments --uly BTC-USD --expTime 250328
# → table: instId, expTime, stk, optType (C/P), state
```
**"What's the IV and delta for BTC options expiring March 28?"**
```bash
okx option greeks --uly BTC-USD --expTime 250328
# → table: instId, delta, gamma, theta, vega, iv (markVol), markPx
```
**"Buy 1 BTC call at strike 95000 expiring March 28, limit at 0.005 BTC"**
```bash
okx option place --instId BTC-USD-250328-95000-C \
--side buy --ordType limit --tdMode cash --sz 1 --px 0.005
# → Order placed: 7890123460 (OK)
```
**"Show my open option positions"**
```bash
okx option positions
# → table: instId, posSide, pos, avgPx, upl, delta, gamma, theta, vega
```
SKILL.md
---
name: okx-cex-trade
description: "Use when the user asks to 'buy BTC', 'sell ETH', 'place a limit order', 'place a market order', 'cancel my order', 'amend my order', 'long BTC perp', 'short ETH swap', 'open a position', 'close a position', 'set take profit', 'limit take profit', 'immediate TP', 'set stop loss', 'self-trade prevention', 'stpMode', 'auto-cancel on close', 'trailing stop', 'pending order', 'chase order', 'iceberg', 'TWAP', 'split order', 'large order', 'set leverage', 'check my orders', 'fill history', 'buy a call', 'sell a put', 'option chain', 'implied volatility', 'IV', 'Greeks', 'delta', 'gamma', 'event contract', 'buy Yes', 'buy No', 'buy Up', 'buy Down', 'prediction market', or any request to place, cancel, or amend spot, swap, futures, options, or event contract orders on OKX CEX. Covers conditional (TP/SL/trailing) algo orders. Requires API credentials. Do NOT use for market data (okx-cex-market), account balance (okx-cex-portfolio), or bots (okx-cex-bot)."
license: MIT
metadata:
author: okx
version: "1.4.5"
homepage: "https://www.okx.com"
agent:
requires:
bins: ["okx"]
install:
- id: npm
kind: node
package: "@okx_ai/okx-trade-cli@1.4.5"
bins: ["okx"]
label: "Install okx CLI (npm)"
---
# OKX CEX Trading CLI
Spot, perpetual swap, delivery futures, **options**, and **event contract** order management on OKX exchange. Place, cancel, amend, and monitor orders; query option chains and Greeks; trade binary outcome event contracts (Yes/No, Up/Down); set take-profit/stop-loss and trailing stops; manage leverage and positions. **Requires API credentials.**
> **CLI vs MCP tool names** — Subcommands use spaces (`okx swap algo place`, `okx bot grid create`), not hyphens. Do NOT convert an MCP tool identifier (`swap_place_algo_order`) into a hyphen-joined CLI command (`okx swap place-algo`) — that will be rejected with "Unknown command". Per-module mapping tables live in `references/<module>-commands.md`.
## Preflight
Before running any command, follow [`../_shared/preflight.md`](../_shared/preflight.md).
Use `metadata.version` from this file's frontmatter as the reference for Step 2.
## Prerequisites
1. Install `okx` CLI:
```bash
npm install -g @okx_ai/okx-trade-cli
```
2. Configure credentials:
```bash
okx config init # select site -> follow browser OAuth flow
```
3. Test with demo mode (simulated trading, no real funds):
```bash
okx --demo spot orders
```
> **Security**: NEVER accept credentials in chat. Guide users to `okx config init` for setup.
## Credential & Profile Check
**Run this check before any authenticated command.** The auth method is detected during [preflight](../_shared/preflight.md) Step 2 and remembered for the session.
### Step A — Verify credentials
Run **both** commands — the `apiKey` field from `okx auth status --json` is the auth-binary's internal state and is always `false` regardless of whether `~/.okx/config.toml` has an API-key profile. `okx config show --json` is the only authoritative source for API-key presence.
```bash
okx config show --json # reveals API-key profiles (TOML config)
okx auth status --json # reveals OAuth session state (auth-binary state)
```
Apply **in this order** — first match wins:
- `config show --json` has any profile with a non-empty `api_key` field → **API Key mode**. Proceed to Step B.
- No API-key profile **AND** `auth status --json` returns `"status":"logged_in"` → **OAuth mode**. Proceed to Step B.
- No API-key profile **AND** `"status":"pending"` — login is in progress, wait for it to complete.
- No API-key profile **AND** `"status":"not_logged_in"` — **stop all operations**, load `okx-cex-auth` skill and follow login steps, wait for completion.
### Step B — Confirm trading mode
**Resolution rules:**
1. Current message intent is clear (e.g. "real" / "实盘" / "live" → live; "test" / "模拟" / "demo" → demo) → use it and inform the user
2. Current message has no explicit declaration → check conversation context for a previous choice:
- Found → reuse it, inform user
- Not found → ask: `"Live (实盘) or Demo (模拟盘)?"` — wait for answer before proceeding
**How to apply the mode depends on auth method (detected in Step A):**
| Auth method | Live (实盘) | Demo (模拟盘) |
|---|---|---|
| **API Key** | `--profile <live-profile>` | `--profile <demo-profile>` |
| **OAuth** | *(no flag needed, live is default)* | `--demo` |
- **API Key users**: run `okx config show --json` to discover available profile names and their `demo` settings. Use `--profile <name>` to select the correct one.
- **OAuth users**: omit flags for live trading; add `--demo` for simulated trading. Do **not** use `--profile` to switch modes.
### Handling Authentication Errors
**Authentication error** (error contains "401", "Session expired", or "Run `okx auth login` first"):
1. **Stop immediately** — do not retry the same command
2. Inform the user: "Authentication failed. Your session may have expired."
3. Load `okx-cex-auth` skill and follow the re-authentication steps
4. After successful re-authentication, retry the original command
## Demo vs Live Mode
| Mode | Funds | API Key param | OAuth param |
|---|---|---|---|
| 实盘 (live) | Real money — irreversible | `--profile <live-profile>` | *(default, no flag)* |
| 模拟盘 (demo) | Simulated — no real funds | `--profile <demo-profile>` | `--demo` |
**Rules:**
1. Trading mode is **required** on every authenticated command — determined in "Credential & Profile Check" Step B
2. Every response after a command must append: `[mode: live]` or `[mode: demo]`
## Skill Routing
- For market data (prices, charts, depth, funding rates) → use `okx-cex-market`
- For account balance, P&L, positions, fees, transfers → use `okx-cex-portfolio`
- For regular spot/swap/futures/options/algo orders → use `okx-cex-trade` (this skill)
- For **browsing/discovering** event contracts (what's available, how many, list active) → use `okx-cex-trade` with `okx event browse` / `okx event series`
- For **trading** event contracts (place/cancel/amend prediction market orders) → use `okx-cex-trade` with `okx event place` / `okx event cancel` / `okx event amend`
- For grid and DCA trading bots → use `okx-cex-bot`
> **Important**: When user asks about "contracts" in the context of event contracts or prediction markets, route to this skill — NOT to `okx-cex-portfolio`. Portfolio does not handle event contracts — it covers account balance, positions, P&L, and transfers only.
## Sz Handling for Derivatives
### ⚠ CRITICAL: Always verify contract face value before placing orders
Before placing any SWAP/FUTURES/OPTION order, call `market_get_instruments` to get `ctVal` (contract face value). **Do NOT assume contract sizes** — they vary by instrument (e.g. ETH-USDT-SWAP = 0.1 ETH/contract, BTC-USDT-SWAP = 0.01 BTC/contract).
Use `ctVal` to:
- Calculate the correct number of contracts from user's intended position size
- Verify margin requirements before submitting the order
- Show the user the actual position value: `sz × ctVal × price`
### SWAP and FUTURES orders
**Three tgtCcy modes for USDT-denominated sizing:**
| `--tgtCcy` | sz meaning | Conversion formula | Example: "500U" at 10x lever |
|---|---|---|---|
| `base_ccy` (default) | contract count | no conversion | 500 contracts |
| `quote_ccy` | USDT notional value | `floor(sz / (ctVal * lastPx))` | 500 USDT notional |
| `margin` | USDT margin cost | `floor(sz * lever / (ctVal * lastPx))` | 500 USDT margin = 5000 USDT notional |
**When user specifies a USDT amount** (e.g. "200U", "500 USDT", "$1000"):
→ **AMBIGUOUS** — this could mean notional value OR margin cost.
You MUST ask the user to clarify before proceeding:
- **notional value**: sz = position value in USDT (e.g. 500 USDT buys 500 USDT worth of contracts directly)
- **margin cost**: actual position = sz × leverage (e.g. 500 USDT margin at 10× = 5000 USDT notional position)
Wait for the user's answer before continuing.
- If notional value → use `--tgtCcy quote_ccy`
- If margin cost → use `--tgtCcy margin`
**When user specifies contracts** (e.g. "2 张", "5 contracts"):
→ First verify `ctVal` via `market_get_instruments`, then use `--sz` with the contract count. Confirm with user: "X contracts = X × ctVal underlying, total value ≈ $Y".
**When user gives a plain number with no unit** (for swap/futures):
→ **AMBIGUOUS** — You MUST ask the user to clarify before proceeding:
- **contract count**: X contracts (each worth ctVal of underlying)
- **USDT notional value**: position value in USDT
- **USDT margin cost**: margin amount (actual position = X × leverage)
Wait for the user's answer before continuing.
⚠ **Inverse contracts** (`*-USD-SWAP`, `*-USD-YYMMDD`): `tgtCcy=quote_ccy` and `tgtCcy=margin` also work (note: `quote_ccy` = USD, not USDT, for inverse instruments). Always warn: "This is an inverse contract. Margin and P&L are settled in BTC, not USDT."
### Option orders
When the user specifies a USDT amount for options, use `--tgtCcy quote_ccy` (notional) or `--tgtCcy margin` (margin cost) and pass the amount as `--sz`. The system automatically converts to contracts. Note: option contracts typically have large face values (e.g. ctVal=1 BTC ≈ $84,000), so the minimum USDT amount for 1 contract is high. For option sellers (`cross`/`isolated` tdMode), `margin` mode accounts for leverage automatically.
## Quickstart
```bash
# Market buy 0.01 BTC (spot)
okx spot place --instId BTC-USDT --side buy --ordType market --sz 0.01
# Buy $10 worth of SOL (spot, USDT amount)
okx spot place --instId SOL-USDT --side buy --ordType market --sz 10 --tgtCcy quote_ccy
# Limit sell 0.01 BTC at $100,000 (spot)
okx spot place --instId BTC-USDT --side sell --ordType limit --sz 0.01 --px 100000
# Long 1 contract BTC perp (cross margin)
okx swap place --instId BTC-USDT-SWAP --side buy --ordType market --sz 1 \
--tdMode cross --posSide long
# Long 1000 USDT notional value of BTC perp (auto-convert to contracts)
okx swap place --instId BTC-USDT-SWAP --side buy --ordType market --sz 1000 \
--tgtCcy quote_ccy --tdMode cross --posSide long
# Long with 500 USDT margin at current leverage (e.g. 10x → 5000 USDT notional)
okx swap place --instId BTC-USDT-SWAP --side buy --ordType market --sz 500 \
--tgtCcy margin --tdMode cross --posSide long
# Long 1 contract with attached TP/SL (one step)
okx swap place --instId BTC-USDT-SWAP --side buy --ordType market --sz 1 \
--tdMode cross --posSide long \
--tpTriggerPx 105000 --tpOrdPx=-1 --slTriggerPx 88000 --slOrdPx=-1
# Close BTC perp long position entirely at market
okx swap close --instId BTC-USDT-SWAP --mgnMode cross --posSide long
# Set 10x leverage on BTC perp (cross)
okx swap leverage --instId BTC-USDT-SWAP --lever 10 --mgnMode cross
# Set TP/SL on a spot BTC position
okx spot algo place --instId BTC-USDT --side sell --ordType oco --sz 0.01 \
--tpTriggerPx 105000 --tpOrdPx=-1 \
--slTriggerPx 88000 --slOrdPx=-1
# Place trailing stop on BTC perp long (callback 2%)
okx swap algo trail --instId BTC-USDT-SWAP --side sell --sz 1 \
--tdMode cross --posSide long --callbackRatio 0.02
# View open spot orders
okx spot orders
# View open swap positions
okx swap positions
# Cancel a spot order
okx spot cancel --instId BTC-USDT --ordId <ordId>
# --- Event Contract ---
# List event series
okx event series
# Browse live markets in a series
okx event markets BTC-ABOVE-DAILY --state live
# Place event contract order
okx event place --instId BTC-ABOVE-DAILY-260224-1600-70000 --side buy --outcome YES --sz 10
```
## Command Index
### Spot Orders (12 commands)
| # | Command | Type | Description |
|---|---|---|---|
| 1 | `okx spot place` | WRITE | Place spot order (market/limit/post_only/fok/ioc) |
| 2 | `okx spot cancel` | WRITE | Cancel spot order |
| 3 | `okx spot amend` | WRITE | Amend spot order price or size |
| 4 | `okx spot algo place` | WRITE | Place spot TP/SL algo order |
| 5 | `okx spot algo amend` | WRITE | Amend spot TP/SL levels |
| 6 | `okx spot algo cancel` | WRITE | Cancel spot algo order |
| 7 | `okx spot algo trail` | WRITE | Place spot trailing stop order |
| 8 | `okx spot orders` | READ | List open or historical spot orders |
| 9 | `okx spot get` | READ | Single spot order details |
| 10 | `okx spot fills` | READ | Spot trade fill history |
| 11 | `okx spot algo orders` | READ | List spot TP/SL algo orders |
| 12 | `okx spot leverage` | WRITE | Set leverage for spot **margin** (borrowing). Pair-level (`--instId`) or currency-level cross (`--ccy`, required for borrow-enabled / multi-ccy / portfolio margin) |
For full command syntax, parameter tables, and edge cases, read `{baseDir}/references/spot-commands.md`.
### Swap / Perpetual Orders (15 commands)
| # | Command | Type | Description |
|---|---|---|---|
| 13 | `okx swap place` | WRITE | Place perpetual swap order |
| 14 | `okx swap cancel` | WRITE | Cancel swap order |
| 15 | `okx swap amend` | WRITE | Amend swap order price or size |
| 16 | `okx swap close` | WRITE | Close entire position at market |
| 17 | `okx swap leverage` | WRITE | Set leverage for an instrument |
| 18 | `okx swap algo place` | WRITE | Place swap TP/SL algo order |
| 19 | `okx swap algo trail` | WRITE | Place swap trailing stop order |
| 20 | `okx swap algo amend` | WRITE | Amend swap algo order |
| 21 | `okx swap algo cancel` | WRITE | Cancel swap algo order |
| 22 | `okx swap positions` | READ | Open perpetual swap positions |
| 23 | `okx swap orders` | READ | List open or historical swap orders |
| 24 | `okx swap get` | READ | Single swap order details |
| 25 | `okx swap fills` | READ | Swap trade fill history |
| 26 | `okx swap get-leverage` | READ | Current leverage settings |
| 27 | `okx swap algo orders` | READ | List swap algo orders |
For full command syntax, parameter tables, and edge cases, read `{baseDir}/references/swap-commands.md`.
### Futures / Delivery Orders (15 commands)
| # | Command | Type | Description |
|---|---|---|---|
| 28 | `okx futures place` | WRITE | Place delivery futures order |
| 29 | `okx futures cancel` | WRITE | Cancel delivery futures order |
| 30 | `okx futures amend` | WRITE | Amend delivery futures order price or size |
| 31 | `okx futures close` | WRITE | Close entire futures position at market |
| 32 | `okx futures leverage` | WRITE | Set leverage for a futures instrument |
| 33 | `okx futures algo place` | WRITE | Place futures TP/SL algo order |
| 34 | `okx futures algo trail` | WRITE | Place futures trailing stop order |
| 35 | `okx futures algo amend` | WRITE | Amend futures algo order |
| 36 | `okx futures algo cancel` | WRITE | Cancel futures algo order |
| 37 | `okx futures orders` | READ | List delivery futures orders |
| 38 | `okx futures positions` | READ | Open delivery futures positions |
| 39 | `okx futures fills` | READ | Delivery futures fill history |
| 40 | `okx futures get` | READ | Single delivery futures order details |
| 41 | `okx futures get-leverage` | READ | Current futures leverage settings |
| 42 | `okx futures algo orders` | READ | List futures algo orders |
For full command syntax, parameter tables, and edge cases, read `{baseDir}/references/futures-commands.md`.
### Options Orders (10 commands)
| # | Command | Type | Description |
|---|---|---|---|
| 43 | `okx option instruments` | READ | Option chain: list available contracts for an underlying |
| 44 | `okx option greeks` | READ | Implied volatility + Greeks (delta/gamma/theta/vega) by underlying |
| 45 | `okx option place` | WRITE | Place option order (call or put, buyer or seller) |
| 46 | `okx option cancel` | WRITE | Cancel unfilled option order |
| 47 | `okx option amend` | WRITE | Amend option order price or size |
| 48 | `okx option batch-cancel` | WRITE | Batch cancel up to 20 option orders |
| 49 | `okx option orders` | READ | List option orders (live / history / archive) |
| 50 | `okx option get` | READ | Single option order details |
| 51 | `okx option positions` | READ | Open option positions with live Greeks |
| 52 | `okx option fills` | READ | Option trade fill history |
For full command syntax, USDT-to-contracts conversion formula, tdMode rules, and edge cases, read `{baseDir}/references/options-commands.md`.
### Event Contract Orders (9 commands)
| # | Command | Type | Description |
|---|---|---|---|
| 53 | `okx event browse` | READ | Browse active event contracts grouped by type (series + live markets in one call) |
| 54 | `okx event series` | READ | List event series (e.g. BTC-ABOVE-DAILY, BTC-UPDOWN-15MIN) |
| 55 | `okx event events <seriesId>` | READ | List events in a series |
| 56 | `okx event markets <seriesId>` | READ | List markets; expired includes Outcome and Settlement value |
| 57 | `okx event place ...` | WRITE | Place event order (outcome required) |
| 58 | `okx event amend <instId> <ordId>` | WRITE | Amend event order (price/size) |
| 59 | `okx event cancel <instId> <ordId>` | WRITE | Cancel event order |
| 60 | `okx event orders` | READ | Pending or historical orders |
| 61 | `okx event fills` | READ | Fill history |
For full command syntax, parameter tables, and edge cases, read `{baseDir}/references/event-commands.md`.
## Operation Flow
### Step 0 — Credential & Profile Check
Before any authenticated command: see [Credential & Profile Check](#credential--profile-check). Determine auth method and trading mode before executing.
After every command result: append `[mode: live]` or `[mode: demo]`.
### Step 1 — Identify instrument type and action
**Spot** (instId format: `BTC-USDT`):
- Place/cancel/amend order → `okx spot place/cancel/amend`
- TP/SL conditional → `okx spot algo place/amend/cancel`
- Trailing stop → `okx spot algo trail`
- Query → `okx spot orders/get/fills/algo orders`
**Swap/Perpetual** (instId format: `BTC-USDT-SWAP`):
- Place/cancel/amend order → `okx swap place/cancel/amend`
- Close position → `okx swap close`
- Leverage → `okx swap leverage` / `okx swap get-leverage`
- TP/SL conditional → `okx swap algo place/amend/cancel`
- Trailing stop → `okx swap algo trail`
- Query → `okx swap positions/orders/get/fills/get-leverage/algo orders`
**Futures/Delivery** (instId format: `BTC-USDT-<YYMMDD>`):
- Place/cancel/amend order → `okx futures place/cancel/amend`
- Close position → `okx futures close`
- Leverage → `okx futures leverage` / `okx futures get-leverage`
- TP/SL conditional → `okx futures algo place/amend/cancel`
- Trailing stop → `okx futures algo trail`
- Query → `okx futures orders/positions/fills/get/get-leverage/algo orders`
**Options** (instId format: `BTC-USD-250328-95000-C` or `...-P`):
- Step 1 (required): find valid instId → `okx option instruments --uly BTC-USD`
- Step 2 (recommended): check IV and Greeks → `okx option greeks --uly BTC-USD`
- Place/cancel/amend → `okx option place/cancel/amend`
- Batch cancel → `okx option batch-cancel --orders '[...]'`
- Query → `okx option orders/get/positions/fills`
- **tdMode**: `cash` for buyers; `cross` or `isolated` for sellers
**Event Contracts**:
Instrument ID (`instId`, API field) format: `{UNDERLYING}-{TYPE}-{YYMMDD}-{HHMM}-{STRIKE}` for "Price Above Target" / "One Touch" contracts (e.g. `BTC-ABOVE-DAILY-260224-1600-70000`), or `{UNDERLYING}-{TYPE}-{YYMMDD}-{START}-{END}` for "Price Direction (Up/Down)" contracts (e.g. `BTC-UPDOWN-15MIN-260224-1600-1615`). Always obtain the instrument ID from `okx event markets <seriesId>` — never guess or use placeholders.
Series ID (`seriesId`, API field): human-readable (e.g. `BTC-ABOVE-DAILY`, `BTC-UPDOWN-15MIN`) or internal random string (e.g. `FMQRZ`). Both are valid for subsequent commands. Obtain from `okx event series`.
Event contract trading flow:
1. **Discover** → `okx event browse` (preferred, returns series + live markets in one call) or `okx event series` — present results grouped by type; highlight named series; always show the Series ID
2. **Browse live markets** → `okx event markets <seriesId> --state live` — obtains the instrument ID for each tradeable contract; if a live Price is shown, it is the event contract price (0.01–0.99), not the underlying asset price — reflects the market-implied probability when actively trading
3. **Check event details** → `okx event events <seriesId>`
4. **Confirm + Place** → `okx event place <instId> <side> <outcome> <sz>` — only after user explicitly confirms
5. **Track** → `okx event orders --status open` / `okx account positions --instType EVENTS`
6. **Exit or settle** → sell via `okx event place <instId> sell <outcome> <sz>`, or wait for `--state expired`
Edge cases:
- **Settled results**: `okx event markets <seriesId> --state expired` — no separate ended tool
**Event Contract sz Rules:**
- **Market order** (`ordType=market`): `--sz` is quote currency amount.
- **Limit order** (`ordType=limit` / `post_only`): `--sz` is number of contracts (integer). Each contract settles at 1 unit of quote currency; cost per contract = `px` (event contract price, 0.01–0.99). E.g. 10 contracts at px=0.5 costs 5.
- **px semantics**: `px` is the event contract price (0.01–0.99), NOT the underlying asset price. When actively trading, it reflects the market-implied probability. Example: `px=0.6` means the market is pricing the event at roughly 60%.
- **Outcome display**: expired/result views show translated values. For `price_up_down`, treat `YES/NO` as `UP/DOWN`.
For event contract workflows and step-by-step examples, read `{baseDir}/references/event-workflows.md`.
For cross-skill workflows and step-by-step examples, read `{baseDir}/references/workflows.md`.
### Step 2 — Confirm profile, then confirm write parameters
**Read commands** (orders, positions, fills, get, get-leverage, algo orders): run immediately.
- `--history` flag: defaults to active/open; use `--history` only if user explicitly asks for history
- `--ordType` for algo: `conditional` = single TP or SL; `oco` = both TP and SL together
- `--tdMode` for swap/futures: `cross` or `isolated`; spot always uses `cash` (set automatically)
- `--posSide` for hedge mode: `long` or `short`; omit in net mode
**Write commands** (place, cancel, amend, close, leverage, algo): confirm the key order details once before executing:
- Spot place: confirm `--instId`, `--side`, `--ordType`, `--sz` (and `--tgtCcy quote_ccy` if quote-currency amount)
- Swap/Futures place: confirm `--instId`, `--side`, `--sz`, `--tdMode`, and **explicitly confirm order mode** when user specifies a USDT amount: `--tgtCcy quote_ccy` (notional value, sz = position value) or `--tgtCcy margin` (margin cost, actual position = sz * leverage). Always state which mode is being used.
- Option place: confirm `--instId`, `--side`, `--sz`, `--tdMode` (and `--tgtCcy quote_ccy` or `--tgtCcy margin` if USDT amount — system auto-converts); do NOT attach TP/SL
- Event Contract place: confirm `--instId`, `--side`, `--outcome`, `--sz`, `--ordType`; for market orders sz is quote currency amount, for limit orders sz is number of contracts + `--px` required
- Swap/Futures close: confirm `--instId`, `--mgnMode`, `--posSide`
- Leverage: confirm new leverage and impact on existing positions. **Pre-checks to avoid common 400s**: (a) `--lever` must be a positive number within the instrument's max (see `okx market instruments` → `lever`); (b) for `--mgnMode isolated` in hedge pos mode, `--posSide` is required — each side (`long`, `short`) must be set **separately**, setting one does NOT auto-apply to the other; (c) **portfolio-margin accounts cannot adjust `cross` leverage for SWAP/FUTURES** — OKX will reject; if unsure, run `okx account config` and check `acctLv` first. **If set-leverage fails** (error mentions "cancel orders or stop bots"): troubleshoot in priority order — (1) query pending algo orders first (`swap/futures algo-orders --status pending`), as this is the most common blocker; (2) only if no algo orders, check active bots (`bot grid-orders`). **Do NOT automatically cancel orders or stop bots** — present findings and let the user decide
- Algo place (TP/SL): confirm trigger prices; use `--tpOrdPx=-1` for market execution
- Algo trail: confirm `--callbackRatio` (e.g., `0.02` = 2%) or `--callbackSpread`
For full parameter details per command, read the relevant reference file.
### Error-suggested remediation safeguard
When an OKX API error message suggests a fix that involves **write operations** (cancel orders, close positions, stop bots/strategies, transfer funds, etc.), you **MUST NOT** automatically execute those actions. Instead:
1. **Report** the error and its suggestion to the user verbatim
2. **Diagnose** — run read-only queries to identify what is blocking (e.g., `algo-orders --status pending`, `positions`, `bot grid-orders --status active`)
3. **Present findings** — show the user what was found and which specific items would need to be cancelled/closed/stopped
4. **Wait for explicit confirmation** before executing any remediation
This applies to all error codes whose messages suggest destructive actions, including but not limited to:
- Set-leverage blocked by pending algo orders or active bots
- Account setting changes requiring order/position/strategy cleanup (e.g., error codes 59000, 59002, 59007)
- Margin mode switches requiring position closure
- Any error containing phrases like "cancel", "close", "stop", "transfer … before"
**Rationale:** Error messages list _all possible_ blockers generically — the actual blocker is often just one item (e.g., a single TP/SL order). Blindly following the error text can cause unnecessary position closures or bot shutdowns that the user did not intend.
### Step 3 — Verify after writes
- After `spot place`: run `okx spot orders` to confirm order is live or `okx spot fills` if market order
- After `swap place`: run `okx swap orders` or `okx swap positions` to confirm
- After `swap close`: run `okx swap positions` to confirm position size is 0
- After `futures place`: run `okx futures orders` or `okx futures positions` to confirm
- After `futures close`: run `okx futures positions` to confirm position size is 0
- After spot algo place/trail: run `okx spot algo orders` to confirm algo is active
- After swap algo place/trail: run `okx swap algo orders` to confirm algo is active
- After futures algo place/trail: run `okx futures algo orders` to confirm algo is active
- After cancel: run `okx spot orders` / `okx swap orders` / `okx futures orders` / `okx event orders` to confirm order is gone
- After `event place`: run `okx event orders --status open` to confirm order is pending
- After `event cancel`: run `okx event orders` to confirm order is gone
## Global Notes
- All write commands require valid credentials (OAuth session or API key in `~/.okx/config.toml`)
- Auth method and trading mode are determined in "Credential & Profile Check"; see that section for parameter rules
- `--json` returns the raw OKX API v5 response by default. Add `--env` to wrap the output as `{"env": "<live|demo>", "profile": "<name>", "data": <response>}` — useful when you need to know the active environment and credential profile
- Rate limit: 60 order operations per 2 seconds per UID
- Batch operations (batch cancel, batch amend) are available via MCP tools directly if needed
- Position mode (`net` vs `long_short_mode`) affects whether `--posSide` is required
- **Network errors**: If commands fail with a connection error, prompt user to check VPN: `curl -I https://www.okx.com`
- **Capability discovery**: Run `okx list-tools --json` to get a machine-readable JSON listing of all CLI commands, tool names, and parameters — useful for programmatic enumeration without parsing `--help` text
For MCP tool reference, output conventions, and order amount safety rules, read `{baseDir}/references/templates.md`.