Looking at your code, you seem to be mixing the risk minimization formulation of the mean-variance problem with the risk aversion formulation. Both formulations include the "budget" constraint, that the sum of the weights equal 1, and can require that each of the weights be greater than zero, the "long-only" inequality constraints. In the risk minimization problem, weights are found which minimize the portfolio variance subject to the constraint that the portfolio return equal a target return.
$$
\underset{w}{\arg \min} \quad w' Q w \quad \text{s.t} \quad rw = r_p,\quad \sum_i w_i=1, \quad w_i \geq 0\quad $$
where $Q$ is the covariance matrix and $r_p$ is the target portfolio return. In the risk aversion form, weights are found which maximize return less a risk aversion coefficient times the portfolio variance as you state in your post.
$$ \underset{w}{\arg \max} \quad w'r - \lambda w' Q w \quad \text{s.t} \sum_i w_i=1, \quad w_i \geq 0\quad
$$
where $\lambda$ is the risk aversion coefficient. Notice that there is no constraint on portfolio return in the risk aversion formulation.
In your code, the second constraint is an inequality constraint on returns which requires the portfolio return be $\geq r_p$ . With this constraint, you solution switches from a risk aversion model to a risk minimization model when the return falls below the target return. This is a possible model but doesn't seem to be what you intended.
While there are many variations of portfolio optimization using different methods for calculating risk and return, once you've chosen a method, there is only one efficient frontier. The code below is a modification of your code which shows how risk and return vary for decreasing the value of $\lambda$ and that this is just an alternate way of mapping the efficient frontier given this set of risks and returns.
library(quadprog)
efficientPortfolio <- function(er,cov.mat,aversion=3, target_return=NULL, method= c("risk_min","risk_aver","mixed","min_var") ){
n_asset <- length(er)
# quad problem
if(method %in% c("risk_min", "min_var")){
aversion = 1
Dmat <- cov.mat
dvec <- rep(0, n_asset)
meq <- ifelse(method == "min_var", 1, 2)}
else {
Dmat <- aversion*cov.mat
dvec <- er
meq <- 1}
# constraint eqns
if(method %in% c("risk_aver","min_var")) {
bvec <- c(1, rep(0,n_asset))
Amat <- matrix( c(rep(1,n_asset), diag(nrow=n_asset)), nrow=n_asset) }
else {
bvec <- c(1, target_return, rep(0,n_asset))
Amat <- matrix( c(rep(1,n_asset), er, diag(nrow=n_asset)), nrow=n_asset) }
sol<-solve.QP(Dmat, dvec,Amat, bvec=bvec, meq=meq)
weights<-sol$solution
exp.ret <- t(er)%*%weights
std.dev <- sqrt(weights %*% cov.mat %*% weights)
ret <- list(er = as.vector(exp.ret),
sd = as.vector(std.dev),
weights = weights,
lagrange_mults=sol$Lagrangian )
}
efficientFrontier <- function(er,cov.mat, nport=20, lambda_min = .1, lambda_max=2, lambda = 1,
target_return = NULL, method = c("risk_min","risk_aver","mixed") ) {
# if method = risk_min, input sequence of target_returns or use defaults; input target_returns < min_var return are not used
# = risk_aver, input upper and lower bounds of risk aversion coefficients lambda or use defaults
# = mixed, input single value of risk aversion coefficient lambda and seq of target_returns or use default
n_asset <- length(er)
method <- method[1]
lambda <- if(method == "risk_min"){
nport <- ifelse(is.null(target_return), nport, length(target_return))
rep(NA_real_,nport) }
else if(method == "mixed") rep(lambda, nport)
else seq(lambda_max, lambda_min, (lambda_min-lambda_max)/(nport-1))
ef <- list(Efficient_Frontier_method = method, sol=matrix(0, nrow=nport, ncol=3, dimnames=list(NULL, c("lambda", "sd", "return")) ),
weights= matrix(0, nrow=nport, ncol=n_asset),
lagrange_mults=matrix(0, nrow=nport, ncol=ifelse(method=="risk_aver", 1, 2) +n_asset) )
colnames(ef$lagrange_mults) <- if(method == "risk_aver") c("budget",rep("",n_asset)) else c("budget","target_return",rep("", n_asset))
# calculate minimum variance portfolio
port_min_var <- efficientPortfolio(er,cov.mat,target_return=NULL, aversion=NULL, method="min_var")
cat("Mininum Variance Portfolio\n sd return\n")
cat(sd=port_min_var$sd, return=port_min_var$er,"\n\n")
target_return <- if(is.null(target_return)) seq(port_min_var$er, max(er), length.out=nport)
else {
target_return[target_return < port_min_var$er] <- port_min_var$er
target_return
}
for (i in 1:nport) {
port <- efficientPortfolio(er,cov.mat,aversion=lambda[i], target_return=target_return[i], method=method)
ef$sol[i,"lambda"] <- lambda[i]
ef$sol[i,"sd"] <- port$sd
ef$sol[i,"return"] <- port$er
ef$weights[i,] <- port$weights
ef$lagrange_mults[i,] <- port$lagrange_mults
}
return(ef)
}
EDIT
The short answer to your question in the comment is yes. As the relation between the different risk formulations may be of interest, I've updated the code above to calculate efficient frontiers using both risk minimization (method = "risk_min") and risk aversion (method="risk_aver") methods. It will also treat your case where the two cases are mixed (method="mixed"). The code now also reports the lagrange multipliers for the points on the efficient frontier.
In particular, for your mixed case, which uses an inequality constraint on the portfolio return, you can see the switch from the risk adverse solution to the risk minimization solution. For smaller values of the target return where the return inequality constraint is not active, the portfolio solution is the same for different value of the target return since nothing has changed and the Lagrange multiplier for the return inequality is zero. As the target return increases, the portfolio return constraint becomes active and determines the solution, and the associated Lagrange multiplier takes on nonzero values. The solution has switched to the risk minimization case. It can be shown that the inverse of portfolio return Lagrange multiplier when it is nonzero is equal to the risk aversion coefficient. A thorough discussion of portfolio optimization using risk averse methods is given in an MSCI paper The Effects of Risk Aversion on Optimization especially in their Section B.6 where the relation between the Lagrange multipliers ( their dual variables $\pi_3$ and $\pi_4$ ) and the risk aversion coefficient is demonstrated.