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:
- Pure algorithmic — rigid rules that work until market conditions change, then they bleed money
- 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:
- Completed trades — what worked, what didn't
- Rejected trades — did the Risk Manager miss good opportunities?
- 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.