← Back to all products

Nesto Perps Bot

$99

Self-hosted automated trading bot for Hyperliquid perpetuals. Configurable strategies, built-in risk limits and position sizing, live and paper modes, Docker deploy, and a guided setup wizard. You set the rules.

📁 147 files
DockerTOMLMarkdownShellYAMLPythonConfigRedisNotion

📄 Product Preview

Try the interactive reader and demo tools below, or get the full product with all content unlocked.

📖 Interactive Reader (Free Preview) ⚙ Try Demo Tools 📦 Download Free Sample

📁 File Structure 147 files

nesto-perps-bot/ ├── .pytest_cache/ │ ├── CACHEDIR.TAG │ ├── README.md │ └── v/ │ └── cache/ │ └── nodeids ├── DISCLAIMER.md ├── Dockerfile ├── LICENSE ├── QUICKSTART.md ├── README.md ├── SECURITY.md ├── config/ │ ├── default.yaml │ ├── live_auto_example.yaml │ ├── live_exit_only.yaml │ ├── paper.yaml │ └── testnet.yaml ├── data/ │ └── terminal.log ├── free-sample.zip ├── guide/ │ ├── 01-hyperliquid-connection.md │ ├── 02-trading-strategies.md │ ├── 03-risk-management.md │ ├── 04-execution-modes.md │ └── 05-monitoring-metrics.md ├── index.html ├── pyproject.toml ├── scripts/ │ ├── run_live_auto.sh │ ├── run_live_exit_only.sh │ ├── run_paper.sh │ └── run_testnet.sh ├── src/ │ ├── nesto_perps_bot.egg-info/ │ │ ├── PKG-INFO │ │ ├── SOURCES.txt │ │ ├── dependency_links.txt │ │ ├── entry_points.txt │ │ ├── requires.txt │ │ └── top_level.txt │ └── perps_bot/ │ ├── __init__.py │ ├── __pycache__/ │ │ ├── __init__.cpython-312.pyc │ │ ├── alerting.cpython-312.pyc │ │ ├── cli.cpython-312.pyc │ │ ├── config.cpython-312.pyc │ │ ├── console.cpython-312.pyc │ │ ├── constants.cpython-312.pyc │ │ ├── errors.cpython-312.pyc │ │ ├── indicators.cpython-312.pyc │ │ ├── math_utils.cpython-312.pyc │ │ ├── models.cpython-312.pyc │ │ ├── redact.cpython-312.pyc │ │ ├── sentiment.cpython-312.pyc │ │ ├── state_store.cpython-312.pyc │ │ └── time_utils.cpython-312.pyc │ ├── adapters/ │ │ ├── __init__.py │ │ ├── __pycache__/ │ │ │ ├── __init__.cpython-312.pyc │ │ │ ├── exchange_base.cpython-312.pyc │ │ │ ├── hyperliquid_adapter.cpython-312.pyc │ │ │ └── paper_adapter.cpython-312.pyc │ │ ├── exchange_base.py │ │ ├── hyperliquid_adapter.py │ │ └── paper_adapter.py │ ├── alerting.py │ ├── app.py │ ├── backtest/ │ │ ├── __init__.py │ │ ├── __pycache__/ │ │ │ ├── __init__.cpython-312.pyc │ │ │ ├── data.cpython-312.pyc │ │ │ ├── engine.cpython-312.pyc │ │ │ └── metrics.cpython-312.pyc │ │ ├── data.py │ │ ├── engine.py │ │ ├── metrics.py │ │ └── report.py │ ├── bot_process.py │ ├── cli.py │ ├── config.py │ ├── console.py │ ├── constants.py │ ├── core/ │ │ ├── __init__.py │ │ ├── __pycache__/ │ │ │ ├── __init__.cpython-312.pyc │ │ │ ├── exits.cpython-312.pyc │ │ │ ├── preflight.cpython-312.pyc │ │ │ ├── reconciliation.cpython-312.pyc │ │ │ ├── risk.cpython-312.pyc │ │ │ ├── sizing.cpython-312.pyc │ │ │ └── strategy_trend.cpython-312.pyc │ │ ├── emergency.py │ │ ├── execution.py │ │ ├── exits.py │ │ ├── manager.py │ │ ├── preflight.py │ │ ├── reconciliation.py │ │ ├── risk.py │ │ ├── signals.py │ │ ├── sizing.py │ │ └── strategy_trend.py │ ├── dashboard.py │ ├── errors.py │ ├── indicators.py │ ├── logging_setup.py │ ├── math_utils.py │ ├── models.py │ ├── redact.py │ ├── remote.py │ ├── sentiment.py │ ├── state_store.py │ ├── time_utils.py │ └── webhooks/ │ ├── __init__.py │ ├── auth.py │ └── server.py ├── static/ │ └── dashboard.html └── tests/ ├── __pycache__/ │ ├── conftest.cpython-312-pytest-9.0.2.pyc │ ├── test_backtest_data.cpython-312-pytest-9.0.2.pyc │ ├── test_backtest_engine.cpython-312-pytest-9.0.2.pyc │ ├── test_config_defaults.cpython-312-pytest-9.0.2.pyc │ ├── test_exits.cpython-312-pytest-9.0.2.pyc │ ├── test_forbidden_actions.cpython-312-pytest-9.0.2.pyc │ ├── test_indicators.cpython-312-pytest-9.0.2.pyc │ ├── test_market_context.cpython-312-pytest-9.0.2.pyc │ ├── test_order_sides.cpython-312-pytest-9.0.2.pyc │ ├── test_paper_adapter.cpython-312-pytest-9.0.2.pyc │ ├── test_preflight_live_gates.cpython-312-pytest-9.0.2.pyc │ ├── test_reconciliation.cpython-312-pytest-9.0.2.pyc │ ├── test_reduce_only_exits.cpython-312-pytest-9.0.2.pyc │ ├── test_risk_governor.cpython-312-pytest-9.0.2.pyc │ ├── test_secret_redaction.cpython-312-pytest-9.0.2.pyc │ ├── test_sentiment.cpython-312-pytest-9.0.2.pyc │ ├── test_sizing.cpython-312-pytest-9.0.2.pyc │ ├── test_startup_retry.cpython-312-pytest-9.0.2.pyc │ └── test_strategy_trend.cpython-312-pytest-9.0.2.pyc ├── conftest.py ├── test_backtest_data.py ├── test_backtest_engine.py ├── test_config_defaults.py ├── test_exits.py ├── test_forbidden_actions.py ├── test_indicators.py ├── test_market_context.py ├── test_order_sides.py ├── test_paper_adapter.py ├── test_preflight_live_gates.py ├── test_reconciliation.py ├── test_reduce_only_exits.py ├── test_risk_governor.py ├── test_secret_redaction.py ├── test_sentiment.py ├── test_sizing.py ├── test_startup_retry.py └── test_strategy_trend.py

📖 Documentation Preview README excerpt

Nesto Perps Bot

Risk-managed Hyperliquid perpetual futures trading bot.

This bot can lose money. Perps use leverage and can be liquidated. No strategy or automation system can guarantee profit. See [DISCLAIMER.md](DISCLAIMER.md).

What This Bot Does

  • Connects to your Hyperliquid account
  • Monitors markets using technical indicators (EMA, RSI, ATR)
  • Opens perpetual futures positions under strict risk rules
  • Attaches take-profit and stop-loss exits to every position
  • Manages trailing stops, time stops, and breakeven logic
  • Reconciles bot state with live exchange state
  • Provides paper trading, testnet, and live modes with progressive safety gates

What This Bot Does NOT Do

  • Guarantee profits - No bot, strategy, or system can guarantee profits
  • Eliminate risk - Leveraged trading carries inherent liquidation risk
  • Touch your wallet keys - Uses only a dedicated API/agent wallet
  • Transfer, withdraw, or bridge funds - These actions are explicitly forbidden
  • Run as a browser extension - It's a standalone local bot

How Your Wallet Maps to Hyperliquid

Hyperliquid perpetual futures are held on the Ethereum address in your wallet (Phantom, MetaMask, Rabby, or any wallet you use on Hyperliquid). This bot is not affiliated with any wallet provider.

1. Open your wallet and find your Ethereum address (the public 0x address)

2. This is your HYPERLIQUID_ACCOUNT_ADDRESS - it's public, not a secret

3. Create an API/agent wallet on Hyperliquid (see below)

4. The agent wallet private key is your HYPERLIQUID_API_WALLET_PRIVATE_KEY

Creating a Hyperliquid API/Agent Wallet

1. Go to [app.hyperliquid.xyz](https://app.hyperliquid.xyz)

2. Connect with the same wallet that holds your perps

3. Navigate to API wallet settings

4. Create a new API wallet and save the private key securely

5. The API wallet can only trade - it cannot withdraw or transfer funds

Never paste your wallet's Secret Recovery Phrase anywhere in this bot.

Installation


# Unzip the downloaded package, then from inside the folder:
cd nesto-perps-bot
python -m venv .venv
source .venv/bin/activate
pip install -e ".[dev]"
perps-bot init   # interactive setup wizard -> writes your .env

Prefer to configure manually? Copy .env.example to .env and edit it instead of running perps-bot init.

Running Paper Mode (No Keys Needed)


perps-bot doctor --mode paper

*... continues with setup instructions, usage examples, and more.*

📄 Code Sample .py preview

src/perps_bot/alerting.py """Alerting system with console implementation and Telegram/Discord stubs.""" from __future__ import annotations import logging from typing import Any, Optional from perps_bot.config import AlertsConfig from perps_bot.redact import redact_hex logger = logging.getLogger("perps_bot.alerts") class AlertManager: """Manages alert dispatch to configured channels.""" def __init__(self, config: AlertsConfig) -> None: self._config = config def info(self, event_type: str, **kwargs: Any) -> None: """Send an informational alert.""" msg = self._format(event_type, kwargs) if self._config.console: logger.info(msg) if self._config.telegram: self._send_telegram(msg) if self._config.discord: self._send_discord(msg) def warning(self, event_type: str, **kwargs: Any) -> None: msg = self._format(event_type, kwargs) if self._config.console: logger.warning(msg) if self._config.telegram: self._send_telegram(msg) if self._config.discord: self._send_discord(msg) def error(self, event_type: str, **kwargs: Any) -> None: msg = self._format(event_type, kwargs) if self._config.console: logger.error(msg) if self._config.telegram: self._send_telegram(msg) if self._config.discord: self._send_discord(msg) def _format(self, event_type: str, data: dict[str, Any]) -> str: parts = [f"[{event_type}]"] for k, v in data.items(): # ... 13 more lines ...
Buy Now — $99 Back to Products