← Back to Blog

Building a Crypto Trading Bot That Learns From Its Mistakes

How we combined technical analysis with LLM agents to create a self-improving trading system — no crystal ball required.

The Problem With Most Trading Bots

Most crypto trading bots fall into one of two camps:

  1. Pure algorithmic — rigid rules that work until market conditions change, then they bleed money
  2. Pure AI — black boxes that "predict" prices with the accuracy of a coin flip

Neither approach works well in practice. Markets are too complex for fixed rules, and too noisy for prediction models.

Our Approach: Follow, Don't Predict

crypto-loco takes a different path. Instead of trying to predict where prices will go, we:

  • Read what the market is doing right now using 8 technical indicators
  • Classify the current market regime (trending, choppy, or volatile)
  • Confirm signals across multiple timeframes (4h entry + daily macro trend)
  • Decide using LLM agents that can reason about context, not just numbers
  • Learn from every trade — wins, losses, and missed opportunities

The result: a bot that adapts to changing conditions and gets smarter over time.

The Architecture

Binance Data → Analysis Engine → LLM Agents → Trade Execution → Dashboard
                                        ↕
                                Self-Improvement Loop

Layer 1: Data Pipeline

We connect to Binance via CCXT (async) for two data streams:

  • REST API — fetches 1 year of historical OHLCV candles for backtesting
  • WebSocket — real-time kline streams that store closed candles to SQLite

This gives us a persistent, queryable database of price data that survives restarts.

Layer 2: Technical Analysis Engine

We calculate 8 indicators using pandas-ta:

Indicator Purpose
EMA (9, 21, 50, 200) Trend direction at multiple scales
RSI (14) Overbought/oversold momentum
MACD (12, 26, 9) Momentum crossovers
Bollinger Bands (20, 2) Volatility envelope + squeeze detection
ATR (14) Volatility for stop-loss sizing
Volume Ratio Confirms moves with volume
ADX (14) Trend strength measurement
Chaikin Money Flow Buying/selling pressure

We also detect support/resistance levels using pivot points and price clustering, and classify the market regime (trending vs choppy vs volatile) using ADX + Bollinger Band width.

Layer 3: Multi-Agent LLM System

This is where it gets interesting. Instead of a single model making all decisions, we use a pipeline:

Signal + Market Data
  → Technical Analyst (Gemini 2.5 Flash)
    → Structured analysis with chart vision
  → Risk Manager (Claude Sonnet 4)
    → Approve/Reject + position sizing
  → Trade Executor (deterministic code)
    → Market order via CCXT

The Technical Analyst receives indicator data, support/resistance levels, and a candlestick chart image. It produces a structured analysis with: - Setup type (pullback, breakout, or consolidation) - Trend direction and strength - Entry zone, stop-loss, and take-profit suggestions - Confidence score (0-100%)

The Risk Manager reviews the analyst's proposal against portfolio constraints: - Max 2% risk per trade (€1.66 on an €83 pair allocation) - Max 6% concurrent risk across all positions - Dynamic sizing based on market regime (reduce in choppy/volatile markets) - Risk/reward ratio minimum of 1.5:1

The Risk Manager can veto any trade. All vetoes are logged for later review.

Layer 4: Self-Improvement Loop

After trades close, a Self-Updater agent reviews:

  1. Completed trades — what worked, what didn't
  2. Rejected trades — did the Risk Manager miss good opportunities?
  3. Approved but not executed — why did execution fail?

It generates reflections like:

"In choppy markets, breakouts without volume expansion fail 70% of the time. Require ADX > 25 before approving breakout entries."

These reflections are injected into future analyst and risk manager prompts, so the bot literally learns from its own experience.

Risk Management

We trade with €250 total capital, split across 3 pairs (~€83 each). Our rules:

Rule Value
Max risk per trade 2% of pair allocation (€1.66)
Max concurrent risk 6% of total (€15)
Stop-loss 2.5× ATR or visual support level
Take-profit 5.0× ATR
Min risk/reward 1.5:1
Max positions 3 (one per pair)

The Risk Manager dynamically adjusts position size based on market regime: - Trending: Full risk (€1.66) - Choppy: Half risk (€0.83) - Volatile: Quarter risk (€0.41) with wider stops

Backtesting Results

On 1 year of 4h data for SUI/USDT, INJ/USDT, and ICP/USDT:

Metric Value
Net P&L (after fees) +12.42%
Average win rate 43.5%
Trades 77
Optimal stop 2.5× ATR
Optimal confidence threshold 45%

The key insight: wider stop losses improve win rate significantly. A 2.5× ATR stop outperformed tighter stops because it survives short-term wicks before the bounce occurs.

The Dashboard

We built a real-time web dashboard with FastAPI and vanilla HTML/CSS/JS:

  • Live price cards with 24h change
  • Signal table showing pair, signal, confidence, trend, RSI
  • Open positions with real-time P&L
  • Agent decision log with model badges and reasoning
  • Candlestick charts per pair with indicator overlays
  • WebSocket live feed updating every 30 seconds

What's Next

  • Live trading with real capital (€250)
  • Telegram/Discord alerts for trade notifications
  • TradingView webhook integration for external signals
  • Sentiment analysis agent for news/social data
  • Continuous agent self-improvement in production

Tech Stack

  • Python 3.11+ with async/await throughout
  • CCXT for Binance API (spot only)
  • pandas-ta for technical indicators
  • aiosqlite for async SQLite storage
  • OpenRouter for multi-model LLM access (Gemini, Claude, GPT-4)
  • FastAPI for the dashboard
  • mplfinance for chart rendering
  • pytest for testing (49 tests)

Why This Matters

Most trading bots are either too rigid or too opaque. By combining deterministic technical analysis with LLM reasoning and a self-improvement loop, we get a system that:

  • Adapts to changing market conditions
  • Explains every decision with clear reasoning
  • Learns from mistakes without human intervention
  • Respects risk with hard-coded safety constraints

It's not perfect. No trading system is. But it's a solid foundation for a bot that gets better every day.


This is an open development log. Follow the progress on GitHub.