File size: 3,243 Bytes
f6da36a
 
 
d76fca3
 
f6da36a
d76fca3
 
 
55ce4b8
d76fca3
f6da36a
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
cc4fc52
 
f6da36a
 
 
 
cc4fc52
f6da36a
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
# ======================================================
# 📉 Choques Macros • VAR · VECM · IRF · FEVD (FRED-only)
# ======================================================

import streamlit as st
import pandas as pd, numpy as np, matplotlib.pyplot as plt
from pandas_datareader import data as web
from statsmodels.tsa.api import VAR
from statsmodels.tsa.vector_ar.vecm import VECM, coint_johansen
from statsmodels.tsa.stattools import adfuller

# ---------- Página ----------
st.set_page_config("Choques Macros – VAR/VECM", layout="wide")

# ---------- Função de dados ----------
@st.cache_data(ttl=3600, show_spinner=False)
def load_data(start="2000-01-01", end=None):
    end = end or pd.Timestamp.today().strftime("%Y-%m-%d")
    fred = web.DataReader(["GDPC1", "PCEPILFE", "DCOILWTICO"], "fred", start, end)

    df = pd.concat(
        [
            np.log(fred["GDPC1"]).to_period("M").to_timestamp("M"),
            np.log(fred["PCEPILFE"]).resample("M").last(),
            np.log(fred["DCOILWTICO"]).resample("M").last(),
        ],
        axis=1,
    ).dropna()

    df.columns = ["PIB_log", "CORE_PCE_log", "WTI_log"]
    return df

# ---------- Sidebar ----------
st.sidebar.title("🎛️ Controles")
ini = st.sidebar.date_input("Data inicial", pd.to_datetime("2000-01-01"))
lags = st.sidebar.slider("Lags (p)", 1, 12, 6)
conf = st.sidebar.slider("Confiança (%)", 80, 99, 95)
modelo = st.sidebar.selectbox("Modelo", ["VECM", "VAR"])
show_fevd = st.sidebar.checkbox("FEVD")
h_irf = st.sidebar.slider("Horizonte IRF (m)", 1, 36, 12)

# ---------- Dados ----------
with st.spinner("🔄 Baixando FRED…"):
    df = load_data(ini.strftime("%Y-%m-%d"))

st.line_chart(df)

# ---------- Testes ----------
with st.expander("🧪 Testes"):
    col1, col2 = st.columns(2)
    with col1:
        st.subheader("ADF")
        for c in df:
            stat, p, *_ = adfuller(df[c])
            st.write(f"{c}: ADF={stat:.2f}, p={p:.4f}")
    with col2:
        joh = coint_johansen(df, 0, lags)
        st.subheader("Johansen")
        for i, (ts, cv) in enumerate(zip(joh.lr1, joh.cvt[:, 1])):
            st.write(f"r≤{i}: {ts:.2f} / {cv:.2f}")

# ---------- Ajuste ----------
if modelo == "VAR":
    res = VAR(df).fit(lags)
    st.success(f"VAR({lags}) ajustado")
else:
    rank = sum(joh.lr1 > joh.cvt[:, 1])
    res = VECM(df, k_ar_diff=lags, coint_rank=rank, deterministic="co").fit()
    st.success(f"VECM ajustado (rank={rank})")

# ---------- IRF ----------
with st.expander("🚀 IRF", expanded=True):
    imp = st.selectbox("Impulso", df.columns, 2)
    resp = st.selectbox("Resposta", df.columns, 0)
    alpha = 1 - conf / 100
    fig = res.irf(h_irf).plot(impulse=imp, response=resp, orth=False, signif=alpha)
    st.pyplot(fig.figure)

# ---------- FEVD ----------
if show_fevd:
    st.subheader("📈 FEVD")
    fevd = res.fevd(h_irf)
    for h in [1, 6, 12]:
        if h <= h_irf:
            st.write(f"**h={h}**")
            tbl = pd.DataFrame(
                fevd.decomp[h],
                columns=[f"Shock_{c}" for c in df.columns],
                index=df.columns,
            ).round(2) * 100
            st.dataframe(tbl)

st.caption("Dados: FRED (GDPC1, PCEPILFE, DCOILWTICO)  •  Demo UnB EPF")