So it's really inevitable when you hear of a new time series model to ask the question, how will this
model perform on stock predictions in this lecture?
We will answer this question.
I'll also point out some very bad mistakes I've come across online, which are the top hits on Google
when you search for how to do stock predictions with profits.
As I recall, one of these authors even claims to have a Ph.D..
So take this as a lesson.
Just because someone says they have a Ph.D. or works at such and such company does not imply that they
know what they are doing.
Moreover, this is yet another example of why you should not trust the top hits on a search engine,
especially those that appear on the most popular blogging platforms, which I will not name but are
pretty obvious.
If you look so, we'll begin by installing profit once again.
The next step is to download our data.
The next step is to import the usual library's.
The next step is to load in our data using PDF to read CSFI.
The next step is to grab the clothes prices for Googs.
The next step is to call Jughead head to remind ourselves what this data frame looks like.
The next step is to rename the clothes column to Y as required by profit, we'll also create a new column
called Yes from the Index, also required by profit.
The next step is to run through the same lines of code we normally do not that I haven't used the entire
time series to build this model only the last few years.
Also note that for the forecast I've specified three hundred sixty five days, which is more than one
year in trading time.
But recall that the forecast gives you all the dates without skipping non-trading days.
So basically this will be a one year forecast.
OK, so looking at this plot, we see that it's not really a great fit.
Moreover, notice that there seems to be some high frequency seasonal component in the forecast, which
is weird because we know that stocks shouldn't look like this.
If we look at the info printout, we see that daily seasonality has been disabled, which makes sense,
but weekly seasonality has remained intact.
Thus, we can assume that these weird little peaks are due to a false weekly seasonal component.
Also, remember that profit is only capable of producing linear and logistic trends.
Thus, this forecast simply assumes that the stock price will continue to go down in the future, which
of course may not be sensible.
The next step is to plot the components.
So one interesting thing that should catch your eye is that the prediction interval for the trend that
gets big very rapidly, this suggests that our model is not really sure of this trend.
The next thing to notice is that there is, in fact, a weekly seasonal component, which makes no sense.
We see that the values increase on the weekends, which cannot be the case since the market is not open
on the weekends.
The final thing to look at is the yearly seasonal component.
Now, this might be real or it might not be.
However, note that the magnitude of this component is much smaller compared to the trend.
So although there seems to be an increase from April to August, this would still be overtaken by the
trend.
OK, so recall that for the previous model, we simply use the default settings for instantiating profit.
What I want to show you in this next example is what not to do, which can be found on essentially every
blog article on this topic, like blog articles on Lithium's.
My suspicion is that these are people who have just all copied from each other.
So the difference here is that we are setting daily seasonality to true.
Of course, this makes absolutely zero sense because our data is daily.
Remember that weekly seasonality is for detecting repeating patterns from one week to the next, which
requires a sub weekly time series.
Yearly seasonality is for detecting patterns that repeat from one year to the next, which requires
a sub yearly time series.
Thus, in order to have daily seasonality, we must have data which is sub daily, which we do not.
However, note that when we run this, we do, incidentally, end up getting a smoother plot.
Of course, this is still not satisfactory because it's based on false presumptions.
The next step is to plot the components.
OK, so most of this we've seen, but the interesting part should be the daily seasonal component.
Now, you should be very worried when you see this because it means your model is doing something which
is impossible.
It's showing us that there are periodic changes within the day, which obviously our model has no chance
of knowing because our data only has daily granularity.
The next step is to create another model, but this time we're going to do what we should have done,
which is to set weekly seasonality to false.
This will help us avoid any false weekly patterns.
OK, so notice how this ends up giving a supply without those very small weekly jumps that we saw the
first time.
The next step is to plot the components.
So essentially, this is very similar to the previous plots, except that now we don't have any false
weekly patterns nor any false daily patterns.
In this next step, we're going to perform cross-validation, the goal of this is not to do cross-validation
per say, but to compare it to the baseline forecasts.
As you recall, I've stated multiple times that this is essential.
If you want to claim that your model can predict stock prices, clearly it's not very good if it cannot
beat simply predicting the last value.
OK, so we're going to start by doing all the necessary imports.
The next step is to create a model setting weekly seasonality to false.
The next step is to fit our model.
The next step is to call cross-validation.
Now you'll notice that I've said both period and horizons of five, you can feel free to try other values,
but you'll probably see that you get the same results.
Note that I've also tried this with 15, 30 and 30, 60.
Either way, the result has not changed.
The next step is to call the head function to remind ourselves what the KVI data frame looks like,
we're going to end up doing a little hack in order to evaluate the new forecast based on this format.
OK, so the next step is to create a data frame called naïf, which we're going to initialize as a copy
of Dfki, note that I've only taken four out of the six columns.
The basic idea is we're going to use this data frame with the same format, but we are going to replace
the white hat column with the night forecast.
Now, because this data frame has the same format as the previous one, we can use all the same functions.
So we can use profits, functionality to get the rolling SMAP, which is what we'll use to compare the
two approaches.
So the next step is a tiny bit complex, but basically we're going to implement the night forecast.
As you recall, the DFAC data frame contains two columns which saw a timestamp.
The cutoff column is where the forecast starts and the D column is the timestamp we are making a forecast
for.
Thus, every forecast should come from its cutoff day.
Now, unfortunately, not every cutoff date exists in the Time series since, as you recall, we only
have prices for trading days.
So the basic strategy is we're going to look backwards to get the last known price and use that as the
prediction.
OK, so to start, we're going to create an empty array of zeros called naive storage.
This is where we will store the predictions.
The next step is to loop through every row of the naïf data frame inside the loop.
We're going to grab the cutoff date.
The next step is to check whether or not this cutoff date exists in the data frame.
If it does not, then we will enter this wide loop where we decrement cut off by one day.
So this loop will only quit when we have found a date which actually has a price.
Once we found this data, we assign the value in the Y column to our naïf storage array at Index I.
Once we are outside the loop, we can then assign naïf storage back to white hat.
And at this point we will have our new forecast.
OK, so the next step is to call performance metrics on Dev CSV, which contains our model predictions,
since we'd like to summarize this in a single number, we're going to take the mean of the SMAP.
Now, of course, this number isn't useful by itself, it's only useful relative to the benchmark.
So the next step is to call the same function on the naïf data frame.
And as you can see, it turns out that the naive forecast wins yet again.
The next step is to make a plot of the cross-validation results.
As expected, we see that the forecast error tends to grow over time.
Now, you might wonder whether or not this will work if we use profit on the log price instead of the
price.
So in this next portion of the notebook, we're going to repeat the same steps, but using the log price
instead.
So the first step is to make a copy of Googs and then compute the log of the price.
The next step is to create a model, fit the model, perform cross validation and compute the SMAP.
OK, so this is the number we get for profit.
The next step is to compute the naive forecast note that this is the same code as before.
OK, so again, we find that the naive forecast wins.
The final step is to make a plot of the cross-validation results.
So, again, we see that over time, the forecast error increases.