9.9 KiB
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):
- 4h-Candle schließt über dem Hoch der letzten 20 4h-Candles (Donchian-20-Breakout), und
- Schlusskurs > EMA-200 (4h) — Trendfilter gegen Kaufen im Bärenmarkt, und
- für dieses Pair ist keine Position offen, und
- 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 Backfillpaper_trades— pair, entry/exit (Zeit+Preis), Größe, Initial-Stop, Exit-Grund, PnL netto, R-Multiplepositions— 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 Configbacktest_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
- 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).
- 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.
- 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)
- 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.
- Live-Monitoring:
/api/statszeigt 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/portfoliosichtbar. - DB-Ausfall: Engine pausiert, Healthcheck rot → Coolify-Restart.
- Neustart mit offenen Positionen:
positionswird 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, Subdomaintrade.kuns.dev, Port 8080, viadeploy-Script. - Dockerfile multi-stage:
oven/bun(Frontend-Build + Server), Healthcheck/health. - Env:
DATABASE_URL(DBtradekunsin 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
- Fundament: Repo-Skelett, Drizzle-Schema, CryptoComClient + Backfill, Indikatoren (+ Tests)
- Backtest zuerst: Strategie, PaperTrader-Logik, BacktestRunner, WalkForwardRunner → Gate-Entscheidung auf echten Daten
- Live-Engine: 5-min-Loop, Positions-Recovery, DecisionLogger + Outcome-Backfill, API
- Dashboard: 4 Views
- 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