2016-03-22 7 views
3

Ich versuche, die realisierte effiziente Grenze von einem Quartal zu schaffen, mit den täglichen Schlusskursen von hundert Aktien, keine Short-Positionen erlaubt.Fehler in der quadratischen Programmierung in R mit portfolio.optim Funktion

Der erste Schritt ist es, den Tag Rückkehr für den Zeitraum für jede Aktie zu berechnen:

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 

Dann habe ich die portfolio.optim() Funktion von {} das tseries Quadratisches Programm auszuführen, und schafft die ein optimales Portfolio:

w2 <-portfolio.optim(as.matrix(returns),shorts=FALSE,riskless=FALSE) 

Aber, wenn ich diese Funktion die folgende Meldung ausgeführt wird:

Error in solve.QP(Dmat, dvec, Amat, bvec = b0, meq = 2) : 
matrix D in quadratic function is not positive definite! 

Wenn ich den gleichen Code für weniger Aktien laufen, es scheint gut zu funktionieren:

# 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 

Jeder weiß, warum ich dieses Problem bin vor? Vielen Dank!

+0

Bitte geben Sie einen reproduzierbaren Beispiel – adaien

+0

Haben Sie versucht, es mit dem zweiten Teil der Daten 'Vermögenswerte rbm

+0

'[1: n-1,]' ist nicht '[1: (n-1),]'! '1: n-1' ist das gleiche wie' 0: (n-1) 'wegen der Vorrangstellung des Operators. – jogo

Antwort

4

OK, hatte einen Blick auf die Daten, und es ist OK. Das Problem ist, wie der Fehler sagt, dass die Kovarianzmatrix kein positiv definit ist. Ein schneller Test bestätigt, dass (BTW - ich verwende Pakete matrixcalc und 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)) 

bekommt

> matrixcalc::is.positive.definite(cov(returns)) 
[1] FALSE 

Was können Sie tun, anzupassen, ist die Kovarianzmatrix auf seine nächste positive definite Matrix durch Matrix::nearPD mit

returns.nearest.PD <- Matrix::nearPD(cov(returns))$mat 
returns.nearest.PD <- as.matrix(returns.nearest.PD) 

, die Sie erhalten dann von ex mit portfolio.optim erlauben plizit Angabe der covmat:

(po <- portfolio.optim(as.matrix(returns), 
       covmat = returns.nearest.PD, 
       shorts=FALSE,riskless=FALSE)) 

, die ohne Fehler funktioniert:

> sum(po$pw) 
[1] 1 

und Sie können bestätigen, dass es Gewichte für jedes Symbol hat:

> length(po$pw) 
[1] 99 

EDIT Nur um Sicher, die angepasste Kovarianzmatrix ist der ursprünglichen Kovarianzmatrix sehr ähnlich, die Diffs sind klein:

> # 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 
+0

vielen dank für ihre hilfe! Sehr geschätzt! –