Análisis de datos de acciones con Pandas
En el análisis de datos de acciones, pandas es una herramienta muy potente que nos ayuda a procesar y analizar datos del mercado de valores.
En este capítulo usamos yfinance (biblioteca de Yahoo Finance) para descargar datos históricos de acciones y realizar varios análisis, incluyendo limpieza de datos, visualización, cálculo de indicadores técnicos, etc.
yfinance es una biblioteca de Python que permite obtener fácilmente datos históricos y en tiempo real de activos como acciones, fondos y criptomonedas desde Yahoo Finance.
Con pandas, podemos almacenar estos datos como DataFrame y realizar análisis posteriores.
- Limpieza de datos: manejar valores faltantes, eliminar columnas innecesarias, etc.
- Visualización de datos: dibujar gráficos de series temporales de acciones, medias móviles, RSI, etc.
- Cálculo de indicadores técnicos: como la media móvil (SMA), el índice de fuerza relativa (RSI), etc.
- Análisis del rendimiento diario y acumulado: ayuda a evaluar el rendimiento de una acción a corto y largo plazo.
- Análisis de volatilidad: mide la volatilidad del precio de una acción.
Para más bibliotecas financieras y análisis cuantitativo, consulta:Trading cuantitativo con Python
Instalar yfinance
Primero, necesitamos instalar la biblioteca yfinance, de la siguiente manera:
pip install yfinance --upgrade --no-cache-dir
Al instalar yfinance, pandas generalmente se instala automáticamente como dependencia. Esto significa que al usar yfinance, puedes aprovechar directamente las estructuras de datos y funciones que proporciona pandas para procesar y analizar datos.
Importar las bibliotecas necesarias:
import yfinance as yf import pandas as pd import matplotlib.pyplot as plt import seaborn as sns
Obtener datos de acciones
Con la biblioteca yfinance, podemos descargar fácilmente datos de acciones.
Normalmente usamos la función yf.download() para obtener datos históricos de una acción desde Yahoo Finance.
El código bursátil de Moutai es 600519.SS, donde.SSes el sufijo de la Bolsa de Valores de Shanghái.
Obtener datos de acciones usando yfinance:
Ejemplo
# Obtener datos de acciones de Moutai (600519.SS), rango de fechas del 2020-01-01 al 2021-01-01
stock_data = yf.download('600519.SS', start='2020-01-01', end='2021-01-01')
# Ver las primeras filas de los datos
print(stock_data.head())
La salida de datos es la siguiente:

Los datos devueltos contienen las siguientes columnas:
Open: precio de aperturaHigh: precio máximoLow: precio mínimoClose: precio de cierreAdj Close: precio de cierre ajustado (considera dividendos, splits, etc.)Volume: volumen de negociación
La función yf.download() devuelve un pandas.DataFrame que contiene los datos históricos de la acción especificada:
Ejemplo
# Obtener datos de la acción de Moutai (600519.SS)
stock_data = yf.download('600519.SS', start='2020-01-01', end='2021-01-01')
# Comprobar el tipo de datos
print(type(stock_data)) # Debería mostrar <class 'pandas.core.frame.DataFrame'>
La salida es:
[*********************100%%**********************] 1 of 1 completed <class 'pandas.core.frame.DataFrame'>
Limpieza y procesamiento de datos
Al analizar datos de acciones, normalmente necesitamos realizar limpieza y procesamiento de datos.
Los pasos comunes incluyen rellenar valores faltantes, eliminar columnas irrelevantes, conversión de tipos de datos, etc.
En algunas versiones de yfinance, pandas se importa automáticamente y no es necesario importarlo de nuevo, por lo que al usar yfinance, puedes aprovechar directamente las estructuras de datos y funciones de pandas para procesar y analizar datos.
Verificar valores faltantes y rellenarlos:
Ejemplo
# Obtener datos de acciones de Moutai (600519.SS), rango de fechas del 2020-01-01 al 2021-01-01
stock_data = yf.download('600519.SS', start='2020-01-01', end='2021-01-01')
# Verificar valores faltantes
print(stock_data.isnull().sum())
# Reemplazar valores faltantes usando relleno hacia adelante
stock_data.ffill(inplace=True)
# O usar relleno hacia atrás
# stock_data.bfill(inplace=True)
# Verificar si los valores faltantes ya fueron procesados
print(stock_data.isnull().sum())
El resultado de salida es el siguiente:
[*********************100%%**********************] 1 of 1 completed Open 0 High 0 Low 0 Close 0 Adj Close 0 Volume 0 dtype: int64 Open 0 High 0 Low 0 Close 0 Adj Close 0 Volume 0
Eliminar columnas irrelevantes:
Ejemplo
# Obtener datos de acciones de Moutai (600519.SS), rango de fechas del 2020-01-01 al 2021-01-01
stock_data = yf.download('600519.SS', start='2020-01-01', end='2021-01-01')
# Eliminar las columnas "Volume" y "Adj Close"
stock_data_cleaned = stock_data.drop(columns=['Adj Close', 'Volume'])
print(stock_data_cleaned.head())
El resultado de salida es el siguiente:

Visualización de datos: dibujar la curva de precios de acciones
Con matplotlib o seaborn, podemos visualizar los datos de acciones, lo que nos ayuda a identificar tendencias y fluctuaciones.
Dibujar el gráfico de serie temporal del precio de cierre:
Ejemplo
import matplotlib.pyplot as plt
# Obtener datos de acciones de Moutai (600519.SS), rango de fechas del 2020-01-01 al 2021-01-01
stock_data = yf.download('600519.SS', start='2020-01-01', end='2021-01-01')
# Eliminar las columnas "Volume" y "Adj Close"
stock_data_cleaned = stock_data.drop(columns=['Adj Close', 'Volume'])
# Dibujar la curva del precio de cierre de Moutai
plt.figure(figsize=(10, 6))
plt.plot(stock_data_cleaned['Close'], label='Close Price')
plt.title('Maotai Stock Price (2020)', fontsize=14)
plt.xlabel('Date', fontsize=12)
plt.ylabel('Close Price (CNY)', fontsize=12)
plt.legend()
plt.grid(True)
plt.show()
La salida es la siguiente:

Calcular indicadores técnicos de acciones
En el análisis de acciones, los indicadores técnicos (como la media móvil, el índice de fuerza relativa RSI, etc.) se utilizan a menudo para apoyar la toma de decisiones; pandas nos ayuda a calcular estos indicadores.
1. Media móvil (SMA)
La media móvil simple (SMA) es uno de los indicadores técnicos más utilizados y representa el precio de cierre promedio de los últimos N días.
Ejemplo
import matplotlib.pyplot as plt
# Obtener datos de acciones de Moutai (600519.SS), rango de fechas del 2020-01-01 al 2021-01-01
stock_data = yf.download('600519.SS', start='2020-01-01', end='2021-01-01')
# Eliminar las columnas "Volume" y "Adj Close"
stock_data_cleaned = stock_data.drop(columns=['Adj Close', 'Volume'])
# Calcular las medias móviles de 50 y 200 días
stock_data_cleaned['SMA_50'] = stock_data_cleaned['Close'].rolling(window=50).mean()
stock_data_cleaned['SMA_200'] = stock_data_cleaned['Close'].rolling(window=200).mean()
# Dibujar el precio de cierre y las medias móviles
plt.figure(figsize=(12, 6))
plt.plot(stock_data_cleaned['Close'], label='Close Price')
plt.plot(stock_data_cleaned['SMA_50'], label='50-Day SMA')
plt.plot(stock_data_cleaned['SMA_200'], label='200-Day SMA')
plt.title('Maotai Stock Price with Moving Averages', fontsize=14)
plt.xlabel('Date', fontsize=12)
plt.ylabel('Price (CNY)', fontsize=12)
plt.legend()
plt.grid(True)
plt.show()
La salida es la siguiente:

2. Índice de fuerza relativa (RSI)
El RSI es un indicador técnico utilizado para evaluar si una acción está sobrecomprada o sobrevendida. En general, un RSI mayor de 70 indica sobrecompra, y menor de 30 indica sobreventa.
Ejemplo
import matplotlib.pyplot as plt
# Obtener datos de acciones de Moutai (600519.SS), rango de fechas del 2020-01-01 al 2021-01-01
stock_data = yf.download('600519.SS', start='2020-01-01', end='2021-01-01')
# Eliminar las columnas "Volume" y "Adj Close"
stock_data_cleaned = stock_data.drop(columns=['Adj Close', 'Volume'])
# Calcular el indicador RSI
delta = stock_data_cleaned['Close'].diff(1)
gain = delta.where(delta > 0, 0)
loss = -delta.where(delta < 0, 0)
# Calcular la ganancia y pérdida promedio
avg_gain = gain.rolling(window=14).mean()
avg_loss = loss.rolling(window=14).mean()
# Calcular el índice de fuerza relativa RSI
rs = avg_gain / avg_loss
rsi = 100 - (100 / (1 + rs))
# Añadir RSI a los datos
stock_data_cleaned['RSI'] = rsi
# Dibujar la curva RSI
plt.figure(figsize=(12, 6))
plt.plot(stock_data_cleaned['RSI'], label='RSI')
plt.axhline(y=70, color='r', linestyle='--', label='Overbought (70)')
plt.axhline(y=30, color='g', linestyle='--', label='Oversold (30)')
plt.title('RSI Indicator for Maotai Stock', fontsize=14)
plt.xlabel('Date', fontsize=12)
plt.ylabel('RSI', fontsize=12)
plt.legend()
plt.grid(True)
plt.show()
La salida es la siguiente:

Aplicaciones del análisis de datos de acciones
En el análisis real de datos de acciones, se pueden realizar las siguientes operaciones comunes con Pandas:
1. Rendimiento diario y rendimiento acumulado
Calcular el rendimiento diario y acumulado de una acción ayuda a evaluar su desempeño a largo plazo.
Ejemplo
import matplotlib.pyplot as plt
# Obtener datos de acciones de Moutai (600519.SS), rango de fechas del 2020-01-01 al 2021-01-01
stock_data = yf.download('600519.SS', start='2020-01-01', end='2021-01-01')
# Eliminar las columnas "Volume" y "Adj Close"
stock_data_cleaned = stock_data.drop(columns=['Adj Close', 'Volume'])
# Calcular el rendimiento diario
stock_data_cleaned['Daily_Return'] = stock_data_cleaned['Close'].pct_change()
# Calcular el rendimiento acumulado
stock_data_cleaned['Cumulative_Return'] = (1 + stock_data_cleaned['Daily_Return']).cumprod()
# Dibujar el rendimiento acumulado
plt.figure(figsize=(10, 6))
plt.plot(stock_data_cleaned['Cumulative_Return'], label='Cumulative Return')
plt.title('Cumulative Return of Maotai Stock (2020)', fontsize=14)
plt.xlabel('Date', fontsize=12)
plt.ylabel('Cumulative Return', fontsize=12)
plt.legend()
plt.grid(True)
plt.show()
La salida es la siguiente:

2. Volatilidad de las acciones
La volatilidad es un indicador que mide la fluctuación del precio de una acción.
Normalmente, podemos usar la desviación estándar de los rendimientos para medir la volatilidad de una acción.
Ejemplo
import matplotlib.pyplot as plt
# Obtener datos de acciones de Moutai (600519.SS), rango de fechas del 2020-01-01 al 2021-01-01
stock_data = yf.download('600519.SS', start='2020-01-01', end='2021-01-01')
# Eliminar las columnas "Volume" y "Adj Close"
stock_data_cleaned = stock_data.drop(columns=['Adj Close', 'Volume'])
# Calcular el rendimiento diario
stock_data_cleaned['Daily_Return'] = stock_data_cleaned['Close'].pct_change()
# Calcular el rendimiento acumulado
stock_data_cleaned['Cumulative_Return'] = (1 + stock_data_cleaned['Daily_Return']).cumprod()
# Calcular la desviación estándar del rendimiento diario (volatilidad)
volatility = stock_data_cleaned['Daily_Return'].std()
# Mostrar la volatilidad
print(f"Daily Volatility: {volatility:.4f}")
La salida es la siguiente:
[*********************100%%**********************] 1 of 1 completed Daily Volatility: 0.0181Otras extensiones