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

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).
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.
# 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?
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).
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.
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.
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.