Hyperliquid Market
Spot and perpetuals.
tribulnation-hyperliquid, venue namehyperliquid.
See the generic market interface for the shared method surface. This page covers only what is Hyperliquid-specific.
Account
venue selects the network: hyperliquid is mainnet, hyperliquid_testnet is testnet. An
address without a private_key is read-only. The built-in hyperliquid account is
accounts.Hyperliquid(public=True), read-only.
Exchanges & ID conventions
Hyperliquid exposes several exchanges under one venue. exchanges() reports:
exchange_id |
Type | What it is |
|---|---|---|
spot |
spot | The spot exchange. |
'' (empty) |
perp | The default perpetuals DEX. |
<dex-name> |
perp | A named builder-deployed perp DEX. |
For perps, exchange_id is the DEX name; the empty string means the default/no-DEX
universe. Under the hood perp_exchange(dex) treats '' and None equivalently.
Market IDs by exchange:
- Perp — the asset name, e.g.
BTC. Full ID:hyperliquid::BTC(empty exchange segment = default DEX) orhyperliquid:<dex>:BTC. - Spot — canonical form
BASE/QUOTE:ASSET_IDX, e.g.BTC/USDC:0. Full ID:hyperliquid:spot:BTC/USDC:0. TheASSET_IDXis Hyperliquid'sspotMeta.universe[].index;market()cross-checks that theBASE/QUOTEnames match that index and raises on mismatch.Exchange.markets()returns fully-formedBASE/QUOTE:IDXstrings you can pass straight back in.
Settings
place_order and index accept settings={'hyperliquid': {...}}, typed by the
Settings TypedDict (core/settings.py). All keys are optional:
| Key | Type | Applies to | Meaning |
|---|---|---|---|
reduce_only |
bool |
place_order |
Place as reduce-only. |
limit_tif |
TimeInForce |
place_order |
Time-in-force for limit orders. |
index_price |
'oracle' | 'mark' |
index (perp) |
Which price index() returns; defaults to 'oracle'. |
index_price='mark' returns the market's mark price, falling back to the oracle price when
mark is unavailable; the default 'oracle' always returns the oracle price.
Venue-specific semantics
- Spot and perp markets are separate objects (
SpotMarket/PerpMarket) with their own rules and position logic. OnlyPerpMarketexposes funding andindex(). candlesraisesNotImplementedErroron both, andCANDLE_INTERVALSis empty:info.candle_snapshotanswers at most 5000 candles per call and the typed client declares no paged walk for it yet, so the series cannot be swept through the client.- Perp
available_notional/leverage and spot balances are computed against Hyperliquid-native metadata (asset/collateral tokens, user fees), cached venue-wide and refreshed lazily. perp_collateralat the exchange level returns the account cross pool in unified account mode. The implementation assertsuser_abstraction == "unifiedAccount"and raises on other modes. In unified mode, the real equity backing perps is the spot collateral token balance (determined byperp_meta['collateralToken'], USDC for the default DEX), notcrossMarginSummary.accountValue(which only reflects USDC deposited into the perps engine). Fields:equity=spot_collateral_balance,free_collateral=tokenToAvailableAfterMaintenancefor the collateral token,initial_margin=equity-free_collateral,maintenance_margin=crossMaintenanceMarginUsed,leverage=totalNtlPos/equity,margin_mode='cross'.Market.perp_collateral()is mode-aware: it finds the asset inassetPositionsand branches on the position's leverage type — a cross position reports the same cross pool, while an isolated position gets its own bucket from that position'srawUsd + unrealizedPnl(equity),marginUsed(=initial_margin), andmargin_mode='isolated'. HL gives no isolated maintenance figure directly, so it is approximated aspositionValue / (2 · maxLeverage)(half the initial-margin fraction at max leverage).collateral(spot) returns the quote-token balance (equity=total,free_collateral=total-hold).- Builder-DEX perps use a DEX-scoped asset-id formula (
100000 + dex_idx*10000 + asset_idx); default-DEX perps use the plain asset index. This only matters internally — you address markets by name.
Example
from dotenv import load_dotenv
from tribulnation.sdk import MarketSDK, accounts
load_dotenv()
sdk = MarketSDK({'hl': accounts.Hyperliquid()})
# default-DEX perp
await sdk.index('hl::BTC')
# spot
book = await sdk.depth('hl:spot:BTC/USDC:0')
await sdk.place_order(
'hl::ETH',
{
'type': 'LIMIT',
'qty': 0.01,
'price': 1000,
},
settings={'hyperliquid': {'limit_tif': 'Alo', 'reduce_only': False}},
)