C3H HUMAN REVIEW WAVE 1: migriert 16 freigegebene HR-A PAIR_MIGRATION_SAFE Paare. Pro Pair: Root (representation=source) + Canonical (representation=canonical, derived_from=Root-ID) atomar. Body byte-genau unveraendert. IDs stabil aus C3 Mapping Preview v2. modul-12/18/19/vps.md NICHT angefasst. Knowledge schema v1. (Red Queen)
7.7 KiB
| knowledge_schema | id | type | role | representation | state |
|---|---|---|---|---|---|
| 1 | object/6fca3e3a-70b2-0927-d7fb-e650a8f0e7f8 | arch | module | source | current |
Modul-04-Market-Regime — Betriebsdokumentation
Erstellt: 20.08.2026 (Rain Ocampo) · Status: ✅ Freigegeben (E2E bestanden)
Zweck
Erster Consumer der Market-Data-Events von Modul-03. Pipeline:
MARKET_DATA_READY / MARKET_CANDLE_CLOSED (Modul-03) → Regime-Berechnung → PostgreSQL (market_regime) → MARKET_REGIME_READY
Deterministische, regelbasierte Engine — bewusst OHNE KI/ML.
Container
| Attribut | Wert |
|---|---|
| Name | Modul-04-Market-Regime |
| Image | market-regime:1.0.0 (lokal gebaut) |
| Port | 55004 — NUR intern (expose, nicht öffentlich) |
| Netzwerk | trading-modules (bridge) |
| Build-Context | /opt/trading-modules/modul04-market-regime/ |
| Restart | unless-stopped |
| Healthcheck | ✅ healthy |
Deployment
cd /opt/trading-modules
docker compose build modul-04-market-regime
docker compose up -d --no-deps --force-recreate modul-04-market-regime
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 |
LOG_LEVEL |
INFO |
Strukturiertes Logging |
Keine festen IPs — nur Docker-interne Hostnamen. Creds via Compose env + Defaults.
Architektur
Modul-03 ──market.data.ready / market.data.candle.closed──▶ RegimeConsumer
│ (bindet beide Routing-Keys)
▼
RegimeEngine (deterministisch)
EMA / ADX / ATR / Slope / Preisstruktur
│
┌───────────┴───────────┐
▼ ▼
market_regime (PG) MARKET_REGIME_READY
(16 Spalten) → market.regime.ready
- Consumer (
app/consumer/consumer.py): bindetmarket.data.ready+market.data.candle.closed; durable Queuemarket-regime.input; manuelles Ack; Reconnect mit Backoff; schließt alte Verbindung beim Reconnect (verhindert Consumer-Leak/Nachrichtenverlust). - Engine (
app/regime/engine.py): deterministisch, ohne KI. - Storage (
app/storage/storage.py): idempotent via partiellen Unique-Index. - Publisher (
app/publisher/publisher.py): publiziertMARKET_REGIME_READYaufmarket.regime(Routingmarket.regime.ready). - History-Client (
app/marketdata/client.py): liest OHLCV über interne FastAPI Modul-03 (http://Modul-03-Market-Data:55003/history/{symbol}).
Regime-Engine (app/regime/engine.py)
Deterministische Regel-Engine (Version 1.0.0), 7 Regime:
TREND_UP, TREND_DOWN, RANGE, HIGH_VOLATILITY, LOW_VOLATILITY, TRANSITION, UNKNOWN
Indikatoren & Metriken:
| Indikator | Fenster/Param | Zweck |
|---|---|---|
| EMA fast/slow | 10 / 30 | Trendrichtung (EMA-Flanken-Differenz) |
| ADX | 14 | Trendstärke (≥20 = echter Trend) |
| ATR | 14 | Volatilität (absolut + Ratio + Perzentil) |
| Slope | 20 | normierte Steigung der Close-Linie |
| Preisstruktur | — | higher_highs / lower_lows / range |
Zentrale Schwellenwerte (app/config.py, env-overridable):
| Parameter | Default | Bedeutung |
|---|---|---|
min_candles_required |
30 | UNKNOWN, wenn weniger Daten |
regime_lookback |
60 | max. Kerzen für Berechnung |
trend_min_ema_gap |
0.02 | |
adx_trend_threshold |
20.0 | ADX ≥ → echter Trend |
slope_up/down_threshold |
0.05 / -0.05 | normierte Steigung |
range_atr_ratio |
0.02 | ATR/close darunter = Range |
atr_high_vol_multiplier |
1.5 | ATR jetzt > hist_mean × → HIGH_VOL |
atr_low_vol_multiplier |
0.6 | ATR jetzt < hist_mean × → LOW_VOL |
high_vol_atr_ratio |
0.03 | ATR/close ≥ → starke Vol |
low_vol_atr_ratio |
0.008 | ATR/close ≤ → geringe Vol |
slope_threshold |
0.01 | |
transition_min_events |
3 | Events für TRANSITION |
Datenbank (Modul-01-PostgreSQL)
Tabelle public.market_regime (16 Spalten, eigene Tabelle — bestehende unangetastet):
symbol TEXT, asset_class TEXT, timeframe TEXT, provider TEXT,
regime TEXT, confidence INTEGER (0-100),
trend_strength DOUBLE PRECISION, volatility_state TEXT,
timestamp TIMESTAMPTZ, indicators_json JSONB,
candles_used INTEGER, version TEXT,
source_event_id TEXT, correlation_id TEXT,
data_ts TIMESTAMPTZ, data_ts_end TIMESTAMPTZ
- Unique (partiell):
uq_market_regime_srcauf(symbol, timeframe, source_event_id)WHERE source_event_id IS NOT NULL → Idempotenz. - Migration:
migrations/001_market_regime.sql(idempotent, löscht nichts).
RabbitMQ (Modul-02)
| Exchange | Typ | Routing | Event |
|---|---|---|---|
market.data |
topic | market.data.ready (eingang) |
MARKET_DATA_READY |
market.data |
topic | market.data.candle.closed (eingang) |
MARKET_CANDLE_CLOSED |
market.regime |
topic | market.regime.ready (ausgang) |
MARKET_REGIME_READY |
Interne API
| Endpoint | Zweck |
|---|---|
GET /health |
Liveness (200 immer) + Komponentenstatus im Body |
GET /health/ready |
Readiness (503 wenn PG/RabbitMQ/Modul-03 down) |
GET /regime/{symbol} |
Regime-Einträge abfragen |
GET /regime/latest/{symbol} |
Letztes Regime eines Symbols |
End-to-End-Test (20.08.2026, final, nach Rebuild) ✅
Kette verifiziert: Modul-03 Ingest → market.data.ready → Modul-04 Consumer → RegimeEngine → market_regime → MARKET_REGIME_READY auf market.regime.ready.
| Fall | Regime | Conf | candles | version | Event | DB |
|---|---|---|---|---|---|---|
| M4TREND_UP (40) | TREND_UP | 100 | 40 | 1.0.0 | genau 1 | ✅ |
| M4TREND_DN (40) | TREND_DOWN | 100 | 40 | 1.0.0 | genau 1 | ✅ |
| M4RANGE (40) | LOW_VOLATILITY (Range) | 60 | 40 | 1.0.0 | genau 1 | ✅ |
| M4HIGHVOL (40) | HIGH_VOLATILITY | 75 | 40 | 1.0.0 | genau 1 | ✅ |
| M4UNKNOWN (5) | UNKNOWN | 20 | 5 | 1.0.0 | genau 1 | ✅ |
| M4IDEMPOT (40) | TREND_UP | 100 | 40 | 1.0.0 | genau 1 | ✅ |
Idempotenz: dasselbe Quell-Event (source_event_id) erneut → kein zweiter Datensatz, kein Doppel-Event. ✅
Logs: keine Errors/Tracebacks. Health {postgresql:true, rabbitmq:true, market_data_ready:true}. ✅
Bugs behoben während E2E (20.08.2026)
| Bug | Fix |
|---|---|
can't adapt type 'dict' (JSONB) |
json.dumps(ind.model_dump(mode="json")) |
tuple index out of range (16/15) |
version in INSERT-VALUES ergänzt |
ON CONFLICT + partieller Index Fehler |
WHERE source_event_id IS NOT NULL in Klausel |
model_dump(default=...) TypeError |
default-Kwarg entfernt (model_dump(mode="json")) |
| Consumer-Verbindungs-Leak | conn.close() bei Reconnect → kein Message-Leak |
Offene Punkte
- Consumer-Downstream für
market.regime.ready(Modul-05+) - Bestätigte TRANSITION-Detektion mit echten Folgedaten
Geändert von: Rain Ocampo
Datum: 20.08.2026
Grund: Modul-04-Dokumentation angelegt (Regime-Engine, market_regime-Schema, Events, E2E freigegeben).