This commit is contained in:
aaron 2026-02-25 22:45:16 +08:00
parent ad1e999f82
commit 6fc6f4c2a3
3 changed files with 83 additions and 81 deletions

View File

@ -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=中性 2. impact_type: 对价格的影响方向bullish=利好, bearish=利空, neutral=中性
3. sentiment: 新闻情绪positive=正面, negative=负面, neutral=中性 3. sentiment: 新闻情绪positive=正面, negative=负面, neutral=中性
4. summary: 根据标题推断并总结新闻核心内容 4. summary: 根据标题推断并总结新闻核心内容
@ -108,6 +120,13 @@ class NewsAnalyzer:
] ]
``` ```
**market_impact 判断标准**:
- **high**: 对市场或公司有**实质性深远影响**的事件改变行业格局或公司生存状态
- **medium**: 对价格有**短期影响**但不会改变长期趋势的事件财报管理层变动一般并购等
- **low**: 常规信息影响有限
**判断原则**: 问自己"这条新闻会改变市场/公司的长期格局吗?" 如果会high如果只是短期波动medium
请只输出 JSON 数组不要包含其他解释 请只输出 JSON 数组不要包含其他解释
""" """

View File

@ -48,8 +48,7 @@ class NewsAgent:
# 配置 # 配置
self.fetch_interval = 300 # 抓取间隔(秒)= 5分钟 self.fetch_interval = 300 # 抓取间隔(秒)= 5分钟
self.min_priority = 40.0 # 最低通知优先级 self.min_priority = 40.0 # 最低通知优先级
self.use_llm = True # 是否使用 LLM 分析 self.use_llm = True # 使用 LLM 批量分析
self.batch_analysis = True # 是否批量分析
# 统计数据 # 统计数据
self.stats = { self.stats = {
@ -182,69 +181,39 @@ class NewsAgent:
if not saved_articles: if not saved_articles:
return return
# 5. LLM 分析 # 5. LLM 分析(仅批量分析)
analyzed_count = 0 analyzed_count = 0
high_priority_articles = [] high_priority_articles = []
if self.use_llm: if self.use_llm:
# 批量分析 # 只使用批量分析
if self.batch_analysis and len(saved_articles) > 1: items_to_analyze = [item for _, item in saved_articles]
items_to_analyze = [item for _, item in saved_articles] results = self.analyzer.analyze_batch(items_to_analyze)
results = self.analyzer.analyze_batch(items_to_analyze)
for (article, _), result in zip(saved_articles, results): for (article, _), result in zip(saved_articles, results):
if result: if result:
priority = self.analyzer.calculate_priority( priority = self.analyzer.calculate_priority(
result, result,
getattr(article, 'quality_score', 0.5) getattr(article, 'quality_score', 0.5)
) )
self.db_service.mark_as_analyzed(article.id, result, priority) self.db_service.mark_as_analyzed(article.id, result, priority)
analyzed_count += 1 analyzed_count += 1
# 只发送重大影响high的新闻 # 只发送重大影响high的新闻
if result.get('market_impact') == 'high': if result.get('market_impact') == 'high':
article_dict = article.to_dict() article_dict = article.to_dict()
article_dict.update({ article_dict.update({
'llm_analyzed': True, 'llm_analyzed': True,
'market_impact': result.get('market_impact'), 'market_impact': result.get('market_impact'),
'impact_type': result.get('impact_type'), 'impact_type': result.get('impact_type'),
'sentiment': result.get('sentiment'), 'sentiment': result.get('sentiment'),
'summary': result.get('summary'), 'summary': result.get('summary'),
'key_points': result.get('key_points'), 'key_points': result.get('key_points'),
'trading_advice': result.get('trading_advice'), 'trading_advice': result.get('trading_advice'),
'relevant_symbols': result.get('relevant_symbols'), 'relevant_symbols': result.get('relevant_symbols'),
'priority': priority, 'priority': priority,
}) })
high_priority_articles.append(article_dict) 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)
else: else:
# 使用规则分析 # 使用规则分析
@ -274,7 +243,7 @@ class NewsAgent:
self.stats['total_analyzed'] += analyzed_count self.stats['total_analyzed'] += analyzed_count
logger.info(f"分析了 {analyzed_count} 条文章") logger.info(f"分析了 {analyzed_count} 条文章")
# 6. 发送通知 # 6. 发送通知(仅批量发送)
if high_priority_articles: if high_priority_articles:
# 按优先级排序 # 按优先级排序
high_priority_articles.sort( high_priority_articles.sort(
@ -282,17 +251,11 @@ class NewsAgent:
reverse=True reverse=True
) )
# 如果只有1-2条单独发送否则批量发送 # 批量发送最多10条
if len(high_priority_articles) <= 2: await self.notifier.notify_news_batch(high_priority_articles[:10])
for article in high_priority_articles: for article in high_priority_articles[:10]:
await self.notifier.notify_single_news(article) self.db_service.mark_as_notified(article['id'])
self.db_service.mark_as_notified(article['id']) self.stats['total_notified'] += 1
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
self.stats['last_notify_time'] = datetime.utcnow().isoformat() self.stats['last_notify_time'] = datetime.utcnow().isoformat()

View File

@ -222,27 +222,47 @@ CRYPTO_KEYWORDS = {
STOCK_KEYWORDS = { STOCK_KEYWORDS = {
'high_impact': [ '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', 'earnings', 'revenue', 'profit', 'loss', 'guidance',
'财报', '营收', '利润', '业绩预告', '财报', '营收', '利润', '业绩预告',
'beat', 'miss', 'surprise',
'超预期', '不及预期',
# 重大事件 # 一般事件
'FDA', 'approval', 'recall', 'lawsuit', 'IPO', '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', 'CFO', 'resign', 'appoint', 'executive',
'辞职', '任命', 'CEO', '辞职', '任命',
],
'medium_impact': [ # 评级相关
'upgrade', 'downgrade', 'rating', 'target price', 'upgrade', 'downgrade', 'rating', 'target price',
'评级', '目标价', '上调', '下调', '评级', '目标价', '上调', '下调',
'dividend', 'buyback', 'split', 'dividend', 'buyback', 'split',