This is a domain-driven design idiomatic Rust implementation of a Hyperliquid liquidation keeper bot for real-time liquidation monitoring of Hyperliquid perpetual futures implemented with Claude Code. This keeper monitors positions, detects liquidation risks, calculates order placement factors, and emits structured alerts for downstream analysis.
This system watches user positions via WebSocket, calculates precise liquidation metrics using Hyperliquid's exact formulas, and generates alerts when positions approach liquidation thresholds. It includes advanced risk detection for cascade liquidations and coordinated market manipulation (Jelly attacks).
- Real-time Position Monitoring: WebSocket connection to Hyperliquid with automatic reconnection
- Precise Liquidation Calculations: Implements Hyperliquid's exact margin formulas with
Decimalprecision - 15 Order Placement Factors: Comprehensive risk analysis including slippage, liquidity depth, cascade probability, and pool health
- Multi-tier Alert System: 6 severity levels from INFO to JELLY_ATTACK
- Jelly Attack Detection: Identifies coordinated market manipulation attempts (4 risk factors scoring 0-100)
- JSONL Persistence: Structured alert logging for analysis and visualization
- Python TUI Integration: Real-time dashboard displaying alerts and factor metrics
- see ARCHITECTURE.md
- Rust 1.75+ (specified in
rust-toolchain.toml) - Hyperliquid API access (testnet or mainnet)
- Clone the repository:
git clone <repository-url>
cd hyperliquid_liquidation_bot- Copy configuration template:
cp config.toml.example config.toml- Configure settings in
config.toml:
[network]
testnet = true # Set to false for mainnet
[monitoring]
user_address = "0xYourWalletAddress"
asset = "BTC" # Asset to monitor
[alerts]
thresholds = [
{ distance_pct = 15.0, severity = "WARNING", cooldown_seconds = 180 },
{ distance_pct = 5.0, severity = "CRITICAL", cooldown_seconds = 60 }
]- Build and run:
# Build
cargo build --release
# Run
cargo run --release --bin keeperOverride config via environment variables:
# Network settings
HYPERLIQUID_NETWORK_TESTNET=false
# Monitoring settings
HYPERLIQUID_MONITORING_USER_ADDRESS=0x123...
HYPERLIQUID_MONITORING_ASSET=ETH
# Run with overrides
cargo run --bin keeperA real-time terminal UI for monitoring alerts:
- Live alerts table with vim-style navigation (j/k)
- Severity filtering (a: all, i: INFO, w: WARNING, c: CRITICAL)
- 15-factor monitoring dashboard with color-coded risk levels
- Alert details panel with position info
- Statistics summary (min/max/avg distance, alerts per hour)
Launch the Python TUI to visualize alerts generated by integration tests:
cd python
python -m tui.main
# With options
python3 main.py --filter critical # Start with CRITICAL filter
python3 main.py --refresh-rate 10 # 10Hz display refresh
python3 main.py --no-watch # Historical view onlyThe TUI displays 15 real-time factors across 4 categories that influence order placement decisions: The keeper implements a risk-adjusted order placement strategy that uses the 15 calculated factors to make intelligent liquidation decisions.
Note: For MVP, fill tracking uses existing position monitoring (not real-time order tracking).
- Slippage Estimate %: Expected price impact of order execution
- Liquidity @ 1%: Available liquidity within 1% of mark price
- Liquidity @ 5%: Available liquidity within 5% of mark price
- Bid/Ask Imbalance: Order book imbalance (positive = bid-heavy, negative = ask-heavy)
- Liquidity Drainage %: Percentage of pool liquidity that would be consumed
- Cascade Probability: Risk score for liquidation cascade event (0-100)
- Jelly Attack Score: Risk score for coordinated market manipulation (0-100, ≥75 = CRITICAL)
- Whale Position: Whether position size qualifies as whale (>20% of pool liquidity)
- Liquidation Price: Price level at which position would be liquidated
- Distance to Liquidation %: Current distance from liquidation price
- Maintenance Margin: Required margin to maintain position
- Liquidation Stage: Current liquidation state (NONE/BOOK/BACKSTOP)
- Realistic Vault Profit: Expected profit from vault liquidation execution
- Liquidity Crisis: Boolean indicating if pool is in liquidity crisis
The Strategy Decision panel displays automated trading recommendations:
- EXECUTE (red): Position is at liquidation risk, execute closing order immediately
- WAIT (yellow): Position approaching risk zone, monitor closely but don't execute yet
- HOLD (green): Position is healthy, maintain current state
- SKIP (gray): Order execution not recommended despite alert
Each factor is compared against configured thresholds from config.toml:
- Green ✓: Factor value is within safe range
- Red ✗: Factor value has violated threshold
Example:
Factor Actual Threshold ✓
Slippage 0.35% <2.0% ✓ (safe)
Drainage 45.5% <60% ✓ (safe)
Distance 4.02% >5% ✗ (violated - too close to liquidation)
Vault Profit $100 >$500 ✗ (violated - insufficient profit)
Cascade 65 <60 ✗ (violated - high cascade risk)
Thresholds are loaded from config.toml:
[strategy]
max_slippage_pct = 2.0 # Maximum acceptable slippage
min_profit_threshold = 500.0 # Minimum vault profit required
[[alert_thresholds]]
severity = "CRITICAL"
distance_pct = 5.0 # Critical distance threshold
cooldown_seconds = 60
[[alert_thresholds]]
severity = "WARNING"
distance_pct = 10.0 # Warning distance threshold
cooldown_seconds = 120The keeper supports three execution modes: monitor (log only), paper (simulated), and live (real trading).
Live trading mode will execute REAL orders with REAL funds on Hyperliquid:
- Start with testnet to validate functionality
- Use monitor or paper modes for testing strategy logic
- Ensure safety rails are properly configured before enabling live mode
- NEVER commit private keys to version control
- All live orders are subject to strategy decision logic and safety rails
Live trading requires a wallet private key:
# REQUIRED for live trading mode
export HYPERLIQUID_PRIVATE_KEY="0x..."
# Optional: Network selection (defaults from config.toml)
export HYPERLIQUID_NETWORK_TESTNET=false # Use mainnet
export HYPERLIQUID_NETWORK_TESTNET=true # Use testnetEnable live trading in config.toml:
[strategy]
# Execution mode: "monitor" (no orders), "paper" (simulated), "live" (REAL TRADING)
execution_mode = "live" # ⚠️ Enables real order placement# Run mock integration tests (uses mockito for API simulation)
cargo test --test live_trading_mock_test -- --nocaptureFull Strategy Integration Test (Recommended):
# Set testnet wallet private key
export HYPERLIQUID_PRIVATE_KEY="0x..."
# Run complete strategy test with factor calculation, decision logic, and live order execution
cargo test --test live_strategy_testnet_test -- --ignored --nocaptureThis test demonstrates the complete flow:
- Creates realistic near-liquidation position (0.1 BTC at 20x leverage, -1.63% distance)
- Calculates all 15 order placement factors
- Runs strategy decision logic (profit/risk analysis)
- Executes safety rails checks
- Submits live order to Hyperliquid testnet
- Logs order result to
./data/orders.jsonl
Basic Order Submission Test:
# Run basic testnet integration test (submits REAL order to testnet)
cargo test --test live_trading_testnet_test -- --ignored --nocaptureTestnet Requirements:
- Testnet wallet with funds (get from Hyperliquid Discord)
- Set
testnet = truein config.toml orHYPERLIQUID_NETWORK_TESTNET=true - Check orders at: https://app.hyperliquid-testnet.xyz/
See LIVE_TRADING_FIXES.md for detailed implementation notes and troubleshooting.
# Set private key
export HYPERLIQUID_PRIVATE_KEY="0x..."
# Configure live mode in config.toml
# [strategy]
# execution_mode = "live"
# Run keeper
cargo run --release --bin keeperExpected Log Output:
INFO hyperliquid_keeper: Live trading enabled - loading wallet from environment
INFO hyperliquid_keeper: Order executor initialized in Live mode
INFO hyperliquid_keeper::infrastructure::order_executor: Submitting live order to Hyperliquid
All order attempts (success and failure) are logged to ./data/orders.jsonl:
{
"timestamp": "2025-12-10T...",
"asset": "BTC",
"side": "SELL",
"requested_size": "0.5",
"filled_size": "0.5",
"average_price": "89000.0",
"status": "PENDING",
"order_id": "123456789",
"client_order_id": "keeper_1733875200",
"error": null,
"slippage_pct": null
}The strategy evaluates positions through multiple phases:
Phase 1: Abort Conditions (hard stops)
- Jelly attack score ≥ 75
- Liquidity crisis (>60% pool drainage)
- Extreme cascade probability (>80)
Phase 2: Delay Conditions (temporary holds)
- Oracle deviation > 1.5%
- Extreme bid/ask imbalance (>60%)
Phase 3: Profit Justification
- Vault profit must exceed
min_profit_threshold
Phase 4: Order Parameters Calculation
- Size: Adjusted for slippage, liquidity, cascade risk, whale detection
- Type: Market (< 1% distance), IOC (1-5%), Limit (> 5%)
- Price: Profit-based slippage tolerance (0.3% per $1K profit)
Error: "Wallet not configured for live trading"
- Ensure
HYPERLIQUID_PRIVATE_KEYenvironment variable is set - Verify private key format starts with
0x - Check that
execution_mode = "live"in config.toml
Error: "Failed to sign order"
- Invalid private key format
- Private key doesn't match expected format for ethers-rs
Error: "Submission error: 400 Bad Request"
- Insufficient balance in wallet
- Invalid order parameters (size, price, asset)
- Check API response in logs for details
Orders not appearing:
- Check
./data/orders.jsonlfor logged order attempts - Verify network settings (testnet vs mainnet)
- Ensure safety rails aren't blocking orders (check daily loss limits, position size limits)
The project includes comprehensive integration tests for all 15 order placement factors:
# Run all integration tests
cargo test --test '*'
# Run all factor integration tests (writes to ./data/alerts.jsonl)
cargo test --test order_placement_factors_test -- --nocapture
# Run Jelly attack tests
cargo test --test jelly_attack_integration_test -- --nocaptureRun specific factor tests by category (all write to ./data/alerts.jsonl):
Slippage & Liquidity Factors (5 tests):
# Test 1: Slippage estimate - low (small position in deep pool)
cargo test test_factor_slippage_estimate_low -- --nocapture
# Test 2: Slippage estimate - high (large position in shallow pool)
cargo test test_factor_slippage_estimate_high -- --nocapture
# Test 3: Liquidity depth at 1% from mid price
cargo test test_factor_liquidity_at_1pct -- --nocapture
# Test 4: Bid/ask imbalance detection (bid-heavy market)
cargo test test_factor_bid_ask_imbalance_bid_heavy -- --nocapture
# Test 5: Liquidity drainage (critical 70% drain)
cargo test test_factor_liquidity_drainage_critical -- --nocaptureRisk Score Factors (3 tests):
# Test 6: Cascade probability (high risk)
cargo test test_factor_cascade_probability_high -- --nocapture
# Test 7: Jelly attack score (critical score ≥75)
cargo test test_factor_jelly_attack_score_critical -- --nocapture
# Test 8: Whale position detection (>15% of pool)
cargo test test_factor_whale_position_detection -- --nocaptureMargin Metrics Factors (5 tests):
# Test 9: Liquidation price calculation accuracy
cargo test test_factor_liquidation_price_accuracy -- --nocapture
# Test 10: Distance to liquidation (WARNING threshold)
cargo test test_factor_distance_to_liquidation_warning -- --nocapture
# Test 11: Maintenance margin calculation
cargo test test_factor_maintenance_margin_calculation -- --nocapture
# Test 12: Liquidation stage detection (BOOK/BACKSTOP)
cargo test test_factor_liquidation_stage_detection -- --nocapture
# Test 13: Realistic vault profit calculation
cargo test test_factor_realistic_vault_profit -- --nocapturePool Health Factors (3 tests):
# Test 14: Total open interest tracking
cargo test test_factor_total_open_interest -- --nocapture
# Test 15: Oracle deviation - normal (<0.5%)
cargo test test_factor_oracle_deviation_normal -- --nocapture
# Test 16: Oracle deviation - high (>1.5%)
cargo test test_factor_oracle_deviation_high -- --nocapture
# Test 17: Liquidity crisis flag (>60% drainage)
cargo test test_factor_liquidity_crisis_flag -- --nocaptureNote: All integration tests write alerts with factor snapshots to ./data/alerts.jsonl for inspection with the Python TUI.
Alerts written to data/alerts.jsonl.
cd python/tui
python3 main.py --file ../../data/alerts.jsonlIt is not possible to track real-time liquidations using neither the Hyperliquid DEX Python or Rust WebSocket SDK. The SDK filters out the liquidation field.
One choice is to use block level fill data. This requires launching a HyperLiquid L1 node and parsing block fills with liquidation flags. The setup and expense (space) required and complexity of decompiling block data is beyond the scope of this MVP.
The other choice was to use the gRPC StreamBlockFills interface from Dwellir (https://www.dwellir.com/networks/hyperliquid) which does have real-time liquidations tracking. I spoke to Ben (@ben_dwellir on Telegram) who agreed to a trial license for the duration of this test. Unfortunatly, Dwellir does not support the Hyperliquid testnet (and has no plans to).
Other choices existed, including building a watchlist of users (from trades or known addresses) and calculate margin ratios in real-time or by polling the clearingHouseState or subAccounts endstate every 5 seconds, or so. For the purpose of this MVP, the choice was made to support polling a single user for state changes.
The crux is the execution strategy looks at a single account's book for executions against liquidations. The liquidation bot does, however, simulate liquidations using a mock objects integration testing interface which supplies sufficient data to cover all factors that could affect execution strategy.
It is not possible to force liquidations of live positions neither through margin withdrawls or position size increases. Therefore the choice was made to simulate trade states by simulating liquidation states with alerts on paper trades with simulated full strategy factor calculations, including the following:
Factor → Order Parameter Influence
| Factor | Influences | Primary Effect |
|---|---|---|
| slippage_estimate_pct | SIZE | Split into more orders if high |
| liquidity_1pct/5pct | SIZE | Cap orders at % of depth |
| bid_ask_imbalance | PRICE, TIMING | Adjust limits, wait if extreme |
| liquidity_drainage_pct | SIZE | Reduce by 50-90% if high |
| cascade_probability | SIZE, TIMING | Reduce size, delay if critical |
| jelly_attack_score | ABORT | No orders if ≥75 |
| is_whale_position | TIMING | Spread over 30-60 minutes |
| liquidation_price | PRICE | Reference for limit orders |
| distance_to_liquidation_pct | TIMING, ORDER TYPE | Market vs limit, urgency |
| maintenance_margin | SIZE | Profit opportunity sizing |
| liquidation_stage | TIMING | Execution trigger |
| realistic_vault_profit | PRICE | Slippage tolerance |
| total_open_interest | SIZE | Reduce in crowded pools |
| oracle_deviation_pct | TIMING, PRICE | Halt if >1.5% |
| has_liquidity_crisis | ABORT/SIZE | Emergency 10% sizing |
The majority of the implementation effort consisted of strategy determination. Several important features were left out.
- Add more robust failure modes handling
- Order retry logic on failure
- Order timeout auto cancellation (or manual cancellation via UI)
- Pre-submission wallet balance validation
- Retry logic with exponential backoff
- Real-time fill tracking using WebSockets
- Safety rails: max position size, daily loss limits, manual override
- Handle partial fills
- Partial fills lead to incomplete liquidation executions where orders achieve only partial fill rates, leaving positions under-hedged and strategy objectives unmet.
- detect partial fills from API responses
- Automatically retry remaining size with exponential backoff
- Aggregate results across multiple attempts
- Enforce abandonment criteria
- Handle competing flows
- The risk of multiple competing keeper liquidation executions occurring simultaneously
- Position validator to detect if another keeper already liquidated
- Network optimization with connection pooling
- Parallel alert processing
- Abandonment strategy
- Race metrics tracking (win/loss/abandoned)
- Competition landscape visualization
- Strategy Metrics
- Performance metrics (latency, fill rate, slippage)
- Backtest against historical liquidation events
- Additional enhancements
- Multiple wallet support
- Multiple asset support
- Advanced EIP-712 typed data implementation matching Hyperliquid spec exactly
