Skip to content本文へ移動

Trading API & SDK · Advanced API Patterns · 7/8

Batch Operations & Rate Limits

Rate Limits

Hyperliquid enforces rate limits to ensure fair access. Understanding these is critical for building reliable trading systems. Figures below are as of October 2026 (rate limits).

IP-Based Limits

Address-Based Limits (actions only)

Nonces

Every signed action carries a nonce (the SDK uses the current time in ms). Hyperliquid keeps the 100 highest nonces per signer; a new nonce must be larger than the smallest of them, never reused, and within (now − 2 days, now + 1 day). Two processes sharing one API wallet can collide, so use one API wallet per process (nonces).

Batch Order Placement

Instead of placing orders one at a time, use batch operations (testnet only; these samples place and cancel real orders):

# Place multiple orders in a single request
orders = [
    {
        "coin": "BTC",
        "is_buy": True,
        "sz": 0.01,
        "limit_px": 90000.0,
        "order_type": {"limit": {"tif": "Gtc"}},
        "reduce_only": False,
    },
    {
        "coin": "BTC",
        "is_buy": True,
        "sz": 0.01,
        "limit_px": 89500.0,
        "order_type": {"limit": {"tif": "Gtc"}},
        "reduce_only": False,
    },
]

result = exchange.bulk_orders(orders)

Batch Cancellation

# Cancel multiple orders at once
cancels = [
    {"coin": "BTC", "oid": 12345},
    {"coin": "BTC", "oid": 12346},
    {"coin": "ETH", "oid": 12347},
]

result = exchange.bulk_cancel(cancels)

Cancel-and-Replace Pattern

A common pattern in market making: replace a resting order with a new price or size. Hyperliquid has native modify and batchModify actions, exposed in the SDK as modify_order and bulk_modify_orders_new:

# Modify an existing order in one action
result = exchange.modify_order(
    oid=12345,
    name="BTC",
    is_buy=True,
    sz=0.02,          # New size
    limit_px=90500.0,  # New price
    order_type={"limit": {"tif": "Gtc"}},
)

modify_order is preferred over a separate cancel + place because it is a single signed action: one request, one nonce, and no window in which your own code has cancelled but not yet re-sent. By default the new order is placed only if the cancel succeeds, so if the old order already filled you will not end up with an extra order. In that default mode the replacement must be a non-trigger order that rests on the book: Alo, or a Gtc price that would not match immediately (exchange endpoint).

Error Handling

Always handle API errors gracefully:

try:
    result = exchange.order(name="BTC", is_buy=True, sz=0.01,
                           limit_px=90000.0,
                           order_type={"limit": {"tif": "Gtc"}})

    if result["status"] == "ok":
        statuses = result["response"]["data"]["statuses"]
        for s in statuses:
            if "error" in s:
                print(f"Order rejected: {s['error']}")
            elif "resting" in s:
                print(f"Order placed: oid={s['resting']['oid']}")
            elif "filled" in s:
                print(f"Order filled immediately")
    else:
        print(f"Request failed: {result}")

except Exception as e:
    print(f"API error: {e}")

取引 API と SDK · API の応用パターン · 7/8

まとめて送る操作とレート制限

レート制限

Hyperliquid は、公平に使えるようにレート制限を設けています。安定して動く取引の仕組みを作るには、これを知っておくことが欠かせません。以下の数字は2026年10月時点のものです(レート制限)。

IP ごとの上限

アドレスごとの上限(action のみ)

nonce

署名付きの action には、どれも nonce が付きます(SDK は現在時刻のミリ秒を使います)。Hyperliquid は、署名する鍵ごとに大きいほうから100個の nonce を覚えています。新しい nonce は、そのうち一番小さいものより大きく、使い回しがなく、(現在 − 2日、現在 + 1日)の範囲に収まっている必要があります。2つのプロセスが1つの API wallet を共有すると、nonce がぶつかることがあります。プロセスごとに API wallet を1つずつ用意してください(nonce)。

注文をまとめて出す

注文を1件ずつ出す代わりに、まとめて送る操作を使います(テストネットだけで使ってください。このサンプルは実際に注文を出し、取り消します)。

# Place multiple orders in a single request
orders = [
    {
        "coin": "BTC",
        "is_buy": True,
        "sz": 0.01,
        "limit_px": 90000.0,
        "order_type": {"limit": {"tif": "Gtc"}},
        "reduce_only": False,
    },
    {
        "coin": "BTC",
        "is_buy": True,
        "sz": 0.01,
        "limit_px": 89500.0,
        "order_type": {"limit": {"tif": "Gtc"}},
        "reduce_only": False,
    },
]

result = exchange.bulk_orders(orders)

まとめて取り消す

# Cancel multiple orders at once
cancels = [
    {"coin": "BTC", "oid": 12345},
    {"coin": "BTC", "oid": 12346},
    {"coin": "ETH", "oid": 12347},
]

result = exchange.bulk_cancel(cancels)

取り消して出し直す

マーケットメイクでよく使う形です。板に置いてある注文を、新しい価格や数量のものに置き換えます。Hyperliquid には modify と batchModify という action がもともとあります。SDK では modify_order と bulk_modify_orders_new として使えます。

# Modify an existing order in one action
result = exchange.modify_order(
    oid=12345,
    name="BTC",
    is_buy=True,
    sz=0.02,          # New size
    limit_px=90500.0,  # New price
    order_type={"limit": {"tif": "Gtc"}},
)

取り消しと発注を別々に送るより、modify_order のほうが向いています。署名付きの action が1つで済むからです。リクエストも nonce も1つで、自分のコードが取り消したのにまだ出し直していない、という隙間もできません。初期設定では、取り消しが成功したときだけ新しい注文を出します。そのため、古い注文がすでに約定していても、余分な注文が残ることはありません。この初期設定では、置き換える注文はトリガー注文ではなく、板に置かれるものでなければなりません。Alo か、すぐには約定しない価格の Gtc です(exchange エンドポイント)。

エラーの処理

API のエラーは、必ず適切に処理します。

try:
    result = exchange.order(name="BTC", is_buy=True, sz=0.01,
                           limit_px=90000.0,
                           order_type={"limit": {"tif": "Gtc"}})

    if result["status"] == "ok":
        statuses = result["response"]["data"]["statuses"]
        for s in statuses:
            if "error" in s:
                print(f"Order rejected: {s['error']}")
            elif "resting" in s:
                print(f"Order placed: oid={s['resting']['oid']}")
            elif "filled" in s:
                print(f"Order filled immediately")
    else:
        print(f"Request failed: {result}")

except Exception as e:
    print(f"API error: {e}")