www.gusucode.com > GAVPai_Book_MathworksCntrlFileEx_May2019 > GAVPai_Book_MathworksCntrlFileEx_May2019/Chapter4_RiskBudgetPortfolioOptmzn_DEHOF.m
% Vijayalakshmi Pai G A, Metaheuristics for Portfolio Optimization, An % Introduction using MATLAB, ISTE-Wiley, 2017. % Differential Evolution with Hall of Fame (DE HOF) for metaheuristic risk % budgeted portfolio optimization, employing Joines and Houck's dynamic % penalty functions for constraint handling % Chapter 4 Secs. 4.8 A, B, C, D % Risk budgeted Portfolio optimization model is represented by equations [4.19]-[4.20] for % its objective function and equations [4.10]-[4.13] for its constraints % The portfolio considered is a case study global portfolio described in % Table 4.1 % Program coding: Dr G A Vijayalakshmi Pai % Note: Coding style has been kept naive and direct to favor novices in % MATLAB. Users familiar with MATLAB are encouraged to improvise the code %------------------------------------------------------------------------ clear all % input risk budgeted portfolio problem parameters and inputs % load the premia and variance-covariance matrix of returns of the assets % in the portfolio load optim_input_export.mat cv premia; risk_budget = 12.5; positive_premia_assets_indx= 1:23; zero_premia_assets_indx= 24:27; zero_premia_splasset_indx = 28; default_low_bound= -3; default_up_bound = 3; low_bound_positive_premia= 0.001; low_bound_zerprsplasset = 0; bound_asset_indx = [positive_premia_assets_indx,zero_premia_splasset_indx]; % Joines and Houck's (1994) dynamic penalty function strategy % Set parameters C, alpha, beta C_dp = 0.5; beta_dp=2; alpha_dp=2; % set Differential Evolution strategy parameters popln_size = 300; total_generations = 1000; beta = 0.5; pr_recombi = 0.87; [row, portfolio_size]=size(premia); chromosm_length = portfolio_size; % set bounds for the categories of assets in the portfolio bounds(1,:)= zeros(1, portfolio_size); bounds(2,:)= zeros(1, portfolio_size); bounds(1,positive_premia_assets_indx)= zeros(1, length(positive_premia_assets_indx))+ low_bound_positive_premia; bounds(1,zero_premia_assets_indx)= zeros(1, length(zero_premia_assets_indx))+default_low_bound; bounds(1,zero_premia_splasset_indx)= zeros(1, length(zero_premia_splasset_indx))+low_bound_zerprsplasset; bounds(2,positive_premia_assets_indx) = zeros(1, length(positive_premia_assets_indx))+default_up_bound; bounds(2,zero_premia_assets_indx) = zeros(1, length(zero_premia_assets_indx))+default_up_bound; bounds(2,zero_premia_splasset_indx)= zeros(1, length(zero_premia_splasset_indx))+default_up_bound; % initialize Hall of Fame which will ultimately hold the optimal weights HOF_fitness = 9999; HOF_individual = zeros(1, portfolio_size); fix(clock) % generation cycle counter gen_indx = 1; % generate initial random population of individuals, the parent population initial_popln_raw= default_low_bound + (default_up_bound-default_low_bound)*rand(popln_size, chromosm_length);%generate initial random population within default bounds initial_popln_lev = satisfy_lowbounds(initial_popln_raw, bounds,bound_asset_indx); initial_popln = weightstdzn(initial_popln_lev, bounds, bound_asset_indx); [GI, psi_i] = compute_constrvioln_fn( initial_popln, cv, risk_budget, C_dp, beta_dp, alpha_dp, gen_indx ); initial_popln_fitness = comp_fitness(initial_popln, premia, cv, psi_i); % beginning of generation cycles while (gen_indx <= total_generations) % set parent population, fitness and constraint violation functions feas_parent_popln = initial_popln; feas_parent_popln_fitness = initial_popln_fitness; GP = GI; psi_p = psi_i; %perform mutation to generate trial vectors trial_vector_popln = DE_mutation(feas_parent_popln, beta, popln_size); %generate offspring population using the parent and trial vector populations offsprng_popln_raw = DE_bin_Crossover(feas_parent_popln, trial_vector_popln, pr_recombi, chromosm_length); % undertake weight repair of offspring population offsprng_popln_lev = satisfy_lowbounds(offsprng_popln_raw, bounds, bound_asset_indx); offsprng_popln = weightstdzn(offsprng_popln_lev, bounds, bound_asset_indx); %compute constraint violation function for the offspring population [GO, psi_o] = compute_constrvioln_fn( offsprng_popln, cv, risk_budget, C_dp, beta_dp, alpha_dp, gen_indx); %compute fitness of the offspring population offsprng_popln_fitness = comp_fitness(offsprng_popln,premia, cv, psi_o); %set the population for the next generation [next_gen_pool, next_gen_pool_fitness, Penalty, Psi_fun] = DE_selection_penalty(feas_parent_popln, GP, psi_p, feas_parent_popln_fitness, offsprng_popln, GO, psi_o, offsprng_popln_fitness, popln_size); % individuals compete to enter Hall of Fame for i=1:popln_size if (isequal(Penalty(i,:), zeros(1, portfolio_size))) if (next_gen_pool_fitness(i)< HOF_fitness) HOF_fitness = next_gen_pool_fitness(i); HOF_individual = next_gen_pool(i,:); end else continue; end end gen_indx = gen_indx + 1 % move to the next generation initial_popln = next_gen_pool; initial_popln_fitness= next_gen_pool_fitness; GI = Penalty; psi_i= Psi_fun; end % end of a generation cycle fix(clock) % extract optimal weights from the individual in the Hall of Fame optimal_weights = HOF_individual; % compute risk budgeted portfolio characteristics: Sharpe Ratio, return and % risk portfolio_sharperatio = ((premia * optimal_weights')/ sqrt(optimal_weights*cv * optimal_weights')); portfolio_return= (premia * optimal_weights'); portfolio_risk = sqrt( optimal_weights * cv * optimal_weights'); % check if the optimal risk budgeted portfolio satisfies its risk budget % constraint mcr = (cv * optimal_weights')/portfolio_risk; mcr_status = (optimal_weights.*mcr')-(risk_budget/100)*portfolio_risk; % display portfolio characteristics disp('Optimization results:') optimal_weights portfolio_return portfolio_risk portfolio_sharperatio disp('Successful execution!');