Antecedentes
Mi objetivo final es encontrar un portafolio ubicado en la frontera eficiente a partir de una selección de 100 acciones de un índice bursátil (por ejemplo, S&P500).
Este portafolio eficiente será tal que su varianza sea la misma que la varianza del índice bursátil. En resumen, maximizando el rendimiento para un riesgo objetivo dado.
Problema
Primero aprendí a usar el paquete PortfolioAnalytics, pero obtuve un error de la función create.efficientFrontier cada vez que pasaba el argumento type="mean-StdDev" a la función.
Sin una solución para el problema anterior, decidí usar el paquete fPortfolio. Obtuve una frontera eficiente pero no puedo obtener una matriz con los pesos, rendimientos y varianza juntos para poder hacer una búsqueda binaria en la columna de varianza y luego seleccionar los pesos correspondientes (quizás haya una forma, pero soy nuevo en R).
Sin una solución para el problema anterior, decidí ir directamente a la solución solve.QP. Finalmente pude hacer lo que quería en primer lugar.
Una vez que obtuve una frontera eficiente, decidí compararla con la que obtuve de fPortfolio. Para mi sorpresa, los resultados de varianza difieren significativamente mientras que los rendimientos son los mismos. Una vez que solucioné el problema, descubrí que la diferencia se debía al argumento Dmat, es decir, la matriz de covarianza.
Estoy pasando Dmat <- Cov * 2 a la función solve.QP pero si en cambio uso Dmat <- Cov entonces obtengo los mismos resultados de fPortfolio. Nada cambió, mismo conjunto de datos, mismas restricciones. Obviamente, la varianza de los portafolios de solve.QP es el doble de la varianza de aquellos de fPortfolio.
Estoy usando la configuración predeterminada más básica en fPortfolio, es decir, solo pasando el conjunto de datos de rendimientos a ella.
Frontera del Portafolio de MV
Estimador: covEstimator
Solucionador: solveRquadprog
Optimizar: minRiesgo
Restricciones: SóloLargo
Pregunta
Me encontré con algunos códigos en la web multiplicando la matriz de covarianza por 2 y pasando esto como Dmat. Sin embargo, algunos otros códigos simplemente pasan la matriz de covarianza como Dmat a la función solve.QP (es decir, sin multiplicarla por 2).
- ¿Cuál enfoque es el correcto?
De mi investigación sobre la programación cuadrática y la función solve.QP, creo que la matriz de covarianza debe ser multiplicada por 2.
El procedimiento solve.QP implementa el método dual de Goldfarb e Idnani (1982, 1983) para resolver problemas de programación cuadrática de la forma min(-d^T b + 1/2 b^T D b) con las restricciones A^T b >= b_0.
La optimización de media-varianza (frontera eficiente) es un problema de programación cuadrática de la forma min(w^T D w - q R^T w) con las restricciones A^T w >= w_0.
Por lo tanto, al traducir la función objetivo de MV a la forma equivalente utilizada por solve.QP, la matriz de covarianza debe ser multiplicada por 2.
Sin embargo, esto implicaría que el código de fPortfolio es incorrecto.
- ¿Alguien ha notado este comportamiento de fPortfolio antes?
¡Creo que estoy pasando por alto algo muy básico aquí!
Código
frontera.eficiente <- function (ret, max.asignacion=NULL, rf=0, limite.riesgo=.5, incremento.riesgo=.005)
{
Dmat <- 2 * cov(ret)
n <- ncol(Dmat)
Amat <- cbind(1, diag(n))
bvec <- c(1, rep(0, n))
meq <- 1
if(!is.null(max.asignacion)){
Amat <- cbind(Amat, -diag(n))
bvec <- c(bvec, rep(-max.asignacion, n))
}
nCiclos <- limite.riesgo / incremento.riesgo + 1
iCiclo <- 1
eff <- matrix(.0, nrow=nCiclos, ncol=n+3)
colnames(eff) <- c(colnames(returns), "Rendimiento", "DesvEst", "RazonSharpe")
for (i in seq(from=0, to=limite.riesgo, by=incremento.riesgo))
{
dvec <- colMeans(ret) * i
sol <- solve.QP(Dmat=Dmat, dvec=dvec, Amat=Amat, bvec=bvec, meq=meq)
eff[iCiclo,"DesvEst"] <- sqrt(sum(sol$solution %*% colSums((Dmat * sol$solution))))
eff[iCiclo,"Rendimiento"] <- as.numeric(sol$solution %*% colMeans(ret))
eff[iCiclo,"RazonSharpe"] <- (eff[iCiclo,"Rendimiento"]-rf) / eff[iCiclo,"DesvEst"]
eff[iCiclo,1:n] <- sol$solution
iCiclo <- iCiclo+1
}
return(as.data.frame(eff))
}
0 votos
¿Podrías contarnos más sobre cómo obtuviste la frontera eficiente usando
fPortfolio
?0 votos
@BobJansen, estoy utilizando la configuración predeterminada en fPortfolio, es decir, solo pasando los datos de rendimiento a él.
0 votos
Mi función objetivo es para la cartera óptima de media-varianza. La configuración fPortfolio que he establecido es para la cartera de varianza mínima, que es una simplificación de la función objetivo anterior.
0 votos
Gracias a @AK88 por señalar el problema en el cálculo del StdDev. Ahora mi pregunta es ¿por qué el uso de dos funciones objetivo diferentes condujo a la misma frontera eficiente?