Dividend Hopper
LockGewichteVersucheRecapData

Recap: Fitness je Versuch

Jeder Versuch wird auf dem Trainingszeitraum (bis 2024-07-01) gesucht und im späteren Testzeitraum (out of sample, OOS) nachgeprüft. Übernommen wird nur, was im Testzeitraum besser ist.

F = Radj − 0,5 · MaxDD − 0,01 · Laufzeit / 60 s − 0,05 · fehlende Aktien
Radj = Rpa · min(1, √(n / 100))  (nur bei Gewinn)
Rpa = Netto € / K / Jahre
VariableBedeutung
Netto €Summe aller Trade-Ergebnisse nach Kursabschlag am Ex-Tag, Ordergebühr 0,25 % je Order, Spread, KESt 27,5 % und Quellensteuer (Anrechnung bis 15 %)
Kgrößtes gleichzeitig gebundenes Kapital
JahreLänge des Zeitraums
nAnzahl Trades; unter 100 wird ein Gewinn mit √(n/100) gekürzt (kleine Stichprobe)
MaxDDgrößter Rückgang der aufsummierten Ergebnisse, relativ zu K
LaufzeitRechenzeit der Bewertung (Code-Effizienz)
fehlende AktienAktien unter dem Minimum von 6 mit Trades

Aktueller Lock: dividend_hopping_v5_stock_test01

Fitness Training-0,0046
Fitness Test (OOS)-0,0029
Netto p.a. Test2,25 %
Trades Test57

Alle Fitnesswerte sind offline aus dem Kurs-Cache mit dem heutigen Kosten-, Steuer- und Euro-Modell auf deinem Portfolio stock_test01 neu gerechnet, damit sie vergleichbar sind. Die damals im Log notierten Werte stehen jeweils darunter. Backtest, keine Anlageberatung.

2026-11-04 · dividend_hopping_v6_props_stock_test01 · Test (nicht übernommen)

2026-11-04 · dividend_hopping_v5_stock_test01 · übernommen (Lock)

2026-11-04 · dividend_hopping_v4_stock_test01 · übernommen

2026-11-04 · dividend_hopping_v4 · verworfen

2026-11-04 · dividend_hopping_v6_stock_test01 · verworfen (Walk-forward)

2026-11-03 · Nachtlauf (Code) · übernommen

2026-11-02 · dividend_hopping_v2 · verworfen

2026-11-02 · dividend_hopping · verworfen

2026-11-02 · Baseline · Referenz

Log

Vollständiges Protokoll aus docs/optimization-log.md.

2026-11-04 (5) – Test Eigenschafts-Parameter (Studie dividend_hopping_v6_props_stock_test01, nicht übernommen)

2026-11-04 (4) – IPOP-CMA-ES + Walk-forward (Studie dividend_hopping_v6_stock_test01)

2026-11-04 (3) – Oberfläche im Dalio-Stil, Versuche als JSON-LD

2026-11-04 (2) – Kosten aus BrokerageAccount.json, EUR-Umrechnung, Ausschlussliste

2026-11-04 – Nutzerportfolio stock_test01 als Universum

2026-11-04 – Nachtlauf (Daten: **Neuabruf** yfinance 04.11.2026 00:37 MEZ, 5 Jahre bis 03.11.2026; Snapshot `/workspace/cache-snapshot-2026-11-04`)

Datenvintage geändert: run_backtest lädt bei Cache > 1 Tag automatisch neu (yfinance diesmal ohne 429). Durch das verschobene 5-Jahres-Fenster fällt im Train 1 Trade weg.

Gelockte Baseline (Commit 2fb7dfe, Default 5/2, R 10) auf neuen Daten: Train F = −0,0447 (98 Trades, R_pa −1,65 %, MaxDD 5,63 %) · OOS F = +0,0304 (82 Trades, R_pa +4,16 %, MaxDD 1,44 %) – vorher (alte Daten) −0,0441 / +0,0306.

#VersuchTrain F vorher → nachherOOS F vorher → nachherEntscheidung
1Strategie S-sma: Kauf nur bei Schluss am Kauftag > SMA(N) der Schlüsse bis einschl. Kauftag (kein Vorgriff; zu kurze Historie = Filter nicht anwendbar). Erwartung vorab: weniger Verlusttrades in Abwärtsphasen, OOS-F ↑−0,0447 → −0,0285 (N = 20, auf Train gewählt)+0,0304 → +0,0141verworfen (Patch /workspace/s-sma-2026-11-04.patch)
2Code C-window: Ex-Tage außerhalb since/until vor der Kosten-/Steuerrechnung überspringen; Datums-/Kursarrays je Historie memoisieren−0,0447 → −0,0447 (nur Laufzeitterm)+0,0304 → +0,0304übernommen (9582014): 1,28 → 0,57 ms je Evaluation, Ergebnisse identisch
3CMA-ES Studie dividend_hopping_v4 fortgesetzt, +400 Versuche (800 gesamt), Suchraum unverändertbest neu +0,0136 (12/10, min_yield 1,01 %, max_wht 19,6 %, R 11; 22 Trades, 6 Aktien)−0,1071 (23 Trades, 4 Aktien → Strafterm)verworfen (OOS < Default)

SMA-Raster (Train / OOS F, Trades Train/OOS): 0: −0,0447/+0,0304 (98/82) · 10: −0,0354/+0,0112 (51/49) · 20: −0,0285/+0,0141 (53/54) · 50: −0,0440/+0,0211 (61/51) · 100: −0,0559/+0,0299 (61/55) · 150: −0,0545/+0,0270 (58/57) · 200: −0,0640/+0,0272 (66/56). OOS nur zur Diagnose.

Erkenntnis: Der Trendfilter senkt den OOS-MaxDD (1,44 → 0,8–1,2 %) und hebt die Trefferquote, halbiert aber die Trades; der Konfidenzfaktor sqrt(n/100) frisst den Gewinn. Train- und OOS-Optimum liegen bei verschiedenen N (20 vs. 100) → kein robustes Signal. CMA-ES v4 konvergiert auch auf neuen Daten auf denselben Punkt (Achse ausgeschöpft).

Fitnessformel unverändert. pytest 93 grün. Default bleibt 5/2, R 10.

Nächste offene Lücke (andere Achse): Universum erweitern (mehr Dividendentitel aus echten Quellen → mehr Trades, Konfidenz).

2026-11-03 – Nachtlauf (Daten: Cache vom 02.11.2026 09:06 MEZ, kein Neuabruf; yfinance-Netz 429 Too Many Requests)

Gelockte Baseline (Commit f803ed6, Default 5/2): Train F = −0,0649 (99 Trades) · OOS F = +0,0183 (82 Trades, MaxDD 1,90 %).

#VersuchTrain F vorher → nachherOOS F vorher → nachherEntscheidung
1Studie dividend_hopping_v3 fortgesetzt, +400 CMA-ES-Versuche (800 gesamt)best +0,0026 → +0,0026 (14/10, min_yield 1,0 %, max_wht 26,4 %; neue 400 nur bis −0,0006)−0,0016 (unverändert)nicht übernommen – CMA-ES konvergiert, Achse ausgeschöpft
2Code/Laufzeit: geparster Kurs-Cache im Speicher (mtime/Größe-Invalidierung)−0,0649 → −0,0649+0,0183 → +0,0183übernommen (11579f4): 5,1 → 1,3 ms je Evaluation, Ergebnisse identisch, Laufzeitterm minimal besser
3Strategie: Erholungs-Exit recover_days – liegt der Schluss am Verkaufstag unter Kaufkurs, bis zu R weitere Handelstage halten, Verkauf am ersten Schluss ≥ Kaufkurs (sonst Fensterende); nur vergangene Kurse−0,0649 → −0,0441 (R = 10)+0,0183 → +0,0306 (MaxDD 1,90 → 1,44 %, Treffer 65 → 82 %)übernommen (cc82ec4), config.DEFAULT_RECOVER_DAYS = 10
4CMA-ES neue Studie dividend_hopping_v4 (recover_days 0–15 im Suchraum), 400 Versuchebest +0,0148 (12/10, min_yield 1,01 %, max_wht 19,1 %, R 11)−0,1070 (23 Trades, nur 4 Aktien → Strafterm)nicht übernommen (OOS < Default +0,0306)

R-Wahl nur auf Train (R 0/1/2/3/5/8/10/15: −0,065/−0,072/−0,066/−0,082/−0,087/−0,061/−0,044/−0,052); OOS nur zur Diagnose nachträglich: +0,018/+0,005/+0,004/+0,003/+0,014/+0,022/+0,031/+0,024. Kurzes Nachhalten (1–5 Tage) schadet in beiden Perioden, ≥ 8 Tage hilft in beiden → konsistentes Muster, aber kleine Stichprobe (12 Aktien, 5 Jahre).

Fitnessformel unverändert. Mehr Haltetage erhöhen die Spitzen-Kapitalbindung (Train K 59,9 → 79,8 Tsd.), das ist in R_pa bereits berücksichtigt. Hinweis: Verkäufe kurz vor dem Split können bis zu 12 Handelstage in den OOS-Zeitraum reichen (Zuordnung nach Ex-Tag, wie bisher).

Neuer Default (5/2, R 10): Train F −0,0441 · OOS F +0,0306 · gesamt F −0,0196 (181 Trades, Netto p.a. +0,86 %, MaxDD 5,63 %).

Nächste offene Lücke (andere Achse): Einstiegsfilter ohne Vorgriff (z. B. Schluss am Kauftag über gleitendem 50-Tage-Schnitt).

2026-11-02 – Hierarchische Gruppen-Variante (Studie `dividend_hopping_v3_groups`)

Modell: globaler Satz (buy_days, sell_days, min_yield, max_wht) + Offsets je Gruppe auf Kauf-/Haltetage (±3 Handelstage), L1-Regularisierung 0,002 · Σ|Offset| von der Fitness abgezogen. Aufruf scripts/optimize.py --grouped; Default (ohne Flag) bleibt dividend_hopping_v3.

Gruppenwahl (Train-Trades Baseline 5/2, < 2024-07-01): Region US 54 / UK 21 / Eurozone inkl. AT 24; Rhythmus Quartal 84 / jährlich+halbjährlich 15. UK, Eurozone und Nicht-Quartal liegen unter 30 → zusammengelegt zu US (54) und EU = UK+Eurozone (45). tests/universe/stocks.json hat jetzt region, payout (Q/S/A) und group.

CMA-ES 400 Versuche: buy 15, sell 1, min_yield 0,91 %, max_wht 29,0 %; Offsets US (−1, 0) → 14/1, EU (+2, 0) → 17/1. Strafterm 0,006.

VarianteZeitraumFitnessTradesAktienNetto p.a.MaxDD
Baseline 5/2Train−0,06499912−2,36 %8,27 %
Baseline 5/2OOS+0,01838212+3,08 %1,90 %
Global v3 (14/10)Train+0,0026399+2,30 %2,35 %
Global v3 (14/10)OOS−0,0016387+3,19 %4,26 %
GruppenTrain+0,01035810+3,71 %2,37 %
GruppenOOS+0,0079469+4,54 %3,37 %

Entscheidung: OOS-Fitness Gruppen (+0,0079) < Baseline (+0,0183) → nicht übernommen, Default 5/2 bleibt. Besser als global v3 und geringerer Train/OOS-Abstand, aber durch min_yield nur 15 US-Trades im Train.

2026-11-02 – Fitness v3 (neue Studie `dividend_hopping_v3`)

Änderungen: min_trades 50 → 100 (Konfidenz c = min(1, sqrt(n/100))); neu MIN_STOCKS = 6.

Baseline 5/2, alle 12 Aktien: gesamt F = −0,042 (181 Trades, R_pa −0,06 %, MaxDD 8,3 %).

Train: F = −0,065, 99 Trades, 12 Aktien, R_pa −2,36 %, MaxDD 8,3 % · OOS: F = +0,018, 82 Trades, 12 Aktien, R_pa +3,08 %, MaxDD 1,9 %.

CMA-ES, 400 Versuche, Train < 2024-07-01, OOS ab dann: best buy_days 14, sell_days 10, min_yield 1,00 %, max_wht 26,4 %.

2026-11-02 – Fitness v2 (neue Studie `dividend_hopping_v2`)

Formeländerung: F = R_adj − 0,5·MaxDD − 0,01·T_norm

Baseline (5/2, alle 12 Aktien, 181 Trades): alt F = −0,252 (R_pa −0,34 %, MaxDD 49,7 %) → neu F = −0,042 (R_pa −0,06 %, MaxDD 8,3 %, K ≈ 59.862, 5,0 Jahre).

CMA-ES, 400 Versuche, Train < 2024-07-01, OOS ab 2024-07-01: best buy_days 15, sell_days 1, min_yield 0,54 %, max_wht 3,0 % (nur UK: Unilever, Shell).

2026-11-02 – CMA-ES, 30 Trials, Train < 2024-07-01, OOS ≥ 2024-07-01

Beste Parameter: buy_days=11, sell_days=3, min_yield=0,47 %, max_wht=8,4 % (→ nur UK: Unilever, Shell).

Train-Fitness 0,1421 · OOS-Fitness 0,0530 (Netto p.a. 8,02 %, MaxDD 5,43 %, 18 Trades, 56 % Treffer).

Hinweis: kleine Stichprobe, Überanpassung möglich. Studie: data_opt/optuna.db (nicht versioniert, fortsetzbar).

2026-11-02 – Baseline (buy_days=5, sell_days=2, keine Filter, 12 Aktien)

FitnessNetto p.a.MaxDDTradesTrefferquote
−0,2524−0,34 %49,69 %18157 %

Backtest-Output nach Kosten und österreichischer Steuer, keine Anlageberatung.