Introduction to forecasting Philippine stock prices using Facebook’s Prophet

To do this, we have to first filter the DataFrame to have only two columns: the date, “CHART_DATE” and the closing price, “CLOSE”.

Then, we change their names to “ds” and “y”, respectively, since Prophet automatically reads the “ds” column as the date and the “y” column as the variable being forecasted.

Finally, we train the model on the training data, which refers to the data before the beginning of a specified holdout period.

In this case, “HOLDOUT_START” is the date corresponding to the beginning of the holdout period (set at 2019–03–01).

Note that the data for the holdout period will be treated as our validation set and will be used in assessing the performance of the trained Prophet model.

# Set holdout (validation) set startHOLDOUT_START = '2019-03-01'# Import the Prophet packagefrom fbprophet import Prophet# Filter to only the date and closing price columnsts = jfc[['CHART_DATE', 'CLOSE']]# Rename the date and closing price columns to 'ds', and 'y', respectively# We do this since prophet automatically reads the 'ds' column as the date and the 'y' column as the variable that we are forecastingts.

columns = ['ds', 'y']# Fit the Prophet model to the training data (before the start of the holdout set)# We set daily_seasonality and yearly_seasonality to True to account for daily and yearly seasonality, respectivelym = Prophet(daily_seasonality=True, yearly_seasonality=True).

fit(ts[ts.

ds < HOLDOUT_START])5.

Predict the future!In Prophet, we do this by first creating a future dataframe, where we specify how far into the future we want to forecast; in this case, we set it to 336 days.

Next, we call the predict method found inside the trained prophet model (using the future dataframe as an argument) and this returns the predictions.

# Set the forecast period, "periods", in the specified unit, "freq"# In this case, we're predicting 336 days into the futurefuture = m.

make_future_dataframe(periods=7*4*12, freq='D')# Make the actual predictionspred = m.

predict(future)# Visualise the predictions using Prophet's plotting methodfrom matplotlib import pyplot as pltfig1 = m.

plot(pred)plt.

title('Jollibee: Forecasted Daily Closing Price', fontsize=25)The forecasts along with historical closing prices are shown above.

The blue line corresponds to the forecasted closing prices, while the black dots correspond to the historical closing prices from the training set.

The forecasted closing prices for the holdout period indicate that prices will go down for that period (2019–03–01 to 2019–04–26).

The shaded blue region corresponds to the forecasted 95% confidence intervals.

You will notice that forecasts that are further away, also have wider forecasted confidence intervals.

6.

Assess accuracyTo assess the accuracy of our trained Prophet model, we will compute the root mean squared error (RMSE) of our predictions on the holdout set from 2019–03–01 to 2019–04–26.

To visualise performance in more detail, we also plot the predicted JFC closing price vs the actual JFC closing price for the 57 day holdout period.

# Concatenate holdout (validation) set predictions and targets into one dataframe for easy comparisonpred_holdout = pred[(pred.

ds >= HOLDOUT_START)&(pred.

ds <= ts.

ds.

max())].

set_index('ds').

yhattarget_holdout = ts[ts.

ds >= HOLDOUT_START].

set_index('ds')comb = pd.

concat([pred_holdout, target_holdout], axis=1).

dropna()# Calculate root mean squared error (RMSE)import numpy as nprmse_holdout = np.

sqrt(comb.

yhat.

subtract(comb.

y).

pow(2).

mean())# Plot predicted vs target while displaying accuracy based on rmsecomb.

columns = ['Predicted', 'Actual']comb.

plot(figsize=(15, 10))plt.

title('Predicted (yhat) vs Actual (y) JFC Closing Price.Validation Set RMSE: {}'.

format(rmse_holdout), fontsize=25)As stated earlier, the forecasted prices (blue) for the holdout set indicate that prices would go down overall for the duration of the holdout set.

Interestingly, the actual prices (orange) also showed an overall decrease in JFC’s closing price, although sharper than the one predicted.

In addition, the short term movements also appear to be reflected by the forecasts.

The actual trend shows an initial increase up to April 8, and then a drop leading to April 26.

Again, the forecasts show similar movements, although not as sharp.

The calculated root mean squared error (RMSE) of 5.

56 tells us that on average (with increased weight on large errors) the Prophet model’s JFC closing price predictions are wrong by PHP 5.

56 for the holdout set from 2019–03–01 to 2019–04–26.

Is this error small enough for us to trust the predictions? That will depend on our willingness to take on risk, but a conservative rule of thumb is to only make trades on forecasts that indicate a profit opportunity even at the expected downward deviation from the forecasted price.

What’s next?Congratulations! You now know how to execute a basic forecasting workflow using the powerful Prophet package.

This involved the following steps: 1) installing and importing the necessary packages, 2) getting the data, 3) plotting the time series, 4) training the Prophet model, 5) predicting the future using the model, and finally, 6) assessing accuracy.

This same workflow can be applied using other forecasting models and for use cases other than predicting stock prices.

It’s important to note that there are still many ways to improve our current forecasting workflow:Use exogenous variables and derived indicators for prediction.

We can explicitly account for information other than the stock’s past closing prices (exogenous variables).

Examples of these are a stock’s traded volume, the price and volume of other stocks, interest rates, inflation, success of a recent ad launched, and other derived metrics like moving volatility, RSI, short-term & long-term moving average, etc.

Identify events that can catalyse price movement.

Examples are company related announcements (often disclosed on twitter) such as those about performance, mergers & acquisitions, new laws, etc.

We can model these specifically in order to estimate their impact on the price.

Experiment with other powerful models.

I often use Prophet as a baseline but still end up using other models that beat the base model’s performance.

Examples of these are gradient boosting machines (e.

g.

LightGBM), deep learning models (e.

g.

LSTM RNNs), and other cutting edge time series models (e.

g.

TBATS, SARIMAX).

Improve accuracy of forecasted model uncertainty.

Aside from the performance of point forecasts, arguably more important is the accuracy of forecasted uncertainty, which can guide us in knowing when to trust the model’s predictions more.

This has been a focus of recent research and some have successfully created models that accurately predict 95% confidence intervals that actually cover 95% of targets.

Visualise estimated impact via simulation engines.

By creating models that can account for external factors and events, we can turn these models into simulation engines that can visualise how prices will change across different scenarios (i.

e.

scenario analysis).

For example, how would the price look given a recession next year, paired with a 2% hike in interest rates?Above are only some of the many ways to improve our current forecasting workflow and I plan to discuss these in more detail in future blog posts.

If you have any suggestions on which ones to start with, feel free to comment or email me at lorenzo.

ampil@gmail.

com.

Stay tuned!.

. More details

Leave a Reply