Skip to content

Kraken SDK ​

Complete reference for ctx.kraken — programmatic spot and margin trading on Kraken from worker code.

Kraken REST + WebSocket v2

This SDK wraps the Kraken REST API with optional WebSocket v2 acceleration. WS-first methods fall back to REST automatically; REST-only methods always work.

Setup ​

  1. Add a Kraken trading block to your workspace canvas.
  2. Open the inspector → API Keys → pick a key (Settings → API Keys → Kraken to add new).
  3. Connect the block to your Worker block via an edge.
  4. ctx.kraken is now available.
python
def tick(ctx):
    t = ctx.kraken.get_ticker("XBTUSD")
    ctx.log.info(f"BTC: {t}")

If no Kraken block is connected:

RuntimeError: No trading block connected. Connect a Kraken block to this worker.

Pairs ​

Kraken uses its own pair codes — sometimes the same as the common ticker, sometimes prefixed with X/Z (asset class). Examples:

CommonKraken pair
BTC/USDXBTUSD
ETH/USDETHUSD
BTC/EURXBTEUR
SOL/USDSOLUSD
Margin BTC/USDXBT/USD

Use get_asset_pairs to discover the canonical pair name for any market, plus its tick size, lot size, and trading status.

USD vs ZUSD

Kraken's "Z" prefix marks fiat assets (ZUSD, ZEUR). For account-level methods (get_trade_balance, get_ledgers) you typically pass ZUSD; for trading you use plain USD-suffix pair codes.

Market Data ​

get_ticker ​

Latest ticker for a pair.

python
ctx.kraken.get_ticker(pair: str = "XBTUSD") -> dict

Returns: {"XXBTZUSD": {"a": [ask, w_lot, lot], "b": [bid, w_lot, lot], "c": [last_price, last_lot], "v": [vol_today, vol_24h], "p": [vwap_today, vwap_24h], "t": [trades_today, trades_24h], "l": [low_today, low_24h], "h": [high_today, high_24h], "o": open_today}}

WebSocket cache

PRO/MAX plans return cached ticker data at 0ms latency from the live WS stream — no REST call.

get_orderbook ​

Order book depth.

python
ctx.kraken.get_orderbook(pair: str = "XBTUSD") -> dict

get_ohlc ​

OHLCV candles.

python
ctx.kraken.get_ohlc(pair: str = "XBTUSD", interval: int = 1) -> dict
interval (minutes)Description
1, 5, 15, 30Intra-day
60, 240Hourly / 4h
1440Daily
10080, 21600Weekly / 15-day

get_recent_trades ​

Recent public trades for a pair.

python
ctx.kraken.get_recent_trades(pair: str = "XBTUSD", since: int = None) -> dict

get_spread ​

Recent bid/ask spreads — useful for liquidity profiling.

python
ctx.kraken.get_spread(pair: str = "XBTUSD", since: int = None) -> dict

get_asset_pairs ​

Tradable pair info: pair_decimals, lot_decimals, tick_size, ordermin, costmin, status.

python
ctx.kraken.get_asset_pairs(pair: str = None) -> dict

Adapter caches this after first call — pair metadata rarely changes.

get_trades ​

Get recent trades from the WebSocket stream (PRO/MAX only).

python
ctx.kraken.get_trades(pair: str = "BTC/USD") -> dict

get_system_status ​

Kraken-wide trading status.

python
ctx.kraken.get_system_status() -> dict
# Returns: {"status": "online" | "maintenance" | "cancel_only" | "post_only", "timestamp": ...}
python
def tick(ctx):
    s = ctx.kraken.get_system_status()
    if s.get("status") != "online":
        ctx.log.warn(f"Kraken {s.get('status')} — pausing")
        return
    # ... trade

Account & Wallet ​

get_balance ​

Account balance per currency.

python
ctx.kraken.get_balance() -> dict
# {"ZUSD": "1234.56", "XXBT": "0.5", ...}

WebSocket cache

PRO/MAX: cached from private WS at 0ms.

get_trade_balance ​

Margin info: equity, P&L, margin, free margin, margin level.

python
ctx.kraken.get_trade_balance(asset: str = "ZUSD") -> dict

Returns: {"eb", "tb", "m", "n", "c", "v", "e", "mf", "ml"} (equity balance, trade balance, margin, unrealized P&L, cost basis, valuation, equity, free margin, margin level).

get_positions ​

Open margin positions.

python
ctx.kraken.get_positions() -> dict

WebSocket cache

PRO/MAX: cached at 0ms.

get_ledgers ​

Account ledger — every deposit, withdrawal, trade, fee, transfer, settlement.

python
ctx.kraken.get_ledgers(
    asset: str = None,
    ledger_type: str = "all",     # "all" | "deposit" | "withdrawal" | "trade" | "margin"
    start: int = None,
    end: int = None,
) -> dict

Orders ​

place_order ​

Place an order. Supports market, limit, stop-loss, take-profit, and stop-loss-limit.

python
ctx.kraken.place_order(
    pair: str,
    side: str,                  # "buy" | "sell"
    volume: float,
    ordertype: str = "market",  # "market" | "limit" | "stop-loss" | "take-profit" | "stop-loss-limit" | …
    price: float = None,
    leverage: float = None,     # None = spot; 2-5 for margin
    reduce_only: bool = False,
    time_in_force: str = None,  # "GTC" | "IOC" | "GTD"
    post_only: bool = False,
    cl_ord_id: str = None,
) -> dict
python
# Spot market buy
r = ctx.kraken.place_order("XBTUSD", "buy", 0.001, "market")

# 3x margin long
r = ctx.kraken.place_order("XBTUSD", "buy", 0.01, "limit",
                            price=65000, leverage=3)

WS-accelerated

In Server mode, orders route through Kraken's V2 WebSocket for ~10× faster acks than REST.

edit_order ​

Modify an unfilled order (volume / price). Keeps queue priority on the original timestamp.

python
ctx.kraken.edit_order(
    order_id: str,
    pair: str,
    volume: float = None,
    price: float = None,
    post_only: bool = None,
) -> dict

cancel_order ​

Cancel a single order by txid.

python
ctx.kraken.cancel_order(order_id: str) -> dict

cancel_all_orders ​

Cancel ALL open orders (account-wide). Kill switch.

python
ctx.kraken.cancel_all_orders() -> dict

batch_add ​

Place up to 15 orders atomically.

python
ctx.kraken.batch_add(orders: list, pair: str, validate: bool = False) -> dict
python
ctx.kraken.batch_add(
    pair="XBTUSD",
    orders=[
        {"ordertype": "limit", "type": "buy",  "volume": "0.001", "price": "60000"},
        {"ordertype": "limit", "type": "buy",  "volume": "0.001", "price": "59000"},
        {"ordertype": "limit", "type": "buy",  "volume": "0.001", "price": "58000"},
    ],
)

batch_cancel ​

Cancel multiple orders by txid.

python
ctx.kraken.batch_cancel(order_ids: list) -> dict

get_orders ​

Active (open) orders.

python
ctx.kraken.get_orders() -> dict

WebSocket cache

PRO/MAX: cached at 0ms.

query_orders ​

Detail of one or more specific orders by txid.

python
ctx.kraken.query_orders(txids, trades: bool = False) -> dict
python
detail = ctx.kraken.query_orders("OQCLML-BW3P3-BUCMWZ", trades=True)

get_closed_orders ​

Closed (filled / cancelled / expired) orders.

python
ctx.kraken.get_closed_orders() -> dict

get_trades_history ​

Trade fills with fees (the actual transactions, not just orders).

python
ctx.kraken.get_trades_history(
    trade_type: str = "all",       # "all" | "any position" | "closed position" | "closing position" | "no position"
    start: int = None,
    end: int = None,
) -> dict

Common Patterns ​

Error handling ​

python
def tick(ctx):
    try:
        balance = ctx.kraken.get_balance()
    except Exception as e:
        ctx.log.error(f"Kraken unreachable: {e}")
        return

KrakenAPIError (extends ExchangeAPIError) wraps the array of strings Kraken returns in error[]. Network failures raise httpx.HTTPStatusError.

Cloud-Run proxy ​

PRO+ workers route Kraken traffic through a Cloud Run proxy with rotating exit IPs. Transparent — no code changes.

WebSocket-first ​

Almost every method has a WebSocket fast-path on PRO+:

MethodWS pathREST fallback
get_ticker, get_orderbook, get_tradespublic stream cacheyes
get_balance, get_positions, get_ordersprivate stream cacheyes
place_order, cancel_order, edit_orderWS v2 add/cancel/amendyes
cancel_all_orders, batch_add, batch_cancelWS v2 batch opsyes (Phase 5)

The adapter probes _ws_client per call — when WS is connected and authenticated, it routes through; otherwise REST.

System-status guard ​

Kraken regularly enters cancel_only or post_only modes during volatility. Always check before placing market orders:

python
def tick(ctx):
    if ctx.kraken.get_system_status().get("status") != "online":
        return
    # safe to trade

Recipes ​

DCA on hourly close (with status guard) ​

python
def setup(ctx):
    ctx.state.set("last_buy_ts", 0)

def tick(ctx):
    import time
    now = int(time.time())
    if now - ctx.state.get("last_buy_ts", 0) < 3600:
        return

    if ctx.kraken.get_system_status().get("status") != "online":
        ctx.log.warn("Kraken not online, deferring buy")
        return

    px = float(ctx.kraken.get_ticker("XBTUSD")["XXBTZUSD"]["c"][0])
    qty = round(50 / px, 5)  # $50 worth

    r = ctx.kraken.place_order("XBTUSD", "buy", qty, "market")
    ctx.state.set("last_buy_ts", now)
    ctx.log.info(f"DCA: {qty} BTC @ {px} → {r}")

Layered grid with batch placement ​

python
def setup(ctx):
    # Always cancel any leftovers from a previous run
    ctx.kraken.cancel_all_orders()

    px = float(ctx.kraken.get_ticker("XBTUSD")["XXBTZUSD"]["c"][0])
    step = px * 0.005

    orders = []
    for i in range(1, 6):
        orders.append({
            "ordertype": "limit", "type": "buy",
            "volume": "0.001",
            "price": str(round(px - i * step, 1)),
        })
        orders.append({
            "ordertype": "limit", "type": "sell",
            "volume": "0.001",
            "price": str(round(px + i * step, 1)),
        })
    ctx.kraken.batch_add(orders, pair="XBTUSD")
    ctx.state.set("grid_centre", px)
    ctx.log.info(f"Grid placed around ${px:.0f}")

Spread-aware market making ​

python
def tick(ctx):
    spreads = ctx.kraken.get_spread("XBTUSD")["XXBTZUSD"]
    if not spreads:
        return
    bid, ask, _ = spreads[-1]   # last record: [bid, ask, ts]
    spread_bps = (float(ask) - float(bid)) / float(bid) * 10000

    if spread_bps > 5:
        ctx.log.info(f"Spread {spread_bps:.1f} bps > target — quoting inside")
        # ... place limit orders inside the spread
    else:
        ctx.log.info(f"Spread tight ({spread_bps:.1f} bps) — staying out")

Reference ​

Kraken endpointSDK method
GET /0/public/Tickerget_ticker
GET /0/public/Depthget_orderbook
GET /0/public/OHLCget_ohlc
GET /0/public/Tradesget_recent_trades
GET /0/public/Spreadget_spread
GET /0/public/AssetPairsget_asset_pairs
GET /0/public/SystemStatusget_system_status
POST /0/private/Balanceget_balance
POST /0/private/TradeBalanceget_trade_balance
POST /0/private/OpenPositionsget_positions
POST /0/private/Ledgersget_ledgers
POST /0/private/AddOrderplace_order
POST /0/private/EditOrderedit_order
POST /0/private/CancelOrdercancel_order
POST /0/private/CancelAllcancel_all_orders
POST /0/private/AddOrderBatchbatch_add
POST /0/private/CancelOrderBatchbatch_cancel
POST /0/private/OpenOrdersget_orders
POST /0/private/QueryOrdersquery_orders
POST /0/private/ClosedOrdersget_closed_orders
POST /0/private/TradesHistoryget_trades_history

NodeGraph Documentation