σμ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 AcademyRoteiros
Ctrl K
AO
+1,2 mil alunos
EntrarParticipar ↗
Roteiros
AO
+1,2 mil alunos
Entrar
  • English
  • Français
  • Español
  • العربية
  • Português
  • Deutsch
  • 日本語
  • 中文
Roteiro de Python›Módulo 2 · NumPy e pandas para dados de mercado›Tópico 2.13·~40 minIntermediário

Reamostragem

Posição no roteiroMódulo 2 de 11 · Tópico 13 de 20
2.13 Reamostragem
—Nota do lab— / 100XP total—Sequência—

Mudar a frequência

Os dados raramente chegam na frequência de que você precisa. Os ticks chegam por milissegundo, um modelo quer barras diárias, um relatório quer meses. A reamostragem reagrupa uma série temporal em novos períodos. Ir do fino ao grosso (dias para meses) é reamostragem para baixo: cada novo período contém várias observações antigas, então é preciso dizer como combiná-las. Ir do grosso ao fino (semanas para dias) é reamostragem para cima: há períodos novos sem dados, então é preciso dizer o que colocar neles.

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

Escolher a agregação

series.resample("ME") sozinho não faz nada: só descreve os períodos. A agregação que vem depois decide o valor e deve corresponder ao significado dos dados. Um preço é um instantâneo, então um mês é representado pelo seu valor last (ou first). Um volume é uma quantidade negociada, então um mês é a sum. Uma amplitude usa max e min. Os rótulos seguem a regra: "ME" rotula um mês com seu último dia corrido, mesmo que seja sábado, e "W-FRI" rotula uma semana com sua sexta-feira.

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 e reamostragem para cima

Gráficos e modelos usam barras OHLC: abertura (primeiro preço), máxima, mínima e fechamento (último preço) de cada período. resample("D").ohlc() as constrói a partir de preços intradiários numa só chamada. Dias corridos sem nenhum negócio, como fins de semana, ainda aparecem como linhas de NaN, então termine com dropna() se quiser só os dias negociados. A reamostragem para cima vai no sentido oposto: resample("D").ffill() repete o último valor conhecido nos dias sem dados, que é o que realmente significa um preço cotado semanalmente. Nunca use bfill com preços: ele copia um valor futuro para trás e vaza a informação de amanhã para hoje.

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
A reamostragem pode vazar o futuroUma barra mensal só é conhecida no fim do mês. Se você associar o fechamento do fim do mês ao primeiro dia desse mês, uma estratégia parece conhecer o futuro. Mantenha o rótulo no fim do período, como faz "ME", use ffill (nunca bfill) ao reamostrar para cima e desloque um sinal mensal para a frente antes de usá-lo em dados diários.
  • series.resample(regra) descreve os períodos ("D", "W-FRI", "ME", "h"); a agregação seguinte calcula os valores.
  • Preços: last ou ohlc(); volumes: sum; períodos vazios aparecem como NaN, que dropna() remove.
  • A reamostragem para cima precisa de uma regra de preenchimento: ffill() repete o último valor conhecido; nunca bfill() com preços, ele vaza o futuro.

A seguir: as janelas móveis, estatísticas como as médias móveis calculadas sobre uma janela deslizante dos períodos recentes.

Lab: o que é avaliado

  • Pegar o último preço de cada mês com month_end_close25 pts
  • Totalizar o volume de cada semana com weekly_volume25 pts
  • Construir barras diárias a partir de preços intradiários com daily_ohlc25 pts
  • Espalhar observações irregulares por todos os dias com fill_to_daily25 pts
Explorador · lab-46-1
▾ lab-46-1
…
bash · no navegador
learner@quantcraft:~/lab-46-1$
Python ainda não carregadoPythonLn 1, Col 1Spaces: 4UTF-8

Redefinir este tópico?

Tudo em lab-46-1 volta aos arquivos iniciais e o terminal é limpo. Sua solução atual será perdida — isso não pode ser desfeito.

Será redefinido
  • main.py → código inicial
  • Histórico do terminal e saída dos testes
  • Alterações não enviadas
Será mantido
  • Melhor nota do lab
  • Seu XP e sua sequência
  • Progresso da aula e anotações

Entre para executar o seu código.

Todas as aulas são gratuitas para ler. Crie uma conta ou entre para executar código, rodar os testes e enviar este lab.

  • IDE no navegador com terminal bash — nada para instalar
  • Correção instantânea, XP e o seu lugar no roteiro
Criar uma contaEntrar
OU
Continuar com o GitHub