omniverse1 commited on
Commit
33fb7c0
·
verified ·
1 Parent(s): 08f6049

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +35 -30
app.py CHANGED
@@ -9,11 +9,10 @@ from utils import (
9
  create_price_chart,
10
  create_technical_chart,
11
  create_prediction_chart,
12
- # Import fungsi baru
13
  calculate_advanced_risk_metrics
14
  )
15
  import warnings
16
- import numpy as np # Tambahkan import numpy
17
 
18
  warnings.filterwarnings("ignore")
19
 
@@ -27,21 +26,17 @@ def analyze_stock(symbol, prediction_days=30):
27
  symbol = symbol.upper() + ".JK"
28
 
29
  stock = yf.Ticker(symbol)
30
- # Menggunakan periode 1 tahun untuk metrik risiko yang lebih relevan
31
  data = stock.history(period="1y", interval="1d")
32
 
33
  if data.empty:
34
  raise ValueError("No price data available for this stock.")
35
 
36
- # Menghitung Indikator Teknikal (Ini juga akan mengisi kolom RSI/MACD ke 'data')
37
  indicators = calculate_technical_indicators(data)
38
  signals = generate_trading_signals(data, indicators)
39
  fundamental_info = get_fundamental_data(stock)
40
 
41
- # Menghitung Metrik Risiko Tingkat Lanjut
42
  risk_metrics = calculate_advanced_risk_metrics(data.copy())
43
 
44
- # Prediksi Chronos-2 dengan Covariates
45
  predictions = predict_prices(data, prediction_days=prediction_days)
46
 
47
  fig_price = create_price_chart(data, indicators)
@@ -51,19 +46,21 @@ def analyze_stock(symbol, prediction_days=30):
51
  # kalkulasi TP1, TP2, SL yang diperbarui berdasarkan quantiles/range prediksi
52
  last_price = data['Close'].iloc[-1]
53
 
54
- # Target/SL yang lebih konservatif berdasarkan range prediksi Q0.1-Q0.9
55
- q05 = predictions.get('values', [last_price])
56
- q01 = predictions.get('q01', [last_price * 0.95])
57
- q09 = predictions.get('q09', [last_price * 1.05])
58
 
59
- # TP1 (Target Konservatif): Midpoint antara harga terakhir dan median tertinggi
60
- tp1 = (last_price + np.max(q05)) / 2
61
- # TP2 (Target Agresif): Quantile 90% tertinggi
62
- tp2 = np.max(q09)
63
- # SL (Stop Loss): Quantile 10% terendah
64
- sl = np.min(q01)
 
 
 
65
 
66
- # Pastikan TP1 < TP2 dan SL lebih rendah dari TP
67
  if tp1 > tp2:
68
  tp1, tp2 = tp2, tp1
69
  if sl > last_price:
@@ -73,12 +70,10 @@ def analyze_stock(symbol, prediction_days=30):
73
  predictions["tp2"] = tp2
74
  predictions["sl"] = sl
75
 
76
- # Menambahkan risk_metrics ke return
77
  return fundamental_info, indicators, signals, risk_metrics, fig_price, fig_technical, fig_prediction, predictions
78
 
79
  except Exception as e:
80
  print(f"Error analyzing {symbol}: {e}")
81
- empty_fig = gr.Plot.update(value=None)
82
 
83
  try:
84
  stock = yf.Ticker(symbol)
@@ -97,8 +92,10 @@ def analyze_stock(symbol, prediction_days=30):
97
  "q01": [], "q09": [],
98
  "tp1": default_tp1, "tp2": default_tp2, "sl": default_sl,
99
  }
100
- # Mengembalikan dictionary kosong untuk risk_metrics saat error
101
- return {}, {}, {}, {}, empty_fig, empty_fig, empty_fig, empty_predictions
 
 
102
 
103
 
104
  def update_analysis(symbol, prediction_days):
@@ -106,25 +103,27 @@ def update_analysis(symbol, prediction_days):
106
  fundamental_info,
107
  indicators,
108
  signals,
109
- risk_metrics, # Tambahan metrik risiko
110
  fig_price,
111
  fig_technical,
112
  fig_prediction,
113
  predictions,
114
  ) = analyze_stock(symbol, prediction_days)
115
 
116
- if not fundamental_info:
117
- error_msg = f"Unable to fetch stock data for {symbol.upper()}. Please check the symbol."
118
- tp_sl_info = f"<b>TP1:</b> Rp{predictions.get('tp1', 0):,.2f}<br><b>TP2:</b> Rp{predictions.get('tp2', 0):,.2f}<br><b>Stop Loss:</b> Rp{predictions.get('sl', 0):,.2f}<br><br><b>Model Insight:</b><br>Data fetching failed. Cannot proceed with analysis."
 
119
 
120
  return (
121
  f"""<div style="color: red; padding: 10px; border: 1px solid red; border-radius: 5px;">{error_msg}</div><br>{tp_sl_info}""",
122
- gr.Plot.update(value=None),
123
- gr.Plot.update(value=None),
124
- gr.Plot.update(value=None),
125
  )
126
 
127
  # --- FUNDAMENTALS ---
 
128
  fundamentals = f"""
129
  <h4>COMPANY FUNDAMENTALS</h4>
130
  <b>Name:</b> {fundamental_info.get('name', 'N/A')} ({symbol.upper()})<br>
@@ -136,6 +135,7 @@ def update_analysis(symbol, prediction_days):
136
  """
137
 
138
  # --- TECHNICAL SIGNAL ---
 
139
  details_list = "".join(
140
  [f"<li>{line.strip()}</li>" for line in signals.get("details", "").split("\n") if line.strip()]
141
  )
@@ -154,6 +154,7 @@ def update_analysis(symbol, prediction_days):
154
  """
155
 
156
  # --- RISK METRICS ---
 
157
  risk_details = ""
158
  if "error" in risk_metrics:
159
  risk_details = f"<b style='color: red;'>{risk_metrics['error']}</b>"
@@ -167,8 +168,12 @@ def update_analysis(symbol, prediction_days):
167
  """
168
 
169
  # --- AI FORECAST ---
170
- band_min = float(min(predictions.get('q01', [0]))) if predictions.get('q01') and predictions.get('q01').size > 0 else 0
171
- band_max = float(max(predictions.get('q09', [0]))) if predictions.get('q09') and predictions.get('q09').size > 0 else 0
 
 
 
 
172
 
173
  prediction = f"""
174
  <h4>{prediction_days}-DAY AI FORECAST (CHRONOS-2 + COVARIATES)</h4>
 
9
  create_price_chart,
10
  create_technical_chart,
11
  create_prediction_chart,
 
12
  calculate_advanced_risk_metrics
13
  )
14
  import warnings
15
+ import numpy as np
16
 
17
  warnings.filterwarnings("ignore")
18
 
 
26
  symbol = symbol.upper() + ".JK"
27
 
28
  stock = yf.Ticker(symbol)
 
29
  data = stock.history(period="1y", interval="1d")
30
 
31
  if data.empty:
32
  raise ValueError("No price data available for this stock.")
33
 
 
34
  indicators = calculate_technical_indicators(data)
35
  signals = generate_trading_signals(data, indicators)
36
  fundamental_info = get_fundamental_data(stock)
37
 
 
38
  risk_metrics = calculate_advanced_risk_metrics(data.copy())
39
 
 
40
  predictions = predict_prices(data, prediction_days=prediction_days)
41
 
42
  fig_price = create_price_chart(data, indicators)
 
46
  # kalkulasi TP1, TP2, SL yang diperbarui berdasarkan quantiles/range prediksi
47
  last_price = data['Close'].iloc[-1]
48
 
49
+ # FIX 3: Dapatkan array prediksi dengan fallback ke array yang berisi harga terakhir
50
+ q05 = predictions.get('values', np.array([last_price]))
51
+ q01 = predictions.get('q01', np.array([last_price * 0.95]))
52
+ q09 = predictions.get('q09', np.array([last_price * 1.05]))
53
 
54
+ # FIX 3: Robust max/min calculation
55
+ q05_max = np.max(q05) if q05.size > 0 else last_price
56
+ q09_max = np.max(q09) if q09.size > 0 else last_price * 1.05
57
+ q01_min = np.min(q01) if q01.size > 0 else last_price * 0.95
58
+
59
+ # Target/SL calculation
60
+ tp1 = (last_price + q05_max) / 2
61
+ tp2 = q09_max
62
+ sl = q01_min
63
 
 
64
  if tp1 > tp2:
65
  tp1, tp2 = tp2, tp1
66
  if sl > last_price:
 
70
  predictions["tp2"] = tp2
71
  predictions["sl"] = sl
72
 
 
73
  return fundamental_info, indicators, signals, risk_metrics, fig_price, fig_technical, fig_prediction, predictions
74
 
75
  except Exception as e:
76
  print(f"Error analyzing {symbol}: {e}")
 
77
 
78
  try:
79
  stock = yf.Ticker(symbol)
 
92
  "q01": [], "q09": [],
93
  "tp1": default_tp1, "tp2": default_tp2, "sl": default_sl,
94
  }
95
+ empty_risk = {"error": "Prediction Model Failed to Load/Run. See console for details."}
96
+
97
+ # FIX 4: Mengembalikan None untuk output plot Gradio untuk membersihkan plot
98
+ return {}, {}, {}, empty_risk, None, None, None, empty_predictions
99
 
100
 
101
  def update_analysis(symbol, prediction_days):
 
103
  fundamental_info,
104
  indicators,
105
  signals,
106
+ risk_metrics,
107
  fig_price,
108
  fig_technical,
109
  fig_prediction,
110
  predictions,
111
  ) = analyze_stock(symbol, prediction_days)
112
 
113
+ # FIX 4: Cek apakah ada plot yang None (berarti ada error)
114
+ if fig_price is None:
115
+ error_msg = f"Unable to run AI prediction or fetch data for {symbol.upper()}. Check the model logs for details."
116
+ tp_sl_info = f"<b>TP1:</b> Rp{predictions.get('tp1', 0):,.2f}<br><b>TP2:</b> Rp{predictions.get('tp2', 0):,.2f}<br><b>Stop Loss:</b> Rp{predictions.get('sl', 0):,.2f}<br><br><b>Model Insight:</b><br>{predictions.get('summary', 'Data fetching or model execution failed. Cannot proceed with analysis.')}"
117
 
118
  return (
119
  f"""<div style="color: red; padding: 10px; border: 1px solid red; border-radius: 5px;">{error_msg}</div><br>{tp_sl_info}""",
120
+ None, # fig_price
121
+ None, # fig_technical
122
+ None, # fig_prediction
123
  )
124
 
125
  # --- FUNDAMENTALS ---
126
+ # ... (code for fundamentals remains the same)
127
  fundamentals = f"""
128
  <h4>COMPANY FUNDAMENTALS</h4>
129
  <b>Name:</b> {fundamental_info.get('name', 'N/A')} ({symbol.upper()})<br>
 
135
  """
136
 
137
  # --- TECHNICAL SIGNAL ---
138
+ # ... (code for trading_signal remains the same)
139
  details_list = "".join(
140
  [f"<li>{line.strip()}</li>" for line in signals.get("details", "").split("\n") if line.strip()]
141
  )
 
154
  """
155
 
156
  # --- RISK METRICS ---
157
+ # ... (code for risk_report remains the same)
158
  risk_details = ""
159
  if "error" in risk_metrics:
160
  risk_details = f"<b style='color: red;'>{risk_metrics['error']}</b>"
 
168
  """
169
 
170
  # --- AI FORECAST ---
171
+ # Perlu memastikan q01/q09 tidak kosong
172
+ q01_values = predictions.get('q01', [])
173
+ q09_values = predictions.get('q09', [])
174
+
175
+ band_min = float(min(q01_values)) if q01_values and len(q01_values) > 0 else 0
176
+ band_max = float(max(q09_values)) if q09_values and len(q09_values) > 0 else 0
177
 
178
  prediction = f"""
179
  <h4>{prediction_days}-DAY AI FORECAST (CHRONOS-2 + COVARIATES)</h4>