Skip to content

lichengzhe/etfwind

Repository files navigation

ETF风向标

AI 驱动的 ETF 投资风向分析工具。自动采集财经新闻,通过 AI 分析生成板块研判和 ETF 推荐。

在线访问: https://etf.aurora-bots.com/

项目背景

作为一个业余投资者,每天要看大量财经新闻,但信息太碎片化了。于是萌生了一个想法:能不能让 AI 帮我读新闻,然后告诉我今天该关注哪些板块?

功能

  • 13个新闻源自动采集(财联社、东方财富、新浪、Bloomberg、CNBC、BBC、新华社、央视等)
  • Claude AI 分析市场动态,输出板块研判 + 风险提示
  • 置信度评分 + 一段式综合分析
  • 智能匹配板块 ETF,展示实时行情 + 90日走势
  • 商品周期轮动指标(黄金→白银→铜→石油→农产品)
  • 信号复盘:1/3/7/20 交易日胜率/均值/沪深300超额
  • 决策仪表盘:买入/观望/回避信号 + 综合分析
  • 企业微信推送:分析完成自动推送到群
  • 每小时自动更新(6:00-20:00 北京时间),完全自动化

架构

GitHub Actions (每小时)
├── 采集新闻 → news_raw.json → R2
└── AI分析 → latest.json → R2
         ↓
Cloudflare Workers ← 读取 R2 渲染页面
         ↓
用户访问 etf.aurora-bots.com

把采集和分析分开的好处:

  1. 采集需要 Playwright,比较重
  2. 分析只需要读 JSON,可以单独触发
  3. 某一步失败不影响另一步
组件 技术
采集 Python + httpx + Playwright
AI Kimi K2.5(httpx,Anthropic 兼容接口)
前端 Cloudflare Workers + Hono
存储 Cloudflare R2
数据 东方财富 API

为什么选这套? 几乎零成本:

  • GitHub Actions 免费额度够用
  • Cloudflare Workers/R2 免费额度够用
  • Kimi K2.5 订阅,每小时调用一次,成本可控

技术亮点

1. 多源采集 + 智能去重

13 个采集器并发跑,用基类统一异常处理:

class BaseCollector:
    async def safe_collect(self):
        try:
            return await self.collect()
        except Exception as e:
            logger.warning(f"{self.name} 采集失败: {e}")
            return []

单个源挂了不影响整体,最后按标题去重。

2. 让 AI 只做"填空题"

一开始让 AI 直接输出完整 JSON,经常格式错误或字段遗漏。后来改成分步提取:

# 第一步:识别重要事件
step1 = "从新闻中识别最重要的5个事件,只输出标题列表"

# 第二步:逐个分析
step2 = "对于事件'{title}',提供:1.所属板块 2.分析 3.建议"

# 代码负责组装最终 JSON

AI 只负责"内容生成",代码负责"结构组装",稳定多了。

3. SSR + 异步水合

首屏用服务端渲染历史数据(5日/20日涨跌、K线图),然后客户端异步请求实时价格覆盖:

// 服务端预渲染 ETF 表格(历史数据)
// 客户端加载后请求实时数据
async function loadSectorEtfs() {
  const resp = await fetch('/api/batch-sector-etfs?sectors=黄金,芯片')
  // 只更新价格、今日涨跌、成交额
}

首屏秒开,实时数据异步加载。

4. 商品周期轮动

追踪「黄金→白银→铜→石油→农产品」的周期传导:

// 计算动量得分
const momentum = commodities.map(c => ({
  key: c.key,
  score: c.change_5d * 2 + c.change_20d  // 5日权重更高
})).sort((a, b) => b.score - a.score)

const leader = momentum[0].key  // 当前领涨品种

理论上,经济周期会按这个顺序传导,可以提前布局下一个品种。

本地开发

# 只运行采集
PYTHONPATH=. uv run python -m src.collect_news

# 只运行分析
PYTHONPATH=. uv run python -m src.analyze_news

# 采集+分析一起跑
PYTHONPATH=. uv run python -m src.worker_simple

# Workers 开发
cd workers && npm run dev

# Workers 部署
cd workers && npm run deploy

环境变量

CLAUDE_API_KEY=sk-kimi-xxx    # AI API 密钥(支持 Anthropic 兼容格式的 API)
CLAUDE_BASE_URL=https://...   # API 地址(当前 api.kimi.com/coding)
CLAUDE_MODEL=kimi-k2.5        # 模型名称
WECHAT_WEBHOOK_URL=https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key=xxx  # 可选,企业微信推送

踩过的坑

  1. Playwright 在 GitHub Actions 里很慢 - 串行执行 + 加延迟,避免被封
  2. AI 输出的 JSON 有时格式错误 - 加了自动修复(移除尾部逗号、替换中文引号)
  3. SVG 里的 emoji 会导致编码错误 - 用正则过滤掉 emoji
  4. ETF 名称多样,关键词匹配不准 - 改用 AI 语义分类
  5. RSS 含非法 XML 字符 - 解析前清理 & 未转义和控制字符(自由時報 RSS)
  6. 东方财富/新浪 API 在 GitHub Actions IP 被封 - 降级策略 + batch=10 限流

License

MIT

About

每日财经新闻收集与基金投资建议系统

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors