1 line
34 KiB
JSON
1 line
34 KiB
JSON
{"repo": "ahriy/aagent", "files": {"analyze_stocks.py": {"231854c5e18448fbe2cdc46402a80546acae2d27": {"t": 1785746392.4069443, "n": 9173, "h": "43b301cac4fa5744", "c": "import pandas as pd\nimport os\nimport json\nimport requests\nfrom loguru import logger\nfrom datetime import datetime\nfrom dotenv import load_dotenv\n\nclass DeepseekAnalyzer:\n def __init__(self, api_key, api_url, system_prompt_file=\"system_prompt.md\"):\n self.api_key = api_key\n self.api_url = api_url\n self.system_prompt = self._load_system_prompt(system_prompt_file)\n \n def _load_system_prompt(self, file_path):\n \"\"\"加载系统提示词\"\"\"\n try:\n with open(file_path, 'r', encoding='utf-8') as f:\n return f.read()\n except Exception as e:\n logger.warning(f\"无法读取系统提示词文件 {file_path}: {e}\")\n return \"你是一个专业的股票分析师,请基于提供的数据进行深入的基本面分析。\"\n \n def analyze_stock(self, stock_data):\n \"\"\"使用Deepseek API分析股票数据\"\"\"\n # 构建提示词\n prompt = self._build_prompt(stock_data)\n \n try:\n response = requests.post(\n self.api_url,\n headers={\n \"Authorization\": f\"Bearer {self.api_key}\",\n \"Content-Type\": \"application/json\"\n },\n json={\n \"model\": \"deepseek-ai/DeepSeek-R1\",\n \"messages\": [\n {\"role\": \"system\", \"content\": self.system_prompt},\n {\"role\": \"user\", \"content\": prompt}\n ],\n \"temperature\": 0.3, # 降低温度,提高一致性\n \"max_tokens\": 6000 # 增加输出长度\n },\n timeout=120 # 增加超时时间\n )\n \n if response.status_code == 200:\n result = response.json()\n return result['choices'][0]['message']['content']\n else:\n logger.error(f\"API调用失败: {response.status_code} - {response.text}\")\n return None\n except Exception as e:\n logger.error(f\"分析过程中出现错误: {e}\")\n return None\n \n def _build_prompt(self, stock_data):\n \"\"\"构建分析提示词\"\"\"\n prompt = f\"\"\"请按照你的专业分析框架,对以下股票进行深度价值投资分析:\n\n## 基本信息\n- **公司名称**: {stock_data['stock_name']}\n- **股票代码**: {stock_data['stock_code']}\n- **所属行业**: {stock_data['industry']}\n\n## 财务数据(近7年)\n\n### ROE(净资产收益率)%\n\"\"\"\n # 添加ROE数据\n roe_data = []\n for col in sorted([c for c in stock_data.index if c.startswith('roe_')]):\n year = col.split('_')[1]\n if pd.notna(stock_data[col]):\n roe_data.append(f\"{year}年: {stock_data[col]:.2f}%\")\n \n if roe_data:\n prompt += \" | \".join(roe_data) + \"\\n\"\n else:\n prompt += \"数据缺失\\n\"\n \n prompt += \"\\n### PE(市盈率)倍\\n\"\n # 添加PE数据\n pe_data = []\n for col in sorted([c for c in stock_data.index if c.startswith('pe_')]):\n year = col.split('_')[1]\n if pd.notna(stock_data[col]):\n pe_data.append(f\"{year}年: {stock_data[col]:.2f}x\")\n \n if pe_data:\n prompt += \" | \".join(pe_data) + \"\\n\"\n else:\n prompt += \"数据缺失\\n\"\n \n prompt += \"\\n### 股息率 %\\n\"\n # 添加股息率数据\n div_data = []\n for col in sorted([c for c in stock_data.index if c.startswith('dividend_')]):\n year = col.split('_')[1]\n if pd.notna(stock_data[col]):\n div_data.append(f\"{year}年: {stock_data[col]:.2f}%\")\n \n if div_data:\n prompt += \" | \".join(div_data) + \"\\n\"\n else:\n prompt += \"数据缺失\\n\"\n \n prompt += \"\\n### 毛利率 %\\n\"\n # 添加毛利率数据\n gm_data = []\n for col in sorted([c for c in stock_data.index if c.startswith('gross_margin_')]):\n year = col.split('_')[1]\n if pd.notna(stock_data[col]):\n gm_data.append(f\"{year}年: {stock_data[col]:.2f}%\")\n \n if gm_data:\n prompt += \" | \".join(gm_data) + \"\\n\"\n else:\n prompt += \"数据缺失(银行等金融企业通常无此指标)\\n\"\n \n prompt += \"\\n### 净利率 %\\n\"\n # 添加净利率数据\n nm_data = []\n for col in sorted([c for c in stock_data.index if c.startswith('net_margin_')]):\n year = col.split('_')[1]\n if pd.notna(stock_data[col]):\n nm_data.append(f\"{year}年: {stock_data[col]:.2f}%\")\n \n if nm_data:\n prompt += \" | \".join(nm_data) + \"\\n\"\n else:\n prompt += \"数据缺失\\n\"\n \n prompt += \"\"\"\\n## 分析要求\n\n请严格按照你的【商业本质诊断→财务健康透视→安全边际测算】三阶分析框架进行分析,并给出:\n\n1. **投资摘要**(一句话观点+明确评级:强烈推荐/推荐/中性/回避/强烈回避)\n2. **商业本质分析**(结合行业特点分析护城河和竞争优势)\n3. **财务健康诊断**(基于提供数据的深度分析)\n4. **估值与安全边际**(当前估值水平+内在价值判断)\n5. **关键风险因素**(主要下行风险+概率评估)\n6. **投资建议**(目标价格区间+持有期建议+仓位配置建议)\n\n请用markdown格式输出,确保分析有理有据,避免模糊表述。\"\"\"\n \n return prompt\n\ndef setup_logger():\n \"\"\"配置日志\"\"\"\n log_path = \"logs\"\n os.makedirs(log_path, exist_ok=True)\n logger.add(\n os.path.join(log_path, \"analysis_{time}.log\"),\n rotation=\"500 MB\",\n encoding=\"utf-8\"\n )\n\ndef load_config():\n \"\"\"加载配置\"\"\"\n load_dotenv()\n config = {}\n \n # API密钥\n config['api_key'] = os.getenv('DEEPSEEK_API_KEY')\n if not config['api_key']:\n logger.warning(\"未找到DEEPSEEK_API_KEY环境变量,将使用模拟分析\")\n logger.info(\"如需使用API分析,请在.env文件中添加:DEEPSEEK_API_KEY=your_api_key_here\")\n return None\n \n # API URL\n config['api_url'] = os.getenv('API_URL', 'https://api.deepseek.com/v1/chat/completions')\n logger.info(f\"使用API URL: {config['api_url']}\")\n \n return config\n\ndef simulate_analysis(stock_data):\n \"\"\"模拟分析结果(当没有API密钥时使用)\"\"\"\n analysis = f\"\"\"# {stock_data['stock_name']}({stock_data['stock_code']})投资分析报告\n\n## 投资摘要\n**核心观点**: 基于现有财务数据的初步分析 | **评级**: 中性(需更多数据验证)\n\n## 基本信息\n- **公司名称**: {stock_data['stock_name']}\n- **股票代码**: {stock_data['stock_code']}\n- **所属行业**: {stock_data['industry']}\n- **分析日期**: {datetime.now().strftime('%Y-%m-%d')}\n\n## 财务数据概览\n\n### ROE(净资产收益率)趋势\n\"\"\"\n \n # 添加ROE分析\n roe_data = []\n for col in sorted([c for c in stock_data.index if c.startswith('roe_')]):\n year = col.split('_')[1]\n if pd.notna(stock_data[col]):\n roe_data.append(f\"- {year}年:{stock_data[col]:.2f}%\")\n \n if roe_data:\n analysis += \"\\n\".join(roe_data)\n else:\n analysis += \"- 数据缺失\"\n \n analysis += \"\"\"\n\n### PE(市盈率)水平\n\"\"\"\n \n # 添加PE分析\n pe_data = []\n for col in sorted([c for c in stock_data.index if c.startswith('pe_')]):\n year = col.split('_')[1]\n if pd.notna(stock_data[col]):\n pe_data.append(f\"- {year}年:{stock_data[col]:.2f}倍\")\n \n if pe_data:\n analysis += \"\\n\".join(pe_data)\n else:\n analysis += \"- 数据缺失\"\n \n analysis += \"\"\"\n\n### 股息率水平\n\"\"\"\n \n # 添加股息率分析\n div_data = []\n for col in sorted([c for c in stock_data.index if c.startswith('dividend_')]):\n year = col.split('_')[1]\n if pd.notna(stock_data[col]):\n div_data.append(f\"- {year}年:{stock_data[col]:.2f}%\")\n \n if div_data:\n analysis += \"\\n\".join(div_data)\n else:\n analysis += \"- 数据缺失\"\n \n analysis += \"\"\"\n\n## 投资建议\n\n**注意**: 这是基于有限数据的模拟分析,如需详细的价值投资分析,请配置Deepseek API密钥以获得专业的三阶分析框架报告。\n\n### 风险提示\n- 本分析仅基于历史财务数据,未考虑宏观环境、行业变化等因素\n- 投资有风险,建议结合更多信息进行决策\n- 股市波动较大,请注意风险控制\n\n---\n*报告生成时间: {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}*\n\"\"\"\n \n return analysis\n\ndef main():\n \"\"\"主程序入口\"\"\"\n setup_logger()\n \n # 创建报告目录\n reports_dir = \"analysis_reports\"\n os.makedirs(reports_dir, exist_ok=True)\n \n # 读取Excel文件\n try:\n df = pd.read_excel('stock_analysis_data.xlsx')\n logger.info(f\"成功读取Excel文件,共{len(df)}只股票\")\n except Exception as e:\n logger.error(f\"读取Excel文件失败: {e}\")\n return\n \n # 获取需要分析的股票\n stocks_to_analyze = df[df['need_analysis'] == True]\n \n if len(stocks_to_analyze) == 0:\n logger.info(\"没有找到需要分析的股票(need_analysis=True)\")\n return\n \n logger.info(f\"找到{len(stocks_to_analyze)}只需要分析的股票\")\n \n # 加载配置\n config = load_config()\n \n if config:\n # 初始化分析器\n analyzer = DeepseekAnalyzer(config['api_key'], config['api_url'])\n logger.info(\"使用Deepseek API进行专业价值投资分析\")\n logger.info(f\"系统提示词已加载:{len(analyzer.system_prompt)}字符\")\n else:\n logger.info(\"未配置API密钥,将使用模拟分析\")\n analyzer = None\n \n # 分析每只股票\n for idx, stock in stocks_to_analyze.iterrows():\n logger.info(f\"开始分析: {stock['stock_name']} ({stock['stock_code']})\")\n \n # 进行深度分析\n if analyzer:\n analysis_result = analyzer.analyze_stock(stock)\n else:\n analysis_result = simulate_analysis(stock)\n \n if analysis_result:\n # 保存分析报告\n report_file = os.path.join(\n reports_dir, \n f\"{stock['stock_code']}_{datetime.now().strftime('%Y%m%d')}.md\"\n )\n \n with open(report_file, 'w', encoding='utf-8') as f:\n f.write(analysis_result)\n \n logger.info(f\"分析报告已保存: {report_file}\")\n else:\n logger.error(f\"分析失败: {stock['stock_code']}\")\n \n logger.info(\"所有分析完成\")\n\nif __name__ == \"__main__\":\n main() "}, "c9fab1e776085e7f1138651382ff5ab5efe5d82f": {"t": 1785763221.9340394, "n": 9173, "h": "43b301cac4fa5744", "c": "import pandas as pd\nimport os\nimport json\nimport requests\nfrom loguru import logger\nfrom datetime import datetime\nfrom dotenv import load_dotenv\n\nclass DeepseekAnalyzer:\n def __init__(self, api_key, api_url, system_prompt_file=\"system_prompt.md\"):\n self.api_key = api_key\n self.api_url = api_url\n self.system_prompt = self._load_system_prompt(system_prompt_file)\n \n def _load_system_prompt(self, file_path):\n \"\"\"加载系统提示词\"\"\"\n try:\n with open(file_path, 'r', encoding='utf-8') as f:\n return f.read()\n except Exception as e:\n logger.warning(f\"无法读取系统提示词文件 {file_path}: {e}\")\n return \"你是一个专业的股票分析师,请基于提供的数据进行深入的基本面分析。\"\n \n def analyze_stock(self, stock_data):\n \"\"\"使用Deepseek API分析股票数据\"\"\"\n # 构建提示词\n prompt = self._build_prompt(stock_data)\n \n try:\n response = requests.post(\n self.api_url,\n headers={\n \"Authorization\": f\"Bearer {self.api_key}\",\n \"Content-Type\": \"application/json\"\n },\n json={\n \"model\": \"deepseek-ai/DeepSeek-R1\",\n \"messages\": [\n {\"role\": \"system\", \"content\": self.system_prompt},\n {\"role\": \"user\", \"content\": prompt}\n ],\n \"temperature\": 0.3, # 降低温度,提高一致性\n \"max_tokens\": 6000 # 增加输出长度\n },\n timeout=120 # 增加超时时间\n )\n \n if response.status_code == 200:\n result = response.json()\n return result['choices'][0]['message']['content']\n else:\n logger.error(f\"API调用失败: {response.status_code} - {response.text}\")\n return None\n except Exception as e:\n logger.error(f\"分析过程中出现错误: {e}\")\n return None\n \n def _build_prompt(self, stock_data):\n \"\"\"构建分析提示词\"\"\"\n prompt = f\"\"\"请按照你的专业分析框架,对以下股票进行深度价值投资分析:\n\n## 基本信息\n- **公司名称**: {stock_data['stock_name']}\n- **股票代码**: {stock_data['stock_code']}\n- **所属行业**: {stock_data['industry']}\n\n## 财务数据(近7年)\n\n### ROE(净资产收益率)%\n\"\"\"\n # 添加ROE数据\n roe_data = []\n for col in sorted([c for c in stock_data.index if c.startswith('roe_')]):\n year = col.split('_')[1]\n if pd.notna(stock_data[col]):\n roe_data.append(f\"{year}年: {stock_data[col]:.2f}%\")\n \n if roe_data:\n prompt += \" | \".join(roe_data) + \"\\n\"\n else:\n prompt += \"数据缺失\\n\"\n \n prompt += \"\\n### PE(市盈率)倍\\n\"\n # 添加PE数据\n pe_data = []\n for col in sorted([c for c in stock_data.index if c.startswith('pe_')]):\n year = col.split('_')[1]\n if pd.notna(stock_data[col]):\n pe_data.append(f\"{year}年: {stock_data[col]:.2f}x\")\n \n if pe_data:\n prompt += \" | \".join(pe_data) + \"\\n\"\n else:\n prompt += \"数据缺失\\n\"\n \n prompt += \"\\n### 股息率 %\\n\"\n # 添加股息率数据\n div_data = []\n for col in sorted([c for c in stock_data.index if c.startswith('dividend_')]):\n year = col.split('_')[1]\n if pd.notna(stock_data[col]):\n div_data.append(f\"{year}年: {stock_data[col]:.2f}%\")\n \n if div_data:\n prompt += \" | \".join(div_data) + \"\\n\"\n else:\n prompt += \"数据缺失\\n\"\n \n prompt += \"\\n### 毛利率 %\\n\"\n # 添加毛利率数据\n gm_data = []\n for col in sorted([c for c in stock_data.index if c.startswith('gross_margin_')]):\n year = col.split('_')[1]\n if pd.notna(stock_data[col]):\n gm_data.append(f\"{year}年: {stock_data[col]:.2f}%\")\n \n if gm_data:\n prompt += \" | \".join(gm_data) + \"\\n\"\n else:\n prompt += \"数据缺失(银行等金融企业通常无此指标)\\n\"\n \n prompt += \"\\n### 净利率 %\\n\"\n # 添加净利率数据\n nm_data = []\n for col in sorted([c for c in stock_data.index if c.startswith('net_margin_')]):\n year = col.split('_')[1]\n if pd.notna(stock_data[col]):\n nm_data.append(f\"{year}年: {stock_data[col]:.2f}%\")\n \n if nm_data:\n prompt += \" | \".join(nm_data) + \"\\n\"\n else:\n prompt += \"数据缺失\\n\"\n \n prompt += \"\"\"\\n## 分析要求\n\n请严格按照你的【商业本质诊断→财务健康透视→安全边际测算】三阶分析框架进行分析,并给出:\n\n1. **投资摘要**(一句话观点+明确评级:强烈推荐/推荐/中性/回避/强烈回避)\n2. **商业本质分析**(结合行业特点分析护城河和竞争优势)\n3. **财务健康诊断**(基于提供数据的深度分析)\n4. **估值与安全边际**(当前估值水平+内在价值判断)\n5. **关键风险因素**(主要下行风险+概率评估)\n6. **投资建议**(目标价格区间+持有期建议+仓位配置建议)\n\n请用markdown格式输出,确保分析有理有据,避免模糊表述。\"\"\"\n \n return prompt\n\ndef setup_logger():\n \"\"\"配置日志\"\"\"\n log_path = \"logs\"\n os.makedirs(log_path, exist_ok=True)\n logger.add(\n os.path.join(log_path, \"analysis_{time}.log\"),\n rotation=\"500 MB\",\n encoding=\"utf-8\"\n )\n\ndef load_config():\n \"\"\"加载配置\"\"\"\n load_dotenv()\n config = {}\n \n # API密钥\n config['api_key'] = os.getenv('DEEPSEEK_API_KEY')\n if not config['api_key']:\n logger.warning(\"未找到DEEPSEEK_API_KEY环境变量,将使用模拟分析\")\n logger.info(\"如需使用API分析,请在.env文件中添加:DEEPSEEK_API_KEY=your_api_key_here\")\n return None\n \n # API URL\n config['api_url'] = os.getenv('API_URL', 'https://api.deepseek.com/v1/chat/completions')\n logger.info(f\"使用API URL: {config['api_url']}\")\n \n return config\n\ndef simulate_analysis(stock_data):\n \"\"\"模拟分析结果(当没有API密钥时使用)\"\"\"\n analysis = f\"\"\"# {stock_data['stock_name']}({stock_data['stock_code']})投资分析报告\n\n## 投资摘要\n**核心观点**: 基于现有财务数据的初步分析 | **评级**: 中性(需更多数据验证)\n\n## 基本信息\n- **公司名称**: {stock_data['stock_name']}\n- **股票代码**: {stock_data['stock_code']}\n- **所属行业**: {stock_data['industry']}\n- **分析日期**: {datetime.now().strftime('%Y-%m-%d')}\n\n## 财务数据概览\n\n### ROE(净资产收益率)趋势\n\"\"\"\n \n # 添加ROE分析\n roe_data = []\n for col in sorted([c for c in stock_data.index if c.startswith('roe_')]):\n year = col.split('_')[1]\n if pd.notna(stock_data[col]):\n roe_data.append(f\"- {year}年:{stock_data[col]:.2f}%\")\n \n if roe_data:\n analysis += \"\\n\".join(roe_data)\n else:\n analysis += \"- 数据缺失\"\n \n analysis += \"\"\"\n\n### PE(市盈率)水平\n\"\"\"\n \n # 添加PE分析\n pe_data = []\n for col in sorted([c for c in stock_data.index if c.startswith('pe_')]):\n year = col.split('_')[1]\n if pd.notna(stock_data[col]):\n pe_data.append(f\"- {year}年:{stock_data[col]:.2f}倍\")\n \n if pe_data:\n analysis += \"\\n\".join(pe_data)\n else:\n analysis += \"- 数据缺失\"\n \n analysis += \"\"\"\n\n### 股息率水平\n\"\"\"\n \n # 添加股息率分析\n div_data = []\n for col in sorted([c for c in stock_data.index if c.startswith('dividend_')]):\n year = col.split('_')[1]\n if pd.notna(stock_data[col]):\n div_data.append(f\"- {year}年:{stock_data[col]:.2f}%\")\n \n if div_data:\n analysis += \"\\n\".join(div_data)\n else:\n analysis += \"- 数据缺失\"\n \n analysis += \"\"\"\n\n## 投资建议\n\n**注意**: 这是基于有限数据的模拟分析,如需详细的价值投资分析,请配置Deepseek API密钥以获得专业的三阶分析框架报告。\n\n### 风险提示\n- 本分析仅基于历史财务数据,未考虑宏观环境、行业变化等因素\n- 投资有风险,建议结合更多信息进行决策\n- 股市波动较大,请注意风险控制\n\n---\n*报告生成时间: {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}*\n\"\"\"\n \n return analysis\n\ndef main():\n \"\"\"主程序入口\"\"\"\n setup_logger()\n \n # 创建报告目录\n reports_dir = \"analysis_reports\"\n os.makedirs(reports_dir, exist_ok=True)\n \n # 读取Excel文件\n try:\n df = pd.read_excel('stock_analysis_data.xlsx')\n logger.info(f\"成功读取Excel文件,共{len(df)}只股票\")\n except Exception as e:\n logger.error(f\"读取Excel文件失败: {e}\")\n return\n \n # 获取需要分析的股票\n stocks_to_analyze = df[df['need_analysis'] == True]\n \n if len(stocks_to_analyze) == 0:\n logger.info(\"没有找到需要分析的股票(need_analysis=True)\")\n return\n \n logger.info(f\"找到{len(stocks_to_analyze)}只需要分析的股票\")\n \n # 加载配置\n config = load_config()\n \n if config:\n # 初始化分析器\n analyzer = DeepseekAnalyzer(config['api_key'], config['api_url'])\n logger.info(\"使用Deepseek API进行专业价值投资分析\")\n logger.info(f\"系统提示词已加载:{len(analyzer.system_prompt)}字符\")\n else:\n logger.info(\"未配置API密钥,将使用模拟分析\")\n analyzer = None\n \n # 分析每只股票\n for idx, stock in stocks_to_analyze.iterrows():\n logger.info(f\"开始分析: {stock['stock_name']} ({stock['stock_code']})\")\n \n # 进行深度分析\n if analyzer:\n analysis_result = analyzer.analyze_stock(stock)\n else:\n analysis_result = simulate_analysis(stock)\n \n if analysis_result:\n # 保存分析报告\n report_file = os.path.join(\n reports_dir, \n f\"{stock['stock_code']}_{datetime.now().strftime('%Y%m%d')}.md\"\n )\n \n with open(report_file, 'w', encoding='utf-8') as f:\n f.write(analysis_result)\n \n logger.info(f\"分析报告已保存: {report_file}\")\n else:\n logger.error(f\"分析失败: {stock['stock_code']}\")\n \n logger.info(\"所有分析完成\")\n\nif __name__ == \"__main__\":\n main() "}, "b14ea19dfad5d2d38ee05a0cf8848eda8141683e": {"t": 1785763223.3934712, "n": 9162, "h": "1d0fe6abfb59d4aa", "c": "import pandas as pd\nimport os\nimport json\nimport requests\nfrom loguru import logger\nfrom datetime import datetime\nfrom dotenv import load_dotenv\n\nclass DeepseekAnalyzer:\n def __init__(self, api_key, api_url, system_prompt_file=\"system_prompt.md\"):\n self.api_key = api_key\n self.api_url = api_url\n self.system_prompt = self._load_system_prompt(system_prompt_file)\n \n def _load_system_prompt(self, file_path):\n \"\"\"加载系统提示词\"\"\"\n try:\n with open(file_path, 'r', encoding='utf-8') as f:\n return f.read()\n except Exception as e:\n logger.warning(f\"无法读取系统提示词文件 {file_path}: {e}\")\n return \"你是一个专业的股票分析师,请基于提供的数据进行深入的基本面分析。\"\n \n def analyze_stock(self, stock_data):\n \"\"\"使用Deepseek API分析股票数据\"\"\"\n # 构建提示词\n prompt = self._build_prompt(stock_data)\n \n try:\n response = requests.post(\n self.api_url,\n headers={\n \"Authorization\": f\"Bearer {self.api_key}\",\n \"Content-Type\": \"application/json\"\n },\n json={\n \"model\": \"deepseek-ai/DeepSeek-R1\",\n \"messages\": [\n {\"role\": \"system\", \"content\": self.system_prompt},\n {\"role\": \"user\", \"content\": prompt}\n ],\n \"temperature\": 0.3, # 降低温度,提高一致性\n \"max_tokens\": 6000 # 增加输出长度\n },\n timeout=120 # 增加超时时间\n )\n \n if response.status_code == 200:\n result = response.json()\n return result['choices'][0]['message']['content']\n else:\n logger.error(f\"API调用失败: {response.status_code} - {response.text}\")\n return None\n except Exception as e:\n logger.error(f\"分析过程中出现错误: {e}\")\n return None\n \n def _build_prompt(self, stock_data):\n \"\"\"构建分析提示词\"\"\"\n prompt = f\"\"\"请按照你的专业分析框架,对以下股票进行深度价值投资分析:\n\n## 基本信息\n- **公司名称**: {stock_data['stock_name']}\n- **股票代码**: {stock_data['stock_code']}\n- **所属行业**: {stock_data['industry']}\n\n## 财务数据(近7年)\n\n### ROE(净资产收益率)%\n\"\"\"\n # 添加ROE数据\n roe_data = []\n for col in sorted([c for c in stock_data.index if c.startswith('roe_')]):\n year = col.split('_')[1]\n if pd.notna(stock_data[col]):\n roe_data.append(f\"{year}年: {stock_data[col]:.2f}%\")\n \n if roe_data:\n prompt += \" | \".join(roe_data) + \"\\n\"\n else:\n prompt += \"数据缺失\\n\"\n \n prompt += \"\\n### PE(市盈率)倍\\n\"\n # 添加PE数据\n pe_data = []\n for col in sorted([c for c in stock_data.index if c.startswith('pe_')]):\n year = col.split('_')[1]\n if pd.notna(stock_data[col]):\n pe_data.append(f\"{year}年: {stock_data[col]:.2f}x\")\n \n if pe_data:\n prompt += \" | \".join(pe_data) + \"\\n\"\n else:\n prompt += \"数据缺失\\n\"\n \n prompt += \"\\n### 股息率 %\\n\"\n # 添加股息率数据\n div_data = []\n for col in sorted([c for c in stock_data.index if c.startswith('dividend_')]):\n year = col.split('_')[1]\n if pd.notna(stock_data[col]):\n div_data.append(f\"{year}年: {stock_data[col]:.2f}%\")\n \n if div_data:\n prompt += \" | \".join(div_data) + \"\\n\"\n else:\n prompt += \"数据缺失\\n\"\n \n prompt += \"\\n### 毛利率 %\\n\"\n # 添加毛利率数据\n gm_data = []\n for col in sorted([c for c in stock_data.index if c.startswith('gross_margin_')]):\n year = col.split('_')[1]\n if pd.notna(stock_data[col]):\n gm_data.append(f\"{year}年: {stock_data[col]:.2f}%\")\n \n if gm_data:\n prompt += \" | \".join(gm_data) + \"\\n\"\n else:\n prompt += \"数据缺失(银行等金融企业通常无此指标)\\n\"\n \n prompt += \"\\n### 净利率 %\\n\"\n # 添加净利率数据\n nm_data = []\n for col in sorted([c for c in stock_data.index if c.startswith('net_margin_')]):\n year = col.split('_')[1]\n if pd.notna(stock_data[col]):\n nm_data.append(f\"{year}年: {stock_data[col]:.2f}%\")\n \n if nm_data:\n prompt += \" | \".join(nm_data) + \"\\n\"\n else:\n prompt += \"数据缺失\\n\"\n \n prompt += \"\"\"\\n## 分析要求\n\n请严格按照你的【商业本质诊断→财务健康透视→安全边际测算】三阶分析框架进行分析,并给出:\n\n1. **投资摘要**(一句话观点+明确评级:强烈推荐/推荐/中性/回避/强烈回避)\n2. **商业本质分析**(结合行业特点分析护城河和竞争优势)\n3. **财务健康诊断**(基于提供数据的深度分析)\n4. **估值与安全边际**(当前估值水平+内在价值判断)\n5. **关键风险因素**(主要下行风险+概率评估)\n6. **投资建议**(目标价格区间+持有期建议+仓位配置建议)\n\n请用markdown格式输出,确保分析有理有据,避免模糊表述。\"\"\"\n \n return prompt\n\ndef setup_logger():\n \"\"\"配置日志\"\"\"\n log_path = \"logs\"\n os.makedirs(log_path, exist_ok=True)\n logger.add(\n os.path.join(log_path, \"analysis_{time}.log\"),\n rotation=\"500 MB\",\n encoding=\"utf-8\"\n )\n\ndef load_config():\n \"\"\"加载配置\"\"\"\n load_dotenv()\n config = {}\n \n # API密钥\n config['api_key'] = os.getenv('DEEPSEEK_API_KEY')\n if not config['api_key']:\n logger.error(\"未找到DEEPSEEK_API_KEY环境变量,请设置API密钥\")\n logger.info(\"请在.env文件中添加:DEEPSEEK_API_KEY=your_api_key_here\")\n return None\n \n # API URL\n config['api_url'] = os.getenv('API_URL', 'https://api.deepseek.com/v1/chat/completions')\n logger.info(f\"使用API URL: {config['api_url']}\")\n \n return config\n\ndef simulate_analysis(stock_data):\n \"\"\"模拟分析结果(当没有API密钥时使用)\"\"\"\n analysis = f\"\"\"# {stock_data['stock_name']}({stock_data['stock_code']})投资分析报告\n\n## 投资摘要\n**核心观点**: 基于现有财务数据的初步分析 | **评级**: 中性(需更多数据验证)\n\n## 基本信息\n- **公司名称**: {stock_data['stock_name']}\n- **股票代码**: {stock_data['stock_code']}\n- **所属行业**: {stock_data['industry']}\n- **分析日期**: {datetime.now().strftime('%Y-%m-%d')}\n\n## 财务数据概览\n\n### ROE(净资产收益率)趋势\n\"\"\"\n \n # 添加ROE分析\n roe_data = []\n for col in sorted([c for c in stock_data.index if c.startswith('roe_')]):\n year = col.split('_')[1]\n if pd.notna(stock_data[col]):\n roe_data.append(f\"- {year}年:{stock_data[col]:.2f}%\")\n \n if roe_data:\n analysis += \"\\n\".join(roe_data)\n else:\n analysis += \"- 数据缺失\"\n \n analysis += \"\"\"\n\n### PE(市盈率)水平\n\"\"\"\n \n # 添加PE分析\n pe_data = []\n for col in sorted([c for c in stock_data.index if c.startswith('pe_')]):\n year = col.split('_')[1]\n if pd.notna(stock_data[col]):\n pe_data.append(f\"- {year}年:{stock_data[col]:.2f}倍\")\n \n if pe_data:\n analysis += \"\\n\".join(pe_data)\n else:\n analysis += \"- 数据缺失\"\n \n analysis += \"\"\"\n\n### 股息率水平\n\"\"\"\n \n # 添加股息率分析\n div_data = []\n for col in sorted([c for c in stock_data.index if c.startswith('dividend_')]):\n year = col.split('_')[1]\n if pd.notna(stock_data[col]):\n div_data.append(f\"- {year}年:{stock_data[col]:.2f}%\")\n \n if div_data:\n analysis += \"\\n\".join(div_data)\n else:\n analysis += \"- 数据缺失\"\n \n analysis += \"\"\"\n\n## 投资建议\n\n**注意**: 这是基于有限数据的模拟分析,如需详细的价值投资分析,请配置Deepseek API密钥以获得专业的三阶分析框架报告。\n\n### 风险提示\n- 本分析仅基于历史财务数据,未考虑宏观环境、行业变化等因素\n- 投资有风险,建议结合更多信息进行决策\n- 股市波动较大,请注意风险控制\n\n---\n*报告生成时间: {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}*\n\"\"\"\n \n return analysis\n\ndef main():\n \"\"\"主程序入口\"\"\"\n setup_logger()\n \n # 创建报告目录\n reports_dir = \"analysis_reports\"\n os.makedirs(reports_dir, exist_ok=True)\n \n # 读取Excel文件\n try:\n df = pd.read_excel('stock_analysis_data.xlsx')\n logger.info(f\"成功读取Excel文件,共{len(df)}只股票\")\n except Exception as e:\n logger.error(f\"读取Excel文件失败: {e}\")\n return\n \n # 获取需要分析的股票\n stocks_to_analyze = df[df['need_analysis'] == True]\n \n if len(stocks_to_analyze) == 0:\n logger.info(\"没有找到需要分析的股票(need_analysis=True)\")\n return\n \n logger.info(f\"找到{len(stocks_to_analyze)}只需要分析的股票\")\n \n # 加载配置\n config = load_config()\n \n if config:\n # 初始化分析器\n analyzer = DeepseekAnalyzer(config['api_key'], config['api_url'])\n logger.info(\"使用Deepseek API进行专业价值投资分析\")\n logger.info(f\"系统提示词已加载:{len(analyzer.system_prompt)}字符\")\n else:\n logger.info(\"未配置API密钥,将使用模拟分析\")\n analyzer = None\n \n # 分析每只股票\n for idx, stock in stocks_to_analyze.iterrows():\n logger.info(f\"开始分析: {stock['stock_name']} ({stock['stock_code']})\")\n \n # 进行深度分析\n if analyzer:\n analysis_result = analyzer.analyze_stock(stock)\n else:\n analysis_result = simulate_analysis(stock)\n \n if analysis_result:\n # 保存分析报告\n report_file = os.path.join(\n reports_dir, \n f\"{stock['stock_code']}_{datetime.now().strftime('%Y%m%d')}.md\"\n )\n \n with open(report_file, 'w', encoding='utf-8') as f:\n f.write(analysis_result)\n \n logger.info(f\"分析报告已保存: {report_file}\")\n else:\n logger.error(f\"分析失败: {stock['stock_code']}\")\n \n logger.info(\"所有分析完成\")\n\nif __name__ == \"__main__\":\n main() "}}}} |