Files
trade-kuns/docs/specs/2026-06-09-trade-kuns-design.md

9.9 KiB
Raw Blame History

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 115-min-Signale 4h-Timeframe: Trades laufen TageWochen, Zielbewegung 520 % → 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 3545 % der Trades. Das ist kein Defekt — der Edge kommt daraus, dass Gewinner im Schnitt 24× 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