Spaces:
Running
Running
Update app.py
Browse files
app.py
CHANGED
@@ -6,41 +6,32 @@ import numpy as np
|
|
6 |
import tensorflow as tf
|
7 |
from tensorflow.keras.models import Sequential
|
8 |
from tensorflow.keras.layers import Dense, LSTM
|
|
|
9 |
|
10 |
# Define periods
|
11 |
-
|
12 |
-
"1 Month": "1mo",
|
13 |
-
"3 Months": "3mo",
|
14 |
-
"6 Months": "6mo",
|
15 |
-
"1 Year": "1y",
|
16 |
-
"5 Years": "5y",
|
17 |
-
"10 Years": "10y",
|
18 |
"Max": "max"
|
19 |
}
|
20 |
|
21 |
def fetch_data(ticker, period):
|
22 |
-
|
23 |
-
return data
|
24 |
|
25 |
def plot_technical_analysis(ticker, period, analysis_type, ma_length, candle_period):
|
26 |
data = fetch_data(ticker, period)
|
27 |
-
|
28 |
fig = go.Figure()
|
29 |
-
|
30 |
if analysis_type == "Candlestick":
|
31 |
-
fig.add_trace(go.Candlestick(x=data.index,
|
32 |
-
open=data['Open'],
|
33 |
-
high=data['High'],
|
34 |
-
low=data['Low'],
|
35 |
-
close=data['Close'],
|
36 |
-
name='Candlestick',
|
37 |
-
xperiod=candle_period))
|
38 |
-
|
39 |
elif analysis_type == "Moving Average":
|
40 |
data[f'MA{ma_length}'] = data['Close'].rolling(window=ma_length).mean()
|
41 |
fig.add_trace(go.Scatter(x=data.index, y=data['Close'], mode='lines', name='Close Price'))
|
42 |
fig.add_trace(go.Scatter(x=data.index, y=data[f'MA{ma_length}'], mode='lines', name=f'{ma_length}-day MA'))
|
43 |
-
|
44 |
elif analysis_type == "Bollinger Bands":
|
45 |
data['MA20'] = data['Close'].rolling(window=20).mean()
|
46 |
data['stddev'] = data['Close'].rolling(window=20).std()
|
@@ -49,154 +40,118 @@ def plot_technical_analysis(ticker, period, analysis_type, ma_length, candle_per
|
|
49 |
fig.add_trace(go.Scatter(x=data.index, y=data['Close'], mode='lines', name='Close Price'))
|
50 |
fig.add_trace(go.Scatter(x=data.index, y=data['upper'], mode='lines', name='Upper Band'))
|
51 |
fig.add_trace(go.Scatter(x=data.index, y=data['lower'], mode='lines', name='Lower Band'))
|
52 |
-
|
53 |
elif analysis_type == "RSI":
|
54 |
delta = data['Close'].diff(1)
|
55 |
gain = delta.where(delta > 0, 0)
|
56 |
loss = -delta.where(delta < 0, 0)
|
57 |
-
|
58 |
avg_gain = gain.rolling(window=14).mean()
|
59 |
avg_loss = loss.rolling(window=14).mean()
|
60 |
-
|
61 |
rs = avg_gain / avg_loss
|
62 |
rsi = 100 - (100 / (1 + rs))
|
63 |
-
|
64 |
fig.add_trace(go.Scatter(x=data.index, y=rsi, mode='lines', name='RSI'))
|
65 |
-
|
66 |
elif analysis_type == "MACD":
|
67 |
exp1 = data['Close'].ewm(span=12, adjust=False).mean()
|
68 |
exp2 = data['Close'].ewm(span=26, adjust=False).mean()
|
69 |
macd = exp1 - exp2
|
70 |
signal = macd.ewm(span=9, adjust=False).mean()
|
71 |
-
|
72 |
fig.add_trace(go.Scatter(x=data.index, y=macd, mode='lines', name='MACD'))
|
73 |
fig.add_trace(go.Scatter(x=data.index, y=signal, mode='lines', name='Signal Line'))
|
74 |
-
|
75 |
fig.update_layout(title=f"{analysis_type} Analysis for {ticker}", xaxis_title="Date", yaxis_title="Price", xaxis_rangeslider_visible=False)
|
76 |
return fig
|
77 |
|
78 |
def plot_fundamental_analysis(ticker, analysis_type):
|
79 |
stock = yf.Ticker(ticker)
|
80 |
-
|
81 |
if analysis_type == "Financials":
|
82 |
data = stock.financials
|
83 |
elif analysis_type == "Balance Sheet":
|
84 |
data = stock.balance_sheet
|
85 |
elif analysis_type == "Cash Flow":
|
86 |
data = stock.cashflow
|
87 |
-
|
88 |
return data.to_html()
|
89 |
|
90 |
def train_predictive_model(ticker, period, epochs, batch_size, future_days):
|
91 |
data = fetch_data(ticker, period)
|
92 |
data['Close'] = data['Close'].fillna(method='ffill')
|
93 |
-
|
94 |
-
|
95 |
-
close_prices = close_prices.reshape(-1, 1)
|
96 |
-
|
97 |
-
# Normalize the data
|
98 |
-
from sklearn.preprocessing import MinMaxScaler
|
99 |
scaler = MinMaxScaler()
|
100 |
close_prices = scaler.fit_transform(close_prices)
|
101 |
-
|
102 |
-
|
103 |
-
X = []
|
104 |
-
y = []
|
105 |
time_step = 10
|
106 |
for i in range(time_step, len(close_prices) - future_days):
|
107 |
X.append(close_prices[i-time_step:i])
|
108 |
y.append(close_prices[i + future_days])
|
109 |
-
|
110 |
-
|
111 |
-
y = np.array(y)
|
112 |
-
|
113 |
-
# Split the data
|
114 |
split = int(0.8 * len(X))
|
115 |
X_train, X_test = X[:split], X[split:]
|
116 |
y_train, y_test = y[:split], y[split:]
|
117 |
-
|
118 |
-
|
119 |
-
|
120 |
-
|
121 |
-
|
122 |
-
|
123 |
-
|
124 |
-
|
125 |
model.compile(optimizer='adam', loss='mean_squared_error')
|
126 |
-
|
127 |
-
# Train the model
|
128 |
model.fit(X_train, y_train, epochs=epochs, batch_size=batch_size)
|
129 |
-
|
130 |
-
|
131 |
-
predictions = model.predict(X_test)
|
132 |
-
predictions = scaler.inverse_transform(predictions)
|
133 |
y_test = scaler.inverse_transform(y_test)
|
134 |
-
|
135 |
-
# Forecast future values
|
136 |
future_predictions = []
|
137 |
last_data = close_prices[-time_step:]
|
138 |
for _ in range(future_days):
|
139 |
pred = model.predict(last_data.reshape(1, time_step, 1))
|
140 |
future_predictions.append(pred[0, 0])
|
141 |
last_data = np.append(last_data[1:], pred[0])
|
142 |
-
|
143 |
future_predictions = scaler.inverse_transform(np.array(future_predictions).reshape(-1, 1))
|
144 |
-
|
145 |
-
# Plot the results
|
146 |
fig = go.Figure()
|
147 |
fig.add_trace(go.Scatter(x=data.index[-len(y_test):], y=y_test.flatten(), mode='lines', name='Actual'))
|
148 |
fig.add_trace(go.Scatter(x=data.index[-len(predictions):], y=predictions.flatten(), mode='lines', name='Predicted'))
|
149 |
-
|
150 |
future_dates = pd.date_range(start=data.index[-1], periods=future_days + 1, inclusive='right')
|
151 |
-
|
152 |
fig.add_trace(go.Scatter(x=future_dates, y=future_predictions.flatten(), mode='lines', name='Future Predictions'))
|
153 |
-
|
154 |
fig.update_layout(title=f"Predicted vs Actual and Future Forecast for {ticker}", xaxis_title="Date", yaxis_title="Price", xaxis_rangeslider_visible=False)
|
155 |
return fig
|
156 |
|
157 |
# Gradio Interface
|
158 |
with gr.Blocks() as demo:
|
159 |
-
gr.Markdown("#
|
160 |
-
|
161 |
with gr.Tab("Technical Analysis"):
|
162 |
with gr.Row():
|
163 |
ticker = gr.Textbox(label="Ticker Symbol", value="AAPL")
|
164 |
-
period = gr.Dropdown(label="Period", choices=list(
|
165 |
-
|
166 |
-
|
167 |
-
|
168 |
-
|
169 |
-
|
170 |
-
|
171 |
-
|
172 |
-
|
173 |
-
|
174 |
-
)
|
175 |
-
|
176 |
-
|
177 |
-
|
178 |
-
plot_button = gr.Button("Plot")
|
179 |
-
plot_output = gr.Plot()
|
180 |
-
|
181 |
-
plot_button.click(fn=plot_technical_analysis, inputs=[ticker, period, analysis_type, ma_length, candle_period], outputs=plot_output)
|
182 |
-
|
183 |
with gr.Tab("Fundamental Analysis"):
|
184 |
ticker = gr.Textbox(label="Ticker Symbol", value="AAPL")
|
185 |
analysis_type = gr.Radio(label="Analysis Type", choices=["Financials", "Balance Sheet", "Cash Flow"], value="Financials")
|
186 |
plot_button = gr.Button("Show Data")
|
187 |
table_output = gr.HTML()
|
188 |
-
|
189 |
plot_button.click(fn=plot_fundamental_analysis, inputs=[ticker, analysis_type], outputs=table_output)
|
190 |
-
|
191 |
with gr.Tab("Predictive Model"):
|
192 |
ticker = gr.Textbox(label="Ticker Symbol", value="AAPL")
|
193 |
-
period = gr.Dropdown(label="Period", choices=list(
|
194 |
epochs = gr.Number(label="Epochs", value=10)
|
195 |
batch_size = gr.Number(label="Batch Size", value=32)
|
196 |
future_days = gr.Number(label="Days to Predict", value=30)
|
197 |
train_button = gr.Button("Train and Predict")
|
198 |
predict_output = gr.Plot()
|
199 |
-
|
200 |
train_button.click(fn=train_predictive_model, inputs=[ticker, period, epochs, batch_size, future_days], outputs=predict_output)
|
201 |
|
202 |
# Launch the interface
|
|
|
6 |
import tensorflow as tf
|
7 |
from tensorflow.keras.models import Sequential
|
8 |
from tensorflow.keras.layers import Dense, LSTM
|
9 |
+
from sklearn.preprocessing import MinMaxScaler
|
10 |
|
11 |
# Define periods
|
12 |
+
PERIODS = {
|
13 |
+
"1 Month": "1mo",
|
14 |
+
"3 Months": "3mo",
|
15 |
+
"6 Months": "6mo",
|
16 |
+
"1 Year": "1y",
|
17 |
+
"5 Years": "5y",
|
18 |
+
"10 Years": "10y",
|
19 |
"Max": "max"
|
20 |
}
|
21 |
|
22 |
def fetch_data(ticker, period):
|
23 |
+
return yf.download(ticker, period=PERIODS[period])
|
|
|
24 |
|
25 |
def plot_technical_analysis(ticker, period, analysis_type, ma_length, candle_period):
|
26 |
data = fetch_data(ticker, period)
|
|
|
27 |
fig = go.Figure()
|
28 |
+
|
29 |
if analysis_type == "Candlestick":
|
30 |
+
fig.add_trace(go.Candlestick(x=data.index, open=data['Open'], high=data['High'], low=data['Low'], close=data['Close'], name='Candlestick', xperiod=candle_period))
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
31 |
elif analysis_type == "Moving Average":
|
32 |
data[f'MA{ma_length}'] = data['Close'].rolling(window=ma_length).mean()
|
33 |
fig.add_trace(go.Scatter(x=data.index, y=data['Close'], mode='lines', name='Close Price'))
|
34 |
fig.add_trace(go.Scatter(x=data.index, y=data[f'MA{ma_length}'], mode='lines', name=f'{ma_length}-day MA'))
|
|
|
35 |
elif analysis_type == "Bollinger Bands":
|
36 |
data['MA20'] = data['Close'].rolling(window=20).mean()
|
37 |
data['stddev'] = data['Close'].rolling(window=20).std()
|
|
|
40 |
fig.add_trace(go.Scatter(x=data.index, y=data['Close'], mode='lines', name='Close Price'))
|
41 |
fig.add_trace(go.Scatter(x=data.index, y=data['upper'], mode='lines', name='Upper Band'))
|
42 |
fig.add_trace(go.Scatter(x=data.index, y=data['lower'], mode='lines', name='Lower Band'))
|
|
|
43 |
elif analysis_type == "RSI":
|
44 |
delta = data['Close'].diff(1)
|
45 |
gain = delta.where(delta > 0, 0)
|
46 |
loss = -delta.where(delta < 0, 0)
|
|
|
47 |
avg_gain = gain.rolling(window=14).mean()
|
48 |
avg_loss = loss.rolling(window=14).mean()
|
|
|
49 |
rs = avg_gain / avg_loss
|
50 |
rsi = 100 - (100 / (1 + rs))
|
|
|
51 |
fig.add_trace(go.Scatter(x=data.index, y=rsi, mode='lines', name='RSI'))
|
|
|
52 |
elif analysis_type == "MACD":
|
53 |
exp1 = data['Close'].ewm(span=12, adjust=False).mean()
|
54 |
exp2 = data['Close'].ewm(span=26, adjust=False).mean()
|
55 |
macd = exp1 - exp2
|
56 |
signal = macd.ewm(span=9, adjust=False).mean()
|
|
|
57 |
fig.add_trace(go.Scatter(x=data.index, y=macd, mode='lines', name='MACD'))
|
58 |
fig.add_trace(go.Scatter(x=data.index, y=signal, mode='lines', name='Signal Line'))
|
59 |
+
|
60 |
fig.update_layout(title=f"{analysis_type} Analysis for {ticker}", xaxis_title="Date", yaxis_title="Price", xaxis_rangeslider_visible=False)
|
61 |
return fig
|
62 |
|
63 |
def plot_fundamental_analysis(ticker, analysis_type):
|
64 |
stock = yf.Ticker(ticker)
|
|
|
65 |
if analysis_type == "Financials":
|
66 |
data = stock.financials
|
67 |
elif analysis_type == "Balance Sheet":
|
68 |
data = stock.balance_sheet
|
69 |
elif analysis_type == "Cash Flow":
|
70 |
data = stock.cashflow
|
|
|
71 |
return data.to_html()
|
72 |
|
73 |
def train_predictive_model(ticker, period, epochs, batch_size, future_days):
|
74 |
data = fetch_data(ticker, period)
|
75 |
data['Close'] = data['Close'].fillna(method='ffill')
|
76 |
+
close_prices = data['Close'].values.reshape(-1, 1)
|
77 |
+
|
|
|
|
|
|
|
|
|
78 |
scaler = MinMaxScaler()
|
79 |
close_prices = scaler.fit_transform(close_prices)
|
80 |
+
|
81 |
+
X, y = [], []
|
|
|
|
|
82 |
time_step = 10
|
83 |
for i in range(time_step, len(close_prices) - future_days):
|
84 |
X.append(close_prices[i-time_step:i])
|
85 |
y.append(close_prices[i + future_days])
|
86 |
+
X, y = np.array(X), np.array(y)
|
87 |
+
|
|
|
|
|
|
|
88 |
split = int(0.8 * len(X))
|
89 |
X_train, X_test = X[:split], X[split:]
|
90 |
y_train, y_test = y[:split], y[split:]
|
91 |
+
|
92 |
+
model = Sequential([
|
93 |
+
LSTM(units=50, return_sequences=True, input_shape=(time_step, 1)),
|
94 |
+
LSTM(units=50, return_sequences=False),
|
95 |
+
Dense(units=25),
|
96 |
+
Dense(units=1)
|
97 |
+
])
|
|
|
98 |
model.compile(optimizer='adam', loss='mean_squared_error')
|
|
|
|
|
99 |
model.fit(X_train, y_train, epochs=epochs, batch_size=batch_size)
|
100 |
+
|
101 |
+
predictions = scaler.inverse_transform(model.predict(X_test))
|
|
|
|
|
102 |
y_test = scaler.inverse_transform(y_test)
|
103 |
+
|
|
|
104 |
future_predictions = []
|
105 |
last_data = close_prices[-time_step:]
|
106 |
for _ in range(future_days):
|
107 |
pred = model.predict(last_data.reshape(1, time_step, 1))
|
108 |
future_predictions.append(pred[0, 0])
|
109 |
last_data = np.append(last_data[1:], pred[0])
|
|
|
110 |
future_predictions = scaler.inverse_transform(np.array(future_predictions).reshape(-1, 1))
|
111 |
+
|
|
|
112 |
fig = go.Figure()
|
113 |
fig.add_trace(go.Scatter(x=data.index[-len(y_test):], y=y_test.flatten(), mode='lines', name='Actual'))
|
114 |
fig.add_trace(go.Scatter(x=data.index[-len(predictions):], y=predictions.flatten(), mode='lines', name='Predicted'))
|
|
|
115 |
future_dates = pd.date_range(start=data.index[-1], periods=future_days + 1, inclusive='right')
|
|
|
116 |
fig.add_trace(go.Scatter(x=future_dates, y=future_predictions.flatten(), mode='lines', name='Future Predictions'))
|
|
|
117 |
fig.update_layout(title=f"Predicted vs Actual and Future Forecast for {ticker}", xaxis_title="Date", yaxis_title="Price", xaxis_rangeslider_visible=False)
|
118 |
return fig
|
119 |
|
120 |
# Gradio Interface
|
121 |
with gr.Blocks() as demo:
|
122 |
+
gr.Markdown("# Stock Analysis Tool")
|
123 |
+
|
124 |
with gr.Tab("Technical Analysis"):
|
125 |
with gr.Row():
|
126 |
ticker = gr.Textbox(label="Ticker Symbol", value="AAPL")
|
127 |
+
period = gr.Dropdown(label="Period", choices=list(PERIODS.keys()), value="1 Year")
|
128 |
+
analysis_type = gr.Radio(label="Analysis Type", choices=["Candlestick", "Moving Average", "Bollinger Bands", "RSI", "MACD"], value="Candlestick")
|
129 |
+
ma_length = gr.Number(label="Moving Average Length", value=20, visible=False)
|
130 |
+
candle_period = gr.Number(label="Candlestick Period", value=1, visible=False)
|
131 |
+
|
132 |
+
def update_visibility(analysis_type):
|
133 |
+
return (gr.update(visible=analysis_type == "Moving Average"), gr.update(visible=analysis_type == "Candlestick"))
|
134 |
+
|
135 |
+
analysis_type.change(fn=update_visibility, inputs=analysis_type, outputs=[ma_length, candle_period])
|
136 |
+
plot_button = gr.Button("Plot")
|
137 |
+
plot_output = gr.Plot()
|
138 |
+
plot_button.click(fn=plot_technical_analysis, inputs=[ticker, period, analysis_type, ma_length, candle_period], outputs=plot_output)
|
139 |
+
|
|
|
|
|
|
|
|
|
|
|
|
|
140 |
with gr.Tab("Fundamental Analysis"):
|
141 |
ticker = gr.Textbox(label="Ticker Symbol", value="AAPL")
|
142 |
analysis_type = gr.Radio(label="Analysis Type", choices=["Financials", "Balance Sheet", "Cash Flow"], value="Financials")
|
143 |
plot_button = gr.Button("Show Data")
|
144 |
table_output = gr.HTML()
|
|
|
145 |
plot_button.click(fn=plot_fundamental_analysis, inputs=[ticker, analysis_type], outputs=table_output)
|
146 |
+
|
147 |
with gr.Tab("Predictive Model"):
|
148 |
ticker = gr.Textbox(label="Ticker Symbol", value="AAPL")
|
149 |
+
period = gr.Dropdown(label="Period", choices=list(PERIODS.keys()), value="1 Year")
|
150 |
epochs = gr.Number(label="Epochs", value=10)
|
151 |
batch_size = gr.Number(label="Batch Size", value=32)
|
152 |
future_days = gr.Number(label="Days to Predict", value=30)
|
153 |
train_button = gr.Button("Train and Predict")
|
154 |
predict_output = gr.Plot()
|
|
|
155 |
train_button.click(fn=train_predictive_model, inputs=[ticker, period, epochs, batch_size, future_days], outputs=predict_output)
|
156 |
|
157 |
# Launch the interface
|