2 votos

¿Cómo crear una cesta de pares de divisas con la menor correlación en R?

Mi estrategia está diseñada para comprar y vender todos los activos de un universo y reequilibrar periódicamente. Va en largo o en corto. Para limitar la exposición al riesgo de una sola moneda, me gustaría que los activos del universo tuvieran una baja relación y una baja correlación de precios entre ellos (positiva o incluso negativa, ya que puede ir en corto).

Por ejemplo, si el universo tiene 3 pares de divisas A, B y C, mi objetivo es que la correlación de precios c1 (entre A y B), c2 (entre B y C) y c3 (entre A y C) sea lo más baja posible. Digamos que c0 es la media de c1, c2 y c3, dará información sobre la correlación "global" entre los pares A, B y C.

Ahora imaginemos que tenemos 26 pares de divisas (de la A a la Z) a considerar para crear un pequeño universo de 5 de ellos (3 fue para el ejemplo).

El método que aplico es crear todas las combinaciones posibles de grupos de 5 pares de divisas y luego calcula c0 correl$corr de cada grupo. También calculo la desviación estándar de c1, c2 y c3 correl$stddev ya que filtrará los grupos con c0 bajo y c1, c2 y c3 altos. Por último, sumo la correlación global y el stddev para clasificar los grupos con un único valor correl$"corr+stddev .

En este ejemplo, 16 pares son candidatos.

Mi conjunto de datos es un objeto xts con los precios históricos de los 16 pares de divisas. Podría ampliarlo a ~50 para mejorar la selección ya que supongo que más grande es la piscina y mejor debe ser.

Así es como procedo para conseguirlo :

# Put all symbols name in a list 
pairs <- names(mydata)
# Create groups of 5 currency pairs with no duplication
group <- combn( pairs , 5 )
# Calculate number of groups
nb_group <- ncol(group)
# Create empty object to store my result
result <- NULL
# For every groups
for (i in 1:nb_group) {

  # Calculate the mean correlation for the group
  correl <- round(mean(cor(mydata[, group[,i]])),3)
  # Transform as data frame and give a name
  correl <- as.data.frame(correl)
  colnames(correl) <- "cor"
  rownames(correl) <- toString(group[,i])
  # Calculate stddev and the sum of correlation and stddev
  correl$stddev <- round(sd(cor(mydata[, group[,i]])),3)
      correl$"cor+sddev" <- correl$cor + correl$stddev
  # export data
  result <- rbind(correl, result)
}

# Basket of currency pairs with the lowest correlation and stddev
head(result[order(result[,3]),])

Esto devuelve algo así como :

> head(result[order(result[,3]),])
                                          cor stddev      cor+sddev
GBPUSD, USDCAD, USDRUB, USDTRY, NZDUSD  0.032  0.583          0.615
GBPUSD, USDCHF, USDCAD, USDRUB, USDTRY  0.048  0.569          0.617
GBPUSD, USDJPY, USDRUB, USDTRY, NZDUSD  0.052  0.576          0.628
GBPUSD, USDCAD, EURCHF, USDRUB, USDTRY  0.048  0.582          0.630
GBPUSD, USDCAD, USDRUB, USDMXN, NZDUSD  0.065  0.566          0.631
GBPUSD, USDCHF, USDCAD, USDRUB, USDMXN  0.097  0.536          0.633

El resultado es el mismo cuando promedia la correlación y el stddev (en lugar de la suma)

¿Cree que R podría ayudar a conseguirlo y existe un enfoque más eficiente para crear dicha cesta de pares de divisas?

He comprobado paquetes de optimización de carteras como leonado , PortfolioAnalytics y fPortfolio pero desgraciadamente no estoy familiarizado con las fórmulas financieras y me he perdido.

Gracias, Florent

1voto

wyatt Puntos 126

Si entiendo bien su problema, está intentando buscar la cesta óptima de 5 pares (sin preocuparse de la ponderación).

El problema es que computacionalmente hay demasiadas combinaciones que ordenar.

Así que voy a proponer un algoritmo sencillo:

Calcule la matriz de correlación, tome el par que tenga la menor correlación media como semilla para su cesta, luego itere a través de las correlaciones con el resto de los pares buscando el siguiente par que esté menos correlacionado con la cesta actual y añadiéndolos iterativamente hasta que tenga suficientes elementos requeridos.

Si quieres añadir la correlación y el stddev, te sugiero que crees una función de preferencia o una función de utilidad para modelar el equilibrio entre ellas.

require(PerformanceAnalytics)
data(edhec)
##simple example on edhec test data

cormat = cor(edhec)

###Seed the basket
inital_asset = which.min(colMeans(cormat))
names_in_basket = labels(inital_asset)

###Grab the one least avg correlated with existing basket
while(length(names_in_basket)<5){
  if(length(names_in_basket)<2){
  names_in_basket=c(names_in_basket, labels(which.min(cormat[,names_in_basket[1]])))
  }else{
    names_in_basket=c(names_in_basket, labels(which.min(rowMeans(cormat[!rownames(cormat)%in%names_in_basket,names_in_basket]))))

      }

    }

###Sanity Check
mean(cormat[rownames(cormat)%in%names_in_basket,names_in_basket])<mean(cormat)

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