Stock_Agent_optimized / services /chart_analysis.py
cryogenic22's picture
Update services/chart_analysis.py
0c4880f verified
# 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