## API Docs

### Introduction to Portfolio Optimization With Multiple Constraints

This tutorial focuses on Markowitz portfolio optimization at the intraday time scale. Using optimization procedures of the PortfolioEffect Quant Library we construct and compare optimal portfolios. Our focus here is on showing how to create optimizer object that meets certain optimization goal and add subsequent optimization constraints.

##### Creating Portfolio

Let's create a portfolio with three positions that use an interval from 2014-09-17 to 2014-09-21 as a holding period. Portfolio metrics mode is set to static, because classic portfolio optimization does not take past history of rebalancing into account.

require(PortfolioEffectHFT)

portfolio=portfolio_create("SPY", "2014-11-19 09:30:00", "2014-11-19 16:00:00")
portfolio_settings(portfolio,portfolioMetricsMode="price",resultsSamplingInterval='1m')

plot(portfolio)

paren = @(x, varargin) x(varargin{:});

portfolio=portfolio_create('index','SPY', 'fromTime', '2014-11-19 09:30:00', 'toTime', '2014-11-19 16:00:00');
portfolio_settings(portfolio,'portfolioMetricsMode','price','resultsSamplingInterval','1m');

plot(portfolio);


##### Performing Portfolio Optimization

At the next step, we specify our optimization goal, which is to minimize portfolio variance in this example. Resulting portfolio optimizer object could be further adjusted by additional optimization constraints. In this example, we add a lower boundary constraint on portfolio's expected return.

optimizer=optimization_goal(variance(portfolio),direction="min")
optimizer=optimization_constraint(optimizer,value(portfolio),'=',10^9)
optimizer=optimization_constraint(optimizer,expected_return(portfolio),">=",0)
optimPortfolioOneConstraints=optimization_run(optimizer)

plot(optimPortfolioOneConstraints)


optimizer=optimization_goal(portfolio,'Variance','minimize');
optimizer=optimization_constraint_portfolioValue(optimizer,10^9);
optimizer=optimization_constraint_expectedReturn(optimizer,'>=',0);
optimPortfolioOneConstraints=optimization_run(optimizer);

close
plot(optimPortfolioOneConstraints)


##### Chaining Optimization Constraints

One could chain several portfolio optimization constraints, so that the optimal portfolio have to meet all of the imposed conditions. Here are are adding an extra lower limit on the sum of absolute weights of Apple and Google positions. In real-world portfolios such a constraint could be used to control concentration risk.

optimizer=optimization_constraint(optimizer,weight_transform(portfolio,"sum_abs_weight",c(position_AAPL,position_GOOG)),">=",0.5)

optimPortfolioTwoConstraints=optimization_run(optimizer)
plot(optimPortfolioTwoConstraints)

optimizer=optimization_constraint_sumOfAbsWeights(optimizer,'>=',0.5,cellstr(['AAPL';'GOOG']));
optimPortfolioTwoConstraints=optimization_run(optimizer);

close
plot(optimPortfolioTwoConstraints)


##### Portfolio Expected Return

Both of our optimal portfolios has expected return as one of their constraints. Chart shows that constraint is generally met by both portfolios except at some short time intervals. One could also notice that portfolio with two constraints has higher expected returns across the range.

plot(expected_return(optimPortfolioOneConstraints),"Portfolio Expected Return",legend="Optimal Portfolio, with Constraints:\nReturn>=0")+
plot(expected_return(optimPortfolioTwoConstraints),legend="Optimal Portfolio, with Constraints:\nReturn>=0, Sum of Abs Weights AAPL and GOOG >=0.5")

close
figure('position',[800 200 1000 700])
util_plot2d(portfolio_expectedReturn(optimPortfolioOneConstraints),'Optimal Portfolio, with Constraints:Return>=0.02','Title','Portfolio Expected Return')+...
util_line2d(portfolio_expectedReturn(optimPortfolioTwoConstraints),'Optimal Portfolio, with Constraints:Return>=0.02, Sum of Abs Weights AAPL and GOOG >=0.5')


##### Portfolio Variance

Portfolio variance is set as our minimization goal. Chart of variance values of the two optimal portfolios shows that portfolio with two constraints generally has a higher return variance.

plot(variance(optimPortfolioOneConstraints),"Portfolio Variance",legend="Optimal Portfolio, with Constraints:\nReturn>=0")+
plot(variance(optimPortfolioTwoConstraints),legend="Optimal Portfolio, with Constraints:\nReturn>=0, \nSum of Abs Weights AAPL and GOOG >=0.5")

util_plot2d(portfolio_variance(optimPortfolioOneConstraints),'Optimal Portfolio, with Constraints:Return>=0.02','Title','Portfolio Variance')+...
util_line2d(portfolio_variance(optimPortfolioTwoConstraints),'Optimal Portfolio, with Constraints:Return>=0.02, Sum of Abs Weights AAPL and GOOG >=0.5')


##### Sum of Absolute Weights

Sum of absolute weights of Apple and Google is used as a constraint in the second portfolio. Chart below shows that this constrant is effective for the second portfolio, but is ignored in the first one.

sumOfAbsWeightsOptimPortfolio=abs(compute(weight(portfolio_getPosition(optimPortfolioOneConstraints,"AAPL")))[[1]][,2])+abs(compute(weight(portfolio_getPosition(optimPortfolioOneConstraints,"GOOG")))[[1]][,2])
sumOfAbsWeightsOptimPortfolioTwoConstraints=abs(compute(weight(portfolio_getPosition(optimPortfolioTwoConstraints,"AAPL")))[[1]][,2])+abs(compute(weight(portfolio_getPosition(optimPortfolioTwoConstraints,"GOOG")))[[1]][,2])
timeUTC=compute(weight(portfolio_getPosition(optimPortfolioOneConstraints,"AAPL")))[[1]][,1]

util_plot2d(cbind(timeUTC,sumOfAbsWeightsOptimPortfolio),"Portfolio Sum Of Abs Weigth AAPL and GOOG",legend="Optimal Portfolio, with Constraints:\nReturn>=0")+
util_line2d(cbind(timeUTC,sumOfAbsWeightsOptimPortfolioTwoConstraints),legend="Optimal Portfolio, with Constraints:\nReturn>=0, \nSum of Abs Weights AAPL and GOOG >=0.5")
sumOfAbsWeightsOptimPortfolio=abs(paren(position_weight(optimPortfolioOneConstraints,'AAPL'),:,2))+abs(paren(position_weight(optimPortfolioOneConstraints,'GOOG'),:,2));
sumOfAbsWeightsOptimPortfolioTwoConstraints=abs(paren(position_weight(optimPortfolioTwoConstraints,'AAPL'),:,2))+abs(paren(position_weight(optimPortfolioTwoConstraints,'GOOG'),:,2));
timeUTC = paren(position_weight(optimPortfolioOneConstraints,'AAPL'),:,1);

util_plot2d([timeUTC,sumOfAbsWeightsOptimPortfolio],'Optimal Portfolio, with Constraints:Return>=0.02','Title','Portfolio Sum Of Abs Weigth AAPL and GOOG')+...
util_line2d([timeUTC,sumOfAbsWeightsOptimPortfolioTwoConstraints],'Optimal Portfolio, with Constraints:Return>=0.02, Sum of Abs Weights AAPL and GOOG >=0.5')