使用 portfolio.optim 函数在 R 中进行二次规划时出错
Error in quadratic programing in R using portfolio.optim function
我正在尝试从一个季度开始创建已实现的有效边界,每天一百只股票的收盘价,不允许空头头寸。
第一步是计算每只股票的周期内的每日return:
setwd("/Users/ClariceLoureiro/Desktop/COPPEAD/5th Term/Introducao ao Pacote estatistico em R/db")
getwd()
library(tseries)
Quarter <- read.csv2("20153Q.csv",header=T,dec=".")
assets <- Quarter
n <- nrow(assets)
returns <- (assets[2:n,])/(assets[1:n-1,])-1
然后我使用 {tseries} 中的 portfolio.optim() 函数执行二次规划并创建最佳投资组合:
w2 <-portfolio.optim(as.matrix(returns),shorts=FALSE,riskless=FALSE)
但是,当我 运行 这个函数时,会出现以下消息:
Error in solve.QP(Dmat, dvec, Amat, bvec = b0, meq = 2) :
matrix D in quadratic function is not positive definite!
当我 运行 相同的代码用于更少的股票时,它似乎运行良好:
# Choosing just 70 stocks out of 100
Quarter <- read.csv2("20153Q.csv",header=T,dec=".")
assets <- Quarter[,1:70]
#Calculating the returns
n <- nrow(assets)
returns <- (assets[2:n,])/(assets[1:n-1,])-1
#Portfolio optimization
w2 <-portfolio.optim(as.matrix(returns),shorts=FALSE,riskless=FALSE)
#Weights
w2$pw
[1] -3.644189e-19 2.390930e-18 1.156864e-01 -3.918512e-16 2.676315e-17 -3.136607e-16
[7] 3.158552e-16 3.901110e-16 -1.112018e-17 -1.927371e-16 1.264102e-19 9.040602e-17
[13] 4.881587e-02 2.291796e-17 -6.328846e-17 8.224983e-02 1.210207e-16 1.329818e-16
[19] 3.460248e-17 8.966350e-02 -4.929045e-17 1.689343e-17 -9.573418e-17 0.000000e+00
[25] -1.323861e-18 1.133006e-01 -1.896390e-17 -1.386383e-17 1.525087e-16 4.805648e-02
[31] -4.695605e-18 6.110056e-02 6.128005e-17 -1.042136e-17 9.100962e-03 1.846112e-17
[37] 5.128598e-17 -3.981178e-16 -4.379979e-16 1.936907e-17 4.694298e-02 2.676847e-18
[43] 8.752091e-18 4.121872e-02 2.970893e-17 6.871426e-03 3.612246e-17 4.217859e-17
[49] -4.834692e-18 3.071602e-17 -7.301697e-19 -1.309647e-17 2.034399e-02 4.689105e-03
[55] -6.014390e-19 6.389368e-02 7.511315e-02 -4.338530e-17 1.551683e-18 -6.838667e-20
[61] 1.445453e-18 4.783709e-17 4.803861e-17 1.866350e-02 -1.471388e-17 1.100957e-01
[67] 1.809216e-02 2.610136e-02 -2.751673e-17 1.393180e-18
# It must sum 1
sum(w2$pw)
[1] 1
有人知道我为什么会遇到这个问题吗?
非常感谢!
好的,看了资料,还可以。正如错误所说,问题是协方差矩阵不是正定的。快速测试证实
(顺便说一句 - 我正在使用包 matrixcalc
和 Matrix
):
library(tseries)
prices <- read.csv2("20153Q.csv",header=TRUE,dec=".")
n <- nrow(prices)
returns <- (prices[2:n,])/(prices[1:(n-1),])-1
portfolio.optim(as.matrix(returns), shorts=FALSE,riskless=FALSE)
# cov(X) not a positive definitive
# check
matrixcalc::is.positive.definite(cov(returns))
获得
> matrixcalc::is.positive.definite(cov(returns))
[1] FALSE
您可以使用 Matrix::nearPD
将协方差矩阵调整为其最接近的正定矩阵
returns.nearest.PD <- Matrix::nearPD(cov(returns))$mat
returns.nearest.PD <- as.matrix(returns.nearest.PD)
这将允许您通过显式指定 covmat
:
来使用 portfolio.optim
(po <- portfolio.optim(as.matrix(returns),
covmat = returns.nearest.PD,
shorts=FALSE,riskless=FALSE))
可以正常工作:
> sum(po$pw)
[1] 1
并且您可以确认它对每个符号都有权重:
> length(po$pw)
[1] 99
编辑
可以肯定的是,调整后的协方差矩阵与原始协方差矩阵非常接近,差异很小:
> # the matrices are really close
> sum((abs(returns.nearest.PD - cov(returns)) > 0.000000001)==TRUE)
[1] 0
> # the matrices are really close
> sum((abs(returns.nearest.PD - cov(returns)) > 0.0000000001)==TRUE)
[1] 74
我正在尝试从一个季度开始创建已实现的有效边界,每天一百只股票的收盘价,不允许空头头寸。
第一步是计算每只股票的周期内的每日return:
setwd("/Users/ClariceLoureiro/Desktop/COPPEAD/5th Term/Introducao ao Pacote estatistico em R/db")
getwd()
library(tseries)
Quarter <- read.csv2("20153Q.csv",header=T,dec=".")
assets <- Quarter
n <- nrow(assets)
returns <- (assets[2:n,])/(assets[1:n-1,])-1
然后我使用 {tseries} 中的 portfolio.optim() 函数执行二次规划并创建最佳投资组合:
w2 <-portfolio.optim(as.matrix(returns),shorts=FALSE,riskless=FALSE)
但是,当我 运行 这个函数时,会出现以下消息:
Error in solve.QP(Dmat, dvec, Amat, bvec = b0, meq = 2) :
matrix D in quadratic function is not positive definite!
当我 运行 相同的代码用于更少的股票时,它似乎运行良好:
# Choosing just 70 stocks out of 100
Quarter <- read.csv2("20153Q.csv",header=T,dec=".")
assets <- Quarter[,1:70]
#Calculating the returns
n <- nrow(assets)
returns <- (assets[2:n,])/(assets[1:n-1,])-1
#Portfolio optimization
w2 <-portfolio.optim(as.matrix(returns),shorts=FALSE,riskless=FALSE)
#Weights
w2$pw
[1] -3.644189e-19 2.390930e-18 1.156864e-01 -3.918512e-16 2.676315e-17 -3.136607e-16
[7] 3.158552e-16 3.901110e-16 -1.112018e-17 -1.927371e-16 1.264102e-19 9.040602e-17
[13] 4.881587e-02 2.291796e-17 -6.328846e-17 8.224983e-02 1.210207e-16 1.329818e-16
[19] 3.460248e-17 8.966350e-02 -4.929045e-17 1.689343e-17 -9.573418e-17 0.000000e+00
[25] -1.323861e-18 1.133006e-01 -1.896390e-17 -1.386383e-17 1.525087e-16 4.805648e-02
[31] -4.695605e-18 6.110056e-02 6.128005e-17 -1.042136e-17 9.100962e-03 1.846112e-17
[37] 5.128598e-17 -3.981178e-16 -4.379979e-16 1.936907e-17 4.694298e-02 2.676847e-18
[43] 8.752091e-18 4.121872e-02 2.970893e-17 6.871426e-03 3.612246e-17 4.217859e-17
[49] -4.834692e-18 3.071602e-17 -7.301697e-19 -1.309647e-17 2.034399e-02 4.689105e-03
[55] -6.014390e-19 6.389368e-02 7.511315e-02 -4.338530e-17 1.551683e-18 -6.838667e-20
[61] 1.445453e-18 4.783709e-17 4.803861e-17 1.866350e-02 -1.471388e-17 1.100957e-01
[67] 1.809216e-02 2.610136e-02 -2.751673e-17 1.393180e-18
# It must sum 1
sum(w2$pw)
[1] 1
有人知道我为什么会遇到这个问题吗? 非常感谢!
好的,看了资料,还可以。正如错误所说,问题是协方差矩阵不是正定的。快速测试证实
(顺便说一句 - 我正在使用包 matrixcalc
和 Matrix
):
library(tseries)
prices <- read.csv2("20153Q.csv",header=TRUE,dec=".")
n <- nrow(prices)
returns <- (prices[2:n,])/(prices[1:(n-1),])-1
portfolio.optim(as.matrix(returns), shorts=FALSE,riskless=FALSE)
# cov(X) not a positive definitive
# check
matrixcalc::is.positive.definite(cov(returns))
获得
> matrixcalc::is.positive.definite(cov(returns))
[1] FALSE
您可以使用 Matrix::nearPD
returns.nearest.PD <- Matrix::nearPD(cov(returns))$mat
returns.nearest.PD <- as.matrix(returns.nearest.PD)
这将允许您通过显式指定 covmat
:
portfolio.optim
(po <- portfolio.optim(as.matrix(returns),
covmat = returns.nearest.PD,
shorts=FALSE,riskless=FALSE))
可以正常工作:
> sum(po$pw)
[1] 1
并且您可以确认它对每个符号都有权重:
> length(po$pw)
[1] 99
编辑 可以肯定的是,调整后的协方差矩阵与原始协方差矩阵非常接近,差异很小:
> # the matrices are really close
> sum((abs(returns.nearest.PD - cov(returns)) > 0.000000001)==TRUE)
[1] 0
> # the matrices are really close
> sum((abs(returns.nearest.PD - cov(returns)) > 0.0000000001)==TRUE)
[1] 74