σμ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.13·~40 minIntermedio

Remuestreo

Posición en la rutaMódulo 2 de 11 · Tema 13 de 20
2.13 Remuestreo
—Puntuación del lab— / 100XP total—Racha—

Cambiar la frecuencia

Los datos rara vez llegan con la frecuencia que necesitas. Los ticks llegan por milisegundo, un modelo quiere barras diarias, un informe quiere meses. El remuestreo reagrupa una serie temporal en nuevos periodos. Pasar de fino a grueso (días a meses) es submuestreo: cada periodo nuevo contiene varias observaciones antiguas, así que hay que decir cómo combinarlas. Pasar de grueso a fino (semanas a días) es sobremuestreo: hay periodos nuevos sin datos, así que hay que decir qué poner en ellos.

import pandas as pd

daily = pd.Series(
    [100.0, 101, 103, 102, 104, 105, 103, 106],
    index=pd.bdate_range("2026-02-25", periods=8),    # Wed 25 Feb ... Fri 6 Mar
    name="close",
)

print(daily.resample("ME").last())     # the last price of each month ("ME" = month end)
# 2026-02-28    103.0
# 2026-03-31    106.0
# Freq: ME, Name: close, dtype: float64

print(daily.resample("W-FRI").last())  # the last price of each week, weeks ending on Friday
# 2026-02-27    103.0
# 2026-03-06    106.0
# Freq: W-FRI, Name: close, dtype: float64

Elegir la agregación

series.resample("ME") solo no hace nada: solo describe los periodos. La agregación que sigue decide el valor y debe corresponder al significado de los datos. Un precio es una instantánea, así que un mes se representa con su valor last (o first). Un volumen es una cantidad negociada, así que un mes es la sum. Un rango usa max y min. Las etiquetas siguen la regla: "ME" etiqueta un mes con su último día natural, aunque sea sábado, y "W-FRI" etiqueta una semana con su viernes.

volume = pd.Series([10, 20, 30, 40, 50, 60, 70, 80], index=daily.index)

print(volume.resample("ME").sum().to_dict())
# {Timestamp('2026-02-28 00:00:00'): 60, Timestamp('2026-03-31 00:00:00'): 300}

# Several summaries at once
print(daily.resample("ME").agg(["first", "last", "max"]))
#             first   last    max
# 2026-02-28  100.0  103.0  103.0
# 2026-03-31  102.0  106.0  106.0

Barras a partir de ticks y sobremuestreo

Los gráficos y los modelos usan barras OHLC: apertura (primer precio), máximo, mínimo y cierre (último precio) de cada periodo. resample("D").ohlc() las construye a partir de precios intradía en una llamada. Los días naturales sin ninguna operación, como los fines de semana, siguen apareciendo como filas de NaN, así que termina con dropna() si solo quieres los días con negociación. El sobremuestreo va al revés: resample("D").ffill() repite el último valor conocido en los días sin datos, que es lo que significa en realidad un precio cotizado semanalmente. Nunca uses bfill con precios: copia un valor futuro hacia atrás y filtra la información de mañana en el hoy.

times = ["2026-03-05 09:30", "2026-03-05 11:00", "2026-03-05 15:59",
         "2026-03-09 09:30", "2026-03-09 12:00", "2026-03-09 15:59"]
ticks = pd.Series([100.0, 101.5, 99.8, 100.7, 102.0, 101.0], index=pd.to_datetime(times))

bars = ticks.resample("D").ohlc()
print(bars)
#              open   high    low  close
# 2026-03-05  100.0  101.5   99.8   99.8
# 2026-03-06    NaN    NaN    NaN    NaN
# 2026-03-07    NaN    NaN    NaN    NaN
# 2026-03-08    NaN    NaN    NaN    NaN
# 2026-03-09  100.7  102.0  100.7  101.0

print(bars.dropna().index.strftime("%d %b").tolist())   # ['05 Mar', '09 Mar']   only the days that traded
# Upsampling: observations on the 2nd, 6th and 10th, spread over every day with ffill
weekly = pd.Series([100.0, 103.0, 101.0], index=pd.to_datetime(["2026-03-02", "2026-03-06", "2026-03-10"]))

print(weekly.resample("D").ffill().tolist())
# [100.0, 100.0, 100.0, 100.0, 103.0, 103.0, 103.0, 103.0, 101.0]

print(int(weekly.resample("D").mean().isna().sum()))   # 6   without a fill rule the new days are empty
El remuestreo puede filtrar el futuroUna barra mensual solo se conoce al final del mes. Si asocias el cierre de fin de mes al primer día de ese mes, una estrategia parece conocer el futuro. Mantén la etiqueta al final del periodo, como hace "ME", usa ffill (nunca bfill) al sobremuestrear y desplaza hacia delante una señal mensual antes de usarla con datos diarios.
  • series.resample(regla) describe los periodos ("D", "W-FRI", "ME", "h"); la agregación posterior calcula los valores.
  • Precios: last u ohlc(); volúmenes: sum; los periodos vacíos aparecen como NaN y dropna() los quita.
  • El sobremuestreo necesita una regla de relleno: ffill() repite el último valor conocido; nunca bfill() con precios, filtra el futuro.

A continuación: las ventanas móviles, estadísticas como las medias móviles calculadas sobre una ventana deslizante de periodos recientes.

Lab: qué se califica

  • Tomar el último precio de cada mes con month_end_close25 pts
  • Totalizar el volumen de cada semana con weekly_volume25 pts
  • Construir barras diarias a partir de precios intradía con daily_ohlc25 pts
  • Extender observaciones irregulares a cada día con fill_to_daily25 pts
Explorador · lab-46-1
▾ lab-46-1
…
bash · en el navegador
learner@quantcraft:~/lab-46-1$
Python aún no cargadoPythonLn 1, Col 1Spaces: 4UTF-8

¿Restablecer este tema?

Todo lo que hay en lab-46-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