## API Docs

### Building Efficient Frontiersfor Intraday Asset Allocation

This tutorial investigates construction of an efficient frontier using HF market data for portfolios of different sizes (theoretical vs realistic) and with various short-sales assumptions (Markowitz vs. Lintner).

##### Creating Portfolio

Here we are creating an asset portfolio with three positions: Google, Apple, and S&P 500 ETF. We set portfolio metrics mode to "price", so that all portfolio metrics will be computed for a buy-and-hold strategy without rebalancing.

require(PortfolioEffectHFT)

portfolio=portfolio_create(fromTime="2014-04-13 9:30:01",
toTime="2014-04-16 16:00:00")
portfolio_settings(portfolio,windowLength = '360m',portfolioMetricsMode='price')

plot(portfolio)

portfolio=portfolio_create('index','SPY', 'fromTime', '2014-04-13 9:30:01', 'toTime', '2014-04-16 16:00:00');
portfolio_settings(portfolio,'portfolioMetricsMode','price','windowLength', '360m');

plot(portfolio)


##### Theoretical Efficient Frontier

The efficient frontier is a concept in modern portfolio theory which refers to the best possible expected level of return for a given level of risk. Level of risk is traditionally represented by volatility of portfolio's returns and portfolios on the efficient frontier are called optimal portfolios.

To produce theoretical efficient frontier, which is a "smooth" curve need to assume that any asset is infinitely divisible. In practice, however, it is usually enough to make portfolio value sufficiently large to achieve the same effect. In our example below we set portfolio value to 100MM USD and use spline interpolation to futher enhance the "smoothness" of the frontier.

portfolio_settings(portfolio,resultsSamplingInterval='last')

resultLintner=data.frame(Variance=0,ExpectedReturn=0)

for(x in seq(0.004,0.016,0.004)){
optimizer=optimization_goal(variance(portfolio),"min")
optimizer=optimization_constraint(optimizer,value(portfolio),'=',10^9)
optimizer=optimization_constraint(optimizer,expected_return(portfolio),"=",x)
optimPortfolio=optimization_run(optimizer)
resultLintner=rbind(resultLintner,c(compute(variance(optimPortfolio))[[1]][2],
compute(expected_return(optimPortfolio))[[1]][2]))
}

resultLintner=resultLintner[-1,]

resultLintner=data.frame(Variance=spline(resultLintner$Variance, n=100)$y,
ExpectedReturn=spline(resultLintner$ExpectedReturn, n=100)$y)

ggplot()+geom_path(data=resultLintner, aes(x=Variance,y=ExpectedReturn),size=1.2)+util_plotTheme()+ggtitle("Efficient Frontier")+ylab("Expected Return")

portfolio_settings(portfolio,'portfolioMetricsMode','price','windowLength', '360m','resultsSamplingInterval','last');

VarianceLintner=null(1);
ExpectedReturnLintner=null(1);

for x = 0:0.005:0.015
optimizer=optimization_goal(portfolio,'Variance','minimize');
optimizer=optimization_constraint_portfolioValue(optimizer,10^9);
optimizer=optimization_constraint_expectedReturn(optimizer,'=',x);
optimPortfolio=optimization_run(optimizer);
temp1=portfolio_variance(optimPortfolio);
temp2=portfolio_expectedReturn(optimPortfolio);
VarianceLintner=[VarianceLintner,temp1(2)];
ExpectedReturnLintner=[ExpectedReturnLintner,temp2(2)];
end

y1=min(ExpectedReturnLintner):(max(ExpectedReturnLintner))/100:max(ExpectedReturnLintner);
x1=spline(ExpectedReturnLintner,VarianceLintner,y1);

close
figure('position',[800 200 1000 700])
plot(x1,y1,'LineSmoothing','on','Color',[0 74/255 97/255],'LineWidth',1.5);
set(gca,'Color',[213/255 228/255 235/255]);
set(gcf,'Color',[213/255 228/255 235/255]);
xlabel('Variance');
ylabel('Expected Return');
grid on
title('Efficient Frontier','FontSize',15,'FontWeight','bold');


##### Actual Efficient Frontiers

Market value of real-world portfolios is rarely large enough, so that discretness of optimal position weights could be neglected for drawing the efficient frontier. To demonstrate how discretness of the weights influences the shape of an effcient frontier, we overlay our previous frontier for a 100MM USD portfolio with a frontiers for small 800 USD and 400 USD portfolios (optimal portfolio value is a second arguement of optimization_goal method)

resultLintner3000Portfolio=data.frame(Variance=0,ExpectedReturn=0)

for(x in seq(0.004,0.016,0.004)){
optimizer=optimization_goal(variance(portfolio),"min")
optimizer=optimization_constraint(optimizer,value(portfolio),'=',3000)
optimizer=optimization_constraint(optimizer,expected_return(portfolio),"=",x)
optimPortfolio=optimization_run(optimizer)
resultLintner3000Portfolio=rbind(resultLintner3000Portfolio,c(compute(variance(optimPortfolio))[[1]][2],compute(expected_return(optimPortfolio))[[1]][2]))
}

resultLintner3000Portfolio=resultLintner3000Portfolio[-1,]

resultLintner20000Portfolio=data.frame(Variance=0,ExpectedReturn=0)

for(x in seq(0.004,0.016,0.004)){
optimizer=optimization_goal(variance(portfolio),"min")
optimizer=optimization_constraint(optimizer,value(portfolio),'=',20000)
optimizer=optimization_constraint(optimizer,expected_return(portfolio),"=",x)
optimPortfolio=optimization_run(optimizer)
resultLintner20000Portfolio=rbind(resultLintner20000Portfolio,c(compute(variance(optimPortfolio))[[1]][2],compute(expected_return(optimPortfolio))[[1]][2]))
}

resultLintner20000Portfolio=resultLintner20000Portfolio[-1,]

resultLintner3000Portfolio$legend="$3000 Portfolio"
resultLintner20000Portfolio$legend="$20000 Portfolio"
resultLintner$legend="Theoretical Portfolio" result=rbind(resultLintner3000Portfolio,resultLintner20000Portfolio,resultLintner) ggplot()+geom_path(data=result, aes(x=Variance,y=ExpectedReturn,col=legend),size=1.2)+ util_plotTheme()+ggtitle("Efficient Frontier of Theoretical/$20000/$3000 portfolio")+ ylab("Expected Return")+util_colorScheme()  Variance6000Lintner=null(1); ExpectedReturn6000Lintner=null(1); for x = 0:0.004:0.016 optimizer=optimization_goal(portfolio,'Variance','minimize'); optimizer=optimization_constraint_portfolioValue(optimizer,6000); optimizer=optimization_constraint_expectedReturn(optimizer,'=',x); optimPortfolio=optimization_run(optimizer); temp1=portfolio_variance(optimPortfolio); temp2=portfolio_expectedReturn(optimPortfolio); Variance6000Lintner=[Variance6000Lintner,temp1(2)]; ExpectedReturn6000Lintner=[ExpectedReturn6000Lintner,temp2(2)]; end Variance20000Lintner=null(1); ExpectedReturn20000Lintner=null(1); for x = 0:0.004:0.016 optimizer=optimization_goal(portfolio,'Variance','minimize'); optimizer=optimization_constraint_portfolioValue(optimizer,20000); optimizer=optimization_constraint_expectedReturn(optimizer,'=',x); optimPortfolio=optimization_run(optimizer); temp1=portfolio_variance(optimPortfolio); temp2=portfolio_expectedReturn(optimPortfolio); Variance20000Lintner=[Variance20000Lintner,temp1(2)]; ExpectedReturn20000Lintner=[ExpectedReturn20000Lintner,temp2(2)]; end plot(x1,y1,Variance20000Lintner,ExpectedReturn20000Lintner,Variance6000Lintner,ExpectedReturn6000Lintner,'LineSmoothing','on','LineWidth',1.5); set(gca,'Color',[213/255 228/255 235/255]); set(gcf,'Color',[213/255 228/255 235/255]); xlabel('Variance'); ylabel('Expected Return'); grid on title('Efficient Frontier of Theoretical/$2000/$6000 portfolio','FontSize',15,'FontWeight','bold'); legend('Theoretical Portfolio','$20000 Portfolio','$6000 Portfolio');  ##### Short Sales Assumptions Finally, we explore how changing from Markowitz to Lintner short-sales assumptions would influence the shape of the efficient frontier. Markowitz definition of short sales assumes the investor, by employing short sales, can create portfolios of extreme risk and return through this costless leveraging of starting capital. In other words, Markowitz short sales constraint states that the sum of position weights must equal to 1 and it is used to normalize the weights: $$\sum_{i=1}^n w_i = 1$$ But individual investors pay a high fee for short sales, cannot short sell a managed portfolio, and the use of funds that arise from short sales of individual securities is restricted by brokerage firms. Lintner short sales constraint is more realitic, and while it also states that the sum of position weights must equals to 1, it is the sum of absolute weights, which is used to normalize position weights: $$\sum_{i=1}^n |w_i| = 1$$ As the chart below shows, Lintner weights produce a quite different efficient set. It seems to produce optimal portfolios with lower level of risk given the same level of return. This seems to support the claim that Markowitz short sales assumption favors excessive risk-taking. portfolio_settings(portfolio, windowLength = '360m', resultsSamplingInterval='last', shortSalesMode = 'markowitz',portfolioMetricsMode='price') resultMarkowitz=data.frame(Variance=0,ExpectedReturn=0) for(x in seq(0.004,0.016,0.004)){ optimizer=optimization_goal(variance(portfolio),"min") optimizer=optimization_constraint(optimizer,value(portfolio),'=',10^9) optimizer=optimization_constraint(optimizer,expected_return(portfolio),"=",x) optimPortfolio=optimization_run(optimizer) resultMarkowitz=rbind(resultMarkowitz,c(compute(variance(optimPortfolio))[[1]][2],compute(expected_return(optimPortfolio))[[1]][2])) } resultMarkowitz=resultMarkowitz[-1,] resultMarkowitz=data.frame(Variance=spline(resultMarkowitz$Variance, n=100)$y, ExpectedReturn=spline(resultMarkowitz$ExpectedReturn, n=100)$y) resultMarkowitz$legend="Markowitz"
resultLintner\$legend="Lintner"
result=rbind(resultMarkowitz,resultLintner)

ggplot()+geom_path(data=result, aes(x=Variance,y=ExpectedReturn,col=legend),size=1.2)+
util_plotTheme()+ggtitle("Markowitz and Lintner Efficient Frontier")+ylab("Expected Return")+
util_colorScheme()

portfolio_settings(portfolio,'portfolioMetricsMode','price','windowLength', '360m','resultsSamplingInterval','last','shortSalesMode', 'markowitz')

VarianceMarkowitz=null(1);
ExpectedReturnMarkowitz=null(1);

for x =  0:0.005:0.015
optimizer=optimization_goal(portfolio,'Variance','minimize');
optimizer=optimization_constraint_portfolioValue(optimizer,10^9);
optimizer=optimization_constraint_expectedReturn(optimizer,'=',x);
optimPortfolio=optimization_run(optimizer);
temp1=portfolio_variance(optimPortfolio);
temp2=portfolio_expectedReturn(optimPortfolio);
VarianceMarkowitz=[VarianceMarkowitz,temp1(2)];
ExpectedReturnMarkowitz=[ExpectedReturnMarkowitz,temp2(2)];
end

y2=min(ExpectedReturnMarkowitz):(max(ExpectedReturnMarkowitz))/100:max(ExpectedReturnMarkowitz);
x2=spline(ExpectedReturnMarkowitz,VarianceMarkowitz,y2);

plot(x1,y1,x2,y2,'LineSmoothing','on','LineWidth',1.5);
set(gca,'Color',[213/255 228/255 235/255]);
set(gcf,'Color',[213/255 228/255 235/255]);
xlabel('Variance');
ylabel('Expected Return');
grid on
title('Markowitz and Lintner Efficient Frontier','FontSize',15,'FontWeight','bold');
legend('Lintner','Markowitz');