158 lines
5.4 KiB
Python
158 lines
5.4 KiB
Python
"""
|
||
配置管理器 - 从数据库读取配置,兼容原有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_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()
|