6. NumPy: arrays y cálculo vectorizado con precios
Nivel 2: Python desde Cero para Finanzas
Las listas de Python son flexibles, pero tienen un problema para el trabajo cuantitativo: son lentas para cálculo numérico y no soportan operaciones matemáticas directas entre ellas. Si tienes dos listas de precios y quieres restarlas elemento a elemento, Python no te deja hacer lista1 - lista2 directamente — tendrías que escribir un bucle. NumPy resuelve exactamente ese problema.
import numpy as np
precios = np.array([182.52, 184.10, 179.88, 181.45, 183.20])
type(precios) # numpy.ndarrayUn array de NumPy se comporta como un vector matemático: las operaciones aritméticas se aplican elemento a elemento de forma automática, sin necesidad de ningún bucle explícito — esto se llama vectorización, y es la razón por la que NumPy es rápido: internamente ejecuta el cálculo en código C compilado, no en Python interpretado.
precios_ayer = np.array([180.00, 183.50, 178.00, 180.90, 182.00])
diferencia = precios - precios_ayer # resta elemento a elemento, sin ningun bucle
retornos = (precios - precios_ayer) / precios_ayer # retorno porcentual de cada dia, vectorizadoPara crear arrays sin escribir cada número a mano, NumPy ofrece varias funciones generadoras. arange(inicio, fin, paso) genera una secuencia numérica, igual que range() pero devolviendo directamente un array:
dias = np.arange(0, 10, 1) # [0, 1, 2, ..., 9]linspace(inicio, fin, cantidad) genera un número exacto de puntos igualmente espaciados entre dos valores — muy útil, por ejemplo, para generar un eje de tiempo continuo para una simulación:
horizonte = np.linspace(0, 1, 252) # 252 puntos entre 0 y 1: los dias de trading de un anozeros y ones crean arrays rellenos de ceros o unos, típicamente usados para inicializar una estructura que luego vas a rellenar con resultados de una simulación:
resultados_simulacion = np.zeros(1000) # espacio reservado para 1000 resultados, todos a 0 de momentoY diag crea una matriz diagonal a partir de una lista de valores — útil, por ejemplo, al construir una matriz de covarianzas donde solo te interesan las varianzas individuales:
varianzas = np.diag([0.04, 0.09, 0.01]) # matriz diagonal 3x3 con esas tres varianzasIndexar un array de NumPy funciona igual que con listas, pero con una potencia extra: puedes seleccionar elementos usando una condición directamente, sin bucle ni comprensión de listas. Esto se llama indexado booleano, y es una de las herramientas más usadas en análisis financiero.
retornos_diarios = np.array([0.02, -0.01, 0.005, -0.03, 0.015])
dias_perdedores = retornos_diarios[retornos_diarios < 0] # array([-0.01, -0.03]) - solo los negativos
mascara = retornos_diarios < 0
retornos_diarios[mascara].mean() # el retorno medio de los dias perdedoresNumPy también trae ya integradas las estadísticas descriptivas más básicas que vas a calcular constantemente sobre una serie de retornos:
retornos_diarios.mean() # retorno medio
retornos_diarios.std() # desviacion estandar (volatilidad)
retornos_diarios.max() # el mejor dia
retornos_diarios.min() # el peor dia
retornos_diarios.cumsum() # suma acumulada, util para ver el retorno acumulado dia a diaLa regla general al trabajar con NumPy es: si te encuentras escribiendo un bucle for para recorrer un array y hacer un cálculo elemento a elemento, casi siempre existe una forma vectorizada de hacer lo mismo, y va a ser bastante más rápida cuando la serie de datos tenga miles o millones de precios en vez de cinco.