config.py
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
配置管理模块
加载环境变量和配置文件
"""
import os
from pathlib import Path
from dotenv import load_dotenv
from typing import Dict, Any
class ConfigManager:
"""配置管理类"""
def __init__(self, env_file: str = ".env"):
"""初始化配置管理器"""
# 加载环境变量
load_dotenv(env_file)
# 项目根目录
self.root_dir = Path(__file__).parent.parent
# 数据存储路径
self.data_dir = self.root_dir / "data"
self.data_dir.mkdir(exist_ok=True)
# 结果存储路径
self.results_dir = self.root_dir / "results"
self.results_dir.mkdir(exist_ok=True)
# 日志存储路径
self.log_dir = self.root_dir / "logs"
self.log_dir.mkdir(exist_ok=True)
# 初始化配置
self._init_config()
def _init_config(self):
"""初始化配置"""
# Tushare配置
self.tushare_token = self._get_env("TUSHARE_TOKEN")
# 火山引擎API配置
self.volcengine_api_key = self._get_env("VOLCENGINE_API_KEY")
self.volcengine_api_base = self._get_env("VOLCENGINE_API_BASE", "https://ark.cn-beijing.volces.com/api/v3/chat/completions")
self.volcengine_model = self._get_env("VOLCENGINE_MODEL", "doubao-pro-32k")
# 数据库配置
self.db_path = self._get_env("DB_PATH", str(self.data_dir / "stock_data.db"))
# 日志配置
self.log_path = self._get_env("LOG_PATH", str(self.log_dir / "quant_trading.log"))
# 选股参数
self.selection_time = self._get_env("SELECTION_TIME", "14:30")
self.stock_selection_count = int(self._get_env("STOCK_SELECTION_COUNT", 10))
self.min_turnover_rate = float(self._get_env("MIN_TURNOVER_RATE", 1.0))
self.max_stock_count = int(self._get_env("MAX_STOCK_COUNT", 3000))
# 回测参数
self.backtest_start_date = self._get_env("BACKTEST_START_DATE", "20200101")
self.backtest_end_date = self._get_env("BACKTEST_END_DATE", "20241231")
# 大模型参数
self.temperature = float(self._get_env("TEMPERATURE", 0.1))
self.top_p = float(self._get_env("TOP_P", 0.9))
self.max_tokens = int(self._get_env("MAX_TOKENS", 8192))
# 模型有效性阈值
self.accuracy_threshold = float(self._get_env("ACCURACY_THRESHOLD", 0.5))
self.profit_loss_threshold = float(self._get_env("PROFIT_LOSS_THRESHOLD", 2.0))
def _get_env(self, key: str, default: str = None) -> str:
"""获取环境变量值"""
value = os.getenv(key, default)
if not value and not default:
raise EnvironmentError(f"缺少环境变量:{key}")
return value
def get_config(self) -> Dict[str, Any]:
"""获取所有配置"""
return {
"tushare": {
"token": self.tushare_token
},
"volcengine": {
"api_key": self.volcengine_api_key,
"api_base": self.volcengine_api_base,
"model": self.volcengine_model
},
"database": {
"path": self.db_path
},
"logging": {
"path": self.log_path
},
"selection": {
"time": self.selection_time,
"count": self.stock_selection_count,
"min_turnover_rate": self.min_turnover_rate,
"max_stock_count": self.max_stock_count
},
"backtest": {
"start_date": self.backtest_start_date,
"end_date": self.backtest_end_date
},
"model": {
"temperature": self.temperature,
"top_p": self.top_p,
"max_tokens": self.max_tokens
},
"validation": {
"accuracy_threshold": self.accuracy_threshold,
"profit_loss_threshold": self.profit_loss_threshold
}
}
def print_config(self):
"""打印配置信息"""
config = self.get_config()
print("=" * 80)
print("配置信息")
print("=" * 80)
for section, params in config.items():
print(f"{section.upper()}")
print("-" * len(section))
for key, value in params.items():
if key == "api_key" or key == "token":
print(f"{key}: {value[:5]}...")
else:
print(f"{key}: {value}")
print()
print("=" * 80)
def save_config(self, config: Dict[str, Any], file_path: str = None):
"""保存配置到文件"""
if not file_path:
file_path = str(self.root_dir / "config" / "config.json")
try:
import json
with open(file_path, 'w', encoding='utf-8') as f:
json.dump(config, f, ensure_ascii=False, indent=2)
return True
except Exception as e:
raise Exception(f"配置保存失败:{e}")
def load_config(self, file_path: str = None) -> Dict[str, Any]:
"""从文件加载配置"""
if not file_path:
file_path = str(self.root_dir / "config" / "config.json")
try:
import json
with open(file_path, 'r', encoding='utf-8') as f:
return json.load(f)
except FileNotFoundError:
raise Exception("配置文件未找到")
except Exception as e:
raise Exception(f"配置加载失败:{e}")
# 全局配置实例
config_manager = ConfigManager()