1

我看到的每个包裹似乎都需要我的资产的时间序列回报。

例如,我喜欢 PortfolioAnalytics 包,我需要提供许多约束(框约束、组约束等)。然而,据我所知,它需要某种时间序列的回报,即使我指定了自己的时刻(我可能是错的)。

我所拥有的只是我 14 种资产中每一种资产的预期收益和协方差矩阵。

如何以此为出发点进行各种形式的优化?最终,我想建立一个完整的有效边界,并能够在给定的风险水平(标准差)下最大化回报给我的限制。如果我有一个时间序列,这不会是一个问题......但可惜我没有。

谢谢。我觉得这应该很容易,但我一直在绕圈子。

最坏的情况是我可以构建一个符合 E(R) 和协方差矩阵参数的假时间序列。如果您认为这是我的解决方案,您能否提供一种简单的方法来做到这一点...但这就是为什么我在这里 :)

4

2 回答 2

1

这个怎么样?

library(stockPortfolio)
library(quadprog)
library(ggplot2)
stocks <- c("SPY",  "EFA",  "IWM",  "VWO",  "LQD",  "HYG")

returns <- getReturns(stocks, freq = "week")

eff.frontier <-  function (returns,
                           short = "no",
                           max.allocation = NULL,
                           risk.premium.up = .5,
                           risk.increment = .005) {
  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 based on how high to vary the risk premium and by what increment
  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 up along the efficient frontier
    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))
}

eff <-
  eff.frontier(
    returns = returns$R,
    short = "yes",
    max.allocation = .45,
    risk.premium.up = .5,
    risk.increment = .001
  )


eff.optimal.point <- eff[eff$sharpe == max(eff$sharpe),]

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 variance)", y =
                                                                "Return") +
  theme(
    panel.background = element_rect(fill = eallighttan),
    text = element_text(color = ealdark),
    plot.title = element_text(size = 24, color = ealred)
  )

这也应该有所帮助。

https://www.r-bloggers.com/a-gentle-introduction-to-finance-using-r-efficient-frontier-and-capm-part-1/

于 2020-02-15T03:09:11.543 回答
1

如果您想使用特定包,并且该特定包仅允许时间序列,那么是的,您使用该特定包的唯一方法是创建与您的均值和方差协方差矩阵匹配的时间序列。(但您可能想检查包从这些时间序列计算均值/方差协方差矩阵的方式。)有关 如何创建此类序列的信息,请参见https://stackoverflow.com/questions/58293991 。

对于均值方差优化,需要时间序列(并且不提供替代的覆盖方法)对于包的一部分来说是一个糟糕的设计选择。(而且我很难相信它PortfolioAnalytics不应该提供这样的机制。)均值方差优化的输入是均值预测和方差协方差矩阵的预测。此类预测可能由历史数据提供或基于历史数据。但即便如此,也有许多不同的可能性来计算这些数量,例如收缩。

在任何情况下,我维护的NMOFminvar都具有函数,mvPortfolio 用于基于均值向量和方差-协方差矩阵计算最小方差和均值方差有效的投资组合。在 的开发版本中NMOF,这些功能还允许指定组约束。

于 2020-02-13T06:51:07.830 回答