3 votos

Comparación de la rentabilidad de las distintas estrategias de rodaje

Estoy interesado en calcular el efecto del retorno del rollo utilizando diferentes estrategias de rollo. En concreto, quiero imitar una inversión en futuros a largo plazo. Tengo datos históricos de varias materias primas agrícolas. Para comparar los rendimientos de las diferentes estrategias de balanceo, he creado series temporales ajustadas a la relación utilizando las siguientes fórmulas.

Ajuste de la relación = (Precio nuevo contrato - Precio antiguo contrato)/(Precio antiguo contrato) Precios ajustados = (todos los futuros antiguos * ajuste de la relación) + precios del nuevo contrato

Como uso datos históricos que van desde los años 80 hasta finales de 2014 hay múltiples tiradas. Para cada uno hago estos ajustes (proceso iterativo). Así que el último contrato no se ajusta mientras que el primer contrato se ajusta decenas de veces (dependiendo de la estrategia de rollo). Quiero saber cuál es la rentabilidad de las distintas estrategias de balanceo. Por lo tanto, no estoy interesado en los precios de los contratos de futuros en sí (me doy cuenta de que estos se distorsionan por el ajuste de la relación). Además, dado que los futuros se negocian con margen, adoptaré un enfoque más académico y supondré que los futuros están totalmente garantizados. Esto significa que una cantidad "x" de dólares se invierte en T-bills, donde x es igual al precio del contrato de futuros. Por lo tanto, calculo la rentabilidad de las estrategias de balanceo de la siguiente manera:

Rendimiento = (nuevo precio de ajuste - antiguo precio de ajuste)/(antiguo precio de ajuste) - (interés de la letra t obtenido sobre el importe x) * 100

Sin embargo, creo que me estoy equivocando ya que la rentabilidad de una posición en soja es extraordinaria. En algún lugar del 600% (cuando no considero los intereses de las letras del tesoro ganados) en un período de tiempo de 1997 a 2014 cuando se hace rodar en el último día de negociación. ¿Qué se me escapa? ¿Cómo debo calcular y comparar el rendimiento de las diferentes estrategias de balanceo si este enfoque es erróneo?

** EDIT: Añadido el código R ** Esta es la función que utilizo para calcular el retorno del rollo en R. Cada fecha del rollo itero sobre esta función:

backAdjTSFun <- function(ts, rollRow, pastRollRow, rollFromColumn,df,adjRatio = FALSE,nextRollRow = NULL, lastColumn = NULL) {
  #adjust the exisiting data by the ratio
  if (is.null(pastRollRow)) {
    currentContractPrices <- df[1:rollRow, rollFromColumn]
    #because you do not necessarily start at the beginning of the dataset
    #there might be some na's from the first row onwards
    #hence, delete these first.
    currentContractPrices <- na.omit(currentContractPrices)
    updatedTS <- as.numeric(currentContractPrices) * as.numeric(adjRatio)
  } else {
    tsRatioAdj <- as.numeric(ts) * as.numeric(adjRatio)
    #You roll at the end of the last trading day to the next contract. Hence, you only need to start counting from the NEXT day. The last trading day is included in the rollFromColumn vector.
    dayAfterPastRoll <- pastRollRow + 1

    #For the deferred roll the last roll is not made. Due to data constraints.
    #Hence you need to make an adjustment and make sure that the data of the second last
    #roll is not adjusted.
    if(!is.null(lastColumn) && lastColumn == TRUE) {
      currentContractPrices <- df[dayAfterPastRoll:rollRow, rollFromColumn]
      updatedTS <- c(tsRatioAdj, currentContractPrices)
    } 
    #For the front month roll and last day roll you should add the contract prices of the
    #last roll unadjusted.
    else {  
      currentContractPrices <- df[dayAfterPastRoll:rollRow, rollFromColumn] * as.numeric(adjRatio)
      #combine the timeseries for the current contract and the already existing adjusted timeseries
      updatedTS <- c(tsRatioAdj, currentContractPrices)
      #if the column is the last column in the sample then
      #select the data in this column and append it to the price vector
      #without adjusting it.
      nextColumn <- rollFromColumn + 1
      if(nextColumn == length(df) && !is.null(nextRollRow)) {
        if(!is.null(lastColumn) && lastColumn == TRUE) {
          nextColumn <- lastColumn
        }
        currentContractPrices <- df[(rollRow+1):nextRollRow, nextColumn]
        updatedTS <- c(updatedTS, currentContractPrices)
      }
    }
  }
  return(updatedTS)
}

ldr <- function (df, settlement = FALSE, ret="roll", startAdj = F) {
  error <- NULL
  rollReturn <- NULL
  retMatrix <- matrix(,nrow=length(df),ncol=13)
  colnames(retMatrix) <- c("previousContract", "newContract", "difference", "rollDate","startDate", "endDate", "Mean roll return", "Std.", "Number of rolls", "Min", "25% - 75%", "Median", "Max")  
  # Ok, there are two possibilities here...
  # Possibility number 1: determine the last trading date of a contract.
  # The last trading is the settlement date
  firstTradingDay <- sapply(df, function (x) min(which(!is.na(x))))
  if (settlement == FALSE) {
    lastTradingDay <- sapply(df, function (x) max(which(!is.na(x))))
  }
  else {
    lastTradingDay <- settlement
  }
  n <- 1
  z <- 1
  pastRollRow <- NULL
  for (i in lastTradingDay) {
    if (n < length(df)) {
      z <- z + 1
      rollFrom <- as.numeric(as.character(df[i,n]))
      rollTo <-  as.numeric(as.character(df[i,n+1]))

      #backadj
      adjRatio <- rollTo/rollFrom
      ts <- backAdjTSFun(ts,i,pastRollRow,n,df,adjRatio,lastTradingDay[z]);
      pastRollRow <- i

      retMatrix[n,1] <- rollFrom
      retMatrix[n,2] <- rollTo
      retMatrix[n,3] <- calcReturn(rollFrom,rollTo)
      retMatrix[n,4] <- as.character(date[i])
    }
    n <- n + 1
  }
  transFormed <- as.numeric(retMatrix[,3])
  quantiles <- quantile(transFormed, c(0.25,0.75), na.rm=T)
  retMatrix[1,5] <- as.character(date[firstTradingDay[1]])
  retMatrix[1,6] <- as.character(date[tail(lastTradingDay,1)])
  retMatrix[1,7] <- mean(transFormed, na.rm=T)   
  retMatrix[1,8] <- sd(transFormed, na.rm=T)   
  retMatrix[1,9] <- length(na.omit(retMatrix[,3]))
  retMatrix[1,10] <- min(transFormed, na.rm=T)
  retMatrix[1:2,11] <- quantiles
  retMatrix[1,12] <- median(transFormed, na.rm=T)
  retMatrix[1,13] <- max(transFormed, na.rm=T)
  #Let the dates overlap/correspond with eachother at every entry across strategies --> add NA's before
  if (startAdj == TRUE && ret == 'ts' || ret == 'tsReturn') {
    ts <- c(rep('NA',firstTradingDay[1]-1),ts)
  }
  return(returnVal(ret, error, retMatrix, ts))  
}

Donde df es mi dataframe que es la salida de Datastream y data es un vector que contiene todas las fechas de la muestra.

** Resultados de la EDICIÓN **

[1] http://imgur.com/NWXv6FL "Resultados"

Cuando la FMR1 enrolla el contrato, enrolla la posición el último día del mes anterior al último día de liquidación. El FMR2 enrolla el contrato el último día de los dos meses anteriores al último día de liquidación y el LDR enrolla el contrato el último día de liquidación de un contrato.

0voto

Ngoc Pham Puntos 171

Bueno. Un método de ajuste rápido e ingenuo que ejecuté mostró un aumento de alrededor del 230% durante el mismo período, excluyendo cualquier interés, por lo que este resultado no es necesariamente irrazonable por sí mismo. Los rendimientos ajustados pueden depender en ocasiones drásticamente de cuáles sean sus reglas de balanceo, especialmente a medida que se profundiza en la historia.

Tal vez, haga un rápido repaso de sus precios/retornos. Algunos contratos (el de noviembre para la soja y otros) se negocian muy poco y deberían excluirse de las series de balanceo. Un mal precio en una fecha de balanceo puede estropear una serie.

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