File size: 7,665 Bytes
65e3d45
9cf3124
65e3d45
 
 
 
 
1b126a6
65e3d45
 
 
 
 
9cf3124
65e3d45
3218655
65e3d45
c18aea7
65e3d45
 
862c4f9
77fb945
862c4f9
 
 
 
57ea600
 
c18aea7
 
 
 
 
862c4f9
65e3d45
 
77fb945
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
65e3d45
862c4f9
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
052ff0f
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
57ea600
 
 
32faf33
 
 
 
 
4f4f41a
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
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)