www.gusucode.com > GAVPai_Book_MathworksCntrlFileEx_May2019 > GAVPai_Book_MathworksCntrlFileEx_May2019/Chapter5_EMNP_DEHOF_Rand5Dir4.m
% Vijayalakshmi Pai G A, Metaheuristics for Portfolio Optimization, An % Introduction using MATLAB, ISTE-Wiley, 2017. % Differential Evolution with Hall of Fame (DE HOF) and Rand5/Dir4 strategy % (DE/Rand5/Dir4) for metaheuristic optimization of risk budgeted % equity market neutral portfolios % Chapter 5 Secs. 5.6 B, C, D, E, F % The Risk budgeted equity market neutral portfolio is represented by equations [5.14]-[5.19] for % its objective function and equations [5.20]-[5.25] for its constraints % The portfolio considered is a long-short portfolio of 49 long positions % followed by 49 short positions over Nikkei225 Index % Sec. 5.5 Portfolio C % The data file Nikkei225_PortfolioC.xls records the mean returns of the % assets of Portfolio C, followed by variance-covariance matrix of returns of the assets % and betas of the assets, with the colour coded 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 % number of long positions in the portfolio L_col = 49; % number of short positions in the portfolio S_col = 49; % portfolio size portfolio_size = L_col+S_col; % serial number of high volatility assets in the portfolio Highvolat_assets = [97 98]; % Softbank Corp and Pacific Metals Co Ltd % obtain mean returns, variance-covariance matrix of returns and asset % betas filename = 'Nikkei225_PortfolioC.xls'; m = xlsread(filename); mean_data = m(1,:); cov_data = m(2:portfolio_size+1, :); Beta_assets = m(portfolio_size+2, :); % input differential evolution parameters popln_size = 980; chromosm_length = portfolio_size; total_generations = 5000; beta = 0.5; pr_recombi = 0.87; % input portfolio parameters Long_low_bound = 0.0001; Long_up_bound=1; Short_low_bound = -1; Short_up_bound=-0.0001; % initialize Hall of Fame HOF_fitness = -9999; HOF_individual = zeros(1, portfolio_size); % generation counter gen_indx = 1; % Hall of Fame induction counter i1=1; fix(clock) % generate initial population representing long short portfolio initial_popln_raw= EMNP_gen_longshort_popln(popln_size, L_col, S_col, Long_low_bound, Long_up_bound, Short_low_bound, Short_up_bound); % undertake weight repair of long and short positions initial_popln_longstd = EMNP_eqconstr_wgtstd(initial_popln_raw, 1, L_col, Long_low_bound, Long_up_bound, 1); initial_popln_firststd = EMNP_eqconstr_wgtstd(initial_popln_longstd, L_col+1, L_col+S_col, -Short_up_bound, -Short_low_bound,0); initial_popln = initial_popln_firststd; % compute constraint violation functions [psi_i, initial_G1, initial_G2] = EMNP_compute_constr_violn_fn( initial_popln, cov_data, Beta_assets, Highvolat_assets); [initial_popln_fitness, initial_popln_obj_val] = EMNP_comp_fitness_function(initial_popln, mean_data, psi_i); % DE generation cycles begin while (gen_indx <= total_generations) gen_indx feas_parent_popln = initial_popln; feas_parent_popln_fitness = initial_popln_fitness; psi_p = psi_i; feas_parent_G1= initial_G1; feas_parent_G2 = initial_G2; feas_parent_obj_val = initial_popln_obj_val; % perform mutation trial_vector_popln = DE_Rand5Dir4_Operator(feas_parent_popln, feas_parent_popln_fitness, beta, popln_size, chromosm_length); % perform crossover offsprng_popln_raw = DE_bin_Crossover(feas_parent_popln, trial_vector_popln, pr_recombi, chromosm_length); % undertake weight repair of long/short positions offsprng_popln_longstd = EMNP_eqconstr_wgtstd(offsprng_popln_raw, 1, L_col, Long_low_bound, Long_up_bound, 1); offsprng_popln_shortstd = EMNP_eqconstr_wgtstd(offsprng_popln_longstd, L_col+1, L_col+S_col, -Short_up_bound, -Short_low_bound,0); offsprng_popln = offsprng_popln_shortstd; % compute constraint violation functions [psi_o,offsprng_G1, offsprng_G2] = EMNP_compute_constr_violn_fn( offsprng_popln, cov_data, Beta_assets, Highvolat_assets); % compute fitness functions [offsprng_popln_fitness, offsprng_obj_val] = EMNP_comp_fitness_function(offsprng_popln, mean_data, psi_o); % Tournament selection of individuals for the next generation [next_gen_pool, next_gen_pool_obj_val, Psi_fun, G1_nextgen,G2_nextgen, next_gen_pool_fitness] = EMNP_DE_selection(feas_parent_popln, psi_p, feas_parent_G1,feas_parent_G2, feas_parent_obj_val, feas_parent_popln_fitness, offsprng_popln, psi_o, offsprng_G1, offsprng_G2, offsprng_obj_val, offsprng_popln_fitness, popln_size); % induct 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; % reset initial population and parameters initial_popln = next_gen_pool; % move to the next generation initial_popln_fitness= next_gen_pool_fitness; psi_i= Psi_fun; initial_G1=G1_nextgen; initial_G2 = G2_nextgen; initial_popln_obj_val=next_gen_pool_obj_val; end % while loop for DE generation cycle ends fix(clock) % record the individual in the Hall of Fame as the optimal solution x_star = HOF_individual; % optimal weights % portfolio characteristics portfolio_return = 261 * sum(mean_data .* x_star); risk = sqrt( 261*x_star * cov_data * x_star'); disp('Equity Market Neutral Portfolio Optimization results:') disp('Annualized risk') disp(risk) disp('Expected portfolio Annualized return') disp(portfolio_return) disp('Optimal weights') disp( x_star) disp('Successful execution!');