AI Mole
Published on

Investington project - machine learning for stock market analysis

Authors
  • avatar

For quite some time now, I have been interested in machine learning for equity investments and have developed a system that allows me to select the most promising assets. The system, over the long term, has consistently and significantly outperformed the market, with a comparable drawdown. The forecasts are provided on Investington website, in real time. This article describes the basic principles of the strategy. I should mention that I am not an economist, but an engineer, so I will describe the technical component of the model.

The idea was to make a system that would automate the selection of stocks in a portfolio, reduce the time spent on it, and avoid the human factor in making the decision. To begin with, I had to come up with a certain concept, so I started wandering around sites like Yahoo, looking at quotation charts and studying the performance of companies. During the search process, Renault caught my interest. I was working for their direct competitor at the time and knew that they were doing great - they were taking specialists away from us one by one. But at the same time, their shares were constantly falling. As it turned out, it was due to global factors - markets were reorganizing, some manufacturers were having difficulties, especially in Asia, and there was a high-profile scandal with their director, who was transported in a grand piano from a Japanese prison. As a result, their stock dropped from 100€ to 50€, although the company was doing fine. After looking at the charts, I decided that the quotes should return to previous levels, i.e. with a return of 100%, in a horizon of 3-4 years (25%/year). It was decided to formalize this idea :

  • company with large market cap (size)
  • the company is not unprofitable, but cheap. (As a criterion - either PER or current price compared to the maximum over 5 years + consistently positive reporting)
  • absence of macroeconomic negative factors (sanctions, dying sector)

By picking about 10 stocks in this way and locking in profits at 25%/year, over a 3-4 year horizon, you can get quite interesting returns with minimal effort. But what if the stock doesn't grow or continues to fall? Essentially the strategy came down to filters by criterion.

I decided to test this logic on history. I wrote a simple script that "traded" my algorithm on data for the last 15 years, selecting stocks that fit the criteria and updating the portfolio day by day. The run confirmed my doubts - many stocks did not return to their original values and kept falling. The percentages averaged 12-13%, but it was obvious that the criteria were too primitive. Besides, it was not clear at what point to close losing positions. I made some important observations:

  • I started to calculate not the absolute value of the percentage, but the percentage over a period of time. For example, I counted returns of 100% for one year and 150% for two years as 100% and 75% for one year. Later I came to calculate returns per working day (250 working days in a year, 25% annualized -> 0.1% per day).

  • I always limited the position by time. At the end of the interval I closed it.

  • I did not try to predict the exact future price, but I determined the level that the stock should reach. This is probably the most important point, which I will call "hypothesis" in the future

  • I always limited the position by time. At the end of the interval, I closed it.

  • I did not try to predict the exact future price, but I determined the level that the stock should reach. This is probably the most important point, which I will call "hypothesis" in the future

  • I did not use stops. Why not? Stops came to us from trading. And there they are more than appropriate - you cannot afford a 20% drawdown with x5 leverage. At the same time, most people know the phenomenon of triggering in Forex, when the price touches a stop and the position is closed, and then a reversal follows. And so the deposit is slowly eaten up. I decided to use the opposite approach - to put fixed take-outs and not to follow the drops. What about risks, you will say? If you diversify into 10 stocks, a 50% drop in one of them is only 5% of your deposit. At the same time, the probability that two stocks in the portfolio will collapse at the same time is less than 0.5%. Since I was planning to invest and not trade, I thought that diversification would be enough to protect me from risks. At the same time, all the strategies that I tested on a long-term perspective, with stops always gave worse results than without them. However, I'm still not convinced that this is a good approach since stops prevent us from unmeasurable risk of dropdown, so this is something i'll strongly suggest to integrate in any real money strategy.

From this, I derived a rather interesting formula by which I was able to estimate the potential profit of the strategy:

  • I expected 100% in two years -> 50%/year
  • 65% of the trades in the simulation were profitable

Based on this, the approximate projected profit would be:

Profit = (2*Probability-1)*Target

Example: (2*0.65-1)*50 = 15

This simple calculation matched the simulation with +-5% accuracy. From this, I realized that it is possible to find the optimal ratio of position duration to profit and then maximize the accuracy of the prediction. The problem is that these values depend on each other. That's where machine learning comes in.

So, the idea is quite simple - why search for stock selection criteria yourself when you can optimize them. Machine learning is ideally suited to this task. It allows you to build a model that estimates a certain value (output, Y) based on a set of criteria (input, X). There are quite a large number of methods. Here is a very brief description of what they are.

Let's start with the basics: there are three main classes of tasks: supervised (1), non-supervised (2) and reinforcement learning (3). In the first case, there is a dataset, each element of which corresponds to a pair (X, Y), and the trained model describes the relationship between them. In the second case, for each element only X is known and the model groups similar elements, as if "inventing" Y. The third, most complex variant: it is assumed that there is a certain environment, which, in response to the action Y, gives a reward R. We try to build a model that so links X and Y as to maximize R. It is assumed that X is known and it is possible to compute R through Y. We will use the first method, supervised learning. Why? It is by far the most efficient and well-studied.

There are two main types of problems - regression and classification. In the case of regression - Y is a continuous value, and in the case of classification - Y corresponds to some category and takes fixed values, e.g. 0 and 1. Most existing stock exchange solutions try to predict the price of a stock (regression). But the results of such models are usually not accurate enough, and they suffer from the numerical conditions of the problem (for example, the model of price estimation by 100 previous values is likely to give the most probable price equal to the current one :). I suggest asking the question -- why would I want to predict the price? Market change is a random process. It is important to understand that random means not that the process is completely unpredictable (white noise), but that its state cannot be described precisely. But it is possible to statistically estimate a certain zone of uncertainty, which will include the real value. So we need to model this uncertainty.

What do we really want to know? Whether a particular stock is worth buying or not. Is it (1) or not (0)? So, the learning model will take available data as input (X) and predict whether the stock is worth buying (Y). But there's a catch - how do you set Y? And here we go back to our previous observations:

  • I forecast the level of price change, not a specific price
  • I limit the forecast to a specific time frame.

Bingo! If a stock crosses level B at least once during period A, its Y=1. If not, it is 0. We calculate the level as a relative value to the current price. After that, it is enough to train the model on the corresponding data. The resulting problem is quite simple and is equally well solved by most modern ML methods: both random forests, boosting and a small recurrent neural network like LSTM also finds a fairly accurate solution without any problems.

Using my formula of profitability, I found optimal values for the period and % of forecast and, based on them, set Y. This is how I got my first trading system:

  • every day, when the market opens, data on all available stocks is downloaded
  • the model checks each stock for growth potential
  • it makes a list of positive stocks.
  • if there is free money - stocks are bought into the portfolio (either randomly or according to another rule. Diversification by sectors, capitalization, profitability - any fundamental criterion you like).

Such a model is easily automated and verified on history. After validation I got 28% annualized returns and my model v1.0. Next I started to improve it.

The first problem I encountered was that even though the model gave 80%+ successful trades, negative trades were more unprofitable. For example, if I earned 10% on +, I could lose 30% and 40%. I decided to train another model that would test stocks for the probability of falling. The training was done in the same way as for growth, but the Y values were set differently. The combination of the two models reduced the number of "good" stocks, but reduced the failed predictions by a factor of 2-3. We will consider this to be model v2.0.

In the third (current) version, I have incorporated several changes at once. First, having seen the effectiveness of combining several models, I started adding hypotheses (long-term growth, short-term jump, etc.), thus forming about 30 models. But when there were many models, the question arose - how to combine them? The second open problem was the final stock selection - it was unclear how to rank positive signals, which were more than 50 per day.

Here we should make a caveat. The model classifier gives an output value from 0 to 1. As a rule, it is considered that values lover than 0.5 equal to 0 and vice versa. It is logical to assume that the higher the value, the more accurate the prediction. In fact, this is not (necessarily) the case. Due to the fact that the model only takes labels equal to 0 and 1 during training, there is no way of grading the accuracy of the prediction (for more on the topic, see the article on label distillation). To solve both problems, I decided to add a calculation of the probability of prediction accuracy.

Let's imagine that we have a label from 0 to 1. How do we relate it to probability? My solution is empirical. Having some historical data set, we can statistically calculate the expectation matrix of the prediction accuracy for each label value and plot the corresponding calibration curve. Naturally, such an estimate may not be accurate and may vary over time, but by estimating it over a floating window of a year, I calculated that the standard deviation did not exceed 7% (hello to all those who say the market is not stationary). The probabilities were calculated for each model separately and combined using the conditional probability rule to calculate the total. The resulting model is v3.0. This model has already shown an average annualized return of 42% over the last 15 years when trading a portfolio of 10 stocks.Making an investment portfolio using machine learning

I have been using my model since the end of 2019 on a live account. Taking into account the lockdown and the crisis, the results of using it were 34% in €, which is more than decent in my opinion. The method is not perfect and will be improved by me, but it is more than interesting just for reliable and long-term investments. I have not found the results of any investor with better historical performance over the long term (I don't take traders into account and I don't use leverage). A few observations:

  • you need to survive the first 3-4 months until the account is consistently over its initial level
  • you have to stick to the plan. Always. Even when it seems unreasonable. None of my actions outside of the strategy brought more profitability than the potential trades of the system in the same period.
  • After about a year, the actions become automatic, every small case seems simple and familiar. You start to get real pleasure from trading.

And now I am finalizing the fourth version of the model, which will be more accurate than the previous one and will give even better forecast. Special attention will be paid to risk management and new functions will be added.

Project is free of use and accessible. However, I disclaim that this is only a machine learning based probability evaluation and in any case not a professional recommendation for trading or a call to action