perp-bot is a Python CLI for running a Hyperliquid perpetual futures mean-reversion bot, collecting market data, backtesting the strategy, and monitoring a live daemon from a terminal UI.
This repository is structured as an installable package with a perpbot console command, SQLite-backed local state, and separate modules for data ingestion, signals, execution, risk, reporting, IPC, and the Textual TUI.
- Package name:
perp-bot - CLI entry point:
perpbot - Python requirement:
>=3.12 - Current release:
0.1.3 - Maturity: alpha
- Backfills OHLCV candles and funding history from Hyperliquid into SQLite
- Polls prediction markets and stores regime signals alongside market data
- Runs a paper or live trading loop with risk controls and health checks
- Exposes daemon state over a Unix socket for
statusandtui - Backtests the strategy with fees, slippage, funding, and execution delay
- Produces comparison and weekly review reports from stored trades
curl -fsSL https://raw.githubusercontent.com/morfize/perp-bot/main/scripts/install.sh | shThis installs a prebuilt standalone binary to ~/.local/bin/perpbot.
perpbot --helpcp .env.example .envFor paper trading, you can leave the Hyperliquid key empty.
The repository ships with a starter config.yaml. By default, perpbot reads:
config.yamlfrom the current working directory.envfrom the current working directory
If you pass --config /path/to/config.yaml, the CLI also loads .env from that config file's directory.
perpbot backfillperpbot backtestperpbot tradeIn another terminal, you can inspect the daemon:
perpbot status
perpbot tuicurl -fsSL https://raw.githubusercontent.com/morfize/perp-bot/main/scripts/install.sh | shThis downloads the latest GitHub release binary for your OS and installs it to ~/.local/bin/perpbot.
curl -fsSL https://raw.githubusercontent.com/morfize/perp-bot/main/scripts/install.sh | env PERPBOT_VERSION=v0.1.3 shuv sync --group dev
source .venv/bin/activate
perpbot --helpRepo-local execution still works, but this is not the primary install path:
./perpbot --help
./main.py --help
python3 main.py --helpThe main config file is config.yaml. Top-level sections are:
tradingsignalsriskdataexecutionpredictionbacktestmode
Important defaults in the sample config:
- symbol universe starts with
["ETH"] - primary timeframe is
15m - database path is
perp_bot.db - mode defaults to
paper
Secrets and alert integrations are read from .env:
HL_PRIVATE_KEYHL_WALLET_ADDRESSDISCORD_WEBHOOK_URLTELEGRAM_BOT_TOKENTELEGRAM_CHAT_ID
Use .env.example as the starting template.
To enable live execution:
- Set
mode: "live"inconfig.yaml - Provide
HL_PRIVATE_KEYin.env - Optionally provide
HL_WALLET_ADDRESSif you do not want to rely on key-derived address detection
Live mode sets leverage on startup, reconciles exchange positions against the local database, and attempts to attach a server-side stop-loss to each new position.
| Command | Purpose |
|---|---|
perpbot backfill |
Backfill historical candles and funding into SQLite |
perpbot trade |
Start the main paper/live trading loop |
perpbot trade --force |
Override the consecutive losing-weeks startup halt |
perpbot backfill-predictions |
Fetch current prediction market snapshots |
perpbot backtest |
Run a full backtest over stored market data |
perpbot walkforward |
Run walk-forward analysis |
perpbot sensitivity |
Run parameter sensitivity analysis |
perpbot screen |
Screen markets for mean-reversion suitability |
perpbot review --weeks 1 |
Generate a weekly performance review |
perpbot compare --days 7 |
Compare paper trading against backtest results |
perpbot status |
Print daemon state as JSON |
perpbot tui |
Launch the Textual monitoring dashboard |
Run the global help for all flags:
perpbot --helpThe main runtime pieces are:
perp_bot.data: Hyperliquid REST/WebSocket access and SQLite persistenceperp_bot.signals: indicator calculations and signal evaluationperp_bot.risk: pre-entry checks, stop-loss logic, cooldowns, and sizingperp_bot.execution: paper executor and Hyperliquid live executorperp_bot.backtest: historical simulation, cost model, metrics, walk-forward, sensitivityperp_bot.ipc: Unix socket server/client and daemon state modelperp_bot.tui: Textual dashboard for monitoring and emergency actionsperp_bot.reporting: weekly reports and paper-vs-backtest comparisonperp_bot.infra: logging, alerts, and health checks
At a high level:
backfillstores candles and funding in SQLite.tradeupdates candles, computes indicators, checks risk, then opens/closes positions.- The trading daemon publishes volatile runtime state over a Unix socket.
statusandtuiattach to that socket while reading persistent trade data from SQLite.backtestreuses the same signal and risk logic against historical data.
.
├── src/perp_bot/
│ ├── backtest/
│ ├── data/
│ ├── execution/
│ ├── infra/
│ ├── ipc/
│ ├── reporting/
│ ├── risk/
│ ├── signals/
│ └── tui/
├── tests/
├── deploy/
├── docs/
├── config.yaml
├── .env.example
└── pyproject.toml
- Documentation index
- Architecture
- Configuration reference
- Development workflow
- Operations and deployment
uv sync --group dev
uv run ruff check src tests
uv run pytest
uv run pytest --cov=src/perp_bot --cov-report=term-missing
uv build
./scripts/build-release-archive.sh perpbot-macos-arm64.tar.gzGitHub Actions runs:
- lint on
srcandtests - test suite on Python
3.12and3.13 - Python package build validation
- standalone binary build validation
The repository includes:
deploy/deploy.shfor pushing the repo to a GCP Compute Engine instancedeploy/perp-bot.servicefor systemd
The service expects the app at /opt/perp-bot and starts:
/opt/perp-bot/.venv/bin/perpbot trade- This is trading software. Review the code, config, and exchange behavior before enabling live mode.
- The project includes capital-based stop-losses, daily loss limits, cooldowns, and a losing-weeks startup halt, but those controls do not eliminate market, exchange, or software risk.
- The software is not financial advice.