Spaces:
Sleeping
Sleeping
File size: 6,218 Bytes
7458986 65d5f73 7458986 65d5f73 380e150 7458986 2e5e038 972a547 05c066f 380e150 7458986 380e150 05c066f 7458986 05c066f 2e5e038 05c066f 525527f 65d5f73 380e150 972a547 65d5f73 972a547 380e150 05c066f 65d5f73 05c066f 2e5e038 05c066f 380e150 2e5e038 380e150 2e5e038 dbe373a 65d5f73 c67acf2 380e150 05c066f 380e150 2e5e038 380e150 2e5e038 dbe373a 65d5f73 380e150 2e5e038 380e150 2e5e038 380e150 2e5e038 380e150 65d5f73 972a547 380e150 2e5e038 380e150 2e5e038 65d5f73 972a547 2e5e038 380e150 2e5e038 65d5f73 2e5e038 525527f 380e150 05c066f 380e150 525527f 65d5f73 380e150 65d5f73 7458986 380e150 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 |
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 numpy as np
def analyze_stock(symbol, mode, pred_days):
try:
stock = yf.Ticker(symbol)
data = stock.history(period="1y")
if data.empty:
msg = f"No data found for {symbol}. Check the symbol or try adding .JK (e.g., ADRO.JK)"
return (
{"name": "N/A", "current_price": 0, "market_cap": 0, "pe_ratio": 0, "dividend_yield": 0, "volume": 0},
{"overall": "N/A", "strength": 0, "support": 0, "resistance": 0, "stop_loss": 0, "details": msg},
None, 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:
msg = f"Error analyzing {symbol}: {e}"
return (
{"name": "N/A", "current_price": 0, "market_cap": 0, "pe_ratio": 0, "dividend_yield": 0, "volume": 0},
{"overall": "Error", "strength": 0, "support": 0, "resistance": 0, "stop_loss": 0, "details": msg},
None, None, None, None
)
def format_fundamental_output(f):
return f"""
<div class="card">
<h3>COMPANY FUNDAMENTALS</h3>
<p><b>Name:</b> {f['name']}</p>
<p><b>Current Price:</b> Rp{f['current_price']:,.2f}</p>
<p><b>Market Cap:</b> {f['market_cap']:,}</p>
<p><b>P/E Ratio:</b> {f['pe_ratio']:.2f}</p>
<p><b>Dividend Yield:</b> {f['dividend_yield']:.2f}%</p>
<p><b>Volume:</b> {f['volume']:,}</p>
</div>
"""
def format_signal_output(s):
details = s.get("details", "")
detail_list = details.split("\n") if details else []
formatted_details = "<ul>" + "".join(f"<li>{d}</li>" for d in detail_list) + "</ul>"
return f"""
<div class="card">
<h3>TECHNICAL SIGNAL SUMMARY</h3>
<p><b>Overall Trend:</b> {s.get('overall','N/A')}</p>
<p><b>Signal Strength:</b> {s.get('strength',0):.2f}%</p>
<p><b>Support:</b> Rp{s.get('support',0):,.2f}</p>
<p><b>Resistance:</b> Rp{s.get('resistance',0):,.2f}</p>
<p><b>Stop Loss:</b> Rp{s.get('stop_loss',0):,.2f}</p>
<h4>Detailed Signals:</h4>
{formatted_details}
</div>
"""
def format_ai_output(p):
if p is None or not isinstance(p, dict) or "values" not in p or len(p["values"]) == 0:
return """
<div class="card">
<h3>30-DAY AI FORECAST (CHRONOS-BOLT)</h3>
<p>No AI prediction data available.</p>
</div>
"""
tp1 = p["mean_30d"] * 0.97
tp2 = p["mean_30d"] * 1.02
sl = p["low_30d"] * 0.95
return f"""
<div class="card">
<h3>30-DAY AI FORECAST (CHRONOS-BOLT)</h3>
<p><b>Predicted High:</b> Rp{p['high_30d']:,.2f}</p>
<p><b>Predicted Low:</b> Rp{p['low_30d']:,.2f}</p>
<p><b>Expected Change:</b> {p['change_pct']:.2f}%</p>
<p><b>TP1:</b> Rp{tp1:,.2f}</p>
<p><b>TP2:</b> Rp{tp2:,.2f}</p>
<p><b>Stop Loss:</b> Rp{sl:,.2f}</p>
<h4>Model Insight:</h4>
<p style="font-size:13px;line-height:1.4;">{p['summary']}</p>
</div>
"""
with gr.Blocks(css="""
body { font-family: 'Inter', sans-serif; background-color: #f9fafc; color: #222; }
.gradio-container { max-width: 1300px; margin: auto; }
h1 { text-align:center; color:#003366; margin-bottom:20px; }
h3 { color:#003366; margin-bottom:8px; }
.card {
background: #ffffff;
border-radius: 10px;
box-shadow: 0 2px 4px rgba(0,0,0,0.08);
padding: 18px;
margin: 5px;
flex: 1;
min-width: 0;
}
.row-flex {
display: flex;
flex-wrap: wrap;
justify-content: space-between;
gap: 10px;
}
ul { margin: 6px 0 0 20px; padding: 0; }
li { margin-bottom: 4px; font-size: 14px; }
""") as demo:
gr.HTML("<h1>STOCK ANALYSIS DASHBOARD</h1>")
with gr.Row():
stock_input = gr.Textbox(label="Enter Stock Symbol (e.g. BBCA.JK, ADRO.JK)", placeholder="Type stock symbol...")
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 (AI only)")
analyze_button = gr.Button("Analyze", variant="primary")
gr.HTML("<hr style='margin:20px 0;'>")
with gr.Row(elem_classes="row-flex"):
fundamentals_output = gr.HTML()
signal_output = gr.HTML()
ai_output = gr.HTML()
gr.HTML("<hr style='margin:20px 0;'>")
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)
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)
|