miércoles, 6 de febrero de 2013

Ejemplo de Sistema de Trading con R


En esta ocasión vamos a ver un ejemplo concreto de sistema de trading en R, cómo se programa, y cómo se evalúa su rendimiento. El sistema que vamos a desarrollar es muy simple. Se basa en el cruce de dos medias móviles simples: una media móvil corta y una media móvil larga. Cuando la media móvil corta está por encima de la media móvil larga nos ponemos en largo, y cuando está por debajo, nos ponemos en corto.

Aquellas personas que hayan programado en otros lenguajes de trading, tales como mql4, encontrarán la forma de trabajar en R un tanto extraña. En la mayoría de los lenguajes para el desarrollo de estrategias de trading, lo que tenemos es un entorno (como por ejemplo MetaTrader 4 para mql4) que invoca nuestro sistema cada vez que hay un tick nuevo, o cada vez que se cierra una barra. Cuando esto ocurre, nuestro código lo que suele hacer es calcular los correspondiente indicadores técnicos, y decidir qué posiciones se cierran y qué posiciones nuevas se abren. Y es el propio entorno que rodea al lenguaje el que lleva la cuenta de las pérdidas y ganancias, así como del balance. En R es distinto. En R lo que tenemos son series temporales, y vectores numéricos, y lo que hacemos es manipularlos, y proceder al análisis de los resultados. Veamos cómo.

Lo primero que tenemos que hacer es importar aquellos paquetes R que necesitamos: quanmod para descargar los datos que necesitamos, TTR para calcular los indicadores técnicos, y PerformaceAnalytics para evaluar los resultados.

> require(TTR)
> require(quantmod)
> require(PerformanceAnalytics)

A continuación vamos a descargar los datos del cambio EUR/USD desde el servidor de Oanda. La función getSymbols del paquete quantmod descarga las últimas barras diarias que existen en el servidor (aproximadamente unas 500). En el caso de hacer análisis de estrategias reales para su uso en producción tendríamos que buscar una fuente de datos más completa, por ejemplo la que nos proporciona nuestro broker en barras de 1 minuto, e importarlas en R. De cómo hacer esto hablaremos en entradas posteriores de este blog.

> getSymbols(“EUR/USD”, src=”oanda”)

La función getSymbols nos ha creado automáticamente la serie temporal EURUSD, que podemos visualizarla gráficamente como explicamos cuando hablamos del paquete quantmod.

Para el cálculo de las medias móviles simples utilizamos la función SMA() del paquete TTR:

> mmc <- SMA(EURUSD, 5)
> mml <- SMA(EURUSD, 60)

Ahora necesitamos comparar ambas medias móviles para saber cuando la media móvil corta está por encima o por debajo de la media móvil larga, para ello nos creamos un nuevo vector que tendrá el valor 1 cuando esté por encima, y el valor -1 cuando esté por debajo:

> sen <- ifelse(mmc >= mml, 1, -1)

La función ROC (rate of change) nos indica la tasa de variación de una serie temporal, en nuestro caso lo que nos indicaría es si una barra ha cerrado por encima o por debajo de la barra anterior, en valores relativos. Vamos a calcular un vector con todas las tasas de cambio:

> ch <- ROC(EURUSD)

Y ahora viene lo interesante: si estamos en largo (valor 1 en el vector sen) y la tasa de cambio es positiva, ganamos dinero, pero si es negativa, perdemos. De igual manera, si estamos en corto (valor -1) y la tasa de cambio es positiva, perdemos dinero, pero si es negativa, ganamos. Es decir, para saber la tasa de beneficio que obtendremos con nuestro sistema lo que hay que hacer es multiplicar el vector de señales con el vector de tasa de cambio:

> ret <- ch * sen

Y ya tenemos todo lo que necesitamos. Vamos a ver qué tal ha funcionado nuestro sistema (los datos corresponden a una media móvil corta de 5, y una media móvil larga de 60). Primero vemos el retorno total acumulado con:

> Return.cumulative(ret)
EUR.USD
Cumulative Return 0.05120814

y cual es el máximo drawdown de nuestro sistema:

> maxDrawdown(ret)
[1] 0.116249

también podemos ver algunos indicadores más avanzados, como el ratio de Sharpe:

> SharpeRatio(ret)
EUR.USD
StdDev Sharpe: (Rf=0%, p=95%) 0.02546219
VaR Sharpe: (Rf=0%, p=95%) 0.01571873
ES Sharpe: (Rf=0%, p=95%) 0.01165527

Y para finalizar, vamos a ver gráficamente cómo se ha comportado el sistema con:

> charts.PerformanceSummary(ret)


Este gráfico se compone de tres partes. En la parte superior tenemos el retorno relativo acumulado. En el gráfico medio tenemos el retorno relativo desglosado por días. Y en el gráfico inferior tenemos el máximo drawdown que se ha producido.

9 comentarios:

  1. Estupendo artículo Ángel.

    Creo que te faltó comentar que además de instalar quantmod, como explicas en otros artículos, es necesario instalar además PerformanceAnalytics.
    install.packages('PerformanceAnalytics'))

    Un saludo.
    Juan Manuel Almodóvar

    ResponderEliminar
    Respuestas
    1. Sí, es cierto. PerformanceAnalytics tampoco viene por defecto y hay que instalarlo. Gracias.

      Eliminar
  2. Enhorabuena Ángel por tu proyecto.

    Tienes fechas previstas para empezar a mostrar Entropycs?

    Un saludo,
    Alex

    ResponderEliminar
    Respuestas
    1. Hola Alex,

      No hay fecha prevista para la presentación de la plataforma Entropycs. Aunque es posible que saque versiones preliminares para ver que tal acogida tiene en la comunidad de traders.

      En cualquier caso, todos los ejemplos que he puesto (y pondré) en este blog se pueden ejecutar en R sin problema.

      Un saludo, y gracias.

      Eliminar
  3. Todo lo que he leido me parece muy interesante, enhorabuena por el blog y el proyecto.

    Ya había leido algo sobre R aunque sin llegar a adivinar su potencial. Por lo que cuentas me atrae su versatilidad. Con los paquetes de trading comercial me da pereza invertir tiempo en conocerlos a fondo a sabiendas de que se quedan cortos, sobretodo en el tema estadistico y en la simulación de estrategias con varios instrumentos de forma simultanea.

    Tengo algunas preguntillas:
    - Al módulo de indicadores que comentas, ¿ se le pueden añadir indicadores de cosecha propia?
    - Aparte de leer datos de la web como comentas de oanda, yahoo, etc, ¿se pueden leer datos de ficheros de texto? lo digo por poder leer datos de futuros de diferentes vencimientos almacenados en disco.

    Muchas gracias, ya espero tu nueva entrega.
    Saludos
    Orion

    ResponderEliminar
    Respuestas
    1. > Al módulo de indicadores que comentas, ¿se le pueden añadir indicadores de cosecha propia?

      TTR es simplemente un acolección de indicadores listos para su uso. Si quieres crear nuevos indicadores lo puedes hacer directamente con R con ayuda de las utilidades de quantmod.

      > ¿se pueden leer datos de ficheros de texto?

      Los datos se pueden leer perfectamente desde fichero, con funciones tales como read.table o read.csv. En mi caso particular los tengo almacenados en una base de datos SQLite (si hay interés puedo postear sobre ello).

      Un saludo

      Eliminar
  4. Se me olvidaba, respecto a los gráficos ¿son estáticos? o admiten algun tipo de interactividad como los de google y yahoo? (zoom, moverse por la escala de tiempo, etc)
    Saludos, Orion

    ResponderEliminar
    Respuestas
    1. Tienes la función zooom() que te permite seleccionar un área del gráfico para hacer zoom sobre ella, pero poco más.

      R tiene una gran potencia y variedad de gráficos, pero desgraciadamente, no son interactivos. Esta es quizás la mayor limitación de R para los que nos dedicamos al trading. Pero bueno, en entropycs estamos trabajando para encontrar una solución :-)

      Eliminar