TradingAgents/backend/app/services/download_service.py

133 lines
4.0 KiB
Python

"""
Download Service for Analyst Reports
Generates combined PDF reports with all analyst analyses
"""
import io
from typing import List, Dict, Optional
from datetime import datetime
from backend.app.services.pdf_generator import PDFGenerator
# 分析師中英文名稱對照表
ANALYST_NAME_MAPPING = {
# 分析師組
"市場分析師": "Market_Analyst",
"基本面分析師": "Fundamentals_Analyst",
"社群媒體分析師": "Social_Media_Analyst",
"新聞分析師": "News_Analyst",
# 研究員組
"看漲研究員": "Bull_Researcher",
"看跌研究員": "Bear_Researcher",
# 風險辯論者組
"激進分析師": "Aggressive_Debator",
"保守分析師": "Conservative_Debator",
"中立分析師": "Neutral_Debator",
# 經理組
"研究經理": "Research_Manager",
"風險經理": "Risk_Manager",
# 交易員
"交易員": "Trader",
}
class DownloadService:
"""Service for handling analyst report downloads"""
def __init__(self):
"""Initialize download service"""
self.pdf_generator = PDFGenerator()
def create_combined_pdf(
self,
ticker: str,
analysis_date: str,
reports: List[Dict[str, str]],
price_data: list = None,
price_stats: dict = None,
language: str = "zh-TW",
) -> tuple[bytes, str]:
"""
Create a single combined PDF containing all analyst reports
Features:
- Cover page with ticker and analysis date
- Table of contents with price chart and analyst list
- All analyst reports as separate sections
Args:
ticker: Stock ticker symbol
analysis_date: Date of analysis (YYYY-MM-DD)
reports: List of dicts with keys 'analyst_name' and 'report_content'
price_data: Optional list of price data for chart
price_stats: Optional price statistics for TOC
language: Language for PDF labels ('en' or 'zh-TW')
Returns:
Tuple of (PDF bytes, filename)
"""
# Define the preferred order for analysts (based on language)
if language == "en":
analyst_order = [
'Market Analyst',
'Fundamentals Analyst',
'Social Media Analyst',
'News Analyst',
'Bull Researcher',
'Bear Researcher',
'Aggressive Analyst',
'Conservative Analyst',
'Neutral Analyst',
'Research Manager',
'Risk Manager',
'Trader',
]
else:
analyst_order = [
'市場分析師',
'基本面分析師',
'社群媒體分析師',
'新聞分析師',
'看漲研究員',
'看跌研究員',
'激進分析師',
'保守分析師',
'中立分析師',
'研究經理',
'風險經理',
'交易員',
]
# Sort reports by preferred order
def get_order(report):
analyst_name = report.get('analyst_name', '')
try:
return analyst_order.index(analyst_name)
except ValueError:
return len(analyst_order) # Unknown analysts go to the end
sorted_reports = sorted(reports, key=get_order)
# Generate combined PDF
pdf_bytes = self.pdf_generator.generate_combined_report_pdf(
ticker=ticker,
analysis_date=analysis_date,
reports=sorted_reports,
price_data=price_data,
price_stats=price_stats,
language=language,
)
# Generate filename: TICKER_Combined_Report_DATE.pdf
filename = f"{ticker}_Combined_Report_{analysis_date}.pdf"
return pdf_bytes, filename
# Singleton instance
download_service = DownloadService()