Hyperliquid
Hyperliquid is a decentralized perpetual futures and spot exchange built on the Hyperliquid L1, a purpose-built blockchain optimized for trading. HyperCore provides a fully on-chain order book and matching engine. This integration supports live market data feeds and order execution on Hyperliquid.
The Hyperliquid integration is under active development. Some features may be incomplete.
Overview
This adapter is implemented in Rust with Python bindings. It provides direct integration with Hyperliquid's REST and WebSocket APIs without requiring external client libraries.
The Hyperliquid adapter includes multiple components:
HyperliquidHttpClient: Low-level HTTP API connectivity.HyperliquidWebSocketClient: Low-level WebSocket API connectivity.HyperliquidInstrumentProvider: Instrument parsing and loading functionality.HyperliquidDataClient: Market data feed manager.HyperliquidExecutionClient: Account management and trade execution gateway.HyperliquidLiveDataClientFactory: Factory for Hyperliquid data clients (used by the trading node builder).HyperliquidLiveExecClientFactory: Factory for Hyperliquid execution clients (used by the trading node builder).
Most users will define a configuration for a live trading node (as shown below) and won't need to work directly with these lower-level components.
Builder fees
This integration is free and open source. NautilusTrader participates in the Hyperliquid Builder Codes program, which routes a small 1 basis point (0.01%) fee on fills to support ongoing development and maintenance. This fee is charged by Hyperliquid in addition to standard fees, and applies to perpetuals and spot sells only.
This builder fee is at the low end of ecosystem norms (Hyperliquid allows up to 0.1% (10 bps) for perps and 1% (100 bps) for spot). See Hyperliquid Builder Codes and Hyperliquid Fees for details.
Checking approval status
You can check whether your wallet has approved the builder fee:
# Check by wallet address (no private key required)
python nautilus_trader/adapters/hyperliquid/scripts/builder_fee_verify.py 0xYourWalletAddress
# Or derive address from private key env var
python nautilus_trader/adapters/hyperliquid/scripts/builder_fee_verify.py
This queries the Hyperliquid API to verify your approval status.
Approving builder fees
Before you can trade on Hyperliquid via NautilusTrader, you must approve the builder fee. This is a one-time setup step per wallet address, per network.
You must sign the approval with your main wallet private key (the same key used for trading). This cannot be done with an API key or agent wallet.
Running the approval script
The script reads your private key from environment variables (HYPERLIQUID_PK or HYPERLIQUID_TESTNET_PK).
It prompts for confirmation before submitting.
# Mainnet (uses HYPERLIQUID_PK)
python nautilus_trader/adapters/hyperliquid/scripts/builder_fee_approve.py
# Testnet (uses HYPERLIQUID_TESTNET_PK)
HYPERLIQUID_TESTNET=true python nautilus_trader/adapters/hyperliquid/scripts/builder_fee_approve.py
The script outputs confirmation of the approval. Once approved, all subsequent orders placed through NautilusTrader include the builder fee automatically.
The approval authorizes a 0.01% (1 basis point) fee rate which applies to perpetuals and spot sells.
You only need to run this script once per wallet per network. The approval persists until you explicitly revoke it.
Revoking approval
If you need to revoke the builder fee approval, the script reads from the same environment
variables as the approval script (HYPERLIQUID_PK or HYPERLIQUID_TESTNET_PK).
The script prompts for confirmation before submitting.
# Mainnet (uses HYPERLIQUID_PK)
python nautilus_trader/adapters/hyperliquid/scripts/builder_fee_revoke.py
# Testnet (uses HYPERLIQUID_TESTNET_PK)
HYPERLIQUID_TESTNET=true python nautilus_trader/adapters/hyperliquid/scripts/builder_fee_revoke.py
After revoking, you will not be able to trade on Hyperliquid via NautilusTrader until you re-approve.
Troubleshooting
API error related to builder fee approval
If you see an error mentioning "builder fee" when placing orders, this indicates the builder fee has not been approved for your wallet. Run the approval script as described above to resolve this.
You can verify your approval status at any time using the verify script.
Examples
You can find live example scripts here.
Testnet setup
Hyperliquid provides a testnet environment for testing strategies without risking real funds.
Getting testnet funds
To receive testnet USDC, you must first have deposited on mainnet using the same wallet address:
- Visit the Hyperliquid mainnet portal and make a deposit with your wallet.
- Visit the testnet faucet using the same wallet.
- Claim 1,000 mock USDC from the faucet.
Email wallet users: Email login generates different addresses for mainnet vs testnet. To use the faucet, export your email wallet from mainnet, import it into MetaMask or Rabby, then connect the extension to testnet.
Creating a testnet account
- Visit the Hyperliquid testnet portal.
- Connect your wallet (MetaMask, WalletConnect, or email).
- The testnet automatically creates an account for your wallet address.
Exporting your private key
To use your testnet account with NautilusTrader, you need to export your wallet's private key:
MetaMask:
- Click the three dots menu next to your account.
- Select "Account details".
- Click "Show private key".
- Enter your password and copy the private key.
Never share your private keys. Store private keys securely using environment variables; never commit them to version control.
Setting environment variables
Set your testnet credentials as environment variables:
export HYPERLIQUID_TESTNET_PK="your_private_key_here"
# Optional: for vault trading
export HYPERLIQUID_TESTNET_VAULT="vault_address_here"
The adapter automatically loads these when testnet=True in the configuration.
Product support
Hyperliquid offers linear perpetual futures and native spot markets.
| Product Type | Data Feed | Trading | Notes |
|---|---|---|---|
| Perpetual Futures | ✓ | ✓ | USDC-settled linear perps. |
| Spot | ✓ | ✓ | Native spot markets. |
Perpetual futures on Hyperliquid are settled in USDC. Spot markets are standard currency pairs.
Symbology
Hyperliquid uses a specific symbol format for instruments:
Perpetual futures
Format: {Base}-USD-PERP
Examples:
BTC-USD-PERP- Bitcoin perpetual futuresETH-USD-PERP- Ethereum perpetual futuresSOL-USD-PERP- Solana perpetual futures
To subscribe in your strategy:
InstrumentId.from_str("BTC-USD-PERP.HYPERLIQUID")
InstrumentId.from_str("ETH-USD-PERP.HYPERLIQUID")
Spot markets
Format: {Base}-{Quote}-SPOT
Examples:
PURR-USDC-SPOT- PURR/USDC spot pairHYPE-USDC-SPOT- HYPE/USDC spot pair
To subscribe in your strategy:
InstrumentId.from_str("PURR-USDC-SPOT.HYPERLIQUID")
Spot instruments may include vault tokens (prefixed with vntls:). These are automatically
handled by the instrument provider.
Instrument provider
The instrument provider supports filtering when loading instruments via
InstrumentProviderConfig(filters=...):
| Filter key | Type | Description |
|---|---|---|
market_types (or kinds) | list[str] | "perp" or "spot". |
bases | list[str] | Base currency codes, e.g. ["BTC", "ETH"]. |
quotes | list[str] | Quote currency codes, e.g. ["USDC"]. |
symbols | list[str] | Full symbols, e.g. ["BTC-USD-PERP"]. |
Example loading only perpetual instruments:
instrument_provider=InstrumentProviderConfig(
load_all=True,
filters={"market_types": ["perp"]},
)
Data subscriptions
The adapter supports the following data subscriptions:
| Data type | Subscription | Historical | Nautilus type | Notes |
|---|---|---|---|---|
| Trade ticks | ✓ | - | TradeTick | Via WebSocket trades channel. |
| Quote ticks | ✓ | - | QuoteTick | Best bid/offer from WebSocket. |
| Order book deltas | ✓ | - | OrderBookDelta | L2 depth. Snapshot on subscribe and reconnect. |
| Bars | ✓ | ✓ | Bar | See supported intervals below. |
| Mark prices | ✓ | - | MarkPriceUpdate | Perpetual mark price ticks. |
| Index prices | ✓ | - | IndexPriceUpdate | Underlying index reference prices. |
| Funding rates | ✓ | - | FundingRate | Perpetual funding rate updates. |
Historical quote tick and trade tick requests are not yet supported by this adapter.
Supported bar intervals
| Resolution | Hyperliquid candle |
|---|---|
| 1-MINUTE | 1m |
| 3-MINUTE | 3m |
| 5-MINUTE | 5m |
| 15-MINUTE | 15m |
| 30-MINUTE | 30m |
| 1-HOUR | 1h |
| 2-HOUR | 2h |
| 4-HOUR | 4h |
| 8-HOUR | 8h |
| 12-HOUR | 12h |
| 1-DAY | 1d |
| 3-DAY | 3d |
| 1-WEEK | 1w |
| 1-MONTH | 1M |
Orders capability
Hyperliquid supports a comprehensive set of order types and execution options.
Order types
| Order Type | Perpetuals | Spot | Notes |
|---|---|---|---|
MARKET | ✓ | ✓ | IOC limit at 0.5% slippage from best BBO. |
LIMIT | ✓ | ✓ | |
STOP_MARKET | ✓ | ✓ | Stop loss orders. |
STOP_LIMIT | ✓ | ✓ | Stop loss with limit execution. |
MARKET_IF_TOUCHED | ✓ | ✓ | Take profit at market. |
LIMIT_IF_TOUCHED | ✓ | ✓ | Take profit with limit execution. |
Conditional orders (stop and if-touched) are implemented using Hyperliquid's native trigger order functionality with automatic TP/SL mode detection. All trigger orders are evaluated against the mark price.
Market orders require cached quote data. The adapter uses the best ask (for buys) or best bid (for sells) with 0.5% slippage, rounded to 5 significant figures. Ensure you subscribe to quotes for any instrument you intend to trade with market orders.
Time in force
| Time in force | Perpetuals | Spot | Notes |
|---|---|---|---|
GTC | ✓ | ✓ | Good Till Canceled. |
IOC | ✓ | ✓ | Immediate or Cancel. |
FOK | - | - | Not supported. |
GTD | - | - | Not supported. |
Execution instructions
| Instruction | Perpetuals | Spot | Notes |
|---|---|---|---|
post_only | ✓ | ✓ | Equivalent to ALO time in force. |
reduce_only | ✓ | ✓ | Close-only orders. |
Post-only orders that would immediately match are rejected by Hyperliquid. The adapter detects
this and generates an OrderRejected event. Post-only orders are routed through Hyperliquid's
ALO (Add-Liquidity-Only) lane.
Order operations
| Operation | Perpetuals | Spot | Notes |
|---|---|---|---|
| Submit order | ✓ | ✓ | Single order submission. |
| Submit order list | ✓ | ✓ | Batch order submission (single API call). |
| Modify order | - | - | Not yet exposed via Python bindings. |
| Cancel order | ✓ | ✓ | Cancel by client order ID. |
| Cancel all orders | ✓ | ✓ | Iterates cached open orders by instrument/side. |
| Batch cancel | ✓ | ✓ | Iterates provided cancel list. |
Order modification exists in the Rust layer but is not yet wired through to the Python execution client. Cancel all and batch cancel issue individual cancel requests per order.
Order books
Order books are maintained via L2 WebSocket subscription with delta updates.
Order book snapshot rebuilds are triggered on:
- Initial subscription of the order book data.
- WebSocket reconnects.
There is a limitation of one order book per instrument per trader instance.
API credentials
There are two options for supplying your credentials to the Hyperliquid clients. Either pass the corresponding values to the configuration objects, or set the following environment variables:
For Hyperliquid mainnet clients, you can set:
HYPERLIQUID_PKHYPERLIQUID_VAULT(optional, for vault trading)
For Hyperliquid testnet clients, you can set:
HYPERLIQUID_TESTNET_PKHYPERLIQUID_TESTNET_VAULT(optional, for vault trading)
We recommend using environment variables to manage your credentials.
Vault trading
Hyperliquid supports vault trading, where a wallet operates on behalf of a vault (sub-account). Orders are signed with the wallet's private key but include the vault address in the signature payload.
To trade via a vault, set the vault_address in your execution client config (or set the
HYPERLIQUID_VAULT / HYPERLIQUID_TESTNET_VAULT environment variable).
When vault trading is enabled, WebSocket subscriptions for order and fill updates automatically use the vault address instead of the wallet address. This is required to receive the vault's order and fill events.
Rate limiting
The adapter implements a token bucket rate limiter for Hyperliquid's REST API with a capacity of 1200 weight per minute. HTTP info requests are automatically retried with exponential backoff (full jitter) on rate limit (429) and server error (5xx) responses.
Configuration
Data client configuration options
| Option | Default | Description |
|---|---|---|
base_url_http | None | Override for the REST base URL. |
base_url_ws | None | Override for the WebSocket base URL. |
testnet | False | Connect to the Hyperliquid testnet when True. |
http_timeout_secs | 10 | Timeout (seconds) applied to REST calls. |
http_proxy_url | None | Optional HTTP proxy URL. |
ws_proxy_url | None | Reserved; WebSocket proxy not yet implemented. |
Execution client configuration options
| Option | Default | Description |
|---|---|---|
private_key | None | EVM private key; loaded from HYPERLIQUID_PK or HYPERLIQUID_TESTNET_PK when omitted. |
vault_address | None | Vault address; loaded from HYPERLIQUID_VAULT or HYPERLIQUID_TESTNET_VAULT if omitted. |
base_url_http | None | Override for the REST base URL. |
base_url_ws | None | Override for the WebSocket base URL. |
testnet | False | Connect to the Hyperliquid testnet when True. |
max_retries | None | Maximum retry attempts for info requests. |
retry_delay_initial_ms | None | Initial delay (milliseconds) between retries. |
retry_delay_max_ms | None | Maximum delay (milliseconds) between retries. |
http_timeout_secs | 10 | Timeout (seconds) applied to REST calls. |
http_proxy_url | None | Optional HTTP proxy URL. |
ws_proxy_url | None | Reserved; WebSocket proxy not yet implemented. |
Configuration example
from nautilus_trader.adapters.hyperliquid import HYPERLIQUID
from nautilus_trader.adapters.hyperliquid import HyperliquidDataClientConfig
from nautilus_trader.adapters.hyperliquid import HyperliquidExecClientConfig
from nautilus_trader.config import InstrumentProviderConfig
from nautilus_trader.config import TradingNodeConfig
config = TradingNodeConfig(
data_clients={
HYPERLIQUID: HyperliquidDataClientConfig(
instrument_provider=InstrumentProviderConfig(load_all=True),
testnet=True, # Use testnet
),
},
exec_clients={
HYPERLIQUID: HyperliquidExecClientConfig(
private_key=None, # Loads from HYPERLIQUID_TESTNET_PK env var
vault_address=None, # Optional: loads from HYPERLIQUID_TESTNET_VAULT
instrument_provider=InstrumentProviderConfig(load_all=True),
testnet=True, # Use testnet
),
},
)
When testnet=True, the adapter automatically uses testnet environment variables
(HYPERLIQUID_TESTNET_PK and HYPERLIQUID_TESTNET_VAULT) instead of mainnet variables.
Then, create a TradingNode and add the client factories:
from nautilus_trader.adapters.hyperliquid import HYPERLIQUID
from nautilus_trader.adapters.hyperliquid import HyperliquidLiveDataClientFactory
from nautilus_trader.adapters.hyperliquid import HyperliquidLiveExecClientFactory
from nautilus_trader.live.node import TradingNode
# Instantiate the live trading node with a configuration
node = TradingNode(config=config)
# Register the client factories with the node
node.add_data_client_factory(HYPERLIQUID, HyperliquidLiveDataClientFactory)
node.add_exec_client_factory(HYPERLIQUID, HyperliquidLiveExecClientFactory)
# Finally build the node
node.build()
Contributing
For additional features or to contribute to the Hyperliquid adapter, please see our contributing guide.