Gráficos Avanzados

La simplicidad de un teorema matemático como el de Pitágoras realza su tremenda belleza, pero también puede ocultar toda la complejidad, tesón y dolor involucrados en su elaboración original. Sin duda no tuvo que ser fácil si, como cuenta la leyenda, al completarlo su autor sacrificó 100 bueyes para dar gracias a los dioses.

Sin llegar a tal desperdicio de solomillos y chuletones también la elaboración de estrategias ganadoras va a requerir de nosotros mucho esfuerzo e inspiración. Para la prueba final unas pocas fórmulas numéricas bastarán, pero durante las arduas iteraciones exploratorias los gráficos adecuados pueden ahorrarnos muchas horas dando palos de ciego.

Hace ya algún tiempo explicamos cómo crear gráficos simples con PyAlgoTrade, pero no explotamos plenamente las posibilidades que una plataforma de código abierto nos puede ofrecer, así que vamos a permitirnos aquí la revancha: al final del artículo seremos capaces de desarrollar gráficos mucho más potentes.

Tamaño Personalizado

Ya sabemos cómo guardar gráficos en disco en lugar de mostrarlos en pantalla:

fig = plot.buildFigure(None, None)
fig.savefig("resultados.png")

Si necesitamos un gráfico mayor para ver la evolución con detalle, también podemos cambiar el tamaño con una sencilla instrucción indicando primero la anchura y luego la altura, ambos en pulgadas (recuerde que 1 pulgada = 2.54 cm).

fig.set_size_inches(60, 30)

Interactividad con Plotly

La capacidad de manipular un gráfico a tiempo real con nuestro ratón es una forma excelente de explorar la información que contiene. Esa interactividad nos la va a proporcionar Plot.ly, una compañía canadiense que además de proveer herramientas analíticas y estadísticas en línea ha desarrollado una serie de librerías de gráficos científicos para Python, R, MATLAB, Perl, Julia, Arduino, y REST que pueden usarse completamente offline, sin siquiera necesitar registrarse en su web.

Podemos instalar dicha librería con la comodidad a la que nos tiene acostumbrados pip:

C:\> pip install plotly

Para nuestros ejemplos usaremos una estrategia anterior con stops e indicadores: ahora no nos importan tanto los resultados como la presencia de gran cantidad de datos que queremos explorar visualmente. Descárguese la primera iteración en este archivo InteractiveGraphs1.py. Cuando la ejecute constatará, sin embargo, lo siguiente:

RuntimeError: Cannot get window extent w/o renderer

Este error proviene de una incompatibilidad entre plotly y la versión actual (1.5.1 al tiempo de escribir este artículo) de la librería gráfica matplotlib. La opción 1 para solucionarlo es volver a una versión anterior de la librería mediante pip:

C:\> pip install matplotlib==1.3.1

En cambio, es aconsejable que intentemos siempre trabajar con las últimas versiones de cada librería, porque al intentar evitar una incompatibilidad podemos exponernos a sufrir varias por otro lado. Si investigamos un poco veremos que los problemas surgen sólo debido al uso de las leyendas, en concreto esta instrucción del archivo plotter.py:

mplSubplot.legend(self._Subplot__series.keys(), shadow=True, loc="best")

Tampoco es recomendable que hagamos cambios directos en el código de las librerías, así que la opción 2 será utilizar la expresividad y flexibilidad de Python para reemplazar esa función entera sobre la marcha:

from pyalgotrade import plotter

def subplot_plot(self, mplSubplot, dateTimes):
 for series in self._Subplot__series.values():
 color = None
 if series.needColor():
 color = self._Subplot__getColor(series)
 series.plot(mplSubplot, dateTimes, color)

plotter.Subplot.plot = subplot_plot

Una vez hecho esto sólo nos queda ejecutar las siguientes instrucciones:

from plotly.offline import plot_mpl

plot_mpl(fig)

¡Así de sencillo! Obtendremos un archivo temp-plot.html con el que podemos trabajar directamente. Por otro lado si queremos que el gráfico se adapte al tamaño disponible en la pantalla sólo hemos de añadir lo siguiente:

plot_mpl(fig, resize=True)

interactive

Formato Personalizado

Plotly también nos permite afinar el formato de los gráficos con la granularidad que necesitemos, transformándolos primero a su propio formato:

import plotly.tools as tls

plotly_fig = tls.mpl_to_plotly(fig, resize=True)
plot(plotly_fig)

plotly_fig es un diccionario con dos partes, “data” y “layout” que podemos modificar libremente. Por ejemplo, las etiquetas “hover” no son muy precisas porque muestran mes y dia. Las vamos a modificar así para que muestren también el año:

for key, value in fl.items():
    if key.startswith("xaxis"):
        value['hoverformat'] = '%Y-%m-%d'

Por otro lado constataremos que las series no tienen nombres. Es algo que podemos modificar en plotply pero mejor hacerlo directamente en PyAlgoTrade con la flexibilidad que ya vimos arriba:

def plot(self, mplSubplot, dateTimes, color):
   values = []
   for dateTime in dateTimes:
       values.append(self.getValue(dateTime))
   mplSubplot.plot(dateTimes, values, color=color, marker=self.getMarker(), label=self.name)

plotter.Series.plot = plot

def getSeries(self, name, defaultClass=plotter.LineMarker):
    try:
        ret = self._Subplot__series[name]
    except KeyError:
        ret = defaultClass()
        ret.name = name
        self._Subplot__series[name] = ret
    return ret

plotter.Subplot.getSeries = getSeries

Extensión Interactiva

Para facilitar el uso repetido de estas mejoras en tantos ejercicios de backtesting como queramos es conveniente que coloquemos el código estructurado dentro de un módulo. Eso es precisamente lo que he hecho en el archivo iplots.py incluido en la carpeta de extensiones pyalgoext disponible como parte del repositorio de GitHub para este proyecto PyAlgoSamples. A partir de ese momento, crear gráficos interactivos es tan sencillo como escribir lo siguiente, como puede constatar si ejecuta este otro archivo de ejemplo InteractiveGraphs2.py:

from pyalgotrade import iplots

iplots.plot(plt.buildFigure())

¡Los resultados hablan por sí mismos! Vea que puede interactuar con los gráficos, comparar fechas, activar y desactivar cada línea pulsando sobre su leyenda, hacer zoom, arrastrar, etc.

plotly¿Tal vez prefiera eliminar el estilo de PyAlgoTrade y usar el propio de Plot.ly? Tan sencillo como añadir un parámetro a su llamada, y vea la diferencia:

iplots.plot(plt.buildFigure(), strip_style=True)

Múltiples Gráficos

Sea consciente también de que no estamos limitados a utilizar un sólo panel, o página web, para contener nuestros gráficos. Podemos utilizar tantos como creamos oportuno.

¿Queremos por ejemplo separar el seguimiento de operaciones y rentabilidad, por un lado, y los diferentes indicadores por otro para analizar mejor sus interacciones? Ningún problema, eso es precisamente la tarea que lleva a cabo este archivo InteractiveGraphs3.py. Cuando lo ejecute obtendrá dos páginas web, plot1.html y plot2.html que puede explorar por separado a pantalla completa.

interactive2

¡Aquí realmente puede constatar la adaptabilidad y potencia de un sistema de código abierto! Después resulta difícil volver al corsé de una plataforma cerrada, por mucho caramelo que le ofrezcan a la puerta del colegio 🙂

 

 

Anuncios

Responder

Introduce tus datos o haz clic en un icono para iniciar sesión:

Logo de WordPress.com

Estás comentando usando tu cuenta de WordPress.com. Cerrar sesión / Cambiar )

Imagen de Twitter

Estás comentando usando tu cuenta de Twitter. Cerrar sesión / Cambiar )

Foto de Facebook

Estás comentando usando tu cuenta de Facebook. Cerrar sesión / Cambiar )

Google+ photo

Estás comentando usando tu cuenta de Google+. Cerrar sesión / Cambiar )

Conectando a %s