⚠ El trading implica un riesgo significativo de pérdida. Todo el contenido de este sitio es únicamente educativo y no constituye asesoramiento financiero.
Lección 10 de 13 · Gratis

Gráficos para el análisis: precio con indicadores, gráficos de capital y drawdown, distribuciones de rentabilidades y exportación de figuras

Usa la interfaz de figura y ejes de matplotlib para construir los cuatro gráficos que necesita todo informe de backtest, interprétalos correctamente y expórtalos con calidad de impresión.

Autor: Moustafa HijaziContenido revisado: 2026-10-306 min de lecturaCurso de autoaprendizaje

Qué aprenderás

  • El patrón fig, ax = plt.subplots() y por qué es mejor que el atajo rápido series.plot() para todo lo que vayas a reutilizar.
  • Cómo apilar paneles de precio, indicador y capital que comparten un mismo eje temporal, y cuándo pasar el eje del capital a escala logarítmica.
  • Cómo dibujar un gráfico de drawdown y un histograma de rentabilidades, y qué buscar en cada uno.
  • Cómo determinan el tamaño de la figura, los DPI y el formato de archivo el aspecto de la imagen exportada.

Explicación

En la investigación, los gráficos no son decoración; son la comprobación más rápida de que tus números son correctos. Una curva de capital que salta un 30 % en un día suele indicar un error en los datos, no una gran operación. Esta lección usa matplotlib, al que pandas llama internamente, a través de su interfaz orientada a objetos.

Figura, ejes y el eje temporal compartido

Una figura es el lienzo completo; un objeto axes (ejes) es un área de gráfico dentro de ella. fig, axes = plt.subplots(3, 1, figsize=(10, 8), sharex=True, height_ratios=[3, 1, 1]) crea tres paneles apilados de distinta altura que se amplían a la vez. El patrón para cada panel es el mismo: llama a ax.plot(x, y, label=...) y después a ax.set_ylabel, ax.legend() y ax.grid(True, alpha=0.3). Da a cada panel un título breve e indica las unidades (€, %, puntos).

Precio con indicadores

  • fig, (ax1, ax2) = plt.subplots(2, 1, figsize=(10, 6), sharex=True, height_ratios=[3, 1])
  • ax1.plot(df.index, df.close, lw=1, label='Cierre')
  • ax1.plot(df.index, df.sma50, lw=1, label='SMA 50')
  • ax1.fill_between(df.index, df.bb_lo, df.bb_hi, alpha=0.15, label='Bollinger')
  • ax1.legend(loc='upper left'); ax1.set_ylabel('Precio (€)')
  • ax2.plot(df.index, df.rsi, lw=1); ax2.axhline(70, ls='--'); ax2.axhline(30, ls='--')
  • ax2.set_ylabel('RSI'); fig.autofmt_xdate(); fig.tight_layout()

fill_between sombrea una banda; axhline dibuja niveles de referencia; autofmt_xdate gira las fechas para que no se solapen. Para marcar las operaciones de la lista de la lección 8, usa ax1.scatter(entries.index, entries.price, marker='^') para las entradas y un triángulo hacia abajo para las salidas.

Capital y drawdown

Dibuja el capital con ax.set_yscale('log') siempre que la cuenta más que se duplique en el periodo. En un eje lineal, un movimiento de €10,000 a €11,000 parece minúsculo junto a un movimiento posterior de €40,000 a €44,000, aunque ambos son de +10 %. El panel de drawdown representa dd = equity / equity.cummax() - 1 y lo rellena: ax.fill_between(dd.index, dd, 0, alpha=0.4). Léelo buscando tres cosas: el punto más profundo (drawdown máximo), el tramo más largo por debajo de cero (tiempo bajo el agua, a menudo más doloroso que la profundidad) y si los drawdowns se concentran en un mismo régimen.

Distribuciones de rentabilidades

ax.hist(returns, bins=50, density=True) muestra la forma de las rentabilidades diarias o por operación. Superpón una curva normal con la misma media y desviación típica para ver las colas gruesas: las rentabilidades reales tienen más días extremos de los que predice la campana de Gauss. Para una lista de operaciones, representa en cambio los múltiplos R: un sistema tendencial sano muestra muchas pérdidas pequeñas cerca de −1R y una larga cola a la derecha; un sistema que vende volatilidad muestra la imagen especular, lo cual es una señal de alarma. Comunica la asimetría y la curtosis con returns.skew() y returns.kurt() (pandas devuelve la curtosis en exceso, así que 0 significa colas similares a las de una normal).

Exportar

fig.savefig('equity.png', dpi=150, bbox_inches='tight') escribe una imagen rasterizada; tamaño en píxeles = pulgadas × DPI, así que una figura de 10 × 6 pulgadas a 150 DPI tiene 1,500 × 900 píxeles. Usa .svg o .pdf para una salida vectorial que se mantenga nítida en un informe, y bbox_inches='tight' para recortar los márgenes blancos. Llama siempre a plt.close(fig) después de guardar dentro de un bucle, o un script que produzca 40 gráficos de la lista de seguimiento (lección 12) mantendrá 40 figuras en memoria. Fija los valores por defecto una sola vez con plt.rcParams['figure.dpi'] = 110 en lugar de hacerlo en cada llamada.

Ejemplo práctico

Ejemplo hipotético: una serie de capital de un backtest (euros, inventada) y su gráfico. Se excluyen comisiones e impuestos de los valores de capital.

  1. Capital al cierre de cada año: €10,000, €13,000, €11,700, €16,000, €24,000. Serie de drawdown: máximos 10,000; 13,000; 13,000; 16,000; 24,000 → drawdowns 0; 0; 11,700 / 13,000 − 1 = −10.0 %; 0; 0. Drawdown máximo del −10 %, tiempo bajo el agua de alrededor de un año.
  2. En un eje lineal, el último tramo (+€8,000) domina la imagen; en un eje logarítmico, los pasos de +30 %, −10 %, +36.8 % y +50 % aparecen con su verdadero tamaño relativo, y el año del −10 % es visible en lugar de quedar aplanado.
  3. Rentabilidades diarias: media del 0.06 %, desviación típica del 1.1 %, curtosis en exceso de 4.2. Una distribución normal con esa desviación típica situaría un día de −3.3 % (tres desviaciones típicas) en aproximadamente uno de cada 740 días; el histograma muestra siete días así en 1,000. Esa diferencia es la cola gruesa, y es la razón por la que los stops pueden saltarse con un gap (lección 8).
  4. Exportación: figsize=(8, 5) con dpi=200 da 1,600 × 1,000 píxeles, suficiente para una diapositiva; la misma figura guardada como SVG es independiente de la resolución y a menudo ocupa menos de 100 kB.

Error frecuente

Dibujar el capital en escala lineal y ver en él una «aceleración»Una estrategia con una rentabilidad anual constante del 15 % produce un gráfico lineal que se curva hacia arriba cada vez con más pendiente, lo que parece un rendimiento creciente. En escala logarítmica es una línea recta. Compara estrategias, periodos y drawdowns sobre un eje de capital logarítmico; usa el eje lineal solo para periodos cortos o para mostrar importes en euros.

Actividad práctica

En papel: (a) Una curva de capital pasa de 20,000 → 26,000 → 19,500 → 28,000 (en euros, cuatro puntos). Calcula el drawdown en cada punto. (b) Quieres una figura de exactamente 1,200 × 800 píxeles a 100 DPI; ¿qué figsize pasas? (c) El histograma de los múltiplos R de una estrategia tiene su barra más alta entre +0.2R y +0.4R y una fina cola izquierda que llega a −6R. Escribe una frase sobre lo que sugiere esta forma acerca de la estrategia y del riesgo que un ratio de Sharpe no mostraría.

Mostrar solución

(a) Máximos: 20,000; 26,000; 26,000; 28,000. Drawdowns: 0; 0; 19,500 / 26,000 − 1 = −25.0 %; 0.

(b) figsize = (1,200 / 100, 800 / 100) = (12, 8) pulgadas.

(c) Muchas ganancias pequeñas y pérdidas muy grandes poco frecuentes es el perfil de una estrategia que vende riesgo (por ejemplo, vender opciones o promediar a la baja); el ratio de Sharpe, construido a partir de una media y una desviación típica, se ve impulsado por las frecuentes ganancias pequeñas y subestima la probabilidad de un día de −6R que borre meses de beneficios.

Limitaciones: un histograma con menos de unas 100 observaciones es demasiado ruidoso para juzgar la forma de las colas; comunica en su lugar los peores valores reales.

Ideas clave

  • Usa plt.subplots con ejes x compartidos para los paneles de precio, indicador, capital y drawdown; indica las unidades.
  • El capital en escala logarítmica muestra con honestidad los movimientos porcentuales; los gráficos de drawdown muestran la profundidad y el tiempo bajo el agua.
  • Los histogramas de rentabilidades o de múltiplos R revelan colas gruesas y asimetrías que las estadísticas resumidas ocultan.
  • Píxeles = pulgadas × DPI; prefiere SVG o PDF para los informes y cierra las figuras dentro de los bucles.

Siguiente paso

La lección 11 pasa de un instrumento a varios: matrices de correlación y covarianza, volatilidad de la cartera a partir de los pesos y una simulación de reequilibrio en pandas.

Autoevaluación

Responde a las preguntas y luego comprueba tus respuestas. Puedes volver a intentarlo tantas veces como quieras.

1. Llamas a fig.savefig('out.png', dpi=300) sobre una figura creada con figsize=(6, 4). ¿Cuál es el tamaño de la imagen en píxeles?

2. Dos estrategias hacen crecer €10,000 hasta €40,000 en diez años. En un gráfico de capital en escala logarítmica, la estrategia A es casi una línea recta y la estrategia B se mantiene plana durante ocho años y después sube con fuerza. ¿Qué te indica esto?

3. Un script genera un gráfico por ticker para una lista de seguimiento de 60 valores y en cada ejecución se vuelve más lento y usa más memoria. ¿Cuál es la solución más probable?

Autoevaluación automática para tu propio repaso. Tus respuestas se comprueban en tu navegador y no las vemos ni evaluamos. No es un examen ni una titulación.

Tu progreso

«Completada» solo significa que marcaste la lección como terminada. No es una prueba de tu comprensión. El progreso y las notas se guardan solo en este navegador y en este dispositivo, no en una cuenta.