omniverse1 commited on
Commit
3686f17
ยท
verified ยท
1 Parent(s): 970d73a

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +56 -64
app.py CHANGED
@@ -75,20 +75,20 @@ def update_analysis(symbol, prediction_days):
75
 
76
  if not fundamental_info:
77
  return (
78
- "โš ๏ธ Unable to fetch stock data.",
79
  gr.Plot.update(value=None),
80
  gr.Plot.update(value=None),
81
  gr.Plot.update(value=None),
82
  )
83
 
84
  fundamentals = f"""
85
- ### ๐Ÿข Company Fundamentals
86
- **Name:** {fundamental_info.get('name', 'N/A')} ({symbol.upper()})
87
- **Current Price:** Rp{fundamental_info.get('current_price', 0):,.2f}
88
- **Market Cap:** {fundamental_info.get('market_cap', 0):,}
89
- **P/E Ratio:** {fundamental_info.get('pe_ratio', 0):.2f}
90
- **Dividend Yield:** {fundamental_info.get('dividend_yield', 0):.2f}%
91
- **Volume:** {fundamental_info.get('volume', 0):,}
92
  """
93
 
94
  details_list = "".join(
@@ -96,91 +96,84 @@ def update_analysis(symbol, prediction_days):
96
  )
97
 
98
  trading_signal = f"""
99
- ### ๐Ÿ“Š Technical Signal Summary
100
- **Overall Trend:** {signals.get('overall', 'N/A')}
101
- **Signal Strength:** {signals.get('strength', 0):.2f}%
102
- **Support:** Rp{signals.get('support', 0):,.2f}
103
- **Resistance:** Rp{signals.get('resistance', 0):,.2f}
104
- **Stop Loss:** Rp{signals.get('stop_loss', 0):,.2f}
105
-
106
- **Detailed Signals:**
107
- <ul style="margin-top:6px; padding-left:20px;">{details_list}</ul>
 
108
  """
109
 
110
  prediction = f"""
111
- ### ๐Ÿค– 30-Day AI Forecast (Chronos-Bolt)
112
- **Predicted High:** Rp{predictions.get('high_30d', 0):,.2f}
113
- **Predicted Low:** Rp{predictions.get('low_30d', 0):,.2f}
114
- **Expected Change:** {predictions.get('change_pct', 0):.2f}%
115
-
116
- **TP1:** Rp{predictions.get('tp1', 0):,.2f}
117
- **TP2:** Rp{predictions.get('tp2', 0):,.2f}
118
- **Stop Loss:** Rp{predictions.get('sl', 0):,.2f}
119
-
120
- **Model Insight:**
121
- {predictions.get('summary', 'No analysis available')}
122
- """
123
-
124
- combined = f"""
125
- <div style="display:flex;flex-wrap:wrap;gap:12px;justify-content:space-between;">
126
- <div style="flex:1;min-width:300px;background-color:white;border-radius:8px;padding:12px;border:1px solid #e5e7eb;">{fundamentals}</div>
127
- <div style="flex:1;min-width:300px;background-color:white;border-radius:8px;padding:12px;border:1px solid #e5e7eb;">{trading_signal}</div>
128
- <div style="flex:1;min-width:300px;background-color:white;border-radius:8px;padding:12px;border:1px solid #e5e7eb;">{prediction}</div>
129
- </div>
130
  """
131
 
 
 
132
  return (
133
- combined,
 
 
 
 
 
 
134
  fig_price,
135
  fig_technical,
136
  fig_prediction,
137
  )
138
 
139
 
140
- # ---------------------- UI ----------------------
141
  with gr.Blocks(
142
- title="REXPRO Financial AI Dashboard",
143
- theme=gr.themes.Soft(primary_hue="blue", secondary_hue="gray"),
144
  ) as app:
145
-
146
  gr.Markdown(
147
- """
148
- # ๐Ÿ’น REXPRO Financial AI Dashboard
149
- Analyze **Indonesian stocks (IDX)** using AI-powered forecasting and technical indicators.
150
- """
151
  )
152
 
153
  with gr.Row():
154
  symbol = gr.Textbox(
155
- label="Stock Symbol (IDX)",
156
  value="BBCA",
157
- placeholder="e.g., BBCA, TLKM, ADRO, BMRI",
 
158
  )
159
  prediction_days = gr.Slider(
160
- label="Forecast Period (Days)",
161
  minimum=5,
162
  maximum=60,
163
  step=5,
164
  value=30,
 
165
  )
166
- analyze_button = gr.Button("๐Ÿ” Run Analysis", variant="primary")
167
 
168
  gr.Markdown("---")
169
-
170
- report_section = gr.HTML(label="Analysis Summary")
171
-
172
  gr.Markdown("---")
173
- gr.Markdown("### ๐Ÿ“ˆ Market Charts")
174
-
175
- with gr.Tabs():
176
- with gr.Tab("Price Overview"):
177
- price_chart = gr.Plot(label="Price & Moving Averages")
178
 
179
- with gr.Tab("Technical Indicators"):
180
- technical_chart = gr.Plot(label="Technical Indicator Overview")
181
-
182
- with gr.Tab("AI Forecast"):
183
- prediction_chart = gr.Plot(label="AI Forecast Projection")
 
184
 
185
  analyze_button.click(
186
  fn=update_analysis,
@@ -188,6 +181,5 @@ with gr.Blocks(
188
  outputs=[report_section, price_chart, technical_chart, prediction_chart],
189
  )
190
 
191
-
192
  if __name__ == "__main__":
193
- app.launch(server_name="0.0.0.0", server_port=7860, ssr_mode=True)
 
75
 
76
  if not fundamental_info:
77
  return (
78
+ "Unable to fetch stock data.",
79
  gr.Plot.update(value=None),
80
  gr.Plot.update(value=None),
81
  gr.Plot.update(value=None),
82
  )
83
 
84
  fundamentals = f"""
85
+ <h4>COMPANY FUNDAMENTALS</h4>
86
+ <b>Name:</b> {fundamental_info.get('name', 'N/A')} ({symbol.upper()})<br>
87
+ <b>Current Price:</b> Rp{fundamental_info.get('current_price', 0):,.2f}<br>
88
+ <b>Market Cap:</b> {fundamental_info.get('market_cap', 0):,}<br>
89
+ <b>P/E Ratio:</b> {fundamental_info.get('pe_ratio', 0):.2f}<br>
90
+ <b>Dividend Yield:</b> {fundamental_info.get('dividend_yield', 0):.2f}%<br>
91
+ <b>Volume:</b> {fundamental_info.get('volume', 0):,}<br>
92
  """
93
 
94
  details_list = "".join(
 
96
  )
97
 
98
  trading_signal = f"""
99
+ <h4>TECHNICAL SIGNAL SUMMARY</h4>
100
+ <b>Overall Trend:</b> {signals.get('overall', 'N/A')}<br>
101
+ <b>Signal Strength:</b> {signals.get('strength', 0):.2f}%<br>
102
+ <b>Support:</b> Rp{signals.get('support', 0):,.2f}<br>
103
+ <b>Resistance:</b> Rp{signals.get('resistance', 0):,.2f}<br>
104
+ <b>Stop Loss:</b> Rp{signals.get('stop_loss', 0):,.2f}<br><br>
105
+ <b>Detailed Signals:</b>
106
+ <ul style="margin-top: 8px; padding-left: 20px; line-height: 1.6;">
107
+ {details_list}
108
+ </ul>
109
  """
110
 
111
  prediction = f"""
112
+ <h4>30-DAY AI FORECAST (CHRONOS-BOLT)</h4>
113
+ <b>Predicted High:</b> Rp{predictions.get('high_30d', 0):,.2f}<br>
114
+ <b>Predicted Low:</b> Rp{predictions.get('low_30d', 0):,.2f}<br>
115
+ <b>Expected Change:</b> {predictions.get('change_pct', 0):.2f}%<br><br>
116
+ <b>TP1:</b> Rp{predictions.get('tp1', 0):,.2f}<br>
117
+ <b>TP2:</b> Rp{predictions.get('tp2', 0):,.2f}<br>
118
+ <b>Stop Loss:</b> Rp{predictions.get('sl', 0):,.2f}<br><br>
119
+ <b>Model Insight:</b><br>{predictions.get('summary', 'No analysis available')}
 
 
 
 
 
 
 
 
 
 
 
120
  """
121
 
122
+ # Karena custom CSS dihapus, kita akan menggunakan div sederhana tanpa class 'panel-box' dan 'triple-panel'
123
+ # Gradio secara otomatis akan menata elemen-elemen ini dengan lebih standar
124
  return (
125
+ f"""
126
+ <div style="display: flex; flex-direction: row; gap: 16px;">
127
+ <div style="flex: 1; min-width: 30%; border: 1px solid #ccc; padding: 10px; border-radius: 5px;">{fundamentals}</div>
128
+ <div style="flex: 1; min-width: 30%; border: 1px solid #ccc; padding: 10px; border-radius: 5px;">{trading_signal}</div>
129
+ <div style="flex: 1; min-width: 30%; border: 1px solid #ccc; padding: 10px; border-radius: 5px;">{prediction}</div>
130
+ </div>
131
+ """,
132
  fig_price,
133
  fig_technical,
134
  fig_prediction,
135
  )
136
 
137
 
138
+ # --- Perubahan utama di sini ---
139
  with gr.Blocks(
140
+ title="REXPRO FINANCIAL AI DASHBOARD"
141
+ # Parameter theme dan css dihapus untuk kembali ke default Gradio
142
  ) as app:
143
+ gr.Markdown("# REXPRO FINANCIAL AI DASHBOARD")
144
  gr.Markdown(
145
+ "Comprehensive stock analytics powered by **AI forecasting and technical analysis.**"
 
 
 
146
  )
147
 
148
  with gr.Row():
149
  symbol = gr.Textbox(
150
+ label="STOCK SYMBOL (IDX)",
151
  value="BBCA",
152
+ placeholder="Example: BBCA, TLKM, ADRO, BMRI",
153
+ interactive=True,
154
  )
155
  prediction_days = gr.Slider(
156
+ label="FORECAST PERIOD (DAYS)",
157
  minimum=5,
158
  maximum=60,
159
  step=5,
160
  value=30,
161
+ interactive=True,
162
  )
163
+ analyze_button = gr.Button("RUN ANALYSIS")
164
 
165
  gr.Markdown("---")
166
+ # Bagian report_section diubah agar lebih kompatibel dengan tema default,
167
+ # menggunakan sedikit inline CSS untuk meniru tata letak tiga kolom dasar.
168
+ report_section = gr.HTML()
169
  gr.Markdown("---")
 
 
 
 
 
170
 
171
+ with gr.Tab("MARKET CHARTS"):
172
+ with gr.Row():
173
+ price_chart = gr.Plot(label="PRICE & MOVING AVERAGES")
174
+ technical_chart = gr.Plot(label="TECHNICAL INDICATORS OVERVIEW")
175
+ gr.Markdown("---")
176
+ prediction_chart = gr.Plot(label="AI FORECAST PROJECTION")
177
 
178
  analyze_button.click(
179
  fn=update_analysis,
 
181
  outputs=[report_section, price_chart, technical_chart, prediction_chart],
182
  )
183
 
 
184
  if __name__ == "__main__":
185
+ app.launch(server_name="0.0.0.0", server_port=7860, ssr_mode=True)