Regresar al blog

Python para análisis financiero: desde los datos hasta la decisión

DataAlias8 min de lectura

El análisis financiero con Python es una de las habilidades más cotizadas en bancos, fintech y fondos de inversión de LATAM. En este artículo vamos a trabajar con precios históricos de acciones y calcular métricas que se usan en el mundo real.

Carga de datos con pandas

Para este ejemplo usamos datos de precios de cierre de empresas listadas en la Bolsa Mexicana de Valores (BMV).

python
import pandas as pd
import numpy as np

# Carga del dataset histórico
df = pd.read_csv("precios_bmv_2025.csv", parse_dates=["fecha"])
df = df.set_index("fecha").sort_index()

print(df.head())
print(f"\nEmpresas: {df.columns.tolist()}")
print(f"Período: {df.index[0].date()}{df.index[-1].date()}")

Cálculo de retornos diarios

El retorno diario es la variación porcentual del precio de cierre respecto al día anterior.

python
# Retorno logarítmico diario (más estable para análisis estadístico)
retornos = np.log(df / df.shift(1)).dropna()

# Estadísticas básicas
print(retornos.describe().round(4))

Retorno acumulado

¿Cuánto habría ganado (o perdido) una inversión de $10,000 pesos al inicio del período?

python
inversion_inicial = 10_000

retorno_acumulado = (1 + retornos).cumprod()
valor_portafolio = inversion_inicial * retorno_acumulado

# Las 3 mejores empresas del año
mejores = valor_portafolio.iloc[-1].sort_values(ascending=False).head(3)
print("Top 3 rendimiento del año:")
print(mejores.round(2))

Volatilidad anualizada

La volatilidad mide el riesgo. Se calcula como la desviación estándar de los retornos diarios, anualizada multiplicando por √252 (días de trading en un año).

python
volatilidad_anual = retornos.std() * np.sqrt(252)

print("Volatilidad anualizada (%):")
print((volatilidad_anual * 100).sort_values(ascending=False).round(2))

Correlación entre activos

La correlación te dice qué tan parecido se mueven dos activos. Útil para construir portafolios diversificados.

python
matriz_correlacion = retornos.corr()

# Pares con mayor correlación (excluyendo la diagonal)
correlaciones = (
    matriz_correlacion
    .unstack()
    .reset_index()
    .rename(columns={"level_0": "activo_1", "level_1": "activo_2", 0: "correlacion"})
    .query("activo_1 < activo_2")  # evita duplicados
    .sort_values("correlacion", ascending=False)
)

print("Pares más correlacionados:")
print(correlaciones.head(5))

Ratio de Sharpe simplificado

El Sharpe ratio mide cuánto retorno obtienes por cada unidad de riesgo.

python
tasa_libre_riesgo = 0.08 / 252  # CETES al 8% anual, diario

sharpe = (retornos.mean() - tasa_libre_riesgo) / retornos.std()
sharpe_anualizado = sharpe * np.sqrt(252)

print("Sharpe ratio anualizado:")
print(sharpe_anualizado.sort_values(ascending=False).round(3))

Conclusión

Con menos de 50 líneas de Python tienes un análisis de portafolio que en Excel tomaría horas. Las mismas técnicas se aplican a datos de bonos, divisas y commodities. El siguiente nivel es agregar visualizaciones con matplotlib o construir un dashboard interactivo con Streamlit.