""" Configuration via pydantic-settings. All settings from ENV or .env file. """ from __future__ import annotations from pydantic_settings import BaseSettings, SettingsConfigDict class Settings(BaseSettings): model_config = SettingsConfigDict( env_file=".env", env_file_encoding="utf-8", extra="ignore", ) # ── NATS ────────────────────────────────────────────────────────── nats_url: str = "nats://localhost:4222" nats_subject: str = "md.events.>" nats_queue_group: str = "senpai-md" use_jetstream: bool = False # ── Internal queue ──────────────────────────────────────────────── queue_size: int = 50_000 queue_drop_threshold: float = 0.9 # start dropping at 90% # ── Features / signals ──────────────────────────────────────────── features_enabled: bool = True features_pub_rate_hz: float = 10.0 # max publish rate per symbol features_pub_subject: str = "senpai.features" signals_pub_subject: str = "senpai.signals" alerts_pub_subject: str = "senpai.alerts" # ── Rolling window ──────────────────────────────────────────────── rolling_window_seconds: float = 60.0 # ── Signal rules (rule-based MVP) ───────────────────────────────── signal_return_threshold: float = 0.003 # 0.3% signal_volume_threshold: float = 1.0 # min volume in 10s signal_spread_max_bps: float = 20.0 # max spread in bps # ── Alert thresholds ────────────────────────────────────────────── alert_latency_ms: float = 1000.0 # alert if p95 latency > this alert_gap_seconds: float = 30.0 # alert if no events for N sec # ── HTTP ────────────────────────────────────────────────────────── http_host: str = "0.0.0.0" http_port: int = 8892 # ── Logging ─────────────────────────────────────────────────────── log_level: str = "INFO" settings = Settings()