MacDash commited on
Commit
87def00
·
verified ·
1 Parent(s): daef553

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +138 -227
app.py CHANGED
@@ -5,50 +5,48 @@ from prophet import Prophet
5
  import plotly.graph_objs as go
6
  import math
7
  import numpy as np
 
 
8
 
9
- # Constants for API endpoints
10
- OKX_TICKERS_ENDPOINT = "https://www.okx.com/api/v5/market/tickers?instType=SPOT"
11
- OKX_CANDLE_ENDPOINT = "https://www.okx.com/api/v5/market/candles"
12
-
13
- TIMEFRAME_MAPPING = {
14
- "1m": "1m",
15
- "5m": "5m",
16
- "15m": "15m",
17
- "30m": "30m",
18
- "1h": "1H",
19
- "2h": "2H",
20
- "4h": "4H",
21
- "6h": "6H",
22
- "12h": "12H",
23
- "1d": "1D",
24
- "1w": "1W",
25
- }
26
-
27
- # Function to calculate technical indicators
28
  def calculate_technical_indicators(df):
 
 
 
 
29
  # RSI Calculation
30
  delta = df['close'].diff()
31
  gain = (delta.where(delta > 0, 0)).rolling(window=14).mean()
32
  loss = (-delta.where(delta < 0, 0)).rolling(window=14).mean()
33
  rs = gain / loss
34
  df['RSI'] = 100 - (100 / (1 + rs))
35
-
36
  # MACD Calculation
37
  exp1 = df['close'].ewm(span=12, adjust=False).mean()
38
  exp2 = df['close'].ewm(span=26, adjust=False).mean()
39
  df['MACD'] = exp1 - exp2
40
  df['Signal_Line'] = df['MACD'].ewm(span=9, adjust=False).mean()
41
-
42
  # Bollinger Bands Calculation
43
  df['MA20'] = df['close'].rolling(window=20).mean()
44
  df['BB_upper'] = df['MA20'] + 2 * df['close'].rolling(window=20).std()
45
  df['BB_lower'] = df['MA20'] - 2 * df['close'].rolling(window=20).std()
46
-
47
  return df
48
 
49
- # Function to create technical analysis charts
50
  def create_technical_charts(df):
51
- # Price and Bollinger Bands Chart
 
 
 
52
  fig1 = go.Figure()
53
  fig1.add_trace(go.Candlestick(
54
  x=df['timestamp'],
@@ -62,14 +60,12 @@ def create_technical_charts(df):
62
  fig1.add_trace(go.Scatter(x=df['timestamp'], y=df['BB_lower'], name='Lower BB', line=dict(color='gray', dash='dash')))
63
  fig1.update_layout(title='Price and Bollinger Bands', xaxis_title='Date', yaxis_title='Price')
64
 
65
- # RSI Chart
66
  fig2 = go.Figure()
67
  fig2.add_trace(go.Scatter(x=df['timestamp'], y=df['RSI'], name='RSI'))
68
  fig2.add_hline(y=70, line_dash="dash", line_color="red")
69
  fig2.add_hline(y=30, line_dash="dash", line_color="green")
70
  fig2.update_layout(title='RSI Indicator', xaxis_title='Date', yaxis_title='RSI')
71
 
72
- # MACD Chart
73
  fig3 = go.Figure()
74
  fig3.add_trace(go.Scatter(x=df['timestamp'], y=df['MACD'], name='MACD'))
75
  fig3.add_trace(go.Scatter(x=df['timestamp'], y=df['Signal_Line'], name='Signal Line'))
@@ -77,73 +73,19 @@ def create_technical_charts(df):
77
 
78
  return fig1, fig2, fig3
79
 
80
- # Fetch available symbols from OKX API
81
- def fetch_okx_symbols():
82
- try:
83
- resp = requests.get(OKX_TICKERS_ENDPOINT)
84
- data = resp.json().get("data", [])
85
- symbols = [item["instId"] for item in data if item.get("instType") == "SPOT"]
86
- return ["BTC-USDT"] + symbols if symbols else ["BTC-USDT"]
87
- except Exception as e:
88
- print(f"Error fetching symbols: {e}")
89
- return ["BTC-USDT"]
90
-
91
- # Fetch historical candle data from OKX API
92
- def fetch_okx_candles(symbol, timeframe="1H", total=2000):
93
- calls_needed = math.ceil(total / 300)
94
- all_data = []
95
-
96
- for _ in range(calls_needed):
97
- params = {"instId": symbol, "bar": timeframe, "limit": 300}
98
- try:
99
- resp = requests.get(OKX_CANDLE_ENDPOINT, params=params)
100
- resp.raise_for_status() # Raise HTTPError for bad responses (4xx or 5xx)
101
- data = resp.json().get("data", [])
102
- except requests.exceptions.RequestException as e:
103
- print(f"Error fetching candles: {e}")
104
- return pd.DataFrame()
105
- except (ValueError, KeyError) as e:
106
- print(f"Error parsing candle data: {e}")
107
- return pd.DataFrame()
108
-
109
- if not data:
110
- break
111
-
112
- columns = ["ts", "o", "h", "l", "c"]
113
- df_chunk = pd.DataFrame(data, columns=columns)
114
- df_chunk.rename(columns={"ts": "timestamp", "o": "open",
115
- "h": "high", "l": "low",
116
- "c": "close"}, inplace=True)
117
- all_data.append(df_chunk)
118
-
119
- if len(data) < 300:
120
- break
121
-
122
- if not all_data:
123
- return pd.DataFrame()
124
-
125
- df_all = pd.concat(all_data)
126
-
127
- # Convert timestamps to datetime and calculate indicators
128
- df_all["timestamp"] = pd.to_datetime(df_all["timestamp"], unit="ms")
129
- numeric_cols = ["open", "high", "low", "close"]
130
- df_all[numeric_cols] = df_all[numeric_cols].astype(float)
131
- df_all = calculate_technical_indicators(df_all)
132
-
133
- return df_all
134
-
135
- # Prepare data for Prophet forecasting
136
  def prepare_data_for_prophet(df):
 
137
  if df.empty:
138
  return pd.DataFrame(columns=["ds", "y"])
139
  df_prophet = df.rename(columns={"timestamp": "ds", "close": "y"})
140
  return df_prophet[["ds", "y"]]
141
 
142
- # Perform forecasting using Prophet
143
  def prophet_forecast(df_prophet, periods=10, freq="h", daily_seasonality=False, weekly_seasonality=False, yearly_seasonality=False, seasonality_mode="additive", changepoint_prior_scale=0.05):
 
144
  if df_prophet.empty:
145
  return pd.DataFrame(), "No data for Prophet."
146
-
147
  try:
148
  model = Prophet(
149
  daily_seasonality=daily_seasonality,
@@ -159,8 +101,8 @@ def prophet_forecast(df_prophet, periods=10, freq="h", daily_seasonality=False,
159
  except Exception as e:
160
  return pd.DataFrame(), f"Forecast error: {e}"
161
 
162
- # Wrapper function for forecasting
163
  def prophet_wrapper(df_prophet, forecast_steps, freq, daily_seasonality, weekly_seasonality, yearly_seasonality, seasonality_mode, changepoint_prior_scale):
 
164
  if len(df_prophet) < 10:
165
  return pd.DataFrame(), "Not enough data for forecasting (need >=10 rows)."
166
 
@@ -180,8 +122,8 @@ def prophet_wrapper(df_prophet, forecast_steps, freq, daily_seasonality, weekly_
180
  future_only = full_forecast.loc[len(df_prophet):, ["ds", "yhat", "yhat_lower", "yhat_upper"]]
181
  return future_only, ""
182
 
183
- # Create forecast plot
184
  def create_forecast_plot(forecast_df):
 
185
  if forecast_df.empty:
186
  return go.Figure()
187
 
@@ -222,44 +164,39 @@ def create_forecast_plot(forecast_df):
222
  )
223
  return fig
224
 
225
- # Function to display forecast and technical analysis charts
226
- def display_forecast(symbol, timeframe, forecast_steps, total_candles, daily_seasonality, weekly_seasonality, yearly_seasonality, seasonality_mode, changepoint_prior_scale):
227
- df_raw, forecast_df, error = predict(
228
- symbol=symbol,
229
- timeframe=timeframe,
230
- forecast_steps=forecast_steps,
231
- total_candles=total_candles,
232
- daily_seasonality=daily_seasonality,
233
- weekly_seasonality=weekly_seasonality,
234
- yearly_seasonality=yearly_seasonality,
235
- seasonality_mode=seasonality_mode,
236
- changepoint_prior_scale=changepoint_prior_scale
237
- )
238
-
239
- if error:
240
- return None, None, None, None, pd.DataFrame() # Return empty dataframe for forecast_df
241
-
242
- forecast_plot = create_forecast_plot(forecast_df)
243
- tech_plot, rsi_plot, macd_plot = create_technical_charts(df_raw)
244
-
245
- # Prepare forecast data for the Dataframe output
246
- forecast_df_display = forecast_df.loc[:, ["ds", "yhat", "yhat_lower", "yhat_upper"]].copy()
247
- forecast_df_display.rename(columns={"ds": "Date", "yhat": "Forecast", "yhat_lower": "Lower Bound", "yhat_upper": "Upper Bound"}, inplace=True)
248
-
249
- return forecast_plot, tech_plot, rsi_plot, macd_plot, forecast_df_display
250
-
251
- # Main prediction function
252
- def predict(symbol, timeframe, forecast_steps, total_candles, daily_seasonality, weekly_seasonality, yearly_seasonality, seasonality_mode, changepoint_prior_scale):
253
- okx_bar = TIMEFRAME_MAPPING.get(timeframe, "1H")
254
- df_raw = fetch_okx_candles(symbol=symbol, timeframe=okx_bar, total=total_candles)
255
 
256
- if df_raw.empty:
257
- return pd.DataFrame(), pd.DataFrame(), "No data fetched."
258
-
259
- df_prophet = prepare_data_for_prophet(df_raw)
260
- freq = "h" if "h" in timeframe.lower() else "d"
 
 
 
 
 
 
 
 
261
 
262
- future_df, err2 = prophet_wrapper(
 
 
 
 
 
 
 
 
 
 
 
 
263
  df_prophet,
264
  forecast_steps,
265
  freq,
@@ -269,112 +206,86 @@ def predict(symbol, timeframe, forecast_steps, total_candles, daily_seasonality,
269
  seasonality_mode,
270
  changepoint_prior_scale,
271
  )
272
-
273
- if err2:
274
- return pd.DataFrame(), pd.DataFrame(), err2
275
-
276
- return df_raw, future_df, ""
277
-
278
-
279
- # Main Gradio app setup
280
- def main():
281
- symbols = fetch_okx_symbols()
282
-
283
- with gr.Blocks(theme=gr.themes.Base()) as demo:
284
- # Header
285
- with gr.Row():
286
- gr.Markdown("# CryptoVision")
287
-
288
- # Market Selection and Forecast Parameters
289
- with gr.Row():
290
- with gr.Column(scale=1):
291
- gr.Markdown("### Market Selection")
292
- symbol_dd = gr.Dropdown(
293
- label="Trading Pair",
294
- choices=symbols,
295
- value="BTC-USDT"
296
- )
297
- timeframe_dd = gr.Dropdown(
298
- label="Timeframe",
299
- choices=list(TIMEFRAME_MAPPING.keys()),
300
- value="1h"
301
- )
302
- with gr.Column(scale=1):
303
- gr.Markdown("### Forecast Parameters")
304
- forecast_steps_slider = gr.Slider(
305
- label="Forecast Steps",
306
- minimum=1,
307
- maximum=100,
308
- value=24,
309
- step=1
310
- )
311
- total_candles_slider = gr.Slider(
312
- label="Historical Candles",
313
- minimum=300,
314
- maximum=3000,
315
- value=2000,
316
- step=100
317
- )
318
-
319
- # Advanced Settings
320
- with gr.Row():
321
- with gr.Column():
322
- gr.Markdown("### Advanced Settings")
323
- daily_box = gr.Checkbox(label="Daily Seasonality", value=True)
324
- weekly_box = gr.Checkbox(label="Weekly Seasonality", value=True)
325
- yearly_box = gr.Checkbox(label="Yearly Seasonality", value=False)
326
- seasonality_mode_dd = gr.Dropdown(
327
- label="Seasonality Mode",
328
- choices=["additive", "multiplicative"],
329
- value="additive"
330
- )
331
- changepoint_scale_slider = gr.Slider(
332
- label="Changepoint Prior Scale",
333
- minimum=0.01,
334
- maximum=1.0,
335
- step=0.01,
336
- value=0.05
337
- )
338
-
339
- # Generate Forecast Button
340
- forecast_btn = gr.Button("Generate Forecast", variant="primary", size="lg")
341
-
342
- # Output Plots
343
- with gr.Row():
344
- forecast_plot = gr.Plot(label="Price Forecast")
345
-
346
- with gr.Row():
347
- tech_plot = gr.Plot(label="Technical Analysis")
348
- rsi_plot = gr.Plot(label="RSI Indicator")
349
-
350
- with gr.Row():
351
- macd_plot = gr.Plot(label="MACD")
352
-
353
- # Output Data Table
354
- forecast_df = gr.Dataframe(
355
- label="Forecast Data",
356
- headers=["Date", "Forecast", "Lower Bound", "Upper Bound"]
357
- )
358
 
359
- # Button click functionality
360
- forecast_btn.click(
361
- fn=display_forecast,
362
- inputs=[
363
- symbol_dd,
364
- timeframe_dd,
365
- forecast_steps_slider,
366
- total_candles_slider,
367
- daily_box,
368
- weekly_box,
369
- yearly_box,
370
- seasonality_mode_dd,
371
- changepoint_scale_slider,
372
- ],
373
- outputs=[forecast_plot, tech_plot, rsi_plot, macd_plot, forecast_df]
374
- )
375
 
376
- return demo
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
377
 
378
  if __name__ == "__main__":
379
- app = main()
380
- app.launch()
 
5
  import plotly.graph_objs as go
6
  import math
7
  import numpy as np
8
+ from data_fetcher import fetch_crypto_data, fetch_stock_data, fetch_sentiment_data # Import the data fetcher module
9
+ from src.model import train_model, predict_growth # Import your model functions
10
 
11
+ # --- Replace with your Alpha Vantage API key ---
12
+ ALPHA_VANTAGE_API_KEY = "YOUR_ALPHA_VANTAGE_API_KEY" # <--- Replace with your key
13
+
14
+ # --- Constants ---
15
+ CRYPTO_SYMBOLS = ["BTCUSDT", "ETHUSDT"]
16
+ STOCK_SYMBOLS = ["AAPL", "MSFT"]
17
+ INTERVAL_OPTIONS = ["1h", "60min"] # Consistent naming
18
+
19
+ # --- Technical Analysis Functions ---
 
 
 
 
 
 
 
 
 
 
20
  def calculate_technical_indicators(df):
21
+ """Calculates RSI, MACD, and Bollinger Bands."""
22
+ if df.empty:
23
+ return df
24
+
25
  # RSI Calculation
26
  delta = df['close'].diff()
27
  gain = (delta.where(delta > 0, 0)).rolling(window=14).mean()
28
  loss = (-delta.where(delta < 0, 0)).rolling(window=14).mean()
29
  rs = gain / loss
30
  df['RSI'] = 100 - (100 / (1 + rs))
31
+
32
  # MACD Calculation
33
  exp1 = df['close'].ewm(span=12, adjust=False).mean()
34
  exp2 = df['close'].ewm(span=26, adjust=False).mean()
35
  df['MACD'] = exp1 - exp2
36
  df['Signal_Line'] = df['MACD'].ewm(span=9, adjust=False).mean()
37
+
38
  # Bollinger Bands Calculation
39
  df['MA20'] = df['close'].rolling(window=20).mean()
40
  df['BB_upper'] = df['MA20'] + 2 * df['close'].rolling(window=20).std()
41
  df['BB_lower'] = df['MA20'] - 2 * df['close'].rolling(window=20).std()
42
+
43
  return df
44
 
 
45
  def create_technical_charts(df):
46
+ """Creates technical analysis charts (Price, RSI, MACD)."""
47
+ if df.empty:
48
+ return None, None, None
49
+
50
  fig1 = go.Figure()
51
  fig1.add_trace(go.Candlestick(
52
  x=df['timestamp'],
 
60
  fig1.add_trace(go.Scatter(x=df['timestamp'], y=df['BB_lower'], name='Lower BB', line=dict(color='gray', dash='dash')))
61
  fig1.update_layout(title='Price and Bollinger Bands', xaxis_title='Date', yaxis_title='Price')
62
 
 
63
  fig2 = go.Figure()
64
  fig2.add_trace(go.Scatter(x=df['timestamp'], y=df['RSI'], name='RSI'))
65
  fig2.add_hline(y=70, line_dash="dash", line_color="red")
66
  fig2.add_hline(y=30, line_dash="dash", line_color="green")
67
  fig2.update_layout(title='RSI Indicator', xaxis_title='Date', yaxis_title='RSI')
68
 
 
69
  fig3 = go.Figure()
70
  fig3.add_trace(go.Scatter(x=df['timestamp'], y=df['MACD'], name='MACD'))
71
  fig3.add_trace(go.Scatter(x=df['timestamp'], y=df['Signal_Line'], name='Signal Line'))
 
73
 
74
  return fig1, fig2, fig3
75
 
76
+ # --- Prophet Forecasting Functions ---
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
77
  def prepare_data_for_prophet(df):
78
+ """Prepares data for Prophet."""
79
  if df.empty:
80
  return pd.DataFrame(columns=["ds", "y"])
81
  df_prophet = df.rename(columns={"timestamp": "ds", "close": "y"})
82
  return df_prophet[["ds", "y"]]
83
 
 
84
  def prophet_forecast(df_prophet, periods=10, freq="h", daily_seasonality=False, weekly_seasonality=False, yearly_seasonality=False, seasonality_mode="additive", changepoint_prior_scale=0.05):
85
+ """Performs Prophet forecasting."""
86
  if df_prophet.empty:
87
  return pd.DataFrame(), "No data for Prophet."
88
+
89
  try:
90
  model = Prophet(
91
  daily_seasonality=daily_seasonality,
 
101
  except Exception as e:
102
  return pd.DataFrame(), f"Forecast error: {e}"
103
 
 
104
  def prophet_wrapper(df_prophet, forecast_steps, freq, daily_seasonality, weekly_seasonality, yearly_seasonality, seasonality_mode, changepoint_prior_scale):
105
+ """Wrapper for Prophet forecasting."""
106
  if len(df_prophet) < 10:
107
  return pd.DataFrame(), "Not enough data for forecasting (need >=10 rows)."
108
 
 
122
  future_only = full_forecast.loc[len(df_prophet):, ["ds", "yhat", "yhat_lower", "yhat_upper"]]
123
  return future_only, ""
124
 
 
125
  def create_forecast_plot(forecast_df):
126
+ """Creates the forecast plot."""
127
  if forecast_df.empty:
128
  return go.Figure()
129
 
 
164
  )
165
  return fig
166
 
167
+ # --- Main Prediction and Display Function ---
168
+ def analyze_market(market_type, symbol, interval, forecast_steps, daily_seasonality, weekly_seasonality, yearly_seasonality, seasonality_mode, changepoint_prior_scale):
169
+ """Main function to orchestrate data fetching, analysis, and prediction."""
170
+ df = pd.DataFrame()
171
+ error_message = ""
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
172
 
173
+ # 1. Data Fetching
174
+ if market_type == "Crypto":
175
+ try:
176
+ df = fetch_crypto_data(symbol)
177
+ except Exception as e:
178
+ error_message = f"Error fetching crypto data: {e}"
179
+ elif market_type == "Stock":
180
+ try:
181
+ df = fetch_stock_data(symbol)
182
+ except Exception as e:
183
+ error_message = f"Error fetching stock data: {e}"
184
+ else:
185
+ error_message = "Invalid market type selected."
186
 
187
+ if df.empty:
188
+ return None, None, None, None, None, "", error_message # Correctly pass the error message
189
+
190
+ # 2. Preprocessing & Technical Analysis
191
+ df["timestamp"] = pd.to_datetime(df["timestamp"]) # No unit arg as it's handled in fetcher
192
+ numeric_cols = ["open", "high", "low", "close", "volume"]
193
+ df[numeric_cols] = df[numeric_cols].astype(float)
194
+ df = calculate_technical_indicators(df)
195
+
196
+ # 3. Prophet Forecasting
197
+ df_prophet = prepare_data_for_prophet(df)
198
+ freq = "h" if interval == "1h" or interval == "60min" else "d" #dynamic freq
199
+ forecast_df, prophet_error = prophet_wrapper(
200
  df_prophet,
201
  forecast_steps,
202
  freq,
 
206
  seasonality_mode,
207
  changepoint_prior_scale,
208
  )
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
209
 
210
+ if prophet_error:
211
+ error_message = f"Prophet Error: {prophet_error}"
212
+ return None, None, None, None, None, "", error_message #Return error
213
+
214
+ forecast_plot = create_forecast_plot(forecast_df)
 
 
 
 
 
 
 
 
 
 
 
215
 
216
+ # 4. Create the Charts
217
+ tech_plot, rsi_plot, macd_plot = create_technical_charts(df)
218
+
219
+ # 5. Model Training and Prediction (simplified)
220
+ try:
221
+ train_model(df.copy()) # Train on a copy to avoid modifying original df.
222
+ if not df.empty: #Check if dataframe is empty or not.
223
+ latest_data = df[["close", "volume"]].iloc[-1].values # Get the last row for prediction.
224
+ growth_prediction = predict_growth(latest_data)
225
+ growth_label = "Yes" if growth_prediction[0] == 1 else "No"
226
+ else:
227
+ growth_label = "N/A: Insufficient Data" # If there is no data to predict the growth.
228
+
229
+ except Exception as e:
230
+ error_message = f"Model Error: {e}"
231
+ growth_label = "N/A"
232
+
233
+ # Prepare forecast data for the Dataframe output
234
+ forecast_df_display = forecast_df.loc[:, ["ds", "yhat", "yhat_lower", "yhat_upper"]].copy()
235
+ forecast_df_display.rename(columns={"ds": "Date", "yhat": "Forecast", "yhat_lower": "Lower Bound", "yhat_upper": "Upper Bound"}, inplace=True)
236
+
237
+ return forecast_plot, tech_plot, rsi_plot, macd_plot, forecast_df_display, growth_label, error_message #Return error
238
+ # --- Gradio Interface ---
239
+ with gr.Blocks(theme=gr.themes.Base()) as demo:
240
+ gr.Markdown("# Market Analysis and Prediction")
241
+
242
+ with gr.Row():
243
+ with gr.Column():
244
+ market_type_dd = gr.Radio(label="Market Type", choices=["Crypto", "Stock"], value="Crypto")
245
+ symbol_dd = gr.Dropdown(label="Symbol", choices=CRYPTO_SYMBOLS, value="BTCUSDT") # Start with Crypto
246
+ interval_dd = gr.Dropdown(label="Interval", choices=INTERVAL_OPTIONS, value="1h")
247
+ forecast_steps_slider = gr.Slider(label="Forecast Steps", minimum=1, maximum=100, value=24, step=1)
248
+ daily_box = gr.Checkbox(label="Daily Seasonality", value=True)
249
+ weekly_box = gr.Checkbox(label="Weekly Seasonality", value=True)
250
+ yearly_box = gr.Checkbox(label="Yearly Seasonality", value=False)
251
+ seasonality_mode_dd = gr.Dropdown(label="Seasonality Mode", choices=["additive", "multiplicative"], value="additive")
252
+ changepoint_scale_slider = gr.Slider(label="Changepoint Prior Scale", minimum=0.01, maximum=1.0, step=0.01, value=0.05)
253
+
254
+ with gr.Column():
255
+ forecast_plot = gr.Plot(label="Price Forecast")
256
+ with gr.Row():
257
+ tech_plot = gr.Plot(label="Technical Analysis")
258
+ rsi_plot = gr.Plot(label="RSI Indicator")
259
+ with gr.Row():
260
+ macd_plot = gr.Plot(label="MACD")
261
+ forecast_df = gr.Dataframe(label="Forecast Data", headers=["Date", "Forecast", "Lower Bound", "Upper Bound"])
262
+ growth_label_output = gr.Label(label="Explosive Growth Prediction") # Added for prediction.
263
+
264
+ # Event Listener to update symbol dropdown based on market type
265
+ def update_symbol_choices(market_type):
266
+ if market_type == "Crypto":
267
+ return gr.Dropdown(choices=CRYPTO_SYMBOLS, value="BTCUSDT")
268
+ elif market_type == "Stock":
269
+ return gr.Dropdown(choices=STOCK_SYMBOLS, value="AAPL") # Default to AAPL for stock
270
+ return gr.Dropdown(choices=[], value=None) # Shouldn't happen, but safety check
271
+ market_type_dd.change(fn=update_symbol_choices, inputs=[market_type_dd], outputs=[symbol_dd])
272
+
273
+ analyze_button = gr.Button("Analyze Market", variant="primary")
274
+ analyze_button.click(
275
+ fn=analyze_market,
276
+ inputs=[
277
+ market_type_dd,
278
+ symbol_dd,
279
+ interval_dd,
280
+ forecast_steps_slider,
281
+ daily_box,
282
+ weekly_box,
283
+ yearly_box,
284
+ seasonality_mode_dd,
285
+ changepoint_scale_slider,
286
+ ],
287
+ outputs=[forecast_plot, tech_plot, rsi_plot, macd_plot, forecast_df, growth_label_output]
288
+ )
289
 
290
  if __name__ == "__main__":
291
+ demo.launch()