Financial Analytics

Séries Temporais: Fundamentos e Decomposição

Paloma Vaissman Uribe

Insper, PADS

Julio Trecenti

2026

🎯 Objetivos do Curso

Ao final do curso você será capaz de:

  • Analisar dados temporais: tendências, sazonalidades e ruídos em séries financeiras
  • Selecionar métodos estatísticos adequados ao problema de decisão
  • Ajustar e interpretar modelos ARIMA e SARIMA
  • Programar análises em Python

🗺️ Estrutura do Curso

Forecasting

  1. Fundamentos de séries temporais (esta aula!)
  2. Modelagem SARIMA / Prophet

📝 Trabalho intermediário: 50% da nota

Finance Applications

  1. Fatos estilizados em finanças
  2. Modelos de volatilidade
  3. VaR, CAPM, Pair Trading, Carteira Ótima
  4. Modelos multivariados
  5. Apresentação de trabalhos

🎤 Trabalho final: 50% da nota

📌 Nesta Aula

Parte 1: Fundamentos

  • Processo estocástico, i.i.d.
  • Autocorrelação (ACF)
  • Estacionariedade
  • Random walk e ruído branco

Parte 2: Componentes e Decomposição

  • Tabela de componentes
  • Decomposição aditiva/multiplicativa
  • Sazonalidade vista pela ACF (IBC-Br)
  • Diferenciação sazonal e teste ADF

Parte 3: PACF e Modelos

  • Autocorrelação Parcial (PACF)
  • Identificação de modelos pela tabela ACF/PACF
  • Processos AR, MA, ARMA
  • Integração: ARIMA

Nota

Aula 2: SARIMA, Prophet e modelos de previsão com sazonalidade

Parte 1 · Fundamentos

Processo estocástico, autocorrelação e estacionariedade

1 · Processo Estocástico & Série Temporal

Um processo estocástico é uma família de variáveis aleatórias indexadas pelo tempo:

\[X = \{X(t, \omega),\ t \in T,\ \omega \in \Omega\}\]

Nota

Cada trajetória \(X^{(i)}(t)\) é uma realização do processo.
A série temporal observada é uma dessas infinitas trajetórias possíveis.

2 · Breve revisão: Variável Aleatória

Uma variável aleatória é uma função que associa a cada elemento \(\omega \in \Omega\) do espaço amostral um número real:

\[X: \Omega \to \mathbb{R}\]

Nota

Exemplo: ao jogar um dado não viciado, \(\Omega = \{1,2,3,4,5,6\}\) e definimos \(X\) como o resultado obtido, tal que \(P(X = k) = \frac{1}{6}\) para \(k = 1, \ldots, 6\).

Um processo estocástico é uma sequência de variáveis aleatórias: é exatamente o que ocorre ao jogar o dado 500 vezes e registrar os resultados consecutivos.

2 · O que é a ACF?

A Função de Autocorrelação (ACF) mede o grau de dependência linear entre \(Y_t\) e seus valores passados \(Y_{t-k}\):

\[\rho_k = \frac{\text{Cov}(Y_t,\, Y_{t-k})}{\text{Var}(Y_t)}\]

onde \(k\) é chamado de lag (defasagem).

  • \(\rho_0 = 1\) sempre (correlação consigo mesmo)
  • \(\rho_k \in [-1, 1]\)
  • Se \(|\rho_k| > \frac{1.96}{\sqrt{n}}\) → autocorrelação significativa no lag \(k\)
  • ACF decaindo lentamente → série não estacionária
  • ACF caindo rápido para zero → série estacionária

Dica

Intuição: a ACF responde “o passado ajuda a prever o futuro?” Se sim → há memória na série. Se não → processo é i.i.d.

2 · Processo i.i.d.

Quando as VAs são independentes e possuem a mesma distribuição de probabilidade, o processo é chamado i.i.d.:

import numpy as np

n = 500

def dados(n, k):
    # Simula n lancamentos de um dado de k faces
    return np.random.randint(1, k + 1, size=n)

dados_gerados = dados(n, 6)

Aviso

Observe que a ACF está toda dentro do intervalo de confiança, confirmando ausência de dependência temporal. Séries temporais reais não são i.i.d.: há memória entre os pontos!

3 · Autocorrelação: Carregando os Dados

Usaremos o IBC-Br (BCB, código 24363), proxy mensal do PIB brasileiro:

import pandas as pd
from python_bcb import sgs

# IBC-Br: Indice de Atividade Economica do Banco Central
ibc = sgs.get({'ibc': 24363}, start='2003-01-01')
ibc = ibc.dropna()
ibc.index = pd.to_datetime(ibc.index)
ibc.index.freq = 'MS'

Nota

O IBC-Br é calculado mensalmente pelo Banco Central e funciona como
proxy do PIB antes da divulgação oficial pelo IBGE.
Instale com: pip install python-bcb

3 · ACF do IBC-Br: Série em Nível

\[\rho_k = \text{Cor}(Y_t, Y_{t-k}) = \frac{\text{Cov}(Y_t, Y_{t-k})}{\text{Var}(Y_t)}\]

import matplotlib.pyplot as plt
from statsmodels.graphics.tsaplots import plot_acf

fig, axes = plt.subplots(1, 2, figsize=(12, 4))
axes[0].plot(ibc.index, ibc['ibc'], color='#E4002B')
axes[0].set_title('IBC-Br: Índice Mensal (BCB 24363)')
plot_acf(ibc['ibc'], ax=axes[1], lags=24, title='ACF: Nível', zero=False)
plt.tight_layout(); plt.show()

Dica

A ACF decai muito lentamente → sinal de não-estacionariedade. Os picos nos lags 12, 24, 36 revelam a sazonalidade anual da série.

4 · Estacionariedade

Um processo é fracamente estacionário quando possui:

Propriedade Condição
Média Constante para todo \(t\)
Variância Constante para todo \(t\)
Covariância Função apenas da defasagem

Dica

A ACF do IBC-Br decai muito lentamente: sinal claro de não-estacionariedade e presença de raiz unitária.

5 · Defasagem e Diferenciação

Defasagem: \(y_{t-1},\ y_{t-2},\ \ldots\) | Diferenciação: \(\Delta y_t = y_t - y_{t-1}\)

ibc['ibc_lag']  = ibc['ibc'].shift(periods=1)
ibc['ibc_diff'] = ibc['ibc'].diff(periods=1)

6 · Passeio Aleatório (Random Walk)

\[y_t = y_{t-1} + \varepsilon_t, \quad \varepsilon_t \sim RB(0, \sigma^2)\]

np.random.seed(42)
n = len(ibc)
epsilon = np.random.normal(0, 1, n)
rw = np.zeros(n); rw[0] = epsilon[0]
for i in range(1, n): rw[i] = rw[i-1] + epsilon[i]

7 · Ruído Branco

Um ruído branco \(\{\varepsilon_t\}\) é um processo estocástico com:

Propriedade Condição
Média \(E[\varepsilon_t] = 0\)
Variância \(\text{Var}(\varepsilon_t) = \sigma^2\) (constante)
Covariância \(\text{Cov}(\varepsilon_t, \varepsilon_s) = 0\ \forall\ t \neq s\)

Nota

Ruído branco gaussiano = processo i.i.d. quando \(\varepsilon_t \sim \mathcal{N}(0, \sigma^2)\)

O ruído branco é o componente residual ideal de qualquer modelo de séries temporais: se os resíduos são ruído branco, o modelo capturou toda a estrutura da série.

Na notação: \[\varepsilon_t \sim RB(0, \sigma^2)\]

  • Sem memória → ACF \(\approx 0\) para todo \(k \neq 0\)
  • É estacionário por construção
  • É o \(\varepsilon_t\) do passeio aleatório: \(y_t = y_{t-1} + \varepsilon_t\)

Parte 2 · Componentes e Decomposição

Tendência, sazonalidade, ciclo, resíduo, decomposição e teste ADF

7 · Sazonalidade na ACF

A sazonalidade se manifesta como picos repetidos na ACF nos múltiplos do período \(s\):

fig, axes = plt.subplots(1, 2, figsize=(12, 4))
# Série em nível
plot_acf(ibc['ibc'], ax=axes[0], lags=36,
         title='ACF: IBC-Br Nível (picos a cada 12 lags)', zero=False)
# Série com 1ª diferença
plot_acf(ibc['ibc_diff'].dropna(), ax=axes[1], lags=36,
         title='ACF: IBC-Br 1ª Diferença (ainda sazonal!)', zero=False)
plt.tight_layout(); plt.show()

Dica

Na 1ª diferença os picos no lag 12, 24, 36 ainda são significativos: a sazonalidade não desaparece com uma simples diferença. É preciso também diferenciar sazonalmente.

7 · Removendo a Sazonalidade + Dummy Covid

\[\Delta\Delta_{12} y_t = \Delta y_t - \Delta y_{t-12}\]

ibc['ibc_diff_seas'] = ibc['ibc_diff'].diff(12)

# Dummy Covid: meses mar/2020-ago/2020 como missing
covid_idx = ibc.index[ibc.index >= '2020-01-01'][:6]
ibc.loc[covid_idx, 'ibc_diff_seas'] = np.nan

7 · Modelos para Sazonalidade: O que vem a seguir

Nota

A diferença sazonal \(\Delta_{12}\) reduz a sazonalidade, mas pode restar estrutura nos lags 12, 24, 36 da ACF. Modelos específicos tratam isso de forma sistemática.

Modelo Abordagem Destaque
SARIMA Parâmetros sazonais \(P\), \(D\), \(Q\) Rigor estatístico
Prophet (Meta) Decomposição + Fourier Sazonalidades múltiplas
ETS Suavização exponencial Simples e robusto
TBATS Box-Cox + Fourier Sazonalidade complexa

Dica

Na Aula 2 veremos como ajustar e comparar esses modelos na prática, incluindo SARIMA e Prophet para séries financeiras.

8 · Componentes de uma Série Temporal

Componente O que é Exemplo Característica
Tendência Movimento de longo prazo PIB crescendo ao longo de décadas Persistente, suave
Sazonalidade Padrão em período fixo e conhecido IBC-Br cai em jan (13º), sobe em dez Período constante
Ciclo Flutuações de período variável Ciclos de expansão/recessão (3-10 anos) Menos previsível
Resíduo Variação após remover os demais Choques imprevistos (Covid, greves) Idealmente ruído branco

Modelo Aditivo: \(Y_t = T_t + S_t + C_t + R_t\)

Dica

Tendência vs. Ciclo: na prática são difíceis de separar: muitos métodos os tratam juntos como “tendência-ciclo”. A sazonalidade, por ter período fixo, é mais fácil de isolar.

Aditivo vs. Multiplicativo: se o “zigue-zague” sazonal cresce com o nível da série → use multiplicativo (\(Y_t = T_t \times S_t \times R_t\)). Na dúvida, aplique log e use aditivo.

8 · Decomposição do IBC-Br

from statsmodels.tsa.seasonal import seasonal_decompose

decomp = seasonal_decompose(ibc['ibc'], model='additive', period=12)
fig = decomp.plot()
fig.suptitle('Decomposição Aditiva: IBC-Br', y=1.01)
plt.tight_layout(); plt.show()

Nota

A crise de 2015-16 aparece na tendência; o choque do Covid no resíduo.

10 · Teste ADF: Nível vs Estacionarizado

from statsmodels.tsa.stattools import adfuller

def rodar_adf(serie, nome):
    k = int(np.floor((len(serie) - 1) ** (1/3)))
    res = adfuller(serie, maxlag=k, autolag=None, regression='c')
    print(f"ADF {nome}: stat={res[0]:.3f} | p-value={res[1]:.3f}")

rodar_adf(ibc['ibc'],                    'IBC-Br: Nível')
rodar_adf(ibc['ibc_diff_seas'].dropna(), 'IBC-Br: Estacionarizado')

Parte 3 · PACF e Modelos

Autocorrelação parcial, identificação e modelos AR/MA/ARIMA

9 · Autocorrelação Parcial (PACF)

A PACF mede a correlação entre \(Y_t\) e \(Y_{t-k}\) após remover o efeito dos lags intermediários:

\[\phi_{kk} = \text{Cor}(Y_t - \hat{Y}_t,\ Y_{t-k} - \hat{Y}_{t-k})\]

onde \(\hat{Y}_t\) é a projeção de \(Y_t\) sobre \(Y_{t-1}, \ldots, Y_{t-k+1}\).

Nota

Algoritmo de Levinson-Durbin:

  • Lag 1: \(\phi_{11} = \rho_1\)
  • Lag 2: \(\phi_{22} = \frac{\rho_2 - \rho_1^2}{1 - \rho_1^2}\)
  • Lag \(k\): recursão usando os coeficientes anteriores

9 · Como interpretar ACF e PACF?

Padrão ACF PACF Modelo
ACF corta Corte em \(q\) Decaimento MA(\(q\))
PACF corta Decaimento Corte em \(p\) AR(\(p\))
Ambas decaem Decaimento Decaimento ARMA(\(p,q\))
ACF não decai Lento Pico lag 1 Não estacionário

Aviso

Na prática, os padrões raramente são tão limpos! Use a tabela como ponto de partida, não diagnóstico definitivo. Critérios AICc são mais confiáveis.

11 · Processo AR(\(p\))

O valor de hoje depende dos \(p\) valores passados:

\[Y_t = c + \phi_1 Y_{t-1} + \phi_2 Y_{t-2} + \cdots + \phi_p Y_{t-p} + \varepsilon_t\]

  • AR(1) com \(\phi = 0.8\): ACF decai exponencialmente, PACF corta no lag 1
  • Estacionariedade: requer \(|\phi_i| < 1\) (raízes fora do círculo unitário)
  • Intuição: o IBC-Br de hoje depende fortemente do mês anterior

11 · Processo MA(\(q\))

O valor de hoje depende dos \(q\) choques passados:

\[Y_t = \mu + \varepsilon_t + \theta_1 \varepsilon_{t-1} + \cdots + \theta_q \varepsilon_{t-q}\]

  • MA(1) com \(\theta = 0.8\): ACF corta no lag 1, PACF decai
  • Sempre estacionário (independente dos \(\theta_i\))
  • Intuição: um choque econômico hoje ainda afeta o próximo mês

9 · ACF e PACF: Padrões Teóricos

# AR(1), MA(1) e ARMA(1,1) simulados
from statsmodels.graphics.tsaplots import plot_acf, plot_pacf

fig, axes = plt.subplots(3, 2, figsize=(12, 9))
for row, serie in enumerate([ar1, ma1, arma11]):
    plot_acf(serie,  ax=axes[row, 0], lags=20, zero=False)
    plot_pacf(serie, ax=axes[row, 1], lags=20, zero=False)
plt.tight_layout(); plt.show()

9 · ACF e PACF do IBC-Br Estacionarizado

from statsmodels.graphics.tsaplots import plot_acf, plot_pacf

serie_est = ibc['ibc_diff_seas'].dropna()

fig, axes = plt.subplots(1, 2, figsize=(12, 4))
plot_acf(serie_est,  ax=axes[0], lags=24, title='ACF: IBC-Br Estacionarizado', zero=False)
plot_pacf(serie_est, ax=axes[1], lags=24, title='PACF: IBC-Br Estacionarizado', zero=False)
plt.tight_layout(); plt.show()

12 · O Modelo ARIMA(\(p\), \(d\), \(q\))

Combina diferenciação com AR e MA:

\[\underbrace{(1 - \phi_1 B - \cdots - \phi_p B^p)}_{\text{AR}(p)} \underbrace{(1-B)^d}_{\text{I}(d)} Y_t = c + \underbrace{(1 + \theta_1 B + \cdots + \theta_q B^q)}_{\text{MA}(q)} \varepsilon_t\]

Parâmetro Significado Como determinar
\(p\) Ordem AR PACF: corte em \(p\)
\(d\) Nº de diferenças Teste ADF
\(q\) Ordem MA ACF: corte em \(q\)

Nota

O ARIMA captura séries não sazonais após diferenciação. Para sazonalidade explícita, a extensão natural é o SARIMA, tema da Aula 2.

13 · Procedimento Box-Jenkins

  1. Identificação: Plotar a série, ACF, PACF. Determinar \(d\) pelo teste ADF. Identificar \(p\) e \(q\) pela tabela ACF/PACF.

  2. Estimação: Ajustar o modelo por máxima verossimilhança. Comparar candidatos via AICc (menor = melhor).

  3. Diagnóstico: Verificar se os resíduos são ruído branco: ACF dos resíduos, teste Ljung-Box. Se não: voltar ao passo 1.

  4. Previsão: Gerar previsões com intervalos de confiança.

Dica

O diagnóstico dos resíduos é o critério definitivo: se sobraram padrões, o modelo ainda não captou tudo.

14 · AutoARIMA: Seleção Automática

O algoritmo Hyndman-Khandakar automatiza o Box-Jenkins:

from statsforecast import StatsForecast
from statsforecast.models import AutoARIMA

sf = StatsForecast(
    models=[AutoARIMA(season_length=1)],  # sem sazonalidade por enquanto
    freq='MS',
    n_jobs=1,
)

ibcbr_df = ibc[['ibc_diff']].dropna().reset_index()
ibcbr_df.columns = ['ds', 'y']
ibcbr_df['unique_id'] = 'ibcbr'

sf.fit(df=ibcbr_df)
previsao = sf.predict(h=12, level=[80, 95])
  1. Testa estacionariedade → determina \(d\) automaticamente
  2. Parte de um modelo inicial simples (ex: ARIMA(2,1,2))
  3. Compara modelos vizinhos variando \(p\) e \(q\) em ±1
  4. Seleciona o modelo com menor AICc
  5. Verifica diagnóstico dos resíduos

Aviso

O AutoARIMA não substitui o entendimento do processo: use-o como validação da escolha manual. Na Aula 2 veremos sua extensão sazonal.

🏋️ Exercício Proposto

  1. Carregue uma série temporal de interesse via python_bcb
  2. Plote a série, ACF e PACF: identifique os componentes
  3. Aplique as diferenças necessárias para estacionarizar
  4. Use a tabela ACF/PACF para propor um modelo SARIMA
  5. Compare com o AutoARIMA: o resultado é semelhante?
  6. Verifique os resíduos: são ruído branco?

📖 Referências Recomendadas

Forecasting: Principles and Practice (3ª ed.)
Hyndman & Athanasopoulos · 🔗 otexts.com/fpppy

Material do Curso
🔗 padsinsper.github.io/202634-fa

Dúvidas?

Financial Analytics · PADS · Insper · 2026