Spaces:
Sleeping
Sleeping
| import gradio as gr | |
| import yfinance as yf | |
| from utils import ( | |
| calculate_technical_indicators, | |
| generate_trading_signals, | |
| get_fundamental_data, | |
| create_price_chart, | |
| create_technical_chart, | |
| create_prediction_chart, | |
| predict_prices, | |
| ) | |
| import pandas as pd | |
| def analyze_stock(symbol, mode, pred_days): | |
| try: | |
| stock = yf.Ticker(symbol) | |
| data = stock.history(period="1y") | |
| if data.empty: | |
| return "No data found", None, None, None | |
| indicators = calculate_technical_indicators(data) | |
| signals = generate_trading_signals(data, indicators) | |
| fundamentals = get_fundamental_data(stock) | |
| fig_price = create_price_chart(data, indicators) | |
| fig_technical = create_technical_chart(data, indicators) | |
| if mode == "AI Prediction": | |
| prediction = predict_prices(data, prediction_days=pred_days) | |
| fig_prediction = create_prediction_chart(data, prediction) | |
| return fundamentals, signals, fig_price, fig_technical, fig_prediction, prediction | |
| else: | |
| return fundamentals, signals, fig_price, fig_technical, None, None | |
| except Exception as e: | |
| return f"Error analyzing {symbol}: {e}", None, None, None, None, None | |
| def format_fundamental_output(f): | |
| return f""" | |
| <h3>COMPANY FUNDAMENTALS</h3> | |
| <b>Name:</b> {f['name']}<br> | |
| <b>Current Price:</b> Rp{f['current_price']:,.2f}<br> | |
| <b>Market Cap:</b> {f['market_cap']:,}<br> | |
| <b>P/E Ratio:</b> {f['pe_ratio']:.2f}<br> | |
| <b>Dividend Yield:</b> {f['dividend_yield']:.2f}%<br> | |
| <b>Volume:</b> {f['volume']:,}<br> | |
| """ | |
| def format_signal_output(s): | |
| details = s["details"].split("\n") | |
| formatted_details = "<ul>" + "".join(f"<li>{d}</li>" for d in details) + "</ul>" | |
| return f""" | |
| <h3>TECHNICAL SIGNAL SUMMARY</h3> | |
| <b>Overall Trend:</b> {s['overall']}<br> | |
| <b>Signal Strength:</b> {s['strength']:.2f}%<br> | |
| <b>Support:</b> Rp{s['support']:,.2f}<br> | |
| <b>Resistance:</b> Rp{s['resistance']:,.2f}<br> | |
| <b>Stop Loss:</b> Rp{s['stop_loss']:,.2f}<br> | |
| <br><b>Detailed Signals:</b>{formatted_details} | |
| """ | |
| def format_ai_output(p): | |
| if not p: | |
| return "" | |
| tp1 = p["mean_30d"] * 0.97 | |
| tp2 = p["mean_30d"] * 1.02 | |
| sl = p["low_30d"] * 0.95 | |
| return f""" | |
| <h3>30-DAY AI FORECAST (CHRONOS-BOLT)</h3> | |
| <b>Predicted High:</b> Rp{p['high_30d']:,.2f}<br> | |
| <b>Predicted Low:</b> Rp{p['low_30d']:,.2f}<br> | |
| <b>Expected Change:</b> {p['change_pct']:.2f}%<br><br> | |
| <b>TP1:</b> Rp{tp1:,.2f}<br> | |
| <b>TP2:</b> Rp{tp2:,.2f}<br> | |
| <b>Stop Loss:</b> Rp{sl:,.2f}<br><br> | |
| <b>Model Insight:</b><br>{p['summary']} | |
| """ | |
| with gr.Blocks(css=""" | |
| body { font-family: 'Inter', sans-serif; background-color: #f9fafc; color: #222; } | |
| .gradio-container { max-width: 1200px; margin: auto; } | |
| h3 { color: #003366; border-bottom: 2px solid #d3d3d3; padding-bottom: 5px; } | |
| .panel-box { background: white; padding: 20px; border-radius: 10px; box-shadow: 0 1px 3px rgba(0,0,0,0.1); } | |
| """) as demo: | |
| gr.HTML("<h1 style='text-align:center;color:#003366;'>📈 STOCK ANALYSIS DASHBOARD</h1>") | |
| with gr.Row(): | |
| stock_input = gr.Textbox(label="Enter Stock Symbol (e.g. BBCA.JK, ADRO.JK)", placeholder="Type your stock symbol here...") | |
| mode_input = gr.Radio(["Technical Analysis", "AI Prediction"], label="Select Analysis Mode", value="Technical Analysis") | |
| pred_days_input = gr.Slider(7, 60, value=30, step=1, label="Prediction Days (for AI mode only)") | |
| analyze_button = gr.Button("Analyze") | |
| with gr.Row(): | |
| fundamentals_output = gr.HTML() | |
| signal_output = gr.HTML() | |
| ai_output = gr.HTML() | |
| with gr.Row(): | |
| chart_price = gr.Plot(label="Price Chart") | |
| chart_technical = gr.Plot(label="Technical Chart") | |
| chart_prediction = gr.Plot(label="AI Prediction Chart") | |
| def run_analysis(symbol, mode, pred_days): | |
| fundamentals, signals, fig_price, fig_technical, fig_prediction, prediction = analyze_stock(symbol, mode, pred_days) | |
| if isinstance(fundamentals, str): | |
| return fundamentals, "", "", None, None, None | |
| return ( | |
| format_fundamental_output(fundamentals), | |
| format_signal_output(signals), | |
| format_ai_output(prediction) if mode == "AI Prediction" else "", | |
| fig_price, | |
| fig_technical, | |
| fig_prediction if mode == "AI Prediction" else None | |
| ) | |
| analyze_button.click( | |
| fn=run_analysis, | |
| inputs=[stock_input, mode_input, pred_days_input], | |
| outputs=[fundamentals_output, signal_output, ai_output, chart_price, chart_technical, chart_prediction] | |
| ) | |
| demo.launch(server_name="0.0.0.0", server_port=7860) | |