# Adding Constraints to Satisfy UCITS Directive

This example shows how to set up and solve a portfolio optimization problem that satisfies the Undertakings for Collective Investment in Transferable Securities (UCITS) Directive. The UCITS directive is a regulatory requirement of European investment funds. As of 2019, the UCITS asset allocation regulation states that funds can only invest only up to 10% in a single issuer, and that investments in excess of 5% must not exceed 40% of the total portfolio, with some exceptions. This rule is known as the 5/10/40 rule.

### Create Portfolio Object

To solve a portfolio problem and add this requirement to the problem, start by creating a `Portfolio`

, `PortfolioCVaR`

, or `PortfolioMAD`

object, depending on the desired risk measure.

% Read table of daily adjusted close prices for 2006 DJI stocks pricesTT = readtimetable('dowPortfolio.xlsx'); % Compute the returns from the prices returnsTT = tick2ret(pricesTT); % Remove the DJI stock from the timetable assetReturnsTT = returnsTT(:,2:end); % Compute the asset returns mean and covariance matrix mu = mean(assetReturnsTT.Variables); Sigma = cov(assetReturnsTT.Variables); % Create Portfolio object p = Portfolio(AssetMean=mu',AssetCovar=Sigma);

To add the 10% upper bound on the maximum that you can invest in any individual asset, use `setBounds`

. In this example, any chosen asset must represent at least 1% of the total portfolio.

% Weights must be either 0 or between 0.01 and 0.1 p = setBounds(p,0.01,0.1,BoundType="conditional");

To set the conditional constraint that limits the aggregate weight that you can invest in assets that exceed 5%, use `setConditionalBudget`

.

% Assets with weights above 5% must not exceed 40% of the total % portfolio p = setConditionalBudget(p,0.05,0.4);

Finally, the portfolio weights must sum to one and must have between 15 and 20 active assets.

% Sum of weights must be equal to one p = setBudget(p,1,1); % 15-20 active assets p = setMinMaxNumAssets(p,15,20);

### Compute Minimum Variance Portfolio with Tracking Error Penalty

Given some `trackingPortfolio`

weights allocation, find the minimum variance portfolio using `estimateCustomObjectivePortfolio`

with a tracking error penalty that satisfies all the constraints in the previous section.

% Define tracking portfolio as the portfolio of the DJI trackingPortfolio = returnsTT{:,2:end}\returnsTT{:,1}; % Penalized objective function penalizedVariance = @(w) w'*Sigma*w + ... (w-trackingPortfolio)'*Sigma*(w-trackingPortfolio); % Penalized variance portfolio p = setSolverMINLP(p,"OuterApproximation",ExtendedFormulation=true, ... ObjectiveScalingFactor=1e4); w = estimateCustomObjectivePortfolio(p,penalizedVariance);

The following bar chart shows the weights distribution of the portfolio.

figure bar(assetReturnsTT.Properties.VariableNames,w); hold on yline(0.05,'r--',LineWidth=2) title('Minimum Variance Portfolio with Tracking Error Penalty') ylabel('Weight')

Only five assets are above the 5% conditional threshold and the sum of these assets are less than 40%.

conditionalBudget = sum(w(w > 0.05))

conditionalBudget = 0.4000