5 votos

Paquete de R para la cartera

En el contexto de la moderna teoría de la cartera, a menudo se desea minimizar $\mathbf{w}^{\mathrm{{\scriptstyle T}}}\boldsymbol{\Sigma}\mathbf{w}$ sujeto a $\mathbf{w}^{T}\boldsymbol{\mu}=c_{1}$, $\left\Vert \mathbf{w}\right\Vert _{1}<c_{2}$ y $\mathbf{w}^{T}\mathbf{1}=1$. Hay una función de R o paquete para hacer esto?

4voto

scottishwildcat Puntos 146

Si usted puede agregar lineal constriants (como se puede hacer en quadprog), entonces usted puede formular $w \mu = c_1$ lineal de restricción, no importa lo que $\mu$ es (y borrarlo primero desde el objetivo por el valor del parámetro a cero. El único problema es la norma. Vamos a aclarar mi, esto es: $$ \sum_{i=1}^n |w_i| < c_2 $$ Por lo tanto se permiten las ventas en corto, pero desea limitar el apalancamiento -> a la derecha? Me temo que quadprog no puede manejar este tipo de restricciones.

Algunos de los solvers puede manejar cuadrática limitaciones, a continuación, $$ \sum_{i=1}^n |w_i|^2 = w^T w< c_2^* $$ sería limitar el apalancamiento. La primera ecuación anterior describe una restricción para la $L_1$-norma. Si te refieres a que $|w_i|$ debe estar delimitado por cada $i$, a continuación, por supuesto, esto se obtiene de las dos desigualdades: $$ w \le c_2 \quad \text{y} \quad w \ge -c_2. $$

EDITAR después del comentario de Juan: El paquete nloptr puede manejar no restricciones lineales. Seguir los ejemplos en el enlace para definir la función objetivo y las restricciones. Tenga en cuenta que el gradiente de $$ f(w) = w^T \Sigma w $$ está dada por $$ 2 \Sigma w.$$ Proporcionar el gradiente va a mejorar el resultado de este no-lineal optimizador.

EDIT: Si quieres algo construido para la optimización del portafolio directamente, entonces usted puede mirar fPorfolio y, por ejemplo, este presentaton. Me parece que la documentación carece de detalles, y me pregunto si todas las funciones "prometido" en la presentación de funcionar correctamente. En la página 13 dicen que el paquete se puede manejar no restricciones lineales. Si lo intentas, a continuación, por favor, díganos si esto funciona.

2voto

ARKBAN Puntos 1388

Me pregunto si es posible usar solve.QP de quadprog mediante el uso de variables ficticias. Una variable ficticia $y_i$ sería utilizado por cada $w_i$ cada $y_i$ vería obligado a ser mayor que cero, y el apalancamiento de la restricción se aplicará a la suma de los $y_i$. La formulación del problema se vería $$ \text{min } w^tΣw $$ sujeto a las restricciones $$ w^t\mu= c_1 $$ $$ w^t 1 = 1 $$

$$ y_i \geq 0 $$ $$ w_i + y_i \geq 0 $$ $$ -w_i + y_i \geq 0 $$

$$ -\sum y_i \geq-c_2 $$

Código podría parecer

leveraged_port <- function( er,cov.mat, target_return=NULL, leverage=1., tickers=NULL ){
   library(quadprog)
# leverage checks and adjustments
   if(leverage < 1.) stop( "leverage must be >= 1.")
   if( target_return > (leverage+1)/2*max(er)) stop("target_return not achievable; increase leverage or decrease target_return")
   lev_adj  <- 1.E-06
   if(leverage < 1 + lev_adj) leverage  <- 1 + lev_adj
   n_asset <- length(er)
   zeros <- integer(n_asset)
 # quad problem
 # calculate small diag value for dummy variables so Dmat is positive def.
    diag_dum <- 1.e-05*min(diag(cov.mat))
    Dmat <- diag(diag_dum, nrow=2*n_asset, ncol=2*n_asset)
    Dmat[1:n_asset, 1:n_asset] <- 2*cov.mat
    dvec <- numeric(2*n_asset)
    meq <-  2
 # constraints on weights
    bvec <- c(1, target_return)
    Amat <- matrix( c(rep(1,n_asset), er, diag(n_asset), -diag(n_asset), diag(0, nrow=n_asset),
                      zeros), nrow=n_asset) 
 # constraints on dummy variables
    bvec <- c(bvec, zeros, zeros, zeros, -leverage)
    Amat <- rbind( Amat, matrix(c(zeros, zeros, diag(n_asset), diag(n_asset), diag(n_asset), 
                                  -rep(1,n_asset)), nrow=n_asset))
    sol<-solve.QP(Dmat, dvec, Amat, bvec, meq=meq)
    weights<-sol$solution[1:n_asset]
        names(weights) <- tickers
        exp.ret <- t(er)%*%weights
        std.dev <- sqrt(weights %*% cov.mat %*% weights)
        ret <- list(er = as.vector(exp.ret),
                    StdDev = as.vector(std.dev),
                    weights = weights,
                    sum_weights = sum(weights),
                    leverage = sum(abs(weights)),
                    lagrange_mults=sol$Lagrangian )  
 }

Resultados en el ejemplo siguiente problema parece factible

library(quantmod)
tickers <- c("MSFT","AAPL", "AMZN", "YHOO", "XOM", "CVX", "UNH", "NKE")
prices <- do.call(cbind, 
         lapply(tickers, function(x) getSymbols(x, from="2010-01-01", auto.assign=FALSE, warnings=FALSE)[,6]))
colnames(prices) <- tickers
returns <- diff(prices, arithmetic=FALSE, na.pad=FALSE) - 1
means <- sapply(returns, mean)

QPsol <- leveraged_port(er=means, cov.mat=cov(coredata(returns)), target_return=.0016, leverage=1.8, tickers)

con los resultados

QPsol
$er
[1] 0.0016

$StdDev
[1] 0.01830004

$weights
         MSFT          AAPL          AMZN          YHOO           XOM           CVX           UNH           NKE 
-9.809695e-14  1.044254e+00 -5.297152e-14 -1.780017e-17 -4.000000e-01 -1.556950e-13  3.557464e-01  4.224909e-14 

$sum_weights
[1] 1

$leverage
[1] 1.8

Finanhelp.com

FinanHelp es una comunidad para personas con conocimientos de economía y finanzas, o quiere aprender. Puedes hacer tus propias preguntas o resolver las de los demás.

Powered by:

X