How to build a Hyperliquid trading bot in Python
The bot uses Hyperliquid's official Python SDK and trades a paper box: your own simulated account with $10,000 and live prices, reached through the SDK's base_url. No key, no deposit, no real funds.
- BOX
- curl -X POST https://api.ironflow.sh/v1/ironbox no key
- SDK
- pip install hyperliquid-python-sdk
- MCP
- create_ironbox on https://mcp.ironflow.sh/mcp
Free key14 days of history at 60 requests a minute. Without a key, the API reaches 24 hours back.
By requesting a key you agree to the Terms and API terms; see the Privacy Policy. We may email you when your key keeps hitting its limits; you can opt out at any time.
The short version#
- SDK: hyperliquid-python-sdk, the one Hyperliquid maintains. Tested here with 0.24.0.
- Paper box: one
POST, no key, no deposit. Orders fill against live Hyperliquid books in the simulator and never reach Hyperliquid. - One flag:
Info(base_url, skip_ws=True). A box has no WebSocket.
1. A paper account#
curl -X POST https://api.ironflow.sh/v1/ironbox{
"id": "ibx_...",
"state": "running",
"mode": "paper",
"trial": true,
"base_url": "https://api.ironflow.sh/box/ibxs_...",
"starting_balance_usd": 10000
}- No key gives a trial box: removed after 24 hours, or after 2 hours with no requests. A free key keeps it.
- Keep
base_urlsecret. Anyone with it can trade the box, and only the box. - Main perps only, cross margin, 0.045% taker and 0.015% maker fees, hourly funding. The full rules are in the paper trading guide.
2. The bot#
Long 0.001 BTC when the last hourly close is above the 20-hour average, short when it is below. It checks every 5 minutes and trades only when it has to flip.
pip install hyperliquid-python-sdk requests"""Hyperliquid trend bot: long BTC above its 20-hour average, short below."""
import hashlib
import os
import time
import requests
from eth_account import Account
from hyperliquid.exchange import Exchange
from hyperliquid.info import Info
BASE_URL = os.environ["BASE_URL"] # your paper box: https://api.ironflow.sh/box/ibxs_...
COIN, SIZE, HOURS = "BTC", 0.001, 20
# A throwaway wallet, the same on every run. Never a funded key.
wallet = Account.from_key(hashlib.sha256(BASE_URL.encode()).digest())
ACCOUNT = wallet.address
info = Info(BASE_URL, skip_ws=True) # a paper box has no /ws
exchange = Exchange(wallet, base_url=BASE_URL, account_address=ACCOUNT)
def closes():
r = requests.get(
"https://api.ironflow.sh/v1/candles",
params={"market": f"{COIN}-PERP", "interval": "1h", "from": "-24h"},
timeout=30,
)
r.raise_for_status()
return [float(c["close"]) for c in r.json()["data"]][-HOURS:]
def position():
for p in info.user_state(ACCOUNT)["assetPositions"]:
if p["position"]["coin"] == COIN:
return float(p["position"]["szi"])
return 0.0
def step():
c = closes()
average = sum(c) / len(c)
target = SIZE if c[-1] > average else -SIZE # long above the average, short below
held = position()
if held != target:
if held:
print(exchange.market_close(COIN))
print(exchange.market_open(COIN, target > 0, SIZE))
print(f"close {c[-1]:.0f} average {average:.0f} position {position()}")
while True:
step()
time.sleep(300)BASE_URL=https://api.ironflow.sh/box/ibxs_... python bot.pyOur run on 12 November 2026, after the SDK's order answers:
close 71603 average 72702 position -0.001- Candles come from Ironflow's
/v1/candles, no key for 24 hours. A box answers your account's info requests (user_state, open orders, fills,l2Book,allMids) but notcandleSnapshot. - Wallet: the first signed order binds the box to it. Deriving it from
base_urlkeeps it the same on every run. - Data gaps: an answer of
Paper market data unavailable.means the box had no fresh book for that market. The next step tries again. - Backtest too: test the idea on past data with fees and funding.
- A paper result is an estimate from real order books and trades.
3. skip_ws=True#
Info(base_url) opens a WebSocket at base_url + "/ws" unless you pass skip_ws=True. A box answers that URL with 404. REST calls still work, but subscribe() gets nothing and the script takes about 50 seconds to exit. Exchange builds its own Info with skip_ws=True already, so only the Info you make needs the flag.
Questions#
What do I need to build a Hyperliquid trading bot?#
Python 3, Hyperliquid's official SDK (pip install hyperliquid-python-sdk), a price source for your signal and a paper account to trade. One POST to https://api.ironflow.sh/v1/ironbox gives a simulated account with $10,000 and live prices, with no key and no deposit.
Can I test a Hyperliquid bot without real money?#
Yes. Set the SDK's base_url to a paper box. Orders fill against live Hyperliquid order books inside the simulator, with fees, funding and liquidation simulated, and never reach Hyperliquid.
Why does my Hyperliquid bot take a minute to exit?#
The SDK's Info opens a WebSocket at base_url plus /ws unless you pass skip_ws=True. A paper box has no WebSocket, so subscriptions get nothing and the script waits about 50 seconds to exit. Pass skip_ws=True.
Does the bot trade real money?#
No. A paper box only simulates: its $10,000 is not real and its orders never reach Hyperliquid.
Where does the bot get candles?#
From Ironflow's GET /v1/candles, which needs no key for the last 24 hours. A paper box answers your account's info requests but not candleSnapshot, and Hyperliquid's own candleSnapshot keeps only the newest 5,000 candles.
Related guides#
- Hyperliquid paper trading: test a bot without risking funds
- Hyperliquid testnet without a mainnet deposit
- How to backtest on Hyperliquid
- A sandbox for Hyperliquid trading agents
References#
- hyperliquid-dex/hyperliquid-python-sdk. The official SDK used above.
- Ironflow docs: Ironbox. Every paper box endpoint, limit and error.
A paper box takes one POST and no signup. Start a paper box and run the bot against it.
Free key14 days of history at 60 requests a minute. Without a key, the API reaches 24 hours back.
By requesting a key you agree to the Terms and API terms; see the Privacy Policy. We may email you when your key keeps hitting its limits; you can opt out at any time.