commit ee22f210a992e994b344cae5c3c86ab76bd741d3 Author: Claude Date: Tue Jun 9 20:04:44 2026 +0000 docs: Design-Spec trade-kuns (Multi-Pair Donchian-Trendfolge, Walk-Forward-Gate) Co-Authored-By: Claude Fable 5 diff --git a/docs/specs/2026-06-09-trade-kuns-design.md b/docs/specs/2026-06-09-trade-kuns-design.md new file mode 100644 index 0000000..5986c57 --- /dev/null +++ b/docs/specs/2026-06-09-trade-kuns-design.md @@ -0,0 +1,171 @@ +# trade-kuns — Multi-Pair-Trendfolge-Bot (Design) + +**Datum:** 2026-06-09 +**Status:** Entwurf zur Review +**Entscheidungen:** Neuer Bot, neues Repo · TypeScript + Bun · Paper-only · komplett eigenständig von krypto-kuns + +--- + +## 1. Was dieser Bot ist — und warum + +**Ein Satz:** Der Bot kauft eines von vier Krypto-Assets (BTC, ETH, SOL, XRP), wenn dessen Preis auf dem 4-Stunden-Chart über das Hoch der letzten 20 Perioden ausbricht und der langfristige Trend aufwärts zeigt — und verkauft, wenn der Preis um 3×ATR vom Höchststand zurückfällt. + +**Warum dieser Ansatz** (Lehren aus krypto-kuns v1, 8 Monate Live-Daten): + +| v1-Problem | trade-kuns-Antwort | +|---|---| +| 20 bps Round-Trip-Fees fraßen den Mini-Edge der 1–15-min-Signale | 4h-Timeframe: Trades laufen Tage–Wochen, Zielbewegung 5–20 % → Fees sind Rundungsfehler | +| Ein Pair (XRP) = ein Schicksal | 4 Pairs: irgendwo trendet es meistens; kein Trade, wenn nirgends | +| R:R 0.88 bei 31 % WinRate — mathematisch chancenlos | Trailing-Stop ohne TP-Deckel: Verlierer klein (−1R), Gewinner offen (+2R bis +10R) | +| 5 Strategien, Aggregator, Gewichte, Veto, Confidence — nichts davon brachte messbaren Nutzen | Eine Regel, binär, in einem Satz erklärbar | +| Backtest in-sample optimiert → Overfitting → live rot | Walk-Forward-Validierung mit hartem Deploy-Gate (siehe §5) | +| `LongOnly`-Config griff live nie (Seed-Gap) | Config wird beim Start per Zod gegen Code-Defaults gemerged + effektive Config geloggt | + +**Hinweis zu Fees:** Crypto.com berechnet 0.1 % pro Trade auf **alle** Pairs — XRP ist nicht günstiger als BTC. Entscheidend ist die Relation Fee : Zielbewegung, und die verbessert nur ein höherer Timeframe. + +**Erwartungsprofil (wichtig, um live nicht nervös zu werden):** Trendfolge gewinnt nur 35–45 % der Trades. Das ist kein Defekt — der Edge kommt daraus, dass Gewinner im Schnitt 2–4× größer sind als Verlierer. Wochen ohne Trade (Seitwärtsmarkt) sind Normalbetrieb, kein Bug. + +## 2. Strategie-Regeln (vollständig) + +Alle Berechnungen auf **4h-Candles** (aggregiert aus 15-min-Candles). + +**Entry (long-only):** +1. 4h-Candle schließt über dem Hoch der letzten 20 4h-Candles (Donchian-20-Breakout), **und** +2. Schlusskurs > EMA-200 (4h) — Trendfilter gegen Kaufen im Bärenmarkt, **und** +3. für dieses Pair ist keine Position offen, **und** +4. die Positionsgröße nach §3 ist ≥ Mindestordergröße. + +**Exit (eine Regel, kein Take-Profit):** +- **Chandelier-Trailing-Stop:** höchstes Hoch seit Entry − 3×ATR(14, 4h). Der Stop wandert nur nach oben, nie nach unten. Geprüft auf **15-min-Granularität** (Low ≤ Stop → Exit zum Stop-Preis, pessimistisch). +- Initialer Stop bei Entry ≈ Entry − 3×ATR → definiert das Trade-Risiko (1R). + +**Parameter (alle konfigurierbar, Defaults):** + +| Parameter | Default | Walk-Forward-Grid | +|---|---|---| +| `donchianPeriod` | 20 | 20 / 40 / 55 | +| `atrPeriod` | 14 | fix | +| `atrMultiplier` | 3.0 | 2.0 / 3.0 / 4.0 | +| `trendEmaPeriod` | 200 | 100 / 200 | +| `pairs` | BTC, ETH, SOL, XRP (USDT) | fix | +| `longOnly` | true | fix | + +## 3. Risiko & Positionsgrößen + +- **Paper-Startkapital:** 1000 USDT. +- **Risiko pro Trade: 1 % der aktuellen Equity** (= 10 USDT initial). Positionsgröße = Risikobetrag ÷ (Entry − Initial-Stop). Beispiel: Entry 100, Stop 94 → 6 % Risiko-Distanz → Position 167 USDT. +- **Cap:** max. 30 % der Equity pro Position, max. 4 Positionen (eine pro Pair), kein Leverage, keine Shorts. +- **Fees:** 0.1 % pro Seite. **Slippage:** zusätzlich 5 bps pro Seite simuliert (konservativ). +- Kein Cooldown nötig — Re-Entry erfordert naturgemäß einen neuen Breakout. + +## 4. Architektur + +### 4.1 Stack + +Bun 1.3 · Hono (HTTP) · Drizzle (Postgres) · Zod (Config/API-Validierung) · `bun test`. Eigene DB **`tradekuns`** in shared-postgres. Frontend: schlankes Vue 3 + Vite Dashboard. + +### 4.2 Module + +``` +src/server/ + market/ CryptoComClient (REST), CandleStore, Backfill (end_ts-Paginierung) + indicators/ ema, atr, donchian + strategy/ DonchianTrendStrategy (pure Funktion: Candles → Signal) + engine/ TradingEngine (5-min-Loop), PortfolioRisk, PaperTrader, DecisionLogger + backtest/ BacktestRunner, WalkForwardRunner, Metriken (PF, MaxDD, Sharpe, vs. Buy&Hold-BTC) + api/ Hono-Routen + db/ Drizzle-Schema + Migrations + config.ts Env (DATABASE_URL, ZITADEL_ISSUER) + Strategie-Defaults +src/frontend/ Vue 3 Dashboard +``` + +**Ein Code-Pfad:** Strategie und PaperTrader sind pure Funktionen über `(candles, state) → actions`. Live füttert sie der 5-min-Loop mit frischen Candles, der Backtest mit historischem Replay — identische Logik, per Konstruktion. + +### 4.3 Datenfluss (Live) + +``` +alle 5 min: 15m-Candles je Pair von Crypto.com → CandleStore (Dedup) + → Stop-Check offener Positionen (15m-Lows gegen Trailing-Stop) + → bei neuer 4h-Candle: Aggregation → Entry-Evaluation je Pair + → PortfolioRisk (Sizing, Caps) → PaperTrader → DecisionLog +``` + +### 4.4 Datenbank (Drizzle, snake_case) + +- `candles` — pair, timestamp, OHLCV, **unique(pair, timestamp)**; 15-min-Basis, ~8 Monate × 4 Pairs ≈ 93k Zeilen nach Backfill +- `paper_trades` — pair, entry/exit (Zeit+Preis), Größe, Initial-Stop, Exit-Grund, PnL netto, R-Multiple +- `positions` — offene Positionen inkl. aktuellem Trailing-Stop (übersteht Neustarts) +- `decision_logs` — pro 4h-Bar je Pair: Indikatorwerte, Signal/Blockierungsgrund, Preis + `price_after_4h/24h/72h` (Outcome-Backfill für Edge-Messung) +- `bot_state` — Equity, Running-Flag, effektive Config +- `backtest_runs` / `backtest_trades` — inkl. Walk-Forward-Fenster-Metriken (JSON) + +### 4.5 API + +| Route | Zweck | +|---|---| +| `GET /health` | Healthcheck (ohne Auth) | +| `GET /api/portfolio` | Equity, offene Positionen mit aktuellem Stop, Cash | +| `GET /api/trades?limit` | abgeschlossene Trades inkl. R-Multiple | +| `GET /api/candles?pair&tf&limit` | Candles (15m / 4h) | +| `GET /api/decisions?pair&limit` | DecisionLog inkl. Outcomes | +| `GET /api/stats` | PF, WR, MaxDD, Equity-Kurve, vs. Buy&Hold-BTC | +| `POST /api/bot/toggle` · `POST /api/bot/reset` | an/aus, Paper-Reset | +| `GET/PUT /api/config` | Strategie-Parameter | +| `POST /api/backtest/run` · `POST /api/backtest/walkforward` · `GET /api/backtest/runs/:id` | Backtests | +| `POST /api/data/backfill` | historische Candles laden | + +Auth: JWT gegen Zitadel (`auth.kuns.dev`), wie bei den anderen kuns.dev-Apps. + +### 4.6 Dashboard (Vue) + +Vier Ansichten: **Portfolio** (Positionen, Equity-Kurve, Stops), **Trades** (Historie mit R-Multiples), **Markt** (4h-Charts je Pair mit Donchian-Kanal/EMA/Stops via lightweight-charts), **Backtest** (Walk-Forward-Report: Fenster-Tabelle Train vs. OOS, Equity-Kurven). Polling 30 s — bei einem 4h-System reicht das locker. + +## 5. Validierung — Deploy-Gate vor Live-Schaltung + +1. **Backfill:** 15-min-Candles für alle 4 Pairs so weit zurück wie die Crypto.com-API liefert (Ziel ≥ 12 Monate; XRP-1m-Historie aus krypto-kuns kann ergänzend zu 15m aggregiert werden). +2. **Walk-Forward:** Train 120 Tage → Test 30 Tage, rollierend (Schritt 30 Tage). Grid-Search (§2-Grid, 18 Kombinationen) **nur auf Train**; beste Train-Kombination läuft ungesehen über das Test-Fenster. +3. **Gate (hart) — kombiniert über alle Test-Fenster:** + - OOS-ProfitFactor ≥ 1.2 nach Fees+Slippage + - ≥ 25 OOS-Trades + - MaxDrawdown ≤ 25 % + - kein Test-Fenster mit PF < 0.5 bei ≥ 5 Trades + - Train-PF ÷ OOS-PF < 2 (Overfitting-Indikator) +4. **Fällt das Gate durch**, ist das Ergebnis „diese Regeln haben keinen handelbaren Edge" — dann werden Regeln überarbeitet (z. B. Donchian-Periode, anderer Filter), nicht das Gate. Dieses Ergebnis ist ein legitimer, einkalkulierter Ausgang. +5. **Live-Monitoring:** `/api/stats` zeigt den rollierenden Edge (Outcome-Tracking aus decision_logs) — der Frühindikator, der bei v1 fehlte. + +## 6. Fehlerbehandlung + +- Crypto.com-Ausfall: Retry mit Backoff (3×), Zyklus überspringen, Lücken-Backfill im nächsten Zyklus; Status in `/api/portfolio` sichtbar. +- DB-Ausfall: Engine pausiert, Healthcheck rot → Coolify-Restart. +- Neustart mit offenen Positionen: `positions` wird geladen, Trailing-Stops laufen nahtlos weiter; verpasste 15m-Bars werden nachgeholt und Stops rückwirkend geprüft. +- Pair-spezifischer Datenfehler (z. B. SOL-Feed leer): Pair wird für den Zyklus übersprungen, andere Pairs laufen weiter. + +## 7. Tests + +- **Unit:** EMA/ATR/Donchian gegen Referenzwerte; Chandelier-Stop (wandert nie abwärts); Sizing-Mathematik inkl. Caps; Intra-Bar-Stop-Ausführung pessimistisch. +- **Integration:** Backtest-Determinismus; Walk-Forward ohne Train/Test-Leak (konstruierter Datensatz); Restart-Recovery offener Positionen. +- **API:** Smoke-Tests gegen Test-DB. + +## 8. Deployment + +- Repo `trade-kuns` → Gitea, Subdomain **`trade.kuns.dev`**, Port 8080, via `deploy`-Script. +- Dockerfile multi-stage: `oven/bun` (Frontend-Build + Server), Healthcheck `/health`. +- Env: `DATABASE_URL` (DB `tradekuns` in shared-postgres), `ZITADEL_ISSUER`. +- **krypto-kuns läuft unberührt weiter** — Vergleich der beiden Paper-Bots über Wochen, bevor irgendetwas abgeschaltet wird. + +## 9. Reihenfolge der Umsetzung + +1. **Fundament:** Repo-Skelett, Drizzle-Schema, CryptoComClient + Backfill, Indikatoren (+ Tests) +2. **Backtest zuerst:** Strategie, PaperTrader-Logik, BacktestRunner, WalkForwardRunner → **Gate-Entscheidung** auf echten Daten +3. **Live-Engine:** 5-min-Loop, Positions-Recovery, DecisionLogger + Outcome-Backfill, API +4. **Dashboard:** 4 Views +5. **Deploy:** Gitea + Coolify + DB anlegen, `trade.kuns.dev` + +Schritt 2 ist der Pivot: erst wenn das Gate besteht, wird die Live-Engine gebaut. + +## 10. Nicht-Ziele + +- Kein Live-Trading (keine Order-Ausführung, keine Schreib-API-Keys) +- Keine Shorts, kein Leverage, kein Intraday-Scalping +- Kein Strategie-Aggregator, keine Confidence-Scores, kein ML +- Keine Übernahme von v1-Code oder v1-Tabellen — nur die XRP-Candle-Historie wird ggf. als Backtest-Daten importiert