Skip to main content

Crypto Trading Agent - Paper Trading Progressing

Published: December 4, 20255 min read
#Crypto#Agent#Progress#Analytics#Testing

Building an AI Trading Bot: When Your Code Actually Makes Money

December 3, 2025

There's something surreal about watching code you wrote at 6am generate $40.46 in profit by 10pm. Not life-changing money, but proof that the system works and hell we started with $2k. Today I want to share what I built, what I learned, and why I think we're at an inflection point for AI-powered trading systems.

The Problem With Fixed Cooling Periods

Most trading bots have a simple risk management approach: after each trade, wait X hours before trading again. It's crude but effective at preventing overtrading.

The problem? It's dumb. Win a trade? Wait 24 hours. Lose a trade? Wait 24 hours. The system treats a winning streak the same as a losing streak, which makes zero sense from a risk management perspective.

Real traders don't work this way. They push when they're hot and step back when they're cold. So why shouldn't our bots?

Sprint 14: Intelligent Loss Streak Detection

Today I shipped loss streak protection - a system that replaces fixed time-based cooling with intelligent, adaptive pausing based on consecutive losses.

Here's the logic:

Condition Action
Win or breakeven Reset streak, keep trading
1 loss Continue normally
2 consecutive losses Pause 2 hours
3 consecutive losses Pause 6 hours
4+ consecutive losses Pause 24 hours

The implementation lives in a new LossStreakTracker class that:

  1. Queries the last 20 trades from the database on startup
  2. Calculates the current streak (persists across restarts)
  3. Determines pause duration based on streak severity
  4. Integrates with the existing CapitalPreservationManager
def should_pause(self) -> bool:
    """Check if trading should be paused due to loss streak."""
    if self.current_streak < self.pause_threshold:
        return False

    if self.pause_until and datetime.now() < self.pause_until:
        return True

    return False

Simple, but effective. The key insight is that consecutive losses are a signal - either the market regime has shifted, or the strategy is temporarily misaligned. Either way, stepping back is the right move.

14 Hours of Live Trading Results

After deploying Sprint 14, I let the system run overnight. Here's what happened across 14 trading cycles:

The Numbers

  • Trading cycles completed: 14
  • System crashes: 0
  • Health check failures: 0
  • TP1 (Take Profit 1) hits: 7
  • Realized profit: $25.95
  • Total profit (including unrealized): $40.46
  • Fee efficiency: Improved from 11.6% to 4.2%

What Actually Happened

The system had 4 open positions going into the session:

  • 2x SOL longs
  • 1x BTC long
  • 1x ETH long

As the market moved up overnight (ETH +5.6%, SOL +4.1%, BTC +1.9%), the partial profit system kicked in beautifully. The ETH position alone hit TP1 six times, progressively taking profits as the price climbed:

22:03 - ETH TP1 hit: +$8.74
23:03 - ETH TP1 hit: +$4.37
00:03 - ETH TP1 hit: +$2.19
01:04 - ETH TP1 hit: +$1.09
02:04 - ETH TP1 hit: +$0.55
03:04 - ETH TP1 hit: +$0.27

Each TP1 closes 50% of the remaining position, locking in gains while letting the rest ride. It's a simple but powerful approach.

The Tech Stack (For Fellow Builders)

For those interested in building something similar:

  • Language: Python 3.11
  • Database: SQLite with WAL mode (simple, fast, no server needed)
  • LLM: DeepSeek V3 for trade generation, Claude for validation
  • Exchange: Coinbase (paper trading mode for now)
  • Deployment: Railway ($5/month, just works)
  • Monitoring: Streamlit dashboard + Telegram alerts

The architecture is intentionally simple. One main loop, hourly cycles, clear separation between strategy generation and execution. No fancy event-driven architecture, no Kubernetes, no microservices. Just Python doing its thing.

What I Learned Today

1. Backwards Compatibility Matters

When I refactored CapitalPreservationManager to add loss streak tracking, I accidentally removed some legacy parameters that main.py was still passing. The deployment failed with:

TypeError: __init__() got unexpected keyword argument 'max_concurrent_positions'

Lesson: When modifying class signatures, always check all callers. Or better yet, use **kwargs for optional parameters.

2. Database Persistence is Everything

The loss streak tracker needed to survive restarts. A bot that forgets its loss streak every time it redeploys is useless. The solution: query the database on startup to reconstruct state.

def initialize_from_db(self) -> None:
    """Load current streak from database on startup."""
    recent_trades = self.db.trades.get_recent_closed_trades(limit=20)

    streak = 0
    for trade in recent_trades:
        if trade.pnl and trade.pnl < 0:
            streak += 1
        else:
            break  # Win breaks the streak

    self.current_streak = streak

3. Logs Are Your Best Friend

Every significant event gets logged. When something goes wrong at 3am, you need to know exactly what happened. Today's logs showed 13 clean cycles with detailed price feeds, position updates, and profit captures. When the SOL TP1 hit at 23:03, I could see exactly what price it executed at and how much profit was realized.

What's Next

The system is paper trading profitably, but there's more to do:

  1. Validate loss streak protection - Need to see it actually trigger on a losing streak
  2. Backtest the parameters - Are 2h/6h/24h pauses optimal?
  3. Add confidence reduction - Require higher confidence after losses
  4. Go live - Eventually, with real money

The Bigger Picture

We're at an interesting moment for AI trading. The tools are finally good enough:

  • LLMs can reason about market conditions in ways rule-based systems can't
  • Deployment is trivial - Railway, Fly.io, etc. make running 24/7 systems easy
  • APIs are mature - Exchanges have solid REST/WebSocket interfaces
  • Costs are low - DeepSeek charges pennies per trade analysis

The edge isn't in having faster computers or better data feeds anymore. It's in having smarter systems that can adapt to changing conditions.

Today's loss streak detection is a small example of that - a system that knows when to step back and reassess rather than blindly following rules.

Try It Yourself

The full implementation is in my trading system repo. The key files:

  • src/risk_management/loss_streak_tracker.py - Core streak logic
  • src/risk_management/capital_preservation.py - Integration point
  • src/monitoring/telegram_bot.py - Alert methods

If you're building something similar, feel free to reach out. Always happy to talk shop with fellow builders.


Building in public. Learning in public. Sometimes profiting in public.

Share this post