3 votos

Casi replicar una cesta con algunos de sus componentes

Motivación

Tengo una cesta con 30 componentes cada uno con un peso que quiero casi replicar con menos de 30 operaciones para reducir los costes de negociación.

Mejor definición

  1. Una mejor replicación equivale a una mayor correlación
  2. Tengo una función de costes que relaciona la correlación a la que estoy dispuesto a renunciar a cambio de menores costes de negociación
  3. El importe nominal en dólares debe ser el mismo
  4. No hay pesos negativos
  5. Sólo puedes intercambiar artículos de la cesta. No se permite nada fuera de ella, por muy correlacionada que esté.

Lo que he probado

  1. Regresión lineal con un subconjunto predefinido adhoc: rompe las definiciones #3-4, y aunque tiene una mayor correlación histórica por definición, las ponderaciones no parecen robustas para el futuro y parecen algo sobreajustadas.
  2. Usando la regresión lasso y afinando el parámetro lambda para un mayor o menor número de elementos seleccionados: todavía rompe los defs #3-4, pero la selección ya no es adhoc
  3. Regresión lineal restringida para que las ponderaciones sumen 1 y no se permitan ponderaciones negativas en un subconjunto adhoc: pasa todas las reglas, sin embargo, el proceso de estimación parece ser delicado. pequeñas diferencias en los coeficientes iniciales conducen a diferentes ponderaciones finales. también a veces la estimación no converge
  4. Dejar caer primero los componentes de menor peso y redistribuir los pesos: aunque funciona, para mí carece de formalidad y podría llevar a una cesta muy poco óptima una vez que se eliminen muchos artículos. También la redistribución de los pesos es objeto de debate. ¿Se hace por peso o por correlación relativa?

Además,no he encontrado ningún material formal (papers o libros) sobre este tema y también si me pudieran indicar sería de inmensa ayuda

2voto

BigCanOfTuna Puntos 210

Es posible que desee consultar la literatura sobre el índice de índices; tal vez encuentre ideas útiles en ella.

Lo escribiría y lo resolvería como un modelo de optimización de optimización. Dado que parece estar más interesado en el número de activos que se requieren para replicar estrechamente su cesta (es decir, la cardinalidad de la cesta de la cesta), podría resolver el modelo para diferentes cardinalidades y luego observar el equilibrio correlación/cardinalidad.

Permítanme esbozar cómo podría ser ese modelo de optimización en R, utilizando un método llamado Threshold Accepting (implementado en el NMOF paquete). Utilizo la correlación, tal y como la has descrito, aunque la correlación puede no ser la mejor medida para la cercanía, ya que puede tener cestas que están altamente correlacionados pero con volatilidades muy diferentes.

n <- 30  ## number of assets in original basket
k <- 3   ## number of assets in replicating basket

La cesta original: Asumo pesos iguales, pero simplemente pero se pueden añadir otros pesos si se desea.

w.basket <- rep(1/n, n)

library("NMOF")        ## https://github.com/enricoschumann/NMOF
library("neighbours")  ## https://github.com/enricoschumann/neighbours

Empiezo creando unos rendimientos aleatorios para sus 30 activos. El resultado es una matriz R de tamaño ns veces na .

random_returns <- function(na, ns, sd, mean = 0, rho = 0) {
    ## na   = number of assets
    ## ns   = number of scenarios
    ## sd   = vol of returns
    ## mean = means of returns
    ##      ==> sd and mean may be scalars or
    ##          vectors of length na    

    ans <- rnorm(na*ns)
    dim(ans) <- c(na, ns)

    if (rho != 0) {
        C <- array(rho, dim = c(na, na)) 
        diag(C) <- 1
        ans <- t(chol(C)) %*% ans
    }
    ans <- ans*sd
    ans <- ans + mean
    t(ans)
}

R <- random_returns(na = n, ns = 250, 0.01, rho = 0.1)

La aceptación del umbral es un método de optimización, por lo que necesitamos una función objetivo: la correlación entre su cesta y una cartera de réplica x . Para simplificar, también utilizo pesos iguales para x pero sólo para el k activos incluidos. Todas las demás ponderaciones son cero.

cor_basket <- function(x, R, w.basket, k, ...)
    -c(cor(R %*% (x/k), R %*% w.basket))

Lo mejor que se puede conseguir es una correlación de 1. Como seguimos la convención de minimizar, utilizamos menos la correlación.

cor_basket(w.basket, R, w.basket, k)
## [1] -1

A continuación, la parte clave de la aceptación de umbrales: la función de vecindad. La vecindad toma una solución, hace una copia, modifica la copia ligeramente (y al azar), y devuelve esta copia modificada. En el caso aquí, la función selecciona aleatoriamente un activo de la canasta y lo sustituye por un activo que no estaba en la cesta.

nb <- neighbourfun(type = "logical",
                   kmin = k,
                   kmax = k)

x0 <- c(rep(TRUE, k), rep(FALSE, n - k))
data.frame(x0, n1 = nb(x0), n2 = nb(x0))
##       x0     n1     n2
## 1   TRUE   TRUE  FALSE
## 2   TRUE  FALSE   TRUE
## 3   TRUE   TRUE   TRUE
## 4  FALSE  FALSE  FALSE
## 5  FALSE  FALSE  FALSE
## 6  FALSE  FALSE  FALSE
## 7  FALSE  FALSE  FALSE
## [...]
## 12 FALSE   TRUE  FALSE
## [...]
## 23 FALSE  FALSE   TRUE
## [...]

sol.ls <- TAopt(cor_basket,
                list(x0 = x0,
                     nI = 5000,
                     neighbour = nb),
                R = R,
                k = k,
                w.basket = w.basket)
## Threshold Accepting
##   [...]
##   Best solution overall: -0.6534397

Recordemos que hemos minimizado: así que la mayor correlación con una cartera de seguimiento de tres activos es de 0,65. Ahora, para ver cómo es la relación correlación/número de activos, basta con ejecutar un bucle.

for (k.i in 2:20) {
    x0 <- c(rep(TRUE, k.i), rep(FALSE, n - k.i))
    sol.ls <- TAopt(cor_basket,
                    list(x0 = x0,
                         nI = 5000,
                         neighbour = nb,
                         printDetail= FALSE,
                         printBar = FALSE),
                    R = R,
                    k = k.i,
                    w.basket = w.basket)
    message(format(k.i, width = 3),
            " | ",
            round(-sol.ls$OFvalue, 3))
}
##   2 | 0.566
##   3 | 0.653
##   4 | 0.721
##   5 | 0.765
##   6 | 0.8
##   7 | 0.833
##   8 | 0.86
##   9 | 0.876
##  10 | 0.89
##  11 | 0.9
##  12 | 0.913
##  13 | 0.921
##  14 | 0.931
##  15 | 0.938
##  16 | 0.946
##  17 | 0.95
##  18 | 0.955
##  19 | 0.96
##  20 | 0.965

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