本文へ移動
レビューを依頼

取引 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}")