2016-04-28 65 views
0

我遇到PortfolioAnalytics包(v1.0.3636)中的create.EfficientFrontier函數意外的結果。我正在嘗試使用均值方差優化來創建一個有效的邊界。我所有的約束都是線性的。我在呼叫中設置了n.portfolio = 100。它只返回下面的表格和圖表中顯示的32個投資組合。意想不到的行爲是邊界存在差距。雖然存在不少差距,但其中較大的一個是結果62和結果94之間。兩點之間的回報和風險有很大的提高。這就是我所說的差距。我不明白爲什麼沒有平均值接近0.04的點。我可以使用目標爲0.04的optimize.portfolio函數並找到解決方案。 cov矢量是54x54,所以我沒有包含數據。如果有人想要它,我會發布它和ret矢量。
R<-xts(mvrnorm(n=120,cmf.tax.adjusted$ret,cmf.tax.adjusted$cov, empirical=TRUE),order.by=seq(as.Date("2000/12/31"),by="month",length.out=120)) eff<-create.EfficientFrontier(R=R,portfolio=pspec, type="mean-sd",match.col="StdDev",n.portfolios=100)爲什麼PortfolioAnalytics平均水平高效的邊界存在差距?

而這裏是產生一個返回的代碼= 0.04

pspec1<-pspec 
pspec1<- add.objective(portfolio=pspec1, type="return", name="mean",target=.04,indexnum=1) 
opt1<-optimize.portfolio(R,pspec1,optimize_method="ROI") 

的PSPEC被有效前沿之後所示create.EfficientFrontier

   mean  StdDev 
result.1 0.004818413 0.03159756 
result.2 0.005285545 0.03159756 
result.3 0.005752677 0.03159757 
result.9 0.008555470 0.03229847 
result.10 0.009022602 0.03257118 
result.11 0.009489734 0.03287380 
result.12 0.009956866 0.03319658 
result.13 0.010423998 0.03356550 
result.23 0.015095319 0.04085273 
result.25 0.016029583 0.04269109 
result.26 0.016496715 0.04363220 
result.27 0.016963847 0.04458671 
result.29 0.017898112 0.04653263 
result.31 0.018832376 0.04855024 
result.32 0.019299508 0.04958316 
result.33 0.019766640 0.05063005 
result.52 0.028642150 0.07234101 
result.53 0.029109282 0.07355126 
result.54 0.029576414 0.07476445 
result.55 0.030043546 0.07598045 
result.56 0.030510678 0.07719941 
result.57 0.030977810 0.07842371 
result.59 0.031912074 0.08090880 
result.60 0.032379206 0.08217014 
result.61 0.032846338 0.08344324 
result.62 0.033313470 0.08472759 
result.94 0.048261697 0.13508563 
result.95 0.048728829 0.13692166 
result.96 0.049195961 0.13901611 
result.97 0.049663094 0.14122860 
result.98 0.050130226 0.14345820 
result.99 0.050597358 0.14571323 
產生

enter image description here 32分

pspec:

$assets 
     USCash-taxed  STUSTsy-taxed  LTUSTsy-taxed  USTIPs-taxed  USCore-taxed 
     0.01960784   0.01960784   0.01960784   0.01960784   0.01960784 
    GlobalCore-taxed   HiYld-taxed  BankLoans-taxed EMNonLclDebt-taxed EMLocalDebt-taxed 
     0.01960784   0.01960784   0.01960784   0.01960784   0.01960784 
    EMCurrency-taxed Commodities-taxed   REIT-taxed  USLarge-taxed  USSmall-taxed 
     0.01960784   0.01960784   0.01960784   0.01960784   0.01960784 
    EAFEEquity-taxed  EMEquity-taxed  USCash-defer  STUSTsy-defer  LTUSTsy-defer 
     0.01960784   0.01960784   0.01960784   0.01960784   0.01960784 
     USTIPs-defer  USCore-defer GlobalCore-defer   HiYld-defer  BankLoans-defer 
     0.01960784   0.01960784   0.01960784   0.01960784   0.01960784 
EMNonLclDebt-defer EMLocalDebt-defer EMCurrency-defer Commodities-defer   REIT-defer 
     0.01960784   0.01960784   0.01960784   0.01960784   0.01960784 
     USLarge-defer  USSmall-defer EAFEEquity-defer  EMEquity-defer  USCash-exempt 
     0.01960784   0.01960784   0.01960784   0.01960784   0.01960784 
    STUSTsy-exempt  LTUSTsy-exempt  USTIPs-exempt  USCore-exempt GlobalCore-exempt 
     0.01960784   0.01960784   0.01960784   0.01960784   0.01960784 
     HiYld-exempt BankLoans-exempt EMNonLclDebt-exempt EMLocalDebt-exempt EMCurrency-exempt 
     0.01960784   0.01960784   0.01960784   0.01960784   0.01960784 
Commodities-exempt   REIT-exempt  USLarge-exempt  USSmall-exempt EAFEEquity-exempt 
     0.01960784   0.01960784   0.01960784   0.01960784   0.01960784 
    EMEquity-exempt 
     0.01960784 

$enabled_constraints 
$enabled_constraints[[1]] 
An object containing 6 constraints. 
Some constraints are of type nonlinear. 

$enabled_constraints[[2]] 
An object containing 5 constraints. 
Some constraints are of type nonlinear. 

$enabled_constraints[[3]] 
An object containing 6 constraints. 
Some constraints are of type nonlinear. 


$disabled_constraints 
list() 

$enabled_objectives 
$enabled_objectives[[1]] 
$name 
[1] "mean" 

$target 
NULL 

$arguments 
list() 

$enabled 
[1] TRUE 

$multiplier 
[1] -1 

$call 
add.objective(portfolio = pspec, type = "return", name = "mean") 

attr(,"class") 
[1] "return_objective" "objective"  

$enabled_objectives[[2]] 
$name 
[1] "StdDev" 

$target 
NULL 

$arguments 
$arguments$portfolio_method 
[1] "single" 


$enabled 
[1] TRUE 

$multiplier 
[1] 1 

$call 
add.objective(portfolio = pspec, type = "risk", name = "StdDev") 

attr(,"class") 
[1] "portfolio_risk_objective" "objective"    


$disabled_objectives 
list() 

attr(,"class") 
[1] "summary.portfolio" 
+0

有時只是無法實現所需的回報率。你能把你的宇宙中的股票添加到情節中嗎? – lebelinoz

回答

0

你能試試嗎?

# Economist at Large 
# Modern Portfolio Theory 
# Use solve.QP to solve for efficient frontier 
# Last Edited 5/3/13 

# This file uses the solve.QP function in the quadprog package to solve for the 
# efficient frontier. 
# Since the efficient frontier is a parabolic function, we can find the solution 
# that minimizes portfolio variance and then vary the risk premium to find 
# points along the efficient frontier. Then simply find the portfolio with the 
# largest Sharpe ratio (expected return/sd) to identify the most 
# efficient portfolio 

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") 

下面是一個鏈接,您可以從中瞭解更多關於代碼的內容。

http://economistatlarge.com/portfolio-theory/r-optimized-portfolio

+0

謝謝。是的,我可以使用quadprog等,通過我的輸入建立一個有效的邊界。我希望能使用一個軟件包。另外,我的問題是我更喜歡使用預測值(至少用於返回)而不是歷史數據。但是你的方法確實有效。我想了解PortfolioAnalytics好一點。 – rmacey