Skip to content

OKX SDK ​

Complete reference for ctx.okx — programmatic trading on OKX from worker code.

OKX V5 API

This SDK wraps the OKX V5 unified API for spot, perpetual swap, futures, and options. Live and demo environments supported.

Setup ​

  1. Add an OKX trading block to your workspace canvas.
  2. Open the inspector → API Keys → pick a key (Settings → API Keys → OKX to add new). OKX requires api_key + api_secret + passphrase.
  3. Connect the block to your Worker block via an edge.
  4. ctx.okx is now available.
python
def tick(ctx):
    t = ctx.okx.get_ticker("BTC-USDT-SWAP")
    ctx.log.info(f"BTC perp: {t['data'][0]['last']}")

If no OKX block is connected:

RuntimeError: No trading block connected. Connect an OKX block to this worker.

Instrument Naming & Modes ​

OKX uses inst_id strings shaped by category:

PatternExampleMeaning
{COIN}-{COIN}BTC-USDTSpot pair
{COIN}-{COIN}-SWAPBTC-USDT-SWAPPerpetual swap
{COIN}-{COIN}-{EXPIRY}BTC-USDT-251227Dated future
{COIN}-USD-{EXP}-{STRIKE}-{C|P}BTC-USD-251227-100000-COption

inst_type parameter (where applicable):

ValueMeaning
SPOTSpot
MARGINMargin
SWAPPerpetual swap
FUTURESDated futures
OPTIONOptions

Account modes (api_mode on key):

ModeEndpointNotes
livewww.okx.comReal funds
demowww.okx.com + x-simulated-trading: 1Paper-trading, real prices

There's no testnet — OKX uses a header flag for demo mode.

Market Data ​

get_ticker ​

Latest ticker.

python
ctx.okx.get_ticker(inst_id: str = "BTC-USDT") -> dict

Returns: {"code", "data": [{"instId", "last", "lastSz", "askPx", "bidPx", "open24h", "high24h", "low24h", "volCcy24h", "vol24h", …}]}

python
t = ctx.okx.get_ticker("BTC-USDT")
last = float(t["data"][0]["last"])

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.okx.get_orderbook(inst_id: str = "BTC-USDT") -> dict

Returns: {"data": [{"asks": [[price, size, ...]], "bids": [[price, size, ...]], "ts"}]}

get_klines ​

Candlestick OHLCV.

python
ctx.okx.get_klines(inst_id: str = "BTC-USDT", bar: str = "1H", limit: int = 100) -> dict

bar values: "1m" "3m" "5m" "15m" "30m" "1H" "2H" "4H" "6H" "12H" "1D" "1W" "1M".

Returns: {"data": [[ts, open, high, low, close, volume, volCcy, volCcyQuote, confirm]]}.

get_instruments ​

All instruments for a category.

python
ctx.okx.get_instruments(inst_type: str = "SWAP") -> dict

get_funding_rate ​

Current funding rate for a perpetual.

python
ctx.okx.get_funding_rate(inst_id: str = "BTC-USDT-SWAP") -> dict

get_mark_price ​

Mark price for derivatives.

python
ctx.okx.get_mark_price(inst_type: str = "SWAP", inst_id: str = None) -> dict
python
mp = ctx.okx.get_mark_price(inst_id="BTC-USDT-SWAP")
mark = float(mp["data"][0]["markPx"])

get_open_interest ​

Open interest for derivatives.

python
ctx.okx.get_open_interest(inst_type: str = "SWAP", inst_id: str = None) -> dict

Account & Positions ​

get_balance ​

Account balance for one or all currencies.

python
ctx.okx.get_balance(ccy: str = None) -> dict

WebSocket cache

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

get_positions ​

Open positions.

python
ctx.okx.get_positions(inst_type: str = None) -> dict

WebSocket cache

PRO/MAX: cached at 0ms.

get_position_history ​

Closed position history with entry / exit and realised P&L.

python
ctx.okx.get_position_history(
    inst_type: str = None,
    inst_id: str = None,
    mgn_mode: str = None,        # "isolated" | "cross"
    type: str = None,            # "1" partial close / "2" full close / "3" liquidation
                                 # "4" auto-deleveraging / "5" settlement
    limit: int = 100,
) -> dict

get_account_config ​

Account-level config: position mode, margin mode, account level (Lv1-Lv4).

python
ctx.okx.get_account_config() -> dict

set_position_mode ​

Switch derivatives mode for the whole account.

python
ctx.okx.set_position_mode(pos_mode: str = "long_short_mode") -> dict
# pos_mode: "long_short_mode" (hedge) | "net_mode" (one-way)

set_leverage ​

Set leverage on an instrument.

python
ctx.okx.set_leverage(inst_id: str, lever: str, mgn_mode: str = "cross") -> dict
# mgn_mode: "cross" | "isolated"

get_max_size ​

Max buy / sell size given current leverage + balance.

python
ctx.okx.get_max_size(
    inst_id: str,
    td_mode: str = "cross",
    ccy: str = None,
    leverage = None,
) -> dict
python
m = ctx.okx.get_max_size("BTC-USDT-SWAP", td_mode="cross")
ctx.log.info(f"Max long: {m['data'][0]['maxBuy']}, max short: {m['data'][0]['maxSell']}")

Orders ​

place_order ​

Place a single order. Auto-routes spot / margin / swap / futures by inst_id.

python
ctx.okx.place_order(
    inst_id: str,
    side: str,                # "buy" | "sell"
    sz: str,                  # contract count for derivatives, base qty for spot
    ord_type: str = "market", # "market" | "limit" | "post_only" | "fok" | "ioc"
    px: str = None,           # required for non-market types
    td_mode: str = "cross",   # "cash" (spot) | "cross" | "isolated"
    pos_side: str = None,     # "long" | "short" (hedge mode only)
    reduce_only: bool = False,
) -> dict
python
# Market buy 0.01 BTC perp at cross margin
r = ctx.okx.place_order("BTC-USDT-SWAP", "buy", "1", "market")  # 1 contract = 0.01 BTC

# Spot limit
r = ctx.okx.place_order("BTC-USDT", "buy", "0.001", "limit", px="65000", td_mode="cash")

cancel_order ​

Cancel a single order.

python
ctx.okx.cancel_order(inst_id: str, order_id: str = None, cl_ord_id: str = None) -> dict

cancel_all_orders ​

Cancel ALL pending orders, optionally filtered.

python
ctx.okx.cancel_all_orders(inst_type: str = None, inst_id: str = None) -> dict
python
# Kill switch — cancel everything
ctx.okx.cancel_all_orders()

amend_order ​

Modify qty / price of an unfilled order.

python
ctx.okx.amend_order(
    inst_id: str,
    order_id: str = None,
    cl_ord_id: str = None,
    new_sz: str = None,
    new_px: str = None,
) -> dict

get_orders ​

Active (unfilled) orders.

python
ctx.okx.get_orders(inst_type: str = None) -> dict

WebSocket cache

PRO/MAX: cached at 0ms.

get_order_history ​

Filled / cancelled order history (last 7 days).

python
ctx.okx.get_order_history(
    inst_type: str = "SWAP",
    inst_id: str = None,
    state: str = None,           # "canceled" | "filled" | "partially_filled"
    limit: int = 100,
) -> dict

get_fills ​

Trade fills with fees.

python
ctx.okx.get_fills(inst_type: str = None, inst_id: str = None) -> dict

close_position ​

Close a position immediately.

python
ctx.okx.close_position(inst_id: str, mgn_mode: str = "cross") -> dict

Algo Orders ​

OKX's algo orders are SDK-level smart orders — placed and managed independently of regular orders. Use them for TP/SL pairs, conditional triggers, trailing stops, iceberg, and TWAP.

place_algo_order ​

Universal algo-order entry point.

python
ctx.okx.place_algo_order(
    inst_id: str,
    side: str,                       # "buy" | "sell"
    sz,
    ord_type: str = "conditional",
    td_mode: str = "cross",
    # ── For "conditional" / "oco" (TP+SL paired) ──
    tp_trigger_px = None,            # take-profit trigger
    tp_ord_px = None,                # take-profit limit price (-1 = market)
    sl_trigger_px = None,            # stop-loss trigger
    sl_ord_px = None,                # stop-loss limit price (-1 = market)
    # ── For "trigger" (price → market/limit) ──
    trigger_px = None,
    order_px = None,                 # -1 = market
    # ── Common ──
    algo_cl_ord_id: str = None,
    reduce_only: bool = False,
) -> dict
ord_typeUse for
"conditional"One-way TP or SL
"oco"TP and SL paired (one cancels the other)
"trigger"Price trigger then market or limit
"move_order_stop"Trailing stop
"iceberg"Iceberg (visible chunks of a large order)
"twap"TWAP (time-weighted average price)
python
# OCO: take 5% profit OR stop-loss at -2%
entry = 65000
ctx.okx.place_algo_order(
    inst_id="BTC-USDT-SWAP",
    side="sell", sz="1",
    ord_type="oco",
    tp_trigger_px=str(entry * 1.05), tp_ord_px="-1",  # market take-profit
    sl_trigger_px=str(entry * 0.98), sl_ord_px="-1",  # market stop-loss
    reduce_only=True,
)

cancel_algo_order ​

Cancel an algo order by algoId.

python
ctx.okx.cancel_algo_order(algo_id: str, inst_id: str) -> dict

get_algo_orders ​

List active algo orders.

python
ctx.okx.get_algo_orders(
    ord_type: str = "conditional",
    inst_type: str = None,
    inst_id: str = None,
    limit: int = 100,
) -> dict

Common Patterns ​

Demo mode during development ​

Set the API-key mode to demo in Settings → API Keys → OKX. All worker calls auto-add the x-simulated-trading: 1 header.

Error handling ​

python
def tick(ctx):
    try:
        positions = ctx.okx.get_positions()
    except Exception as e:
        ctx.log.error(f"OKX unreachable: {e}")
        return

OkxAPIError (extends ExchangeAPIError) is raised for API errors. Network failures raise httpx.HTTPStatusError.

Cloud-Run proxy ​

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

WebSocket caching ​

PRO+ subscribes to public + private streams in the background. get_ticker, get_orderbook, get_balance, get_positions, get_orders auto-prefer the cache when fresh.

Recipes ​

OCO entry (TP + SL paired) ​

python
def tick(ctx):
    pos = ctx.okx.get_positions(inst_type="SWAP")
    if any(p["instId"] == "BTC-USDT-SWAP" and float(p["pos"]) != 0
           for p in pos.get("data", [])):
        return  # already in a position

    px = float(ctx.okx.get_ticker("BTC-USDT-SWAP")["data"][0]["last"])

    # Limit-buy 1 contract
    ctx.okx.place_order("BTC-USDT-SWAP", "buy", "1", "limit", px=str(round(px - 50)))

    # Pre-stage OCO: TP +3%, SL -1.5%
    ctx.okx.place_algo_order(
        inst_id="BTC-USDT-SWAP",
        side="sell", sz="1",
        ord_type="oco",
        tp_trigger_px=str(round(px * 1.03, 1)), tp_ord_px="-1",
        sl_trigger_px=str(round(px * 0.985, 1)), sl_ord_px="-1",
        reduce_only=True,
    )
    ctx.log.info(f"Entry placed at {px:.2f} with OCO exits")

Trailing stop after 2% in profit ​

python
def tick(ctx):
    pos = ctx.okx.get_positions(inst_type="SWAP")
    long = next((p for p in pos.get("data", [])
                 if p["instId"] == "BTC-USDT-SWAP" and float(p["pos"]) > 0), None)
    if not long:
        return

    entry = float(long["avgPx"])
    mark = float(ctx.okx.get_mark_price(inst_id="BTC-USDT-SWAP")["data"][0]["markPx"])

    # Activate 1% trailing stop once we're +2%
    if mark > entry * 1.02:
        existing = ctx.okx.get_algo_orders(ord_type="move_order_stop",
                                            inst_id="BTC-USDT-SWAP")
        if existing.get("data"):
            return  # already active
        ctx.okx.place_algo_order(
            inst_id="BTC-USDT-SWAP",
            side="sell", sz=long["pos"],
            ord_type="move_order_stop",
            order_px="-1",                     # -1 = market once triggered
            reduce_only=True,
        )
        ctx.log.info("Trailing stop activated")

Cross-instrument funding-rate arb scanner ​

python
def tick(ctx):
    swaps = ctx.okx.get_instruments(inst_type="SWAP")["data"]
    rates = []
    for s in swaps[:20]:
        if not s["instId"].endswith("-USDT-SWAP"):
            continue
        try:
            r = ctx.okx.get_funding_rate(s["instId"])
            rates.append((s["instId"], float(r["data"][0]["fundingRate"])))
        except Exception:
            pass
    rates.sort(key=lambda x: abs(x[1]), reverse=True)

    for inst, rate in rates[:5]:
        ctx.log.info(f"{inst:25} funding={rate*100:+.4f}%")

Reference ​

OKX V5 endpointSDK method
GET /api/v5/market/tickerget_ticker
GET /api/v5/market/booksget_orderbook
GET /api/v5/market/candlesget_klines
GET /api/v5/public/instrumentsget_instruments
GET /api/v5/public/funding-rateget_funding_rate
GET /api/v5/public/mark-priceget_mark_price
GET /api/v5/public/open-interestget_open_interest
GET /api/v5/account/balanceget_balance
GET /api/v5/account/positionsget_positions
GET /api/v5/account/positions-historyget_position_history
GET /api/v5/account/configget_account_config
POST /api/v5/account/set-position-modeset_position_mode
POST /api/v5/account/set-leverageset_leverage
GET /api/v5/account/max-sizeget_max_size
POST /api/v5/trade/orderplace_order
POST /api/v5/trade/cancel-ordercancel_order
POST /api/v5/trade/cancel-batch-orderscancel_all_orders
POST /api/v5/trade/amend-orderamend_order
GET /api/v5/trade/orders-pendingget_orders
GET /api/v5/trade/orders-historyget_order_history
GET /api/v5/trade/fillsget_fills
POST /api/v5/trade/close-positionclose_position
POST /api/v5/trade/order-algoplace_algo_order
POST /api/v5/trade/cancel-algoscancel_algo_order
GET /api/v5/trade/orders-algo-pendingget_algo_orders

NodeGraph Documentation