Stock portfolio optimizer.
This project shows the application of a Nelder-Mead optimization algorithm to the well-known stock portfolio optimization problem. The original Nelder-Mead procedure has been enhanced to cope with the only portfolio constraint: stocks have to sum up to 100%.
What we'd like to have is a prediction of what a good investment would be. For an investment to be good, we'd like it to be profitable and safe (kinda), so we'll want to minimize risk, while maximizing profit. A simple objective function would therefore be:
or better, since the created Nelder-Mead optimization is a minimization technique:Nelder-Mead is an iterative simplex optimization method, which works through for operations: reflection, expansion, contraction, shrinkage. These are usually tried in this order. Basically, what they do is the following:
- Reflection: tries moving the simplex away from the sub-optimal area, by computing the reflected point through the centroid of the other points, excluding the worst one;
- Expansion: if reflection generated a point which is better than the current best, the point is moved along the same direction for a bit further;
- Contraction: if, on the contrary, the reflected point did not improve the result, we'll want to contract the simplex towards the best point;
- Shrinkage: if none of the previous did work, we'll want to re-calculate all the points except for the best one, computing them through the best one's coordinates.
Several solutions have been proposed to create the initial simplex. This implementation uses a popular one (used in the MATLAB implementation too): after selecting the initial point (randomly), the others are created using the i-th dimension unit vector :
where is a shift coefficient equal to if the coefficient of in the definition of is non-zero, otherwise.Nelder-Mead is an unconstrained method. To cope with the portfolio constraint, I introduced a fixing function that rescales the results to a percentage.
The termination is decided basing on the standard deviation of the values of the points, and a maximum number of iterations.
Hyperparameter tuning and a little bit of research led to the following parameters:
Stock data are retrieved from AlphaVantage, a free API that provides real-time stock data.
Timeseries prediction has been added to work on predicted data and not historical data only, using a Temporal Convolutional Network implemented in Darts.
First, install the requirements through pip:
$> pip install -r requirements.txt
Then, add your API secret to the code of realtime_stocks.py
and run it:
$> python realtime_stocks.py
Different scripts are available:
run_me.py
is the purest version: it uses the historical data contained inall_stocks_5yr.csv
to create a portfolio;realtime_stocks.py
is instead able to work on real data: it downloads the history of stocks values from AlphaVantage, then analyzes them through Darts and outputs an optimal portfolio;nelder_mead.py
is where the optimization is done: it provides an implementation of the Nelder-Mead iterative optimization technique, using a simplex;tester.py
provides a backtesting script that is able to test the techniques found inrealtime_stocks.py
to actually see if they work.
That's it!