Stock Price Forecasting w/ XGBoost
Full breakdown of my time series forecasting project
DATA SCIENCE
![](https://assets.zyrosite.com/cdn-cgi/image/format=auto,w=812,h=344,fit=crop,trim=327.58620689655174;0;327.58620689655174;0/AR0elX211Mt7zOWa/growth-stock-chart-mv0xl6pnQ6sGMM1d.jpg)
![](https://assets.zyrosite.com/cdn-cgi/image/format=auto,w=382,h=320,fit=crop,trim=0;107.72833723653395;0;107.72833723653395/AR0elX211Mt7zOWa/growth-stock-chart-mv0xl6pnQ6sGMM1d.jpg)
The full Jupyter notebook for this experiment can be found here.
Objective
The objective of this experiment is to build and train a model to predict the daily adjusted closing prices of Tesla (TSLA) 1 year into the future. This experiment will consist of data starting from TSLA's IPO date which is 2010-06-29 to 2023-05-24. The data is taken from yahoo finance using a python library called yfinance. After downloading, the dataset looks like this:
![](https://assets.zyrosite.com/cdn-cgi/image/format=auto,w=534,h=328,fit=crop/AR0elX211Mt7zOWa/screenshot-2023-06-01-164716-dWxM0r5044h718MK.png)
![](https://assets.zyrosite.com/cdn-cgi/image/format=auto,w=382,h=231,fit=crop/AR0elX211Mt7zOWa/screenshot-2023-06-01-164716-dWxM0r5044h718MK.png)
Altogether we have 3249 days of data, excluding the weekends. This plot below shows the adjusted closing price of TSLA’s entire dataset.
![](https://assets.zyrosite.com/cdn-cgi/image/format=auto,w=534,h=320,fit=crop/AR0elX211Mt7zOWa/screenshot-2023-06-01-164944-AwvLP2p7rJIK8Rq5.png)
![](https://assets.zyrosite.com/cdn-cgi/image/format=auto,w=382,h=233,fit=crop/AR0elX211Mt7zOWa/screenshot-2023-06-01-164944-AwvLP2p7rJIK8Rq5.png)
In this experiment, I aim to utilize XGBoost to accurately forecast TSLA’s performance in one years time. However, since the data from years 2010 - 2019 are so small compared to the recent years’ data, I will perform time series cross validation to train sectioned date ranges in order to achieve a better trained model.
To evaluate the effectiveness of my model, I will use the root mean square error (RMSE) score where the lower the score, the more accurate the prediction.
Exploratory Data Analysis (EDA)
In order to understand the data set more, I performed some EDA on the dataset. I looked at monthly adjusted closing price, annual adjusted closing price, adjusted closing price for each day of the week. Performing EDA will give me more insight on the data, its growth and its patterns.
The plot below shows the average adjusted closing price for each month. We can see that mid year months tend to have a lower value.
![](https://assets.zyrosite.com/cdn-cgi/image/format=auto,w=447,h=360,fit=crop/AR0elX211Mt7zOWa/screenshot-2023-06-01-170512-dOqXNKzxk7unrGKO.png)
![](https://assets.zyrosite.com/cdn-cgi/image/format=auto,w=338,h=268,fit=crop/AR0elX211Mt7zOWa/screenshot-2023-06-01-170512-dOqXNKzxk7unrGKO.png)
The plot below shows the average adjusted closing price for each year. We can see the growth in 2020 and slight pullback in 2023.
![](https://assets.zyrosite.com/cdn-cgi/image/format=auto,w=487,h=360,fit=crop,trim=0;1.210633946830266;0;1.210633946830266/AR0elX211Mt7zOWa/screenshot-2023-06-01-170545-A856rBb7g1I1q6X7.png)
![](https://assets.zyrosite.com/cdn-cgi/image/format=auto,w=370,h=274,fit=crop,trim=0;1.5913978494623657;0;1.5913978494623657/AR0elX211Mt7zOWa/screenshot-2023-06-01-170545-A856rBb7g1I1q6X7.png)
The plot below shows the average adjusted closing price for each day of the week. We can see that the end of the week seems to be slightly lower than the mid week.
![](https://assets.zyrosite.com/cdn-cgi/image/format=auto,w=479,h=360,fit=crop,trim=0;9.503030303030304;0;9.503030303030304/AR0elX211Mt7zOWa/screenshot-2023-06-01-170624-YrDLXrxvVxFBKELr.png)
![](https://assets.zyrosite.com/cdn-cgi/image/format=auto,w=351,h=265,fit=crop,trim=0;11.307692307692308;0;11.307692307692308/AR0elX211Mt7zOWa/screenshot-2023-06-01-170624-YrDLXrxvVxFBKELr.png)
I added some lags to the dataset in order to see the correlation of previous days’ vs the current day. The heatmap below shows the correlation of lags with the Adjusted Close price. As expected, the more recent the price, the more correlated it is.
![](https://assets.zyrosite.com/cdn-cgi/image/format=auto,w=479,h=387,fit=crop,trim=9.216957605985037;0;9.216957605985037;0/AR0elX211Mt7zOWa/screenshot-2023-06-01-170816-mP4XN0ykJrFDzBaR.png)
![](https://assets.zyrosite.com/cdn-cgi/image/format=auto,w=382,h=320,fit=crop,trim=0;0;0;0/AR0elX211Mt7zOWa/screenshot-2023-06-01-170816-mP4XN0ykJrFDzBaR.png)
Feature Engineering
For this project, I decided to create some additional features to improve the accuracy of my model by using the help of fastai. I have added 13 new features for model training. These features include: Year, Month, Week, Day, Dayofweek, Dayofyear, Is_month_end, Is_month_start, Is_quarter_end, Is_quarter_start, Is_year end, and Is_year_start.
![](https://assets.zyrosite.com/cdn-cgi/image/format=auto,w=408,h=67,fit=crop,trim=0.9117647058823529;0;0.9117647058823529;0/AR0elX211Mt7zOWa/screenshot-2023-06-01-172421-A3QErM5XLbuNMMRK.png)
![](https://assets.zyrosite.com/cdn-cgi/image/format=auto,w=304,h=50,fit=crop,trim=1.2156862745098038;0;1.2156862745098038;0/AR0elX211Mt7zOWa/screenshot-2023-06-01-172421-A3QErM5XLbuNMMRK.png)
After the adding the new features, the dataset looks like this:
![](https://assets.zyrosite.com/cdn-cgi/image/format=auto,w=812,h=387,fit=crop,trim=0;2.4392638036809817;0;2.4392638036809817/AR0elX211Mt7zOWa/screenshot-2023-06-05-085944-A0x4rJbrn0hka071.png)
![](https://assets.zyrosite.com/cdn-cgi/image/format=auto,w=382,h=182,fit=crop,trim=0;2.5953002610966056;0;2.5953002610966056/AR0elX211Mt7zOWa/screenshot-2023-06-05-085944-A0x4rJbrn0hka071.png)
Training / Test Split
Given the large span of data (13 years), I figured the more accurate way to train/test split would be by Time Series Cross Validation. Scikit learn conveniently has a model that helps split and test data according to your needs. In this experiment, I will split the entire data by 6 for training and the following year for testing. Doing so in chronological order would also prevent information leak in the model.
![](https://assets.zyrosite.com/cdn-cgi/image/format=auto,w=686,h=806,fit=crop/AR0elX211Mt7zOWa/screenshot-2023-06-05-091318-m5KWr3ERMNsy56BZ.png)
![](https://assets.zyrosite.com/cdn-cgi/image/format=auto,w=382,h=428,fit=crop/AR0elX211Mt7zOWa/screenshot-2023-06-05-091318-m5KWr3ERMNsy56BZ.png)
The code below displays the model creation. The split train / test data will be assigned accordingly. The FEATURES are all the columns of data we wish to train. The added lags could give us a slight boost in accuracy.
![](https://assets.zyrosite.com/cdn-cgi/image/format=auto,w=676,h=535,fit=crop/AR0elX211Mt7zOWa/screenshot-2023-06-06-111012-Y4LEpQD5RLTKgpNy.png)
![](https://assets.zyrosite.com/cdn-cgi/image/format=auto,w=382,h=302,fit=crop/AR0elX211Mt7zOWa/screenshot-2023-06-06-111012-Y4LEpQD5RLTKgpNy.png)
Running this code would display the root mean square error (RMSE). As you can see after about 11000 iterations, the score seems to have stabilized at its minimal.
![](https://assets.zyrosite.com/cdn-cgi/image/format=auto,w=248,h=320,fit=crop/AR0elX211Mt7zOWa/screenshot-2023-06-06-111556-A0x4rJvweBtWlDqx.png)
![](https://assets.zyrosite.com/cdn-cgi/image/format=auto,w=238,h=302,fit=crop/AR0elX211Mt7zOWa/screenshot-2023-06-06-111556-A0x4rJvweBtWlDqx.png)
Predicting the Future
In order to predict TSLA 1 year’s time into the future I had to create a skeleton date frame and combine it to the current data. Since the dataset ends at 05-24-2023, the start of the future dataset will be on 05-25-2023. Note that I also added a new column called [‘isFuture’] to indicate which rows of data are in the past and which is in the future.
![](https://assets.zyrosite.com/cdn-cgi/image/format=auto,w=123,h=152,fit=crop/AR0elX211Mt7zOWa/screenshot-2023-06-05-091656-d95Er0WwrDfReQvd.png)
![](https://assets.zyrosite.com/cdn-cgi/image/format=auto,w=125,h=155,fit=crop/AR0elX211Mt7zOWa/screenshot-2023-06-05-091656-d95Er0WwrDfReQvd.png)
After combining the datasets, and re-implementing the feature engineering, the dataset looks like this:
![](https://assets.zyrosite.com/cdn-cgi/image/format=auto,w=682,h=320,fit=crop/AR0elX211Mt7zOWa/screenshot-2023-06-05-091921-Yyvk2bEpj1u0EWyr.png)
![](https://assets.zyrosite.com/cdn-cgi/image/format=auto,w=382,h=184,fit=crop/AR0elX211Mt7zOWa/screenshot-2023-06-05-091921-Yyvk2bEpj1u0EWyr.png)
Now all that’s left to do is to retrain all of the data and plot all the rows where [‘isFuture’] is true.
Findings
![](https://assets.zyrosite.com/cdn-cgi/image/format=auto,w=573,h=320,fit=crop/AR0elX211Mt7zOWa/screenshot-2023-06-05-092109-meP3GZOp6wujPEKL.png)
![](https://assets.zyrosite.com/cdn-cgi/image/format=auto,w=372,h=204,fit=crop/AR0elX211Mt7zOWa/screenshot-2023-06-05-092109-meP3GZOp6wujPEKL.png)
The model has successfully predicted the stock prices in one years time. Though this model is not perfect. In the future I would like to introduce feature scaling to the date lags so that the model could be even more accurate. I would also like to introduce the stocks financials as features that could affect the stock price as well. Lastly, I aim to deploy this into an open sourced website so people could see the forecast for whichever stock they want.
The full Jupyter notebook link for this project can be found here.