Files
Eurojackpot-Tipp-Generator/documentation/ARCHITECTURE.md
T
cbazzaandClaude Sonnet 5 c9da3841f9 Add regression tests for the popularity/EV score
Ports tests/test_popularity_score.py from the Lotto sibling project
(same purpose: pin down known overplayed combinations scoring lower
than spread ones), adapted for 5 main numbers and adds coverage for
the Euro-number determinism bug fixed in 0285a1c (tips #1-3 used to
always return the identical pair). Also documents beautifulsoup4 as
a required dependency in the README, which was missing despite
update_from_eurojackpot_zahlen_eu.py needing it.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-12 10:08:59 +02:00

169 lines
8.7 KiB
Markdown
Raw 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
bekannte Schwachstellen des Eurojackpot-Systems. Erstellt mit Hilfe einer
Code-Graph-Analyse (`graphify-out/`) analog zum Schwesterprojekt Lotto 6aus49
— siehe dort `documentation/ARCHITECTURE.md` für den Vergleich. Format: 5
Hauptzahlen (1–50) + 2 Eurozahlen.
## 1. Aktiver Datenfluss
```mermaid
flowchart LR
subgraph Ingestion["1. Daten-Ingestion"]
A1[lottoAPI / Lottoland / Sazka.cz] -->|EurojackpotAPIUpdater| B[AlleEurojackpotzahlen.csv]
A2[eurojackpot-zahlen.eu<br/>Web-Scraper Fallback] -.->|nur falls API leer| B
end
subgraph Training["2. Training"]
B --> C[EurojackpotFeatureEngineer]
C --> D[EurojackpotAIMLEngine<br/>RandomForest]
C --> E[DeepLearningEngine<br/>LSTM, PyTorch]
D --> F[Hybrid Predictor]
E --> F
end
subgraph Generation["3. Tipp-Generierung"]
F --> G[UltimateAIMLEurojackpotGenerator]
G --> H1[HYBRID-OPT]
G --> H2[BALANCED-SPREAD]
G --> H3[HIGH-EV]
G --> H4[SOFT-CONTRARIAN]
H1 & H2 & H3 & H4 --> I[Quality/Popularity Score<br/>5 Hauptzahlen + 2 Eurozahlen]
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[EurojackpotRealTimeLearner /<br/>strategy_weights]
end
J --> M[EurojackpotNotifier<br/>Telegram]
K --> M
L -.->|beeinflusst nächsten Lauf| G
```
**Zwei launchd-Jobs** (nicht crontab — siehe Abschnitt 4):
| Schritt | Entrypoint | Zeitplan (tatsächlich) |
|---|---|---|
| Ingestion + Training + Learning | `run_update_and_learn.sh` → `scripts/automation/auto_update_and_learn.py` | Mi + Sa, 08:00 Uhr (Morgen nach Di/Fr-Ziehung) |
| Tipp-Generierung | `run_tip_generator.sh` → `scripts/automation/weekly_tip_generator.py` | Mo + Do, 21:00 Uhr (Abend vor Di/Fr-Ziehung) |
Anders als beim Lotto-Projekt prüft der Update-Job hier erst am **nächsten
Morgen**, nicht noch am Ziehungsabend — das gibt den Datenquellen mehr Zeit,
die Ziehung zu veröffentlichen.
## 2. Kernkomponenten (aktive Pipeline)
Alle Pfade relativ zum Projekt-Root.
| Komponente | Datei | Rolle |
|---|---|---|
| `EurojackpotAPIUpdater` | `scripts/utils/update_from_api.py` | Holt neue Ziehungen über `fetch_from_all_apis()`: lottoAPI, Lottoland, Sazka.cz. `AutoUpdateAndLearn.update_data()` nutzt bereits `api_name='all'` **und** fällt bei leerem API-Ergebnis zusätzlich auf einen Web-Scraper zurück — robuster als die Lotto-Pipeline vor deren Fix. |
| `WebScraper` (`EurojackpotUpdater`) | `scripts/utils/update_from_eurojackpot_zahlen_eu.py` | Zweiter Fallback, wird nur aktiv wenn die API-Kette keine neuen Daten liefert. |
| `AutoUpdateAndLearn` | `scripts/automation/auto_update_and_learn.py` | Orchestriert: Daten aktualisieren → neue Ziehung prüfen → letzte Tipps evaluieren → Learning-Update (Retraining). |
| `EurojackpotFeatureEngineer` | `scripts/generators/ultimate_ai_ml_eurojackpot_generator.py` | Feature-Engineering (Frequenzen, Gaps, Momentum) für Haupt- und Eurozahlen. |
| `EurojackpotAIMLEngine` | `scripts/generators/ultimate_ai_ml_eurojackpot_generator.py` | RandomForest-Modelle. **Achtung:** eine Klasse mit identischem Namen existiert nochmal in der Backup-Datei (siehe Abschnitt 5) — beim Editieren die richtige Datei prüfen. |
| `DeepLearningEngine` | `scripts/utils/deep_learning_engine_pytorch.py` | LSTM (PyTorch), analog zu Lotto. |
| `UltimateAIMLEurojackpotGenerator` | `scripts/generators/ultimate_ai_ml_eurojackpot_generator.py` | **God Node der Pipeline** (40 Kanten im Code-Graph) — zentraler Einstiegspunkt `generate_ultimate_tips()`. |
| `EurojackpotPatternEngine`, `EurojackpotHybridOptimizer` | `scripts/generators/ultimate_ai_ml_eurojackpot_generator.py` | Wie bei Lotto: historische Muster bzw. Kandidaten-Generierung für HYBRID-OPT. |
| `EurojackpotRealTimeLearner` | `scripts/generators/ultimate_ai_ml_eurojackpot_generator.py` | Persistiert Learning-State, passt `strategy_weights` an. |
| `EurojackpotPerformanceTracker` | `scripts/generators/ultimate_ai_ml_eurojackpot_generator.py` | Loggt Trefferauswertungen. |
| `EurojackpotNotifier` | `scripts/utils/notifier.py` | Telegram-Benachrichtigungen. |
### Die 4 Tipp-Strategien
Analog zu Lotto: HYBRID-OPT, BALANCED-SPREAD, HIGH-EV, SOFT-CONTRARIAN —
gleiche Namen, gleiches Grundprinzip, aber Zahlenraum 1–50 (5 Hauptzahlen)
statt 1–49 (6 Zahlen) plus zusätzlich 2 Eurozahlen (`_get_smart_euro_numbers`).
## 3. Design-Entscheidung: Quality-Score = EV-Optimierung — hier noch nicht nachgezogen
Wie beim Lotto-Projekt gilt: Eurojackpot-Ziehungen sind unabhängige
Zufallsereignisse, kein Modell kann die Trefferwahrscheinlichkeit über den
Zufalls-Erwartungswert heben. `_calculate_quality_score()` sollte deshalb auf
Expected Value (unpopuläre Kombinationen → höhere Auszahlung bei Treffer)
optimieren.
**Der Code hier entspricht noch dem alten, unrevidierten Lotto-Stand
(vor der Überarbeitung dort):**
- `_calculate_popularity_score()` (Zeile 688) nutzt weiterhin die ad-hoc
`lucky_numbers = {3, 7, 9, 11, 13, 17, 19, 21, 23}`-Liste ohne empirische
Grundlage, statt der bei Lotto inzwischen verwendeten
`POPULAR_PLAYER_PICKS = {5, 7, 9, 11, 12, 13}`.
- Nur direkte ±1-Nachbarn werden als Muster erkannt, keine allgemeinen
arithmetischen Folgen (z.B. 5-10-15-20-25).
- Kein Odd/Even-Split-Kriterium.
- Popularity zählt nur 20% der Quality-Formel (`main_quality` 25%,
`euro_quality` 15%, `pattern_quality` 15%, `diversity` 10%, `popularity`
20%, `recency` 15%) — Recency/Pattern-Anteile folgen Heuristiken, die auch
andere Systemspieler nutzen und damit das EV-Ziel eher unterlaufen.
- **`_get_smart_euro_numbers()`** (Zeile 673) hat **gar keine**
EV-Betrachtung — die 2 Eurozahlen werden rein nach AI-Score gewählt, analog
zur alten (inzwischen bei Lotto durch eine EV-Heuristik ersetzten)
Superzahl-Logik.
Eine Übertragung der Lotto-Fixes (siehe dortiges `ARCHITECTURE.md` Abschnitt 3)
auf dieses Projekt steht noch aus.
## 4. Automatisierung
Läuft über **launchd** (`~/Library/LaunchAgents/`), nicht über `crontab`:
| launchd Job | Plist | Zeitplan |
|---|---|---|
| `com.eurojackpot.update` | `scripts/automation/com.eurojackpot.update.plist` | Mi + Sa, 08:00 Uhr |
| `com.eurojackpot.weekly` | `scripts/automation/com.eurojackpot.weekly.plist` | Mo + Do, 21:00 Uhr |
## 5. Bekannte Schwachstellen / offene Punkte
- **Echtes Klassen-Duplikat:** `UltimateAIMLEurojackpotGenerator` (inkl.
`EurojackpotAIMLEngine`, `EurojackpotPatternEngine`,
`EurojackpotHybridOptimizer`) ist **wortgleich** sowohl in der aktiven
`scripts/generators/ultimate_ai_ml_eurojackpot_generator.py` als auch in
`scripts/generators/ultimate_ai_ml_eurojackpot_generator_v2.1_backup.py`
definiert. Nur die erste Datei wird importiert
(`auto_update_and_learn.py`, `weekly_tip_generator.py`).
- **Dritter, eigenständiger Generator:** `optimized_eurojackpot_generator.py`
(Klasse `UltimativerEurojackpotGenerator`) ist im README als Feature
dokumentiert, aber nirgends in der Automatisierung importiert.
- **Ungenutzter zweiter Updater:** `scripts/utils/update_historical_data.py`
(`EurojackpotDataUpdater`, eigene Quellen euro-jackpot.net/eurojackpot.de)
wird von keinem aktiven Skript referenziert.
- **~12 Standalone-Analyse-/Utility-Skripte** ohne Anbindung an die
Automatisierung: `eurojackpot_processor.py`, `eurojackpot_processor_fixed.py`,
`eurojackpot_simple.py`, `bereichskombinationen_analyse.py`,
`positionsanalyse.py`, `zahlen_umschluesseln.py`,
`treffer_analyse_umschluesselt.py`, `simple_bereichsanalyse.py`,
`create_example_files.py`, `tipp_generator_nmmhh.py`,
`tipp_generator_nmmhh_v2.py`, `eurojackpot_bereichsanalyse.py`,
`eurojackpot_generator.py`.
- **Popularity/Quality-Score veraltet** — siehe Abschnitt 3.
- **`documentation/`-Ordner** enthält laut README selbst "Alte Dokumentation"
(`README 2.md`, `NOTIFICATIONS_SETUP.md`, `ULTIMATE_GENERATOR_GUIDE.md`) —
Aktualität gegenüber dem laufenden Code nicht verifiziert.
## 6. Code-Graph
Navigierbare Graph-Ansicht unter `graphify-out/`:
- `graphify-out/graph.html` — interaktive Visualisierung
- `graphify-out/GRAPH_REPORT.md` — God Nodes, Communities, auffällige Verbindungen
- `graphify-out/graph.json` — Rohdaten
Bei strukturellen Änderungen: `/graphify --update` zum inkrementellen
Neuaufbau.
## 7. Tests
`tests/test_popularity_score.py` (pytest) prüft den Popularity/EV-Score
gegen bekannte Vielspieler-Kombinationen (portiert von Lotto) und deckt
außerdem den Euro-Zahlen-Determinismus-Bug ab (Tipps #1-3 lieferten früher
immer dasselbe Paar). Ausführen mit `pytest tests/`.