Skip to content

[Kraken] WebSocket v2 subscriptions silently fail for XDG/USD (Dogecoin) — stale wsname in REST AssetPairs #3960

@mcgrj

Description

@mcgrj

Expected behavior

All Kraken Spot instruments should receive live WebSocket v2 data after a successful subscription. Specifically, subscribing to XDG/USD.KRAKEN for quote ticks, trade ticks, and bars via the adapter should result in data flowing over the WS v2 ticker and trade channels.

Actual behavior

Zero WebSocket data is received for any XDG/* instrument. The adapter calls subscribe_quotes / subscribe_trades without error at the Python layer, but the underlying WS v2 subscription silently fails — no quote ticks, no trade ticks, no bars arrive.

Root cause

The Nautilus Kraken adapter uses the wsname field from Kraken's REST /0/public/AssetPairs endpoint to construct both the Nautilus InstrumentId and the symbol sent in WS v2 subscribe messages. For Dogecoin, REST reports:

"wsname": "XDG/USD"

But Kraken WS v2 rejects this symbol at subscription time:

{"error": "Currency pair not supported XDG/USD", "success": false, "method": "subscribe"}

WS v2 requires "DOGE/USD". The rejection response is not surfaced to the caller — the adapter proceeds as if subscribed, but no data ever arrives.

The fix path is parse_spot_instrument (reads REST wsname) → normalize_spot_symbol (applies known renames) → to_ws_v2_symbol (used in all WS subscribe calls). Since normalize_spot_symbol has no XDG → DOGE rule, the stale value reaches the wire.

This is the same class of bug as #3509 (XBT → BTC), where Kraken's REST wsname does not match their WS v2 accepted symbol.

Reproduction

Step 1 — confirm REST reports XDG:

curl -s 'https://api.kraken.com/0/public/AssetPairs?pair=XDGUSD' | \
  python3 -c "import sys,json; p=json.load(sys.stdin)['result']['XDGUSD']; print('wsname:', p['wsname'])"
# wsname: XDG/USD

Step 2 — confirm WS v2 rejects XDG/USD and accepts DOGE/USD:

import asyncio, json, websockets

async def probe(symbol):
    async with websockets.connect("wss://ws.kraken.com/v2") as ws:
        await ws.send(json.dumps({
            "method": "subscribe",
            "params": {"channel": "ticker", "symbol": [symbol], "event_trigger": "bbo"}
        }))
        for _ in range(3):
            msg = json.loads(await asyncio.wait_for(ws.recv(), timeout=3))
            if "success" in msg:
                print(f"{symbol}: success={msg['success']}  error={msg.get('error', '')}")
                return

asyncio.run(probe("XDG/USD"))   # success=False  error=Currency pair not supported XDG/USD
asyncio.run(probe("DOGE/USD"))  # success=True

Affected pairs

All XDG/* pairs: XDG/USD, XDG/EUR, XDG/BTC, XDG/AUD, XDG/CAD, XDG/GBP, XDG/USDC, XDG/USDT, XDG/USD:BTNL.

Other X-prefixed symbols (XLM, XRP, XMR, XTZ) are not affected — WS v2 accepts them unchanged.

Proposed fix

Extend normalize_spot_symbol in crates/adapters/kraken/src/common/parse.rs to map XDG → DOGE, mirroring the existing XBT → BTC logic. Refactoring to a static rename table makes future additions a one-liner.

Specifications

  • nautilus_trader: 1.225.0 (confirmed reproducible; same code path in 1.226.0)
  • Python: 3.12
  • OS: Linux x86_64

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions