Advertisement

The Bot That Lied: How V3.7's Status Reporter Was Hiding Eight Open Positions

There’s a particular kind of dread that comes with looking at your trading bot’s status report and seeing “all clear” — and then realising the report is wrong.

That’s exactly what happened with Krypto’s V3.7 DCA grid bot earlier this week. The hourly status reporter was confidently displaying:

0 filled | 0 pending (all grid levels idle)

The problem? The bot wasn’t idle. It had 8 open DCA buy positions and an orphan sell order sitting live in the market. The reporter just wasn’t looking at them.

What V3.7’s DCA Grid Does

Krypto’s V3.7 strategy is a Dollar-Cost Averaging grid for BTC. When market conditions are right, it places a series of staged buy orders at descending price levels — buying more as the price dips. The idea is to accumulate at a lower average entry price, then exit the whole position when the market recovers.

At the time the bug was discovered, V3.7 had accumulated 8 DCA fills with an average entry of $76,831 — a total of 0.00517 BTC in live exposure. On top of that, there was an orphan sell order sitting at $79,632 for a separate 0.00997 BTC position that hadn’t been cleaned up.

That’s real exposure. Real capital. And the system reporting on it was pointing at empty data.

The Blind Spot: A Wrong State Key

The root cause was a simple but consequential mistake in bot_status_reporter.py. When V3.7 was built, it stored its open positions under a state key called dca_positions — which makes sense, it’s a DCA strategy. But the status reporter was reading from positions, a key that’s used by the older grid strategies and is always empty in V3.7’s state.

The reporter dutifully read positions, found nothing, and reported “all grid levels idle.” It wasn’t wrong per se — it was just looking in the wrong drawer.

The second issue was the sell-side. Even if the reporter had been reading the right position key, it wasn’t checking sell-side live_orders — so open sell orders were completely invisible, regardless of strategy version.

Two separate gaps, both in the same file. Neither was dangerous on its own, but together they made the bot effectively invisible to monitoring.

Why This Matters

Status reporting isn’t just a convenience feature — it’s your early-warning system. When a DCA strategy is accumulating positions in a falling market, you need to know: how deep is the exposure? What’s the average entry? Is there a stale sell order that needs attention?

If your reporter is telling you the bot is idle while it’s actively managing live positions, you lose the ability to make informed decisions. You might not notice if a position has grown beyond your risk tolerance. You might miss an orphan sell that’s blocking capital. In a fast-moving market, that’s the kind of gap that costs real money.

This particular bug was caught by Delmar during a manual check — not by the reporter itself. That’s a useful reminder: automated reporting is only as good as what it’s actually measuring.

The Fix

Closing the blind spot required two PRs — and the distinction matters.

CoinClaw PR #1261 was the first fix: it updated bots/bot_status_reporter.py (the module-level copy) to read dca_positions instead of positions, and to render sell-side live_orders. That addressed the logic correctly, but it targeted the wrong file.

The actual Slack reporter the system runs lives at the repository root — bot_status_reporter.py — a separate copy that wasn’t touched by PR #1261. Which meant the bot was still reporting blind in production.

CoinClaw PR #1263 is the complete fix. Merged on 2026-05-01 (squash commit ae97e9f), it applies the same corrections to the root-level reporter: reads dca_positions for V3.7 state, and surfaces open sell-side live_orders. After this fix, the next hourly Slack report correctly showed the full picture:

📊 Open Positions: 8 filled | 0 pending limit orders | 1 sell order
   • DCA fills: avg entry $76,831 | 0.00517 BTC total
   • Orphan sell @ $79,632 (0.00997 BTC)

32 tests (27 existing + 5 new) pass against the updated reporter logic, covering both the DCA position display and sell-order rendering. The blind spot is now fully closed — both copies of the reporter are in sync.

The Takeaway for Traders

If you’re running a custom or automated strategy, the status layer deserves the same scrutiny as the trading logic itself. A bot that executes correctly but reports incorrectly is almost as dangerous as one that trades wrong — because it removes your ability to see what’s happening and respond.

V3.7’s DCA grid is working as intended. The blind spot is closed — both PR #1261 (module reporter) and PR #1263 (root-level Slack reporter) — and now the hourly reports actually mean something.

Advertisement