""" 全局配置模块。 敏感信息优先从环境变量读取,其次使用默认值(仅开发环境)。 """ import os from pathlib import Path from dotenv import load_dotenv # 确保加载 finance/.env,无论从哪个目录运行 _env_path = Path(__file__).resolve().parent.parent / ".env" load_dotenv(_env_path) # ── MariaDB 连接 ────────────────────────────────────────── # 通过 SSH 隧道连接:shared/script/autossh.sh MARIADB_CONFIG = { "host": os.getenv("MAC_DB_HOST", "127.0.0.1"), "port": int(os.getenv("MAC_DB_PORT", "13306")), "user": os.getenv("MAC_DB_USER", "myquant"), "password": os.getenv("MAC_DB_PASSWORD", ""), "database": os.getenv("MAC_DB_NAME", "myquant"), "charset": "utf8mb4", "pool_size": 5, "pool_recycle": 600, # 10分钟回收,避免 SSH 隧道半开连接 } # ── 表名前缀 ────────────────────────────────────────────── TABLE_PREFIX = "mac_" # 完整表名 TABLE_STOCK_BASIC = f"{TABLE_PREFIX}stock_basic" TABLE_STOCK_DAILY = f"{TABLE_PREFIX}stock_daily" TABLE_STOCK_FINANCIAL = f"{TABLE_PREFIX}stock_financial" TABLE_REPORT = f"{TABLE_PREFIX}report" # ── AkShare 配置 ────────────────────────────────────────── AKSHARE_CONFIG = { "request_timeout": 30, "retry_times": 3, "retry_delay": 2, # 秒 } # ── 默认参数 ────────────────────────────────────────────── DEFAULT_START_DATE = "20200101" DEFAULT_END_DATE = None # None 表示当天 # ── 数据新鲜度 ──────────────────────────────────────────── # DB 窗口尾部落后于请求日多少个自然日,视为存在缺口需补拉(get_daily) DATA_FRESHNESS_GAP_DAYS = int(os.getenv("DATA_FRESHNESS_GAP_DAYS", "7")) # ── 风险评估参数(RiskAgent) ───────────────────────────── # 风险等级阈值:年化波动率(%) / 当前回撤(%),超过即升级 RISK_THRESHOLDS = { "high": {"vol": float(os.getenv("RISK_HIGH_VOL", "35")), "dd": float(os.getenv("RISK_HIGH_DD", "-15"))}, "medium": {"vol": float(os.getenv("RISK_MED_VOL", "25")), "dd": float(os.getenv("RISK_MED_DD", "-8"))}, } # 各等级对应的建议总仓位、单票上限、止损线 RISK_EXPOSURE = {"low": 0.85, "medium": 0.60, "high": 0.30} RISK_MAX_SINGLE = {"low": 0.15, "medium": 0.10, "high": 0.05} RISK_STOP_LOSS = {"low": -0.05, "medium": -0.08, "high": -0.12} # ── 选股参数(SelectionAgent) ──────────────────────────── # 默认选股池大小(按股票列表前 N 只作为代表股池) SELECTION_UNIVERSE_SIZE = int(os.getenv("SELECTION_UNIVERSE_SIZE", "100")) # 单次打分上限(防止单次过慢) SELECTION_SCORE_LIMIT = int(os.getenv("SELECTION_SCORE_LIMIT", "300")) # 默认返回 Top N SELECTION_TOP_N = int(os.getenv("SELECTION_TOP_N", "15")) # 选股核心因子(覆盖多维度,减少计算量) SELECTION_CORE_FACTORS = [ "momentum_20", "momentum_60", "rsi_14", "volatility_20", "vol_ratio_5", "ma_dev_20", "turnover_5", "amplitude_5", ] # z-score 打分时是否做去极值(避免单股离群值主导 Top 排名) SELECTION_WINSORIZE_ZSCORE = os.getenv("SELECTION_WINSORIZE_ZSCORE", "1") == "1" # ── 报告参数(ReportAgent) ──────────────────────────────── # 日报市场概览指数代码 REPORT_INDEX_CODES = { "000001.SH": "上证指数", "399001.SZ": "深证成指", "399006.SZ": "创业板指", } # 日报标题中展示的 Top N(与 SELECTION_TOP_N 联动) REPORT_TOP_N = SELECTION_TOP_N