Files
nofx/news/provider/default/default.go
wwg d2af549bac feat(config): 增加新闻源配置与数据库迁移支持
- 在config.json.example中添加新闻源相关配置示例,支持telegram频道订阅
- 扩展数据库表结构,新增traders表多字段支持信号源和杠杆参数
- 新增NewsConfig结构体及相关telegram新闻配置数据模型
- 在交易决策上下文结构Context中添加新闻数据news字段支持传递新闻
- 在交易决策构建用户提示信息时加入相关新闻内容
- 优化数据库操作代码,支持交易所和交易员配置的完整字段读取与更新
- 添加数据库exchanges表迁移逻辑,重建表结构和触发器以支持新字段
- 引入第三方库github.com/samber/lo用于集合操作
- 在go.mod添加新的依赖模块,并更新相关依赖版本
2025-11-01 23:10:02 +08:00

146 lines
3.7 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

package news
import (
"fmt"
"nofx/news"
"time"
)
// DefaultNewsProvider 默认新闻提供者实现(参考示例)
// 展示如何实现 NewsProvider 接口
type DefaultNewsProvider struct {
// API配置根据实际数据源调整
APIKey string
BaseURL string
Timeout time.Duration
CacheTime time.Duration
// 可选:缓存机制
cache map[string]cacheEntry
}
type cacheEntry struct {
news []news.NewsItem
timestamp time.Time
}
// NewDefaultNewsProvider 创建默认新闻提供者
func NewDefaultNewsProvider(apiKey, baseURL string) *DefaultNewsProvider {
return &DefaultNewsProvider{
APIKey: apiKey,
BaseURL: baseURL,
Timeout: 30 * time.Second,
CacheTime: 5 * time.Minute, // 5分钟缓存
cache: make(map[string]cacheEntry),
}
}
// FetchNews 实现 NewsProvider 接口
// 按币种批量获取最新新闻返回值按symbol分组
func (p *DefaultNewsProvider) FetchNews(symbols []string, limit int) (map[string][]news.NewsItem, error) {
if len(symbols) == 0 {
return make(map[string][]news.NewsItem), nil
}
result := make(map[string][]news.NewsItem)
for _, symbol := range symbols {
// 1. 检查缓存
if cached, ok := p.getFromCache(symbol); ok {
result[symbol] = cached
continue
}
// 2. 从数据源获取(具体实现留空,由你后续补充)
news, err := p.fetchFromSource(symbol, limit)
if err != nil {
// 单个币种失败不影响其他币种
continue
}
// 3. 更新缓存
p.updateCache(symbol, news)
result[symbol] = news
}
return result, nil
}
// getFromCache 从缓存获取新闻
func (p *DefaultNewsProvider) getFromCache(symbol string) ([]news.NewsItem, bool) {
entry, exists := p.cache[symbol]
if !exists {
return nil, false
}
// 检查缓存是否过期
if time.Since(entry.timestamp) > p.CacheTime {
delete(p.cache, symbol)
return nil, false
}
return entry.news, true
}
// updateCache 更新缓存
func (p *DefaultNewsProvider) updateCache(symbol string, news []news.NewsItem) {
p.cache[symbol] = cacheEntry{
news: news,
timestamp: time.Now(),
}
}
// fetchFromSource 从数据源获取新闻(具体实现由你补充)
func (p *DefaultNewsProvider) fetchFromSource(symbol string, limit int) ([]news.NewsItem, error) {
// TODO: 实现具体的新闻获取逻辑
// 可选的数据源:
// 1. CryptoPanic API: https://cryptopanic.com/developers/api/
// 2. CoinGecko Events API
// 3. 交易所公告币安、OKX等
// 4. Twitter/X API
// 5. Reddit API
// 6. 自定义爬虫
// 示例返回结构实际需要调用API
news := []news.NewsItem{
{
Symbol: symbol,
Headline: fmt.Sprintf("%s 相关新闻标题", symbol),
Source: "CryptoPanic", // 或其他来源
URL: "https://example.com/news/123",
PublishedAt: time.Now().Add(-1 * time.Hour),
Sentiment: 0, // -100 到 100
Impact: 50, // 0 到 100
Summary: "新闻摘要内容...",
Tags: []string{"breaking", "market"},
},
}
return news, nil
}
// 可选:实现其他辅助方法
// FilterByImpact 按影响力过滤新闻
func (p *DefaultNewsProvider) FilterByImpact(items []news.NewsItem, minImpact int) []news.NewsItem {
filtered := make([]news.NewsItem, 0)
for _, item := range items {
if item.Impact >= minImpact {
filtered = append(filtered, item)
}
}
return filtered
}
// FilterByTime 按时间过滤新闻只保留最近N小时的
func (p *DefaultNewsProvider) FilterByTime(items []news.NewsItem, hours int) []news.NewsItem {
cutoff := time.Now().Add(-time.Duration(hours) * time.Hour)
filtered := make([]news.NewsItem, 0)
for _, item := range items {
if item.PublishedAt.After(cutoff) {
filtered = append(filtered, item)
}
}
return filtered
}