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:
@@ -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 (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.
|
||||
Reference in New Issue
Block a user