> ## Documentation Index
> Fetch the complete documentation index at: https://docs.renesis.fi/llms.txt
> Use this file to discover all available pages before exploring further.

# Trading on Kraken

> End-to-end guide for spot + futures trading on Kraken via OEMS

# Trading on Kraken

Kraken is the only supported exchange that runs **two separate products**
behind a single account: **Kraken Spot** at `api.kraken.com` and
**Kraken Futures** at `futures.kraken.com`. They have separate API key
management, different signing schemes, and different symbol formats.

OEMS hides most of this. You register one exchange account (one
`exchange_account_id`), provide one credential pair for spot and an
optional second pair for futures, and OEMS routes every call to the
right product behind the scenes.

This guide walks through the full flow.

***

## 1. Set up your Kraken API keys

You'll need two API keys, generated independently. Create both in
**Kraken Pro** (web UI), one in the Spot area and one in the Futures
area.

### Spot key (api.kraken.com)

In **Kraken Pro → Settings → API → Manage API Keys**, generate a key
with these permissions:

* ✅ **Query Funds** (required for balance / position polling)
* ✅ **Query Open Orders & Trades**
* ✅ **Query Closed Orders & Trades**
* ✅ **Query Ledger Entries**
* ✅ **Create & Modify Orders** (for spot order placement)
* ✅ **Cancel/Close Orders**
* ❌ **Withdraw Funds**, DO NOT enable
* ❌ **Deposit Funds**, not needed for trading

**Set Nonce Window = 10000 ms.** This absorbs cross-process nonce
drift between OEMS, the polling jobs, and any other services sharing
the key. The default 5000 ms is fine for a single-process integration
but tight for ours.

### Futures key (futures.kraken.com)

Open **futures.kraken.com → Settings → API Keys**. Generate a separate
key with:

* ✅ **Read** (account / positions / orders)
* ✅ **Trade** (place / cancel orders)
* ❌ **Withdraw**, DO NOT enable

Kraken Futures' UI does not expose a per-key nonce window setting.
That's fine, OEMS uses microsecond nonces and few processes hit the
futures key, so collisions are very unlikely.

***

## 2. Register the account in OEMS

You can configure the keys at registration or add them later.

### Option A, at registration time

```bash theme={null}
curl -X POST https://api.renesis.fi/delegation/register-exchange-account \
  -H "X-API-Key: $API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "exchange_account_id": "exchange_my_kraken",
    "exchange": "kraken",
    "params": {
      "apiKey": "<spot-api-key>",
      "secret": "<spot-secret>",
      "futuresApiKey": "<futures-api-key>",
      "futuresSecret": "<futures-secret>"
    }
  }'
```

Either credential pair can be omitted. Spot-only or futures-only are
both valid configurations:

* **Spot only**: Trading futures pairs returns
  `PERMISSION_DENIED: futures key not configured`.
* **Futures only**: Trading spot pairs returns the equivalent.

### Option B, add the futures key later

If the account already exists with only the spot pair, send a `PUT` to
the credentials endpoint:

```bash theme={null}
curl -X PUT https://api.renesis.fi/delegation/exchange-account/credentials \
  -H "X-API-Key: $API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "exchange_account_id": "exchange_my_kraken",
    "params": {
      "futuresApiKey": "<futures-api-key>",
      "futuresSecret": "<futures-secret>"
    }
  }'
```

Same path can be used to **rotate** keys (overwrite) or **clear** them
(send `""` or `null` for the value).

Behind the scenes:

* Each value is encrypted via the same `SECRET_KEY`-derived AES path
  as the spot keys; it sits in the same `params` JSONB column.
* The cached CCXT instances for the account are invalidated, so the
  next OEMS call re-instantiates with the new credentials.

***

## 3. Symbol conventions

Kraken Spot and Kraken Futures use different symbol formats. OEMS
accepts CCXT's unified format for both.

| Product                     | CCXT symbol                      | Notes                                                                  |
| --------------------------- | -------------------------------- | ---------------------------------------------------------------------- |
| Spot                        | `BTC/USD`, `BTC/EUR`, `BTC/USDT` | Quote is a fiat or stablecoin.                                         |
| Perp (USD-margined)         | `BTC/USD:USD`                    | The `:USD` suffix marks it as a perpetual settled in USD.              |
| Perp (USDT-margined linear) | `BTC/USD:USDT`                   | Less common on Kraken; use `:USD` unless you specifically need linear. |
| Dated futures               | `BTC/USD:USD-260626`             | Expiry suffix `YYMMDD`.                                                |

When you call `/order-execution/execution/order` with `market_type: "swap"` and a
Kraken account, OEMS resolves to `ccxt.krakenfutures` and expects
the symbol to be in CCXT futures format (`BTC/USD:USD`).

***

## 4. Move funds to the right wallet

Kraken Spot and Kraken Futures hold balances in **separate wallets**.
A USDT balance on the spot side can't margin a futures order, you
need to transfer it across.

### Check both wallets

```bash theme={null}
# Spot
curl "https://api.renesis.fi/order-execution/execution/balance?exchange_account_id=exchange_my_kraken&market_type=spot" \
  -H "X-API-Key: $API_KEY"

# Futures
curl "https://api.renesis.fi/order-execution/execution/balance?exchange_account_id=exchange_my_kraken&market_type=swap" \
  -H "X-API-Key: $API_KEY"
```

### Transfer spot → futures

```bash theme={null}
curl -X POST https://api.renesis.fi/order-execution/execution/transfer \
  -H "X-API-Key: $API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "exchange_account_id": "exchange_my_kraken",
    "asset": "USD",
    "amount": 100,
    "from_account": "spot",
    "to_account": "swap"
  }'
```

The `/transfer` endpoint is unified across exchanges that support
inter-wallet moves (Kraken, Binance, OKX, Gate.io). On exchanges with
a single unified wallet (Bybit UTA, Hyperliquid) it returns
`NOT_SUPPORTED`.

***

## 5. Set leverage and margin mode (futures only)

### Set leverage

```bash theme={null}
curl -X POST https://api.renesis.fi/order-execution/execution/leverage \
  -H "X-API-Key: $API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "exchange_account_id": "exchange_my_kraken",
    "symbol": "BTC/USD:USD",
    "leverage": 5,
    "market_type": "swap"
  }'
```

### Set margin mode

Kraken Futures models margin mode as a **per-pair leverage preference**:

* **isolated**: a leverage preference is set for the symbol
* **cross**: no leverage preference is set (default)

```bash theme={null}
# Isolated 5x
curl -X POST https://api.renesis.fi/order-execution/execution/margin-mode \
  -H "X-API-Key: $API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "exchange_account_id": "exchange_my_kraken",
    "symbol": "BTC/USD:USD",
    "margin_mode": "isolated",
    "market_type": "swap"
  }'

# Back to cross
curl -X POST https://api.renesis.fi/order-execution/execution/margin-mode \
  -H "X-API-Key: $API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "exchange_account_id": "exchange_my_kraken",
    "symbol": "BTC/USD:USD",
    "margin_mode": "cross",
    "market_type": "swap"
  }'
```

<Note>
  CCXT's unified `set_margin_mode` is not implemented for `krakenfutures`.
  OEMS works around this via an adapter override that calls Kraken's
  `/derivatives/api/v3/leveragepreferences` endpoint directly. From the
  caller's perspective the unified `/margin-mode` route just works.
</Note>

***

## 6. Place orders

The `/order-execution/execution/order` endpoint takes the same shape regardless
of spot / perp, only `symbol`, `market_type`, and a few perp-specific
flags (`reduce_only`) change between the two.

### Spot market buy

```bash theme={null}
curl -X POST https://api.renesis.fi/order-execution/execution/order \
  -H "X-API-Key: $API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "exchange_account_id": "exchange_my_kraken",
    "symbol": "BTC/USD",
    "side": "buy",
    "order_type": "market",
    "quantity": 0.001,
    "market_type": "spot"
  }'
```

### Perp limit order, post-only

```bash theme={null}
curl -X POST https://api.renesis.fi/order-execution/execution/order \
  -H "X-API-Key: $API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "exchange_account_id": "exchange_my_kraken",
    "symbol": "BTC/USD:USD",
    "side": "buy",
    "order_type": "limit",
    "quantity": 0.0001,
    "price": 70000,
    "post_only": true,
    "market_type": "swap"
  }'
```

### Perp stop-loss with reduce-only

```bash theme={null}
curl -X POST https://api.renesis.fi/order-execution/execution/order \
  -H "X-API-Key: $API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "exchange_account_id": "exchange_my_kraken",
    "symbol": "BTC/USD:USD",
    "side": "sell",
    "order_type": "stop_loss",
    "quantity": 0.0004,
    "stop_price": 70000,
    "reduce_only": true,
    "market_type": "swap"
  }'
```

### Perp take-profit with reduce-only

```bash theme={null}
curl -X POST https://api.renesis.fi/order-execution/execution/order \
  -H "X-API-Key: $API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "exchange_account_id": "exchange_my_kraken",
    "symbol": "BTC/USD:USD",
    "side": "sell",
    "order_type": "take_profit",
    "quantity": 0.0004,
    "stop_price": 95000,
    "reduce_only": true,
    "market_type": "swap"
  }'
```

### Stop-limit (limit triggered at stop price)

```bash theme={null}
curl -X POST https://api.renesis.fi/order-execution/execution/order \
  -H "X-API-Key: $API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "exchange_account_id": "exchange_my_kraken",
    "symbol": "BTC/USD:USD",
    "side": "sell",
    "order_type": "stop_loss_limit",
    "quantity": 0.0004,
    "price": 69000,
    "stop_price": 70000,
    "reduce_only": true,
    "market_type": "swap"
  }'
```

***

## 7. Read positions and close

### Get open positions

```bash theme={null}
curl "https://api.renesis.fi/order-execution/execution/positions?exchange_account_id=exchange_my_kraken&market_type=swap" \
  -H "X-API-Key: $API_KEY"
```

Response:

```json theme={null}
{
  "isError": false,
  "data": {
    "positions": [
      {
        "symbol": "BTC/USD:USD",
        "side": "short",
        "contracts": 0.0004,
        "entry_price": 80826.0,
        "leverage": 5.0,
        "exchange": "krakenfutures",
        "exchange_account_id": "exchange_my_kraken"
      }
    ],
    "count": 1
  }
}
```

### Close a position

OEMS doesn't have a separate "close position" verb, close via a
`reduce_only` market order in the opposite direction:

```bash theme={null}
# Close the SHORT BTC/USD:USD position above
curl -X POST https://api.renesis.fi/order-execution/execution/order \
  -H "X-API-Key: $API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "exchange_account_id": "exchange_my_kraken",
    "symbol": "BTC/USD:USD",
    "side": "buy",
    "order_type": "market",
    "quantity": 0.0004,
    "reduce_only": true,
    "market_type": "swap"
  }'
```

***

## 8. Funding and realized PnL

### Funding rate history

```bash theme={null}
curl "https://api.renesis.fi/order-execution/execution/funding-history?exchange_account_id=exchange_my_kraken&symbol=BTC/USD:USD&limit=10&market_type=swap" \
  -H "X-API-Key: $API_KEY"
```

Kraken Futures publishes funding rates as a schedule (per-rate
history), not as discrete payment events. OEMS sources this from
`fetch_funding_rate_history` and returns the unified payments shape.

### Realized PnL

```bash theme={null}
curl "https://api.renesis.fi/order-execution/execution/realized-pnl?exchange_account_id=exchange_my_kraken&limit=10&market_type=swap" \
  -H "X-API-Key: $API_KEY"
```

Kraken Futures has no "income" endpoint analogous to Binance. OEMS
aggregates realized PnL from `fetch_my_trades`, each trade that
closes (or partially closes) a position carries `realisedPnl` in its
`info` payload. OEMS filters and returns just the PnL events.

***

## 9. Troubleshooting

### `EAPI:Invalid nonce`

The same Kraken key was used by another process in the recent past
with a higher nonce. **Set `Nonce Window = 10000` ms** on the spot
key in Kraken Pro → API → Manage API Keys (per the setup section
above). The futures-side UI doesn't expose this setting; the
microsecond override OEMS applies is normally sufficient there.

### `EGeneral:Permission denied`

The key is valid but lacks a permission for the operation. Most
common: missing **Query Funds** on the spot key. Update permissions in
Kraken Pro and retry. OEMS surfaces this with an explicit
`PERMISSION_DENIED` rather than the generic "wrong key" message.

### `authenticationError` from `krakenfutures`

You're trying to use a **spot** key against the **futures** API.
Spot keys cannot sign futures requests. Configure a separate futures
key per the setup section, then either re-register or use the
`PUT /credentials` endpoint to add it.

### Order rejected with `wouldNotReducePosition`

A reduce-only order's quantity exceeds the open position size, or the
order is in the wrong direction to reduce. Check `/positions` first
and place a smaller / opposite order.

### Spot-purchased BTC shows up under "Staking/Yield Farming"

Kraken auto-allocates spot balances to **Flex Earn** by default in
many regions. This is a Kraken account setting, disable
**Auto-allocate to Earn** in Kraken Pro → Earn → Allocations to keep
new spot purchases in the trading wallet, or un-allocate the existing
balance manually.

***

## Quick reference

| Task                     | Endpoint                                       | `market_type`                                    |
| ------------------------ | ---------------------------------------------- | ------------------------------------------------ |
| Spot balance             | `GET /balance`                                 | `spot`                                           |
| Futures balance          | `GET /balance`                                 | `swap`                                           |
| Place spot order         | `POST /order`                                  | `spot`                                           |
| Place perp order         | `POST /order`                                  | `swap`                                           |
| Set leverage             | `POST /leverage`                               | `swap`                                           |
| Set margin mode          | `POST /margin-mode`                            | `swap`                                           |
| Open positions           | `GET /positions`                               | `swap`                                           |
| Move spot → futures      | `POST /transfer`                               | implicit (driven by `from_account`/`to_account`) |
| Funding rate history     | `GET /funding-history`                         | `swap`                                           |
| Realized PnL             | `GET /realized-pnl`                            | `swap`                                           |
| Add / rotate futures key | `PUT /delegation/exchange-account/credentials` | n/a                                              |
