From 1bddf393e05dc8e86b6830f36799878d0e97bd0d Mon Sep 17 00:00:00 2001 From: oficcejo Date: Mon, 20 Oct 2025 09:18:44 +0800 Subject: [PATCH] =?UTF-8?q?=E5=A2=9E=E5=8A=A0=E5=AE=9A=E6=97=B6=E5=88=86?= =?UTF-8?q?=E6=9E=90=E5=8A=9F=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .gitignore | 5 +- AGENTS.md | 18 + README.md | 69 ++++ app.py | 35 ++ monitor_db.py | 131 +++++++ notification_service.py | 238 +++++++++++++ portfolio_db.py | 625 ++++++++++++++++++++++++++++++++ portfolio_manager.py | 526 +++++++++++++++++++++++++++ portfolio_scheduler.py | 715 +++++++++++++++++++++++++++++++++++++ portfolio_stocks.db | Bin 0 -> 28672 bytes portfolio_ui.py | 771 ++++++++++++++++++++++++++++++++++++++++ stock_analysis.db | Bin 6131712 -> 7172096 bytes stock_monitor.db | Bin 20480 -> 20480 bytes 13 files changed, 3132 insertions(+), 1 deletion(-) create mode 100644 AGENTS.md create mode 100644 portfolio_db.py create mode 100644 portfolio_manager.py create mode 100644 portfolio_scheduler.py create mode 100644 portfolio_stocks.db create mode 100644 portfolio_ui.py diff --git a/.gitignore b/.gitignore index 9616a79..f0abfa7 100644 --- a/.gitignore +++ b/.gitignore @@ -6,4 +6,7 @@ /venv /__pycache__ # 环境变量文件 -.env \ No newline at end of file +.env +/.cursor +/openspec +/docs \ No newline at end of file diff --git a/AGENTS.md b/AGENTS.md new file mode 100644 index 0000000..0669699 --- /dev/null +++ b/AGENTS.md @@ -0,0 +1,18 @@ + +# OpenSpec Instructions + +These instructions are for AI assistants working in this project. + +Always open `@/openspec/AGENTS.md` when the request: +- Mentions planning or proposals (words like proposal, spec, change, plan) +- Introduces new capabilities, breaking changes, architecture shifts, or big performance/security work +- Sounds ambiguous and you need the authoritative spec before coding + +Use `@/openspec/AGENTS.md` to learn: +- How to create and apply change proposals +- Spec format and conventions +- Project structure and guidelines + +Keep this managed block so 'openspec update' can refresh the instructions. + + \ No newline at end of file diff --git a/README.md b/README.md index 0f1dea1..bb931bb 100644 --- a/README.md +++ b/README.md @@ -12,6 +12,75 @@ image +## ✨最新更新 - 持仓定时分析功能 ⭐️ + +### 📊 持仓定时分析系统全新上线 +专为长期投资者和组合管理打造的智能持仓管理与自动化分析系统 + +#### 核心功能 +- **📝 持仓管理**:可视化管理持仓股票清单 + - 添加/编辑/删除持仓股票 + - 记录成本价、持仓数量、买入备注 + - 支持A股、港股、美股全市场 + +- **🔄 批量分析**:一键分析全部持仓 + - 顺序分析模式:稳定可靠,逐个深度分析 + - 并行分析模式:速度更快,支持3-10线程 + - 实时进度显示,详细结果展示 + +- **⏰ 定时任务**:全自动定时分析(支持多时间点)⭐️ + - **多时间点支持**:可设置多个每日分析时间(如09:25+15:05) + - 灵活添加/删除时间点,自动排序 + - 后台自动执行,无需人工干预 + - 支持立即执行和手动触发 + - 调度器状态实时监控 + +- **🎯 自动监测同步**:智能联动实时监测 + - 分析完成自动将评级结果同步到监测列表 + - 自动设置进场区间、止盈位、止损位 + - 覆盖同名股票,始终保持最新结果 + +- **📬 通知推送**:及时获取分析报告 + - 邮件通知:HTML精美格式,详细结果展示 + - Webhook通知:钉钉/飞书群消息推送 + - 包含分析概况、同步结果、个股详情 + +- **📈 分析历史**:完整的历史记录追踪 + - 每只股票的历史分析记录 + - 评级变化趋势可视化 + - 验证预测准确性 + - 优化投资决策 + +#### 使用场景 +- ✅ **长期投资者**:每日跟踪持仓,及时调整策略 +- ✅ **组合管理**:批量分析多只股票,优化资产配置 +- ✅ **自动化交易**:联动监测和量化交易,实现全自动化 +- ✅ **策略回测**:历史记录对比实际走势,验证有效性 + +#### 技术实现 +- **数据库**:SQLite持久化存储(portfolio_stocks, portfolio_analysis_history) +- **批量分析**:复用AI智能体团队,支持顺序/并行模式 +- **定时调度**:schedule库实现多时间点调度管理 +- **监测集成**:批量API无缝对接实时监测系统 +- **通知扩展**:专用通知模板,邮件/Webhook双通道 +- **统一规范**:强制使用统一的分析函数和字段名,确保代码复用和一致性 + +#### 快速开始 +```bash +# 安装依赖 +pip install schedule + +# 启动应用 +streamlit run app.py + +# 点击侧边栏"📊 持仓分析"进入功能 +``` + +#### 详细文档 +请查看 [`docs/PORTFOLIO_USAGE.md`](docs/PORTFOLIO_USAGE.md) 获取完整使用指南 + +--- + ## ✨1019 更新说明 ### 🎯 风险管理师功能增强 ⭐️ diff --git a/app.py b/app.py index 8d8ef19..cfafcc9 100644 --- a/app.py +++ b/app.py @@ -296,6 +296,8 @@ def main(): del st.session_state.show_monitor if 'show_longhubang' in st.session_state: del st.session_state.show_longhubang + if 'show_portfolio' in st.session_state: + del st.session_state.show_portfolio if st.button("📊 实时监测", use_container_width=True, key="nav_monitor"): st.session_state.show_monitor = True @@ -305,6 +307,8 @@ def main(): del st.session_state.show_main_force if 'show_longhubang' in st.session_state: del st.session_state.show_longhubang + if 'show_portfolio' in st.session_state: + del st.session_state.show_portfolio if st.button("🎯 主力选股", use_container_width=True, key="nav_main_force"): st.session_state.show_main_force = True @@ -318,6 +322,8 @@ def main(): del st.session_state.show_sector_strategy if 'show_longhubang' in st.session_state: del st.session_state.show_longhubang + if 'show_portfolio' in st.session_state: + del st.session_state.show_portfolio if st.button("🎯 智策板块", use_container_width=True, key="nav_sector_strategy"): st.session_state.show_sector_strategy = True @@ -331,6 +337,8 @@ def main(): del st.session_state.show_main_force if 'show_longhubang' in st.session_state: del st.session_state.show_longhubang + if 'show_portfolio' in st.session_state: + del st.session_state.show_portfolio if st.button("🎯 智瞰龙虎", use_container_width=True, key="nav_longhubang"): st.session_state.show_longhubang = True @@ -344,6 +352,23 @@ def main(): del st.session_state.show_main_force if 'show_sector_strategy' in st.session_state: del st.session_state.show_sector_strategy + if 'show_portfolio' in st.session_state: + del st.session_state.show_portfolio + + if st.button("📊 持仓分析", use_container_width=True, key="nav_portfolio"): + st.session_state.show_portfolio = True + if 'show_history' in st.session_state: + del st.session_state.show_history + if 'show_monitor' in st.session_state: + del st.session_state.show_monitor + if 'show_config' in st.session_state: + del st.session_state.show_config + if 'show_main_force' in st.session_state: + del st.session_state.show_main_force + if 'show_sector_strategy' in st.session_state: + del st.session_state.show_sector_strategy + if 'show_longhubang' in st.session_state: + del st.session_state.show_longhubang if st.button("🏠 返回首页", use_container_width=True, key="nav_home"): if 'show_history' in st.session_state: @@ -358,6 +383,8 @@ def main(): del st.session_state.show_sector_strategy if 'show_longhubang' in st.session_state: del st.session_state.show_longhubang + if 'show_portfolio' in st.session_state: + del st.session_state.show_portfolio if st.button("⚙️ 环境配置", use_container_width=True, key="nav_config"): st.session_state.show_config = True @@ -371,6 +398,8 @@ def main(): del st.session_state.show_sector_strategy if 'show_longhubang' in st.session_state: del st.session_state.show_longhubang + if 'show_portfolio' in st.session_state: + del st.session_state.show_portfolio st.markdown("---") @@ -471,6 +500,12 @@ def main(): display_longhubang() return + # 检查是否显示持仓分析 + if 'show_portfolio' in st.session_state and st.session_state.show_portfolio: + from portfolio_ui import display_portfolio_manager + display_portfolio_manager() + return + # 检查是否显示环境配置 if 'show_config' in st.session_state and st.session_state.show_config: display_config_manager() diff --git a/monitor_db.py b/monitor_db.py index 9fa8e41..cdc4880 100644 --- a/monitor_db.py +++ b/monitor_db.py @@ -390,6 +390,137 @@ class StockMonitorDatabase: 'quant_config': quant_config } return None + + def get_monitor_by_code(self, symbol: str) -> Optional[Dict]: + """ + 根据股票代码获取监测信息 + + Args: + symbol: 股票代码 + + Returns: + 监测股票信息字典,不存在则返回None + """ + conn = sqlite3.connect(self.db_path) + cursor = conn.cursor() + + cursor.execute(''' + SELECT * FROM monitored_stocks WHERE symbol = ? + ''', (symbol,)) + + row = cursor.fetchone() + conn.close() + + if row: + entry_range = json.loads(row[4]) + quant_config = json.loads(row[12]) if row[12] else None + + return { + 'id': row[0], + 'symbol': row[1], + 'name': row[2], + 'rating': row[3], + 'entry_range': entry_range, + 'take_profit': row[5], + 'stop_loss': row[6], + 'current_price': row[7], + 'last_checked': row[8], + 'check_interval': row[9], + 'notification_enabled': row[10], + 'quant_enabled': row[11], + 'quant_config': quant_config + } + return None + + def batch_add_or_update_monitors(self, monitors_data: List[Dict]) -> Dict[str, int]: + """ + 批量添加或更新监测股票 + + Args: + monitors_data: 监测股票数据列表,每个字典包含: + - code/symbol: 股票代码 + - name: 股票名称 + - rating: 投资评级 + - entry_min, entry_max: 进场区间 + - take_profit: 止盈位 + - stop_loss: 止损位 + - check_interval: 检查间隔(可选,默认60秒) + - notification_enabled: 是否启用通知(可选,默认True) + + Returns: + 统计字典 {"added": X, "updated": Y, "failed": Z, "total": N} + """ + added = 0 + updated = 0 + failed = 0 + + for data in monitors_data: + try: + # 兼容code和symbol两种字段名 + symbol = data.get('code') or data.get('symbol') + name = data.get('name', symbol) + rating = data.get('rating', '持有') + entry_min = data.get('entry_min') + entry_max = data.get('entry_max') + take_profit = data.get('take_profit') + stop_loss = data.get('stop_loss') + check_interval = data.get('check_interval', 60) + notification_enabled = data.get('notification_enabled', True) + + # 验证必需字段 + if not symbol or not all([entry_min, entry_max, take_profit, stop_loss]): + print(f"[WARN] {symbol} 参数不完整,跳过") + failed += 1 + continue + + # 构建entry_range + entry_range = {"min": entry_min, "max": entry_max} + + # 检查是否已存在 + existing = self.get_monitor_by_code(symbol) + + if existing: + # 更新现有监测 + self.update_monitored_stock( + existing['id'], + rating=rating, + entry_range=entry_range, + take_profit=take_profit, + stop_loss=stop_loss, + check_interval=check_interval, + notification_enabled=notification_enabled + ) + updated += 1 + print(f"[OK] 更新监测: {symbol}") + else: + # 添加新监测 + self.add_monitored_stock( + symbol=symbol, + name=name, + rating=rating, + entry_range=entry_range, + take_profit=take_profit, + stop_loss=stop_loss, + check_interval=check_interval, + notification_enabled=notification_enabled + ) + added += 1 + print(f"[OK] 添加监测: {symbol}") + + except Exception as e: + symbol_str = data.get('code') or data.get('symbol', 'Unknown') + print(f"[ERROR] 处理监测失败 ({symbol_str}): {str(e)}") + failed += 1 + + result = { + "added": added, + "updated": updated, + "failed": failed, + "total": added + updated + failed + } + + print(f"\n[OK] 批量同步完成: 新增{added}只, 更新{updated}只, 失败{failed}只") + return result # 全局数据库实例 monitor_db = StockMonitorDatabase() \ No newline at end of file diff --git a/notification_service.py b/notification_service.py index db2258a..bdc06cc 100644 --- a/notification_service.py +++ b/notification_service.py @@ -516,6 +516,244 @@ _此消息由AI股票分析系统自动发送_""" 'webhook_url': self.config['webhook_url'][:50] + '...' if self.config['webhook_url'] else '未配置', 'configured': bool(self.config['webhook_url']) } + + def send_portfolio_analysis_notification(self, analysis_results: dict, sync_result: dict = None) -> bool: + """ + 发送持仓分析完成通知 + + Args: + analysis_results: 批量分析结果 + sync_result: 监测同步结果(可选) + + Returns: + 是否发送成功 + """ + try: + # 构建通知内容 + total = analysis_results.get("total", 0) + succeeded = len([r for r in analysis_results.get("results", []) if r.get("result", {}).get("success")]) + failed = total - succeeded + elapsed_time = analysis_results.get("elapsed_time", 0) + results = analysis_results.get("results", []) + + # 邮件主题 + subject = f"持仓定时分析完成 - 共{total}只股票" + + # 构建邮件正文(HTML格式) + html_body = f""" + + + + + +

持仓定时分析完成

+
+

分析概况

+

总数: {total} 只

+

成功: {succeeded} 只

+

失败: {failed} 只

+

耗时: {elapsed_time:.2f} 秒

+ """ + + # 添加监测同步结果 + if sync_result: + html_body += f""" +

监测同步结果

+

新增监测: {sync_result.get('added', 0)} 只

+

更新监测: {sync_result.get('updated', 0)} 只

+

同步失败: {sync_result.get('failed', 0)} 只

+ """ + + html_body += """ +
+

分析结果详情

+ """ + + # 添加每只股票的详细结果 + for item in results[:10]: # 只显示前10只 + code = item.get("code", "") + result = item.get("result", {}) + + if result.get("success"): + final_decision = result.get("final_decision", {}) + stock_info = result.get("stock_info", {}) + + # 使用正确的字段名 + rating = final_decision.get("rating", "未知") + confidence = final_decision.get("confidence_level", "N/A") + entry_range = final_decision.get("entry_range", "N/A") + take_profit = final_decision.get("take_profit", "N/A") + stop_loss = final_decision.get("stop_loss", "N/A") + + # 评级颜色 + rating_class = "rating-hold" + if "强烈买入" in rating or "买入" in rating: + rating_class = "rating-buy" + elif "卖出" in rating: + rating_class = "rating-sell" + + html_body += f""" +
+

{code} {stock_info.get('name', '')} - {rating} (信心度: {confidence})

+

进场区间: {entry_range}

+

止盈位: {take_profit} | 止损位: {stop_loss}

+
+ """ + else: + error = result.get("error", "未知错误") + html_body += f""" +
+

{code} - 分析失败

+

错误: {error}

+
+ """ + + if len(results) > 10: + html_body += f"

...还有 {len(results) - 10} 只股票未显示

" + + html_body += """ + + + """ + + # 构建纯文本版本 + text_body = f""" +持仓定时分析完成 + +分析概况: +- 总数: {total} 只 +- 成功: {succeeded} 只 +- 失败: {failed} 只 +- 耗时: {elapsed_time:.2f} 秒 +""" + + if sync_result: + text_body += f""" +监测同步结果: +- 新增监测: {sync_result.get('added', 0)} 只 +- 更新监测: {sync_result.get('updated', 0)} 只 +- 同步失败: {sync_result.get('failed', 0)} 只 +""" + + text_body += "\n分析结果详情:\n" + for item in results[:10]: + code = item.get("code", "") + result = item.get("result", {}) + + if result.get("success"): + final_decision = result.get("final_decision", {}) + stock_info = result.get("stock_info", {}) + # 使用正确的字段名 + rating = final_decision.get("rating", "未知") + text_body += f"- {code} {stock_info.get('name', '')}: {rating}\n" + else: + error = result.get("error", "未知错误") + text_body += f"- {code}: 分析失败 ({error})\n" + + success = False + + # 发送邮件 + if self.config['email_enabled']: + email_success = self._send_custom_email(subject, html_body, text_body) + if email_success: + success = True + print("[OK] 邮件通知发送成功") + + # 发送Webhook + if self.config['webhook_enabled']: + webhook_success = self._send_portfolio_webhook(analysis_results, sync_result) + if webhook_success: + success = True + print("[OK] Webhook通知发送成功") + + return success + + except Exception as e: + print(f"[ERROR] 发送持仓分析通知失败: {str(e)}") + import traceback + traceback.print_exc() + return False + + def _send_custom_email(self, subject: str, html_body: str, text_body: str) -> bool: + """发送自定义邮件""" + try: + msg = MIMEMultipart('alternative') + msg['From'] = self.config['email_from'] + msg['To'] = self.config['email_to'] + msg['Subject'] = subject + + part1 = MIMEText(text_body, 'plain', 'utf-8') + part2 = MIMEText(html_body, 'html', 'utf-8') + + msg.attach(part1) + msg.attach(part2) + + with smtplib.SMTP(self.config['smtp_server'], self.config['smtp_port']) as server: + server.starttls() + server.login(self.config['email_from'], self.config['email_password']) + server.send_message(msg) + + return True + + except Exception as e: + print(f"[ERROR] 邮件发送失败: {str(e)}") + return False + + def _send_portfolio_webhook(self, analysis_results: dict, sync_result: dict = None) -> bool: + """发送持仓分析Webhook通知""" + try: + import requests + + total = analysis_results.get("total", 0) + succeeded = len([r for r in analysis_results.get("results", []) if r.get("result", {}).get("success")]) + failed = total - succeeded + elapsed_time = analysis_results.get("elapsed_time", 0) + + # 构建Markdown消息 + content = f"### 持仓定时分析完成\\n\\n" + content += f"**分析概况**\\n" + content += f"- 总数: {total} 只\\n" + content += f"- 成功: {succeeded} 只\\n" + content += f"- 失败: {failed} 只\\n" + content += f"- 耗时: {elapsed_time:.2f} 秒\\n\\n" + + if sync_result: + content += f"**监测同步**\\n" + content += f"- 新增: {sync_result.get('added', 0)} 只\\n" + content += f"- 更新: {sync_result.get('updated', 0)} 只\\n\\n" + + # 根据webhook类型构建请求 + if self.config['webhook_type'] == 'dingtalk': + data = { + "msgtype": "markdown", + "markdown": { + "title": f"{self.config['webhook_keyword']}", + "text": f"{self.config['webhook_keyword']}\\n\\n{content}" + } + } + else: # feishu + data = { + "msg_type": "text", + "content": { + "text": content + } + } + + response = requests.post(self.config['webhook_url'], json=data, timeout=10) + return response.status_code == 200 + + except Exception as e: + print(f"[ERROR] Webhook发送失败: {str(e)}") + return False # 全局通知服务实例 notification_service = NotificationService() \ No newline at end of file diff --git a/portfolio_db.py b/portfolio_db.py new file mode 100644 index 0000000..6b0f595 --- /dev/null +++ b/portfolio_db.py @@ -0,0 +1,625 @@ +""" +持仓股票数据库管理模块 + +提供持仓股票和分析历史的数据库操作接口 +""" + +import sqlite3 +from datetime import datetime +from typing import List, Dict, Optional, Tuple +import os + +# 数据库文件路径 +DB_PATH = "portfolio_stocks.db" + + +class PortfolioDB: + """持仓股票数据库管理类""" + + def __init__(self, db_path: str = DB_PATH): + """ + 初始化数据库连接 + + Args: + db_path: 数据库文件路径 + """ + self.db_path = db_path + self._init_database() + + def _get_connection(self) -> sqlite3.Connection: + """获取数据库连接""" + conn = sqlite3.connect(self.db_path) + conn.row_factory = sqlite3.Row # 使查询结果可以通过列名访问 + return conn + + def _init_database(self): + """初始化数据库表结构""" + conn = self._get_connection() + cursor = conn.cursor() + + try: + # 创建持仓股票表 + cursor.execute(''' + CREATE TABLE IF NOT EXISTS portfolio_stocks ( + id INTEGER PRIMARY KEY AUTOINCREMENT, + code TEXT NOT NULL UNIQUE, + name TEXT NOT NULL, + cost_price REAL, + quantity INTEGER, + note TEXT, + auto_monitor BOOLEAN DEFAULT 1, + created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, + updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP + ) + ''') + + # 创建持仓分析历史表 + cursor.execute(''' + CREATE TABLE IF NOT EXISTS portfolio_analysis_history ( + id INTEGER PRIMARY KEY AUTOINCREMENT, + portfolio_stock_id INTEGER NOT NULL, + analysis_time TIMESTAMP DEFAULT CURRENT_TIMESTAMP, + rating TEXT, + confidence REAL, + current_price REAL, + target_price REAL, + entry_min REAL, + entry_max REAL, + take_profit REAL, + stop_loss REAL, + summary TEXT, + FOREIGN KEY (portfolio_stock_id) REFERENCES portfolio_stocks(id) ON DELETE CASCADE + ) + ''') + + # 创建索引以提升查询性能 + cursor.execute(''' + CREATE INDEX IF NOT EXISTS idx_portfolio_analysis_stock_id + ON portfolio_analysis_history(portfolio_stock_id) + ''') + + cursor.execute(''' + CREATE INDEX IF NOT EXISTS idx_portfolio_analysis_time + ON portfolio_analysis_history(analysis_time DESC) + ''') + + conn.commit() + print(f"[OK] 数据库初始化成功: {self.db_path}") + + except Exception as e: + print(f"[ERROR] 数据库初始化失败: {e}") + conn.rollback() + raise + finally: + conn.close() + + # ==================== 持仓股票CRUD操作 ==================== + + def add_stock(self, code: str, name: str, cost_price: Optional[float] = None, + quantity: Optional[int] = None, note: str = "", + auto_monitor: bool = True) -> int: + """ + 添加持仓股票 + + Args: + code: 股票代码 + name: 股票名称 + cost_price: 持仓成本价(可选) + quantity: 持仓数量(可选) + note: 备注信息 + auto_monitor: 是否自动同步到监测列表 + + Returns: + 新增股票的ID + + Raises: + sqlite3.IntegrityError: 如果股票代码已存在 + """ + conn = self._get_connection() + cursor = conn.cursor() + + try: + cursor.execute(''' + INSERT INTO portfolio_stocks + (code, name, cost_price, quantity, note, auto_monitor, created_at, updated_at) + VALUES (?, ?, ?, ?, ?, ?, ?, ?) + ''', (code, name, cost_price, quantity, note, auto_monitor, + datetime.now(), datetime.now())) + + conn.commit() + stock_id = cursor.lastrowid + print(f"[OK] 添加持仓股票成功: {code} {name} (ID: {stock_id})") + return stock_id + + except sqlite3.IntegrityError as e: + print(f"[ERROR] 股票代码已存在: {code}") + raise ValueError(f"股票代码 {code} 已存在") from e + except Exception as e: + print(f"[ERROR] 添加持仓股票失败: {e}") + conn.rollback() + raise + finally: + conn.close() + + def update_stock(self, stock_id: int, **kwargs) -> bool: + """ + 更新持仓股票信息 + + Args: + stock_id: 股票ID + **kwargs: 要更新的字段(code, name, cost_price, quantity, note, auto_monitor) + + Returns: + 是否更新成功 + """ + conn = self._get_connection() + cursor = conn.cursor() + + # 允许更新的字段 + allowed_fields = ['code', 'name', 'cost_price', 'quantity', 'note', 'auto_monitor'] + update_fields = {k: v for k, v in kwargs.items() if k in allowed_fields} + + if not update_fields: + print("[WARN] 没有需要更新的字段") + return False + + # 添加更新时间 + update_fields['updated_at'] = datetime.now() + + # 构建SQL语句 + set_clause = ', '.join([f"{field} = ?" for field in update_fields.keys()]) + values = list(update_fields.values()) + [stock_id] + + try: + cursor.execute(f''' + UPDATE portfolio_stocks + SET {set_clause} + WHERE id = ? + ''', values) + + conn.commit() + + if cursor.rowcount > 0: + print(f"[OK] 更新持仓股票成功: ID {stock_id}") + return True + else: + print(f"[WARN] 未找到股票: ID {stock_id}") + return False + + except Exception as e: + print(f"[ERROR] 更新持仓股票失败: {e}") + conn.rollback() + raise + finally: + conn.close() + + def delete_stock(self, stock_id: int) -> bool: + """ + 删除持仓股票(级联删除其所有分析历史) + + Args: + stock_id: 股票ID + + Returns: + 是否删除成功 + """ + conn = self._get_connection() + cursor = conn.cursor() + + try: + # 由于设置了ON DELETE CASCADE,删除股票会自动删除其分析历史 + cursor.execute('DELETE FROM portfolio_stocks WHERE id = ?', (stock_id,)) + conn.commit() + + if cursor.rowcount > 0: + print(f"[OK] 删除持仓股票成功: ID {stock_id}") + return True + else: + print(f"[WARN] 未找到股票: ID {stock_id}") + return False + + except Exception as e: + print(f"[ERROR] 删除持仓股票失败: {e}") + conn.rollback() + raise + finally: + conn.close() + + def get_stock(self, stock_id: int) -> Optional[Dict]: + """ + 获取单只持仓股票信息 + + Args: + stock_id: 股票ID + + Returns: + 股票信息字典,不存在则返回None + """ + conn = self._get_connection() + cursor = conn.cursor() + + try: + cursor.execute('SELECT * FROM portfolio_stocks WHERE id = ?', (stock_id,)) + row = cursor.fetchone() + + if row: + return dict(row) + return None + + finally: + conn.close() + + def get_stock_by_code(self, code: str) -> Optional[Dict]: + """ + 根据股票代码获取持仓股票信息 + + Args: + code: 股票代码 + + Returns: + 股票信息字典,不存在则返回None + """ + conn = self._get_connection() + cursor = conn.cursor() + + try: + cursor.execute('SELECT * FROM portfolio_stocks WHERE code = ?', (code,)) + row = cursor.fetchone() + + if row: + return dict(row) + return None + + finally: + conn.close() + + def get_all_stocks(self, auto_monitor_only: bool = False) -> List[Dict]: + """ + 获取所有持仓股票列表 + + Args: + auto_monitor_only: 是否只返回启用自动监测的股票 + + Returns: + 股票信息字典列表 + """ + conn = self._get_connection() + cursor = conn.cursor() + + try: + if auto_monitor_only: + cursor.execute(''' + SELECT * FROM portfolio_stocks + WHERE auto_monitor = 1 + ORDER BY created_at DESC + ''') + else: + cursor.execute('SELECT * FROM portfolio_stocks ORDER BY created_at DESC') + + rows = cursor.fetchall() + return [dict(row) for row in rows] + + finally: + conn.close() + + def search_stocks(self, keyword: str) -> List[Dict]: + """ + 搜索持仓股票(按代码或名称) + + Args: + keyword: 搜索关键词 + + Returns: + 匹配的股票信息字典列表 + """ + conn = self._get_connection() + cursor = conn.cursor() + + try: + keyword_pattern = f"%{keyword}%" + cursor.execute(''' + SELECT * FROM portfolio_stocks + WHERE code LIKE ? OR name LIKE ? + ORDER BY created_at DESC + ''', (keyword_pattern, keyword_pattern)) + + rows = cursor.fetchall() + return [dict(row) for row in rows] + + finally: + conn.close() + + def get_stock_count(self) -> int: + """ + 获取持仓股票总数 + + Returns: + 股票数量 + """ + conn = self._get_connection() + cursor = conn.cursor() + + try: + cursor.execute('SELECT COUNT(*) as count FROM portfolio_stocks') + result = cursor.fetchone() + return result['count'] + + finally: + conn.close() + + # ==================== 分析历史记录操作 ==================== + + def save_analysis(self, stock_id: int, rating: str, confidence: float, + current_price: float, target_price: Optional[float] = None, + entry_min: Optional[float] = None, entry_max: Optional[float] = None, + take_profit: Optional[float] = None, stop_loss: Optional[float] = None, + summary: str = "") -> int: + """ + 保存分析历史记录 + + Args: + stock_id: 持仓股票ID + rating: 投资评级(买入/持有/卖出) + confidence: 信心度(0-10) + current_price: 当前价格 + target_price: 目标价位 + entry_min: 进场区间最小值 + entry_max: 进场区间最大值 + take_profit: 止盈位 + stop_loss: 止损位 + summary: 分析摘要 + + Returns: + 新增分析记录的ID + """ + conn = self._get_connection() + cursor = conn.cursor() + + try: + cursor.execute(''' + INSERT INTO portfolio_analysis_history + (portfolio_stock_id, analysis_time, rating, confidence, current_price, + target_price, entry_min, entry_max, take_profit, stop_loss, summary) + VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?) + ''', (stock_id, datetime.now(), rating, confidence, current_price, + target_price, entry_min, entry_max, take_profit, stop_loss, summary)) + + conn.commit() + analysis_id = cursor.lastrowid + print(f"[OK] 保存分析历史成功: 股票ID {stock_id}, 评级 {rating}") + return analysis_id + + except Exception as e: + print(f"[ERROR] 保存分析历史失败: {e}") + conn.rollback() + raise + finally: + conn.close() + + def get_analysis_history(self, stock_id: int, limit: int = 10) -> List[Dict]: + """ + 获取股票的分析历史记录 + + Args: + stock_id: 持仓股票ID + limit: 返回记录数量限制 + + Returns: + 分析历史记录列表(按时间倒序) + """ + conn = self._get_connection() + cursor = conn.cursor() + + try: + cursor.execute(''' + SELECT * FROM portfolio_analysis_history + WHERE portfolio_stock_id = ? + ORDER BY analysis_time DESC + LIMIT ? + ''', (stock_id, limit)) + + rows = cursor.fetchall() + return [dict(row) for row in rows] + + finally: + conn.close() + + def get_latest_analysis_history(self, stock_id: int, limit: int = 10) -> List[Dict]: + """ + 获取股票的最新分析历史记录(按时间倒序) + + 这是 get_analysis_history 的别名方法,用于保持代码兼容性 + + Args: + stock_id: 持仓股票ID + limit: 返回记录数量限制 + + Returns: + 分析历史记录列表(按时间倒序) + """ + return self.get_analysis_history(stock_id, limit) + + def get_latest_analysis(self, stock_id: int) -> Optional[Dict]: + """ + 获取股票的最新一次分析记录 + + Args: + stock_id: 持仓股票ID + + Returns: + 最新分析记录字典,不存在则返回None + """ + conn = self._get_connection() + cursor = conn.cursor() + + try: + cursor.execute(''' + SELECT * FROM portfolio_analysis_history + WHERE portfolio_stock_id = ? + ORDER BY analysis_time DESC + LIMIT 1 + ''', (stock_id,)) + + row = cursor.fetchone() + if row: + return dict(row) + return None + + finally: + conn.close() + + def get_rating_changes(self, stock_id: int, days: int = 30) -> List[Tuple[str, str, str]]: + """ + 获取股票在指定天数内的评级变化 + + Args: + stock_id: 持仓股票ID + days: 查询天数 + + Returns: + 评级变化列表 [(时间, 旧评级, 新评级), ...] + """ + conn = self._get_connection() + cursor = conn.cursor() + + try: + cursor.execute(''' + SELECT analysis_time, rating + FROM portfolio_analysis_history + WHERE portfolio_stock_id = ? + AND analysis_time >= datetime('now', '-' || ? || ' days') + ORDER BY analysis_time ASC + ''', (stock_id, days)) + + rows = cursor.fetchall() + + changes = [] + for i in range(1, len(rows)): + prev_rating = rows[i-1]['rating'] + curr_rating = rows[i]['rating'] + if prev_rating != curr_rating: + changes.append(( + rows[i]['analysis_time'], + prev_rating, + curr_rating + )) + + return changes + + finally: + conn.close() + + def delete_old_analysis(self, days: int = 90) -> int: + """ + 删除超过指定天数的分析历史记录 + + Args: + days: 保留天数 + + Returns: + 删除的记录数量 + """ + conn = self._get_connection() + cursor = conn.cursor() + + try: + cursor.execute(''' + DELETE FROM portfolio_analysis_history + WHERE analysis_time < datetime('now', '-' || ? || ' days') + ''', (days,)) + + conn.commit() + deleted_count = cursor.rowcount + print(f"[OK] 清理历史分析记录: 删除 {deleted_count} 条记录") + return deleted_count + + except Exception as e: + print(f"[ERROR] 清理历史分析记录失败: {e}") + conn.rollback() + raise + finally: + conn.close() + + def get_all_latest_analysis(self) -> List[Dict]: + """ + 获取所有持仓股票的最新分析记录 + + Returns: + 包含股票信息和最新分析的字典列表 + """ + conn = self._get_connection() + cursor = conn.cursor() + + try: + cursor.execute(''' + SELECT + s.*, + h.rating, h.confidence, h.current_price, h.target_price, + h.entry_min, h.entry_max, h.take_profit, h.stop_loss, + h.analysis_time + FROM portfolio_stocks s + LEFT JOIN ( + SELECT h1.* + FROM portfolio_analysis_history h1 + INNER JOIN ( + SELECT portfolio_stock_id, MAX(analysis_time) as max_time + FROM portfolio_analysis_history + GROUP BY portfolio_stock_id + ) h2 + ON h1.portfolio_stock_id = h2.portfolio_stock_id + AND h1.analysis_time = h2.max_time + ) h ON s.id = h.portfolio_stock_id + ORDER BY s.created_at DESC + ''') + + rows = cursor.fetchall() + return [dict(row) for row in rows] + + finally: + conn.close() + + +# 创建全局数据库实例 +portfolio_db = PortfolioDB() + + +if __name__ == "__main__": + # 测试代码 + print("=" * 50) + print("持仓股票数据库测试") + print("=" * 50) + + # 初始化数据库 + db = PortfolioDB("test_portfolio.db") + + # 测试添加股票 + try: + stock_id = db.add_stock("600519", "贵州茅台", 1650.5, 100, "长期持有") + print(f"\n添加股票ID: {stock_id}") + except ValueError as e: + print(f"\n{e}") + + # 测试查询所有股票 + print("\n所有持仓股票:") + stocks = db.get_all_stocks() + for stock in stocks: + print(f" {stock['code']} {stock['name']}") + + # 测试保存分析历史 + if stocks: + stock_id = stocks[0]['id'] + analysis_id = db.save_analysis( + stock_id, "买入", 8.5, 1700.0, 1850.0, + 1600.0, 1650.0, 1900.0, 1500.0, + "技术面和基本面均良好" + ) + print(f"\n保存分析记录ID: {analysis_id}") + + # 查询分析历史 + print(f"\n股票 {stocks[0]['code']} 的分析历史:") + history = db.get_analysis_history(stock_id) + for h in history: + print(f" {h['analysis_time']}: {h['rating']} (信心度: {h['confidence']})") + + print("\n[OK] 数据库测试完成") + diff --git a/portfolio_manager.py b/portfolio_manager.py new file mode 100644 index 0000000..879ab84 --- /dev/null +++ b/portfolio_manager.py @@ -0,0 +1,526 @@ +""" +持仓管理器模块 + +提供持仓股票管理和批量分析功能 +""" + +import time +from typing import List, Dict, Optional, Tuple +from concurrent.futures import ThreadPoolExecutor, as_completed +from datetime import datetime + +# 导入必要的模块 +from portfolio_db import portfolio_db + + +class PortfolioManager: + """持仓管理器类""" + + def __init__(self, model="deepseek-chat"): + """ + 初始化持仓管理器 + + Args: + model: AI模型(deepseek-chat 或 deepseek-reasoner) + """ + self.model = model + self.db = portfolio_db + + # ==================== 持仓股票管理 ==================== + + def add_stock(self, code: str, name: str, cost_price: Optional[float] = None, + quantity: Optional[int] = None, note: str = "", + auto_monitor: bool = True) -> Tuple[bool, str, Optional[int]]: + """ + 添加持仓股票 + + Args: + code: 股票代码 + name: 股票名称 + cost_price: 持仓成本价 + quantity: 持仓数量 + note: 备注 + auto_monitor: 是否自动同步到监测 + + Returns: + (成功标志, 消息, 股票ID) + """ + try: + # 验证股票代码格式 + code = code.strip().upper() + if not code: + return False, "股票代码不能为空", None + + # 检查股票代码是否已存在 + existing = self.db.get_stock_by_code(code) + if existing: + return False, f"股票代码 {code} 已存在", None + + # 添加到数据库 + stock_id = self.db.add_stock(code, name, cost_price, quantity, note, auto_monitor) + return True, f"添加持仓股票成功: {code} {name}", stock_id + + except Exception as e: + return False, f"添加失败: {str(e)}", None + + def update_stock(self, stock_id: int, **kwargs) -> Tuple[bool, str]: + """ + 更新持仓股票信息 + + Args: + stock_id: 股票ID + **kwargs: 要更新的字段 + + Returns: + (成功标志, 消息) + """ + try: + success = self.db.update_stock(stock_id, **kwargs) + if success: + return True, "更新成功" + else: + return False, f"未找到股票ID: {stock_id}" + except Exception as e: + return False, f"更新失败: {str(e)}" + + def delete_stock(self, stock_id: int) -> Tuple[bool, str]: + """ + 删除持仓股票(级联删除分析历史) + + Args: + stock_id: 股票ID + + Returns: + (成功标志, 消息) + """ + try: + success = self.db.delete_stock(stock_id) + if success: + return True, "删除成功" + else: + return False, f"未找到股票ID: {stock_id}" + except Exception as e: + return False, f"删除失败: {str(e)}" + + def get_stock(self, stock_id: int) -> Optional[Dict]: + """获取单只持仓股票信息""" + return self.db.get_stock(stock_id) + + def get_all_stocks(self, auto_monitor_only: bool = False) -> List[Dict]: + """获取所有持仓股票列表""" + return self.db.get_all_stocks(auto_monitor_only) + + def search_stocks(self, keyword: str) -> List[Dict]: + """搜索持仓股票""" + return self.db.search_stocks(keyword) + + def get_stock_count(self) -> int: + """获取持仓股票总数""" + return self.db.get_stock_count() + + # ==================== 单只股票分析 ==================== + + def analyze_single_stock(self, stock_code: str, period="1y", + selected_agents: List[str] = None) -> Dict: + """ + 分析单只股票(复用app.py中的分析逻辑) + + Args: + stock_code: 股票代码 + period: 数据周期 + selected_agents: 选中的分析师列表 + + Returns: + 分析结果字典 + """ + print(f"\n{'='*60}") + print(f"开始分析股票: {stock_code}") + print(f"{'='*60}\n") + + try: + # 导入app.py中的分析函数 + from app import analyze_single_stock_for_batch + + # 构建分析师配置 + if selected_agents is None: + enabled_analysts_config = { + 'technical': True, + 'fundamental': True, + 'fund_flow': True, + 'risk': True, + 'sentiment': False, + 'news': False + } + else: + enabled_analysts_config = { + 'technical': 'technical' in selected_agents, + 'fundamental': 'fundamental' in selected_agents, + 'fund_flow': 'fund_flow' in selected_agents, + 'risk': 'risk' in selected_agents, + 'sentiment': 'sentiment' in selected_agents, + 'news': 'news' in selected_agents + } + + # 调用首页的分析函数 + result = analyze_single_stock_for_batch( + symbol=stock_code, + period=period, + enabled_analysts_config=enabled_analysts_config, + selected_model=self.model + ) + + # 检查结果 + if not result.get("success", False): + error_msg = result.get("error", "未知错误") + print(f"\n[ERROR] 分析失败: {error_msg}") + return {"success": False, "error": error_msg} + + print(f"\n{'='*60}") + print(f"分析完成!") + print(f"{'='*60}\n") + + return result + + except Exception as e: + print(f"\n[ERROR] 分析失败: {str(e)}") + import traceback + traceback.print_exc() + return {"success": False, "error": str(e)} + + # ==================== 批量分析 ==================== + + def batch_analyze_sequential(self, stock_codes: List[str], period="1y", + selected_agents: List[str] = None, + progress_callback=None) -> Dict: + """ + 顺序批量分析(逐只分析) + + Args: + stock_codes: 股票代码列表 + period: 数据周期 + selected_agents: 选中的分析师列表 + progress_callback: 进度回调函数 callback(current, total, code, status) + + Returns: + 批量分析结果字典 + """ + print(f"\n{'='*60}") + print(f"开始批量分析 (顺序模式): {len(stock_codes)}只股票") + print(f"{'='*60}\n") + + start_time = time.time() + results = [] + failed = [] + + for i, code in enumerate(stock_codes, 1): + print(f"\n--- 分析进度: {i}/{len(stock_codes)} ---") + + if progress_callback: + progress_callback(i, len(stock_codes), code, "analyzing") + + try: + result = self.analyze_single_stock(code, period, selected_agents) + + if result.get("success"): + results.append({ + "code": code, + "result": result + }) + if progress_callback: + progress_callback(i, len(stock_codes), code, "success") + else: + failed.append({ + "code": code, + "error": result.get("error", "未知错误") + }) + if progress_callback: + progress_callback(i, len(stock_codes), code, "failed") + + except Exception as e: + print(f"[ERROR] 股票 {code} 分析失败: {str(e)}") + failed.append({ + "code": code, + "error": str(e) + }) + if progress_callback: + progress_callback(i, len(stock_codes), code, "error") + + elapsed_time = time.time() - start_time + + print(f"\n{'='*60}") + print(f"批量分析完成!") + print(f"成功: {len(results)}只, 失败: {len(failed)}只, 耗时: {elapsed_time:.1f}秒") + print(f"{'='*60}\n") + + return { + "success": True, + "mode": "sequential", + "total": len(stock_codes), + "succeeded": len(results), + "failed": len(failed), + "results": results, + "failed_stocks": failed, + "elapsed_time": elapsed_time + } + + def batch_analyze_parallel(self, stock_codes: List[str], period="1y", + selected_agents: List[str] = None, + max_workers: int = 3, + progress_callback=None) -> Dict: + """ + 并行批量分析(多线程) + + Args: + stock_codes: 股票代码列表 + period: 数据周期 + selected_agents: 选中的分析师列表 + max_workers: 最大并发数(默认3) + progress_callback: 进度回调函数 + + Returns: + 批量分析结果字典 + """ + print(f"\n{'='*60}") + print(f"开始批量分析 (并行模式): {len(stock_codes)}只股票, 并发数: {max_workers}") + print(f"{'='*60}\n") + + start_time = time.time() + results = [] + failed = [] + completed = 0 + + with ThreadPoolExecutor(max_workers=max_workers) as executor: + # 提交所有任务 + future_to_code = { + executor.submit(self.analyze_single_stock, code, period, selected_agents): code + for code in stock_codes + } + + # 处理完成的任务 + for future in as_completed(future_to_code): + code = future_to_code[future] + completed += 1 + + try: + result = future.result() + + if result.get("success"): + results.append({ + "code": code, + "result": result + }) + print(f"\n[{completed}/{len(stock_codes)}] {code} 分析完成") + if progress_callback: + progress_callback(completed, len(stock_codes), code, "success") + else: + failed.append({ + "code": code, + "error": result.get("error", "未知错误") + }) + print(f"\n[{completed}/{len(stock_codes)}] {code} 分析失败: {result.get('error')}") + if progress_callback: + progress_callback(completed, len(stock_codes), code, "failed") + + except Exception as e: + failed.append({ + "code": code, + "error": str(e) + }) + print(f"\n[{completed}/{len(stock_codes)}] {code} 分析异常: {str(e)}") + if progress_callback: + progress_callback(completed, len(stock_codes), code, "error") + + elapsed_time = time.time() - start_time + + print(f"\n{'='*60}") + print(f"批量分析完成!") + print(f"成功: {len(results)}只, 失败: {len(failed)}只, 耗时: {elapsed_time:.1f}秒") + print(f"{'='*60}\n") + + return { + "success": True, + "mode": "parallel", + "total": len(stock_codes), + "succeeded": len(results), + "failed": len(failed), + "results": results, + "failed_stocks": failed, + "elapsed_time": elapsed_time + } + + def batch_analyze_portfolio(self, mode="sequential", period="1y", + selected_agents: List[str] = None, + max_workers: int = 3, + progress_callback=None) -> Dict: + """ + 批量分析所有持仓股票 + + Args: + mode: 分析模式 ("sequential" 或 "parallel") + period: 数据周期 + selected_agents: 选中的分析师列表 + max_workers: 并行模式下的最大并发数(默认3) + progress_callback: 进度回调函数 + + Returns: + 批量分析结果字典 + """ + # 获取所有持仓股票 + stocks = self.get_all_stocks() + + if not stocks: + return { + "success": False, + "error": "没有持仓股票" + } + + stock_codes = [stock['code'] for stock in stocks] + + # 根据模式选择分析方法 + if mode == "parallel": + return self.batch_analyze_parallel(stock_codes, period, selected_agents, max_workers, progress_callback) + else: + return self.batch_analyze_sequential(stock_codes, period, selected_agents, progress_callback) + + # ==================== 分析结果保存 ==================== + + def save_analysis_results(self, analysis_results: Dict) -> List[int]: + """ + 保存批量分析结果到数据库 + + Args: + analysis_results: 批量分析结果字典 + + Returns: + 保存的分析记录ID列表 + """ + saved_ids = [] + + if not analysis_results.get("success"): + print("[WARN] 分析未成功,跳过保存") + return saved_ids + + for item in analysis_results.get("results", []): + code = item.get("code") + result = item.get("result", {}) + + # 获取持仓股票ID + stock = self.db.get_stock_by_code(code) + if not stock: + print(f"[WARN] 未找到持仓股票: {code},跳过保存") + continue + + stock_id = stock['id'] + + # 提取分析结果关键信息 + final_decision = result.get("final_decision", {}) + stock_info = result.get("stock_info", {}) + + # 使用正确的字段名 + rating = final_decision.get("rating", "持有") + confidence = final_decision.get("confidence_level", 5.0) + current_price = stock_info.get("current_price", 0.0) + target_price_str = final_decision.get("target_price", "") + entry_range = final_decision.get("entry_range", "") + take_profit_str = final_decision.get("take_profit", "") + stop_loss_str = final_decision.get("stop_loss", "") + + # 解析目标价格 + import re + target_price = None + if target_price_str: + try: + numbers = re.findall(r'\d+\.?\d*', str(target_price_str)) + if numbers: + target_price = float(numbers[0]) + except: + pass + + # 解析进场区间 + entry_min, entry_max = None, None + if entry_range and isinstance(entry_range, str) and "-" in entry_range: + try: + parts = entry_range.split("-") + entry_min = float(parts[0].strip()) + entry_max = float(parts[1].strip()) + except: + pass + + # 解析止盈止损 + take_profit, stop_loss = None, None + if take_profit_str: + try: + numbers = re.findall(r'\d+\.?\d*', str(take_profit_str)) + if numbers: + take_profit = float(numbers[0]) + except: + pass + + if stop_loss_str: + try: + numbers = re.findall(r'\d+\.?\d*', str(stop_loss_str)) + if numbers: + stop_loss = float(numbers[0]) + except: + pass + + # 生成摘要(使用advice或summary字段) + summary = final_decision.get("advice", final_decision.get("summary", ""))[:500] # 限制长度 + + try: + # 保存到数据库 + analysis_id = self.db.save_analysis( + stock_id, rating, confidence, current_price, target_price, + entry_min, entry_max, take_profit, stop_loss, summary + ) + saved_ids.append(analysis_id) + + except Exception as e: + print(f"[ERROR] 保存分析结果失败 ({code}): {str(e)}") + + print(f"\n[OK] 保存分析结果: {len(saved_ids)}条记录") + return saved_ids + + # ==================== 分析历史查询 ==================== + + def get_analysis_history(self, stock_id: int, limit: int = 10) -> List[Dict]: + """获取股票分析历史""" + return self.db.get_analysis_history(stock_id, limit) + + def get_latest_analysis(self, stock_id: int) -> Optional[Dict]: + """获取最新一次分析""" + return self.db.get_latest_analysis(stock_id) + + def get_all_latest_analysis(self) -> List[Dict]: + """获取所有持仓股票的最新分析""" + return self.db.get_all_latest_analysis() + + def get_rating_changes(self, stock_id: int, days: int = 30) -> List[Tuple]: + """获取评级变化""" + return self.db.get_rating_changes(stock_id, days) + + +# 创建全局实例 +portfolio_manager = PortfolioManager() + + +if __name__ == "__main__": + # 测试代码 + print("="*60) + print("持仓管理器测试") + print("="*60) + + manager = PortfolioManager() + + # 测试添加持仓 + success, msg, stock_id = manager.add_stock("000001", "平安银行", 12.5, 1000, "测试持仓") + print(f"\n添加持仓: {msg}") + + # 测试获取所有持仓 + stocks = manager.get_all_stocks() + print(f"\n持仓数量: {len(stocks)}") + for stock in stocks: + print(f" {stock['code']} {stock['name']} - 成本:{stock['cost_price']}, 数量:{stock['quantity']}") + + print("\n[OK] 持仓管理器测试完成") + diff --git a/portfolio_scheduler.py b/portfolio_scheduler.py new file mode 100644 index 0000000..af07b15 --- /dev/null +++ b/portfolio_scheduler.py @@ -0,0 +1,715 @@ +""" +持仓定时分析调度器模块 + +提供定时任务调度功能,在设定时间自动执行持仓批量分析 +""" + +import schedule +import threading +import time +from datetime import datetime +from typing import Optional, Callable +import traceback + +from portfolio_manager import portfolio_manager +from notification_service import NotificationService + + +class PortfolioScheduler: + """持仓分析定时调度器""" + + def __init__(self): + """初始化调度器""" + self.schedule_times = ["09:30"] # 支持多个定时时间点 + self.analysis_mode = "sequential" # 默认顺序分析 + self._is_running = False # 使用私有属性 + self.thread = None + self.last_run_time = None + self.next_run_time = None + self.auto_monitor_sync = True # 默认启用自动监测同步 + self.notification_enabled = True # 默认启用通知 + self.selected_agents = None # None表示全部分析师 + self.notification_service = NotificationService() + self.max_workers = 3 # 并行模式的线程数 + + # 兼容旧代码的属性 + @property + def schedule_time(self) -> str: + """获取第一个定时时间(向后兼容)""" + return self.schedule_times[0] if self.schedule_times else "09:30" + + def is_running(self) -> bool: + """ + 检查调度器是否正在运行 + + Returns: + bool: True表示运行中,False表示已停止 + """ + return self._is_running + + def set_schedule_time(self, time_str: str): + """ + 设置定时分析时间(向后兼容,设置为单个时间) + + Args: + time_str: 时间字符串,格式"HH:MM"(如"08:00") + """ + try: + # 验证时间格式 + datetime.strptime(time_str, "%H:%M") + self.schedule_times = [time_str] + print(f"[OK] 设置定时分析时间: {time_str}") + + # 如果调度器正在运行,重新调度 + if self._is_running: + self._reschedule() + + except ValueError: + print(f"[ERROR] 无效的时间格式: {time_str},应为 HH:MM") + + def add_schedule_time(self, time_str: str) -> bool: + """ + 添加一个定时分析时间点 + + Args: + time_str: 时间字符串,格式"HH:MM" + + Returns: + 是否添加成功 + """ + try: + # 验证时间格式 + datetime.strptime(time_str, "%H:%M") + + # 检查是否已存在 + if time_str in self.schedule_times: + print(f"[WARN] 定时时间 {time_str} 已存在") + return False + + self.schedule_times.append(time_str) + self.schedule_times.sort() # 保持时间顺序 + print(f"[OK] 添加定时时间: {time_str}") + + # 如果调度器正在运行,重新调度 + if self._is_running: + self._reschedule() + + return True + + except ValueError: + print(f"[ERROR] 无效的时间格式: {time_str},应为 HH:MM") + return False + + def remove_schedule_time(self, time_str: str) -> bool: + """ + 删除一个定时分析时间点 + + Args: + time_str: 时间字符串 + + Returns: + 是否删除成功 + """ + if time_str in self.schedule_times: + self.schedule_times.remove(time_str) + print(f"[OK] 删除定时时间: {time_str}") + + # 如果调度器正在运行,重新调度 + if self._is_running: + self._reschedule() + + return True + else: + print(f"[WARN] 定时时间 {time_str} 不存在") + return False + + def get_schedule_times(self) -> list: + """ + 获取所有定时分析时间点 + + Returns: + 时间列表 + """ + return self.schedule_times.copy() + + def set_schedule_times(self, times: list): + """ + 批量设置定时分析时间点 + + Args: + times: 时间字符串列表 + """ + valid_times = [] + for time_str in times: + try: + datetime.strptime(time_str, "%H:%M") + valid_times.append(time_str) + except ValueError: + print(f"[WARN] 跳过无效时间: {time_str}") + + if valid_times: + self.schedule_times = sorted(valid_times) + print(f"[OK] 设置定时时间: {', '.join(self.schedule_times)}") + + # 如果调度器正在运行,重新调度 + if self._is_running: + self._reschedule() + else: + print(f"[ERROR] 没有有效的时间配置") + + def set_analysis_mode(self, mode: str): + """ + 设置分析模式 + + Args: + mode: "sequential" 或 "parallel" + """ + if mode in ["sequential", "parallel"]: + self.analysis_mode = mode + print(f"[OK] 设置分析模式: {mode}") + else: + print(f"[ERROR] 无效的分析模式: {mode}") + + def set_auto_monitor_sync(self, enabled: bool): + """设置是否启用自动监测同步""" + self.auto_monitor_sync = enabled + print(f"[OK] 自动监测同步: {'启用' if enabled else '禁用'}") + + def set_notification_enabled(self, enabled: bool): + """设置是否启用通知""" + self.notification_enabled = enabled + print(f"[OK] 通知推送: {'启用' if enabled else '禁用'}") + + def set_selected_agents(self, agents: Optional[list]): + """设置参与分析的AI分析师""" + self.selected_agents = agents + if agents: + print(f"[OK] 选择分析师: {', '.join(agents)}") + else: + print("[OK] 选择分析师: 全部") + + def _scheduled_job(self): + """定时任务执行的作业""" + print("\n" + "="*60) + print(f"定时分析开始: {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}") + print("="*60 + "\n") + + try: + # 1. 执行批量分析 + print("[1/4] 执行持仓批量分析...") + analysis_results = portfolio_manager.batch_analyze_portfolio( + mode=self.analysis_mode, + max_workers=self.max_workers, + selected_agents=self.selected_agents + ) + + if not analysis_results.get("success"): + error_msg = analysis_results.get("error", "未知错误") + print(f"[ERROR] 批量分析失败: {error_msg}") + + # 发送错误通知 + if self.notification_enabled: + self._send_error_notification(error_msg) + + self.last_run_time = datetime.now() + return + + # 2. 保存分析结果 + print("\n[2/4] 保存分析结果...") + saved_ids = portfolio_manager.save_analysis_results(analysis_results) + print(f"[OK] 保存 {len(saved_ids)} 条分析记录") + + # 3. 自动监测同步 + sync_result = None + if self.auto_monitor_sync: + print("\n[3/4] 自动同步到监测列表...") + sync_result = self._sync_to_monitor(analysis_results) + else: + print("\n[3/4] 跳过监测同步(已禁用)") + + # 4. 发送通知 + if self.notification_enabled: + print("\n[4/4] 发送通知...") + self._send_notification(analysis_results, sync_result) + else: + print("\n[4/4] 跳过通知发送(已禁用)") + + # 更新运行时间 + self.last_run_time = datetime.now() + + print("\n" + "="*60) + print(f"定时分析完成: {self.last_run_time.strftime('%Y-%m-%d %H:%M:%S')}") + print("="*60 + "\n") + + except Exception as e: + print(f"\n[ERROR] 定时任务执行异常: {str(e)}") + traceback.print_exc() + + # 发送错误通知 + if self.notification_enabled: + self._send_error_notification(str(e)) + + self.last_run_time = datetime.now() + + def _sync_to_monitor(self, analysis_results: dict) -> dict: + """ + 同步分析结果到监测列表 + + Args: + analysis_results: 批量分析结果 + + Returns: + 同步结果统计 + """ + try: + from monitor_db import monitor_db + + # 准备批量监测数据 + monitors_data = [] + failed_count = 0 + + for item in analysis_results.get("results", []): + code = item.get("code") + result = item.get("result", {}) + + # 检查分析是否成功 + if not result.get("success"): + continue + + final_decision = result.get("final_decision", {}) + stock_info = result.get("stock_info", {}) + + # 检查是否启用自动监测 + stock = portfolio_manager.db.get_stock_by_code(code) + if not stock or not stock.get("auto_monitor"): + continue + + # 从final_decision中提取数据(使用正确的字段名) + rating = final_decision.get("rating", "持有") + entry_range = final_decision.get("entry_range", "") + take_profit_str = final_decision.get("take_profit", "") + stop_loss_str = final_decision.get("stop_loss", "") + + # 解析进场区间(格式如"10.5-12.3") + entry_min, entry_max = None, None + if entry_range and isinstance(entry_range, str) and "-" in entry_range: + try: + parts = entry_range.split("-") + entry_min = float(parts[0].strip()) + entry_max = float(parts[1].strip()) + except: + pass + + # 解析止盈止损(提取数字) + import re + take_profit, stop_loss = None, None + if take_profit_str: + try: + numbers = re.findall(r'\d+\.?\d*', str(take_profit_str)) + if numbers: + take_profit = float(numbers[0]) + except: + pass + + if stop_loss_str: + try: + numbers = re.findall(r'\d+\.?\d*', str(stop_loss_str)) + if numbers: + stop_loss = float(numbers[0]) + except: + pass + + # 检查参数有效性 + if not all([entry_min, entry_max, take_profit, stop_loss]): + print(f"[WARN] {code} 参数不完整,跳过同步") + failed_count += 1 + continue + + # 构建监测数据 + monitor_data = { + "code": code, + "name": stock_info.get("name", stock.get("name", code)), + "rating": rating, + "entry_min": entry_min, + "entry_max": entry_max, + "take_profit": take_profit, + "stop_loss": stop_loss, + "check_interval": 60, + "notification_enabled": True + } + + monitors_data.append(monitor_data) + + # 使用批量API同步 + if monitors_data: + result = monitor_db.batch_add_or_update_monitors(monitors_data) + return result + else: + print("[WARN] 没有需要同步的监测数据") + return {"added": 0, "updated": 0, "failed": 0, "total": 0} + + except Exception as e: + print(f"[ERROR] 监测同步异常: {str(e)}") + import traceback + traceback.print_exc() + return {"added": 0, "updated": 0, "failed": 0, "total": 0} + + def _send_notification(self, analysis_results: dict, sync_result: Optional[dict]): + """ + 发送分析完成通知(使用新的notification_service方法) + + Args: + analysis_results: 批量分析结果 + sync_result: 监测同步结果 + """ + try: + from notification_service import notification_service + + # 使用新的专用通知方法 + success = notification_service.send_portfolio_analysis_notification( + analysis_results, sync_result + ) + + if success: + print("[OK] 持仓分析通知发送成功") + else: + print("[WARN] 持仓分析通知发送失败(可能未配置通知服务)") + + except Exception as e: + print(f"[ERROR] 发送通知失败: {str(e)}") + import traceback + traceback.print_exc() + + def _send_error_notification(self, error_msg: str): + """发送错误通知""" + try: + content = f""" +持仓定时分析执行失败 + +错误信息: +{error_msg} + +时间:{datetime.now().strftime('%Y-%m-%d %H:%M:%S')} + +请检查系统日志或手动运行分析。 +""" + + if self.notification_service.email_enabled: + self.notification_service.send_email("【持仓定时分析】执行失败", content) + + if self.notification_service.webhook_enabled: + self.notification_service.send_webhook("【持仓定时分析】执行失败", content) + + except Exception as e: + print(f"[ERROR] 发送错误通知失败: {str(e)}") + + def _generate_notification_content(self, analysis_results: dict, + sync_result: Optional[dict]) -> str: + """ + 生成通知内容 + + Args: + analysis_results: 批量分析结果 + sync_result: 监测同步结果 + + Returns: + 通知内容文本 + """ + total = analysis_results.get("total", 0) + succeeded = analysis_results.get("succeeded", 0) + failed = analysis_results.get("failed", 0) + mode = analysis_results.get("mode", "sequential") + elapsed_time = analysis_results.get("elapsed_time", 0) + + # 统计评级分布 + rating_stats = {"买入": 0, "持有": 0, "卖出": 0} + rating_changes = [] + + for item in analysis_results.get("results", []): + code = item.get("code") + result = item.get("result", {}) + final_decision = result.get("final_decision", {}) + rating = final_decision.get("investment_rating", "持有") + + rating_stats[rating] = rating_stats.get(rating, 0) + 1 + + # 检查评级变化 + stock = portfolio_manager.db.get_stock_by_code(code) + if stock: + history = portfolio_manager.db.get_analysis_history(stock['id'], limit=2) + if len(history) >= 2: + old_rating = history[1]['rating'] + new_rating = history[0]['rating'] + if old_rating != new_rating: + stock_info = result.get("stock_info", {}) + name = stock_info.get("name", stock.get("name", code)) + rating_changes.append(f"{code} {name}: {old_rating} → {new_rating}") + + # 构建通知内容 + content = f""" +持仓定时分析报告 - {datetime.now().strftime('%Y-%m-%d %H:%M')} + +📊 分析完成:{total}只持仓股票 +✅ 成功:{succeeded}只 +❌ 失败:{failed}只 +⏱ 耗时:{elapsed_time:.1f}秒 +🔄 模式:{'顺序分析' if mode == 'sequential' else '并行分析'} + +📈 投资评级分布: +• 买入:{rating_stats.get('买入', 0)}只 +• 持有:{rating_stats.get('持有', 0)}只 +• 卖出:{rating_stats.get('卖出', 0)}只 +""" + + # 添加评级变化 + if rating_changes: + content += "\n🔔 评级变化:\n" + for change in rating_changes[:5]: # 最多显示5个 + content += f"• {change}\n" + + # 添加监测同步结果 + if sync_result: + content += f""" +🎯 监测同步: +• 新增:{sync_result.get('added', 0)}只 +• 更新:{sync_result.get('updated', 0)}只 +• 失败:{sync_result.get('failed', 0)}只 +""" + + # 添加失败股票 + if failed > 0: + failed_stocks = analysis_results.get("failed_stocks", []) + content += "\n⚠️ 失败股票:\n" + for stock in failed_stocks[:3]: # 最多显示3个 + content += f"• {stock.get('code')}: {stock.get('error')}\n" + + content += "\n详细报告请登录系统查看。" + + return content + + def _reschedule(self): + """重新调度任务(支持多个时间点)""" + schedule.clear() + for time_str in self.schedule_times: + schedule.every().day.at(time_str).do(self._scheduled_job) + self._update_next_run_time() + print(f"[OK] 重新调度任务: 每天 {', '.join(self.schedule_times)}") + + def _update_next_run_time(self): + """更新下次运行时间""" + jobs = schedule.jobs + if jobs: + self.next_run_time = jobs[0].next_run + else: + self.next_run_time = None + + def _run_schedule_loop(self): + """调度循环(在后台线程中运行)""" + print("[OK] 定时调度器线程启动") + + while self._is_running: + schedule.run_pending() + self._update_next_run_time() + time.sleep(1) + + print("[OK] 定时调度器线程停止") + + def start(self) -> bool: + """ + 启动定时任务 + + Returns: + 是否启动成功 + """ + if self._is_running: + print("[WARN] 定时任务已在运行中") + return False + + # 检查持仓数量 + stock_count = portfolio_manager.get_stock_count() + if stock_count == 0: + print("[ERROR] 没有持仓股票,无法启动定时任务") + return False + + # 检查时间配置 + if not self.schedule_times: + print("[ERROR] 没有配置定时时间") + return False + + # 调度任务(为每个时间点创建任务) + schedule.clear() + for time_str in self.schedule_times: + schedule.every().day.at(time_str).do(self._scheduled_job) + print(f"[OK] 添加调度任务: 每天 {time_str}") + + self._update_next_run_time() + + # 启动后台线程 + self._is_running = True + self.thread = threading.Thread(target=self._run_schedule_loop, daemon=True) + self.thread.start() + + print(f"\n[OK] 定时任务已启动") + print(f" 调度时间: {', '.join(self.schedule_times)}") + print(f" 分析模式: {self.analysis_mode}") + print(f" 持仓数量: {stock_count}只") + if self.next_run_time: + print(f" 下次运行: {self.next_run_time.strftime('%Y-%m-%d %H:%M:%S')}") + + return True + + def stop(self) -> bool: + """ + 停止定时任务 + + Returns: + 是否停止成功 + """ + if not self._is_running: + print("[WARN] 定时任务未运行") + return False + + self._is_running = False + schedule.clear() + + # 等待线程结束(最多等待2秒) + if self.thread and self.thread.is_alive(): + self.thread.join(timeout=2) + + self.thread = None + self.next_run_time = None + + print("[OK] 定时任务已停止") + return True + + def run_once(self) -> bool: + """ + 立即执行一次分析(不影响定时计划) + + Returns: + 是否执行成功 + """ + # 检查持仓数量 + stock_count = portfolio_manager.get_stock_count() + if stock_count == 0: + print("[ERROR] 没有持仓股票") + return False + + print("[OK] 立即执行持仓分析...") + self._scheduled_job() + return True + + def get_status(self) -> dict: + """ + 获取定时任务状态 + + Returns: + 状态字典 + """ + return { + "is_running": self._is_running, + "schedule_time": self.schedule_time, + "analysis_mode": self.analysis_mode, + "auto_monitor_sync": self.auto_monitor_sync, + "notification_enabled": self.notification_enabled, + "last_run_time": self.last_run_time.strftime("%Y-%m-%d %H:%M:%S") if self.last_run_time else None, + "next_run_time": self.next_run_time.strftime("%Y-%m-%d %H:%M:%S") if self.next_run_time else None, + "portfolio_count": portfolio_manager.get_stock_count() + } + + def get_next_run_time(self) -> Optional[str]: + """ + 获取下次运行时间 + + Returns: + 下次运行时间字符串,格式"HH:MM",如果未设置则返回None + """ + if self.next_run_time: + return self.next_run_time.strftime("%H:%M") + return None + + def update_config(self, schedule_time: str = None, analysis_mode: str = None, + max_workers: int = None, auto_sync_monitor: bool = None, + send_notification: bool = None): + """ + 更新调度器配置 + + Args: + schedule_time: 定时分析时间(格式"HH:MM",可选,用于向后兼容) + analysis_mode: 分析模式("sequential"或"parallel") + max_workers: 并行线程数(仅在parallel模式下有效) + auto_sync_monitor: 是否自动同步到监测 + send_notification: 是否发送通知 + """ + if schedule_time is not None: + self.set_schedule_time(schedule_time) + + if analysis_mode is not None: + self.set_analysis_mode(analysis_mode) + + if max_workers is not None: + self.max_workers = max_workers + print(f"[OK] 设置并行线程数: {max_workers}") + + if auto_sync_monitor is not None: + self.set_auto_monitor_sync(auto_sync_monitor) + + if send_notification is not None: + self.set_notification_enabled(send_notification) + + print("[OK] 配置已更新") + + def start_scheduler(self) -> bool: + """ + 启动调度器(UI友好方法名) + + Returns: + 是否启动成功 + """ + return self.start() + + def stop_scheduler(self) -> bool: + """ + 停止调度器(UI友好方法名) + + Returns: + 是否停止成功 + """ + return self.stop() + + def run_analysis_now(self) -> bool: + """ + 立即执行一次分析(UI友好方法名) + + Returns: + 是否执行成功 + """ + return self.run_once() + + +# 创建全局实例 +portfolio_scheduler = PortfolioScheduler() + + +if __name__ == "__main__": + # 测试代码 + print("="*60) + print("持仓定时调度器测试") + print("="*60) + + scheduler = PortfolioScheduler() + + # 设置配置 + scheduler.set_schedule_time("09:00") + scheduler.set_analysis_mode("sequential") + scheduler.set_auto_monitor_sync(True) + scheduler.set_notification_enabled(False) # 测试时禁用通知 + + # 获取状态 + status = scheduler.get_status() + print("\n调度器状态:") + for key, value in status.items(): + print(f" {key}: {value}") + + print("\n[OK] 调度器测试完成") + diff --git a/portfolio_stocks.db b/portfolio_stocks.db new file mode 100644 index 0000000000000000000000000000000000000000..e7995cac409025e1de66c94285215d8e68cb1f5d GIT binary patch literal 28672 zcmeI4Z)h837{KpxNv;Vb@2s1pqVr(LQnqHf%m0AxZt1OrwQ1KRZkiFV6h|D{Rg$%Epk*KLgP(!?{l~L=gPflrsGwf>Xo~zIT^PlWUS~qGRCm z!lifjyzlcq&+mEO9CvxHiR}ZDoMZCE(nLmPyu>PkBnh5j2!iOu8;v);nemRY>5bHP z+WhS#+)uyaKz|U{jvoofJi6eB+jF*gd;kpy00AHX1b_e#00RFVf!T7zE#8#iHeE3{8EEnc1hVD1~243aX`f10#P9m75c;#`O-5?S-UoD zAV<|SFHeo*TdQ zYLx!#i({;q#i@-`lhM}#lZwZ-r^M#Dta#Pfy?MW}V)^DdI5nLq$dWvxFURJp3PpT( z+j{Y2rsZOKqF9jdmprp&XlOtblqhQ}lx?nZtdz^hxojHWFW1&?ZOkpM>gmbsZRl8; zXq!#eu0$_Ms27E5@+iKj$90!CElbj@F%u|!x$RIcxemOUohJx%8pWKy;~i)~00;m9 zAOHk_01yBIKmZ5;0U!Vb?ks^_W;@aSFl{1ig5dFZSbwN;@nYrNxyr$#i*Fp}gI=}W zdw}zB{$AG8%Xt`2Fyi+|Je)i13$Y$wYsoN$bw5O^y1iI8%T``HvUv3L(vkN&)~_;* z^F_Fj+ZPT8!bXjCl3k{HYdOvvsGK@eIdphw-&+eGUE+PC$8bB2=5^g{nBlkx=a2XU zZjKFvxnOI_D5>fu6%yFmAm>{=bYbDr`Gt?)tQ}n4lx^3En1m*XC6Z)J$*YO85AOHk_01yBIKmZ5;0U!VbfB+Bx0zlv{ zC$QE;3FLB}f9>_7>I+o%)g;whC)eH#Fe~@}c88ZhpP=WF+xe^WUFVe3#S@pN+5{cPJF{bK%8< zvx_HRqWQ<>Rbc$iuv!D2NY(aoHU~ip4`WqIbC{az@~}SN(%E+w=MFD?aJDjc+RAfp z=at5L6@|x+^W3_x?2k;I;<-`nSU=BdHS)0zWt#QaT9P1X2i0_%pbuA;R}Q^i+5h3D zr8D~$PoA*y%%9))zqk4snzr!|e4(_fn`uQAc3yFbc9@&03IsULr>U~>A=T78A9z8f z5V2P2DYh8tdAt#S&>aY}o^Vj3XVvM+2{{$DR3|5KTY;-OIKcV6RrEDbYwqb>!*5dO zCnETsSM>n@|2k}d!Go$2ztdB~h*N}|0@d3Zz z6VS&Sl2NJux1-Ah`U`!FE~6W00bNDEpf7Pfz}Fft_yht#00;m9AOHk_01yBIKmZ5; z0U!Vb?iK=O%0}8P6iJ$F$|u#Ke41(Hv{gNAQBRmvA*G%%QIyT5-v2wV5Y8*k>&S*& zs2}Cg96E(QLqFUtzJVP;00;m9AOHk_01yBIKmZ5;0U!Vb>IkgG_3ur~5!7M~duy>$ zUtw!0R_h`?tH)9k It7QRy1DrdQHvj+t literal 0 HcmV?d00001 diff --git a/portfolio_ui.py b/portfolio_ui.py new file mode 100644 index 0000000..29eb2ac --- /dev/null +++ b/portfolio_ui.py @@ -0,0 +1,771 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- +""" +持仓管理UI模块 +提供持仓股票的增删改查、批量分析、定时任务管理界面 +""" + +import streamlit as st +import pandas as pd +from datetime import datetime +from typing import List, Dict +import time + +from portfolio_manager import portfolio_manager +from portfolio_scheduler import portfolio_scheduler + + +def display_portfolio_manager(): + """显示持仓管理主界面""" + + st.markdown("## 📊 持仓定时分析") + st.markdown("---") + + # 创建标签页 + tab1, tab2, tab3, tab4 = st.tabs([ + "📝 持仓管理", + "🔄 批量分析", + "⏰ 定时任务", + "📈 分析历史" + ]) + + with tab1: + display_portfolio_stocks() + + with tab2: + display_batch_analysis() + + with tab3: + display_scheduler_management() + + with tab4: + display_analysis_history() + + +def display_portfolio_stocks(): + """显示持仓股票列表和管理""" + + st.markdown("### 📝 持仓股票管理") + + # 添加新股票表单 + with st.expander("➕ 添加持仓股票", expanded=False): + display_add_stock_form() + + # 获取所有持仓股票 + stocks = portfolio_manager.get_all_stocks() + + if not stocks: + st.info("暂无持仓股票,请添加股票代码开始管理。") + return + + # 显示统计 + col1, col2, col3 = st.columns(3) + with col1: + st.metric("持仓股票数", len(stocks)) + with col2: + auto_monitor_count = sum(1 for s in stocks if s.get("auto_monitor")) + st.metric("启用自动监测", auto_monitor_count) + with col3: + total_cost = sum( + s.get("cost_price", 0) * s.get("quantity", 0) + for s in stocks + if s.get("cost_price") and s.get("quantity") + ) + st.metric("总持仓成本", f"¥{total_cost:,.2f}") + + st.markdown("---") + + # 显示股票列表(卡片式布局) + for stock in stocks: + display_stock_card(stock) + + +def display_stock_card(stock: Dict): + """显示单个股票卡片""" + + code = stock.get("code", "") + name = stock.get("name", "") + cost_price = stock.get("cost_price") + quantity = stock.get("quantity") + note = stock.get("note", "") + auto_monitor = stock.get("auto_monitor", True) + created_at = stock.get("created_at", "") + + # 创建卡片 + with st.container(): + col1, col2, col3, col4 = st.columns([3, 2, 2, 2]) + + with col1: + st.markdown(f"**{code}** {name}") + if note: + st.caption(f"备注: {note}") + + with col2: + if cost_price and quantity: + st.write(f"成本: ¥{cost_price:.2f}") + st.caption(f"数量: {quantity}股") + else: + st.caption("未设置持仓") + + with col3: + if auto_monitor: + st.success("🔔 自动监测") + else: + st.info("🔕 不监测") + + with col4: + col_edit, col_del = st.columns(2) + with col_edit: + if st.button("✏️", key=f"edit_{code}", help="编辑"): + st.session_state[f"editing_{code}"] = True + st.rerun() + with col_del: + if st.button("🗑️", key=f"del_{code}", help="删除"): + portfolio_manager.delete_stock(code) + st.success(f"已删除 {code}") + time.sleep(0.5) + st.rerun() + + # 编辑表单(如果处于编辑状态) + if st.session_state.get(f"editing_{code}"): + with st.form(key=f"edit_form_{code}"): + st.markdown(f"#### 编辑 {code}") + + col_a, col_b = st.columns(2) + with col_a: + new_cost = st.number_input( + "成本价", + value=cost_price if cost_price else 0.0, + min_value=0.0, + step=0.01 + ) + new_quantity = st.number_input( + "持仓数量", + value=quantity if quantity else 0, + min_value=0, + step=100 + ) + + with col_b: + new_note = st.text_area("备注", value=note, height=80) + new_auto_monitor = st.checkbox("自动同步到监测", value=auto_monitor) + + col_submit, col_cancel = st.columns(2) + with col_submit: + if st.form_submit_button("保存", type="primary"): + portfolio_manager.update_stock( + code, + cost_price=new_cost if new_cost > 0 else None, + quantity=new_quantity if new_quantity > 0 else None, + note=new_note, + auto_monitor=new_auto_monitor + ) + del st.session_state[f"editing_{code}"] + st.success("更新成功!") + time.sleep(0.5) + st.rerun() + + with col_cancel: + if st.form_submit_button("取消"): + del st.session_state[f"editing_{code}"] + st.rerun() + + st.markdown("---") + + +def display_add_stock_form(): + """显示添加股票表单""" + + with st.form(key="add_stock_form"): + col1, col2 = st.columns(2) + + with col1: + code = st.text_input( + "股票代码*", + placeholder="例如: 600519.SH 或 000001.SZ", + help="必填,格式:代码.市场(SH/SZ/HK/US)" + ) + name = st.text_input( + "股票名称", + placeholder="例如: 贵州茅台", + help="可选,留空将自动获取" + ) + + with col2: + cost_price = st.number_input( + "成本价", + min_value=0.0, + step=0.01, + help="可选,用于计算收益" + ) + quantity = st.number_input( + "持仓数量", + min_value=0, + step=100, + help="可选,单位:股" + ) + + note = st.text_area("备注", height=80, placeholder="可选,记录买入理由等信息") + auto_monitor = st.checkbox("分析后自动同步到监测", value=True) + + if st.form_submit_button("➕ 添加股票", type="primary"): + if not code: + st.error("请输入股票代码") + else: + try: + portfolio_manager.add_stock( + code=code.strip().upper(), + name=name.strip() if name else None, + cost_price=cost_price if cost_price > 0 else None, + quantity=quantity if quantity > 0 else None, + note=note.strip() if note else None, + auto_monitor=auto_monitor + ) + st.success(f"✅ 已添加 {code} 到持仓列表") + time.sleep(0.5) + st.rerun() + except Exception as e: + st.error(f"添加失败: {str(e)}") + + +def display_batch_analysis(): + """显示批量分析功能""" + + st.markdown("### 🔄 批量分析持仓股票") + + stocks = portfolio_manager.get_all_stocks() + + if not stocks: + st.warning("暂无持仓股票,请先添加股票。") + return + + # 分析选项 + col1, col2, col3 = st.columns(3) + + with col1: + st.metric("持仓股票数", len(stocks)) + + with col2: + analysis_mode = st.selectbox( + "分析模式", + options=["sequential", "parallel"], + format_func=lambda x: "顺序分析" if x == "sequential" else "并行分析", + help="顺序分析较慢但稳定,并行分析更快但消耗更多资源" + ) + + with col3: + if analysis_mode == "parallel": + max_workers = st.number_input( + "并行线程数", + min_value=2, + max_value=10, + value=3, + help="同时分析的股票数量" + ) + else: + max_workers = 1 + + st.markdown("---") + + # 同步和通知选项 + col_a, col_b = st.columns(2) + + with col_a: + auto_sync = st.checkbox( + "自动同步到监测", + value=True, + help="分析完成后自动将评级结果同步到实时监测列表" + ) + + with col_b: + send_notification = st.checkbox( + "发送完成通知", + value=True, + help="通过邮件或Webhook发送分析完成通知" + ) + + # 立即分析按钮 + if st.button("🚀 立即开始分析", type="primary", use_container_width=True): + with st.spinner("正在批量分析持仓股票..."): + # 显示进度 + progress_bar = st.progress(0) + status_text = st.empty() + + # 执行批量分析 + try: + # 定义进度回调函数 + def update_progress(current, total, code, status): + progress_bar.progress(current / total) + status_map = { + "analyzing": "正在分析", + "success": "✅ 完成", + "failed": "❌ 失败", + "error": "⚠️ 错误" + } + status_text.text(f"{status_map.get(status, '处理中')} {code} ({current}/{total})") + + result = portfolio_manager.batch_analyze_portfolio( + mode=analysis_mode, + max_workers=max_workers, + progress_callback=update_progress + ) + + # 清除进度显示 + progress_bar.empty() + status_text.empty() + + # 显示结果 + st.success(f"✅ 批量分析完成!") + + col_r1, col_r2, col_r3, col_r4 = st.columns(4) + with col_r1: + st.metric("总计", result.get("total", 0)) + with col_r2: + st.metric("成功", result.get("succeeded", 0)) + with col_r3: + st.metric("失败", result.get("failed", 0)) + with col_r4: + st.metric("耗时", f"{result.get('elapsed_time', 0):.1f}秒") + + # 保存分析结果到数据库 + saved_ids = portfolio_manager.save_analysis_results(result) + st.info(f"💾 已保存 {len(saved_ids)} 条分析记录到数据库") + + # 同步到监测 + sync_result = None # 初始化同步结果 + if auto_sync: + with st.spinner("正在同步到监测列表..."): + from monitor_db import monitor_db + + # 准备同步数据 + monitors_to_sync = [] + for item in result.get("results", []): + # 检查分析是否成功 + if not item.get("result", {}).get("success"): + continue + + code = item["code"] + stock = portfolio_manager.db.get_stock_by_code(code) + + # 只同步启用了自动监测的股票 + if not stock or not stock.get("auto_monitor"): + continue + + analysis_result = item["result"] + stock_info = analysis_result.get("stock_info", {}) + final_decision = analysis_result.get("final_decision", {}) + + # 从final_decision中提取数据 + rating = final_decision.get("rating", "持有") + entry_range = final_decision.get("entry_range", "") + take_profit_str = final_decision.get("take_profit", "") + stop_loss_str = final_decision.get("stop_loss", "") + + # 解析进场区间(格式如"10.5-12.3") + entry_min, entry_max = None, None + if entry_range and isinstance(entry_range, str) and "-" in entry_range: + try: + parts = entry_range.split("-") + entry_min = float(parts[0].strip()) + entry_max = float(parts[1].strip()) + except: + pass + + # 解析止盈止损(提取数字) + import re + take_profit, stop_loss = None, None + if take_profit_str: + try: + numbers = re.findall(r'\d+\.?\d*', str(take_profit_str)) + if numbers: + take_profit = float(numbers[0]) + except: + pass + + if stop_loss_str: + try: + numbers = re.findall(r'\d+\.?\d*', str(stop_loss_str)) + if numbers: + stop_loss = float(numbers[0]) + except: + pass + + # 只有当所有必需字段都有效时才添加 + if entry_min and entry_max and take_profit and stop_loss: + monitors_to_sync.append({ + "code": code, + "name": stock_info.get("name", stock.get("name", "")), + "rating": rating, + "entry_min": entry_min, + "entry_max": entry_max, + "take_profit": take_profit, + "stop_loss": stop_loss + }) + + if monitors_to_sync: + sync_result = monitor_db.batch_add_or_update_monitors(monitors_to_sync) + st.info(f"📊 监测同步: 新增 {sync_result.get('added', 0)} 只, 更新 {sync_result.get('updated', 0)} 只") + else: + sync_result = {"added": 0, "updated": 0, "failed": 0, "total": 0} + st.info("📊 无需同步监测列表(无启用自动监测的股票)") + + # 发送通知 + if send_notification: + from notification_service import notification_service + notification_service.send_portfolio_analysis_notification( + result, + sync_result if auto_sync else None + ) + st.info("✉️ 已发送完成通知") + + # 显示详细结果 + st.markdown("### 分析结果详情") + for item in result.get("results", []): + display_analysis_result_card(item) + + except Exception as e: + st.error(f"批量分析失败: {str(e)}") + import traceback + st.code(traceback.format_exc()) + + +def display_analysis_result_card(item: Dict): + """显示单个分析结果卡片""" + + code = item.get("code", "") + result = item.get("result", {}) + + # 检查分析是否成功 + if result.get("success"): + final_decision = result.get("final_decision", {}) + stock_info = result.get("stock_info", {}) + + # 使用正确的字段名 + rating = final_decision.get("rating", "未知") + confidence = final_decision.get("confidence_level", "N/A") + target_price = final_decision.get("target_price", "N/A") + entry_range = final_decision.get("entry_range", "N/A") + take_profit = final_decision.get("take_profit", "N/A") + stop_loss = final_decision.get("stop_loss", "N/A") + + # 评级颜色 + if "强烈买入" in rating or "买入" in rating: + rating_color = "🟢" + elif "卖出" in rating: + rating_color = "🔴" + else: + rating_color = "🟡" + + with st.expander(f"{rating_color} {code} {stock_info.get('name', '')} - {rating} (信心度: {confidence})"): + col1, col2 = st.columns(2) + + with col1: + st.markdown("**进出场位置**") + st.write(f"进场区间: {entry_range}") + st.write(f"目标价: {target_price}") + + with col2: + st.markdown("**风控位置**") + st.write(f"止盈位: {take_profit}") + st.write(f"止损位: {stop_loss}") + + # 投资建议 + advice = final_decision.get("advice", "") + if advice: + st.markdown("**投资建议**") + st.info(advice) + + else: + # 分析失败 + error = result.get("error", "未知错误") + with st.expander(f"🔴 {code} - 分析失败"): + st.error(f"错误: {error}") + + +def display_scheduler_management(): + """显示定时任务管理""" + + st.markdown("### ⏰ 定时任务管理") + + # 调度器状态 + is_running = portfolio_scheduler.is_running() + schedule_times = portfolio_scheduler.get_schedule_times() + + col1, col2, col3 = st.columns(3) + + with col1: + if is_running: + st.success("🟢 调度器运行中") + else: + st.error("🔴 调度器已停止") + + with col2: + st.info(f"⏰ 定时数量: {len(schedule_times)}个") + + with col3: + next_run = portfolio_scheduler.get_next_run_time() + if next_run: + st.info(f"⏭️ 下次运行: {next_run}") + else: + st.info("⏭️ 下次运行: 未设置") + + st.markdown("---") + + # 显示所有定时时间点 + st.markdown("#### 📋 已配置的定时时间") + + if schedule_times: + cols_per_row = 4 + for i in range(0, len(schedule_times), cols_per_row): + cols = st.columns(cols_per_row) + for j, col in enumerate(cols): + idx = i + j + if idx < len(schedule_times): + time_str = schedule_times[idx] + with col: + col_time, col_del = st.columns([3, 1]) + with col_time: + st.info(f"⏰ {time_str}") + with col_del: + if st.button("🗑️", key=f"del_time_{idx}", help="删除"): + if len(schedule_times) > 1: + portfolio_scheduler.remove_schedule_time(time_str) + st.success(f"已删除 {time_str}") + time.sleep(0.3) + st.rerun() + else: + st.error("至少保留一个定时时间") + else: + st.warning("暂无定时配置") + + # 添加新的定时时间 + with st.expander("➕ 添加定时时间", expanded=False): + col_input, col_add = st.columns([3, 1]) + with col_input: + new_time = st.time_input( + "选择时间", + value=datetime.strptime("15:05", "%H:%M").time(), + help="添加新的每日分析时间" + ) + with col_add: + st.write("") # 占位,对齐按钮 + st.write("") + if st.button("➕ 添加", type="primary", use_container_width=True): + time_str = new_time.strftime("%H:%M") + if portfolio_scheduler.add_schedule_time(time_str): + st.success(f"已添加 {time_str}") + time.sleep(0.3) + st.rerun() + else: + st.warning(f"{time_str} 已存在") + + st.markdown("---") + + # 任务配置 + with st.form(key="scheduler_config_form"): + st.markdown("#### 分析配置") + + col_a, col_b = st.columns(2) + + with col_a: + analysis_mode = st.selectbox( + "分析模式", + options=["sequential", "parallel"], + format_func=lambda x: "顺序分析" if x == "sequential" else "并行分析", + index=0 if portfolio_scheduler.analysis_mode == "sequential" else 1 + ) + + with col_b: + max_workers = st.number_input( + "并行线程数", + min_value=2, + max_value=10, + value=portfolio_scheduler.max_workers, + disabled=(analysis_mode == "sequential"), + help="仅在并行模式下生效" + ) + + auto_sync_monitor = st.checkbox( + "自动同步到监测", + value=portfolio_scheduler.auto_monitor_sync, + help="分析完成后自动将结果同步到实时监测列表" + ) + send_notification = st.checkbox( + "发送完成通知", + value=portfolio_scheduler.notification_enabled, + help="通过邮件或Webhook发送分析结果" + ) + + col_update, col_reset = st.columns(2) + + with col_update: + if st.form_submit_button("💾 更新配置", type="primary"): + portfolio_scheduler.update_config( + analysis_mode=analysis_mode, + max_workers=max_workers if analysis_mode == "parallel" else 1, + auto_sync_monitor=auto_sync_monitor, + send_notification=send_notification + ) + st.success("配置已更新!") + time.sleep(0.5) + st.rerun() + + with col_reset: + if st.form_submit_button("🔄 恢复默认"): + portfolio_scheduler.set_schedule_times(["09:30"]) + portfolio_scheduler.update_config( + analysis_mode="sequential", + max_workers=1, + auto_sync_monitor=True, + send_notification=True + ) + st.success("已恢复默认配置!") + time.sleep(0.5) + st.rerun() + + st.markdown("---") + + # 控制按钮 + col_btn1, col_btn2, col_btn3 = st.columns(3) + + with col_btn1: + if is_running: + if st.button("⏹️ 停止调度器", type="secondary", use_container_width=True): + portfolio_scheduler.stop_scheduler() + st.success("调度器已停止") + time.sleep(0.5) + st.rerun() + else: + if st.button("▶️ 启动调度器", type="primary", use_container_width=True): + portfolio_scheduler.start_scheduler() + st.success("调度器已启动") + time.sleep(0.5) + st.rerun() + + with col_btn2: + if st.button("🚀 立即执行一次", type="primary", use_container_width=True): + with st.spinner("正在执行持仓分析..."): + try: + portfolio_scheduler.run_analysis_now() + st.success("执行完成!请查看分析历史。") + except Exception as e: + st.error(f"执行失败: {str(e)}") + + with col_btn3: + if st.button("🔄 刷新状态", use_container_width=True): + st.rerun() + + +def display_analysis_history(): + """显示分析历史""" + + st.markdown("### 📈 分析历史记录") + + stocks = portfolio_manager.get_all_stocks() + + if not stocks: + st.info("暂无持仓股票") + return + + # 选择股票 + stock_codes = [s["code"] for s in stocks] + selected_code = st.selectbox( + "选择股票", + options=["全部"] + stock_codes, + help="查看特定股票的分析历史" + ) + + # 获取历史记录 + if selected_code == "全部": + # 获取所有股票的最新历史 + all_history = [] + for stock in stocks: + stock_id = stock["id"] + history = portfolio_manager.db.get_latest_analysis_history(stock_id, limit=5) + for h in history: + h["code"] = stock["code"] + h["name"] = stock["name"] + all_history.extend(history) + + # 按时间排序 + all_history.sort(key=lambda x: x.get("analysis_time", ""), reverse=True) + history_list = all_history[:20] # 只显示最近20条 + else: + # 获取指定股票的历史 + stock = next((s for s in stocks if s["code"] == selected_code), None) + if stock: + history_list = portfolio_manager.db.get_latest_analysis_history( + stock["id"], limit=20 + ) + for h in history_list: + h["code"] = stock["code"] + h["name"] = stock["name"] + else: + history_list = [] + + if not history_list: + st.info(f"暂无分析历史记录") + return + + # 显示历史记录 + st.markdown(f"共 {len(history_list)} 条记录") + + for record in history_list: + display_history_record(record) + + +def display_history_record(record: Dict): + """显示单条历史记录""" + + code = record.get("code", "") + name = record.get("name", "") + analysis_time = record.get("analysis_time", "") + rating = record.get("rating", "未知") + confidence = record.get("confidence", 0) + current_price = record.get("current_price") + target_price = record.get("target_price") + entry_min = record.get("entry_min") + entry_max = record.get("entry_max") + take_profit = record.get("take_profit") + stop_loss = record.get("stop_loss") + summary = record.get("summary", "") + + # 评级颜色 + if "强烈买入" in rating or "买入" in rating: + rating_icon = "🟢" + elif "卖出" in rating: + rating_icon = "🔴" + else: + rating_icon = "🟡" + + with st.expander( + f"{rating_icon} {code} {name} - {rating} | {analysis_time}", + expanded=False + ): + col1, col2, col3 = st.columns(3) + + with col1: + st.markdown("**价格信息**") + if current_price: + st.write(f"当时价格: ¥{current_price:.2f}") + if target_price: + st.write(f"目标价: ¥{target_price:.2f}") + + with col2: + st.markdown("**进场区间**") + if entry_min and entry_max: + st.write(f"¥{entry_min:.2f} ~ ¥{entry_max:.2f}") + + with col3: + st.markdown("**风控位置**") + if take_profit: + st.write(f"止盈: ¥{take_profit:.2f}") + if stop_loss: + st.write(f"止损: ¥{stop_loss:.2f}") + + if summary: + st.markdown("**分析摘要**") + st.info(summary) + + st.caption(f"置信度: {confidence}%") + diff --git a/stock_analysis.db b/stock_analysis.db index f2f0f27329afc8938c8e56c424db15188a686dd0..c29f662f84cc211173bc3c5c3b63805363d181db 100644 GIT binary patch delta 263886 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�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 delta 357 zcmWm8$xc%N06@{#37)h<3o;`XWm2ZA%qSEUM+z;dl`-KnSP??ZO_vh*02VG?KpNm% z*pcu9tXvD*vpW0N=dt~hf6?FV34YHf8IA?Rc>&5|)Fo Qe3{9{_rl9^d3(3|KNf0iw*UYD diff --git a/stock_monitor.db b/stock_monitor.db index ace9f811f2e9d6ec0bee6b66affc1abc9419b8bc..5439c65765cdf895704d1aee6dc6ee35ce3bdde2 100644 GIT binary patch delta 528 zcmZozz}T>Wae_2s_e2?I#_o*?OZWxYc>Xi+z2qx+v!FsI&*WN}rurf- z0R~A`Nk?`@1_nk>4hCamV*>+oBa>&n+n?;+{AADkryaAO^)x=4(^;*Qo0+F%rC?#K zXP~2?l$%%q;+X0g)H+01&IE#4!8S$)My9%k2D(ND3I+yNriNCA23Uj|8970gs=BhX z*TZZzFfcMQHha2c`P1IM7flPF?B4rg!-{9EeNT37c-p!YX1Ae*o}mfcav;yxwAR5G zWckcl4u(Lt0|A;N42-Qz&9OM5oI`*?U%g(^krD3m5ZB<4cqhjYXODQGbM%6vo^|eg z+1~$bYxj%wQ;kqV!N>q96pW03p&%&)x7pBA!O+CYz|6|X7-ln)P&qruW{AaFkT6HF j*-$Uo1KDOnNEl2$$1A1D&q<^un_tR_2{LjmGEe{jIlG*L delta 368 zcmZozz}T>Wae_2s+e8^>#L@7X zCRTuW7J3#IwPJz}Msqa29_o)la)P0Om4Ts^fr%WFn1Llo%+y#Oix|HSL#?E$x+^0) z1Hw|fbff49MNl8Z(KUf$W0eu1_QC)9ls%HRqyqSfbL2dr#mvUl) JjBJYx6aW~eT&Dm4