Add ARCHITECTURE.md documenting data flow and active vs. legacy code

Built with a graphify code-graph pass, mirroring the audit done on the
sibling Lotto 6aus49 project. Documents the ingestion -> training ->
tip generation -> notification flow and several findings:

- The data-fetch fallback chain (lottoAPI/Lottoland/Sazka.cz + web
  scraper) is already more robust here than Lotto's was before its fix.
- UltimateAIMLEurojackpotGenerator (and its EurojackpotAIMLEngine/
  PatternEngine/HybridOptimizer) is duplicated verbatim in an unused
  ultimate_ai_ml_eurojackpot_generator_v2.1_backup.py.
- A third standalone generator (optimized_eurojackpot_generator.py)
  and a second updater (update_historical_data.py) exist but aren't
  wired into automation, alongside ~12 unreferenced analysis scripts.
- The popularity/quality score still uses the pre-fix Lotto approach
  (ad-hoc lucky-number list, no arithmetic-progression detection, no
  odd/even split heuristic, popularity only 20% of quality) and Euro
  number selection has no EV consideration at all - a follow-up to
  port the Lotto fix has not been done yet.

graphify-out/ itself is gitignored as a regenerable build artifact.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
2026-08-10 18:50:02 +02:00
co-authored by Claude Sonnet 5
parent f8fbe265c0
commit 5703e6a12c
2 changed files with 164 additions and 0 deletions
+3
View File
@@ -33,3 +33,6 @@ data/backups/
data/*.backup* data/*.backup*
data/generated_tips/weekly_tips_*.csv data/generated_tips/weekly_tips_*.csv
data/performance_reports/ data/performance_reports/
# graphify Code-Graph (regenerierbar via /graphify --update)
graphify-out/
+161
View File
@@ -0,0 +1,161 @@
# 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 (150) + 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 150 (5 Hauptzahlen)
statt 149 (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.