diff --git a/.env b/.env index 0af9986..deb3ca8 100644 --- a/.env +++ b/.env @@ -1,8 +1,13 @@ -# API配置 -OPENAI_API_KEY= -DEEPSEEK_API_KEY= +# DeepSeek API 配置 +DEEPSEEK_API_KEY=sk-49dccf9e8a754d3abb36ce396cb8f189 DEEPSEEK_API_URL=https://api.deepseek.com/v1/chat/completions +# OpenAI API 配置 +OPENAI_API_KEY=your_openai_api_key + +# Gemini API 配置 +GEMINI_API_KEY=your_gemini_api_key + # 天勤TQSDK配置 # 填写你的TQSDK账号密码以使用真实数据 TQSDK_USERNAME=windsdreamer diff --git a/qihuo_analyzer/modules/__pycache__/deepseek_agent.cpython-311.pyc b/qihuo_analyzer/modules/__pycache__/deepseek_agent.cpython-311.pyc index b5d63b4..72103a4 100644 Binary files a/qihuo_analyzer/modules/__pycache__/deepseek_agent.cpython-311.pyc and b/qihuo_analyzer/modules/__pycache__/deepseek_agent.cpython-311.pyc differ diff --git a/qihuo_analyzer/modules/deepseek_agent.py b/qihuo_analyzer/modules/deepseek_agent.py index 45edc52..5781061 100644 --- a/qihuo_analyzer/modules/deepseek_agent.py +++ b/qihuo_analyzer/modules/deepseek_agent.py @@ -7,15 +7,50 @@ from qihuo_analyzer.core.models import AnalysisResult class DeepseekAgent: - """DeepSeek AI 研判代理""" + """AI 研判代理,支持多种模型""" - def __init__(self): - self.api_key = config_manager.deepseek_api_key - self.api_url = config_manager.deepseek_api_url - self.headers = { - 'Content-Type': 'application/json', - 'Authorization': f'Bearer {self.api_key}' + def __init__(self, model_name='deepseek'): + """初始化AI代理 + + Args: + model_name: 模型名称,支持 'deepseek', 'gpt', 'gemini' 等 + """ + self.model_name = model_name + # 安全获取API密钥,避免访问不存在的属性 + gemini_api_key = getattr(config_manager, 'gemini_api_key', '') + + self.api_configs = { + 'deepseek': { + 'api_key': config_manager.deepseek_api_key, + 'api_url': config_manager.deepseek_api_url, + 'headers': { + 'Content-Type': 'application/json', + 'Authorization': f'Bearer {config_manager.deepseek_api_key}' + } + }, + 'gpt': { + 'api_key': config_manager.openai_api_key, + 'api_url': 'https://api.openai.com/v1/chat/completions', + 'headers': { + 'Content-Type': 'application/json', + 'Authorization': f'Bearer {config_manager.openai_api_key}' + } + }, + 'gemini': { + 'api_key': gemini_api_key, + 'api_url': 'https://generativelanguage.googleapis.com/v1/models/gemini-pro:generateContent', + 'headers': { + 'Content-Type': 'application/json', + 'Authorization': f'Bearer {gemini_api_key}' + } + } } + + # 获取当前模型的配置 + self.current_config = self.api_configs.get(model_name, self.api_configs['deepseek']) + self.api_key = self.current_config['api_key'] + self.api_url = self.current_config['api_url'] + self.headers = self.current_config['headers'] def analyze_market(self, market_data: Dict, technical_indicators: Dict, trend_analysis: Dict, risk_metrics: Dict) -> Dict: @@ -24,7 +59,7 @@ class DeepseekAgent: prompt = self._build_analysis_prompt(market_data, technical_indicators, trend_analysis, risk_metrics) # 调用API - response = self._call_deepseek_api(prompt) + response = self._call_ai_api(prompt) # 解析结果 analysis_result = self._parse_analysis_result(response) @@ -37,7 +72,7 @@ class DeepseekAgent: prompt = self._build_recommendation_prompt(analysis_result) # 调用API - response = self._call_deepseek_api(prompt) + response = self._call_ai_api(prompt) # 解析结果 recommendation = self._parse_recommendation_result(response) @@ -126,28 +161,89 @@ class DeepseekAgent: """ return prompt - def _call_deepseek_api(self, prompt: str) -> str: - """调用DeepSeek API""" - # 如果没有API密钥,返回模拟结果 + def _call_ai_api(self, prompt: str) -> str: + """调用AI API""" + # 如果没有API密钥,返回错误提示 if not self.api_key: - return self._get_mock_response(prompt) + return json.dumps({'error': 'API密钥未配置'}) - payload = { - 'model': 'deepseek-chat', - 'messages': [ - { - 'role': 'system', - 'content': '你是一位专业的期货市场分析师,精通技术分析和基本面分析,能够基于多维度数据提供准确的市场研判和交易建议。' - }, - { - 'role': 'user', - 'content': prompt + # 根据模型类型构建不同的payload + if self.model_name == 'deepseek': + payload = { + 'model': 'deepseek-chat', + 'messages': [ + { + 'role': 'system', + 'content': '你是一位专业的期货市场分析师,精通技术分析和基本面分析,能够基于多维度数据提供准确的市场研判和交易建议。' + }, + { + 'role': 'user', + 'content': prompt + } + ], + 'temperature': 0.3, + 'max_tokens': 2000, + 'top_p': 0.9 + } + elif self.model_name == 'gpt': + payload = { + 'model': 'gpt-3.5-turbo', + 'messages': [ + { + 'role': 'system', + 'content': '你是一位专业的期货市场分析师,精通技术分析和基本面分析,能够基于多维度数据提供准确的市场研判和交易建议。' + }, + { + 'role': 'user', + 'content': prompt + } + ], + 'temperature': 0.3, + 'max_tokens': 2000, + 'top_p': 0.9 + } + elif self.model_name == 'gemini': + payload = { + 'contents': [ + { + 'parts': [ + { + 'text': '你是一位专业的期货市场分析师,精通技术分析和基本面分析,能够基于多维度数据提供准确的市场研判和交易建议。' + } + ] + }, + { + 'parts': [ + { + 'text': prompt + } + ] + } + ], + 'generationConfig': { + 'temperature': 0.3, + 'maxOutputTokens': 2000, + 'topP': 0.9 } - ], - 'temperature': 0.3, - 'max_tokens': 2000, - 'top_p': 0.9 - } + } + else: + # 默认使用deepseek格式 + payload = { + 'model': 'deepseek-chat', + 'messages': [ + { + 'role': 'system', + 'content': '你是一位专业的期货市场分析师,精通技术分析和基本面分析,能够基于多维度数据提供准确的市场研判和交易建议。' + }, + { + 'role': 'user', + 'content': prompt + } + ], + 'temperature': 0.3, + 'max_tokens': 2000, + 'top_p': 0.9 + } try: response = requests.post( @@ -159,10 +255,17 @@ class DeepseekAgent: response.raise_for_status() result = response.json() - return result['choices'][0]['message']['content'] + + # 根据模型类型解析不同的响应格式 + if self.model_name == 'deepseek' or self.model_name == 'gpt': + return result['choices'][0]['message']['content'] + elif self.model_name == 'gemini': + return result['candidates'][0]['content']['parts'][0]['text'] + else: + return result['choices'][0]['message']['content'] except Exception as e: print(f"API调用失败:{e}") - return self._get_mock_response(prompt) + return json.dumps({'error': 'API调用失败'}) def _get_mock_response(self, prompt: str) -> str: """获取模拟响应""" diff --git a/web/app.py b/web/app.py index 3a6ab4e..6f49198 100644 --- a/web/app.py +++ b/web/app.py @@ -254,12 +254,28 @@ def index(): except (ValueError, TypeError): safe_adx = 0 + # 计算胜率(模拟数据,实际项目中应该使用真实的胜率计算) + win_rate = round(win_rate, 1) if win_rate is not None else 0 + + # 计算换月预警(模拟数据,实际项目中应该使用真实的距离交割天数) + rollover_warning = _get_rollover_warning(rollover_analysis) + + # 计算主力资金流向(模拟数据,实际项目中应该使用真实的资金流向数据) + fund_flow = fund_flow_to_cn(fund_flow_analysis.get('fund_signal', 'neutral')) + + # 计算周期(模拟数据,实际项目中应该使用真实的周期判断) + cycle = cycle_to_cn(cycle) + symbol_data = { 'symbol': symbol, 'name': f"{product_name_cn}({symbol})".upper(), 'current_price': safe_current_price, 'direction': trend_analysis.get('overall_trend', 'sideways'), - 'trend_strength': _get_trend_strength_display(safe_adx) + 'win_rate': win_rate, + 'trend_strength': _get_trend_strength_display(safe_adx), + 'cycle': cycle, + 'rollover_warning': rollover_warning, + 'fund_flow': fund_flow } selected_symbols_data.append(symbol_data) except Exception as e: @@ -288,6 +304,9 @@ def index(): def symbol_detail(symbol): """品种详情页""" try: + # 获取模型选择参数,默认为deepseek + model_name = request.args.get('model', 'deepseek') + # 辅助函数:安全地四舍五入数字 def safe_round(value, decimals=2, context=''): try: @@ -429,9 +448,10 @@ def symbol_detail(symbol): 'risk_ratio': safe_round(position_info.get('actual_risk_percent', 0) * 100, 2, context='risk_metrics_risk_ratio') } - # AI 分析 - ai_analysis = deepseek_agent.analyze_market(market_data, technical_indicators, trend_data, risk_metrics) - recommendation = deepseek_agent.generate_trade_recommendation(ai_analysis) + # AI 分析 - 使用指定的模型 + ai_agent = DeepseekAgent(model_name=model_name) + ai_analysis = ai_agent.analyze_market(market_data, technical_indicators, trend_data, risk_metrics) + recommendation = ai_agent.generate_trade_recommendation(ai_analysis) # 构建模板数据 # 获取中文名称 @@ -512,7 +532,9 @@ def symbol_detail(symbol): 'ai_analysis': ai_analysis, 'recommendation': recommendation, 'kline_data': _get_kline_data_for_chart(kline_data), - 'is_favorite': symbol in selected_symbols + 'is_favorite': symbol in selected_symbols, + 'model_name': model_name, + 'available_models': ['deepseek', 'gpt', 'gemini'] } print("[DEBUG] context built successfully") diff --git a/web/templates/index.html b/web/templates/index.html index c4e1400..1eb51f9 100644 --- a/web/templates/index.html +++ b/web/templates/index.html @@ -291,13 +291,23 @@
+ {% if ai_analysis.error == 'API密钥未配置' %} + 当前模型的API密钥未配置,请在.env文件中添加相应的API密钥 + {% elif ai_analysis.error == 'API调用失败' %} + API调用失败,请检查网络连接或API密钥是否正确 + {% else %} + {{ ai_analysis.error }} + {% endif %} +
+{{ ai_analysis.analysis_logic }}
+ {% endif %} + {% else %} + +{{ ai_analysis.analysis_logic | default('无详细分析') }}
+ {% endif %} +{{ recommendation.execution_plan }}
+ {% endif %} + {% else %} +无详细计划
+ {% endif %}{{ recommendation.risk_tips }}
+ {% endif %} + {% else %} +无风险提示
+ {% endif %}