"""集中配置(环境变量可覆盖)。""" from __future__ import annotations from functools import lru_cache from pathlib import Path from pydantic import Field from pydantic_settings import BaseSettings, SettingsConfigDict class Settings(BaseSettings): model_config = SettingsConfigDict( env_file=".env", env_file_encoding="utf-8", extra="ignore", ) # 服务 mi_port: int = Field(default=5170, alias="MI_PORT") tz: str = Field(default="Asia/Shanghai", alias="TZ") auth_secret: str = Field(default="change-me", alias="AUTH_SECRET") admin_username: str = Field(default="admin", alias="ADMIN_USERNAME") admin_password: str = Field(default="admin123", alias="ADMIN_PASSWORD") env_file: str = Field(default=".env", alias="ENV_FILE") backup_dir: str = Field(default="/root/market_intel_backups", alias="BACKUP_DIR") # OKX okx_api_key: str = Field(default="", alias="OKX_API_KEY") okx_api_secret: str = Field(default="", alias="OKX_API_SECRET") okx_api_passphrase: str = Field(default="", alias="OKX_API_PASSPHRASE") okx_base_url: str = Field(default="https://www.okx.com", alias="OKX_BASE_URL") okx_proxy: str = Field(default="", alias="OKX_PROXY") index_inst_id: str = Field(default="ETH-USD", alias="INDEX_INST_ID") option_inst_family: str = Field(default="ETH-USD_UM", alias="OPTION_INST_FAMILY") underlying: str = Field(default="ETH", alias="UNDERLYING") sample_interval_sec: int = Field(default=30, alias="SAMPLE_INTERVAL_SEC", ge=15, le=120) index_sample_interval_sec: int = Field(default=60, alias="INDEX_SAMPLE_INTERVAL_SEC", ge=15) instruments_refresh_sec: int = Field(default=300, alias="INSTRUMENTS_REFRESH_SEC", ge=60) min_option_hours: float = Field(default=12.0, alias="MIN_OPTION_HOURS", ge=0) min_option_leverage: float = Field(default=100.0, alias="MIN_OPTION_LEVERAGE", ge=1) mi_db_path: str = Field(default="./data/market_intel.db", alias="MI_DB_PATH") bucket_minutes: int = Field(default=60, alias="BUCKET_MINUTES") month_range_mode: str = Field(default="rolling_30", alias="MONTH_RANGE_MODE") settle_backfill_interval_sec: int = Field( default=300, alias="SETTLE_BACKFILL_INTERVAL_SEC", ge=60 ) # 企微告警 wecom_enabled: bool = Field(default=False, alias="WECOM_ENABLED") wecom_webhook_url: str = Field(default="", alias="WECOM_WEBHOOK_URL") wecom_machine_name: str = Field(default="", alias="WECOM_MACHINE_NAME") alert_fail_threshold: int = Field(default=5, alias="ALERT_FAIL_THRESHOLD", ge=1) @property def db_path(self) -> Path: return Path(self.mi_db_path) @property def env_file_path(self) -> Path: return Path(self.env_file) @property def backup_dir_path(self) -> Path: return Path(self.backup_dir) def reload_settings() -> Settings: get_settings.cache_clear() return get_settings() @lru_cache def get_settings() -> Settings: return Settings()