2 votos

Cartera de optimización de los condicional restricciones de peso entre los activos

Quiero optimizar una cartera de activos de diferentes países (a,B,C...) donde el conjunto de todo el país-de los activos de combinaciones (A1, A2, A3, A4.... B1, B2, B3... C1...). Quiero incluir una restricción tal que sólo puedo invertir en un activo de un país determinado. Por ejemplo, si tengo que invertir en activos A1, entonces no puedo invertir en cualquier otro ", Un" activo.

Soy nuevo en la cartera de optimización y quería preguntar si hay algún paquete en R tal vez que de manera eficiente puede resolver este problema? Es este llamado no lineal entero restringida de la optimización?

Agradecería cualquier referencia que se ocupan de este problema y de los enlaces a R paquetes que pueden ser útiles.

Gracias!

2voto

BigCanOfTuna Puntos 210

Usted podría intentar una aproximación heurística.

El problema se puede dividir en dos anidada optimizaciones: i) en el interior de la optimización, dado un conjunto de activos seleccionados, calcular decir--varianza eficiente de pesos; ii) en el exterior de la optimización, se itera a través de combinaciones de activos.

El interior de la optimización puede ser resuelto a través de una ecuación cuadrática programa (QP). Para el exterior de la optimización, usted podría el uso de un local-técnica de búsqueda. Boceto de cómo un el método podría ser aplicado, puedo crear algunos datos aleatorios. Yo se asume que para cada activo, hay 60 regreso observaciones (para la intuición, para pensar en ellos como rendimientos mensuales).

set.seed(75578)

I <- cbind(0:15*1440+1, 1:16*1440)
rownames(I) <- LETTERS[1:nrow(I)]
colnames(I) <- c("first", "last")

R <- rnorm(60*max(I), sd = 0.02)
dim(R) <- c(60, max(I))

Los rendimientos de la matriz R es de tamaño 60 veces 23040, como por tu comentario: de 16 países con 1440 activos de cada uno. El columnas de R son asignados a los países a, B, ... y la inicio y fin de los índices para cada país se encuentran en la matriz I. Esta última matriz se parece a esto:

   first   last
A      1   1440
B   1441   2880
C   2881   4320
D   4321   5760
E   5761   7200
F   7201   8640
G   8641  10080
H  10081  11520
I  11521  12960
J  12961  14400
K  14401  15840
L  15841  17280
M  17281  18720
N  18721  20160
O  20161  21600
P  21601  23040

Puedo recoger todos estos datos en una lista única, lo que hace que es más fácil transmitir la información a una función.

Data <- list(I = I,
             nc = nrow(I),
             R = R)

Ahora supongamos que tenemos un conjunto de activos:

x <- Data$I[,1]

x ve de la siguiente manera:

    A     B     C     D     E     F     G     H 
    1  1441  2881  4321  5761  7201  8641 10081 
    I     J     K     L     M     N     O     P 
11521 12961 14401 15841 17281 18721 20161 21601

Para el cálculo de la solución para el interior problema, yo uso el la función mvar. Para mantener las cosas simples, se calcula el tiempo-sólo mínimo de la varianza de la cartera. La función hace uso de la NMOF paquete. (Yo soy el autor del paquete. Necesitarás la última versión, que puede ser instalado como se muestra a continuación o desde GitHub; con el CRAN versión, usted tendrá que escribir NMOF:::minvar).

## install.packages('NMOF', type = 'source',
##                  repos = c('http://enricoschumann.net/R',
##                            getOption('repos')))
require("NMOF")

mvar <- function(x, Data) {
    cv <- cov(Data$R[ ,x])
    w <- minvar(cv, wmin = 0, wmax = 0.5)
    c(sqrt(w %*% cv %*% w))
}

Comprobamos lo bien que la cartera x es mediante el cálculo de su valor de la función objetivo.

mvar(x, Data)

que, con la semilla, es

0.003645508

En realidad, antes de utilizar una búsqueda local, tratemos de un 'constructivo' solución como punto de referencia: seleccione el activo con el menor volatilidad de cada país, y, a continuación, calcular el mínimo de la varianza de los pesos de esta selección.

x_sort <- numeric(Data$nc)
for (i in 1:nrow(Data$I)) {
    cols  <- Data$I[i,1]:Data$I[i,2]
    x_sort[i] <- cols[order(apply(Data$R[ ,cols ], 2, sd))[1]]
}

Podemos calcular esta solución el valor de la función objetivo

mvar(x_sort, Data)

que es mejor:

0.002234832

Tenga en cuenta que la volatilidad (0.2%) es un orden de magnitud inferior a la media de la volatilidad de los al azar del conjunto de datos, que fue del 2%.

Ahora, en una búsqueda local, empezamos con un poco de solución y tratar de mejorarlo de forma iterativa. Para ello, necesitamos un barrio función que toma una de las soluciones y devuelve un poco cambiado solución. Aquí es una manera de escribir una función.

nb <- function(x, Data) {

    ## randomly pick one country 
    i <- sample(Data$nc, 1)

    ## randomly pick one asset 
    x[i] <- sample(Data$I[i,1]:Data$I[i,2], 1)

    x
}

Ahora trato de dos locales-algoritmos de búsqueda: simple estocásticos de búsqueda local (LSopt) y el Umbral de Aceptación (TAopt). Yo el uso de las implementaciones en el NMOF paquete. La diferencia entre los dos algoritmos es que LSoptle sólo aceptan a los vecinos que no son peores que el solución actual, mientras que TAopt es más tolerante y incluso a aceptar soluciones que son ligeramente peor que el solución actual. De esta manera, TAopt puede escapar de local los mínimos. Ambos métodos utilizan 100000 iteraciones.

steps <- 100000
sol_LS <- LSopt(mvar, list(x0 = Data$I[,1],
                           neighbour = nb,
                           nS = steps),
                Data = Data)

sol_TA <- TAopt(mvar, list(x0 = Data$I[,1],
                           neighbour = nb,
                           nS = steps/10),
         Data = Data)

Podemos comparar los resultados de ambos métodos con nuestro punto de referencia de la solución, que me agregue como un azul horizontal de la línea.

par(mar = c(5,5,1,1), las = 1, mgp = c(3,0.25,0), tck = 0.01)
plot(x = seq(1, steps, length.out = 1000),
     y = sol_TA$Fmat[seq(1, steps, length.out = 1000),2], log = "y",
     xlab = "iteration", ylab = "portfolio vol", type = "l")
lines(x = seq(1, steps, length.out = 1000),
     y = sol_LS$Fmat[seq(1, steps, length.out = 1000),2], col = grey(.4))
abline(h = mvar(x_sort, Data), col = "blue")
legend("topright", 
       legend = c("Local Search", "Threshold Accepting"),
       col = c(grey(.4), "black"), lwd = 4, lty =1)
text(x = steps*0.8, y = mvar(x_sort, Data), pos = 3,
     "lowest-vol asset per country", col = "blue")

enter image description here

LSopt (gris) y TAopt (negro) ambos a lograr soluciones de alrededor de 0.1%, por lo que claramente mejor que la de la solución constructiva. Umbral de Aceptación de prestaciones son ligeramente mejor que una simple búsqueda local.

1voto

Sassafras Puntos 18

Puesto que usted había especificado la función objetivo es media-varianza, entonces este es un problema fácil de resolver. Deje $R = (R_{A1}, \ldots, R_{An}, \ldots, R_{Z1}, \ldots, R_{Zn})$ ser el vector de retornos para todos los $A$ a $Z$ países, y por simplicidad en la notación, digamos que cada país tiene el mismo número de acciones (sólo ajustar las notaciones y las dimensiones en consecuencia, si no fuera el caso). Deje $dim(R) = N$, y deje $\mu = E[R]$ la media de retorno de vector, y $\Sigma = Var(R)$ ser la varianza-covarianza de la matriz.

La habitual media-varianza problema de optimización (puede ser escrito en una de varias maneras diferentes, pero esta es una manera):

$$ \max_{\pi} \; \pi^\top \mu - \frac{\eta}{2} \pi^\top \Sigma \pi \etiqueta{O} $$ donde $\eta > 0$ puede ser pensado como la aversión al riesgo del inversionista. Aquí, $\pi$ es el $N$-dimensiones vector que representa la cartera de pesos, y así tenemos la restricción presupuestaria que

$$ \pi^\top \iota = 1 \etiqueta{1} $$, donde $\iota$ es el $N$-dimensiones del vector de uno.

Sin más restricciones, la solución al anterior problema de optimización es la media de la varianza de la solución.

Lo que usted está buscando es un problema con restricciones adicionales. Sin pérdida de generalidad, reordenar la indexación si es necesario, digamos que sólo desea invertir en acciones número 1 de cada país. Definir un $n \times n$ matriz $K$ de la forma,

$$ K = \begin{bmatrix} 1 & 0 & \ldots & 0 \\ 1 & 0 & \ldots & 0 \\ & & \ddots & \\ 1 & 0 & \ldots & 0 \end{bmatrix} $$ a continuación, se definen las restricciones en los países de la a a la Z,

$$ K\pi_A = e_1, \ldots, K\pi_Z = e_1 \etiqueta{2} $$ donde $\pi_j = (\pi_{j1}, \ldots, \pi_{jn} )^\top$ es la cartera de vector para el país $j$. (claramente hay un camino a la pila de todo esto en una gran matriz de la ecuación, pero las dimensiones y la notación va a ser desordenado, y yo soy demasiado perezoso para volver a escribir el OP de la notación para los países de la a a la Z).

En conjunto, tenemos una concavidad de la función objetivo $(O)$, sujeto a dos restricciones lineales, donde $(1)$ es un (lineal) restricción presupuestaria, y $(2)$ es un (lineal) país de restricción. La solución existe y es única. Por otra parte, en este momento, cualquier programación cuadrática solver puede resolver esto (de hecho, incluso se puede configurar el Lagrangiano y todos y resolver este casi de forma explícita).

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