Guardian
Guardian watches any Hyperliquid address for liquidation risk, missing stop-losses, funding bleed and more — straight from the CLI. It is strictly read-only: it never places orders, and it works without a private key. Point it at any address you care about.
The same monitoring is available as a hosted dashboard at /markets/guardian; the CLI version runs on your own machine with your own Telegram bot, so nothing about your positions leaves your infrastructure. See Hosted vs CLI.
Requires OpenBroker 1.11.0+ (npm install -g openbroker@latest).
Quick start
openbroker guardian run # watch your configured account
openbroker guardian run --address 0xabc...,0xdef... # watch any addresses (no wallet needed)
openbroker guardian run --min-severity warning # only warnings and criticals
openbroker guardian run --disable position_lifecycle # mute open/close/resize chatterguardian run is a long-running foreground process: it seeds a snapshot, prints your open positions with liquidation distance, then keeps evaluating and printing alerts until you stop it with Ctrl+C. When exactly one address is watched, it also subscribes to the exchange WebSocket for instant liquidation alerts and fill-triggered re-checks.
OpenBroker Guardian — watching (read-only, Ctrl+C to stop)
Addresses: 0xc370...55df
Min severity: info
Channels: console, telegram
0xc370...55df: equity $18685.07, margin 22.6%
short 6.4967 ETH @ $1680.67 (5x, liq $4495.05, uPnL $-713.50)
short 18.3 SOL @ $71.0675 (5x, liq $1033.37, uPnL $-125.18)
[14:32:07] WARNING liq_proximity ETH — Liquidation risk on ETH: mark $4102.1 is 8.74% from liquidation price $4495.05 (short, 5x)Alert rules
Six rules, all enabled by default. Run openbroker guardian rules for the same table in the terminal.
| Rule | Fires | Severity |
|---|---|---|
| liq_proximity | Mark price within 10% / 5% / 2% of the liquidation price. Hysteresis re-arming and a 30-minute cooldown prevent alert spam while the position hovers near a threshold. | warning / critical |
| margin_usage | Margin used exceeds 80% of account equity. | warning |
| no_tpsl | A position has been open 15+ minutes with no reduce-only trigger orders protecting it ("trading naked"). | info |
| stale_order | A limit order has been resting 12+ hours and sits 3%+ away from the current mid. | info |
| funding_bleed | The position side is paying 15%+ annualized funding continuously for 60+ minutes. | warning |
| position_lifecycle | A position was opened, closed, or resized. | info |
Getting liquidated outright produces an immediate critical alert via the WebSocket fast lane. Alerts are suppressed whenever the price feed goes stale, so a network hiccup can't produce false alarms. HIP-3 positions (dex:COIN) are fully covered, including their per-dex order books for the no-TP/SL check.
Tuning thresholds
Every threshold is a flag on guardian run:
| Flag | Default | Meaning |
|---|---|---|
| --min-severity | info | Delivery floor: info, warning, or critical |
| --disable / --only | — | CSV of rules to mute, or to run exclusively |
| --liq-warn / --liq-critical | 10 / 5 | Liquidation-distance thresholds (% from liq price) |
| --margin-pct | 80 | Margin-usage warning threshold (% of equity) |
| --funding-apr | 15 | Funding-bleed APR threshold (%) |
| --tpsl-minutes | 15 | Minutes a position may sit unprotected before no_tpsl fires |
| --stale-hours | 12 | Hours a limit order may rest before stale_order fires |
| --poll | 30000 | Position poll cadence in ms (drops to 15s automatically near liquidation) |
Telegram alerts
The CLI guardian delivers to your own Telegram bot — your token, your chat, no third-party relay. One-time setup:
- Message @BotFather on Telegram, send
/newbot, and follow the prompts. Copy the bot token. - Add it to your OpenBroker config (
~/.openbroker/.env):
TELEGRAM_BOT_TOKEN=123456789:AAF...- Link your chat:
openbroker guardian connectThe CLI prints a https://t.me/your_bot?start=<code> deep link. Open it and tap START — the CLI captures the chat and saves TELEGRAM_CHAT_ID automatically. Verify with:
openbroker guardian test
openbroker guardian statusFrom then on, every guardian run delivers alerts to that chat (mute with --no-telegram). Use a dedicated bot for the guardian: the link flow long-polls the Telegram API, which conflicts with any other consumer of the same token.
Agents and JSON output
Two integration paths for agents:
JSON lines. --json turns each alert into one machine-readable line on stdout:
openbroker guardian run --json --min-severity warning{"time":1783701023456,"address":"0xc370...","rule":"liq_proximity","coin":"ETH","severity":"warning","message":"Liquidation risk on ETH: ...","payload":{"distancePct":8.74,"thresholdPct":10}}OpenClaw agent hook. If OPENCLAW_HOOKS_TOKEN (and optionally OPENCLAW_GATEWAY_PORT) is set, every alert also POSTs to the local agent gateway's /hooks/agent with wakeMode: "now" — the same channel the plugin's position watcher uses. The agent wakes with the alert text and can respond, e.g. by proposing openbroker tpsl --coin ETH --sl 5% --dry after a no_tpsl alert.
Guardian itself only observes. If you want automated enforcement — auto-attaching stops, de-risking on margin alerts — write an automation with explicit trading guardrails and let the guardian remain the independent watchdog.
Hosted vs CLI
| Hosted (/markets/guardian) | CLI (openbroker guardian) | |
|---|---|---|
| Runs on | Our infrastructure, 24/7 | Your machine, while the process runs |
| Telegram | Shared OpenBroker bot | Your own BotFather bot |
| Sign-in | Wallet + SIWE signature | None — just an address |
| Extras | Web dashboard, alert history, browser push | JSON output, agent hooks, threshold flags, library API |
Both run the same rules with the same default thresholds. Run both if you like — the hosted guardian covers you while your machine is off, the CLI guardian feeds your agents. Neither can touch your funds: both are address-only and read-only.
Library usage
Everything the command does is available in-process from the openbroker package:
import { startGuardian } from 'openbroker';
const guardian = await startGuardian({
addresses: ['0xabc...'],
prefs: { minSeverity: 'warning', rules: { position_lifecycle: false } },
thresholds: { fundingBleedAprPct: 25 },
quiet: true, // no console output
onAlert: (alert) => {
// route anywhere: your own notifier, a queue, an agent
console.log(alert.severity, alert.message);
},
});
// later
await guardian.stop();GuardianRiskEngine is also exported separately if you want to run the rule evaluation against your own data feed.