What You Are Building
A Python bot that connects to Hyperliquid’s perpetuals DEX, pulls live BTC-PERP price data, runs a Donchian channel breakout strategy, and submits orders against the on-chain orderbook. Claude Code writes the SDK code while you set up the wallet, pick the strategy parameters, and run it on testnet first. By the end you will have a working bot trading against Hyperliquid’s testnet without spending gas.
Why Hyperliquid for AI Bots
Hyperliquid runs a fully on-chain central limit order book on its own L1. Every order, fill, and funding payment lives on-chain, and there are no gas fees for placing or canceling orders. That makes it one of the few DEXes where a Python bot can compete on latency without paying network costs per action.
A few things that matter for AI bot builders:
| Feature | Hyperliquid | Centralized Exchange |
|---|---|---|
| Custody | Non-custodial (your wallet signs) | Custodial (exchange holds funds) |
| Order placement cost | Zero gas | Zero gas, but KYC required |
| Order book transparency | Fully on-chain, public | Hidden, exchange controls |
| API | REST + WebSocket | REST + WebSocket |
| Python SDK | Official hyperliquid-python-sdk | Varies (ccxt, official SDKs) |
| Testnet | Yes, free funds via faucet | Most exchanges have testnet |
If you have built a Bybit MCP bot or an Alpaca stock bot, the workflow here is similar. The main shift is that you sign orders with a wallet private key instead of an API secret, and execution settles on a public chain instead of a private exchange engine.
Prerequisites
- Python 3.10+
- A funded Ethereum wallet (a fresh one is fine for testnet)
- Claude Code installed and working
- Basic Python and async familiarity
- A code editor
Step 1: Set Up a Hyperliquid Testnet Wallet
Do not use your main wallet for bot work. Create a fresh one and fund it with test USDC.
- Generate a new wallet in MetaMask or your wallet of choice. Save the private key.
- Visit app.hyperliquid-testnet.xyz and connect the wallet.
- Click the faucet button on the testnet UI to receive test USDC.
- Approve the trading permissions when prompted (one-time signature).
Hyperliquid uses an “agent wallet” pattern for bots. Your main wallet authorizes a separate hot wallet that signs trades, so you never expose your primary key to the bot process. The official docs cover this in the Python SDK readme, and Claude Code can scaffold the agent setup for you.
Step 2: Install the Python SDK
Create a project folder and install the official SDK:
mkdir hyperliquid-bot && cd hyperliquid-bot
python -m venv venv
source venv/bin/activate
pip install hyperliquid-python-sdk eth-account python-dotenv pandas
Create a .env file:
HYPERLIQUID_PRIVATE_KEY=0xyour-agent-wallet-private-key
HYPERLIQUID_ACCOUNT_ADDRESS=0xyour-main-wallet-address
HYPERLIQUID_NETWORK=testnet
The account_address is your main wallet (the one that holds funds). The private_key belongs to the agent wallet that signs trades. This split is what keeps your real funds safe if the bot machine is ever compromised.
Step 3: Prompt Claude Code for the Bot Skeleton
Open Claude Code in the project directory and paste this prompt:
Write a Python trading bot for Hyperliquid testnet that:
- Uses the hyperliquid-python-sdk to connect to testnet
- Loads the agent private key and main account address from a .env file via python-dotenv
- Subscribes to BTC-PERP candles on the 5-minute timeframe via WebSocket
- Calculates a 20-period Donchian channel (highest high and lowest low of last 20 candles)
- Generates a LONG signal when price breaks above the upper channel
- Generates a SHORT signal when price breaks below the lower channel
- Submits market orders sized at 10% of available USDC balance
- Sets a stop-loss at 1.5% from entry and a take-profit at 3% from entry
- Tracks open positions to avoid duplicate orders
- Logs every action with timestamp, price, signal, and tx hash
- Cleanly handles WebSocket reconnects and signing errors
Claude Code will scaffold the connection and the strategy loop. The core looks like this:
import os
import time
from dotenv import load_dotenv
from eth_account import Account
from hyperliquid.info import Info
from hyperliquid.exchange import Exchange
from hyperliquid.utils import constants
load_dotenv()
PRIVATE_KEY = os.getenv("HYPERLIQUID_PRIVATE_KEY")
ACCOUNT = os.getenv("HYPERLIQUID_ACCOUNT_ADDRESS")
BASE_URL = constants.TESTNET_API_URL
agent = Account.from_key(PRIVATE_KEY)
info = Info(BASE_URL, skip_ws=False)
exchange = Exchange(agent, BASE_URL, account_address=ACCOUNT)
def get_donchian(candles, period=20):
highs = [float(c["h"]) for c in candles[-period:]]
lows = [float(c["l"]) for c in candles[-period:]]
return max(highs), min(lows)
def check_signal(symbol="BTC"):
candles = info.candles_snapshot(symbol, "5m", int(time.time()*1000) - 86400_000, int(time.time()*1000))
upper, lower = get_donchian(candles, 20)
last = float(candles[-1]["c"])
if last > upper:
return "long", last
if last < lower:
return "short", last
return None, last
The order placement helper is the part that takes the most iterations. Hyperliquid orders need a tick-size-aligned price, an SZ (size) in the asset’s decimals, and a signed payload. Ask Claude Code to wrap it:
def place_order(symbol, is_buy, size, price=None):
order_type = {"limit": {"tif": "Ioc"}} if price else {"market": {}}
return exchange.order(
coin=symbol,
is_buy=is_buy,
sz=size,
limit_px=price or 0,
order_type=order_type,
reduce_only=False,
)
If you want a simpler order interface, the SDK also exposes exchange.market_open() and exchange.market_close() which handle slippage protection internally.
Step 4: Add Position Sizing and Risk Controls
A bot that ignores risk will blow up the account on the first bad streak. Tell Claude Code to wire in three controls:
Add the following to the bot:
1. Read available USDC from info.user_state(ACCOUNT)["marginSummary"]["accountValue"]
2. Cap each position at 10% of account value
3. Set a hard daily loss limit of 5% — stop trading if hit
4. Reject any trade if open positions count is already 1
5. Round size to the asset's szDecimals from info.meta()
Hyperliquid’s info.meta() returns the universe of tradable assets with their tick sizes and size decimals. Without rounding, your order will be rejected with a “Px is invalid” or “Sz is invalid” error. Asking Claude Code to handle this upfront saves a debugging session.
| Risk Control | Setting | Why |
|---|---|---|
| Per-trade size | 10% of account value | Survives a long losing streak |
| Stop-loss | 1.5% from entry | Donchian breakouts fail often, cut fast |
| Take-profit | 3% from entry | 2:1 reward-to-risk minimum |
| Daily loss cap | 5% | Hard stop that blocks new orders |
| Max concurrent positions | 1 | Keeps the strategy auditable |
Step 5: Run It on Testnet
Save the script as bot.py and run:
python bot.py
The first run prints the loaded account, the WebSocket connection state, and the first Donchian calculation. When the price breaks the upper or lower channel, you should see a signal log and an order response with a transaction hash.
Check the trade on Hyperliquid testnet’s UI under your wallet address. The order will appear in the order history with the same SZ and price the bot logged.
Step 6: Watch for the Common Bugs
Three things tend to break first:
- Signing errors: Hyperliquid uses EIP-712 typed-data signing. If the agent wallet was not approved by the main account, every order returns
Signature verification failed. Re-run the agent approval flow in the testnet UI. - Symbol naming: Use
"BTC"not"BTC-PERP"or"BTC/USDT". The SDK assumes perpetual context. - Tick size: Asset prices must be rounded to the tick. For BTC the tick is usually 0.5, for SOL it can be 0.001.
round(price * 2) / 2works for BTC; useinfo.meta()for the general case.
If Claude Code cannot reproduce a bug, paste the full SDK error message into the chat. The error strings are descriptive and Claude can usually pinpoint the missing parameter.
Step 7: Backtest Before Going Live
Before moving to mainnet, test the strategy on historical Hyperliquid data. Pull candles via info.candles_snapshot() for the last 90 days, run the same Donchian logic offline, and check the equity curve. We have a step-by-step backtesting guide that walks through the workflow with pandas and a vector approach.
The numbers to look for:
- Win rate: Donchian breakouts on a 5-minute chart usually win 35-45% of the time. The edge is in the reward-to-risk ratio, not the hit rate.
- Average winner vs average loser: You want winners to average at least 1.5x your losers. If the ratio is below 1, the strategy is wrong for this market regime.
- Max drawdown: 20% peak-to-trough is the worst-case bound for a small breakout bot. Anything beyond means your sizing is too aggressive.
Going to Mainnet
When you are ready to switch from testnet to mainnet, change two things:
BASE_URL = constants.MAINNET_API_URL
And generate a new agent wallet on the mainnet UI, approve it from your main wallet, fund the main wallet with real USDC. Start with a tiny position size (0.5% of account value) for the first week. Hyperliquid’s order book has real liquidity but slippage on a low-cap perp can still surprise you.
Where to Go Next
- Add a second strategy and rotate based on regime — see the macro sentiment trading bot for one approach.
- Pipe trade logs into the daily AI trading research routine so you can review each day’s signals.
- If you want to compare AI coding tools for this kind of build, the tools comparison post covers Claude Code, Cursor, and Windsurf on the same Python tasks.
Hyperliquid is one of the more agent-friendly venues in crypto right now. The on-chain orderbook means every fill is verifiable, the Python SDK is well-maintained, and Claude Code handles the SDK calls without much hand-holding. Start on testnet, get the risk controls right, then size up slowly.