""" Configuration via pydantic-settings. All secrets come from .env; no defaults for sensitive keys. """ 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", ) # ── Binance (no key needed for public WS) ────────────────────────── binance_ws_url: str = "wss://stream.binance.com:9443/ws" binance_rest_url: str = "https://api.binance.com" # ── Bybit (backup crypto — no key needed) ────────────────────────── bybit_ws_url: str = "wss://stream.bybit.com/v5/public/spot" # ── Alpaca (paper trading — free tier) ───────────────────────────── alpaca_key: str = "" alpaca_secret: str = "" alpaca_base_url: str = "https://paper-api.alpaca.markets" alpaca_data_ws_url: str = "wss://stream.data.alpaca.markets/v2/iex" alpaca_dry_run: bool = True # True = skip real API calls if no keys # ── Storage ──────────────────────────────────────────────────────── sqlite_url: str = "sqlite+aiosqlite:///market_data.db" jsonl_path: str = "events.jsonl" # ── Reliability ──────────────────────────────────────────────────── reconnect_max_retries: int = 20 reconnect_base_delay: float = 1.0 # seconds, exponential backoff reconnect_max_delay: float = 60.0 heartbeat_timeout: float = 30.0 # no-message timeout → reconnect # ── Metrics / HTTP ───────────────────────────────────────────────── http_host: str = "0.0.0.0" http_port: int = 8891 metrics_enabled: bool = True # ── NATS output adapter ───────────────────────────────────────────── nats_url: str = "" # e.g. "nats://localhost:4222" nats_subject_prefix: str = "md.events" # → md.events.trade.BTCUSDT nats_enabled: bool = False # ── Logging ──────────────────────────────────────────────────────── log_level: str = "INFO" log_sample_rate: int = 100 # PrintConsumer: log 1 out of N events @property def alpaca_configured(self) -> bool: return bool(self.alpaca_key and self.alpaca_secret) @property def nats_configured(self) -> bool: return bool(self.nats_url and self.nats_enabled) settings = Settings()