""" Configuration settings for the Crypto Trading Bot Dashboard. """ import os from pathlib import Path from typing import Optional from dotenv import load_dotenv from pydantic import Field from pydantic_settings import BaseSettings # Load environment variables from .env file env_file = Path(__file__).parent.parent / ".env" if env_file.exists(): load_dotenv(env_file) class DatabaseSettings(BaseSettings): """Database configuration settings.""" host: str = Field(default="localhost", env="POSTGRES_HOST") port: int = Field(default=5434, env="POSTGRES_PORT") database: str = Field(default="dashboard", env="POSTGRES_DB") user: str = Field(default="dashboard", env="POSTGRES_USER") password: str = Field(default="", env="POSTGRES_PASSWORD") url: Optional[str] = Field(default=None, env="DATABASE_URL") @property def connection_url(self) -> str: """Get the database connection URL.""" if self.url: return self.url return f"postgresql://{self.user}:{self.password}@{self.host}:{self.port}/{self.database}" class RedisSettings(BaseSettings): """Redis configuration settings.""" host: str = Field(default="localhost", env="REDIS_HOST") port: int = Field(default=6379, env="REDIS_PORT") password: Optional[str] = Field(default=None, env="REDIS_PASSWORD") @property def connection_url(self) -> str: """Get the Redis connection URL.""" if self.password: return f"redis://:{self.password}@{self.host}:{self.port}" return f"redis://{self.host}:{self.port}" class OKXSettings(BaseSettings): """OKX API configuration settings.""" api_key: str = Field(default="", env="OKX_API_KEY") secret_key: str = Field(default="", env="OKX_SECRET_KEY") passphrase: str = Field(default="", env="OKX_PASSPHRASE") sandbox: bool = Field(default=True, env="OKX_SANDBOX") @property def is_configured(self) -> bool: """Check if OKX API is properly configured.""" return bool(self.api_key and self.secret_key and self.passphrase) class DashboardSettings(BaseSettings): """Dashboard application settings.""" host: str = Field(default="0.0.0.0", env="DASH_HOST") port: int = Field(default=8050, env="DASH_PORT") debug: bool = Field(default=True, env="DASH_DEBUG") class BotSettings(BaseSettings): """Bot management settings.""" max_concurrent_bots: int = Field(default=5, env="MAX_CONCURRENT_BOTS") update_interval: int = Field(default=2, env="BOT_UPDATE_INTERVAL") default_virtual_balance: float = Field(default=10000.0, env="DEFAULT_VIRTUAL_BALANCE") class DataSettings(BaseSettings): """Data configuration settings.""" market_data_symbols: str = Field(default="BTC-USDT,ETH-USDT,LTC-USDT", env="MARKET_DATA_SYMBOLS") historical_data_days: int = Field(default=30, env="HISTORICAL_DATA_DAYS") chart_update_interval: int = Field(default=2000, env="CHART_UPDATE_INTERVAL") @property def symbols_list(self) -> list[str]: """Get the list of trading symbols.""" return [symbol.strip() for symbol in self.market_data_symbols.split(",")] class AppSettings(BaseSettings): """Application-wide settings.""" debug: bool = Field(default=True, env="DEBUG") environment: str = Field(default="development", env="ENVIRONMENT") log_level: str = Field(default="INFO", env="LOG_LEVEL") # Create settings instances database = DatabaseSettings() redis = RedisSettings() okx = OKXSettings() dashboard = DashboardSettings() bot = BotSettings() data = DataSettings() app = AppSettings() def get_project_root() -> Path: """Get the project root directory.""" return Path(__file__).parent.parent def get_config_dir() -> Path: """Get the configuration directory.""" return get_project_root() / "config" def get_bot_configs_dir() -> Path: """Get the bot configurations directory.""" return get_config_dir() / "bot_configs"