When "closed" doesn't mean closed: a Hyperliquid stop-loss post-mortem

When "closed" doesn't mean closed: a Hyperliquid stop-loss post-mortem A trading bot logged "Stop-loss triggered" every 5 minutes for 36 hours. The position was never closed. Here's what went wrong...

By · · 1 min read
When "closed" doesn't mean closed: a Hyperliquid stop-loss post-mortem

Source: DEV Community

When "closed" doesn't mean closed: a Hyperliquid stop-loss post-mortem A trading bot logged "Stop-loss triggered" every 5 minutes for 36 hours. The position was never closed. Here's what went wrong and how to prevent it. What happened The Hyperliquid short bot had a configured stop-loss. ETH moved against the position and breached the threshold. The bot logged: Closing position. Reason: Stop-loss triggered (-15.2%) And then logged it again. And again. Every 5 minutes, for 36+ hours. The position was never actually closed. By the time the failure was caught manually — via direct log inspection — the unrealized loss had grown from the configured -15% to approximately -25%. The position was closed manually. Total capital lost: roughly 85% of the initial collateral instead of the intended 15%. Root cause: three bugs stacked Bug 1 — The close function swallowed exceptions silently def close_position(exchange, reason): try: result = exchange.market_close("ETH", None, slippage) return result