From 6fc6f4c2a3439f2cef2864ae684361e9230bf5ec Mon Sep 17 00:00:00 2001 From: aaron <> Date: Wed, 25 Feb 2026 22:45:16 +0800 Subject: [PATCH] update --- backend/app/news_agent/analyzer.py | 21 +++++- backend/app/news_agent/news_agent.py | 105 +++++++++------------------ backend/app/news_agent/sources.py | 38 +++++++--- 3 files changed, 83 insertions(+), 81 deletions(-) diff --git a/backend/app/news_agent/analyzer.py b/backend/app/news_agent/analyzer.py index ce74006..181a7ed 100644 --- a/backend/app/news_agent/analyzer.py +++ b/backend/app/news_agent/analyzer.py @@ -59,7 +59,19 @@ class NewsAnalyzer: ``` **分析要求**: -1. market_impact: 对市场的潜在影响(high=重大影响, medium=中等影响, low=轻微影响) +1. market_impact: 对市场的潜在影响(high/medium/low) + - **high**: 对市场或公司有**实质性、深远影响**的事件 + * 改变行业格局或公司生存状态 + * 监管政策重大变化(批准、禁止、调查) + * 系统性风险事件(破产、退市、重大欺诈) + - **medium**: 对价格有**短期影响**但不会改变长期趋势的事件 + * 财报业绩、管理层变动、一般并购 + * 评级调整、业务合作或重组 + - **low**: 常规信息,影响有限 + * 分析师观点、价格波动、一般评论 + + **判断原则**: 问自己"这条新闻会改变市场/公司的长期格局吗?" 如果会→high,如果只是短期波动→medium,如果无关紧要→low + 2. impact_type: 对价格的影响方向(bullish=利好, bearish=利空, neutral=中性) 3. sentiment: 新闻情绪(positive=正面, negative=负面, neutral=中性) 4. summary: 根据标题推断并总结新闻核心内容 @@ -108,6 +120,13 @@ class NewsAnalyzer: ] ``` +**market_impact 判断标准**: +- **high**: 对市场或公司有**实质性、深远影响**的事件(改变行业格局或公司生存状态) +- **medium**: 对价格有**短期影响**但不会改变长期趋势的事件(财报、管理层变动、一般并购等) +- **low**: 常规信息,影响有限 + +**判断原则**: 问自己"这条新闻会改变市场/公司的长期格局吗?" 如果会→high,如果只是短期波动→medium。 + 请只输出 JSON 数组,不要包含其他解释。 """ diff --git a/backend/app/news_agent/news_agent.py b/backend/app/news_agent/news_agent.py index 6488e18..7c036f8 100644 --- a/backend/app/news_agent/news_agent.py +++ b/backend/app/news_agent/news_agent.py @@ -48,8 +48,7 @@ class NewsAgent: # 配置 self.fetch_interval = 300 # 抓取间隔(秒)= 5分钟 self.min_priority = 40.0 # 最低通知优先级 - self.use_llm = True # 是否使用 LLM 分析 - self.batch_analysis = True # 是否批量分析 + self.use_llm = True # 使用 LLM 批量分析 # 统计数据 self.stats = { @@ -182,69 +181,39 @@ class NewsAgent: if not saved_articles: return - # 5. LLM 分析 + # 5. LLM 分析(仅批量分析) analyzed_count = 0 high_priority_articles = [] if self.use_llm: - # 批量分析 - if self.batch_analysis and len(saved_articles) > 1: - items_to_analyze = [item for _, item in saved_articles] - results = self.analyzer.analyze_batch(items_to_analyze) + # 只使用批量分析 + items_to_analyze = [item for _, item in saved_articles] + results = self.analyzer.analyze_batch(items_to_analyze) - for (article, _), result in zip(saved_articles, results): - if result: - priority = self.analyzer.calculate_priority( - result, - getattr(article, 'quality_score', 0.5) - ) - self.db_service.mark_as_analyzed(article.id, result, priority) + for (article, _), result in zip(saved_articles, results): + if result: + priority = self.analyzer.calculate_priority( + result, + getattr(article, 'quality_score', 0.5) + ) + self.db_service.mark_as_analyzed(article.id, result, priority) - analyzed_count += 1 - # 只发送重大影响(high)的新闻 - if result.get('market_impact') == 'high': - article_dict = article.to_dict() - article_dict.update({ - 'llm_analyzed': True, - 'market_impact': result.get('market_impact'), - 'impact_type': result.get('impact_type'), - 'sentiment': result.get('sentiment'), - 'summary': result.get('summary'), - 'key_points': result.get('key_points'), - 'trading_advice': result.get('trading_advice'), - 'relevant_symbols': result.get('relevant_symbols'), - 'priority': priority, - }) - high_priority_articles.append(article_dict) - - else: - # 单个分析 - for article, item in saved_articles: - result = self.analyzer.analyze_single(item) - - if result: - priority = self.analyzer.calculate_priority( - result, - getattr(article, 'quality_score', 0.5) - ) - self.db_service.mark_as_analyzed(article.id, result, priority) - - analyzed_count += 1 - # 只发送重大影响(high)的新闻 - if result.get('market_impact') == 'high': - article_dict = article.to_dict() - article_dict.update({ - 'llm_analyzed': True, - 'market_impact': result.get('market_impact'), - 'impact_type': result.get('impact_type'), - 'sentiment': result.get('sentiment'), - 'summary': result.get('summary'), - 'key_points': result.get('key_points'), - 'trading_advice': result.get('trading_advice'), - 'relevant_symbols': result.get('relevant_symbols'), - 'priority': priority, - }) - high_priority_articles.append(article_dict) + analyzed_count += 1 + # 只发送重大影响(high)的新闻 + if result.get('market_impact') == 'high': + article_dict = article.to_dict() + article_dict.update({ + 'llm_analyzed': True, + 'market_impact': result.get('market_impact'), + 'impact_type': result.get('impact_type'), + 'sentiment': result.get('sentiment'), + 'summary': result.get('summary'), + 'key_points': result.get('key_points'), + 'trading_advice': result.get('trading_advice'), + 'relevant_symbols': result.get('relevant_symbols'), + 'priority': priority, + }) + high_priority_articles.append(article_dict) else: # 使用规则分析 @@ -274,7 +243,7 @@ class NewsAgent: self.stats['total_analyzed'] += analyzed_count logger.info(f"分析了 {analyzed_count} 条文章") - # 6. 发送通知 + # 6. 发送通知(仅批量发送) if high_priority_articles: # 按优先级排序 high_priority_articles.sort( @@ -282,17 +251,11 @@ class NewsAgent: reverse=True ) - # 如果只有1-2条,单独发送;否则批量发送 - if len(high_priority_articles) <= 2: - for article in high_priority_articles: - await self.notifier.notify_single_news(article) - self.db_service.mark_as_notified(article['id']) - self.stats['total_notified'] += 1 - else: - await self.notifier.notify_news_batch(high_priority_articles[:10]) - for article in high_priority_articles[:10]: - self.db_service.mark_as_notified(article['id']) - self.stats['total_notified'] += 1 + # 批量发送最多10条 + await self.notifier.notify_news_batch(high_priority_articles[:10]) + for article in high_priority_articles[:10]: + self.db_service.mark_as_notified(article['id']) + self.stats['total_notified'] += 1 self.stats['last_notify_time'] = datetime.utcnow().isoformat() diff --git a/backend/app/news_agent/sources.py b/backend/app/news_agent/sources.py index f0588ee..72b0bc2 100644 --- a/backend/app/news_agent/sources.py +++ b/backend/app/news_agent/sources.py @@ -222,27 +222,47 @@ CRYPTO_KEYWORDS = { STOCK_KEYWORDS = { 'high_impact': [ - # 财报相关 + # 只保留真正重大、罕见的事件 + # 破产/退市级别 + 'bankruptcy', 'delisting', 'fraud', 'scandal', + '破产', '退市', '欺诈', '丑闻', + + # 重大监管事件 + 'antitrust', 'DOJ ', 'SEC investigation', 'sanction', + '反垄断', '司法部', '证监会调查', '制裁', + + # 超级并购/分拆 + 'mega merger', 'mega acquisition', 'breakup', 'spinoff', + '巨型并购', '分拆', + + # 重大安全事故/风险 + 'data breach', 'cyber attack', 'massive layoff', 'shutdown', + '数据泄露', '网络攻击', '大规模裁员', '停产', + ], + 'medium_impact': [ + # 财报相关(移到这里,因为太常见) 'earnings', 'revenue', 'profit', 'loss', 'guidance', '财报', '营收', '利润', '业绩预告', + 'beat', 'miss', 'surprise', + '超预期', '不及预期', - # 重大事件 + # 一般事件 'FDA', 'approval', 'recall', 'lawsuit', 'IPO', '批准', '召回', '诉讼', '上市', - # 并购重组 - 'merger', 'acquisition', 'spinoff', 'buyout', + # 并购重组(一般规模) + 'merger', 'acquisition', 'buyout', '并购', '收购', '重组', # 市场动态 - 'beat', 'miss', 'surge', 'plunge', 'rally', - '超预期', '不及预期', '暴涨', '暴跌', '反弹', + 'surge', 'plunge', 'rally', 'crash', + '暴涨', '暴跌', '反弹', '崩盘', # 管理层变动 'CEO', 'CFO', 'resign', 'appoint', 'executive', - '辞职', '任命', 'CEO', - ], - 'medium_impact': [ + '辞职', '任命', + + # 评级相关 'upgrade', 'downgrade', 'rating', 'target price', '评级', '目标价', '上调', '下调', 'dividend', 'buyback', 'split',