Learn to predict stock prices using HMM in this article by Ankur Ankan, an open source enthusiast, and Abinash Panda, a data scientist who has worked at multiple start-ups.
A Hidden Markov Model (HMM) is a specific case of the state space model in which the latent variables are discrete and multinomial variables. From the graphical representation, you can consider an HMM to be a double stochastic process consisting of a hidden stochastic Markov process (of latent variables) that you cannot observe directly and another stochastic process that produces a sequence of the observation given the first process.
HMMs are capable of predicting and analyzing time-based phenomena. Hence, they are very useful in fields such as speech recognition, natural language processing, and financial market prediction. In this article, you’ll look into the applications of HMMs in the field of financial market analysis, mainly stock price prediction.
Stock Price Prediction
The stock market prediction has been one of the more active research areas in the past, given the obvious interest of a lot of major companies. Historically, various machine learning algorithms have been applied with varying degrees of success. However, stock forecasting is still severely limited due to its non-stationary, seasonal, and unpredictable nature. Predicting forecasts from just the previous stock data is an even more challenging task since it ignores several outlying factors.
HMMs are capable of modeling hidden state transitions from the sequential observed data. The problem of stock prediction can also be thought of as following the same pattern. The price of the stock depends upon a multitude of factors, which generally remain invisible to the investor (hidden variables). The transition between the underlying factors change based on company policy and decisions, its financial conditions, and management decisions, and these affect the price of the stock (observed data). So, HMMs are a natural fit to the problem of price prediction.
Now, you can put this to test by predicting the stock prices for Alphabet Inc. (GOOGL), Facebook (FB), and Apple Inc. (AAPL) with HMM.
Collecting Stock Price Data
Use pystock data (http://data.pystock.com) to get the historical stock prices data. Every day, before the US stock exchanges open at 9:30 EST/EDT, the pystock crawler collects the stock prices and financial reports, and pushes the data, such as the previous day’s opening price, closing price, highest price, and lowest price for a given stock, to the repository. This data is day-based, which means that there won’t be any hour or minute-level data.
Download the pystock data for a given year. As the dataset is large, create a Python script to download the data for a given year and run the program simultaneously for three different years to download all the data in parallel:
Run the following scripts simultaneously for three different years:
python get_data.py --year 2015 python get_data.py --year 2016 python get_data.py --year 2017
Once the data is downloaded, get all the data for each of the preceding stated stocks by combining data corresponding to all years:
Run the following scripts to create a .csv file containing all the historical data for the GOOGL, FB, and AAPL stocks:
python parse_data.py --company GOOGL python parse_data.py --company FB python parse_data.py --company AAPL
Features for Stock Price Prediction
You have very limited features for each day, namely the opening price of the stock for that day, closing price, the highest price of the stock, and the lowest price of the stock. So, use them to compute the stock prices. You can compute the closing stock price for a day, given the opening stock price for that day, and previous some d days’ data. Your predictor would have a latency of d days.
Now, create a predictor called StockPredictor, which will contain all the logic to predict the stock price for a given company during a given day.
Instead of directly using the opening, closing, low, and high prices of a stock, extract the fractional changes in each of them that would be used to train your HMM. Define these parameters as follows:
For the stock price predictor HMM, you can represent a single observation as a vector for these parameters, namely Xt= < fracchange, frachigh, fraclow >:
Predicting Price Using HMM
The first step in predicting the price is to train an HMM to compute the parameters from a given sequence of observations. As the observations are a vector of continuous random variables, assume that the emission probability distribution is continuous. For simplicity, assume that it is a multinomial Gaussian distribution with parameters (μ and Σ). So, you have to determine the following parameters for the transition matrix, A, prior probabilities, π, along with μ and Σ, which represent the multinomial Gaussian distribution.
For now, assume that you have four hidden states. In the coming sections, you’ll look into the ways of finding the optimal number of hidden states. Use the GaussianHMM class provided by the hmmlearn package as your HMM and perform parameter estimation using the fit() method provided by it:
In machine learning, you divide the entire dataset into two categories. The first set, the training dataset, is used to train the model. The second set, the test dataset, is used to provide an unbiased evaluation of a final model fit on the training dataset. Separating the training dataset from the test dataset prevents from overfitting the data into the model. So, in this case, split the dataset into two categories, train_data for training the model and test_data for evaluating the model. To do so, use the train_test_split method provided by the sklearn.model_selection module:
The train_test_split can split arrays or matrices into the random train and test subsets. As you train your HMM with sequential data, you do not want to randomly split the data. To prevent random splitting of the test and train data, pass shuffle=False as the argument.
Once your model is trained, you need to predict the stock closing price. As mentioned earlier, you want to predict the stock closing price for a day given that you know the opening price. This means that if you are able to predict fracchange for a given day, you can compute the closing price as follows:
Thus, your problem boils down to computing the Xt+1 = < fracchange, frachigh, fraclow > observation vector for a day given the observation data for t days, x1,…,xt, and the parameters of the HMM
, which is finding the value of Xt+1 that maximizes the posterior probability of P(Xt+1|X1,…,Xt,θ):
Once you remove all the parameters that are independent of Xt+1 from the maximization equation, you are left with the problem of finding the value of Xt+1, which optimizes the probability of P(X1,…,Xt+1|θ). If you assume that fracchange is a continuous variable, the optimization of the problem would be computationally difficult. So, divide these fractional changes into some discrete values ranging between two finite variables (as stated in the following table) and find a set of fractional changes, < fracchange, frachigh, fraclow > that would maximize the probability, P(X1,…,Xt+1|θ):
|Observation||Minimum value||Maximum value||Number of points|
So, with the preceding discrete set of values, run (20 x 10 x 10 =) 2,000 operations:
Now, implement the method to predict the closing price, as follows:
Predict the closing price for some days and plot both the curves:
The output is as follows:
You’ve successfully predicted the price of stocks using HMM. You applied the parameter-estimation and evaluation-of-model methods to determine the closing price of a stock. Using HMM in the stock market analysis is just another example of the application of HMM in analyzing time series data.
Thank you for reading!
If you liked this article, explore Hands-On Markov Models with Python to unleash the power of machine learning. Hands-On Markov Models with Python helps you get to grips with HMMs and different inference algorithms by working on real-world problems.