Initial commit: TradeMind – Krypto-Trading-Bot mit Lernmodus

Per Podman deploybarer Bot, der Käufe und Verkäufe simuliert ausführt und sich
aus den Ergebnissen weiter antrainiert.

Aufbau
- Einheitliche Bar-Verarbeitung für paper, backtest und live; ausgetauscht werden
  nur Datenquelle und Broker.
- Börsenanbindung über ccxt: rund 100 Börsen allein über exchange.id erreichbar.
  Zugangsdaten kommen über ENV-Platzhalter, der Live-Modus ist doppelt abgesichert.
- Paper-Broker mit Gebühren, Slippage, Börsenpräzision und Volumengrenzen.
- Online trainierte logistische Regression bewertet jedes Einstiegssignal. Sie lernt
  aus realen Trade-Ergebnissen, aus Shadow-Labels aller Kandidaten – auch der
  abgelehnten – und aus Hintergrund-Stichproben; beim Kaltstart wird sie aus der
  Kurshistorie vorgelernt.
- Risikomanagement: Positions- und Exposure-Grenzen, ATR-Stops, Cooldown sowie
  Tagesverlust- und Drawdown-Notbremsen.
- SQLite-Persistenz, HTTP-Status mit Prometheus-Metriken und Dashboard, Webhooks.

Deployment
- Containerfile (zweistufig, non-root UID 10001), podman-compose, systemd-Quadlet.
- Modell und Datenbank liegen im Volume /data und überleben Neustarts.

128 Tests, ruff sauber. Verifiziert gegen echte Marktdaten sowie im gebauten
Container inklusive Healthcheck und Zustandswiederherstellung.
This commit is contained in:
Tobias Zimmermann
2026-08-22 08:53:04 +02:00
commit 65ed73977e
40 changed files with 7033 additions and 0 deletions
+135
View File
@@ -0,0 +1,135 @@
# ─────────────────────────────────────────────────────────────────────────────
# TradeMind Beispielkonfiguration
#
# Kopieren nach config/config.yaml und anpassen:
# cp config/config.example.yaml config/config.yaml
#
# ${VAR} wird durch die Umgebungsvariable VAR ersetzt (leer = nicht gesetzt)
# ${VAR:-wert} nutzt "wert" als Rückfallwert
# TRADEMIND__A__B überschreibt zusätzlich den Schlüssel a.b (z. B. TRADEMIND__RISK__MAX_OPEN_POSITIONS=5)
# ─────────────────────────────────────────────────────────────────────────────
# paper = simulierte Ausführung auf echten Live-Kursen; das Modell trainiert mit ← Standard
# backtest = historische Daten im Schnelldurchlauf
# live = echte Orders (erfordert live_confirmation + API-Schlüssel)
mode: ${TRADEMIND_MODE:-paper}
log_level: ${TRADEMIND_LOG_LEVEL:-INFO}
# Muss für mode: live wörtlich auf I_UNDERSTAND_THE_RISK stehen. Sicherheitsnetz gegen
# versehentlichen Echtgeldhandel.
live_confirmation: ${TRADEMIND_LIVE_CONFIRMATION}
# ─────────────────────────────── Börsenanbindung ────────────────────────────
# id: jede von ccxt unterstützte Börse. Liste anzeigen mit: trademind exchanges
# binance · binanceus · kraken · krakenfutures · coinbase · bybit · okx
# kucoin · bitget · gate · mexc · bitstamp · bitfinex · huobi · cryptocom · …
exchange:
id: ${TRADEMIND_EXCHANGE:-binance}
api_key: ${TRADEMIND_API_KEY}
api_secret: ${TRADEMIND_API_SECRET}
# Passphrase nötig bei OKX, KuCoin, Coinbase Advanced, Bitget
password: ${TRADEMIND_API_PASSWORD}
# true = Testnet/Sandbox der Börse (soweit unterstützt). Für die ersten Live-Tests dringend empfohlen.
sandbox: ${TRADEMIND_SANDBOX:-true}
enable_rate_limit: true
timeout_ms: 20000
options:
defaultType: spot # spot | swap | future je nach Börse
# ──────────────────────────────── Marktauswahl ──────────────────────────────
market:
# Alle Symbole müssen dieselbe Quote-Währung haben (hier USDT).
symbols:
- BTC/USDT
- ETH/USDT
timeframe: 5m # 1m 3m 5m 15m 30m 1h 2h 4h 6h 8h 12h 1d 3d 1w
history_bars: 500 # Kerzen pro Abfrage (Indikatoren brauchen ≥ 140)
poll_interval_seconds: 20 # wie oft nach einer neuen Kerze gesehen wird
# ───────────────────── Simulation (Modus paper und backtest) ────────────────
paper:
starting_balance: 10000
quote_currency: USDT
fee_rate: 0.001 # 0,1 % Taker-Gebühr pro Seite
slippage_bps: 5 # 5 Basispunkte Ausführungsnachteil
max_volume_participation: 0.1 # max. 10 % des Kerzenvolumens pro Order
# ──────────────────────────────── Risikoregeln ──────────────────────────────
risk:
max_position_pct: 0.20 # je Position, gemessen an der Equity
max_total_exposure_pct: 0.60 # Summe aller Positionen
max_open_positions: 3
stop_loss_atr_mult: 2.0 # Stop = Einstieg 2 × ATR (0 = kein Stop)
take_profit_atr_mult: 3.0 # Ziel = Einstieg + 3 × ATR (0 = kein Ziel)
trailing_stop_atr_mult: 0.0 # > 0 aktiviert den nachziehenden Stop
max_holding_bars: 0 # 0 = unbegrenzt
max_daily_loss_pct: 0.05 # Notbremse bis zum nächsten UTC-Tag
max_drawdown_pct: 0.25 # Notbremse bis zum Neustart (schließt Positionen)
min_notional: 10 # kleinste sinnvolle Ordergröße in Quote-Währung
cooldown_bars_after_exit: 3 # Pause pro Symbol nach einem Ausstieg
# ───────────────────────────────── Strategie ───────────────────────────────
strategy:
# adaptive = Regelwerk erzeugt Signale, das Lernmodell filtert sie
# rules = nur das Regelwerk, kein Lernen
name: adaptive
rules:
fast_ema: 12
slow_ema: 26
rsi_period: 14
rsi_oversold: 35
rsi_overbought: 70
atr_period: 14
trend_filter_period: 100 # 0 = Trendfilter aus
min_holding_bars: 3 # Signalausstiege erst danach; Stop/Ziel gelten immer
learner:
enabled: true
model_path: /data/models/adaptive.npz
entry_threshold: 0.55 # ab welcher Gewinnwahrscheinlichkeit gehandelt wird
exploration_rate: 0.05 # Anteil bewusst gegen das Modell gehandelter Signale
learning_rate: 0.02
l2: 0.0001
replay_size: 5000
batch_size: 64
train_every_n_samples: 5
warmup_samples: 200 # bis dahin entscheidet allein das Regelwerk
label_horizon_bars: 12 # Bewertungsfenster für ein Signal
label_target_bps: 30 # 30 bps = 0,3 % Kursziel gilt als Treffer
trade_sample_weight: 3.0 # echte Trades zählen dreifach gegenüber Shadow-Labels
# Einstiegssignale sind selten. Zusätzliche Stichproben des Marktzustands verkürzen die
# Aufwärmphase von Wochen auf Tage (0 = aus).
background_sample_every_n_bars: 10
background_sample_weight: 0.5
# Beim Start ein noch untrainiertes Modell aus der Kurshistorie vorlernen, damit der Bot
# nach Sekunden einsatzbereit ist statt nach Tagen (0 = aus).
bootstrap_bars: 3000
freeze_in_live: false # true = im Live-Modus nicht weiterlernen
save_every_n_updates: 50
# ───────────────────────────────── Persistenz ───────────────────────────────
storage:
database_path: /data/trademind.sqlite3
# ─────────────────────────── Status-Server / Monitoring ─────────────────────
server:
enabled: true
host: 0.0.0.0
port: 8080
enable_metrics: true # /metrics im Prometheus-Textformat
# ──────────────────────────────── Benachrichtigungen ────────────────────────
notifications:
# Slack- oder Discord-Webhook (leer lassen = aus)
webhook_url: ${TRADEMIND_WEBHOOK_URL}
notify_on_trade: true
notify_on_risk_halt: true
# ───────────────────────────── Backtest-Voreinstellungen ────────────────────
backtest:
bars: 5000
start: # z. B. 2024-01-01T00:00:00Z überschreibt bars
end:
csv_dir: # OHLCV aus CSV statt von der Börse (Spalten: timestamp,open,high,low,close,volume)
+35
View File
@@ -0,0 +1,35 @@
# Geheimnisse und Laufzeitschalter für TradeMind.
# Kopieren nach config/trademind.env und NIEMALS committen (.gitignore deckt das ab).
#
# podman run --env-file config/trademind.env ...
# podman-compose --env-file config/trademind.env up
# paper | backtest | live
TRADEMIND_MODE=paper
# Börse (ccxt-ID): binance, kraken, coinbase, bybit, okx, kucoin, bitget, gate, mexc, ...
TRADEMIND_EXCHANGE=binance
# true = Testnet/Sandbox der Börse verwenden
TRADEMIND_SANDBOX=true
# API-Zugangsdaten. Im Paper-Modus nicht nötig dort werden nur öffentliche Kurse gelesen.
# Für Live: Schlüssel ausschließlich mit Handelsrecht anlegen, Auszahlungen NICHT erlauben,
# und wenn möglich die IP des Servers hinterlegen.
TRADEMIND_API_KEY=
TRADEMIND_API_SECRET=
# Passphrase nur bei OKX, KuCoin, Coinbase Advanced, Bitget
TRADEMIND_API_PASSWORD=
# Muss für den Live-Modus wörtlich auf I_UNDERSTAND_THE_RISK stehen.
TRADEMIND_LIVE_CONFIRMATION=
# Optionaler Slack-/Discord-Webhook für Trade-Meldungen
TRADEMIND_WEBHOOK_URL=
TRADEMIND_LOG_LEVEL=INFO
# Punktuelle Overrides ohne Änderung der YAML-Datei (Muster: TRADEMIND__<ABSCHNITT>__<SCHLUESSEL>)
# TRADEMIND__RISK__MAX_OPEN_POSITIONS=5
# TRADEMIND__MARKET__SYMBOLS=BTC/USDT,ETH/USDT,SOL/USDT
# TRADEMIND__STRATEGY__LEARNER__ENTRY_THRESHOLD=0.6