¿Cómo visualizar gráficos de candelas japonesas en Python?

Gráficos de candelas en python
Un gráfico de candelas japonesas es un tipo de gráfico de precios financiero que muestra los movimientos de precios de activos a lo largo del tiempo. El siguiente ejemplo muestra cómo crear un gráfico de candelas utilizando la biblioteca de visualización Matplotlib en Python.
En adiciones posteriores a este artículo vamos a mostrar formas adicionales de crear gráficos de candelas con este lenguaje usando otras librerías.
¿Qué puedes aprender en este artículo?
Como parte de este tutorial, vamos a explicar cómo crear gráficos de candelas en Python utilizando la biblioteca de visualización de datos Matplotlib. Los gráficos generados con esta librería son estáticos, mientras que los creados con otras bibliotecas son interactivos y más adelante hablaremos sobre estas aplicaciones.
Además de la creación básica de gráficos de velas a partir del conjunto de datos, iremos ampliando el artículo con los siguientes temas:
- Personalización del estilo de los gráficos.
- Gestión del diseño (layout).
- Adición de líneas de medias móviles (SMA, EMA, RSI, etc.).
- Incorporación de controles deslizantes para seleccionar rangos.
- Visualización de barras de volumen.
- Inclusión de Bandas de Bollinger.
- Guardado de figuras, entre otros.
El conjunto de datos utilizado para los gráficos corresponde a los precios de las acciones de Apple (AAPL) durante un mes, obtenidos de Yahoo Finance. Los datos se cargaron como un DataFrame de pandas, y todos los gráficos se generaron a partir de él.
Para comenzar, veamos el siguiente ejemplo simple:
Creación de un gráfico de candelas en Python con Matploblib
Supongamos que tenemos el siguiente DataFrame de pandas que muestra los precios de apertura, cierre, máximo y mínimo de una acción determinada durante un período de 8 días:
import pandas as pd #create DataFrame prices = pd.DataFrame({'open': [25, 22, 21, 19, 23, 21, 25, 29], 'close': [24, 20, 17, 23, 22, 25, 29, 31], 'high': [28, 27, 29, 25, 24, 26, 31, 37], 'low': [22, 16, 14, 17, 19, 18, 22, 26]}, index=pd.date_range("2021-01-01", periods=8, freq="d")) #display DataFrame print(prices) open close high low 2021-01-01 25 24 28 22 2021-01-02 22 20 27 16 2021-01-03 21 17 29 14 2021-01-04 19 23 25 17 2021-01-05 23 22 24 19 2021-01-06 21 25 26 18 2021-01-07 25 29 31 22 2021-01-08 29 31 37 26
Supongamos que tenemos el siguiente DataFrame de pandas que muestra los precios de apertura, cierre, máximo y mínimo de una acción determinada durante un período de 8 días:
import matplotlib.pyplot as plt #create figure plt.figure() #define width of candlestick elements width = .4 width2 = .05 #define up and down prices up = prices[prices.close>=prices.open] down = prices[prices.close<prices.open] #define colors to use col1 = 'green' col2 = 'red' #plot up prices plt.bar(up.index,up.close-up.open,width,bottom=up.open,color=col1) plt.bar(up.index,up.high-up.close,width2,bottom=up.close,color=col1) plt.bar(up.index,up.low-up.open,width2,bottom=up.open,color=col1) #plot down prices plt.bar(down.index,down.close-down.open,width,bottom=down.open,color=col2) plt.bar(down.index,down.high-down.open,width2,bottom=down.open,color=col2) plt.bar(down.index,down.low-down.close,width2,bottom=down.close,color=col2) #rotate x-axis tick labels plt.xticks(rotation=45, ha='right') #display candlestick chart plt.show()
Con este código, el programa muestra la siguiente imagen:

Gráficos de candelas en Python
Cada vela representa el movimiento del precio del activo en un día concreto. El color de la vela nos indica si el precio cerró más alto (verde) o más bajo (rojo) que el día anterior.
Puedes modificar libremente el ancho de las velas y los colores utilizados para personalizar el gráfico según tus preferencias.
Por ejemplo, podríamos hacer las velas más delgadas y usar diferentes colores para representar los días ‘alcistas’ y ‘bajistas’:
import matplotlib.pyplot as plt #create figure plt.figure() #define width of candlestick elements width = .2 width2 = .02 #define up and down prices up = prices[prices.close>=prices.open] down = prices[prices.close<prices.open] #define colors to use col1 = 'black' col2 = 'steelblue' #plot up prices plt.bar(up.index,up.close-up.open,width,bottom=up.open,color=col1) plt.bar(up.index,up.high-up.close,width2,bottom=up.close,color=col1) plt.bar(up.index,up.low-up.open,width2,bottom=up.open,color=col1) #plot down prices plt.bar(down.index,down.close-down.open,width,bottom=down.open,color=col2) plt.bar(down.index,down.high-down.open,width2,bottom=down.open,color=col2) plt.bar(down.index,down.low-down.close,width2,bottom=down.close,color=col2) #rotate x-axis tick labels plt.xticks(rotation=45, ha='right') #display candlestick chart plt.show()

Gráfico de candelas con formato distinto
Esto mismo lo podemos hacer usando datos del mercado obtenidos mediante librerías como yfinance. Por ejemplo, el siguiente código muestra cómo obtener datos de precios de Apple mediante esta librería y trazar un gráfico de candelas con estos datos:
import yfinance as yf import mplfinance as mpf import matplotlib.pyplot as plt # 1. Descargar datos de Apple (AAPL) - Último año datos = yf.download('AAPL', period='1y', # Período de 1 año interval='1d') # Datos diarios # 2. Configuración del gráfico estilo = mpf.make_mpf_style(base_mpf_style='charles', rc={'font.size': 10}) # 3. Calcular medias móviles (SMA 20 y 50 días) sma20 = datos['Close'].rolling(window=20).mean() sma50 = datos['Close'].rolling(window=50).mean() # 4. Personalizar colores (verde=sube, rojo=baja) colores = mpf.make_marketcolors(up='#2E7D32', # Verde down='#C62828', # Rojo wick={'up':'#2E7D32', 'down':'#C62828'}, edge={'up':'#2E7D32', 'down':'#C62828'}) estilo_personalizado = mpf.make_mpf_style(base_mpl_style='seaborn', marketcolors=colores) # 5. Crear gráfico con: # - Velas japonesas # - SMA 20 (azul) y SMA 50 (naranja) # - Volumen en la parte inferior mpf.plot(datos, type='candle', style=estilo_personalizado, title='\nApple (AAPL) - Último año', ylabel='Precio (USD)', volume=True, mav=(20, 50), figratio=(12, 6), figscale=1.1, show_nontrading=False) plt.show()
Si tienen alguna duda con respecto al código por favor déjenla en la sección de comentarios.