www.gusucode.com > 使用MATLAB来优化投资组合与金融工具箱 > 使用MATLAB来优化投资组合与金融工具箱/使用MATLAB来优化投资组合与金融工具箱/portfoliodemo/part2_strategy.m
%% part2_strategy - Performance evaluation of maximum return/risk ratio portfolios % % Copyright 2011 The MathWorks, Inc. load BlueChipStocks % control parameters for backtest numportfolio = 20; % number of portfolios on each efficient frontier window = 60; % historical estimation window in months offset = 3; % shift in time for each frontier in months cutoff = 0.4; % this fraction of data in a series must be non-NaN values relative = true; % true if relative returns, false if absolute returns accumulate = true; % true if accumulation of assets, false if current universe only imarket = strcmpi('Market', Asset); % locate "market" series icash = strcmpi('Cash', Asset); % locate "cash" series (riskfree rate proxy) % bookkeeping pfactor = 12/offset; % factor to convert periodicity to annual period if relative criterion = 'Information Ratio'; else criterion = 'Sharpe Ratio'; end % form cumulative map of assets (include all prior active assets that are still listed) if accumulate for t = 2:size(Map,1) Map(t,:) = Map(t - 1,:) | Map(t,:); end end % ex-ante and ex-post analysis PortDate = []; PortRisk = []; PortReturn = []; PortSigma = []; PortMean = []; PerfDate = []; PerfPort = []; PerfMarket = []; PerfCash = []; for t = window:offset:numel(Date) % set up date indices for current period startindex = t - window + 1; endindex = t; % select "market" series Xmarket = Data(startindex:endindex,imarket); % select assets that are active on the endindex date iasset = Map(endindex,:); % keep series with sufficient numbers of non-NaN values imissing = sum(isnan(Data(startindex:endindex,:))) > cutoff*window; % form active universe for current endindex date iasset = logical(iasset) & ~logical(imissing); iasset(end-1:end) = 0; % last two series are not stocks (not used in this step) % select data for active universe A = Asset(iasset); X = Data(startindex:endindex,iasset); fprintf('Estimation period %s to %s with %d assets ...\n', ... datestr(Date(startindex)), datestr(Date(endindex)), numel(A)); % remove "market" from the data (market-neutral relative returns) if relative X = X - repmat(Xmarket, 1, numel(A)); end % construct portfolio object (use RiskFreeRate if not market-neutral) p = PortfolioDemo('AssetList', A, 'Name', sprintf('Universe %s', datestr(Date(endindex)))); if ~relative p = PortfolioDemo(p, 'RiskFreeRate', Data(endindex,icash)); end p = p.setDefaultConstraints; p = p.estimateAssetMoments(X, 'MissingData', true); % estimate portfolios on efficient frontier pwgt = p.estimateFrontier(numportfolio); % estimate portfolio that maximizes the ratio of relative risk to relative return % if absolute returns, then maximize the Sharpe ratio [swgt, sbuy, ssell] = p.maximizeSharpeRatio; [srsk, sret] = p.estimatePortMoments(swgt); disp(p.AssetList(swgt > 1.0e-4)); % enter data for 3D frontier PortDate = [ PortDate; Date(endindex) ]; PortRisk = [ PortRisk; sqrt(pfactor)*(p.estimatePortRisk(pwgt))' ]; PortReturn = [ PortReturn; pfactor*(p.estimatePortReturn(pwgt))' ]; PortSigma = [ PortSigma; sqrt(pfactor)*srsk ]; PortMean = [ PortMean; pfactor*sret ]; % evaluate performance if (endindex + offset) <= numel(Date) Xret = ret2tick(Data(endindex+1:endindex+offset,:)); Xret = Xret(end,:) - 1; PerfDate = [ PerfDate; Date(endindex+offset) ]; PerfPort = [ PerfPort; Xret(iasset)*swgt ]; PerfMarket = [ PerfMarket; Xret(imarket) ]; PerfCash = [ PerfCash; Xret(icash) ]; end end % set up dates across 3D frontier PortDate = repmat(PortDate, 1, numportfolio); %% plot 3D frontier figure(1); surf(PortDate, PortRisk, PortReturn, ... 'FaceColor', 'interp', 'EdgeColor', 'none', 'FaceLighting', 'phong'); hold on plot3(PortDate(:,1), PortSigma, PortMean + 1.0e-6, 'w', 'LineWidth', 3); datetick('x'); ylabel('Portfolio Risk'); zlabel('Portfolio Returns'); title('\bfTime Evolution of Efficient Frontier'); camlight right view(30, 30); hold off figure(2); plot([datenum(Date(window)); PerfDate], ret2tick([PerfPort, PerfMarket, PerfCash])); datetick('x'); title('\bfBacktest Performance of Portfolio Strategy'); ylabel('Cumulative Value of $1 Invested 31-Dec-1984'); legend(criterion, 'Market', 'Cash', 'Location', 'NorthWest'); %% summarize results perf = [PerfPort, PerfMarket, PerfCash]; pmean = pfactor*mean(perf); pstdev = sqrt(pfactor)*std(perf); perfret = ret2tick(perf); ptotret = (perfret(end,:) .^ (pfactor/size(perf,1))) - 1; pmaxdd = maxdrawdown(perfret); fprintf('Results for Backtest Period from %s to %s\n',datestr(PortDate(1,1)),datestr(PortDate(end,1))); fprintf('%18s %12s %12s %12s %12s\n','','Mean','Std.Dev.','Tot.Ret.','Max.DD'); fprintf('%18s %12g %12g %12g %12g\n',criterion, ... 100*pmean(1),100*pstdev(1),100*ptotret(1),100*pmaxdd(1)); fprintf('%18s %12g %12g %12g %12g\n','Market', ... 100*pmean(2),100*pstdev(2),100*ptotret(2),100*pmaxdd(2)); fprintf('%18s %12g %12g %12g %12g\n','Cash', ... 100*pmean(3),100*pstdev(3),100*ptotret(3),100*pmaxdd(3));