""" 配置管理器 - 从数据库读取配置,兼容原有config.py """ import sys import os from pathlib import Path # 加载.env文件 try: from dotenv import load_dotenv backend_dir = Path(__file__).parent project_root = backend_dir.parent env_files = [ backend_dir / '.env', project_root / '.env', ] for env_file in env_files: if env_file.exists(): load_dotenv(env_file, override=True) break else: load_dotenv(project_root / '.env', override=False) except ImportError: pass except Exception: pass # 添加项目根目录到路径 project_root = Path(__file__).parent.parent sys.path.insert(0, str(project_root)) # 延迟导入,避免在trading_system中导入时因为缺少依赖而失败 try: from database.models import TradingConfig except ImportError as e: TradingConfig = None import logging logger = logging.getLogger(__name__) logger.warning(f"无法导入TradingConfig: {e},配置管理器将无法使用数据库") import logging logger = logging.getLogger(__name__) class ConfigManager: """配置管理器 - 优先从数据库读取,回退到环境变量和默认值""" def __init__(self): self._cache = {} self._load_from_db() def _load_from_db(self): """从数据库加载配置""" if TradingConfig is None: logger.warning("TradingConfig未导入,无法从数据库加载配置") self._cache = {} return try: configs = TradingConfig.get_all() for config in configs: key = config['config_key'] value = TradingConfig._convert_value( config['config_value'], config['config_type'] ) self._cache[key] = value logger.info(f"从数据库加载了 {len(self._cache)} 个配置项") except Exception as e: logger.warning(f"从数据库加载配置失败,使用默认配置: {e}") self._cache = {} def get(self, key, default=None): """获取配置值""" # 1. 优先从数据库缓存读取 if key in self._cache: return self._cache[key] # 2. 从环境变量读取 env_value = os.getenv(key) if env_value is not None: return env_value # 3. 返回默认值 return default def set(self, key, value, config_type='string', category='general', description=None): """设置配置(同时更新数据库和缓存)""" if TradingConfig is None: logger.warning("TradingConfig未导入,无法更新数据库配置") self._cache[key] = value return try: TradingConfig.set(key, value, config_type, category, description) self._cache[key] = value logger.info(f"配置已更新: {key} = {value}") except Exception as e: logger.error(f"更新配置失败: {e}") raise def reload(self): """重新加载配置""" self._cache = {} self._load_from_db() def get_trading_config(self): """获取交易配置字典(兼容原有config.py的TRADING_CONFIG)""" return { # 仓位控制 'MAX_POSITION_PERCENT': self.get('MAX_POSITION_PERCENT', 0.05), 'MAX_TOTAL_POSITION_PERCENT': self.get('MAX_TOTAL_POSITION_PERCENT', 0.30), 'MIN_POSITION_PERCENT': self.get('MIN_POSITION_PERCENT', 0.01), 'MIN_MARGIN_USDT': self.get('MIN_MARGIN_USDT', 0.5), # 最小保证金要求(USDT) # 涨跌幅阈值 'MIN_CHANGE_PERCENT': self.get('MIN_CHANGE_PERCENT', 2.0), 'TOP_N_SYMBOLS': self.get('TOP_N_SYMBOLS', 10), # 风险控制 'STOP_LOSS_PERCENT': self.get('STOP_LOSS_PERCENT', 0.03), 'TAKE_PROFIT_PERCENT': self.get('TAKE_PROFIT_PERCENT', 0.05), # 市场扫描(1小时主周期) 'SCAN_INTERVAL': self.get('SCAN_INTERVAL', 3600), # 1小时 'TOP_N_SYMBOLS': self.get('TOP_N_SYMBOLS', 10), # 每次扫描后处理的交易对数量 'MAX_SCAN_SYMBOLS': self.get('MAX_SCAN_SYMBOLS', 500), # 扫描的最大交易对数量(0表示扫描所有) 'KLINE_INTERVAL': self.get('KLINE_INTERVAL', '1h'), 'PRIMARY_INTERVAL': self.get('PRIMARY_INTERVAL', '1h'), 'CONFIRM_INTERVAL': self.get('CONFIRM_INTERVAL', '4h'), 'ENTRY_INTERVAL': self.get('ENTRY_INTERVAL', '15m'), # 过滤条件 'MIN_VOLUME_24H': self.get('MIN_VOLUME_24H', 10000000), 'MIN_VOLATILITY': self.get('MIN_VOLATILITY', 0.02), # 高胜率策略参数 'MIN_SIGNAL_STRENGTH': self.get('MIN_SIGNAL_STRENGTH', 5), 'LEVERAGE': self.get('LEVERAGE', 10), 'USE_TRAILING_STOP': self.get('USE_TRAILING_STOP', True), 'TRAILING_STOP_ACTIVATION': self.get('TRAILING_STOP_ACTIVATION', 0.01), 'TRAILING_STOP_PROTECT': self.get('TRAILING_STOP_PROTECT', 0.01), } # 全局配置管理器实例 config_manager = ConfigManager() # 兼容原有config.py的接口 def get_config(key, default=None): """获取配置(兼容函数)""" return config_manager.get(key, default) def get_trading_config(): """获取交易配置(兼容函数)""" return config_manager.get_trading_config()