aitrader/CLAUDE.md

6.3 KiB

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 .envconfig.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

.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.