Skip to main content

30 Days Without a Single Trade

Published: February 2, 20266 min read
#Crypto#Agent#Progress#Analytics

30 Days Without a Single Trade

In early January, our LLM-powered crypto trading system hadn't executed a trade in over a month. Signals were being generated. Analysis was running. The AI models were thinking hard about the market every hour. But nothing was getting through.

The system had accumulated so many safety gates that the probability of any trade passing all of them was near zero. Twelve conservative checkpoints, each with a 70% pass rate, create a compound probability of 1.4%. Our trading bot had become an extremely sophisticated way to do nothing.

This is the story of how we methodically dismantled that problem across 12 sprints, and where we stand today: 42.9% win rate, $170 in profit, and open positions running in the right direction.

The Root Cause: Death by a Thousand Checks

The system architecture was sound. We had DeepSeek generating signals, Claude validating them, regime detection adapting to market conditions, and risk management sizing positions. Each component worked. Together, they conspired to reject everything.

Sprint 80 uncovered the first layer: our strategist prompt didn't know how to output mean-reversion strategies. When RSI hit 80 (clearly overbought), the strategist warned about "overbought conditions" but still output strategy: momentum, causing LONG proposals in the wrong direction.

Sprint 80.2 revealed the signal generator was the real bottleneck. DeepSeek was producing 97.5% HOLD signals because the prompt said "If you cannot find a setup with 3:1 R:R, output HOLD instead." Only 2 actionable signals in 60 opportunities. We reframed DeepSeek's role from pre-filter to directional analyst. Signal rate jumped from 3.3% to 71% overnight.

The Validation Deadlock

With signals flowing, we hit the next wall. The LLM validator (Claude) was rejecting 68% of proposals. Deep dive revealed a hardcoded 3.0:1 R:R requirement that ignored market regime entirely.

Sprint 82.3 taught the validator about regimes. Range-bound markets with 2.5:1 R:R are valid. Momentum markets need 3.0:1. The architecture had always intended this. The code just wasn't following it.

Sprint 82.4 attacked the other side: the signal generator was proposing realistic targets (2.08% for XRP in a tight range), but main.py was clamping the take-profit to 4.5%, creating unrealistic targets that Claude correctly rejected. We removed the clamping. Let signals be what they are.

Breaking Through

Sprint 83 fixed position sizing. The estimation function was using a 1.5x leverage multiplier for ALL proposals, regardless of confidence. An 82% confidence signal (which should use 1.0x) was being estimated at 95% of capital instead of 63%. This broke sector limits and blocked everything.

Sprint 84 handled LLM output failures. Claude Opus occasionally outputs invalid enum values like "trading_stance": "selective". One bad output would freeze the entire pipeline. We implemented validate-retry-fallback: try once, retry with guidance, fall back to defensive defaults. The system never freezes.

Sprint 86 was the breakthrough. Three surgical changes: override the reversal confirmation requirement for mean-reversion, fix R:R tolerance, and monitor execution. On January 26th, the first trade in over 30 days executed.

The Refinement Phase

Once trades were flowing, we shifted from "make it work" to "make it work well."

Sprint 87 fixed regime direction alignment. Local momentum was being overridden by global structure, causing wrong-direction trades. Local wins for direction, global for sizing.

Sprint 88 recalibrated leverage across three phases. The old conviction tiers (3x/5x/7x at 80/90/95%) didn't match our multi-LLM distribution where 75-85% is typical. We implemented continuous interpolation: 75% confidence gives 3.3x leverage, not a hard step to 3.0x. Margin-aware sizing means the system actually checks available margin before determining leverage.

Sprint 90 fixed a paper trading bug where stop-loss exits were recording the polled market price instead of the actual stop price, overstating losses by $18-35 per trade.

The Fee Monitor Incident

Then last night, with three profitable short positions open and $130+ in unrealized gains, the fee monitor triggered an emergency stop.

The math: $5.18 in fees divided by $15.10 in realized profit = 34.3%, which exceeded the 30% critical threshold. But $5.18 in fees on $17,267 of notional traded is exactly 0.03% — the correct Coinbase taker fee. The ratio was noisy because it was early in the month with few closed trades.

The emergency stop had no auto-recovery path. Trading was halted permanently until the next deployment.

Sprint 91 (today) redesigned the fee monitor entirely. The cumulative ratio is now informational only — logged for dashboards, never triggers an emergency stop. Instead, we added per-trade fee validation (catches actual problems like wrong fee tiers), churn detection (catches excessive trading frequency), and funding rate monitoring (catches positions held too long on perpetuals).

No professional trading desk halts trading because of fee ratios. Fees are a cost of doing business. The real risks — wrong fee tier, excessive churn, funding drag — are now caught by targeted checks that warn without halting.

Where We Stand

Metric Value
Win Rate 42.9% (3/7 closed trades)
Total PnL +$170.96
Return on Capital +5.7%
Open Positions BTC SHORT (+$36), SOL SHORT (+$23)
Fee Efficiency 10.4% of profit (healthy)
Sprints Since Restart 12 (Sprint 80 → 91)

The market is in a WEAK_BEAR regime with RSIs approaching oversold (28-36). Our existing short positions are riding the move. The system correctly isn't opening new positions because R:R targets can't be achieved realistically after such an extended decline — the safety valve working as designed.

What I Learned

1. Compound probability kills systems silently. Each 70% gate looks reasonable. Twelve of them in series is a 1.4% pass rate. You can't see this without measuring the pipeline end-to-end.

2. Fix one thing at a time. Every sprint in this journey fixed exactly one problem and verified it before moving on. Sprint 86 was three phases with mandatory monitoring between each. The temptation to fix everything at once is strong. Resist it.

3. Safety mechanisms can be the biggest risk. The fee monitor emergency stop did more damage than any fee drag ever could. It halted profitable trading based on a noisy metric with no recovery path. Safety features need failure modes too.

4. LLM prompts are code. When DeepSeek's prompt said "output HOLD if R:R is low," that was a business logic decision embedded in natural language. It took analysis of 60 signal opportunities to discover a 97.5% HOLD rate was a prompt problem, not a market problem.

5. The system works when you let it. Once we removed the compound gatekeeping and let each component do its job (DeepSeek: directional analysis, Claude: quality validation, Risk: position sizing), the system started trading profitably. The AI models were always capable. We were just standing in their way.


Building Trader-7 in public. An LLM-powered crypto trading system learning to trade one sprint at a time.

Share this post