No BSD License  

Highlights from
Interactive Efficient Frontier Viewer

image thumbnail
from Interactive Efficient Frontier Viewer by Paul Taylor
Efficient Frontier Viewer using nested functions

portfolio_eff_frontier(varargin)
function portfolio_eff_frontier(varargin)
% Generates an efficient frontier, either by generating returns from from a
% set of tick prices passed into the function, or by generating random
% returns
%
% Created by:
%   Paul Taylor
%   The MathWorks Australia
%   2/05/2006

if nargin == 1
    % A set of tick prices was passed into the function - calculate returns
    
    % Extract tick prices
    x = varargin{1};
    % Calculate returns
    r = x(2:end,:) ./ x(1:(end-1),:) - 1;  
    % the above could be done using the "tick2ret" function from the 
    %  Financial Toolbox
elseif nargin == 0
    % No inputs - generate random returns from a normal distribution for
    % 200 observations of 6 assets
    daily_ret_lim = 0.05;
    r = 2*daily_ret_lim*rand(400,8) - daily_ret_lim;
end

% Calculate expected return and expected covariance
% This could also be done using the "ewstats" function from the Financial
% Toolbox: [m,c] = ewstats(r)
ExpReturn = mean(r);
ExpCovariance = cov(r);

% Convert daily return to annual - assume 252 business days per year
ExpReturn=ExpReturn*252;

% invoke the "portopt" function from the Financial Toolbox to produce the
% efficient frontier
npts = 100;
[PortRisk, PortReturn, PortWts] = portopt(ExpReturn,ExpCovariance,npts);

% Convert return to percentage
PortReturn = PortReturn*100;

%% Plot Efficient Frontier
% Create the figure and axes
h_f = figure('units','norm','pos',[0.1 0.1 0.8 0.8]);
h_a = axes('units','norm','pos',[0.1 0.1 0.73 0.8]);
% Plot the curve, add a grid, and display labels
plot(h_a,PortRisk,PortReturn,'-b.');
grid(h_a,'on')
xlabel(h_a,'Volatility (\sigma)')
ylabel(h_a,'Annualized Rate of Return (%)')
title(h_a,'Efficient Frontier')
hold(h_a,'on');

% Select a point on the frontier about half-way along
sel_node = ceil(npts/2);
% Set the crosshair location to the selected point on the frontier
x_mouse = PortRisk(sel_node);

h_ch = [];
h_an = [];
move_crosshair = 0;

set_crosshair_location(x_mouse)
    
%% Crosshair motion-related nested functions
   
    function set_crosshair_location(x_mouse)
        % Displays a green crosshair on the frontier.  The user can use this 
        % crosshair to select a point on the frontier to view the weights for 
        % the selected portfolio
        
        xr = xlim;
        yr = ylim;
        [cl_pt,idx] = min(abs(PortRisk - x_mouse));
        x_ch = [repmat(PortRisk(idx),1,2) xr(1)];
        y_ch = [yr(1) repmat(PortReturn(idx),1,2)];
        
        if isempty(h_ch)
            h_ch = plot(h_a,x_ch,y_ch,'g','linewidth',3);
        else
           set(h_ch,'xdata',x_ch);
           set(h_ch,'ydata',y_ch);
        end
        
        display_port_wghts(idx)
        
        
    end


    function display_port_wghts(idx)
        % Display the asset weights in an annotation text box on the
        % right-hand side of the axes
        w = PortWts(idx,:);
        disp_cell = {'Weights:'};
        txt = [repmat('Asset ',length(w),1) num2str((1:length(w))') ...
            repmat('  ',length(w),1) num2str(w','% 6.2f')];
        disp_cell = [disp_cell ; cellstr(txt) ; {''}];
        disp_cell{end+1} = ['Risk:       ' num2str(PortRisk(idx),'%6.3f')];
        disp_cell{end+1} = ['Return (%): ' num2str(PortReturn(idx),'%6.1f')];
        if isempty(h_an)
            h_an = annotation('textbox',[0.85 0.4 0.12 0.5],'String',disp_cell);
        else
            set(h_an,'String',disp_cell)
        end

    end
    
    function mouse_down(h,b)
        % The user clicked down on the crosshairs
        move_crosshair = 1;
    end

    function mouse_up(h,b)
        % The user released the mouse button 
        move_crosshair = 0;
    end

    function mouse_motion(h,b)
        if move_crosshair == 1
            % The mouse is moving while the mouse button is down
            mouse_loc = get(gca,'currentPoint');
            x_mouse = mouse_loc(1);
            set_crosshair_location(x_mouse)
        end
    end

%% Assign callbacks for crosshairs, and figure
set(h_ch,'buttondownfcn',@mouse_down);
set(h_f,'WindowButtonUpFcn',@mouse_up);
set(h_f,'WindowButtonMotionFcn',@mouse_motion);

    
end

Contact us at files@mathworks.com