import gradio as gr import pandas as pd import yfinance as yf from utils import ( calculate_technical_indicators, generate_trading_signals, get_fundamental_data, predict_prices, create_price_chart, create_technical_chart, create_prediction_chart, ) import warnings warnings.filterwarnings("ignore") def analyze_stock(symbol, prediction_days=30): try: if not symbol.strip(): raise ValueError("Please enter a valid stock symbol.") if not symbol.endswith(".JK"): symbol = symbol.upper() + ".JK" stock = yf.Ticker(symbol) data = stock.history(period="6mo", interval="1d") if data.empty: raise ValueError("No price data available for this stock.") indicators = calculate_technical_indicators(data) signals = generate_trading_signals(data, indicators) fundamental_info = get_fundamental_data(stock) predictions = predict_prices(data, prediction_days=prediction_days) fig_price = create_price_chart(data, indicators) fig_technical = create_technical_chart(data, indicators) fig_prediction = create_prediction_chart(data, predictions) # kalkulasi TP1, TP2, SL last_price = data['Close'].iloc[-1] tp1 = last_price * (1 + (predictions.get("change_pct", 0) / 200)) tp2 = last_price * (1 + (predictions.get("change_pct", 0) / 100)) sl = last_price * 0.95 predictions["tp1"] = tp1 predictions["tp2"] = tp2 predictions["sl"] = sl return fundamental_info, indicators, signals, fig_price, fig_technical, fig_prediction, predictions except Exception as e: print(f"Error analyzing {symbol}: {e}") empty_fig = gr.Plot.update(value=None) empty_predictions = { "high_30d": 0, "low_30d": 0, "change_pct": 0, "summary": "Prediction unavailable.", } return {}, {}, {}, empty_fig, empty_fig, empty_fig, empty_predictions def update_analysis(symbol, prediction_days): ( fundamental_info, indicators, signals, fig_price, fig_technical, fig_prediction, predictions, ) = analyze_stock(symbol, prediction_days) if not fundamental_info: return ( "⚠️ Unable to fetch stock data.", gr.Plot.update(value=None), gr.Plot.update(value=None), gr.Plot.update(value=None), ) fundamentals = f""" ### 🏢 Company Fundamentals **Name:** {fundamental_info.get('name', 'N/A')} ({symbol.upper()}) **Current Price:** Rp{fundamental_info.get('current_price', 0):,.2f} **Market Cap:** {fundamental_info.get('market_cap', 0):,} **P/E Ratio:** {fundamental_info.get('pe_ratio', 0):.2f} **Dividend Yield:** {fundamental_info.get('dividend_yield', 0):.2f}% **Volume:** {fundamental_info.get('volume', 0):,} """ details_list = "".join( [f"
  • {line.strip()}
  • " for line in signals.get("details", "").split("\n") if line.strip()] ) trading_signal = f""" ### 📊 Technical Signal Summary **Overall Trend:** {signals.get('overall', 'N/A')} **Signal Strength:** {signals.get('strength', 0):.2f}% **Support:** Rp{signals.get('support', 0):,.2f} **Resistance:** Rp{signals.get('resistance', 0):,.2f} **Stop Loss:** Rp{signals.get('stop_loss', 0):,.2f} **Detailed Signals:** """ prediction = f""" ### 🤖 30-Day AI Forecast (Chronos-Bolt) **Predicted High:** Rp{predictions.get('high_30d', 0):,.2f} **Predicted Low:** Rp{predictions.get('low_30d', 0):,.2f} **Expected Change:** {predictions.get('change_pct', 0):.2f}% **TP1:** Rp{predictions.get('tp1', 0):,.2f} **TP2:** Rp{predictions.get('tp2', 0):,.2f} **Stop Loss:** Rp{predictions.get('sl', 0):,.2f} **Model Insight:** {predictions.get('summary', 'No analysis available')} """ combined = f"""
    {fundamentals}
    {trading_signal}
    {prediction}
    """ return ( combined, fig_price, fig_technical, fig_prediction, ) # ---------------------- UI ---------------------- with gr.Blocks( title="REXPRO Financial AI Dashboard", theme=gr.themes.Soft(primary_hue="blue", secondary_hue="gray"), ) as app: gr.Markdown( """ # 💹 REXPRO Financial AI Dashboard Analyze **Indonesian stocks (IDX)** using AI-powered forecasting and technical indicators. """ ) with gr.Row(): symbol = gr.Textbox( label="Stock Symbol (IDX)", value="BBCA", placeholder="e.g., BBCA, TLKM, ADRO, BMRI", ) prediction_days = gr.Slider( label="Forecast Period (Days)", minimum=5, maximum=60, step=5, value=30, ) analyze_button = gr.Button("🔍 Run Analysis", variant="primary") gr.Markdown("---") report_section = gr.HTML(label="Analysis Summary") gr.Markdown("---") gr.Markdown("### 📈 Market Charts") with gr.Tabs(): with gr.Tab("Price Overview"): price_chart = gr.Plot(label="Price & Moving Averages") with gr.Tab("Technical Indicators"): technical_chart = gr.Plot(label="Technical Indicator Overview") with gr.Tab("AI Forecast"): prediction_chart = gr.Plot(label="AI Forecast Projection") analyze_button.click( fn=update_analysis, inputs=[symbol, prediction_days], outputs=[report_section, price_chart, technical_chart, prediction_chart], ) if __name__ == "__main__": app.launch(server_name="0.0.0.0", server_port=7860, ssr_mode=True)