Crypto Trading Agent - Progress - 27 Nov 2025
Smarter Trades: How I Taught Trader-7 to Pick the Best Instruments
TL;DR:
Today I wrapped up a big feature to make Trader-7’s instrument selection truly strategic — no more blindly picking symbols in order or ignoring funding costs. Plus, I squashed a couple of annoying bugs that almost crashed the bot after running a few hours.
I’ve been neck-deep in Sprint 7c, building out Trader-7’s ability to choose which instrument to trade — spot or perpetual — on the fly, based on real-time funding rates and market signals. It sounds simple, but it turned out to be a surprisingly tricky problem that touches the heart of how the bot thinks about cost and risk.
The Problem: Dumb Instrument Selection
Before today, Trader-7 simply processed four hardcoded symbols in a fixed order:
- BTC/USD spot
- ETH/USD spot
- BTC-PERP
- ETH-PERP
Funding costs were all set to zero across the board. So the bot never factored in the real cost of holding a perpetual contract, which can be significant if funding rates spike. This meant it wasn’t making cost-efficient decisions — sometimes paying way more than needed, or missing out on the chance to earn funding when rates are negative.
What I Built: Strategic Instrument Selection
I wrote nearly 900 lines of code across four new components to fix this:
1. InstrumentSelector
This is the brains of the operation. It fetches live funding rates, predicts if those rates are anomalous and dampens spikes, and detects whether the market regime is bullish (leaning toward spot when funding is high). Then it decides:
- If funding is negative → pick perpetual (getting paid to hold!)
- If funding is too high → pick spot (avoid bleeding fees)
- Otherwise, balance based on expected hold time and market trend
2. HoldTimeEstimator
To estimate how long a position will be held, I combined several indicators — volatility, ADX trend strength, RSI extremes, and distance to take-profit levels. This helps predict the actual funding cost over the expected holding period.
3. InstrumentSelectionRepository
All decisions get logged here with reasons and estimated vs actual costs. This will let me analyze cost savings over time and tweak the logic.
4. Database Migration
A new table now tracks instrument selection history, so I can look back and understand what choices the bot made and why.
The Decision Logic — In a Nutshell
For each asset (BTC, ETH):
- Fetch current perpetual funding rate
- Estimate expected hold time
- Calculate cost of holding spot (zero) vs perpetual (funding rate × position size × hours held)
- Pick the instrument with the lowest expected cost, considering factors like high funding rate, negative funding, and hold duration
- Log everything for analysis
This shift from fixed, hardcoded processing to dynamic, cost-aware selection is a game changer for capital efficiency.
Bug Fixes That Saved My Day
While testing, the bot kept crashing after 4 hours — a showstopper. Turns out, this was due to a mismatch in the Pydantic model constraints for open positions. The environment variable allowed up to 5 open positions, but the model was set to max 3. That mismatch caused validation errors, crashing the bot.
A quick fix in two model files fixed that. I also realized the CoinbasePerpetualAdapter class was missing a crucial get_exchange_name() method which the base class had — a tiny slip but enough to break things.
These bugs were caught fast thanks to clear error logs from Railway, underscoring how critical good logging is.
What’s Running Now?
- The bot is in HYBRID mode (spot + perpetual)
- Position limit increased to 5
- Trade frequency limit upped from 12 to 20 per 30 days
- Strategic instrument selection enabled and logging decisions
- Paper trading mode active — no real money on the line yet
The bot is stable, correctly managing open positions, rejecting trades when the market is choppy (thanks ADX filter!), and making smarter instrument choices.
What’s Next?
- Keep a close eye on stability over the next 24 hours
- Watch for trades when market conditions improve
- Verify frequency limits behave as configured
- Dive into the instrument selection logs to spot patterns and optimize
- Continue paper trading validation before flipping the switch to live capital
Lessons Learned
- Model constraints must keep pace with config changes. That Pydantic mismatch cost me hours — lesson learned!
- Adapters should implement all base methods. Missing
get_exchange_name()was a sneaky oversight. - Dynamic funding rate fetching is critical. Hardcoding zero funding silently wastes money.
- Think in assets, not symbols. Grouping by BTC or ETH rather than fixed symbols opens smarter decision-making.
- Logs are your friends. Railway’s detailed logs made debugging way easier.
Building this smarter instrument selection feels like a big leap toward a more cost-efficient, adaptive trading bot. It’s not glamorous code, mostly plumbing and business logic, but it lays the groundwork for better returns and smarter risk management.
Onward to the next sprint! 🚀