我有一个自2012年以来股票回报的时间序列对象.investmentFrontier函数可以很好地创建我的效率边界,直到我将数据集扩展到月数之后。例如,我看到有39个月,一切正常,有38只股票。但是一旦我添加第39个股票(和第40个等),我就会收到错误。代码和错误如下。
dput:
returns <- new("timeSeries", .Data = structure(c(-0.0108, 0.005, -0.0059, 0.0067, -0.0069, -0.0275,
0.0226, 0.0089, 0.0469, 0.0193, -5e-04, -0.03, -0.0483, 0.0251,
0.013, 0.0202, 0.019, 0.015, 0.0091, 0.002, -0.014, 0.0046, 0.002,
0.025, 0.008, 0.0177, -0.0023, 0.0023, -0.0217, 0.0045, 0.0117,
0.0081, 0.0345, 0.0332, 0.0098, 0.0086, -0.0362, -0.0137, 0.0162,
0.0276, 0.0749, 0.0691, 0.0275, -0.0278, -0.0442, 0.0226, -0.0136,
0.0305, 0.0178, 0.0061, 0.0034, 0.0039, -0.0042, -0.0017, 0.0039,
0.0083, -0.008, -0.0044, 7e-04, 0.0018, 0.008, -0.0057, 0.0044,
0.0043, 0.012, 0.0134, 0.003, 0.0078, -0.0092, 0.0113, 0.0132,
0.0168, 0.032, 0.037, 0.033, 0.017, -0.037, 0.027, 0.026, 0.018
), .Dim = c(8L, 10L), .Dimnames = list(NULL, c("Stock.A", "Stock.B",
"Stock.C", "Stock.D", "Stock.E", "Stock.F", "Stock.G", "Stock.H",
"Stock.I", "Stock.J")))
, units = c("Stock.A", "Stock.B", "Stock.C", "Stock.D", "Stock.E", "Stock.F",
"Stock.G", "Stock.H", "Stock.I", "Stock.J")
, positions = c(1327968000, 1330473600, 1333152000, 1335744000, 1338422400,
1341014400, 1343692800, 1346371200)
, format = "%Y-%m-%d"
, FinCenter = "GMT"
, recordIDs = structure(list(), .Names = character(0), row.names = integer(0), class = "data.frame")
, title = "Time Series Object"
, documentation = "Tue Jun 23 13:48:36 2015"
)
代码:
library(timeSeries)
library(fPortfolio)
# returns <- read.csv("Not Working Excel File.csv")
#lct <- Sys.getlocale("LC_TIME"); Sys.setlocale("LC_TIME", "C")
#returns[,1] = as.Date(as.character(returns[,1]),format="%d-%b-%y")
#Sys.setlocale("LC_TIME", lct)
#returns = timeSeries(returns[,-1], charvec = returns[,1])
Frontier <- portfolioFrontier(returns)
错误:
Error in `colnames<-`(`*tmp*`, value = c("AAPL", :
attempt to set 'colnames' on an object with less than two dimensions
如何解决此问题,以便在不添加日期的情况下添加我想要的股票数量?
编辑:以下是数据集外观的快照。 http://i.imgur.com/i0hkBdY.png 所以在这个例子里有8个月的数据和只有4个股票,我上面发布的代码运行正常。但是,一旦我再添加5个股票(总共9个),我就会得到上面列出的错误。
将数据框更改为矩阵会产生相同的错误。 添加更多月份可以让我添加更多股票,但我不想要更多月份。
答案 0 :(得分:0)
在没有添加任何更多月份(年)的情况下,您无法再添加任何股票的原因似乎与最小化均值差异的问题有关。
来自Cochrane“资产定价”第81-83页:
定理:只要回报的方差 - 协方差矩阵是非奇异的,就有一个均值 - 方差边界。
问题是“选择投资组合以尽量减少差异 对于给定的平均值“然后是
min {w}w0Σws.t。 W0
您可以使用本书中概述的拉格朗日乘数法来解决此问题。然而,值得注意的是,回归的协方差矩阵必须是非奇异的,这意味着协方差矩阵必须是正定。如果你提供的用于计算边界的协方差矩阵是单数的,那么边界将不存在。
dput:
returns <- new("timeSeries", .Data = structure(c(-0.0108, 0.005, -0.0059, 0.0067, -0.0069, -0.0275,
0.0226, 0.0089, 0.0469, 0.0193, -5e-04, -0.03, -0.0483, 0.0251,
0.013, 0.0202, 0.019, 0.015, 0.0091, 0.002, -0.014, 0.0046, 0.002,
0.025, 0.008, 0.0177, -0.0023, 0.0023, -0.0217, 0.0045, 0.0117,
0.0081, 0.0345, 0.0332, 0.0098, 0.0086, -0.0362, -0.0137, 0.0162,
0.0276, 0.0749, 0.0691, 0.0275, -0.0278, -0.0442, 0.0226, -0.0136,
0.0305, 0.0178, 0.0061, 0.0034, 0.0039, -0.0042, -0.0017, 0.0039,
0.0083, -0.008, -0.0044, 7e-04, 0.0018, 0.008, -0.0057, 0.0044,
0.0043, 0.012, 0.0134, 0.003, 0.0078, -0.0092, 0.0113, 0.0132,
0.0168, 0.032, 0.037, 0.033, 0.017, -0.037, 0.027, 0.026, 0.018
), .Dim = c(8L, 10L), .Dimnames = list(NULL, c("StockA", "StockB",
"StockC", "StockD", "StockE", "StockF", "StockG", "StockH",
"StockI", "StockJ")))
, units = c("StockA", "StockB", "StockC", "StockD", "StockE", "StockF",
"StockG", "StockH", "StockI", "StockJ")
, positions = c(1327968000, 1330473600, 1333152000, 1335744000, 1338422400,
1341014400, 1343692800, 1346371200)
, format = "%Y-%m-%d"
, FinCenter = "GMT"
, recordIDs = structure(list(), .Names = character(0), row.names = integer(0), class = "data.frame")
, title = "Time Series Object"
, documentation = "Tue Jun 23 13:48:36 2015"
)
代码块1:
# Load Matrix Checks
library(matrixcalc)
# Get dimensions and check if positive definite
dim(returns)
is.positive.definite(cov(returns))
### Results ###
# > dim(returns)
# [1] 8 10
# > is.positive.definite(cov(returns))
# [1] FALSE
正如您所看到的,协方差矩阵不是正定的,如果您尝试使用portfolioFrontier()
,则会产生错误。
> portfolioFrontier(returns)
Error in `colnames<-`(`*tmp*`, value = c("StockA", "StockB", "StockC", :
attempt to set 'colnames' on an object with less than two dimensions
代码块2:
# Remove first three columns to fit n (obs) > m (stocks)
returns <- returns[,4:10]
dim(returns)
#Check if positive definite
is.positive.definite(cov(returns))
### Results ###
# > dim(returns)
# [1] 8 7
# > is.positive.definite(cov(returns))
# [1] TRUE
现在检查portfolioFrontier()
输出:
Title:
MV Portfolio Frontier
Estimator: covEstimator
Solver: solveRquadprog
Optimize: minRisk
Constraints: LongOnly
Portfolio Points: 5 of 50
Portfolio Weights:
StockD StockE StockF StockG StockH StockI StockJ
1 0.0000 0.0000 0.0000 0.0000 1.0000 0.0000 0.0000
13 0.0000 0.0000 0.0000 0.1452 0.5016 0.2566 0.0966
25 0.0000 0.0000 0.0000 0.0000 0.1345 0.6738 0.1917
37 0.0000 0.0000 0.0000 0.0000 0.0000 0.4758 0.5242
50 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 1.0000
Covariance Risk Budgets:
StockD StockE StockF StockG StockH StockI StockJ
1 0.0000 0.0000 0.0000 0.0000 1.0000 0.0000 0.0000
13 0.0000 0.0000 0.0000 0.1417 -0.0570 0.4871 0.4282
25 0.0000 0.0000 0.0000 0.0000 -0.0455 0.5865 0.4589
37 0.0000 0.0000 0.0000 0.0000 0.0000 0.2196 0.7804
50 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 1.0000
Target Returns and Risks:
mean Cov CVaR VaR
1 0.0001 0.0056 0.0080 0.0080
13 0.0048 0.0037 0.0025 0.0025
25 0.0094 0.0092 0.0122 0.0122
37 0.0141 0.0158 0.0238 0.0238
50 0.0191 0.0237 0.0370 0.0370
似乎现在正在工作。因此,让我们绘制Efficient Frontier:
portfolio <- portfolioFrontier(returns)
plot(portfolio)