Crypto Trading Agent - Progress - Nov 30th
Wrestling with Connections and Consistency: Fixing Trader-7’s Critical Bugs
TL;DR: Spent the day squashing three nasty bugs that were tripping up Trader-7’s trading cycles — stale database connections killing later cycles, capital preservation checks that never ran, and conflicting ADX thresholds that caused valid trades to be rejected. The bot’s feeling a lot more reliable now.
Today was one of those days where a few subtle bugs piled up and really started to mess with the smooth running of Trader-7. After some digging and head-scratching, I managed to get to the bottom of things and patch them up. It wasn’t fun, but it was definitely satisfying.
What Went Down
First off, I tackled the database connection issue. Trader-7 sleeps for an hour between trading cycles, but SQLite connections don’t like sitting idle that long — they go stale and close unexpectedly. Originally, my reconnect method just created a brand new connection object, but some parts of the code (like the TradeFrequencyLimiter) were still holding on to old references with dead connections. This meant that from cycle 2 onwards, all proposals would fail because the bot couldn’t query the database properly.
The fix was to add smarter reconnect logic directly inside the existing database connection object. Now, before each cycle, the bot proactively checks if the connection is alive and reconnects if needed — all while keeping references intact. I also made it so that if any query hits a stale connection error mid-cycle, the bot will try reconnecting and retrying automatically. This took about an hour to track down and implement but feels rock solid now.
Next, I looked at the capital preservation logic. Oddly enough, the bot was supposed to check if there were existing open positions before entering new trades — a crucial safety measure — but that check was never actually running. Turns out, the method get_open_positions() was being called on the wrong object (self.db instead of self.db.trades), so it always returned an empty list. This was a simple fix, but took around 30 minutes to trace through the logs and make sense of the call hierarchy. Lesson learned: using type hints and better IDE autocomplete would have caught this earlier.
Finally, I hunted down an inconsistency with the ADX threshold used to classify market regimes. On November 26, I lowered the ADX threshold from 25 to 20 in one core file (regime_detector.py), but forgot to update six other files that still used 25. This mismatch meant the bot’s regime detector would call a market “trending,” but other parts would reject the same instrument as “choppy,” leading to valid trades being blocked. I aligned all the threshold constants to 20 (and 15 for some cases) across the codebase — about 45 minutes of auditing and refactoring. Definitely putting these constants in a single config file next time!
Behind the Scenes: Some Technical Bits
- Database reconnect logic now includes
_check_connection()to ping the connection andreconnect()to reset it without creating new objects. - Replaced all deprecated Streamlit calls for container width (switched from
use_container_width=Truetowidth='stretch'). - Fixed the rules validator where
MIN_TREND_STRENGTHwas compared against 0.7 but ADX values run from 0–100, effectively disabling the filter. - Added a new environment variable
MIN_HOURS_BETWEEN_TRADESfor more granular cooldown control between trades in hourly cycles.
What’s Next?
Over the next few days, I’ll be closely monitoring the bot through multiple trading cycles to make sure:
- The database auto-reconnect logic truly keeps connections alive without hiccups.
- Capital preservation kicks in properly when open positions exist.
- The ADX threshold alignment actually improves the number of valid trades approved.
This kind of bug hunt isn’t glamorous, but it’s the kind of careful plumbing that keeps Trader-7 humming along reliably. Onward and upward!
Generated from progress.md on 2025-11-30 at 19:30