QAway-to commited on
Commit
4e75484
·
unverified ·
2 Parent(s): bc26e05 4a15189

Merge pull request #52 from QAway-to/codex/analyze-project-repository-y17yqj

Browse files
app.py CHANGED
@@ -31,7 +31,7 @@ comparer = PortfolioComparer(llm_service, MODEL_NAME)
31
 
32
  # === Main Interface ===
33
  with gr.Blocks(css=base_css) as demo:
34
- gr.Markdown("## Investment Portfolio Analyzer")
35
  gr.Markdown(
36
  "Professional AI-driven analytics for investment and crypto markets.",
37
  elem_classes="subtitle",
@@ -73,12 +73,7 @@ with gr.Blocks(css=base_css) as demo:
73
  wrap=True,
74
  elem_id="comparison_table",
75
  )
76
- comp_comment = gr.Textbox(
77
- label="AI Commentary",
78
- lines=14,
79
- elem_id="llm_comment_box",
80
- interactive=False,
81
- )
82
  compare_btn.click(
83
  fn=show_comparison_table,
84
  inputs=[pid_a, pid_b],
 
31
 
32
  # === Main Interface ===
33
  with gr.Blocks(css=base_css) as demo:
34
+ gr.Markdown("## Investment Portfolio Analyzer", elem_classes="page-title")
35
  gr.Markdown(
36
  "Professional AI-driven analytics for investment and crypto markets.",
37
  elem_classes="subtitle",
 
73
  wrap=True,
74
  elem_id="comparison_table",
75
  )
76
+ comp_comment = gr.HTML(elem_id="llm_comment_box")
 
 
 
 
 
77
  compare_btn.click(
78
  fn=show_comparison_table,
79
  inputs=[pid_a, pid_b],
presentation/components/comparison_table.py CHANGED
@@ -7,6 +7,10 @@ import pandas as pd
7
  from infrastructure.cache import CacheUnavailableError
8
  from infrastructure.llm_client import llm_service
9
  from infrastructure.output_api import extract_portfolio_id, fetch_metrics_cached
 
 
 
 
10
  from prompts.system_prompts import COMPARISON_SYSTEM_PROMPT
11
 
12
 
@@ -17,18 +21,18 @@ def show_comparison_table(portfolio_a: str, portfolio_b: str):
17
  pid_b = extract_portfolio_id(portfolio_b)
18
  if not pid_a or not pid_b:
19
  message = "❌ Invalid portfolio IDs."
20
- return _message_df(message), message
21
 
22
  try:
23
  df, commentary = _build_comparison_with_comment(pid_a, pid_b)
24
- return df, commentary
25
  except CacheUnavailableError as e:
26
  wait = int(e.retry_in) + 1
27
  message = f"⚠️ Metrics temporarily unavailable. Retry in ~{wait} seconds."
28
- return _message_df(message), message
29
  except Exception:
30
  message = "❌ Unable to build comparison right now. Please try again later."
31
- return _message_df(message), message
32
 
33
 
34
  def _build_comparison_with_comment(p1: str, p2: str):
 
7
  from infrastructure.cache import CacheUnavailableError
8
  from infrastructure.llm_client import llm_service
9
  from infrastructure.output_api import extract_portfolio_id, fetch_metrics_cached
10
+ from presentation.components.analysis_formatter import (
11
+ render_analysis_html,
12
+ render_status_html,
13
+ )
14
  from prompts.system_prompts import COMPARISON_SYSTEM_PROMPT
15
 
16
 
 
21
  pid_b = extract_portfolio_id(portfolio_b)
22
  if not pid_a or not pid_b:
23
  message = "❌ Invalid portfolio IDs."
24
+ return _message_df(message), render_status_html(message)
25
 
26
  try:
27
  df, commentary = _build_comparison_with_comment(pid_a, pid_b)
28
+ return df, render_analysis_html(commentary)
29
  except CacheUnavailableError as e:
30
  wait = int(e.retry_in) + 1
31
  message = f"⚠️ Metrics temporarily unavailable. Retry in ~{wait} seconds."
32
+ return _message_df(message), render_status_html(message)
33
  except Exception:
34
  message = "❌ Unable to build comparison right now. Please try again later."
35
+ return _message_df(message), render_status_html(message)
36
 
37
 
38
  def _build_comparison_with_comment(p1: str, p2: str):
presentation/styles/themes/base.css CHANGED
@@ -3,6 +3,35 @@
3
  [data-testid="block-container"] { max-width:1180px !important; margin:auto !important; }
4
  h2, h3, .gr-markdown { color:#f0f6fc !important; font-weight:600 !important; }
5
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
6
  /* === Tabs Navigation === */
7
  #main_tabs {
8
  width:72%;
 
3
  [data-testid="block-container"] { max-width:1180px !important; margin:auto !important; }
4
  h2, h3, .gr-markdown { color:#f0f6fc !important; font-weight:600 !important; }
5
 
6
+ /* === Page headers & footer === */
7
+ .page-title,
8
+ .subtitle,
9
+ .footer {
10
+ width:100%;
11
+ margin:0 auto 18px;
12
+ text-align:center !important;
13
+ }
14
+
15
+ .page-title .gr-markdown,
16
+ .subtitle .gr-markdown,
17
+ .footer .gr-markdown {
18
+ text-align:center !important;
19
+ margin:0 auto;
20
+ }
21
+
22
+ .page-title .gr-markdown h1,
23
+ .page-title .gr-markdown h2,
24
+ .subtitle .gr-markdown p,
25
+ .footer .gr-markdown p,
26
+ .footer .gr-markdown small {
27
+ text-align:center !important;
28
+ }
29
+
30
+ .subtitle { margin-bottom:28px; color:#9ca3af !important; }
31
+ .subtitle .gr-markdown { color:#9ca3af !important; font-weight:500 !important; }
32
+
33
+ .footer { margin-top:40px; margin-bottom:0; }
34
+
35
  /* === Tabs Navigation === */
36
  #main_tabs {
37
  width:72%;
prompts/system_prompts.py CHANGED
@@ -60,33 +60,33 @@ Analytical guidance:
60
  - Stream the HTML sequentially, closing tags promptly so partial updates render cleanly.
61
  """
62
 
63
-
64
  COMPARISON_SYSTEM_PROMPT = """
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
65
 
66
- You are a financial analysis model specializing in quantitative portfolio comparison.
67
-
68
- Your goal is to compare two portfolios **objectively** using their metrics.
69
-
70
- When analyzing:
71
- - Do not make emotional or vague statements.
72
- - Base conclusions strictly on the provided numerical data.
73
- - Identify *which portfolio is statistically stronger* based on performance, risk, and stability.
74
-
75
- Your output must be concise and structured in the following format:
76
-
77
- Comparative Analysis
78
- - Discuss which portfolio shows **better performance** (higher return / alpha).
79
- - Discuss **risk-adjusted efficiency** (Sharpe / Sortino ratio, volatility, maxDD).
80
- - Highlight **consistency** and **downside protection** if metrics imply it.
81
-
82
- Recommendation
83
- Provide an actionable insight:
84
- - If one portfolio is clearly better, state which one and why.
85
- - If both are weak or over-risked — say it explicitly.
86
- - If data is incomplete or contradictory — mention this clearly.
87
-
88
- Avoid phrases like “depends on the investor” or “might be better for risk-taking investors”.
89
- You are the quantitative analyst — give a judgment based on data, not preference.
90
  """
91
 
92
 
 
60
  - Stream the HTML sequentially, closing tags promptly so partial updates render cleanly.
61
  """
62
 
 
63
  COMPARISON_SYSTEM_PROMPT = """
64
+ You are a quantitative analyst comparing two portfolios.
65
+
66
+ Output fully formed HTML using only <div>, <h2>, <p>, <span>, and <hr> tags.
67
+ Structure the report exactly as follows:
68
+
69
+ <div class="section">
70
+ <h2>Comparative Analysis</h2>
71
+ ...metrics and commentary...
72
+ </div>
73
+ <div class="section-divider"></div>
74
+ <div class="section">
75
+ <h2>Recommendation</h2>
76
+ ...actionable insight...
77
+ </div>
78
+
79
+ Formatting requirements:
80
+ - Use <p class="analysis-line metric"> for quantitative statements that cite specific figures.
81
+ - Inside each metric line, wrap the label in <span class="metric-name">Metric</span> and place a single colon separator span.
82
+ - Wrap every numeric value in <span class="metric-value"> containing a <span class="metric-number positive|negative|neutral"> token chosen by whether the figure signals strength, weakness, or neutral impact.
83
+ - Provide at least two narrative paragraphs per section using <p class="analysis-line">…</p> with concise professional tone and varied phrasing.
84
+ - Mention each metric only once; do not repeat values in multiple sentences.
85
+ - Do not emit inline CSS, markdown, bullet characters, or placeholder text. Use single spaces only.
86
 
87
+ Analytical guidance:
88
+ - Base every conclusion on the supplied Portfolio A/B metrics and explicitly contrast the stronger vs weaker portfolio on returns, risk-adjusted efficiency, volatility, drawdowns, and stability.
89
+ - Deliver a decisive recommendation that names the favored portfolio (or flags deficiencies in both) with clear reasoning grounded in data.
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
90
  """
91
 
92