The Nesto Perps Bot communicates with Hyperliquid through the official Python SDK. This chapter covers API key setup, websocket configuration, and the differences between testnet and mainnet environments.
Hyperliquid requires an agent wallet pattern — a dedicated API wallet, not your main wallet. Generate a key pair with the Hyperliquid dashboard, then configure the bot:
from perps_bot.config import AppConfig, EnvConfig
from perps_bot.adapters.hyperliquid import HyperliquidAdapter
config = AppConfig.from_yaml("config/default.yaml")
env = EnvConfig(
api_wallet_private_key="0x...",
account_address="0x...",
)
adapter = HyperliquidAdapter(config, env)The bot enforces that the agent wallet address differs from the account address. If they match, initialization raises an ExchangeError.
The bot selects the correct API URL based on run_mode:
| Mode | API URL | Key Required |
|---|---|---|
testnet | TESTNET_API_URL | Yes (testnet keys) |
live-auto | MAINNET_API_URL | Yes |
paper | N/A (simulated) | No |
if config.run_mode == RunMode.TESTNET:
base_url = TESTNET_API_URL
else:
base_url = MAINNET_API_URLThe Hyperliquid SDK fetches market metadata in its constructor, which can fail during exchange rate-limits. The bot uses capped exponential backoff:
def _retry_init(what, factory, max_attempts=480, base_delay=1.5, max_delay=60):
attempt = 0
while True:
attempt += 1
try:
return factory()
except Exception as e:
delay = min(max_delay, base_delay * (2 ** min(attempt - 1, 5)))
logger.warning(f"{what}: attempt {attempt} failed, retrying in {delay:.0f}s")
time.sleep(delay)Websockets reduce REST polling load and provide real-time order book updates. Enable them in exchange.use_websocket. When disabled, the bot falls back to REST-based all_mids() and meta_and_asset_ctxs() polling at the configured loop interval.
The adapter enforces a client-side rate limit based on exchange weight per minute:
def _rate_limit(self):
elapsed = time.time() - self._last_request_ts
min_interval = 60.0 / config.exchange.rate_limit_max_rest_weight_per_minute
if elapsed < min_interval:
time.sleep(min_interval - elapsed)
self._last_request_ts = time.time()Default: 900 weight/minute, adjustable in config/exchange.yaml. The startup_max_retries: 480 (8 minutes at default backoff) lets the bot survive a temporary API ban without crashing.
The Nesto Perps Bot ships with a configurable trend strategy engine. This chapter covers the three strategy families you can implement and how the built-in candidate works.
The production strategy uses EMA crossovers, RSI filters, and ATR-based stops:
from perps_bot.indicators import ema, rsi, atr, adx
from perps_bot.models import Side, Signal
def evaluate_coin(coin, closes, candles, config):
ema_fast = ema(closes, 20)
ema_mid = ema(closes, 50)
ema_slow = ema(closes, 200)
current_rsi = rsi(closes, 14)[-1]
current_atr = atr(candles, 14)[-1]
# Long: close > EMA200, EMA20 > EMA50, RSI in [45, 68]
if price > ema_slow[-1] and ema_fast[-1] > ema_mid[-1]:
if long_rsi_min < current_rsi < long_rsi_max:
return Signal(coin=coin, side=Side.LONG, ...)# config/default.yaml
strategy_trend:
ema_fast: 20
ema_mid: 50
ema_slow: 200
rsi_period: 14
atr_period: 14
long_rsi_min: 45
long_rsi_max: 68
short_rsi_min: 32
short_rsi_max: 55For market-making strategies, the bot supports limit orders with offset pricing. Entry orders can be limit_gtc (good-til-cancelled) or limit_ioc (immediate-or-cancel):
if config.entries.entry_order_type == "limit_ioc":
order_type = {"limit": {"tif": "Ioc"}}
elif config.entries.entry_order_type == "limit_gtc":
order_type = {"limit": {"tif": "Gtc"}}The entry_limit_offset_bps parameter controls how aggressively the price is set relative to mid. LONG entries price above mid; SHORT entries below.
The trend strategy is inherently momentum-based — it enters in the direction of the prevailing EMA alignment. To add a mean-reversion variant, you would invert the EMA conditions and tighten RSI bands. The sentiment module can also act as a mean-reversion filter by skipping overextended moves.
Funding rate and Fear & Greed Index gate entries. The funding filter skips longs when the crowd is already long (high funding) and shorts when the crowd is short (negative funding):
if sent.funding_bias_enabled and funding is not None:
if funding > sent.funding_skip_long_above:
return None # Skip long — too expensiveThe Fear & Greed Index prevents entering shorts at fear extremes (capitulation / squeeze zone) and longs at greed extremes (blow-off top risk).
Get the full Nesto Perps Bot and unlock everything.
Get the complete guide with every chapter unlocked, including code samples, diagrams, and best practices.
Access all interactive tools with complete data, all workload profiles, and the full scenario library.
Downloadable source code, configuration files, and working examples from every chapter.
Free updates for life. Every new chapter, tool, and improvement included.