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('Insert a number', step=1, min_value=2, max_value=100, value=10) n_futures = st.number_input('Length of future (to forecast)', step=1, min_value=10, max_value=300, value=30) 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). """ ) 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) y_LSTM = np.array(y_LSTM) y_GRU = np.array(y_GRU) next_point_forecasts = np.array([y_RNN, y_LSTM, y_GRU]).reshape(-1) st.success("See the next point forecasts below:") st.write(f"Mean is: {np.mean(next_point_forecasts)}") st.write(f"Median is: {np.median(next_point_forecasts)}") st.write(f"Std is: {np.std(next_point_forecasts)}") # Create MC Simulation closing_prices = data['Close'] last_close = closing_prices.iloc[-1] 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)