0

我遇到了 PortfolioAnalytics 包 (v1.0.3636) 中 create.EfficientFrontier 函数的意外结果。我正在尝试使用均值方差优化创建一个有效的边界。我所有的约束都是线性的。我在通话中设置了 n.portfolios = 100。它仅返回下表和图表中显示的 32 个投资组合。出乎意料的行为是边界存在缺口。虽然有不少差距,但较大的差距之一是在 result.62 和 result.94 之间。这两点之间的回报和风险有很大的跳跃。这就是我所说的差距。例如,我不明白为什么没有平均值接近 0.04 的点。我可以使用目标为 0.04 的 optimize.portfolio 函数并找到解决方案。cov 向量是 54x54,所以我没有包含数据。如果有人愿意,
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)

这是产生 return = 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 产生的 32 个点

                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

规格:

$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"
4

1 回答 1

1

你可以这样试试吗?

# 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

于 2016-05-20T21:22:44.747 回答