aitrader/CLAUDE.md
sylyx 680a4fcc5f feat: graceful fallback to single-voter when voter_a hits rate limit
- main.py: detect rate_limit_exhausted from voter_a, switch to single(voter_b)
  and notify Discord once per session
- discord.py: add notify_voter_fallback() with yellow warning embed
- config.py: add voter_fallback to default notify_on list
- dashboard/app.py: show warning banner when fallback mode active (last 2h)
- CLAUDE.md: refresh architecture docs, fix stale google-genai migration note

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-07 19:55:47 +02:00

6.4 KiB

CLAUDE.md

This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.

Was das ist

Crypto-Trading-Bot, der alle 15 Minuten Marktdaten von Kraken Futures Demo holt, sie an zwei LLM-Voter 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).

Commands

# Tests + Lint
.venv/bin/pytest -q                          # Unit-Tests
.venv/bin/pytest tests/test_indicators.py    # einzelner Test
.venv/bin/ruff check src/                    # Linting

# Smoke-Tests (erfordern .env mit echten Keys)
.venv/bin/python scripts/smoke_kraken.py     # Demo-API erreichbar?
.venv/bin/python scripts/smoke_ai.py         # AI-Voter liefern JSON?
.venv/bin/python scripts/smoke_discord.py    # Webhook erreichbar?

# Ausführen
.venv/bin/python -m aitrader.main --once     # Ein vollständiger Tick
aitrader --once                              # alternativ via installiertem Entrypoint

# Dashboard (lokal)
.venv/bin/streamlit run src/aitrader/dashboard/app.py

Package-Manager: uv. Dependencies installieren mit uv pip install -e ".[dev]".

Architektur

src/aitrader/
├── main.py              # run_tick(): vollständiger Tick-Flow von oben nach unten
├── config.py            # YAML (config.yaml) + .env → Pydantic Settings (lru_cache)
├── exchange/
│   ├── kraken.py        # ccxt-Wrapper, sandbox=True für Demo
│   └── market_data.py   # OHLCV + Orderbook + Ticker → MarketSnapshot
├── features/
│   ├── indicators.py    # RSI/MACD/EMA/ATR — pandas-only, kein pandas-ta
│   └── orderbook.py     # Spread, Imbalance
├── news/sentiment.py    # CryptoPanic + VADER (optional)
├── ai/
│   ├── registry.py      # VoterConfig → konkreter Client (make_voter)
│   ├── prompt.py        # System- + User-Prompt-Builder
│   ├── schema.py        # TradeDecision Pydantic-Modell + JSON-Schema
│   ├── gemini.py        # google-genai SDK, response_schema
│   ├── claude.py        # anthropic SDK, Tool-Use für strukturierten Output
│   ├── openai_compat.py # OpenAI-kompatible Endpunkte (groq/deepseek/xai/openrouter/ollama)
│   └── ensemble.py      # combine() / single() — HOLD bei Disagreement oder zu niedriger Confidence
├── trader/
│   ├── risk.py          # evaluate(): 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 — absolute Imports wegen Script-Ausführung

Tick-Flow (main.py:run_tick): Marktdaten → Features/Indikatoren → Orderbook → News/Sentiment → Prompt-Builder → Voter A + B → Ensemble → DB → Discord → Risk-Check → Execute.

AI-Voter

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 braucht nur Config-Änderung + den passenden ENV-Key.

provider ENV-Key Beispiel-Modell
gemini GEMINI_API_KEY gemini-2.0-flash
claude ANTHROPIC_API_KEY claude-haiku-4-5-20251001
groq GROQ_API_KEY llama-3.3-70b-versatile
deepseek DEEPSEEK_API_KEY deepseek-chat
xai XAI_API_KEY grok-4-fast
openrouter OPENROUTER_API_KEY meta-llama/llama-3.3-70b-instruct:free
ollama (kein Key) llama3.3

ai.mode: single → nur voter_a, kein Konsens nötig.

Wichtige Regeln & Gotchas

  • Niemals exchange.sandbox: false ohne explizite User-Bestätigung. Das ist die einzige Schutzlinie zum Live-Geld.
  • exchange.paper_only: true blockt Trade-Execution zusätzlich, auch bei sandbox=true.
  • Indikatoren sind selbst implementiert (pandas-only) weil pandas-ta + numpy 2 inkompatibel war.
  • Pair-Symbole: Kraken Futures nutzt teils PI_XBTUSD-Format statt BTC/EUR — bei Symbol-Fehlern pairs: in config.yaml anpassen.
  • Ensemble-HOLD ist gewollt: Bei Disagreement oder zu niedriger Confidence wird absichtlich nicht getradet.
  • discord.notify_on enthält decision standardmäßig nicht (192 Embeds/Tag wären spammig). Nur trade_open, trade_close, error etc.
  • Daily-Loss-Limit (5%) pausiert Trading automatisch — Reset um 00:00 UTC.
  • get_settings() ist lru_cache — Änderungen an .env/config.yaml nach Start werden nicht übernommen ohne Neustart.

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 sqlite3 data/aitrader.db ".tables"
Logs (Server) journald journalctl -u aitrader -f
Dashboard (Server) http://<tailscale-host>:8501 nur via Tailscale

Update-Workflow (lokal → Server)

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

Für Claude

  • Kein Refactor "weil schöner" — der Code ist bewusst kompakt gehalten.
  • Bei Trading-Logik: ai/ensemble.py und trader/risk.py sind die zwei kritischen Dateien.
  • Bei 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.