投资组合优化SOLVE.QP不等式约束 [英] Portfolio Optimization SOLVE.QP inequality constraints
问题描述
我的名字是Grégory,我试图计算一个具有以下约束的最小方差组合:
My name is Grégory and I am trying to compute a Minimum Variance portfolio with the following constraints:
- 等于1(投资组合可以完全投资,但它不是一种义务)
- 总和高于或等于0(投资组合可以完全是现金,但不是一个义务)
-
0 <=资产重量<= 5%(不允许短期销售,最大资产重量为5%)
- Sum of the weights lower or equal to 1 (the portfolio can be fully invested, but it's not an obligation)
- Sum of the weights higher or equal to 0 (the portfolio can be fully in cash, but it's not an obligation)
0<= Asset weight <= 5% (no short-sales are allowed, and the maximum asset weight is 5%)
MV <-function(Returns,percentage = TRUE,...)
{
if(is.null {
stop('Returns'的参数必须为rectangle.\\\
)
}
call< - match.call()
V&返回,...)
V< - make.positive.definite(V)
N< - ncol(返回)
a1< b $ b b1 < - -1
a2 < - diag(N)
b2 <-rep(0,N)
c1 <已经添加到模型中(说:min 5%)
c2 <-rep(-0.05,N)##这已被添加到模型中(说:min 5%)
c3 ; - rep(1,N)
c4 < - 0
Amat < - cbind(a1,c3,a2,c1)###对应于定义不同约束的矩阵
Bvec < - c(b1,c4,b2,c2)###对应于约束的向量
Dvec <-rep(0,N)###设置为0,因为例程的第一项必须等于0
#meq <-c(1,1,rep(1,N),rep(1,N))
opt < dvc = Dvec,Amat = Amat,bvec = Bvec,meq = 0)
w_mv < - opt $ solution
names(w_mv)
w_mv< - w_mv * 100
return(w_mv)
}
当我查看MV投资组合权重时,所有资产权重都等于0,因此我不知道错误来自何处。
When I look at the MV portfolio weights, all the asset weights are equal to 0, so I don't know where the error comes from.
如果你能帮助我,我会非常感谢。
I would be very grateful if you could help me.
非常感谢,
Grégory
推荐答案
library(stockPortfolio) # Base package for retrieving returns
library(ggplot2) # Used to graph efficient frontier
library(reshape2) # Used to melt the data
library(quadprog) #Needed for solve.QP
# Create the portfolio using ETFs, incl. hypothetical non-efficient allocation
stocks <- c(
"VTSMX" = .0,
"SPY" = .20,
"EFA" = .10,
"IWM" = .10,
"VWO" = .30,
"LQD" = .20,
"HYG" = .10)
# Retrieve returns, from earliest start date possible (where all stocks have
# data) through most recent date
returns <- getReturns(names(stocks[-1]), freq="week") #Currently, drop index
#### Efficient Frontier function ####
eff.frontier <- function (returns, short="no", max.allocation=NULL,
risk.premium.up=.5, risk.increment=.005){
# return argument should be a m x n matrix with one column per security
# short argument is whether short-selling is allowed; default is no (short
# selling prohibited)max.allocation is the maximum % allowed for any one
# security (reduces concentration) risk.premium.up is the upper limit of the
# risk premium modeled (see for loop below) and risk.increment is the
# increment (by) value used in the for loop
covariance <- cov(returns)
print(covariance)
n <- ncol(covariance)
# Create initial Amat and bvec assuming only equality constraint
# (short-selling is allowed, no allocation constraints)
Amat <- matrix (1, nrow=n)
bvec <- 1
meq <- 1
# Then modify the Amat and bvec if short-selling is prohibited
if(short=="no"){
Amat <- cbind(1, diag(n))
bvec <- c(bvec, rep(0, n))
}
# And modify Amat and bvec if a max allocation (concentration) is specified
if(!is.null(max.allocation)){
if(max.allocation > 1 | max.allocation <0){
stop("max.allocation must be greater than 0 and less than 1")
}
if(max.allocation * n < 1){
stop("Need to set max.allocation higher; not enough assets to add to 1")
}
Amat <- cbind(Amat, -diag(n))
bvec <- c(bvec, rep(-max.allocation, n))
}
# Calculate the number of loops
loops <- risk.premium.up / risk.increment + 1
loop <- 1
# Initialize a matrix to contain allocation and statistics
# This is not necessary, but speeds up processing and uses less memory
eff <- matrix(nrow=loops, ncol=n+3)
# Now I need to give the matrix column names
colnames(eff) <- c(colnames(returns), "Std.Dev", "Exp.Return", "sharpe")
# Loop through the quadratic program solver
for (i in seq(from=0, to=risk.premium.up, by=risk.increment)){
dvec <- colMeans(returns) * i # This moves the solution along the EF
sol <- solve.QP(covariance, dvec=dvec, Amat=Amat, bvec=bvec, meq=meq)
eff[loop,"Std.Dev"] <- sqrt(sum(sol$solution*colSums((covariance*sol$solution))))
eff[loop,"Exp.Return"] <- as.numeric(sol$solution %*% colMeans(returns))
eff[loop,"sharpe"] <- eff[loop,"Exp.Return"] / eff[loop,"Std.Dev"]
eff[loop,1:n] <- sol$solution
loop <- loop+1
}
return(as.data.frame(eff))
}
# Run the eff.frontier function based on no short and 50% alloc. restrictions
eff <- eff.frontier(returns=returns$R, short="no", max.allocation=.50,
risk.premium.up=1, risk.increment=.001)
# Find the optimal portfolio
eff.optimal.point <- eff[eff$sharpe==max(eff$sharpe),]
# graph efficient frontier
# Start with color scheme
ealred <- "#7D110C"
ealtan <- "#CDC4B6"
eallighttan <- "#F7F6F0"
ealdark <- "#423C30"
ggplot(eff, aes(x=Std.Dev, y=Exp.Return)) + geom_point(alpha=.1, color=ealdark) +
geom_point(data=eff.optimal.point, aes(x=Std.Dev, y=Exp.Return, label=sharpe),
color=ealred, size=5) +
annotate(geom="text", x=eff.optimal.point$Std.Dev,
y=eff.optimal.point$Exp.Return,
label=paste("Risk: ",
round(eff.optimal.point$Std.Dev*100, digits=3),"\nReturn: ",
round(eff.optimal.point$Exp.Return*100, digits=4),"%\nSharpe: ",
round(eff.optimal.point$sharpe*100, digits=2), "%", sep=""),
hjust=0, vjust=1.2) +
ggtitle("Efficient Frontier\nand Optimal Portfolio") +
labs(x="Risk (standard deviation of portfolio)", y="Return") +
theme(panel.background=element_rect(fill=eallighttan),
text=element_text(color=ealdark),
plot.title=element_text(size=24, color=ealred))
ggsave("Efficient Frontier.png")
下面的链接中有一个很好的解释。
There is a good explanation of how this works at the link below.
http:// economistatlarge。 com / portfolio-theory / r-optimized-portfolio
这篇关于投资组合优化SOLVE.QP不等式约束的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!