miércoles, 13 de febrero de 2013

Optimización Lineal de un Sistema con R


Una de las tareas más importantes en el desarrollo de un sistema de trading de éxito es la optimización del mismo. Una vez desarrollado un sistema de trading, y elegido el símbolo donde lo vamos a utilizar, la optimización consiste en encontrar aquellos parámetros que maximicen el rendimiento del sistema. Para ello lo que se hace es probar el sistema con diferentes combinaciones de parámetros, sobre un conjunto de datos históricos.

Optimizar un sistema es una tarea muy complicada, que requiere tener en cuenta multitud de factores para no caer en una sobre-optimización (una sobre-optimización se da cuando un sistema ha sido optimizado inadecuadamente, lo que le lleva a describir casi a la perfección el pasado, pero tiene una capacidad nula para predecir el futuro). Además, por otro lado, existen decenas de técnicas de optimización, cada una con sus ventajas e inconvenientes.

Aunque de todos estos temas tendremos tiempo de hablar en este blog, en esta ocasión vamos a empezar por lo más básico: como optimizar un sencillo sistema de trading mediante una optimización lineal. Para ello, vamos a utilizar un sistema basado en el cruce de dos medias móviles, del que ya hemos hablado en este blog.

Lo primero que vamos a hacer es empaquetar nuestro sistema en una función, de tal manera que pueda ser invocado con distintos valores de medias móviles, que es una condición necesaria para poder hacer la optimización. La función se llamará CDMM (de Cruce de Dos Medias Móviles), y recibirá tres parámetros: “símbolo” conteniendo el histórico del símbolo sobre el que queremos realizar la optimización, “mmc” que contiene el valor actual de la media móvil corta, y “mml” con el valor de la media móvil larga:

CDMM <- function(simbolo, mmc, mml) {

# Calculamos las medias móviles
vmmc <- SMA(simbolo, mmc)
vmml <- SMA(simbolo, mml)

# Calculamos la señal (cruce de dos medias móviles)
sen <- ifelse(vmmc >= vmml, 1, -1)

# Calcula el retorno
ret <- ROC(simbolo)*sen

return(ret)

}

A continuación descargamos los valores del símbolo como hacemos habitualmente, y definimos una tabla (data frame en la jerga de R) que contendrá tes columnas: “corta” para los valores sobre los que queremos iterar para la media móvil corta (5, 7, 9, ..., 43), “larga” igual para la media móvil larga (60, 65, 70, ..., 155), y “retorno” que contendrá el retorno relativo para cada combinación de media móvil corta y larga (para entender mejor cómo se construye el data frame recomiendo al lector que ejecute paso a paso las sentencias anteriores e imprima los resultados):

require(quantmod)
require(PerformanceAnalytics)
getSymbols(“EUR/USD”, src=”oanda”)

corta <- rep(seq(from=5, to=43, by=2), 20)
larga <- rep(seq(from=60, to=155, by=5), each=20)
retorno <- rep(NA, 400)
result <- data.frame(corta, larga, retorno)

Finalmente ejecutamos un bucle que nos compruebe el retorno obtenido por cada combinación de medias móviles (siguiendo la paradigma funcional de R debería haber utilizado una función tipo sapply() en vez de un bucle, pero por claridad he optado por el bucle):

for( i in 1:nrow(result)) {

row <- result[i,]
ret <- CDMM(EURUSD, row$corta, row$larga)
ret_cum <- Return.cumulative(ret)

result[i,]$retorno <- ret_cum

print(row$corta)
print(row$larga)
print(ret_cum)

}

Para ver los resultados podemos utilizar cualquiera de las funciones gráficas de R, por ejemplo:

persp(seq(from=5, to=43, by=2), seq(from=60, to=155, by=5), matrix(result$retorno, nrow=20), theta = 135, phi = 30, col = "green3", ltheta = -120, shade = 0.75)

Que nos mostraría el siguiente gráfico:
Nota: Me gustaría comentaros que hemos creado un grupo en LinkedIn para todos aquellos que tengáis interés en el análisis cuantitativo de estrategias de trading con R. Estáis invitados a uniros.

No hay comentarios:

Publicar un comentario