148 lines
4.4 KiB
Python
148 lines
4.4 KiB
Python
from fastapi import APIRouter, HTTPException, Query
|
|
from typing import List
|
|
from app.services.news_service import news_service
|
|
from app.services.alert_service import alert_service
|
|
from app.schemas.schemas import (
|
|
NewsFeedResponse,
|
|
EconomicCalendarResponse,
|
|
AlertsResponse,
|
|
CorrelationAnalysisResponse,
|
|
)
|
|
|
|
router = APIRouter(prefix="/news", tags=["News & Sentiment"])
|
|
|
|
|
|
@router.get("/feed", response_model=NewsFeedResponse)
|
|
async def get_news_feed(
|
|
limit: int = Query(50, description="Maximum number of articles to return"),
|
|
):
|
|
"""
|
|
Get aggregated news feed from multiple sources with sentiment analysis
|
|
|
|
Features:
|
|
- Fetches from Alpha Vantage News Sentiment API
|
|
- Fetches from Finnhub (if API key provided)
|
|
- Filters for gold-relevant news
|
|
- Performs sentiment analysis
|
|
- Categorizes by impact type
|
|
- Calculates relevance scores
|
|
- Provides overall market sentiment
|
|
"""
|
|
try:
|
|
news_feed = await news_service.get_aggregated_news_feed()
|
|
|
|
# Limit articles
|
|
news_feed.articles = news_feed.articles[:limit]
|
|
|
|
# Generate alerts for high-impact news
|
|
for article in news_feed.articles:
|
|
if article.impact_on_gold == "HIGH":
|
|
alert_service.add_news_alert(
|
|
news_title=article.title,
|
|
impact=article.impact_on_gold,
|
|
sentiment=article.sentiment.value,
|
|
)
|
|
|
|
return news_feed
|
|
|
|
except Exception as e:
|
|
raise HTTPException(
|
|
status_code=500,
|
|
detail=f"Failed to fetch news feed: {str(e)}"
|
|
)
|
|
|
|
|
|
@router.get("/economic-calendar", response_model=EconomicCalendarResponse)
|
|
async def get_economic_calendar():
|
|
"""
|
|
Get upcoming economic events that may impact gold prices
|
|
|
|
Includes:
|
|
- Federal Reserve meetings
|
|
- Employment reports
|
|
- Inflation data (CPI, PPI)
|
|
- GDP releases
|
|
- Central bank decisions
|
|
"""
|
|
try:
|
|
calendar = await news_service.get_economic_calendar()
|
|
return calendar
|
|
|
|
except Exception as e:
|
|
raise HTTPException(
|
|
status_code=500,
|
|
detail=f"Failed to fetch economic calendar: {str(e)}"
|
|
)
|
|
|
|
|
|
@router.get("/alerts", response_model=AlertsResponse)
|
|
async def get_alerts(
|
|
limit: int = Query(50, description="Maximum number of alerts to return"),
|
|
):
|
|
"""
|
|
Get recent alerts for price movements and news events
|
|
|
|
Alert Types:
|
|
- PRICE_SPIKE: Significant upward price movement
|
|
- PRICE_DROP: Significant downward price movement
|
|
- NEWS_BREAKING: High-impact breaking news
|
|
- SUPPORT_BREACH: Price broke below support level
|
|
- RESISTANCE_BREACH: Price broke above resistance level
|
|
- HIGH_VOLATILITY: Unusual price volatility detected
|
|
- ECONOMIC_EVENT: Upcoming important economic release
|
|
"""
|
|
try:
|
|
alerts = alert_service.get_alerts(limit=limit)
|
|
return alerts
|
|
|
|
except Exception as e:
|
|
raise HTTPException(
|
|
status_code=500,
|
|
detail=f"Failed to fetch alerts: {str(e)}"
|
|
)
|
|
|
|
|
|
@router.get("/correlation", response_model=CorrelationAnalysisResponse)
|
|
async def get_news_price_correlation():
|
|
"""
|
|
Analyze correlation between news events and price movements
|
|
|
|
Shows:
|
|
- How price reacted to specific news
|
|
- Time delay between news and price change
|
|
- Correlation strength (STRONG/MODERATE/WEAK)
|
|
- Average price impact from news
|
|
"""
|
|
try:
|
|
# Get recent news and price data
|
|
news_feed = await news_service.get_aggregated_news_feed()
|
|
|
|
# Would need price data here - for MVP return empty
|
|
# In full implementation, fetch from market service
|
|
correlation = alert_service.analyze_news_price_correlation(
|
|
news_articles=news_feed.articles[:20],
|
|
price_data=[], # Would pass actual price data
|
|
)
|
|
|
|
return correlation
|
|
|
|
except Exception as e:
|
|
raise HTTPException(
|
|
status_code=500,
|
|
detail=f"Failed to analyze correlation: {str(e)}"
|
|
)
|
|
|
|
|
|
@router.post("/alerts/clear")
|
|
async def clear_old_alerts():
|
|
"""Clear alerts older than 24 hours"""
|
|
try:
|
|
alert_service.clear_old_alerts(hours=24)
|
|
return {"message": "Old alerts cleared successfully"}
|
|
|
|
except Exception as e:
|
|
raise HTTPException(
|
|
status_code=500,
|
|
detail=f"Failed to clear alerts: {str(e)}"
|
|
)
|