Portfolio Optimization Demo (with Distributed Arrays and SPMD)

This demo calculates returns the risk-return relationship in the stock portfolio that is optimal in the mean-variance sense. covMat and expRet are the covariance and mean returns of a collection of stocks and muVec is a vector of desired returns.

The covariance matrix (covMat) is calculated using distributed arrays. To calculate the covariance matrix we must process a large data set comprising several thousand time points for each stock. For this exercise, for demostration purposes, we use a reduced dataset so as to fit all the data in a single computer running four local workers. However, for higher-fidelity simulations one would require higher number of data points for a larger number of stocks. This can quickly breach the limits of a single desktop computer.

Once the covariance matrix is computed, since it is N x N where N is just the number of stocks, it can be held in a single computer's memory and used locally.


Clear out all old variables

clear all

Opening a matlabpool

if matlabpool('size') == 0
    matlabpool open 2
    warning('MATLAB:poolOpen', 'matlabpool already open')
Starting matlabpool using the parallel configuration 'local'.
Waiting for parallel job to start...
Connected to a matlabpool session with 2 labs.

Loading in historical stock data

numFiles = 4; % number of files to use
numStocks = 200; % number of stocks to use
numPoints = 10;  % number of points on the efficency frontier

x = Exercise2_loadReturns(numFiles,numStocks);
  1 ans =
          144004         200
  2 ans =
          144004         200

Calculating the covariance matrix

    [n,m] = size(x);

    % calculating the covariance and expected return
    expRet = sum(x)/m;
    expRet = gather(expRet);

    x = bsxfun(@minus,localPart(x),sum(localPart(x),1)./m);  % Remove mean
    x = codistributed(x, codistributor('1d',1));

    covMat = (x' * x) / (m-1);
    covMat = gather(covMat,1);


Calculating range and points along the efficency frontier

expRet = expRet{1}; % getting data back from workers
covMat = covMat{1}; % getting data back from workers

retRange = [min(expRet(expRet > 0)) max(expRet)];
rangeFudge = abs(diff(retRange))/20;  % a little above and below the range
retRange = retRange + [rangeFudge -rangeFudge];
muVec = linspace(retRange(1), retRange(2), numPoints); % points along frontier

Find the frontier for the stock portfolio

This function uses a parfor. You can combine parfor and spmd in the same program along with serial code. View code for Exercise2_task_optim

[risk, ret] = Exercise2_task_optim(covMat, expRet, muVec);


fig2 = figure;
Exercise2_plot_optim(fig2, risk, ret);

Close the matlabpool

if matlabpool('size') ~= 0
    matlabpool close
    warning('MATLAB:poolClose', 'matlabpool already closed')
Sending a stop signal to all the labs...
Waiting for parallel job to finish...
Performing parallel job cleanup...