www.gusucode.com > GAVPai_Book_MathworksCntrlFileEx_May2019 > GAVPai_Book_MathworksCntrlFileEx_May2019/Chapter6_130_30_PortfOptmzn_DEHOF_Rand4BestDir5.m
% Vijayalakshmi Pai G A, Metaheuristics for Portfolio Optimization, An % Introduction using MATLAB, ISTE-Wiley, 2017. % Differential Evolution with Hall of Fame (DE HOF), Rand4/Best/Dir5 strategy % and dynamic scale factor bets, for constrained optimization of 130-30 % portfolio optimization % Chapter 6 Sec. 6.5E % The constrained 130-30 portfolio optimization model is represented by equations [6.12]-[6.13] for % its objective function and equations [6.15]-[6.19] for its constraints % The portfolio considered is a k-portfolio of 90 assets over S&PBSE200 Index % Sec. 6.4.4 % The data file S&PBSE200_kPortfolio.xls records the mean returns of the % assets of the k-portfolio, followed by variance-covariance matrix of returns of the assets % and betas of the assets, with the asset labels displayed in the last row % 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 mean returns, variance-covariance matrix of asset returns and asset % betas portfolio_size =90; file_name = 'S&PBSE200_kPortfolio.xls'; m = xlsread(file_name); mean_data = m(1,:); cov_data = m(2:portfolio_size+1, :); Beta_assets = m(portfolio_size+2, :); % general bounds for c = 1: portfolio_size bounds(:,c) = [-0.3; 1.3]; end % bounds for the long and short positions in the portfolio z = zeros(1,portfolio_size); o = ones (1, portfolio_size); long_pos_bounds(1,:) = z ; % set lower and upper bounds for long positions as (0, 1.3) long_pos_bounds(2,:) = 1.3*o; short_pos_bounds(1,:) = -0.3*o; short_pos_bounds(2,:) = z; % set lower and upper bounds for short positions as ( -0.3, 0) % portfolio parameters annriskfree = 6.5/100; riskfree = ((1+annriskfree)^(1/360) -1)*100; % Differential Evolution strategy parameters popln_size = 1000; chromosm_length = 90; total_generations = 8000; beta = 0.5; pr_recombi = 0.87; aa = -0.3; bb= 1.3; % Joines and Houck's (1994) dynamic penalty (dp) function strategy % Set parameters C, alpha, beta C_dp = 0.5; alpha_dp=2; beta_dp=2; % initialize Hall of Fame which will finally hold the optimal weights HOF_fitness = -999; HOF_individual = zeros(1, portfolio_size); i1 = 1; % generation counter gen_indx = 1; fix(clock) % generate initial random population within the range [-0.3, 1.3] initial_popln_raw = aa + (bb-aa)*rand(popln_size, chromosm_length); % repair weights initial_popln_bound = weight_std_130_30_boundsconstr(initial_popln_raw, bounds); initial_popln = weight_std_130_30_budgetconstr(initial_popln_bound, long_pos_bounds, short_pos_bounds); % compute constraint violation function [initial_popln_psi, initial_popln_G1]= ConstrViolnFun_130_30(initial_popln, Beta_assets, C_dp, alpha_dp, beta_dp, gen_indx); % compute fitness function initial_popln_fitness = CompFitness_130_30(initial_popln, mean_data, cov_data, riskfree, initial_popln_psi); % create parent population and compute fitness feas_parent_popln = initial_popln; feas_parent_popln_fitness = initial_popln_fitness; feas_parent_popln_psi = initial_popln_psi; % while loop for generation cycles begins while (gen_indx <= total_generations) gen_indx %dynamic beta for each generation dynamic_beta = 0.5+(1-0.5)*rand(1,1); % obtain trial vector population trial_vector_popln = DE_Rand4BestDir5_Operator(feas_parent_popln, feas_parent_popln_fitness, dynamic_beta, popln_size, chromosm_length); % obtain offspring population offsprng_popln = DE_bin_Crossover(feas_parent_popln, trial_vector_popln, pr_recombi, chromosm_length); % undertake weight repair strategy Phase 1 mutat_popln_bound = weight_std_130_30_boundsconstr(offsprng_popln, bounds); % undertake weight repair strategy Phase 2 feas_mutat_popln = weight_std_130_30_budgetconstr(mutat_popln_bound, long_pos_bounds, short_pos_bounds); % compute constraint violation function [feas_mutat_popln_psi, feas_mutat_popln_G1]= ConstrViolnFun_130_30(feas_mutat_popln, Beta_assets, C_dp, alpha_dp, beta_dp, gen_indx); % compute fitness function values feas_mutat_popln_fitness = CompFitness_130_30(feas_mutat_popln, mean_data, cov_data, riskfree, feas_mutat_popln_psi); % set the population for the next generation [next_gen_pool, next_gen_pool_fitness, Psi_fun ] = DE_selection_penalty_13030(feas_parent_popln, feas_parent_popln_fitness, feas_parent_popln_psi, feas_mutat_popln, feas_mutat_popln_fitness, feas_mutat_popln_psi, popln_size); % induce best individual into Hall of Fame for i=1:popln_size if (Psi_fun(i)== 0) if (next_gen_pool_fitness(i) > HOF_fitness) HOF_fitness = next_gen_pool_fitness(i) HOF_individual = next_gen_pool(i,:); HOF_genarray(i1) = gen_indx; HOF_fitarray(i1) = HOF_fitness; i1=i1+1; end else continue; end end % increment generation counter gen_indx = gen_indx + 1; % form the parent population for the next generation feas_parent_popln = next_gen_pool; feas_parent_popln_fitness = next_gen_pool_fitness; end % while loop for generations ends fix(clock) % obtain optimal weights from the Hall of Fame x_star = HOF_individual; % compute optimal portfolio annualized risk and return portfolio_return = 261 * sum(mean_data .* x_star); risk = sqrt(261 * x_star * cov_data * x_star'); disp('Integrated 130-30 Portfolio Optimization results:') disp('risk return Sharpe ratio') risk portfolio_return sharperatio = (portfolio_return-annriskfree*100)/ risk disp('long positions short positions') long = find(x_star > 0) short = find(x_star < 0) disp('weights: long positions short positions weight sum portfolio beta') sum (x_star(long)) sum(x_star(short)) sum(x_star) portfoliobeta = sum(x_star.* Beta_assets) disp('Successful execution!')