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.sandboxinconfig.yamlauffalseä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. WennBTC/EURnicht gefunden wird, ist das die Ursache —pairs:inconfig.yamlanpassen. - 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_onenthältdecisionnicht), 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_eurnur seit Tagesbeginn summiert. run_in_backgroundfür lange Operationen: Smoke-Tests und Bot sind interaktiv okay, aber wenn du den Bot im Dauerbetrieb startest mach das viasystemctl, 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)
- Lokal Änderung →
git commit && git push - Auf Server:
cd /opt/aitrader && sudo -u aitrader git pull - Bei neuen Dependencies:
sudo -u aitrader /home/aitrader/.local/bin/uv pip install -e . sudo systemctl restart aitrader aitrader-dashboardsudo 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 zugoogle-genai
Wenn Claude diese Datei liest
- Kein Refactor "weil schöner" — der Code ist bewusst kompakt gehalten.
- Bei Fragen zu Trading-Logik:
ai/ensemble.pyundtrader/risk.pysind die zwei kritischen Dateien. - Bei Fragen zu Daten-Pipeline:
main.py:run_tickist der Flow von oben nach unten. - Niemals echtes Geld ohne explizite User-Bestätigung — das Projekt ist Demo-only.