Spaces:
Running
Running
import streamlit as st | |
import math | |
import numpy as np | |
import pandas as pd | |
import yfinance as yf | |
import datetime as dt | |
import plotly.graph_objects as go | |
import tensorflow as tf | |
from tensorflow.keras.models import Sequential | |
from tensorflow.keras.layers import SimpleRNN, LSTM, GRU, Dense, Dropout | |
from tensorflow.keras.optimizers import SGD, Adam | |
from sklearn.preprocessing import MinMaxScaler | |
from utils.helper import * | |
# Streamlit interface | |
st.set_page_config(layout="wide") | |
st.title('Stock Forecasting App') | |
with st.sidebar: | |
stock = st.text_input('Enter Stock Ticker', 'AAPL') | |
start_date = st.date_input('Start Date', dt.date(2020, 1, 1)) | |
end_date = st.date_input('End Date', dt.date.today()) | |
num_of_epochs = st.number_input('Num. of training iterations (epochs)', step=5, min_value=2, max_value=100, value=10) | |
st.warning("A default value of 10 is large enough to get decent results and has a waiting time of ~20 min on a basic CPU with 16G RAM running the default parameters.") | |
n_futures = st.number_input('Length of future (to forecast)', step=10, min_value=10, max_value=100, value=40) | |
n_samples = st.number_input('Number of Simulations (to synthesize)', step=10, min_value=10, max_value=10000, value=50) | |
st.markdown( | |
f""" | |
For webpage, please click [here](https://huggingface.co/spaces/eagle0504/stock-forecast). | |
""" | |
) | |
# Credit | |
current_year = current_year() # This will print the current year | |
st.markdown( | |
f""" | |
<h6 style='text-align: left;'>Copyright Β© 2010-{current_year} Present Yiqiao Yin</h6> | |
""", | |
unsafe_allow_html=True, | |
) | |
look_back = 50 | |
guide_expander = st.expander("User Guide π", expanded=False) | |
with guide_expander: | |
st.markdown(""" | |
# Stock Forecasting App Guide π | |
Welcome to the **Stock Forecasting App**! This application allows you to predict future stock prices using advanced machine learning models such as RNN, LSTM, and GRU. Follow this guide to learn how to navigate and utilize the app effectively. | |
## Getting Started π | |
To begin using the app: | |
1. **Open the App**: | |
- Navigate to the provided URL if you're using a hosted version or run it locally on your machine using Streamlit if it's installed. | |
2. **Input Stock Ticker**: | |
- In the sidebar, you'll see a field labeled `Enter Stock Ticker`. Type in the ticker symbol for the stock you wish to forecast. For example, `AAPL` for Apple Inc. The default is set to `AAPL`. | |
## Selecting the Date Range π | |
- Below the stock ticker input, you'll find two date fields: | |
1. **Start Date**: Select the beginning date from which the stock data should be considered. | |
2. **End Date**: Select the ending date until which the stock data should be fetched. | |
- These dates define the period for which the model will fetch historical data to train and make predictions. | |
## Training the Models π€ | |
- After setting the stock ticker and date range, specify how many training epochs you wish to run: | |
- **Number of Epochs**: Choose how many times the model should process the entire dataset. More epochs might lead to better predictions but can increase processing time. | |
- Use the slider to set the number of epochs between 2 and 100, with a default value of 10. | |
## Launch the Forecast π | |
- Once all inputs are set: | |
- Click the `Train Models` button at the bottom of the sidebar to start training the models. | |
- The app will display a spinner indicating that the models are being trained. This process might take some time depending on the volume of data and the number of epochs. | |
## Viewing Predictions π | |
- After training, the predictions made by the RNN, LSTM, and GRU models will be displayed in a graph format. | |
- **Graphs**: You will see three graphs, one for each model. Each graph will show: | |
- The historical stock prices (as training data). | |
- The actual stock prices for the test period. | |
- The predicted stock prices for the test period. | |
## Navigation Tips π | |
- You can use the sidebar to adjust parameters and re-run predictions as many times as you like. | |
- For a different stock, simply change the ticker in the sidebar and click `Train Models` again. | |
## Conclusion π | |
Thank you for using the Stock Forecasting App! We hope it provides valuable insights into stock price trends and assists in your investment decisions. If you have any questions or feedback, please do not hesitate to reach out. | |
""", unsafe_allow_html=True) | |
if st.button('Train Models'): | |
with st.spinner('Wait for it...'): | |
data = download_data(stock, start_date, end_date) | |
# Setting 80 percent data for training | |
training_data_len = math.ceil(len(data) * .8) | |
# Splitting the dataset | |
train_data = data[:training_data_len].iloc[:,:5] | |
test_data = data[training_data_len:].iloc[:,:5] | |
# Selecting Open Price values | |
dataset_train = train_data.Close.values | |
# Reshaping 1D to 2D array | |
dataset_train = np.reshape(dataset_train, (-1,1)) | |
# scaling dataset | |
scaler = MinMaxScaler(feature_range=(0,1)) | |
scaled_train = scaler.fit_transform(dataset_train) | |
# Selecting Open Price values | |
dataset_test = test_data.Close.values | |
# Reshaping 1D to 2D array | |
dataset_test = np.reshape(dataset_test, (-1,1)) | |
# Normalizing values between 0 and 1 | |
scaled_test = scaler.fit_transform(dataset_test) | |
# Split train and test | |
X_train, y_train = create_datasets(scaled_train, look_back) | |
X_test, y_test = create_datasets(scaled_test, look_back) | |
# Create models | |
rnn_model = create_rnn_model((look_back, 1)) | |
lstm_model = create_lstm_model((look_back, 1)) | |
gru_model = create_gru_model((look_back, 1)) | |
# Training | |
rnn_model.fit(X_train, y_train, epochs=num_of_epochs, batch_size=1) | |
lstm_model.fit(X_train, y_train, epochs=num_of_epochs, batch_size=1) | |
gru_model.fit(X_train, y_train, epochs=num_of_epochs, batch_size=1) | |
st.success("Models finished training.") | |
# Inference | |
y_RNN = [] | |
y_LSTM = [] | |
y_GRU = [] | |
starter_data = scaled_test[-50::].reshape((50, 1)).reshape((-1, 50, 1)) | |
for i in range(1): | |
curr_y_RNN = rnn_model.predict(starter_data, verbose=0) | |
curr_y_LSTM = lstm_model.predict(starter_data, verbose=0) | |
curr_y_GRU = gru_model.predict(starter_data, verbose=0) | |
curr_y_RNN = scaler.inverse_transform(curr_y_RNN) | |
curr_y_LSTM = scaler.inverse_transform(curr_y_LSTM) | |
curr_y_GRU = scaler.inverse_transform(curr_y_GRU) | |
y_RNN.append(curr_y_RNN) | |
y_LSTM.append(curr_y_LSTM) | |
y_GRU.append(curr_y_GRU) | |
y_RNN = np.array(y_RNN).flatten()[0] | |
y_LSTM = np.array(y_LSTM).flatten()[0] | |
y_GRU = np.array(y_GRU).flatten()[0] | |
next_point_forecasts = np.array([y_RNN, y_LSTM, y_GRU]).reshape(-1) | |
st.success("See the next point forecasts below by 3 different models (RNN, LSTM, GRU):") | |
closing_prices = data['Close'] | |
last_close = closing_prices.iloc[-1] | |
forecast_results_tab = pd.DataFrame({ | |
'Last Close': last_close, | |
'RNN': y_RNN, | |
'LSTM': y_LSTM, | |
'GRU': y_GRU, | |
'Average': np.mean(next_point_forecasts), | |
'Median': np.median(next_point_forecasts), | |
'Std Dev': np.std(next_point_forecasts) | |
}, index=[0]) | |
forecast_results_tab = forecast_results_tab.transpose() | |
st.table(forecast_results_tab) | |
# Create MC Simulation | |
all_rets = next_point_forecasts / last_close - 1 | |
mean_return = np.mean(all_rets) | |
std_dev = np.std(all_rets) | |
plot_monte_carlo_forecasts(data=data, n_futures=n_futures, n_samples=n_samples, mean_return=mean_return, std_dev=std_dev) | |