Insider series·2026-05-04·7 min read·← all posts

The timeout bug — why three user positions hung 33 hours

A subscriber asked a simple question: "why are these positions on Binance still open after two days?". The strategy spec defined a max hold time well below that. The positions had been open 33 hours. The honest post-mortem on the bug, the fix, and what it cost us in trust.

The discovery

Three long positions on a subscriber's account, opened in the same morning window. Strategy spec defined a maximum hold time, then close at market regardless of P&L (because the underlying thesis decays after that point).

The customer noticed the positions still showing on Binance at hour 33. They opened the conversation by saying "why are these still open?". That's the exact moment a quant firm earns or loses a customer. If we'd been the kind of shop that hand-waves and blames Binance, we would have been a different shop. We dug in.

The mechanism

Execution flow when a signal fires:

  1. Detector emits a signal with coin, score, side, suggested entry
  2. Executor fans out to (a) firm account, (b) all Pro subscribers with that strategy enabled
  3. For each fanout target, place market entry + emergency SL on Binance
  4. Register the position with positionMonitor for the strategy-specific timeout

Step 4 is where the bug lived. The executor handled firm and user trades on different code paths — firm trades got a positionMonitor registration; user trades just marked status=filled. No timeout registration for user accounts. Binance held the SL order, but if price never reached SL or any TP, the position would just sit there indefinitely.

How it survived to production

The original code path was firm-only. When we added per-user execution two months ago, we forked the code path but didn't propagate the timeout-registration logic. The unit tests we wrote for per-user execution covered "did the order place correctly" and "did the SL register on Binance" — but not "does the strategy-spec timeout fire" because that kind of test takes hours to run, and we relied on the firm-side production behavior as our safety net.

Firm-side production never showed the bug because firm positions always closed via SL or TP within hours, by chance. The first time conditions lined up to keep a position alive past the spec'd timeout was on a user account, which had no timeout registration, on a market day where price stayed in a range that didn't trigger SL or TP.

The fix

Added a per-strategy hold-hours map in userPositionGuard.js with a per-tick force-close check. Deployed within 20 minutes of the customer report. The userPositionGuard polls every 60 seconds, so the next tick caught all three stuck positions and closed them at market. Net P&L across the three: roughly flat. The lesson cost was symbolic.

The real cost

The dollar P&L barely moved. The trust cost was real. A subscriber paying for a system that promises a defined max hold deserves a system that honors that hold, not one that drifts to 33 hours. We told the customer exactly what happened, deployed the fix while they were still on the line, and showed them the closed records with computed PnL the moment they appeared.

The customer kept their subscription. That's the right outcome only because we caught it within hours of the report. If the same bug had hit during a market crash and a position rode through a -25% drop because no timeout fired, the conversation would have been different.

What we changed beyond the fix

Two operational improvements:

Why we publish this

The firm-vs-user-execution-parity bug is exactly the kind of thing other crypto-bot operators would hide. Most platforms run on closed-source code, opaque P&L attribution, and "trust us, the system works as advertised". When something goes wrong, customers eat it.

We'd rather publish the bug, the fix, and the lesson. If you're considering Hedonist Pro: this is what the operations look like from the inside. Bugs happen. We catch them, fix them publicly, and improve the test surface so the same class of bug doesn't recur. That's the standard.

Production-grade execution, with the receipts

Hedonist Pro auto-executes our four signal algorithms on your Binance account. Same engine, same code paths, post-mortemed in public when things go wrong.

See Pro pricing →