129 lines
7.3 KiB
Markdown
129 lines
7.3 KiB
Markdown
# Modul-13: Optimization
|
||
|
||
**Status: FREIGEGEBEN ✅** · Container `Modul-13-Optimization` · Image `optimization:0.1.0`
|
||
|
||
## Zweck
|
||
Deterministische, reproduzierbare **Parameteroptimierung** für die V1.1-Strategie
|
||
(`trend_pullback_v1.1`, Modul-12). Findet robuste Parameter im erlaubten Suchraum
|
||
**ohne KI/LLM und ohne Live-Orders** — Ergebnis ist nur **CANDIDATE/RECOMMENDATION**,
|
||
es gibt keine automatische Parameterübernahme in Modul-05.
|
||
|
||
## Kernprinzipien
|
||
- **Deterministisch**: gleiche Eingaben → gleiche Kandidaten, Reihenfolge, run_hash (kein Zufall außer explizit via Seed).
|
||
- **Kein Lookahead**: IS/OOS strikt zeitlich getrennt; **OOS wird nie zur Selektion verwendet**.
|
||
- **IS/OOS strikt**: `is_ratio` (z.B. 0.7) teilt die Daten; OOS ausschließlich zur Validierung.
|
||
- **Robuste Bereiche > Einzelmax**: best = Kandidat mit bester kombinierter Score (nicht max net_pnl).
|
||
- **Reject-/Overfit-Logik**: zu wenige Trades, DD-Limit, IS/OOS-Degradation → Kandidat wird `rejected`.
|
||
- **Parametergrenzen zwingend**: Suchraum begrenzt auf `pullback_band_atr`, `trend_regime_window`, `rr_multiplier`.
|
||
- **Score-Gewichte**: Expectancy/R 0.30, PF 0.25, Max-Drawdown 0.20, Trades 0.10, Stabilität 0.15.
|
||
- **Synchron**: Request/Response über API (kein RabbitMQ).
|
||
|
||
## Architektur / Datenfluss
|
||
```
|
||
OHLCV (Modul-01 PostgreSQL, Tabelle ohlcv)
|
||
│ synchron, direkt nach Timestamp/Zeitraum
|
||
▼
|
||
Modul-13-Optimization ── POST /optimization
|
||
│
|
||
├── core/split.py IS/OOS + Walk-Forward-Folds (kein Leakage)
|
||
├── core/optimizer.py Grid/Random-Suche, ScoreEngine, WF, Reject
|
||
├── core/scoring.py Multi-Metrik-Score (Gewichte siehe oben)
|
||
├── storage/storage.py Persistenz optimization_run/candidate/walk_forward
|
||
├── backtest_client.py synchroner Aufruf Modul-12 (POST /backtest)
|
||
└── api/main.py REST-API (intern, Port 55013)
|
||
```
|
||
|
||
API (Docker-intern, Port 55013, kein öffentliches Port-Mapping):
|
||
```
|
||
GET /health, /health/ready
|
||
POST /optimization Start (Grid/Random), synchron
|
||
GET /optimization Liste aller Runs
|
||
GET /optimization/{id} Run-Metadaten + Status
|
||
GET /optimization/{id}/candidates Kandidaten + Multi-Metrik-Ranking
|
||
GET /optimization/{id}/best bester ROBUSTER Kandidat (RECOMMENDATION/NO_RECOMMENDATION)
|
||
GET /optimization/{id}/walk-forward Walk-Forward-Folds
|
||
```
|
||
|
||
## Suchraum (V1.1 — NUR 3 optimierbare Parameter)
|
||
| Parameter | Suchraum (E2E) | Zweck |
|
||
|-----------|----------------|-------|
|
||
| `pullback_band_atr` | {0.2, 0.5, 0.8, 1.0} | ATR-Band um EMA20 (Pullback-Timing) |
|
||
| `trend_regime_window` | {60, 200, 300} | Fenster für strategie-internes Trend-Regime |
|
||
| `rr_multiplier` | {1.0, 2.0, 3.0} | Target = Entry + rr×Risiko |
|
||
|
||
Fix (nicht optimiert): `atr_period=14`, `regime_vol_override=false`, `min_risk_reward=1.0`,
|
||
ADX-/EMA-Perioden (14/20/30), `adx_trend_threshold=20`.
|
||
|
||
## Profile
|
||
| Profil | min_trades_is | min_trades_oos | max_drawdown_limit | max_oos_degradation | Zweck |
|
||
|--------|---------------|----------------|--------------------|--------------------|-------|
|
||
| **produktion** (Default) | 3 | 1 | 0.30 | 0.5 | Anti-Overfit, Produktion |
|
||
| **test** (`profile=test`) | 1 | 1 | — | — | nur Mindest-Trade-Schwellen gesenkt für technischen E2E; sonst identisch |
|
||
|
||
Das TEST-PROFIL senkt **ausschließlich** die Mindest-Trade-Schwellen (damit ein
|
||
Sweep über die kalibrierte synthetische Fixture genügend Kandidaten akzeptiert).
|
||
Produktive Anti-Overfit-Defaults bleiben unverändert. `profile` wird per API-Feld
|
||
übergeben; explizite Request-Werte (`min_trades_is/oos`) haben Vorrang.
|
||
|
||
## Eigene Tabellen (Migration)
|
||
- `optimization_run` — Run-Metadaten: optimization_id, strategy+version, symbol, timeframe,
|
||
optimizer_method, optimizer_version, param_space, seed, status, result (JSON), created/completed_at.
|
||
- `optimization_candidate` — Kandidaten: rank, params, backtest_run_id_is/oos, is_metrics,
|
||
oos_metrics, score, score_components, rejected, reject_reasons, flags, stability, robustness.
|
||
- `walk_forward_result` — WF-Folds: fold, params, is_start/end, oos_start/end, is/oos_metrics,
|
||
score, backtest_run_id_is/oos.
|
||
|
||
## Reject-/Overfit- und Recommendation-Verhalten
|
||
- Kandidat wird `rejected` wenn: zu wenige Trades (min_trades_is/oos), Drawdown über Limit,
|
||
OOS-Degradation zu hoch (Overfit), fachlich unbrauchbare Metriken (z.B. PF<=0/kein Trades).
|
||
- `/best` liefert:
|
||
- `recommendation=RECOMMENDATION` + `best_candidate` wenn ein fachlich brauchbarer robuster Bester existiert.
|
||
- `recommendation=NO_RECOMMENDATION` (statt leerem `best_candidate`), wenn das Kandidatenfeld
|
||
fachlich unbrauchbar ist — eine produktive Empfehlung wird nie aus unbrauchbaren Daten erzeugt.
|
||
|
||
## Tests
|
||
- `tests/test_optimization.py`: 12/12 grün (Grid deterministisch, Random-Seed, IS/OOS-Leak,
|
||
Walk-Forward korrekt + JSON-serialisierbar, Multi-Metrik-Ranking, Reject/Overfit, Robustheit,
|
||
Suchraum=3 Params, Reproduzierbarkeit, NO_RECOMMENDATION, TEST-PROFIL).
|
||
|
||
## E2E-Verifikation (VPS, 20.08.2026)
|
||
- **Suchraum-Differenzierung** (kalibrierte Fixture `M13_E2E`, 1314 Bars, alle 3 Params unterscheidbar):
|
||
- `pullback_band_atr`: 0.2→8 Trades, 0.5→9–10, 0.8/1.0→1 Trade.
|
||
- `trend_regime_window`: bei pba=0.5: 60→9 Trades vs 200/300→10 Trades.
|
||
- `rr_multiplier`: 1.0→8–10 Trades (net +828…+1046), 2.0/3.0→1 Trade.
|
||
- **12/12 E2E-Punkte über API bestätigt** (e2e_full.py):
|
||
Grid deterministisch, Random-Seed identisch, IS/OOS-Leak ausgeschlossen, WF-Folds zeitlich
|
||
korrekt + DB-persistiert (3 Folds), Multi-Metrik-Ranking, Reject-Logik (36 Kandidaten,
|
||
30 rejected / 6 accepted), best=robust + RECOMMENDATION, DB-Run/Candidates vollständig,
|
||
API list_runs, Reproduzierbarkeit (status COMPLETED), NO_RECOMMENDATION bei nur-1-Trade
|
||
Konfiguration (produktion-Profil).
|
||
- **Bugfix C**: Walk-Forward-Fold-Ergebnisse enthalten `datetime`-Timestamps → beim
|
||
`json.dumps` in `complete_run` nicht serialisierbar (422). Fix: ISO-String-Kopie im
|
||
Run-Result, datetime bleibt für `storage.insert_wf`. Verifiziert (3 WF-Folds in DB).
|
||
- Health `/health/ready` → `{"status":"ready","db":"ok"}` (M13 und M12). Keine Tracebacks.
|
||
- Port 55013 nur intern (`expose`), kein Host-Port-Binding (verifiziert).
|
||
|
||
## Freigabe
|
||
- **20.08.2026: Modul-13-Optimization-Service vom Nutzer FREIGEGEBEN ✅**
|
||
(nach vollständiger E2E-Verifikation: 12/12 API-Punkte, Suchraum-Differenzierung für alle
|
||
3 Params, TEST-PROFIL, NO_RECOMMENDATION, Bugfixes A/B/C deployt, Tests 12/12 grün).
|
||
- Keine weiteren technischen Änderungen an Modul-13.
|
||
|
||
## Compose / Betrieb
|
||
- Netzwerk `trading-modules`, DB-Host `Modul-01-PostgreSQL` (Modul-01), Backtest via
|
||
`Modul-12-Backtesting` (intern). Port 55013 nur intern (`expose`), `restart: unless-stopped`.
|
||
|
||
## Nächste Module
|
||
- **Modul-14 ff.** — noch Platzhalter (alpine), NICHT gestartet.
|
||
|
||
---
|
||
## Geändert
|
||
```
|
||
Geändert von: Rain Ocampo
|
||
Datum: 20.08.2026
|
||
Grund: Modul-13-Optimization dokumentiert — E2E-verifiziert (12/12 Punkte), Suchraum-Diffusion für alle 3 Params, TEST-PROFIL, NO_RECOMMENDATION, Bugfix C (WF-JSON-datetime).
|
||
|
||
Geändert von: Rain Ocampo
|
||
Datum: 20.08.2026
|
||
Grund: Modul-13 vom Nutzer FREIGEGEBEN — Status auf FREIGEGEBEN gesetzt, Freigabe-Sektion ergänzt. Keine technischen Änderungen.
|
||
```
|