# 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