Predicting stock prices is an uncertain task which is modelled using machine learning to predict the return on stocks. There are a lot of methods and tools used for the purpose of stock market prediction. The stock market is considered to be very dynamic and complex in nature. An accurate prediction of future prices may lead to a higher yield of profit for investors through stock investments. As per the predictions, investors will be able to pick the stocks that may give a higher return.
Over the years, various machine learning techniques have been used in stock market prediction, but with the increased amount of data and expectation of more accurate prediction, the deep learning models are being used nowadays which have proven their advantage over traditional machine learning methods in terms of accuracy and speed of prediction. In this article, we will discuss the Long-Short-Term Memory (LSTM) Recurrent Neural Network, one of the popular deep learning models, used in stock market prediction. In this task, we will fetch the historical data of stock automatically using python libraries and fit the LSTM model on this data to predict the future prices of the stock.
LSTM Recurrent Neural Network
Long-Short-Term Memory Recurrent Neural Network belongs to the family of deep learning algorithms. It is a recurrent network because of the feedback connections in its architecture. It has an advantage over traditional neural networks due to its capability to process the entire sequence of data. Its architecture comprises the cell, input gate, output gate and forget gate.
Subscribe to our Newsletter
Join our editors every weekday evening as they steer you through the most significant news of the day, introduce you to fresh perspectives, and provide unexpected moments of joy
Your newsletter subscriptions are subject to AIM Privacy Policy and Terms and Conditions.
The cell remembers values over arbitrary time intervals, and the three gates regulate the flow of information into and out of the cell. The cell of the model is responsible for keeping track of the dependencies between the elements in the input sequence. The input gate controls the extent to which a new value flows into the cell, the forget gate controls the extent to which a value remains in the cell, and the output gate controls the extent to which the value in the cell is used to compute the output activation of the LSTM unit.
However, there are some variants of the LSTM model such as Gated Recurrent Units (GRUs) that do not have the output gate. LSTM Networks are popularly used on time-series data for classification, processing, and making predictions. The reason for its popularity in time-series application is that there can be several lags of unknown duration between important events in a time series.
(For more details on LSTM, please read this post: How to Code Your First LSTM Network in Keras)
Stock Prediction
In this task, the future stock prices of State Bank of India (SBIN) are predicted using the LSTM Recurrent Neural Network. Our task is to predict stock prices for a few days, which is a time series problem. The LSTM model is very popular in time-series forecasting, and this is the reason why this model is chosen in this task. The historical prices of SBIN are collected automatically using the nsepy library of python. We have used 6 years of historical price data, from 01.01.2013 to 31.12.2018.
This data set contains 1483 observations with 12 attributes. After preprocessing, only dates and OHLC (Open, High, Low, Close) columns, a total of 5 columns, are taken as these columns have main significance in the dataset. The LSTM model is trained on this entire dataset, and for the testing purpose, a new dataset is fetched for the duration between 01.01.2019 to 18.09.2019. The stock prices for this new duration will be predicted by the already trained LSTM model, and the predicted prices will be plotted against the original prices to visualise the model’s accuracy.
Implementation
Before proceeding further, make sure that you have installed TensorFlow and nsepy libraries. TensorFlow will be used as a backend for LSTM model, and nsepy will be used to fetch the historical stock data. Once installed, follow the below steps:
1.Import the required libraries
from nsepy import get_history as gh import datetime as dt from matplotlib import pyplot as plt from sklearn import model_selection from sklearn.metrics import confusion_matrix from sklearn.preprocessing import StandardScaler from sklearn.model_selection import train_test_split import numpy as np import pandas as pd from sklearn.preprocessing import MinMaxScaler from keras.models import Sequential from keras.layers import Dense from keras.layers import LSTM from keras.layers import Dropout
2. We will fetch 6 years of historical prices of SBIN from 01.01.2013 to 31.12.2018. So we need to set the start and end dates and pass these parameters to the function for fetching the data.
start = dt.datetime(2013,1,1) end = dt.datetime(2018,12,31) stk_data = gh(symbol='SBIN',start=start,end=end)
3. We can visualise the fetched data in the above step. For simplicity, only the day-wise closing prices are visualised.
plt.figure(figsize=(14,14)) plt.plot(stk_data['Close']) plt.title('Historical Stock Value') plt.xlabel('Date') plt.ylabel('Stock Price') plt.show()
4. There are 12 columns in the fetched data. Many of the columns are not of our interest so only significant columns are selected to create the main dataset.
stk_data['Date'] = stk_data.index data2 = pd.DataFrame(columns = ['Date', 'Open', 'High', 'Low', 'Close']) data2['Date'] = stk_data['Date'] data2['Open'] = stk_data['Open'] data2['High'] = stk_data['High'] data2['Low'] = stk_data['Low'] data2['Close'] = stk_data['Close']
5. Preprocess the data in order to prepare it for the LSTM model. The data fetched in step one is used for training purpose only. For testing purpose, different data will be fetched later.
train_set = data2.iloc[:, 1:2].values sc = MinMaxScaler(feature_range = (0, 1)) training_set_scaled = sc.fit_transform(train_set) X_train = [] y_train = [] for i in range(60, 1482): X_train.append(training_set_scaled[i-60:i, 0]) y_train.append(training_set_scaled[i, 0]) X_train, y_train = np.array(X_train), np.array(y_train) X_train = np.reshape(X_train, (X_train.shape[0], X_train.shape[1], 1))
6. Define the LSTM Recurrent Neural Network. Here, you can add more LSTM layers and adjust the dropout in order to improve the accuracy of the model.
regressor = Sequential() regressor.add(LSTM(units = 50, return_sequences = True, input_shape = (X_train.shape[1], 1))) regressor.add(Dropout(0.2)) regressor.add(LSTM(units = 50, return_sequences = True)) regressor.add(Dropout(0.2)) regressor.add(LSTM(units = 50, return_sequences = True)) regressor.add(Dropout(0.2)) regressor.add(LSTM(units = 50)) regressor.add(Dropout(0.2)) regressor.add(Dense(units = 1))
7. Compile and train the model defined in the above step. Iteratively, you can increase or decrease the epochs and batch size to get more accuracy.
regressor.compile(optimizer = 'adam', loss = 'mean_squared_error') regressor.fit(X_train, y_train, epochs = 15, batch_size = 32)
8. Now, our model is trained and needs to be tested on the testing data. For this purpose, fetch the new data for a different period. Preprocessing steps are similar as we have done with training data.
testdataframe= gh(symbol='SBIN',start=dt.datetime(2019,1,1),end=dt.datetime(2019,9,18)) testdataframe['Date'] = testdataframe.index testdata = pd.DataFrame(columns = ['Date', 'Open', 'High', 'Low', 'Close']) testdata['Date'] = testdataframe['Date'] testdata['Open'] = testdataframe['Open'] testdata['High'] = testdataframe['High'] testdata['Low'] = testdataframe['Low'] testdata['Close'] = testdataframe['Close'] real_stock_price = testdata.iloc[:, 1:2].values dataset_total = pd.concat((data2['Open'], testdata['Open']), axis = 0) inputs = dataset_total[len(dataset_total) - len(testdata) - 60:].values inputs = inputs.reshape(-1,1) inputs = sc.transform(inputs) X_test = [] for i in range(60, 235): X_test.append(inputs[i-60:i, 0]) X_test = np.array(X_test) X_test = np.reshape(X_test, (X_test.shape[0], X_test.shape[1], 1))
9. Test the LSTM model on the new dataset.
predicted_stock_price = regressor.predict(X_test) predicted_stock_price = sc.inverse_transform(predicted_stock_price)
10. Visualize the predicted stock prices with original stock prices.
plt.figure(figsize=(20,10)) plt.plot(real_stock_price, color = 'green', label = 'SBI Stock Price') plt.plot(predicted_stock_price, color = 'red', label = 'Predicted SBI Stock Price') plt.title('SBI Stock Price Prediction') plt.xlabel('Trading Day') plt.ylabel('SBI Stock Price') plt.legend() plt.show()
The plot is shown in the below image.
Binding all the above steps together.
#Importing the libraries from nsepy import get_history as gh import datetime as dt from matplotlib import pyplot as plt from sklearn import model_selection from sklearn.metrics import confusion_matrix from sklearn.preprocessing import StandardScaler from sklearn.model_selection import train_test_split import numpy as np import pandas as pd from sklearn.preprocessing import MinMaxScaler from keras.models import Sequential from keras.layers import Dense from keras.layers import LSTM from keras.layers import Dropout #Setting start and end dates and fetching the historical data start = dt.datetime(2013,1,1) end = dt.datetime(2018,12,31) stk_data = gh(symbol='SBIN',start=start,end=end) #Visualizing the fetched data plt.figure(figsize=(14,14)) plt.plot(stk_data['Close']) plt.title('Historical Stock Value') plt.xlabel('Date') plt.ylabel('Stock Price') plt.show() #Data Preprocessing stk_data['Date'] = stk_data.index data2 = pd.DataFrame(columns = ['Date', 'Open', 'High', 'Low', 'Close']) data2['Date'] = stk_data['Date'] data2['Open'] = stk_data['Open'] data2['High'] = stk_data['High'] data2['Low'] = stk_data['Low'] data2['Close'] = stk_data['Close'] train_set = data2.iloc[:, 1:2].values sc = MinMaxScaler(feature_range = (0, 1)) training_set_scaled = sc.fit_transform(train_set) X_train = [] y_train = [] for i in range(60, 1482): X_train.append(training_set_scaled[i-60:i, 0]) y_train.append(training_set_scaled[i, 0]) X_train, y_train = np.array(X_train), np.array(y_train) X_train = np.reshape(X_train, (X_train.shape[0], X_train.shape[1], 1)) #Defining the LSTM Recurrent Model regressor = Sequential() regressor.add(LSTM(units = 50, return_sequences = True, input_shape = (X_train.shape[1], 1))) regressor.add(Dropout(0.2)) regressor.add(LSTM(units = 50, return_sequences = True)) regressor.add(Dropout(0.2)) regressor.add(LSTM(units = 50, return_sequences = True)) regressor.add(Dropout(0.2)) regressor.add(LSTM(units = 50)) regressor.add(Dropout(0.2)) regressor.add(Dense(units = 1)) #Compiling and fitting the model regressor.compile(optimizer = 'adam', loss = 'mean_squared_error') regressor.fit(X_train, y_train, epochs = 15, batch_size = 32) #Fetching the test data and preprocessing testdataframe = gh(symbol='SBIN',start=dt.datetime(2019,1,1),end=dt.datetime(2019,9,18)) testdataframe['Date'] = testdataframe.index testdata = pd.DataFrame(columns = ['Date', 'Open', 'High', 'Low', 'Close']) testdata['Date'] = testdataframe['Date'] testdata['Open'] = testdataframe['Open'] testdata['High'] = testdataframe['High'] testdata['Low'] = testdataframe['Low'] testdata['Close'] = testdataframe['Close'] real_stock_price = testdata.iloc[:, 1:2].values dataset_total = pd.concat((data2['Open'], testdata['Open']), axis = 0) inputs = dataset_total[len(dataset_total) - len(testdata) - 60:].values inputs = inputs.reshape(-1,1) inputs = sc.transform(inputs) X_test = [] for i in range(60, 235): X_test.append(inputs[i-60:i, 0]) X_test = np.array(X_test) X_test = np.reshape(X_test, (X_test.shape[0], X_test.shape[1], 1)) #Making predictions on the test data predicted_stock_price = regressor.predict(X_test) predicted_stock_price = sc.inverse_transform(predicted_stock_price) #Visualizing the prediction plt.figure(figsize=(20,10)) plt.plot(real_stock_price, color = 'green', label = 'SBI Stock Price') plt.plot(predicted_stock_price, color = 'red', label = 'Predicted SBI Stock Price') plt.title('SBI Stock Price Prediction') plt.xlabel('Trading Day') plt.ylabel('SBI Stock Price') plt.legend() plt.show()