aitrader/CLAUDE.md

114 lines
6.3 KiB
Markdown
Raw Normal View History

# aitrader — Projekt-Kontext für Claude
Diese Datei wird von Claude Code automatisch geladen. Sie beschreibt das Projekt so kompakt wie möglich, damit jede neue Session — lokal oder auf dem VPS — sofort produktiv ist.
## Was das ist
Crypto-Trading-Bot, der **alle 15 Minuten** Marktdaten von **Kraken Futures Demo** holt, sie an **Gemini + Claude im Ensemble** schickt und nur bei Konsens (beide BUY/SELL ≥ 0.6 confidence) einen Trade ausführt. Alle Decisions/Trades landen in SQLite, ein Streamlit-Dashboard visualisiert PnL, ein Discord-Webhook benachrichtigt über Trades/Errors/Daily-Summary.
**Zweck:** Empirisch herausfinden, ob LLM-basiertes Trading profitabel wäre — ohne reales Risiko (Demo-Account).
## Architektur (kurz)
```
src/aitrader/
├── main.py # Scheduler (APScheduler), --once Modus
├── config.py # YAML + ENV → Pydantic Settings
├── logging_setup.py # structlog
├── exchange/
│ ├── kraken.py # ccxt Wrapper, sandbox=True für Demo
│ └── market_data.py # OHLCV + Orderbook + Ticker Snapshots
├── features/
│ ├── indicators.py # RSI/MACD/EMA/ATR (eigene Implementierung, kein pandas-ta)
│ └── orderbook.py # Spread, Imbalance
├── news/sentiment.py # CryptoPanic + VADER (optional)
├── ai/
│ ├── prompt.py # Prompt-Builder (System + User)
│ ├── schema.py # TradeDecision Pydantic + JSON-Schema
│ ├── gemini.py # google-generativeai, response_schema
│ ├── claude.py # anthropic SDK, Tool-Use für strukturierten Output
│ └── ensemble.py # Konsens-Logik
├── trader/
│ ├── risk.py # Position-Cap, Daily-Loss-Limit, max offene Positionen
│ ├── executor.py # Market-Order auf Kraken Demo + DB-Eintrag
│ └── portfolio.py # SL/TP-Check, Equity-Snapshot, Trade-Close
├── notify/discord.py # Webhook-Notifier (Embeds)
├── storage/
│ ├── models.py # SQLModel-Tabellen: Decision, Trade, EquitySnapshot
│ └── db.py # SQLite-Engine + create_all
└── dashboard/app.py # Streamlit
```
## AI-Voter
Statt fest verdrahtetem Gemini+Claude gibt es zwei generische **Voter-Slots** in `config.yaml` (`ai.voter_a`, `ai.voter_b`). Provider werden via `ai/registry.py` instanziiert. Default: `voter_a=gemini`, `voter_b=groq`. Wechsel auf andere Provider braucht nur Config-Änderung + den passenden ENV-Key.
| provider | base_url | ENV-Key | Beispiel-Modell |
|---|---|---|---|
| gemini | (Google SDK) | `GEMINI_API_KEY` | `gemini-2.0-flash` |
| claude | (Anthropic SDK) | `ANTHROPIC_API_KEY` | `claude-haiku-4-5-20251001` |
| groq | api.groq.com | `GROQ_API_KEY` | `llama-3.3-70b-versatile` |
| deepseek | api.deepseek.com | `DEEPSEEK_API_KEY` | `deepseek-chat` |
| xai | api.x.ai | `XAI_API_KEY` | `grok-4-fast` |
| openrouter | openrouter.ai | `OPENROUTER_API_KEY` | `meta-llama/llama-3.3-70b-instruct:free` |
| ollama | localhost:11434 | (kein Key) | `llama3.3` |
Modus `ai.mode: single` → nur `voter_a` wird gefragt, kein Konsens nötig.
## Wichtige Regeln & Gotchas
- **Niemals** `exchange.sandbox` in `config.yaml` auf `false` ändern, ohne dass der User das explizit will. Das ist die Schutzlinie zum Live-Geld.
- **Keine API-Keys** ins Repo. Alle gehen via `.env``config.py:get_settings()`.
- **Indikatoren** sind selbst implementiert (pandas-only) weil pandas-ta + numpy 2 broken war.
- **Pair-Symbole**: Kraken Futures nutzt teils `PI_XBTUSD`-Format. Wenn `BTC/EUR` nicht gefunden wird, ist das die Ursache — `pairs:` in `config.yaml` anpassen.
- **Ensemble-HOLD ist gewollt**: Bei Disagreement oder zu niedriger Confidence wird absichtlich nicht getradet.
- **Decision-Notify ist standardmäßig AUS** in `config.yaml` (`discord.notify_on` enthält `decision` nicht), weil 192 Embeds/Tag spammig wären.
- **SQLite-DB unter `data/aitrader.db`** (lokal) bzw. `/opt/aitrader/data/aitrader.db` (Server) — nicht löschen, da Backtest-Replay drauf basiert.
- **Daily-Loss-Limit (5%)** pausiert Trading automatisch — Reset um 00:00 UTC weil `daily_pnl_eur` nur seit Tagesbeginn summiert.
- **`run_in_background` für lange Operationen**: Smoke-Tests und Bot sind interaktiv okay, aber wenn du den Bot im Dauerbetrieb startest mach das via `systemctl`, nicht im Vordergrund.
## Wo läuft was
| Umgebung | Pfad | Aufruf |
|---|---|---|
| Lokal (Dev) | `~/code/aitrader` | `.venv/bin/python -m aitrader.main --once` |
| Server (Prod) | `/opt/aitrader` | `systemctl status aitrader` |
| DB | `data/aitrader.db` | SQLite — `sqlite3 data/aitrader.db ".tables"` |
| Logs (Server) | journald | `journalctl -u aitrader -f` |
| Dashboard (Server) | `http://<tailscale-host>:8501` | nur via Tailscale |
## Test + Verifikation
```bash
.venv/bin/pytest -q # Unit-Tests
.venv/bin/python scripts/smoke_kraken.py # Demo-API erreichbar?
.venv/bin/python scripts/smoke_ai.py # Gemini+Claude liefern JSON?
.venv/bin/python scripts/smoke_discord.py # Webhook erreichbar?
.venv/bin/python -m aitrader.main --once # Ein vollständiger Tick
```
## Update-Workflow (lokal → Server)
1. Lokal Änderung → `git commit && git push`
2. Auf Server: `cd /opt/aitrader && sudo -u aitrader git pull`
3. Bei neuen Dependencies: `sudo -u aitrader /home/aitrader/.local/bin/uv pip install -e .`
4. `sudo systemctl restart aitrader aitrader-dashboard`
5. `sudo journalctl -u aitrader -f`
Siehe `DEPLOY.md` für vollen Setup vom Frischserver inkl. Tailscale.
## Ausstehende / sinnvolle Erweiterungen (nicht implementiert)
- Backtest-Modus (historische Daten replay durch Decisions-Tabelle)
- Mehr Pairs / dynamisches Universe-Selection
- Position-Sizing per Kelly oder Vol-Targeting
- Prompt-Tuning A/B (zwei Prompts, vergleichen welcher besser performt)
- Migration weg von `google-generativeai` (deprecated) hin zu `google-genai`
## Wenn Claude diese Datei liest
- Kein Refactor "weil schöner" — der Code ist bewusst kompakt gehalten.
- Bei Fragen zu Trading-Logik: `ai/ensemble.py` und `trader/risk.py` sind die zwei kritischen Dateien.
- Bei Fragen zu Daten-Pipeline: `main.py:run_tick` ist der Flow von oben nach unten.
- Niemals echtes Geld ohne explizite User-Bestätigung — das Projekt ist Demo-only.