Melchior Reimers ad890d23b0
All checks were successful
Deployment / deploy-docker (push) Successful in 23s
bugfixes
2026-02-17 13:56:02 +01:00
2026-01-27 11:30:50 +01:00
2026-02-16 11:59:53 +01:00
2026-01-25 18:02:20 +01:00
2026-01-25 17:36:29 +01:00
2026-01-25 17:36:29 +01:00
2026-02-17 13:56:02 +01:00
2026-02-17 13:56:02 +01:00
2026-01-27 09:59:43 +01:00

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

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)

docker-compose up -d

QuestDB ist dann unter http://localhost:9000 erreichbar.

2. Python Abhängigkeiten installieren

pip install -r requirements.txt

3. Manuell starten

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)

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)
Description
No description provided
Readme 1 MiB
Languages
Python 72%
HTML 22.3%
PowerShell 3.5%
Shell 1.2%
JavaScript 0.9%
Other 0.1%