Files
trading-daemon/README.md
Melchior Reimers ad890d23b0
All checks were successful
Deployment / deploy-docker (push) Successful in 23s
bugfixes
2026-02-17 13:56:02 +01:00

180 lines
7.5 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.
# Trading Data Daemon
Ein modularer Daemon zum Herunterladen und Speichern von Handelsdaten von verschiedenen deutschen Börsen in QuestDB (Time-Series-Datenbank).
## Unterstützte Exchanges
- **European Investor Exchange (EIX)** — Streaming-Verarbeitung (große CSV-Dateien)
- **Lang & Schwarz (LS)** — JSON/CSV-RPC API
- **Deutsche Börse** — Xetra, Frankfurt, Quotrix
- **Gettex** — Bayerische Börse (MUNC/MUND)
- **Stuttgart** — MiFIR II Delayed Data
- **Börsenag** — Düsseldorf (DUSA/DUSB/DUSC/DUSD), Hamburg (HAMA/HAMB), Hannover (HANA/HANB)
## Architektur
Fünf Microservices, orchestriert via Docker Compose:
```
┌─────────────────────────────────────────────────────────────────┐
│ QuestDB │
│ (9000=HTTP, 8812=PostgreSQL, 9009=ILP) │
└──────────┬──────────────┬──────────────┬──────────────┬─────────┘
│ │ │ │
┌──────┴──────┐ ┌─────┴─────┐ ┌──────┴──────┐ ┌─────┴─────┐
│ fetcher │ │ analytics │ │ metadata │ │ dashboard │
│ daemon.py │ │ worker │ │ fetcher │ │ :8080 │
└─────────────┘ └───────────┘ └─────────────┘ └───────────┘
```
- **Fetcher (`daemon.py`):** Orchestrator. Holt Trades von allen Börsen täglich um 23:00. Streaming für EIX, Batch für alle anderen. Deduplizierung via Hash-Cache.
- **Analytics Worker (`src/analytics/worker.py`):** Berechnet aggregierte Tabellen für Zeiträume: 7, 30, 42, 69, 180, 365 Tage.
- **Metadata Fetcher (`src/metadata/fetcher.py`):** Reichert ISINs mit Firmen-/Sektordaten an (OpenFIGI API, yfinance).
- **Dashboard (`dashboard/server.py`):** FastAPI-Server mit REST-Endpunkten und statischem UI aus `dashboard/public/`.
## Datenbank-Schema
QuestDB speichert alle Daten via Influx Line Protocol (ILP) mit Nanosekunden-Präzision.
### `trades`
Rohe Handelsdaten aller Börsen. Geschrieben vom Fetcher.
| Spalte | Typ | Beschreibung |
|--------|-----|-------------|
| `timestamp` | timestamp | Zeitpunkt des Trades |
| `exchange` | symbol (tag) | Börsenname (z.B. `XETRA`, `LS`, `GETTEX`) |
| `symbol` | symbol (tag) | Wertpapiername |
| `isin` | symbol (tag) | ISIN-Kennung (z.B. `DE000BAY0017`) |
| `price` | double | Handelspreis |
| `quantity` | double | Handelsvolumen (Stückzahl) |
### `analytics_exchange_daily`
Tägliche Aggregationen pro Börse mit Moving Averages. Geschrieben vom Analytics Worker.
| Spalte | Typ | Beschreibung |
|--------|-----|-------------|
| `timestamp` | timestamp | Tag der Aggregation |
| `exchange` | symbol (tag) | Börsenname |
| `trade_count` | long | Anzahl Trades am Tag |
| `volume` | double | Gesamtvolumen (Summe von Preis × Menge) |
| `ma{N}_count` | double | N-Tage Moving Average der Trade-Anzahl |
| `ma{N}_volume` | double | N-Tage Moving Average des Volumens |
*N = 7, 30, 42, 69, 180, 365*
### `analytics_daily_summary`
Tagesübergreifende Zusammenfassung aller Börsen. Geschrieben vom Analytics Worker.
| Spalte | Typ | Beschreibung |
|--------|-----|-------------|
| `timestamp` | timestamp | Tag der Zusammenfassung |
| `total_trades` | long | Gesamtanzahl Trades über alle Börsen |
| `total_volume` | double | Gesamtvolumen über alle Börsen |
| `unique_assets` | long | Anzahl verschiedener gehandelter ISINs |
### `analytics_stock_trends`
Trendanalyse pro ISIN mit prozentualen Veränderungen. Geschrieben vom Analytics Worker.
| Spalte | Typ | Beschreibung |
|--------|-----|-------------|
| `timestamp` | timestamp | Analysedatum |
| `isin` | symbol (tag) | ISIN-Kennung |
| `trade_count` | long | Gesamtanzahl Trades im Zeitraum |
| `volume` | double | Gesamtvolumen im Zeitraum |
| `count_change_pct` | double | Prozentuale Änderung der Trade-Anzahl (1. vs. 2. Hälfte) |
| `volume_change_pct` | double | Prozentuale Änderung des Volumens |
| `period_days` | long | Zeitraum in Tagen (7/30/42/69/180/365) |
### `analytics_volume_changes`
Volumen- und Anzahländerungen pro Börse mit Trendklassifizierung. Geschrieben vom Analytics Worker.
| Spalte | Typ | Beschreibung |
|--------|-----|-------------|
| `timestamp` | timestamp | Analysedatum |
| `exchange` | symbol (tag) | Börsenname |
| `trend` | symbol (tag) | Trendklasse (s.u.) |
| `trade_count` | long | Gesamtanzahl Trades im Zeitraum |
| `volume` | double | Gesamtvolumen im Zeitraum |
| `count_change_pct` | double | Prozentuale Änderung der Trade-Anzahl |
| `volume_change_pct` | double | Prozentuale Änderung des Volumens |
| `period_days` | long | Zeitraum in Tagen |
**Trendklassen:** `mehr_trades_mehr_volumen`, `mehr_trades_weniger_volumen`, `weniger_trades_mehr_volumen`, `weniger_trades_weniger_volumen`, `stabil`
### `analytics_custom`
Vorberechnete Custom-Analytics für den Dashboard-Graphen-Builder. Geschrieben vom Analytics Worker.
| Spalte | Typ | Beschreibung |
|--------|-----|-------------|
| `timestamp` | timestamp | Tag der Berechnung |
| `y_axis` | symbol (tag) | Metrik-Typ (`volume`, `trade_count`, `avg_price`) |
| `group_by` | symbol (tag) | Gruppierung (`exchange`, `isin`, `date`) |
| `exchange_filter` | symbol (tag) | Exchange-Filter (Börsenname oder `all`) |
| `group_value` | string | Wert der Gruppierung (z.B. Börsenname, ISIN) |
| `y_value` | double | Berechneter Metrik-Wert |
### `metadata`
ISIN-Stammdaten (Firmenname, Land, Sektor). Geschrieben vom Metadata Fetcher.
| Spalte | Typ | Beschreibung |
|--------|-----|-------------|
| `timestamp` | timestamp | Zeitpunkt der letzten Aktualisierung |
| `isin` | symbol (tag) | ISIN-Kennung |
| `name` | string | Firmen-/Wertpapiername |
| `country` | string | Ländercode oder -name |
| `continent` | string | Kontinent |
| `sector` | string | Branchenklassifizierung |
## Installation und Setup
### 1. QuestDB starten (via Docker Compose)
```bash
docker-compose up -d
```
QuestDB ist dann unter `http://localhost:9000` erreichbar.
### 2. Python Abhängigkeiten installieren
```bash
pip install -r requirements.txt
```
### 3. Manuell starten
```bash
python3 daemon.py # Fetcher
python -m src.analytics.worker # Analytics Worker
python src/metadata/fetcher.py # Metadata Fetcher
python dashboard/server.py # Dashboard (Port 8000)
```
### 4. Systemd Service (optional)
```bash
sudo cp systemd/trading-daemon.service /etc/systemd/system/
sudo cp systemd/trading-daemon.timer /etc/systemd/system/
sudo systemctl daemon-reload
sudo systemctl enable --now trading-daemon.timer
```
## Umgebungsvariablen
| Variable | Default | Beschreibung |
|----------|---------|-------------|
| `DB_USER` | `admin` | QuestDB Benutzername |
| `DB_PASSWORD` | `quest` | QuestDB Passwort |
| `DB_HOST` | `questdb` | QuestDB Hostname (Docker-intern) |
## Erweiterung
Um eine neue Börse hinzuzufügen:
1. Erstelle eine neue Klasse in `src/exchanges/`, die von `BaseExchange` erbt
2. Implementiere `fetch_latest_trades()` (gibt `List[Trade]` zurück)
3. Implementiere die `name`-Property
4. Registriere in `daemon.py` unter `STREAMING_EXCHANGES` (große Daten) oder `STANDARD_EXCHANGES` (Batch)