σμimplied vol · KKmax(S−K,0)udβρᵢⱼfat tailsPnL · drawdownyield · TdSₜ = μSₜ dt + σSₜ dWₜC = S·N(d₁) − K·e⁻ʳᵀ·N(d₂)σₚ² = wᵀΣwd₁ = [ln(S/K) + (r + σ²⁄2)T] ⁄ σ√T∂V/∂t + ½σ²S²·∂²V/∂S² + rS·∂V/∂S − rV = 0Sharpe = (Rₚ − R_f) ⁄ σₚVaR₉₉ = μ − 2.33σρ = Cov(X,Y) ⁄ σₓσᵧE[Rₚ] = Σ wᵢ·E[Rᵢ]φ(x) = e^(−x²/2) ⁄ √2πE[Rᵢ] = R_f + βᵢ(E[Rₘ] − R_f)dXₜ = θ(μ − Xₜ)dt + σ dWₜσ²ₜ = ω + α·ε²ₜ₋₁ + β·σ²ₜ₋₁C − P = S − K·e⁻ʳᵀΔ = ∂V/∂S Γ = ∂²V/∂S²p = (e^(rΔt) − d) ⁄ (u − d)rₜ = ln(Pₜ ⁄ Pₜ₋₁)E[Xₜ₊₁ | ℱₜ] = Xₜf* = (bp − q) ⁄ bz = (x − μ) ⁄ σP(N=k) = λᵏe^(−λ) ⁄ k!Θ = −∂V/∂Tν = S·φ(d₁)·√Tmin wᵀΣw s.t. wᵀμ = μ*∫Σ∂∞λ
σμimplied vol · KKmax(S−K,0)udβρᵢⱼfat tailsPnL · drawdownyield · TdSₜ = μSₜ dt + σSₜ dWₜC = S·N(d₁) − K·e⁻ʳᵀ·N(d₂)σₚ² = wᵀΣwd₁ = [ln(S/K) + (r + σ²⁄2)T] ⁄ σ√T∂V/∂t + ½σ²S²·∂²V/∂S² + rS·∂V/∂S − rV = 0Sharpe = (Rₚ − R_f) ⁄ σₚVaR₉₉ = μ − 2.33σρ = Cov(X,Y) ⁄ σₓσᵧE[Rₚ] = Σ wᵢ·E[Rᵢ]φ(x) = e^(−x²/2) ⁄ √2πE[Rᵢ] = R_f + βᵢ(E[Rₘ] − R_f)dXₜ = θ(μ − Xₜ)dt + σ dWₜσ²ₜ = ω + α·ε²ₜ₋₁ + β·σ²ₜ₋₁C − P = S − K·e⁻ʳᵀΔ = ∂V/∂S Γ = ∂²V/∂S²p = (e^(rΔt) − d) ⁄ (u − d)rₜ = ln(Pₜ ⁄ Pₜ₋₁)E[Xₜ₊₁ | ℱₜ] = Xₜf* = (bp − q) ⁄ bz = (x − μ) ⁄ σP(N=k) = λᵏe^(−λ) ⁄ k!Θ = −∂V/∂Tν = S·φ(d₁)·√Tmin wᵀΣw s.t. wᵀμ = μ*∫Σ∂∞λ
uantCraft AcademyRutas
Ctrl K
AO
+1,2 k estudiantes
Iniciar sesiónUnirse ↗
Rutas
AO
+1,2 k estudiantes
Iniciar sesión
  • English
  • Français
  • Español
  • العربية
  • Português
  • Deutsch
  • 日本語
  • 中文
Ruta de Python›Módulo 2 · NumPy y pandas para datos de mercado›Tema 2.20·~35 minIntermedio

Histogramas y distribuciones

Posición en la rutaMódulo 2 de 11 · Tema 20 de 20
2.20 Histogramas y distribuciones
—Puntuación del lab— / 100XP total—Racha—

Contar por rango

La media y la desviación típica comprimen mil rendimientos en dos números. Un histograma conserva la forma: divide el rango de valores en intervalos y cuenta cuántas observaciones caen en cada uno. Barras altas en el centro y bajas en los extremos dan la campana conocida; una forma desequilibrada o con extremos pesados es una advertencia. np.histogram(values, bins=edges) devuelve los conteos y trabaja sobre un array entero. El intervalo i toma los valores desde edges[i] incluido hasta edges[i + 1] excluido; solo el último intervalo incluye también su borde derecho.

import numpy as np

returns = np.array([-0.021, -0.012, -0.008, -0.004, -0.002, 0.000, 0.001, 0.003, 0.004, 0.006, 0.009, 0.015, 0.032])
edges = np.array([-0.03, -0.01, 0.0, 0.01, 0.03])      # four bins: -3%..-1%, -1%..0%, 0%..1%, 1%..3%

counts, _ = np.histogram(returns, bins=edges)
print(counts.tolist(), counts.sum(), len(returns))      # [2, 3, 6, 1] 12 13   the 3.2% return is outside every bin

# bins=4 asks numpy for 4 equal-width bins between the minimum and the maximum
counts, edges4 = np.histogram(returns, bins=4)
print(counts.tolist(), edges4.round(4).tolist())        # [3, 6, 3, 1] [-0.021, -0.0078, 0.0055, 0.0188, 0.032]

Frecuencia o densidad

Los conteos dependen del número de observaciones y del ancho de los intervalos, así que dos histogramas con tamaños de muestra distintos no se pueden comparar. Una densidad lo arregla: divide cada conteo por el total contado y por el ancho del intervalo, de modo que el área de las barras sume 1. Entonces una densidad se puede comparar con una curva teórica, como la campana normal, o con otra muestra. np.histogram(values, bins=edges, density=True) lo hace, igual que counts / (counts.sum() * np.diff(edges)).

counts, _ = np.histogram(returns, bins=edges)
density = counts / (counts.sum() * np.diff(edges))
print(density.round(2).tolist())              # [8.33, 25.0, 50.0, 4.17]
print((density * np.diff(edges)).sum())        # 1.0   the areas add up to 1

Dibujarlo y leer las colas

ax.hist(values, bins=10) cuenta y dibuja en una llamada: una barra por intervalo (ax.patches), cuyas alturas son los conteos. Rotula siempre los ejes, porque un histograma de rendimientos no significa nada sin «Rendimiento diario» debajo. Lo que importa es la forma, y lo que duele son las colas: contar la proporción de observaciones a más de k desviaciones típicas de la media, np.mean(np.abs(x - mean) > k * std), dice con qué frecuencia ocurren los extremos. En una normal, alrededor del 4,6 % de los valores están más allá de 2 desviaciones y el 0,27 % más allá de 3. Los mercados son peores, como mostrarán los próximos temas.

import matplotlib
matplotlib.use("Agg")
import matplotlib.pyplot as plt

fig, ax = plt.subplots()
ax.hist(returns, bins=5)
ax.set_xlabel("Daily return")
ax.set_ylabel("Frequency")
print(len(ax.patches), [round(p.get_height()) for p in ax.patches])   # 5 [2, 4, 5, 1, 1]   one bar per bin; the heights are the counts

# How often are the returns more than 1 standard deviation from the mean?
mean, std = returns.mean(), returns.std(ddof=1)
print(round(float(np.mean(np.abs(returns - mean) > 1 * std)), 3))     # 0.308   about 4 of 13 days
# The number of bins changes the picture: compare a few
for bins in (2, 4, 8):
    print(bins, np.histogram(returns, bins=bins)[0].tolist())
# 2 [9, 4]
# 4 [3, 6, 3, 1]
# 8 [1, 2, 2, 4, 2, 1, 0, 1]
Los intervalos cambian la imagenMuy pocos intervalos ocultan la forma y demasiados hacen ruido. No hay un número correcto único; prueba varios y compara histogramas con los mismos límites. Recuerda también que un histograma es una muestra: la siguiente se verá un poco distinta, así que juzga la forma general, no barras sueltas.
  • np.histogram(values, bins=edges) cuenta los valores de cada intervalo; el último intervalo incluye su borde derecho.
  • Una densidad divide por el total contado y el ancho del intervalo: las áreas suman 1 y las muestras se vuelven comparables.
  • ax.hist(values, bins=n) lo dibuja; np.mean(np.abs(x - mean) > k * std) mide las colas. Rotula los ejes y compara con los mismos límites.

A continuación: media y varianza de los rendimientos, los dos números que resumen una distribución, calculados a partir de sus definiciones.

Lab: qué se califica

  • Contar los rendimientos de cada intervalo con bin_counts25 pts
  • Convertir los conteos en densidad con density25 pts
  • Medir las colas con fraction_beyond25 pts
  • Dibujar el histograma con plot_histogram25 pts
Explorador · lab-53-1
▾ lab-53-1
…
bash · en el navegador
learner@quantcraft:~/lab-53-1$
Python aún no cargadoPythonLn 1, Col 1Spaces: 4UTF-8

¿Restablecer este tema?

Todo lo que hay en lab-53-1 vuelve a los archivos iniciales y se limpia el terminal. Tu solución actual se perderá: no se puede deshacer.

Se restablecerá
  • main.py → código inicial
  • Historial del terminal y salida de pruebas
  • Cambios sin enviar
Se conservará
  • Mejor puntuación del lab
  • Tu XP y tu racha
  • Progreso de la lección y notas

Inicia sesión para ejecutar tu código.

Todas las clases se pueden leer gratis. Crea una cuenta o inicia sesión para ejecutar código, lanzar las pruebas y enviar este lab.

  • IDE en el navegador con terminal bash — sin instalar nada
  • Corrección instantánea, XP y tu lugar en la ruta
Crear una cuentaIniciar sesión
O
Continuar con GitHub