S-Dreamer commited on
Commit
e1d4db9
·
verified ·
1 Parent(s): 3898efa

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +103 -140
app.py CHANGED
@@ -1,186 +1,149 @@
1
  #!/usr/bin/env python3
2
  # -*- coding: utf-8 -*-
3
  """
4
- app.py
5
- Crypto & Stock Prediction Dashboard
6
- Using Chronos AI (ZeroGPU) or Technical Analysis
7
  """
8
 
9
- import numpy as np
10
- import pandas as pd
11
  import yfinance as yf
 
 
12
  import plotly.graph_objects as go
13
  from plotly.subplots import make_subplots
14
  import gradio as gr
 
 
15
 
16
  # ------------------------
17
- # Data Retrieval
18
  # ------------------------
19
- def get_historical_data(symbol: str, timeframe: str, period: str = "1y") -> pd.DataFrame:
20
- """
21
- Fetch historical OHLCV data and compute returns, RSI, MACD.
22
- """
23
- df = yf.download(symbol, period=period, interval=timeframe)
24
- df.dropna(inplace=True)
25
- df['Returns'] = df['Close'].pct_change()
26
- # Technical indicators
27
- df['RSI'] = 100 - (100 / (1 + df['Returns'].rolling(14).mean() / df['Returns'].rolling(14).std()))
28
- df['MACD'] = df['Close'].ewm(span=12, adjust=False).mean() - df['Close'].ewm(span=26, adjust=False).mean()
29
- df['MACD_Signal'] = df['MACD'].ewm(span=9, adjust=False).mean()
30
- # Dummy market info columns
31
- df['Market_Cap'] = np.nan
32
- df['Sector'] = "N/A"
33
- df['Industry'] = "N/A"
34
- df['Dividend_Yield'] = np.nan
35
- df['Annualized_Vol'] = df['Returns'].rolling(252).std() * np.sqrt(252)
36
- df['Max_Drawdown'] = (df['Close'].cummax() - df['Close']) / df['Close'].cummax()
37
- return df
38
 
39
  # ------------------------
40
- # Prediction Logic
41
  # ------------------------
42
- def make_prediction(symbol: str, timeframe: str, prediction_days: int, strategy: str):
43
- try:
44
- df = get_historical_data(symbol, timeframe)
45
- returns = df['Returns'].dropna()
46
-
47
- if strategy == "chronos":
48
- try:
49
- # Use ZeroGPU / CPU-compatible Chronos (mocked)
50
- mean_pred = returns[-prediction_days:].values
51
- std_pred = returns[-prediction_days:].std() * np.ones_like(mean_pred)
52
-
53
- actual_len = len(mean_pred)
54
- if actual_len < prediction_days:
55
- last_pred = mean_pred[-1]
56
- last_std = std_pred[-1]
57
- extension = last_pred * (1 + np.random.normal(0, last_std, prediction_days - actual_len))
58
- mean_pred = np.concatenate([mean_pred, extension])
59
- std_pred = np.concatenate([std_pred, np.full(prediction_days - actual_len, last_std)])
60
-
61
- # Denormalize predictions
62
- mean_pred = mean_pred * returns.std() + returns.mean()
63
-
64
- # Convert returns to price predictions
65
- last_price = df['Close'].iloc[-1]
66
- price_predictions = [last_price]
67
- for ret in mean_pred:
68
- price_predictions.append(price_predictions[-1] * (1 + ret))
69
- price_predictions = np.array(price_predictions[1:])
70
-
71
- # Confidence intervals
72
- upper_bound = price_predictions * (1 + 1.96 * std_pred)
73
- lower_bound = price_predictions * (1 - 1.96 * std_pred)
74
-
75
- except Exception:
76
- strategy = "technical"
77
-
78
- if strategy == "technical":
79
- last_price = df['Close'].iloc[-1]
80
- avg_return = df['Returns'].mean()
81
- price_predictions = [last_price * (1 + avg_return) ** i for i in range(1, prediction_days + 1)]
82
- price_predictions = np.array(price_predictions)
83
- upper_bound = price_predictions * 1.1
84
- lower_bound = price_predictions * 0.9
85
-
86
- # Prediction dates
87
- last_date = df.index[-1]
88
- freq = "D" if timeframe == "1d" else ("H" if timeframe == "1h" else "15T")
89
- future_dates = pd.date_range(start=last_date + pd.Timedelta(1, freq=freq), periods=prediction_days, freq=freq)
90
-
91
- predictions = {
92
- "dates": future_dates,
93
- "mean": price_predictions,
94
- "upper": upper_bound,
95
- "lower": lower_bound,
96
- "strategy": strategy
97
- }
98
-
99
- fig = create_prediction_plot(df, predictions, symbol, timeframe)
100
- return predictions, fig
101
 
102
- except Exception as e:
103
- raise Exception(f"Prediction failed: {str(e)}")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
104
 
105
  # ------------------------
106
- # Plotting
107
  # ------------------------
108
- def create_prediction_plot(df: pd.DataFrame, predictions: dict, symbol: str, timeframe: str) -> go.Figure:
109
  fig = make_subplots(
110
  rows=2, cols=1,
111
  subplot_titles=('Price Prediction', 'Technical Indicators'),
112
- vertical_spacing=0.1,
113
  row_width=[0.3, 0.7]
114
  )
115
- # Historical price
116
- fig.add_trace(go.Scatter(x=df.index, y=df['Close'], name='Historical Price', line=dict(color='#1f77b4')), row=1, col=1)
117
- # Predicted mean
118
- fig.add_trace(go.Scatter(x=predictions['dates'], y=predictions['mean'], name='Predicted Mean', line=dict(color='#ff7f0e')), row=1, col=1)
119
- # Confidence interval
 
120
  fig.add_trace(go.Scatter(
121
- x=predictions['dates'].tolist() + predictions['dates'].tolist()[::-1],
122
- y=predictions['upper'].tolist() + predictions['lower'].tolist()[::-1],
123
- fill='toself',
124
- fillcolor='rgba(255,127,14,0.2)',
125
- line=dict(color='rgba(255,255,255,0)'),
126
- name='Confidence Interval'
127
  ), row=1, col=1)
128
- # Technical indicators
129
- fig.add_trace(go.Scatter(x=df.index, y=df['RSI'], name='RSI', line=dict(color='#2ca02c')), row=2, col=1)
130
- fig.add_trace(go.Scatter(x=df.index, y=df['MACD'], name='MACD', line=dict(color='#d62728')), row=2, col=1)
131
- fig.add_trace(go.Scatter(x=df.index, y=df['MACD_Signal'], name='MACD Signal', line=dict(color='#9467bd')), row=2, col=1)
132
 
133
- fig.update_layout(height=800, title_text=f"{symbol} Price Prediction ({timeframe}) - Using {predictions['strategy'].upper()} Strategy", showlegend=True)
 
 
 
 
 
 
 
 
 
134
  fig.update_yaxes(title_text="Price ($)", row=1, col=1)
135
  fig.update_yaxes(title_text="Indicator Value", row=2, col=1)
136
  return fig
137
 
138
  # ------------------------
139
- # Trading Signals (dummy)
140
- # ------------------------
141
- def calculate_trading_signals(df: pd.DataFrame) -> dict:
142
- signals = {}
143
- signals['Buy'] = df.index[df['RSI'] < 30].tolist()
144
- signals['Sell'] = df.index[df['RSI'] > 70].tolist()
145
- return signals
146
-
147
- # ------------------------
148
- # Gradio Interface
149
  # ------------------------
150
  def create_dashboard():
151
- with gr.Blocks(title="Crypto & Stock Predictor") as demo:
152
- gr.Markdown("# 📈 Crypto & Stock Prediction Dashboard")
153
- gr.Markdown("Predict future prices using Chronos AI or technical analysis")
154
  with gr.Row():
155
  with gr.Column(scale=1):
156
- symbol = gr.Textbox(label="Symbol", value="BTC-USD")
157
- timeframe = gr.Dropdown(label="Timeframe", choices=["1d", "1h", "15m"], value="1d")
158
- prediction_days = gr.Slider(label="Prediction Days", minimum=1, maximum=30, value=7, step=1)
159
- strategy = gr.Dropdown(label="Strategy", choices=["chronos", "technical"], value="chronos")
160
  btn_predict = gr.Button("Predict", variant="primary")
 
161
  with gr.Column(scale=2):
162
- plot = gr.Plot(label="Prediction Results")
163
- info = gr.JSON(label="Market Data")
164
- signals = gr.JSON(label="Trading Signals")
165
-
166
- @btn_predict.click(inputs=[symbol, timeframe, prediction_days, strategy], outputs=[plot, info, signals])
167
- def update_dashboard(symbol, timeframe, prediction_days, strategy):
 
 
 
168
  df = get_historical_data(symbol, timeframe)
169
- predictions, fig = make_prediction(symbol, timeframe, prediction_days, strategy)
170
- trading_signals = calculate_trading_signals(df)
171
- market_info = {
 
 
 
172
  "Current Price": f"${df['Close'].iloc[-1]:.2f}",
173
- "Market Cap": "N/A",
174
- "Sector": df['Sector'].iloc[-1],
175
- "Industry": df['Industry'].iloc[-1],
176
- "Dividend Yield": "N/A",
177
- "Volatility (Annualized)": f"{df['Annualized_Vol'].iloc[-1]*100:.2f}%",
178
- "Max Drawdown": f"{df['Max_Drawdown'].iloc[-1]*100:.2f}%"
179
  }
180
- return fig, market_info, trading_signals
 
181
 
182
  return demo
183
 
184
  if __name__ == "__main__":
185
  demo = create_dashboard()
186
- demo.launch(server_name="0.0.0.0", server_port=7860, share=False)
 
1
  #!/usr/bin/env python3
2
  # -*- coding: utf-8 -*-
3
  """
4
+ app.py - Enhanced Crypto & Stock Predictor with intuitive UI/UX
 
 
5
  """
6
 
7
+ import ccxt
 
8
  import yfinance as yf
9
+ import pandas as pd
10
+ import numpy as np
11
  import plotly.graph_objects as go
12
  from plotly.subplots import make_subplots
13
  import gradio as gr
14
+ from ta.momentum import RSIIndicator
15
+ from ta.trend import MACD
16
 
17
  # ------------------------
18
+ # Data Fetching
19
  # ------------------------
20
+ def get_historical_data(symbol: str, timeframe: str = "1d", limit: int = 200) -> pd.DataFrame:
21
+ """Fetch historical OHLCV data using CCXT (crypto) or yfinance (stocks)."""
22
+ try:
23
+ if "/" in symbol:
24
+ exchange = ccxt.binance()
25
+ ohlcv = exchange.fetch_ohlcv(symbol, timeframe, limit=limit)
26
+ df = pd.DataFrame(ohlcv, columns=["timestamp", "Open", "High", "Low", "Close", "Volume"])
27
+ df['timestamp'] = pd.to_datetime(df['timestamp'], unit='ms')
28
+ df.set_index('timestamp', inplace=True)
29
+ else:
30
+ df = yf.download(symbol, period="1y", interval=timeframe)
31
+ df['Returns'] = df['Close'].pct_change().fillna(0)
32
+ return df
33
+ except Exception as e:
34
+ raise Exception(f"Data fetch failed for {symbol}: {str(e)}")
 
 
 
 
35
 
36
  # ------------------------
37
+ # Indicators
38
  # ------------------------
39
+ def add_indicators(df: pd.DataFrame) -> pd.DataFrame:
40
+ df['SMA20'] = df['Close'].rolling(20).mean()
41
+ df['SMA50'] = df['Close'].rolling(50).mean()
42
+ df['Signal'] = np.where(df['SMA20'] > df['SMA50'], 'Buy', 'Sell')
43
+ df['RSI'] = RSIIndicator(df['Close'], window=14).rsi()
44
+ macd = MACD(df['Close'], window_slow=26, window_fast=12, window_sign=9)
45
+ df['MACD'] = macd.macd()
46
+ df['MACD_Signal'] = macd.macd_signal()
47
+ return df
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
48
 
49
+ # ------------------------
50
+ # Chronos AI Prediction
51
+ # ------------------------
52
+ def make_chronos_prediction(df: pd.DataFrame, prediction_days: int = 7) -> dict:
53
+ """Simulated Chronos AI predictions with confidence intervals."""
54
+ returns = df['Returns'].values
55
+ mean_pred = np.random.normal(np.mean(returns), np.std(returns), prediction_days)
56
+ std_pred = np.full(prediction_days, np.std(returns))
57
+
58
+ mean_pred = mean_pred * df['Close'].std() + df['Close'].mean()
59
+ last_price = df['Close'].iloc[-1]
60
+ price_predictions = [last_price]
61
+ for ret in mean_pred:
62
+ price_predictions.append(price_predictions[-1] * (1 + ret))
63
+ price_predictions = np.array(price_predictions[1:])
64
+
65
+ upper_bound = price_predictions * (1 + 1.96 * std_pred)
66
+ lower_bound = price_predictions * (1 - 1.96 * std_pred)
67
+
68
+ return {"mean": price_predictions, "upper": upper_bound, "lower": lower_bound}
69
 
70
  # ------------------------
71
+ # Plotly Figure
72
  # ------------------------
73
+ def create_prediction_plot(df: pd.DataFrame, predictions: dict, prediction_days: int) -> go.Figure:
74
  fig = make_subplots(
75
  rows=2, cols=1,
76
  subplot_titles=('Price Prediction', 'Technical Indicators'),
77
+ vertical_spacing=0.15,
78
  row_width=[0.3, 0.7]
79
  )
80
+
81
+ fig.add_trace(go.Scatter(x=df.index, y=df['Close'], name='Historical Price', line=dict(color='blue')), row=1, col=1)
82
+
83
+ future_dates = pd.date_range(start=df.index[-1] + pd.Timedelta(1, unit='D'), periods=prediction_days)
84
+ fig.add_trace(go.Scatter(x=future_dates, y=predictions['mean'], name='Predicted Price', line=dict(color='orange', width=3)), row=1, col=1)
85
+
86
  fig.add_trace(go.Scatter(
87
+ x=list(future_dates) + list(future_dates[::-1]),
88
+ y=list(predictions['upper']) + list(predictions['lower'][::-1]),
89
+ fill='toself', fillcolor='rgba(255,127,14,0.2)',
90
+ line=dict(color='rgba(255,255,255,0)'), name='Confidence Interval'
 
 
91
  ), row=1, col=1)
 
 
 
 
92
 
93
+ fig.add_trace(go.Scatter(x=df.index, y=df['RSI'], name='RSI', line=dict(color='green')), row=2, col=1)
94
+ fig.add_trace(go.Scatter(x=df.index, y=df['MACD'], name='MACD', line=dict(color='red')), row=2, col=1)
95
+ fig.add_trace(go.Scatter(x=df.index, y=df['MACD_Signal'], name='MACD Signal', line=dict(color='purple')), row=2, col=1)
96
+
97
+ fig.update_layout(
98
+ title="📊 Price & Technical Predictions",
99
+ height=800,
100
+ showlegend=True,
101
+ template="plotly_dark"
102
+ )
103
  fig.update_yaxes(title_text="Price ($)", row=1, col=1)
104
  fig.update_yaxes(title_text="Indicator Value", row=2, col=1)
105
  return fig
106
 
107
  # ------------------------
108
+ # Gradio Dashboard (Improved UX)
 
 
 
 
 
 
 
 
 
109
  # ------------------------
110
  def create_dashboard():
111
+ with gr.Blocks(title="📈 Crypto & Stock Predictor") as demo:
 
 
112
  with gr.Row():
113
  with gr.Column(scale=1):
114
+ gr.Markdown("## Input Parameters")
115
+ symbol = gr.Textbox(label="Symbol", value="BTC/USDT", placeholder="e.g., BTC/USDT or AAPL", info="Enter crypto pair or stock symbol")
116
+ timeframe = gr.Dropdown(label="Timeframe", choices=["1d", "1h", "15m"], value="1d", info="Select candle timeframe")
117
+ prediction_days = gr.Slider(label="Prediction Days", minimum=1, maximum=30, value=7, step=1, info="How many days to predict")
118
  btn_predict = gr.Button("Predict", variant="primary")
119
+
120
  with gr.Column(scale=2):
121
+ with gr.Tab("Predictions"):
122
+ plot = gr.Plot(label="Prediction Plot")
123
+ with gr.Tab("Signals"):
124
+ signals_table = gr.Dataframe(label="SMA Signals", headers=["SMA20","SMA50","Signal"], interactive=False)
125
+ with gr.Tab("Market Info"):
126
+ market_info = gr.JSON(label="Market Info")
127
+
128
+ @btn_predict.click(inputs=[symbol, timeframe, prediction_days], outputs=[plot, signals_table, market_info])
129
+ def update_dashboard(symbol, timeframe, prediction_days):
130
  df = get_historical_data(symbol, timeframe)
131
+ df = add_indicators(df)
132
+ predictions = make_chronos_prediction(df, prediction_days)
133
+ fig = create_prediction_plot(df, predictions, prediction_days)
134
+ signals_data = df[['SMA20','SMA50','Signal']].tail(prediction_days)
135
+
136
+ info = {
137
  "Current Price": f"${df['Close'].iloc[-1]:.2f}",
138
+ "RSI": f"{df['RSI'].iloc[-1]:.2f}",
139
+ "MACD": f"{df['MACD'].iloc[-1]:.2f}",
140
+ "MACD Signal": f"{df['MACD_Signal'].iloc[-1]:.2f}"
 
 
 
141
  }
142
+
143
+ return fig, signals_data, info
144
 
145
  return demo
146
 
147
  if __name__ == "__main__":
148
  demo = create_dashboard()
149
+ demo.launch(server_name="0.0.0.0", server_port=7860)