Verushen Coopoo, Application Engineer
Opti-Num Solutions (2019)
In this script, we demonstrate the strength of MATLAB’s optimisation capabilities to construct a portfolio driven by smart beta investment techniques. We do not advocate for the use of any particular investment or trading strategy, but rather demonstrate how to import your own data, implement a custom-made optimisation routine, and backtest the strategy: all in one place. We supply the code in the form of this live script for you to get started right away.
The methodology used in this example is risk parity, where the weightings of all assets in this portfolio are calculated such that they all contribute the same level of marginal risk to the portfolio.
We import 14 years’ worth of data from 20 stocks on the JSE, optimise for the best portfolio and then back-test the strategy to see how the risk evolves over time. In this way, we show how quickly a portfolio manager can build desktop tools to test and optimise for a custom strategy.
In this example, the assets are 20 randomly stocks which are listed on the JSE. We import approximately 14 years’ worth of prices.
The functions getDate and getStock were automatically generated by the MATLAB Import Tool. The MATLAB Import Tool is useful because it allowed me to explore the data interactively, choose what data I want and then to generate the code automatically. These two functions are included as local functions at the end of this live script.
Let’s visualise the stock prices as a set of time-series to get a feel for the data.
The in-sample data set is going to be the amount of time which the optimisation uses in its calculation of the optimal portfolio. The remaining time, which is then the out-sample, will be used to backtest the portfolio. Once you’ve gone through the code, use the slider to vary numInSample to see how this changes the portfolio and its backtest results. Sliders, drop-down menus and checkboxes are examples of some of the graphical components you can integrate in your live script. It enriches your code and lets you experiment with your analysis.
We calculate the returns, as well as the mean of the returns and covariance matrix of the returns as inputs for our portfolio optimisation routine.
A portfolio optimisation is a straightforward application of mathematical optimisation. In order to leverage this, we specify our objective function, initial condition and constraints.
The key to solving your optimisation problem is choosing a solver. The solver dictates the approach and algorithm that MATLAB uses to perform your optimisation, and your choice of solver is governed by the nature of your problem, i.e. the mathematical properties of your constraints an objective function.
MATLAB allows the optimisation of a constrained, non-linear system via a solver called fmincon. There are plenty of other solvers including those for quadratic or linear least-squares problems. The use of fmincon is powerful because it allows complex, non-linear systems to be optimised.
We define additional options below.
The function riskCostFunction is what governs our optimisation. Customising this function is key to implementing your own investment strategy. You can view it at the end of this script as a local function.
Essentially, riskCostFunction accepts a vector of marginal risk contributions. It forms a matrix of these contributions. This matrix is a special type of matrix called a distance matrix, where each element in the matrix has a “distance” to every other element. By minimising all of these distances – by making all the distances as close to zero as possible – it makes the marginal risk contributions the same. This is what allows us to implement the risk parity.
It is a function customised to our own needs, which you can view at the end of this script as a local function. We chose to implement our own, customised optimisation.
Constraints are important to control your optimisation. Firstly, we define the initial allocation of all our assets such they are equally weighted.
We now constrain the allocation such that the sum of all weightings adds up to 1.
We define the upper and lower bounds such that the final weighting for each asset must be greater than or equal to zero 0 and less than or equal 0.25, i.e. .
We have set up our problem. The only thing left to do is to run our optimisation! The line of code below uses fmincon with our custom-defined objective function, riskCostFunction and constraints, in order to optimise our portfolio.
The outputs of the optimisation are fixWeights and fVal, where fixWeights are the weightings of the assets in our optimised portfolio. They are “fixed” because they are based off of a fixed set of stock data, which you can vary using the slider numInSample. fVal is the output of the fmincon at each stop in the optimisation. We do not use it, but it can be useful as diagnostic information to see how the optimisation is performing.
Let’s visualise the weights returned by the optimisation routine.
We see that GRT is weighted quite heavily. Due to the equal risk parity weighting scheme of this optimisation, this implies that GRT presents less risk to the portfolio. It is thus weighted more. Conversely, riskier stocks are weighted less.
Once the weightings have been applied, we expect that all the weighted stocks should present the same amount of risk to the portfolio – and indeed, they do.
Using MATLAB’s Portfolio object, we march the portfolio through time to see how the composite risk changes with time.
We have seen how the risk evolves as a function of time. Now, let’s visualise how the risk changes as a function of time for each stock. This yields the 3D plot below.
We indeed see that the risk of all assets is set to be the same when the investment period begins.
Using MATLAB, we have automated a time-consuming component of a portfolio manager’s workflow when looking to explore a new strategy: we imported data (using automatically generated functions), created our own optimisation according to the principles of risk parity, and we back-tested our results to see how the risk of our portfolio will evolve.
Now that you have explored risk party with MATLAB, what’s next: hierarchical risk parity, which uses machine learning to allocate the asset weights, or the Black-Litterman model which incorporates an economist’s views into your asset allocation? It’s time to download the live script and optimise your own strategy and to speak to us abut implementing bespoke investment or optimisation strategies.
At the end of the day, if you can think it, it can be done with MATLAB!
Calculate the marginal contributions, forassets with returns according to the equation below, where is the initial weighting.
As you can see, MATLAB live scripts allow you to take your analysis and reporting to the next level by including your equations alongside your code.
This is a cost function for the to get equal risk-contribution portfolio.
Owen, D. MATLAB for Portfolio Construction: Smart Beta & Stock Selection. [https://www.mathworks.com/videos/matlab-for-advanced-portfolio-construction-and-stock-selection-models-120626.html] 2016