Stock price prediction using NeuralProphet

Photo by Yiorgos Ntrahas

Predicting stock price is a difficult task. Many factors affect the stock price like company policies and government policies. These policy changes affect stock prices to rise or fall massively. But still, we can predict trends, seasonality and other parameters using historical data. We are going to do this using the NeuralProphet library.

NeuralProphet

NeuralProphet is a Neural Network based Time-Series model, inspired by Facebook Prophet and AR-Net, built on PyTorch. This framework addresses some key points like modularity and scalability. NeuralProphet can produce both single step and multi step-ahead forecasts. But at the moment, NeuralProphet builds models univariately.

Install NeuralProphet

You can install NeuralProphet on your machine by running the following commands.

#!/bin/sh
git clone https://github.com/ourownstory/neural_prophet.git 
cd neural_prophet && pip install .[live]

Install other libraries

#!/bin/sh
pip install pandas
pip install matplotlib
pip install seaborn

Import libraries

import pandas as pd
import matplotlib.pyplot as plt
%matplotlib inline
import seaborn as sns
from neuralprophet import NeuralProphet

The variability of results comes from SGD finding different optima on different runs. The majority of the randomness comes from the random initialization of weights, different learning rates and different shuffling of the data loader. We can control the random number generator by setting its seed.

from neuralprophet import set_random_seed 
set_random_seed(0)

Import Data

For this tutorial, we will be using the stock data from NIFTY-50 Stock Market Data (2000 - 2021) Kaggle Dataset. We will try to predict Wipro's stock price for this demo.

input_df = pd.read_csv("./data/stock/WIPRO.csv", parse_dates=["Date"])
input_df.head()
neuralprophet-1

Simple Model

A simple model with neural_prophet for this dataset can be fitted by creating an object of the NeuralProphet class as follows and calling the fit function. This fits a model with the default settings in the model. In NeuralProphet only two columns are expected ‘ds’ which is the timestamp and ‘y’ the dependent variable( for stocks it is VWAP or Volume Weighted Average Price).

input_df = input_df[["Date", "VWAP"]]
input_df.rename(columns={"Date": "ds", "VWAP": "y"}, inplace=True)

By default, the y values would be min-max normalized. If the user specifically, sets the normalize_y argument to true, the data is z-score normalized. For the time being, we will leave it with default values. We can perform validation per every epoch during model fitting. This is done by setting the validate_each_epoch and valid_p arguments in the fit function call. This lets us look at the validation metrics while model training.

neural_prophet_model = NeuralProphet()
neural_prophet_metrics = neural_prophet_model.fit(input_df, validate_each_epoch=True, valid_p=0.2, freq="D")

Making future predictions from the model

Now let's predict the trend for the next 365 days.

future_df = neural_prophet_model.make_future_dataframe(input_df, periods=365, n_historic_predictions=len(input_df))
forecast_df = neural_prophet_model.predict(future_df)

Plotting prediction

fig, ax = plt.subplots(figsize=(8,8))
neural_prophet_model.plot(forecast_df, xlabel="Date", ylabel="VWAP", ax=ax)

ax.xaxis.label.set_size(24)
ax.yaxis.label.set_size(24)
ax.tick_params(axis='both', which='major', labelsize=18)
ax.set_title("Wipro Stocks", fontsize=24, fontweight="bold")
neuralprophet-2
fig_comp = neural_prophet_model.plot_components(forecast_df)
neuralprophet-3

Plotting the parameters

This will show the trend, trend rate, weekly seasonality and a yearly seasonality.

fig_param = neural_prophet_model.plot_parameters()
neuralprophet-3
neuralprophet-5

Model Loss

Loss is a number indicating how bad the model's prediction was on a single example. If the model's prediction is perfect, the loss is zero; otherwise, the loss is greater.

fig, ax = plt.subplots(figsize=(14, 10))
ax.plot(neural_prophet_metrics["MAE"], '-b', linewidth=6, label="Training Loss")  
ax.plot(neural_prophet_metrics["MAE_val"], '-r', linewidth=2, label="Validation Loss")

# You can use metrics["SmoothL1Loss"] and metrics["SmoothL1Loss_val"] too.

ax.legend(loc='center right', fontsize=16)
ax.tick_params(axis='both', which='major', labelsize=18)
ax.set_xlabel("Epoch", fontsize=24, fontweight="bold")
ax.set_ylabel("Loss", fontsize=24, fontweight="bold")

ax.set_title("Model Loss (MAE)", fontsize=28, fontweight="bold")
neuralprophet-6

Conclusion

Hooray! Now we have predicted the stock trend of Wipro using the NeuralProphet library. As you can see, the loss is about 200. Which is not as accurate as we expect from a machine learning model. This model may be improved by optimizing hyperparameters or by enabling AR-Net. Visit the official documentation for a list of available hyperparameters.

All the code of this article is available over on Github. This is a python project, so it should be easy to import and run as it is.

Share