Spaces:
Runtime error
Runtime error
| # services/chart_analysis.py | |
| import streamlit as st | |
| from datetime import datetime | |
| from utils.file_handlers import save_chat_history | |
| from utils.prompts import create_analysis_prompt | |
| class ChartAnalysisService: | |
| def __init__(self, claude_service): | |
| self.claude_service = claude_service | |
| def analyze_multiple_charts(self, image_data_list, patterns, indicators, comparison_type="Individual Analysis", expertise_level="Novice"): | |
| """Analyze multiple charts and provide comprehensive analysis""" | |
| try: | |
| results = [] | |
| individual_analyses = [] | |
| # First get individual analyses | |
| for idx, image_data in enumerate(image_data_list): | |
| chart_type = self.claude_service.detect_chart_type(image_data) | |
| st.info(f"Chart {idx + 1} detected as: {chart_type}") | |
| analysis = self.analyze_single_chart( | |
| image_data, | |
| patterns, | |
| indicators, | |
| chart_type, | |
| expertise_level | |
| ) | |
| if analysis: | |
| individual_analyses.append(analysis) | |
| # If we have multiple charts, perform comparison analysis | |
| if len(individual_analyses) > 1 and comparison_type != "Individual Analysis": | |
| comparison_prompt = self.create_comparison_prompt( | |
| individual_analyses, | |
| comparison_type, | |
| expertise_level | |
| ) | |
| # Combine all images for the comparison analysis | |
| comparative_analysis = self.claude_service.analyze_multiple_images( | |
| image_data_list, | |
| comparison_prompt | |
| ) | |
| if comparative_analysis: | |
| results.append({ | |
| 'timestamp': datetime.now().isoformat(), | |
| 'analysis_type': comparison_type, | |
| 'analysis': comparative_analysis, | |
| 'num_charts': len(image_data_list) | |
| }) | |
| # Add individual analyses | |
| results.extend(individual_analyses) | |
| return results | |
| except Exception as e: | |
| st.error(f"Error in multiple chart analysis: {str(e)}") | |
| return None | |
| def analyze_single_chart(self, image_data, patterns, indicators, chart_type=None, expertise_level="Novice"): | |
| """Analyze a single chart""" | |
| try: | |
| prompt = create_analysis_prompt(patterns, indicators, expertise_level) | |
| analysis = self.claude_service.analyze_image(image_data, prompt) | |
| if analysis: | |
| return { | |
| 'timestamp': datetime.now().isoformat(), | |
| 'chart_type': chart_type, | |
| 'analysis': analysis, | |
| 'analysis_type': 'Individual' | |
| } | |
| return None | |
| except Exception as e: | |
| st.error(f"Error in chart analysis: {str(e)}") | |
| return None | |
| def handle_follow_up_question(self, question, previous_analysis, image_data=None): | |
| """Handle follow-up questions about the analysis""" | |
| try: | |
| # Get previous conversation context from session state | |
| if 'conversation_context' not in st.session_state: | |
| st.session_state.conversation_context = [] | |
| # Add previous analysis to context if not already present | |
| if previous_analysis and not st.session_state.conversation_context: | |
| st.session_state.conversation_context.append({ | |
| 'role': 'assistant', | |
| 'content': previous_analysis, | |
| 'timestamp': datetime.now().isoformat() | |
| }) | |
| # Add current question to context | |
| st.session_state.conversation_context.append({ | |
| 'role': 'user', | |
| 'content': question, | |
| 'timestamp': datetime.now().isoformat() | |
| }) | |
| # Create a conversation-aware prompt | |
| context = "\n".join([f"{'Q' if msg['role'] == 'user' else 'A'}: {msg['content']}" | |
| for msg in st.session_state.conversation_context]) | |
| response = self.claude_service.continue_analysis( | |
| question=question, | |
| previous_analysis=context, # Use full conversation context | |
| image_data=image_data | |
| ) | |
| if response: | |
| # Add response to context | |
| st.session_state.conversation_context.append({ | |
| 'role': 'assistant', | |
| 'content': response, | |
| 'timestamp': datetime.now().isoformat() | |
| }) | |
| # Add to followups for UI display | |
| if 'followups' not in st.session_state: | |
| st.session_state.followups = [] | |
| st.session_state.followups.append({ | |
| 'question': question, | |
| 'response': response, | |
| 'timestamp': datetime.now().isoformat() | |
| }) | |
| return { | |
| 'timestamp': datetime.now().isoformat(), | |
| 'question': question, | |
| 'analysis': response, | |
| 'analysis_type': 'Follow-up', | |
| 'context_length': len(st.session_state.conversation_context) | |
| } | |
| return None | |
| except Exception as e: | |
| st.error(f"Error handling follow-up question: {str(e)}") | |
| return None | |
| def get_conversation_context(self): | |
| """Get the current conversation context""" | |
| return st.session_state.get('conversation_context', []) | |
| def create_comparison_prompt(self, individual_analyses, comparison_type, expertise_level="Novice"): | |
| """Create a prompt for comparing multiple charts""" | |
| expertise_adjustments = { | |
| "Novice": { | |
| "depth": "Focus on basic relationships and clear patterns.", | |
| "language": "Use simple terms and explain technical concepts." | |
| }, | |
| "Intermediate": { | |
| "depth": "Include both basic and advanced correlations.", | |
| "language": "Balance technical terms with clear explanations." | |
| }, | |
| "Expert": { | |
| "depth": "Provide sophisticated multi-chart analysis.", | |
| "language": "Use full technical terminology and advanced concepts." | |
| } | |
| } | |
| adj = expertise_adjustments[expertise_level] | |
| if comparison_type == "Correlated Analysis": | |
| prompt = f"""Analyze these charts together and provide insights on their relationships. | |
| {adj['depth']} {adj['language']} | |
| 1. Correlation Analysis | |
| - Identify any price correlations | |
| - Note common patterns or divergences | |
| - Highlight synchronized movements | |
| 2. Relative Strength Comparison | |
| - Compare relative performance | |
| - Identify leader/laggard relationships | |
| - Note any rotation patterns | |
| 3. Market Implications | |
| - What these relationships suggest | |
| - Potential trading opportunities | |
| - Risk considerations | |
| 4. Summary | |
| Provide a clear summary of the key relationships and trading implications.""" | |
| else: # Market Trend Analysis | |
| prompt = f"""Analyze these charts to identify broader market patterns. | |
| {adj['depth']} {adj['language']} | |
| 1. Market Trend Analysis | |
| - Identify common trend directions | |
| - Note sector/market momentum | |
| - Highlight any broader pattern formations | |
| 2. Market Condition Assessment | |
| - Overall market health | |
| - Risk levels | |
| - Potential market turning points | |
| 3. Trading Implications | |
| - Sector rotation opportunities | |
| - Risk management considerations | |
| - Timeframe recommendations | |
| 4. Summary | |
| - Provide a clear summary of the market condition | |
| - List key trading implications | |
| - Note major risk factors""" | |
| # Add disclaimer | |
| prompt += "\n\nIMPORTANT: Clearly mark this as AI-generated analysis for informational purposes only." | |
| return prompt |