Quantitative finance collector
C++ Matlab VBA/Excel Java Mathematica R/Splus Net Code Site Other
Oct 5

Is NAG Toolbox Faster Than MATLAB's Fsolve?

Posted by abiao at 10:36 | Code » Matlab | Comments(5) | Reads(12098)
Walking Randomly is a blog I visit frequently devoting to share some fun stuff like how to use things like Matlab, Mathematica, Python, Condor, Beowulf clusters etc. Recently, I was reading a blog post on how to replace MATLAB's fsolve function with the NAG Toolbox for MATLAB  in order to get quite dramatic speed gains and thought I'd try it out for myself with a practical example in finance.

To make good use of fsolve, the example is to solve the Markowitz problem by finding an optimal portfolio with minimum variance for a targeted return, mathematically, for a portfolio of n risky assets we want to find the solution to:

subject to

here r-bar is a fixed pre-desired level for expected rate of return, and a solution is any portfolio that minimizes the objective function (variance) and offers expected rate r-bar. This is an example of what is called a quadratic program, an optimization problem with a quadratic objective function, and linear constraints. By introducing Lagrange multipliers and taking the first  derivative a solution to our Markowitz problem is found by finding a solution to the set of n + 2 linear equations

In the end, the problem falls into the standard framework of linear algebra, and amounts to computing the inverse of a matrix: solve Ax = b, and finally fsolve can be used directly.

To make the problem bigger, I set up a pool with 500 assets, randomly simulate 5-year return and optimize my portfolio under a given target return. 500 assets may be too many for most applications but the set-up of this example is fair enough as we usually have to impose other constraints in reality such as the maximum or minimum weights allocated to a certain industry, etc.

function MarkowitzWeight = fsolve_markowitz_MATLAB()
RandStream.setDefaultStream (RandStream('mt19937ar','seed',1));
% simulate 500 stocks return
SimR = randn(1000,500);
r = mean(SimR); % use mean return as expected return
targetR = 0.02;
rCOV = cov(SimR); % covariance matrix
NumAsset = length(r);

startX = [1/NumAsset*ones(1, NumAsset), 1, 1];
x = fsolve(@fsolve_markowitz,startX,options, r, targetR, rCOV);
MarkowitzWeight = x(1:NumAsset);

function F = fsolve_markowitz(x, r, targetR, rCOV)
NumAsset = length(r);
F = zeros(1,NumAsset+2);
weight = x(1:NumAsset); % for asset weights
lambda = x(NumAsset+1);
mu = x(NumAsset+2);

for i = 1:NumAsset
    F(i) = sum(weight.*rCOV(i,:))-lambda*r(i)-mu;
F(NumAsset+1) = sum(weight.*r)-targetR;
F(NumAsset+2) = sum(weight)-1;

I performed the calculations tic; fsolve_markowitz_MATLAB(); toc on a computer running Windows XP, MATLAB 2008b and got the following timings (averaged over 10 runs): 3.35 seconds.

So Michael, are you able to speed up my example for 19.7 times faster?

Tags: , , ,
I have added a blog post to this debate. Please see:http://rationalize-this.blogspot.com/
Thanks, VoR, that's another way to speed up, I admit I should have used vectorization in Matlab. The main purpose of this post is to test the optimization (fsolve vs c05nb) for given codes, replacing one with each other.
Yes, I see that. But it is also important to note that I got a different solution.
The difference is too small to be paid attention, I guess, 1E-11, it may be due to the setting of your Matlab.
I’ve been visiting your blog for a while now and I always find a gem in your new posts. Thanks for your usual wonderful effort. brain teaser games
Pages: 1/1 First page 1 Final page
Add a comment
Enable HTML
Enable UBB
Enable Emots
Nickname   Password   Optional
Site URI   Email   [Register]