Skip to content

[OKX] Document EEA endpoint overrides for live and demo accounts #4250

Description

@msnatm-code

Summary

OKX users registered via the EEA (European Economic Area) portal (my.okx.com) are completely unable to use the OKX adapter for both live trading and paper trading. Their API keys are only valid on my.okx.com infrastructure and return error 60032 ("API key doesn't exist") on all global OKX WebSocket endpoints currently hardcoded in NT.


Environment

  • NautilusTrader version: 1.228.0
  • OS: Windows 11
  • Python: 3.12
  • OKX account type: EEA (European Economic Area) — registered via my.okx.com

Reproduction

REST API — works fine ✅

import ccxt
exchange = ccxt.okx({
    'apiKey': '...',
    'secret': '...',
    'password': '...',
    'options': {'defaultType': 'swap'},
    'hostname': 'my.okx.com',  # EEA endpoint
})
print(exchange.fetch_balance())  # Returns correct balance

WebSocket — all global endpoints fail ❌

import websockets, asyncio, json, hmac, hashlib, base64, datetime

async def test(url):
    ts = str(int(datetime.datetime.now(datetime.UTC).timestamp()))
    msg = ts + 'GET' + '/users/self/verify'
    sig = base64.b64encode(hmac.new(secret.encode(), msg.encode(), hashlib.sha256).digest()).decode()
    login = {'op': 'login', 'args': [{'apiKey': key, 'passphrase': passphrase, 'timestamp': ts, 'sign': sig}]}
    async with websockets.connect(url) as ws:
        await ws.send(json.dumps(login))
        print(await asyncio.wait_for(ws.recv(), timeout=10))

asyncio.run(test('wss://ws.okx.com:8443/ws/v5/private'))
asyncio.run(test('wss://wspap.okx.com:8443/ws/v5/private'))  # demo

Output:

wss://ws.okx.com:8443/ws/v5/private     -> {"event":"error","msg":"API key doesn't exist","code":"60032"}
wss://wspap.okx.com:8443/ws/v5/private  -> {"event":"error","msg":"Authentication timed out","code":"60022"}
wss://wsaws.okx.com:8443/ws/v5/private  -> ERROR: [Errno 11001] getaddrinfo failed
wss://wsap.okx.com:8443/ws/v5/private   -> ERROR: [Errno 11001] getaddrinfo failed

The EEA WebSocket endpoint is wss://ws.my.okx.com:8443/ws/v5/private (and wss://wspap.my.okx.com:8443/ws/v5/private for demo).


Root Cause

The OKX adapter hardcodes the global WS base URL. EEA users need *.my.okx.com instead of *.okx.com. There is no configuration option to override the WS endpoint.

OKX maintains a separate infrastructure for EEA users due to EU regulatory requirements. API keys issued on my.okx.com are not portable to the global (okx.com) infrastructure — they return 60032 on any global endpoint.


Proposed Fix

Add a configurable ws_base_url (and optionally rest_base_url) parameter to OKXDataClientConfig and OKXExecClientConfig, defaulting to the current global URLs but allowing EEA users to override:

# Live EEA
OKXDataClientConfig(
    api_key="...",
    api_secret="...",
    passphrase="...",
    base_url_ws="wss://ws.my.okx.com:8443",   # EEA override
    base_url_http="https://www.my.okx.com",    # EEA override
)

# Demo/paper EEA
OKXDataClientConfig(
    base_url_ws="wss://wspap.my.okx.com:8443",
    is_demo=True,
)

Alternatively, adding an is_eea=True flag that automatically selects my.okx.com endpoints would be a cleaner API.


Impact

This blocks all EU/EEA OKX users from using the OKX adapter entirely, for both live trading and paper trading. Given OKX's significant EU user base and regulatory requirements that have been in place since 2023, this likely affects a large portion of European NT users.


References

  • OKX EEA portal: https://my.okx.com
  • OKX API docs (EEA): mentions separate endpoints for EU-regulated accounts
  • Related: OKX enforces separate infrastructure per jurisdiction since EU MiCA regulations

Metadata

Metadata

Assignees

Labels

docsRelating to documentationimprovementImprovement to existing functionality

Type

No type

Projects

Status
Done

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions