Files
cbazzaandClaude Sonnet 5 a45092b162 Wire the Lottoland fallback into the automated update workflow
AutoUpdateAndLearn.update_data() called LottoAPIUpdater with
api_name='github', which skipped the already-implemented Lottoland ->
GitHub -> lottoAPI fallback chain entirely. The GitHub archive alone
has repeatedly lagged 1-6 days behind actual draws (most recently the
Aug 5 draw, still missing as of Aug 7), causing tips to be generated
and models to be retrained on stale data. Switching to api_name='all'
tries Lottoland first, which has consistently had same-day results in
testing, with GitHub still covering full history/fallback.

Also includes the Aug 5 draw pulled in via this fix and the resulting
model retrain (data update was previously interrupted by a truncated
pipe during manual testing, this completes it).

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-07 10:55:17 +02:00

152 lines
8.1 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Architektur
Dieses Dokument beschreibt den aktiven Datenfluss, die Kernkomponenten und die
wichtigsten Design-Entscheidungen des Lotto-6aus49-Systems. Es wurde mit Hilfe
einer Code-Graph-Analyse (`graphify-out/`, siehe unten) erstellt und sollte bei
größeren strukturellen Änderungen aktualisiert werden.
## 1. Aktiver Datenfluss
```mermaid
flowchart LR
subgraph Ingestion["1. Daten-Ingestion"]
A[GitHub Lotto Archive] -->|LottoAPIUpdater| B[AlleLottozahlen.csv]
end
subgraph Training["2. Training"]
B --> C[FeatureEngineer<br/>20 Features]
C --> D[AIMLEngine<br/>RandomForest, 40 Zahlen]
C --> E[DeepLearningEngine<br/>LSTM, PyTorch]
D --> F[Hybrid Predictor<br/>RF 40% + LSTM 60%]
E --> F
end
subgraph Generation["3. Tipp-Generierung"]
F --> G[UltimateAIMLHybridGenerator]
G --> H1[HYBRID-OPT]
G --> H2[BALANCED-SPREAD]
G --> H3[HIGH-EV]
G --> H4[SOFT-CONTRARIAN]
H1 & H2 & H3 & H4 --> I[Quality/Popularity Score]
I --> J[10 Tipps als CSV]
end
subgraph Learning["4. Learning-Loop"]
B -->|neue Ziehung| K[AutoUpdateAndLearn]
K -->|evaluiert| J
K -->|retrained| D
K -->|retrained| E
K --> L[learning_log.json /<br/>strategy_weights]
end
J --> M[LottoNotifier<br/>Telegram]
K --> M
L -.->|beeinflusst nächsten Lauf| G
```
**Zwei unabhängige Cron-Zyklen** (siehe Abschnitt 4):
| Schritt | Entrypoint | Ausführt |
| --- | --- | --- |
| Ingestion + Training + Learning | `run_update_and_learn.sh``scripts/automation/auto_update_and_learn.py` | Mi + Sa, 20:00 Uhr |
| Tipp-Generierung | `run_tip_generator.sh``scripts/automation/weekly_tip_generator.py` | Di + Fr, 21:00 Uhr |
Wichtig: Die Tipp-Generierung läuft **vor** dem nächsten Update-Lauf. Das
System hinkt daher strukturell immer bis zu einem Zyklus hinter neu
verfügbaren Ziehungen hinterher, falls die externe Datenquelle verspätet
aktualisiert (siehe Abschnitt 5).
## 2. Kernkomponenten (aktive Pipeline)
Alle Pfade relativ zum Projekt-Root.
| Komponente | Datei | Rolle |
| --- | --- | --- |
| `LottoAPIUpdater` | `scripts/utils/update_from_api.py` | Holt neue Ziehungen über `fetch_from_all_apis()`: Lottoland zuerst (liefert die neueste Ziehung meist noch am Ziehungstag), GitHub-Archiv für die Historie/als Fallback (kann tagelang hinterherhinken). `auto_update_and_learn.py` nutzt seit August 2026 `api_name='all'`, davor fest `api_name='github'` — daher wiederholt verspätete Ziehungen in der Vergangenheit. |
| `AutoUpdateAndLearn` | `scripts/automation/auto_update_and_learn.py` | Orchestriert den 4-Schritte-Workflow: Daten aktualisieren → neue Ziehung prüfen → letzte Tipps evaluieren → Learning-Update (Retraining). |
| `FeatureEngineer` | `scripts/generators/ultimate_ai_ml_hybrid_generator.py` | Baut 20 Features (Frequenzen, Gaps, Momentum, Trends, Beziehungen, Zyklen) aus den Rohdaten. |
| `AIMLEngine` | `scripts/generators/ultimate_ai_ml_hybrid_generator.py` | RandomForest-Modelle, ein Modell pro Zahl (149). Cached unter `data/ultimate_ml_models/`. |
| `DeepLearningEngine` | `scripts/utils/deep_learning_engine_pytorch.py` | LSTM (PyTorch) über Sequenzen der letzten 20 Ziehungen. Wird mit RF zu 40/60 kombiniert (`Hybrid Predictor`). |
| `UltimateAIMLHybridGenerator` | `scripts/generators/ultimate_ai_ml_hybrid_generator.py` | **God Node der Pipeline** (35 Kanten im Code-Graph) — verbindet Training, die 4 Tipp-Strategien und den Quality/Popularity-Score. Zentraler Einstiegspunkt für `generate_ultimate_tips()`. |
| `PatternEngine` | `scripts/generators/ultimate_ai_ml_hybrid_generator.py` | Historische Verteilungsmuster (N/M/H-Zonen etc.), fließt als `pattern_weight` in die Tipp-Bewertung ein. |
| `HybridOptimizer` | `scripts/generators/ultimate_ai_ml_hybrid_generator.py` | Kandidaten-Generierung für die HYBRID-OPT-Strategie. |
| `RealTimeLearner` | `scripts/generators/ultimate_ai_ml_hybrid_generator.py` | Persistiert Learning-State (`learning_state.json`), passt `strategy_weights` nach jedem Zyklus an (`_update_strategy_weights`). |
| `PerformanceTracker` | `scripts/generators/ultimate_ai_ml_hybrid_generator.py` | Loggt Trefferauswertungen nach `data/learning_log.json`. |
| `WeeklyTipGenerator` | `scripts/automation/weekly_tip_generator.py` | Ruft `generate_ultimate_tips()`, exportiert CSV nach `data/generated_tips/`, aktualisiert `generation_history.json`. |
| `LottoNotifier` | `scripts/utils/notifier.py` | Telegram-Benachrichtigungen für neue Tipps und Ziehungsergebnisse. |
### Die 4 Tipp-Strategien
Pro Lauf werden 10 Tipps über 4 Strategien verteilt (Gewichtung passt sich
über `RealTimeLearner` dynamisch an, Startwerte: HYBRID-OPT 40%,
BALANCED-SPREAD 30%, HIGH-EV 20%, SOFT-CONTRARIAN 10%):
- **HYBRID-OPT** — AI-Score + Pattern-Gewicht kombiniert (`HybridOptimizer`)
- **BALANCED-SPREAD** — erzwingt Verteilung über N/M/H-Zonen, Summenbereich 127171
- **HIGH-EV** — 23 Zahlen >31, meidet empirisch belegte populäre Einzelzahlen (siehe Abschnitt 3)
- **SOFT-CONTRARIAN** — bevorzugt in den letzten 30 Ziehungen unterrepräsentierte Zahlen
## 3. Design-Entscheidung: Quality-Score = EV-Optimierung, nicht Trefferprognose
Lotto-6aus49-Ziehungen sind mechanisch geprüfte, unabhängige Zufallsereignisse
(i.i.d.). Kein Modell — auch kein LSTM — kann daraus einen Vorteil gegenüber
reinem Zufall bei der **Trefferwahrscheinlichkeit** ableiten. Das bestätigen
auch die eigenen `learning_log.json`-Daten: die durchschnittlichen
Haupttreffer schwanken um den Erwartungswert von Zufallstipps (~0.73 Treffer
pro 6er-Tipp), ohne erkennbaren Aufwärtstrend trotz kontinuierlichem Retraining.
Der `_calculate_quality_score()` in `ultimate_ai_ml_hybrid_generator.py`
optimiert deshalb bewusst nicht auf Trefferwahrscheinlichkeit, sondern auf
**Expected Value im Gewinnfall**: unpopuläre Zahlenkombinationen haben bei
einem Treffer weniger Mitgewinner und damit eine höhere Auszahlung.
`_calculate_popularity_score()` bewertet dafür (Gewicht 50% der Quality-Formel):
1. Geburtstags-Range (>31 bevorzugt)
2. Empirisch belegte populäre Einzelzahlen (`POPULAR_PLAYER_PICKS`)
3. Zahlenfolgen/arithmetische Muster (nicht nur direkte Nachbarn)
4. Odd/Even-Split-Extremität (Menschen bevorzugen "ausgeglichen aussehende" 3-3-Splits)
Die Superzahl-Auswahl (`_get_smart_superzahl`) folgt derselben Logik: eine
feste EV-Rangfolge unpopulärer Ziffern statt (bedeutungsloser) historischer
Ziehungshäufigkeit, da die Superzahl pro Ziehung unabhängig gleichverteilt ist.
AI-Score, Pattern-Gewicht und Recency fließen weiterhin mit reduziertem
Gewicht in die Quality-Formel ein — nicht weil sie die Trefferchance erhöhen,
sondern weil eine gewisse Portfolio-Diversität über die 10 Wochentipps
gewünscht ist.
## 4. Automatisierung
Die Automatisierung läuft über **launchd** (`~/Library/LaunchAgents/`), nicht
über `crontab` — die Kommentare in `crontab -l` sind veraltete Doku-Reste und
spiegeln nicht den tatsächlichen Zeitplan wider:
| launchd Job | Plist | Zeitplan (tatsächlich) |
| --- | --- | --- |
| `com.lotto.update` | `scripts/automation/com.lotto.update.plist` | Mi + Sa, 20:00 Uhr |
| `com.lotto.weekly` | `scripts/automation/com.lotto.weekly.plist` | Di + Fr, 21:00 Uhr |
Logs: `logs/update_stdout.log` (Update+Learning), `logs/stdout.log`
(Tipp-Generierung).
## 5. Bekannte Schwachstellen / offene Punkte
- **`update_from_web.py`** (lotto.de-Scraper) ist als dritter Fallback
implementiert, aber nirgends in der automatisierten Pipeline eingebunden.
- **Utility-Skripte** in `scripts/utils/` (`health_check.py`, `validate_csv.py`,
`verify_draws.py`, `model_evaluator.py`) existieren, sind aber nicht in die
Cron-Automatisierung eingebunden; manuelle Ausführung bei Bedarf.
## 6. Code-Graph
Eine navigierbare Graph-Ansicht aller Module, Klassen und ihrer Beziehungen
liegt unter `graphify-out/`:
- `graphify-out/graph.html` — interaktive Visualisierung (im Browser öffnen)
- `graphify-out/GRAPH_REPORT.md` — God Nodes, Communities, auffällige Verbindungen
- `graphify-out/graph.json` — Rohdaten (GraphRAG-fähig)
Bei größeren strukturellen Änderungen: `/graphify --update` zum
inkrementellen Neuaufbau.