5 KiB
5 KiB
| type | _organized |
|---|---|
| Trading-Modul-System | true |
Modul-03-Market-Data — Betriebsdokumentation
Erstellt: 20.08.2026 (Rain Ocampo) · Status: ✅ In Betrieb (healthy)
Zweck
Zentrale Marktdatenquelle des Trading-Systems. Pipeline:
Marktdaten → Validierung → Normalisierung → PostgreSQL → RabbitMQ-Event
Keine Strategie, keine Orders, keine KI — nur zuverlässige Marktdaten.
Container
| Attribut | Wert |
|---|---|
| Name | Modul-03-Market-Data |
| Image | market-data:0.1.0 (lokal gebaut) |
| Port | 55003 — NUR intern (expose, nicht öffentlich) |
| Netzwerk | trading-modules (bridge) |
| Build-Context | /opt/trading-modules/modul03-market-data/ |
| Restart | unless-stopped |
| Healthcheck | ✅ healthy |
Deployment
cd /opt/trading-modules
docker compose build modul-03-market-data
docker compose up -d modul-03-market-data
Environment Variables (Compose)
| Variable | Wert (Default) | Zweck |
|---|---|---|
PG_HOST |
Modul-01-PostgreSQL |
Docker-interner Servicename |
PG_PORT |
5432 |
intern (Host: 55432) |
PG_USER/PASSWORD/DB |
trading |
aus .env-Defaults |
RABBITMQ_HOST |
Modul-02-RabbitMQ |
Docker-interner Servicename |
RABBITMQ_PORT |
5672 |
intern (Host: 55672) |
RABBITMQ_USER/PASSWORD/VHOST |
trading |
vhost trading |
DATA_PROVIDER |
noop |
noop / demo / später Broker |
LOG_LEVEL |
INFO |
Strukturiertes Logging |
Keine festen IPs — nur Docker-interne Hostnamen. Creds via Compose env + ${VAR:-default}.
Datenbank (Modul-01-PostgreSQL)
Tabelle public.ohlcv:
symbol TEXT, asset_class TEXT, provider TEXT, timeframe TEXT,
ts TIMESTAMPTZ, open/high/low/close DOUBLE PRECISION, volume DOUBLE PRECISION,
created_at TIMESTAMPTZ DEFAULT now(), id BIGSERIAL PRIMARY KEY
Finale Constraints & Indizes (Stand 20.08.2026)
| Index | Typ |
|---|---|
uq_ohlcv_provider_symbol_tf_ts |
UNIQUE (provider, symbol, timeframe, ts) |
ohlcv_pkey |
UNIQUE (id) |
idx_ohlcv_symbol_tf |
(symbol, timeframe) |
idx_ohlcv_symbol_tf_ts |
(symbol, timeframe, ts DESC) |
idx_ohlcv_provider_symbol_tf_ts |
(provider, symbol, timeframe, ts DESC) |
Der Unique-Index inkludiert den Provider — langfristig werden mehrere Provider/Broker unterstützt (gleiche Symbol+Timeframe+Timestamp können von verschiedenen Quellen kommen).
Migrationen: /app/migrations/001_ohlcv.sql + 002_unique_provider.sql
(idempotent, löschen nichts; automatisch via ensure_schema()/glob angewendet).
RabbitMQ (Modul-02)
- Exchange:
market.data(topic, durable) - vhost:
trading(wichtig!) - Routing-Keys:
| Routing-Key | Event-Typ | Wann |
|---|---|---|
market.data.ready |
MARKET_DATA_READY |
Batch/Import — EIN Event pro Batch, candle_count + batch:true |
market.data.candle.closed |
MARKET_CANDLE_CLOSED |
Live — pro abgeschlossener Kerze EIN Event, OHLCV im payload |
- Eventschema v1.0:
event_id, event_type, event_version, timestamp, symbol, asset_class, timeframe, provider+ payload.
Interne API
| Endpoint | Zweck |
|---|---|
GET /health |
Liveness (200 immer) + Komponentenstatus im Body |
GET /health/ready |
Readiness (503 wenn PG/RabbitMQ down) |
POST /ingest |
Kerzen einspeisen (JSON: {"candles":[...]}) |
GET /prices/{symbol} |
Letzte Kurse |
GET /history/{symbol}?timeframe= |
Historische OHLCV |
Provider-Adapter
app/providers/providers.py:
DataProvider(ABC) — abstrakte Schnittstellefetch_ohlcv(),health()NoopProvider— keine Datenquelle konfiguriert (Default)DemoProvider— synthetische OHLCV-Daten für Tests- Neue Broker = neue Klasse, umschalten via
DATA_PROVIDERenv → keine harte Anbieter-Kopplung
Validierung (app/validation/validator.py)
- Timestamp gültig (UTC, nicht Zukunft, nicht zu alt/stale)
- OHLC-Werte > 0
- High ≥ Low, High ≥ Open/Close, Low ≤ Open/Close
- Duplikat-Erkennung (Storage + DB-Unique-Index)
End-to-End-Test (20.08.2026, nach Provider-Constraint-Upgrade) ✅
- Batch-Pfad: 4 GOOG-Kerzen → saved:4, GENAU EIN
MARKET_DATA_READY(routingmarket.data.ready, candle_count:4). 3 NVDA → saved:3, EIN Event. - Live-Pfad: 1 AMZN-Candle →
MARKET_CANDLE_CLOSED(routingmarket.data.candle.closed, OHLCV im payload). - Provider-Duplikat: identische NVDA-Kerze erneut →
duplicate, kein Insert, kein Event. - Port-Sicherheit: 55003 von außen (
http://187.124.31.123:55003/health) → nicht erreichbar ✅ - Datenbestand final: AAPL 5, GOOG 4, NVDA 3, EURUSD 3, TSLA 4, MSFT 1, AMZN 1.
Offene Punkte
- Echter Broker-/Datenprovider-Adapter (Interface bereit, noop/demo Defaults)
- Zusätzliche Daten (Bid/Ask/Spread, Ticks, Fundamentaldaten) — vorbereitet
- Consumer für
market.data.ready/market.data.candle.closed(Modul-04 ff.)
Geändert von: Rain Ocampo
Datum: 20.08.2026
Grund: Modul-03-Dokumentation angelegt (Provider-Constraint, Event-Trennung, Port-Nicht-Exposition).