gusucode.com > GAVPai_Book_MathworksCntrlFileEx_May2019 > GAVPai_Book_MathworksCntrlFileEx_May2019/PortfolioRebalancing_WeightRepair.m

    % To obtain a feasible solution set by standardizing
% the proportion of buy/sell weights, viz., xi+  and  xi- 
% In this function Pos (itive)  and Neg (ative)  weights representing buy and sell,  are 
% tackled separately during standardization and later conjoined as a single
% weight set
%------------------------------------------------------------------------

function std_weight_mat = PortfolioRebalancing_WeightRepair(weight_mat, Wgtlimits, TrCost)

[row_mat, col_mat]=size(weight_mat);
a = (1-TrCost)/(1+TrCost);  % a is constant (1-p)/(1+p), p is the proportional tr cost

for i =1:row_mat
    
    low_up_bounds = Wgtlimits{i};
    Pos_Weights = weight_mat(i,:).*(weight_mat(i,:)>=0);    % buy weights
    Neg_Weights = -(weight_mat(i,:).*(weight_mat(i,:)<0));  % sell weights

    X_Plus = sum(Pos_Weights); 
    X_Minus = sum(Neg_Weights);
    NZSet_Size = sum(Pos_Weights ~=0) + sum(Neg_Weights ~= 0); 
    
    X_Minus_Whole = a*X_Minus;
    if (X_Plus > X_Minus_Whole) 
        DIFF = X_Plus - X_Minus_Whole;
        SIGNAL = 1; % sum of buy  weights greater than sum of sell weights
    else
        if (X_Plus < X_Minus_Whole)
        DIFF = X_Minus_Whole- X_Plus;
        SIGNAL =0; % sum of sell weights greater than sum of buy weights
        else continue;
        end
    end
    
    LOWLIMIT_FLAG=1;
    UPLIMIT_FLAG =1;
    if (DIFF ~=0)
        
        term = DIFF/NZSet_Size;  % redistribute excess weights 
        if (SIGNAL == 1)
            for j=1:col_mat
                if (Pos_Weights(1,j) >0)
                Pos_Weights(1,j) = Pos_Weights(1,j) -term;
                end
                if Neg_Weights(1,j) >0
                Neg_Weights(1,j) = Neg_Weights(1,j) + term/a;
                end
                
                
            end
        else
            if (SIGNAL == 0)     % redistribute excess weights 
            for j=1:col_mat
                if (Neg_Weights(1,j) >0)
                Neg_Weights(1,j) = Neg_Weights(1,j) -term/a;
                end
                if Pos_Weights(1,j) >0
                Pos_Weights(1,j) = Pos_Weights(1,j) + term;
                end
                
            end
            end
       end
    end
    
    for j=1:col_mat
                
                P = Pos_Weights(1,j);
                N = Neg_Weights(1,j);
                l = low_up_bounds(1,j);
                u = low_up_bounds(2,j);
                if (P ~= 0)
                    if ((P >= l) && (P <= u))
                        continue;
                    else
                        LOWLIMIT_FLAG =0;
                    end
                end
                
                if (N ~= 0)
                    if ((N >= l) && (N <=u)) 
                        continue;     
                    else
                        LOWLIMIT_FLAG =0;
                    end
                end
                           
    end


   if (LOWLIMIT_FLAG ==0)
        
       [Pos_Weights(1,:),Neg_Weights(1,:), UPLIMIT_FLAG] = adjustPosNegWgts_lowbounds(Pos_Weights(1,:),Neg_Weights(1,:), low_up_bounds, SIGNAL, a);
   end;

   if (UPLIMIT_FLAG ==0)
        
        [Pos_Weights(1,:), Neg_Weights(1,:)] = adjustPosNegWgts_upbounds(Pos_Weights(1,:),Neg_Weights(1,:),  low_up_bounds, SIGNAL, a);
   end;


std_weight_mat(i,:) = Pos_Weights(1,:)- Neg_Weights(1,:);
end  
end