PierreBrunelle commited on
Commit
f257889
Β·
verified Β·
1 Parent(s): 4692a0c

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +2 -20
app.py CHANGED
@@ -54,7 +54,6 @@ def calculate_basic_indicators(data: pd.DataFrame) -> pd.DataFrame:
54
 
55
  return df.ffill().bfill()
56
 
57
- # Also update the system prompt in generate_analysis_prompt to ensure structured output:
58
  @pxt.udf
59
  def generate_analysis_prompt(data: str, analysis_type: str) -> list[dict]:
60
  """Generate a structured prompt for AI analysis"""
@@ -112,7 +111,6 @@ def parse_analysis_response(response: str) -> Dict[str, str]:
112
  for line in response.split('\n'):
113
  line = line.strip()
114
 
115
- # Check if this line is a section header (now handling markdown formatting)
116
  matched_section = None
117
  for section in sections.keys():
118
  # Remove asterisks and check for exact match
@@ -133,11 +131,9 @@ def parse_analysis_response(response: str) -> Dict[str, str]:
133
  if cleaned_content: # Only add non-empty lines
134
  buffer.append(cleaned_content)
135
 
136
- # Save the last section
137
  if current_section and buffer:
138
  sections[current_section] = '\n'.join(buffer).strip()
139
 
140
- # Clean up sections and provide meaningful defaults
141
  section_messages = {
142
  'SUMMARY': 'Market analysis summary not available',
143
  'TECHNICAL ANALYSIS': 'Technical analysis not available',
@@ -147,7 +143,6 @@ def parse_analysis_response(response: str) -> Dict[str, str]:
147
  'RECOMMENDATION': 'Investment recommendation not available'
148
  }
149
 
150
- # Only use default messages if section is truly empty
151
  for key in sections:
152
  if sections[key] is None or not sections[key].strip():
153
  sections[key] = section_messages[key]
@@ -163,7 +158,6 @@ def create_visualization(data: pd.DataFrame, technical_depth: str) -> go.Figure:
163
  subplot_titles=('Price & Moving Averages', 'Volume', 'RSI' if technical_depth == 'advanced' else None)
164
  )
165
 
166
- # Price candlesticks with improved styling
167
  fig.add_trace(
168
  go.Candlestick(
169
  x=data.index,
@@ -178,7 +172,6 @@ def create_visualization(data: pd.DataFrame, technical_depth: str) -> go.Figure:
178
  row=1, col=1
179
  )
180
 
181
- # Moving averages with distinct colors
182
  colors = {'MA20': '#1E88E5', 'MA50': '#FFC107', 'MA200': '#7B1FA2'}
183
  for ma, color in colors.items():
184
  fig.add_trace(
@@ -191,7 +184,6 @@ def create_visualization(data: pd.DataFrame, technical_depth: str) -> go.Figure:
191
  row=1, col=1
192
  )
193
 
194
- # Volume with color based on price change
195
  colors = ['#26A69A' if close >= open_price else '#EF5350'
196
  for close, open_price in zip(data['Close'].values, data['Open'].values)]
197
  fig.add_trace(
@@ -215,7 +207,6 @@ def create_visualization(data: pd.DataFrame, technical_depth: str) -> go.Figure:
215
  row=3, col=1
216
  )
217
 
218
- # Add RSI reference lines
219
  fig.add_hline(y=70, line_dash="dash", line_color="red", row=3, col=1)
220
  fig.add_hline(y=30, line_dash="dash", line_color="green", row=3, col=1)
221
 
@@ -232,7 +223,6 @@ def create_visualization(data: pd.DataFrame, technical_depth: str) -> go.Figure:
232
  )
233
  )
234
 
235
- # Update y-axes labels
236
  fig.update_yaxes(title_text="Price", row=1, col=1)
237
  fig.update_yaxes(title_text="Volume", row=2, col=1)
238
  if technical_depth == 'advanced':
@@ -281,7 +271,6 @@ def process_outputs(ticker_symbol, analysis_type, time_horizon, risk_tolerance,
281
  max_tokens=1000
282
  )
283
 
284
- # Process the analysis with better error handling
285
  try:
286
  analysis_text = data_table.select(
287
  analysis=data_table.analysis.choices[0].message.content
@@ -310,7 +299,6 @@ def process_outputs(ticker_symbol, analysis_type, time_horizon, risk_tolerance,
310
  parsed_analysis = parse_analysis_response("")
311
  raw_llm_output = f"Error processing analysis: {str(analysis_error)}"
312
 
313
- # Prepare market stats with proper number formatting
314
  try:
315
  current_price = float(technical_data['Close'].iloc[-1])
316
  previous_price = float(technical_data['Close'].iloc[-2])
@@ -327,7 +315,6 @@ def process_outputs(ticker_symbol, analysis_type, time_horizon, risk_tolerance,
327
  'RSI': f"{rsi:.2f}"
328
  }
329
 
330
- # Add timestamp to technical data
331
  technical_data_with_time = technical_data.reset_index()
332
  technical_data_with_time['Date'] = technical_data_with_time['Date'].dt.strftime('%Y-%m-%d %H:%M:%S')
333
 
@@ -379,7 +366,6 @@ def create_interface() -> gr.Blocks:
379
  """
380
  )
381
 
382
- # Information Accordions
383
  with gr.Row():
384
  with gr.Column():
385
  with gr.Accordion("🎯 What does it do?", open=False):
@@ -428,7 +414,7 @@ def create_interface() -> gr.Blocks:
428
  )
429
 
430
  with gr.Row():
431
- # Left sidebar for inputs (reduced width)
432
  with gr.Column(scale=1):
433
  with gr.Row():
434
  gr.Markdown("### πŸ“Š Analysis Parameters")
@@ -516,13 +502,12 @@ def create_interface() -> gr.Blocks:
516
  with gr.Row():
517
  plot_output = gr.Plot()
518
 
519
- # AI Analysis section with better layout
520
  with gr.Row():
521
  with gr.Column(scale=2):
522
  with gr.Row():
523
  gr.Markdown("### πŸ€– AI Analysis")
524
 
525
- # Summary at the top
526
  with gr.Row():
527
  summary = gr.Textbox(
528
  label="Executive Summary",
@@ -531,7 +516,6 @@ def create_interface() -> gr.Blocks:
531
  show_label=True
532
  )
533
 
534
- # Main analysis sections
535
  with gr.Row():
536
  with gr.Column(scale=1):
537
  tech_analysis = gr.Textbox(
@@ -561,7 +545,6 @@ def create_interface() -> gr.Blocks:
561
  show_label=True
562
  )
563
 
564
- # Recommendation at the bottom
565
  with gr.Row():
566
  recommendation = gr.Textbox(
567
  label="Investment Recommendation",
@@ -570,7 +553,6 @@ def create_interface() -> gr.Blocks:
570
  show_label=True
571
  )
572
 
573
- # Examples section at the bottom
574
  gr.Examples(
575
  examples=[
576
  ["AAPL", "comprehensive", "medium", "moderate", "balanced", "advanced"],
 
54
 
55
  return df.ffill().bfill()
56
 
 
57
  @pxt.udf
58
  def generate_analysis_prompt(data: str, analysis_type: str) -> list[dict]:
59
  """Generate a structured prompt for AI analysis"""
 
111
  for line in response.split('\n'):
112
  line = line.strip()
113
 
 
114
  matched_section = None
115
  for section in sections.keys():
116
  # Remove asterisks and check for exact match
 
131
  if cleaned_content: # Only add non-empty lines
132
  buffer.append(cleaned_content)
133
 
 
134
  if current_section and buffer:
135
  sections[current_section] = '\n'.join(buffer).strip()
136
 
 
137
  section_messages = {
138
  'SUMMARY': 'Market analysis summary not available',
139
  'TECHNICAL ANALYSIS': 'Technical analysis not available',
 
143
  'RECOMMENDATION': 'Investment recommendation not available'
144
  }
145
 
 
146
  for key in sections:
147
  if sections[key] is None or not sections[key].strip():
148
  sections[key] = section_messages[key]
 
158
  subplot_titles=('Price & Moving Averages', 'Volume', 'RSI' if technical_depth == 'advanced' else None)
159
  )
160
 
 
161
  fig.add_trace(
162
  go.Candlestick(
163
  x=data.index,
 
172
  row=1, col=1
173
  )
174
 
 
175
  colors = {'MA20': '#1E88E5', 'MA50': '#FFC107', 'MA200': '#7B1FA2'}
176
  for ma, color in colors.items():
177
  fig.add_trace(
 
184
  row=1, col=1
185
  )
186
 
 
187
  colors = ['#26A69A' if close >= open_price else '#EF5350'
188
  for close, open_price in zip(data['Close'].values, data['Open'].values)]
189
  fig.add_trace(
 
207
  row=3, col=1
208
  )
209
 
 
210
  fig.add_hline(y=70, line_dash="dash", line_color="red", row=3, col=1)
211
  fig.add_hline(y=30, line_dash="dash", line_color="green", row=3, col=1)
212
 
 
223
  )
224
  )
225
 
 
226
  fig.update_yaxes(title_text="Price", row=1, col=1)
227
  fig.update_yaxes(title_text="Volume", row=2, col=1)
228
  if technical_depth == 'advanced':
 
271
  max_tokens=1000
272
  )
273
 
 
274
  try:
275
  analysis_text = data_table.select(
276
  analysis=data_table.analysis.choices[0].message.content
 
299
  parsed_analysis = parse_analysis_response("")
300
  raw_llm_output = f"Error processing analysis: {str(analysis_error)}"
301
 
 
302
  try:
303
  current_price = float(technical_data['Close'].iloc[-1])
304
  previous_price = float(technical_data['Close'].iloc[-2])
 
315
  'RSI': f"{rsi:.2f}"
316
  }
317
 
 
318
  technical_data_with_time = technical_data.reset_index()
319
  technical_data_with_time['Date'] = technical_data_with_time['Date'].dt.strftime('%Y-%m-%d %H:%M:%S')
320
 
 
366
  """
367
  )
368
 
 
369
  with gr.Row():
370
  with gr.Column():
371
  with gr.Accordion("🎯 What does it do?", open=False):
 
414
  )
415
 
416
  with gr.Row():
417
+ # Left sidebar for inputs
418
  with gr.Column(scale=1):
419
  with gr.Row():
420
  gr.Markdown("### πŸ“Š Analysis Parameters")
 
502
  with gr.Row():
503
  plot_output = gr.Plot()
504
 
505
+ # AI Analysis section
506
  with gr.Row():
507
  with gr.Column(scale=2):
508
  with gr.Row():
509
  gr.Markdown("### πŸ€– AI Analysis")
510
 
 
511
  with gr.Row():
512
  summary = gr.Textbox(
513
  label="Executive Summary",
 
516
  show_label=True
517
  )
518
 
 
519
  with gr.Row():
520
  with gr.Column(scale=1):
521
  tech_analysis = gr.Textbox(
 
545
  show_label=True
546
  )
547
 
 
548
  with gr.Row():
549
  recommendation = gr.Textbox(
550
  label="Investment Recommendation",
 
553
  show_label=True
554
  )
555
 
 
556
  gr.Examples(
557
  examples=[
558
  ["AAPL", "comprehensive", "medium", "moderate", "balanced", "advanced"],