Many of you who wished to use the Matlab’s Financial Toolbox for portfolio visualization most probably realised that something was wrong. Not every time the annualised risk and return for different time-series matched with what was expected. Below you can find an improved piece of code which does the job correctly.
The input sampling of your financial time-series now can be specified directly as daily, weekly, monthly, or quarterly and the risk-return diagram will be displayed with annualised results. Otherwise, you have an option, instead of annualised value, specify another time-horizon. All smooth and easy.
% Specialised plotting function for visualisation of portfolios
% based on the Financial Toolbox's portfolio objects
%
% Modified by Pawel Lachowicz, 2014/03/01
%
% Remarks: Essential corrections introduced in the calculation and plotting
% of the annualised risk and returns coded incorrectly by the team at
% The MathWorks, Inc.
function plotportfolio(varargin)
plottitle = varargin{1}; % plot title, e.g. 'Efficient Frontier'
plotfreq = varargin{2}; % frequency of raw data (dt; or 'daily', etc.)
plotfreq2= varargin{3}; % e.g. ’annualised’
plotfreq3= varargin{4};
plotlegend = [];
switch plotfreq2
case 'annualised'
switch plotfreq
case 'daily'
periods=252;
case 'weekly'
periods=52;
case 'monthly'
periods=12;
case 'quarterly'
periods=4;
end
otherwise
periods=plotfreq3;
end
for i = 5:nargin
plotinfo = varargin{i};
plottype = plotinfo{1};
plotrsk = plotinfo{2};
plotret = plotinfo{3};
if numel(plotinfo) > 3
plotlabel = plotinfo{4};
else
plotlabel = [];
end
if numel(plotinfo) > 4
plotstyle = plotinfo{5};
if isempty(plotstyle)
plotstyle = 'b';
end
else
if strcmpi(plottype,'line')
plotstyle = 'b';
else
plotstyle = 'g';
end
end
if numel(plotinfo) > 5
plotline = plotinfo{6};
if isempty(plotline)
plotline = 1;
end
else
if strcmpi(plottype,'line')
plotline = 2;
else
plotline = [];
end
end
% line plot
if strcmpi(plottype,'line')
hold on;
for k = 1:size(plotrsk,2)
plot(plotrsk(:,k)*sqrt(periods),((plotret(:,k)+1).^periods-1), ...
plotstyle, 'LineWidth', plotline);
if i == 2 && k == 1
hold on
end
if ~isempty(plotlabel) && ~isempty(plotlabel{k})
plotlegend = [ plotlegend, {plotlabel{k}} ];
end
end
% scatter plot
else
if any(plotstyle == '.')
scatter(plotrsk*sqrt(periods),((plotret(:,k)+1).^periods-1),'or','Filled');
else
scatter(plotrsk*sqrt(periods),((plotret(:,k)+1).^periods-1),'og','Filled');
end
if i==2
hold on
end
if ~isempty(plotlabel)
for k = 1:numel(plotrsk)
if ~isempty(plotlabel{k})
text(plotrsk(k)*sqrt(periods)+0.005, ...
((plotret(k)+1).^periods-1), plotlabel{k},'FontSize', 9);
end
end
end
end
end
if ~isempty(plotlegend)
legend(plotlegend,'Location','SouthEast');
end
if(plotfreq2=='annualised')
xlabel('Annualised Volatility');
ylabel('Annualised Expected Returns');
else
xlabel('Volatility');
ylabel('Returns');
end
grid on
end
Now, you can call it with various parameters of your interest, matching the data directly, for instance:
plotportfolio('Portfolio',dt,'annualised',[], ...
{'line', prsk, pret}, ...
{'scatter',CashRsk,CashRet, {'Cash'}}, ...
{'scatter', sqrt(diag(p.AssetCovar)), p.AssetMean, p.AssetList,'.r'});