import logging import os from dotenv import load_dotenv from pydantic import BaseModel load_dotenv() class BotConfig(BaseModel): """Bot configuration from environment variables.""" # Binance API binance_api_key_testnet: str = os.getenv("BINANCE_API_KEY_TESTNET", "") binance_api_secret_testnet: str = os.getenv("BINANCE_API_SECRET_TESTNET", "") binance_api_key_live: str = os.getenv("BINANCE_API_KEY_LIVE", "") binance_api_secret_live: str = os.getenv("BINANCE_API_SECRET_LIVE", "") # Bot dry_run: bool = os.getenv("DRY_RUN", "false").lower() == "true" environment: str = os.getenv("ENVIRONMENT", "testnet") # "testnet" or "live" trading_pair: str = os.getenv("TRADING_PAIR", "BTCUSDT") dca_amount_usd: float = float(os.getenv("DCA_AMOUNT", "10")) dca_interval_hours: float = float(os.getenv("DCA_INTERVAL_HOURS", "1")) stop_loss_percent: float = float(os.getenv("STOP_LOSS_PERCENT", "2")) # Telegram telegram_bot_token: str = os.getenv("TELEGRAM_BOT_TOKEN", "") telegram_chat_id: str = os.getenv("TELEGRAM_CHAT_ID", "") # Obsidian obsidian_vault_path: str = os.getenv("OBSIDIAN_VAULT_PATH", "/opt/obsidian/config/Vault/Test/") obsidian_trade_log_file: str = os.getenv("OBSIDIAN_TRADE_LOG_FILE", "BrainDock/trading-log.md") # Database db_path: str = os.getenv("DB_PATH", "/data/bot_state.db") class Config: env_file = ".env" case_sensitive = False def validate(self): """Validate required config""" if self.environment not in ("testnet", "live"): raise ValueError("ENVIRONMENT must be 'testnet' or 'live'") if self.environment == "testnet": if not self.binance_api_key_testnet or not self.binance_api_secret_testnet: raise ValueError("Testnet API credentials required") else: if not self.binance_api_key_live or not self.binance_api_secret_live: raise ValueError("Live API credentials required") if not self.telegram_bot_token or not self.telegram_chat_id: logger.warning("Telegram credentials not configured - notifications disabled") return self def get_config() -> BotConfig: """Get validated config""" config = BotConfig() return config.validate()