matheusbm commited on
Commit
d76fca3
·
verified ·
1 Parent(s): 261e843

Create tarefa3

Browse files
Files changed (1) hide show
  1. tarefa3 +131 -0
tarefa3 ADDED
@@ -0,0 +1,131 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # ============================================================
2
+ # VAR-VECM • IRF • FEVD (Séries: PIB_real, Core PCE, Petróleo WTI)
3
+ # Requer: streamlit ≥ 1.25, pandas ≥ 2.0, statsmodels ≥ 0.14
4
+ # ============================================================
5
+
6
+ import streamlit as st
7
+ import pandas as pd
8
+ import numpy as np
9
+ import matplotlib.pyplot as plt
10
+ from pandas_datareader import data as web
11
+ from yahooquery import Ticker
12
+ from statsmodels.tsa.api import VAR
13
+ from statsmodels.tsa.vector_ar.vecm import VECM, coint_johansen
14
+ from statsmodels.tsa.stattools import adfuller
15
+
16
+ # ---------- CONFIGURAÇÃO DA PÁGINA ------------------------------------------
17
+ st.set_page_config(
18
+ page_title="Choques Macroeconômicos – VAR • VECM • IRF",
19
+ layout="wide",
20
+ initial_sidebar_state="expanded"
21
+ )
22
+
23
+ # ---------- FUNÇÃO PARA BAIXAR DADOS ----------------------------------------
24
+ @st.cache_data(show_spinner=False)
25
+ def fetch_series(start='2000-01-01', end=None):
26
+ """
27
+ Baixa PIB real (trimestral), Core PCE (mensal) do FRED
28
+ e preço do petróleo WTI (diário) do YahooFinance;
29
+ devolve DataFrame log-nível, frequência mensal.
30
+ """
31
+ end = end or pd.Timestamp.today().strftime("%Y-%m-%d")
32
+
33
+ # --- FRED ---------------------------------------------------------------
34
+ fred = web.DataReader(['GDPC1', 'PCEPILFE'], 'fred', start, end)
35
+ pib_log = np.log(fred['GDPC1']).to_period('M').to_timestamp('M')
36
+ pce_log = np.log(fred['PCEPILFE']).resample('M').last()
37
+
38
+ # --- WTI ---------------------------------------------------------------
39
+ wti_raw = Ticker('CL=F').history(start=start, end=end)['adjclose'].droplevel(0)
40
+ wti_log = np.log(wti_raw).resample('M').last()
41
+
42
+ df = (
43
+ pd.concat([pib_log, pce_log, wti_log], axis=1)
44
+ .dropna()
45
+ .rename(columns={
46
+ 'GDPC1' : 'PIB_log',
47
+ 'PCEPILFE': 'CORE_PCE_log',
48
+ 'adjclose': 'WTI_log'
49
+ })
50
+ )
51
+ return df
52
+
53
+ # ---------- SIDEBAR ---------------------------------------------------------
54
+ st.sidebar.title("Controles do modelo")
55
+
56
+ start_date = st.sidebar.date_input("Data inicial", pd.to_datetime("2000-01-01"))
57
+ lags = st.sidebar.slider("Número de lags (p)", 1, 12, 6)
58
+ conf = st.sidebar.slider("Nível de confiança (%)", 80, 99, 95)
59
+ model_type = st.sidebar.selectbox("Modelo", ["VECM", "VAR"])
60
+ show_fe = st.sidebar.checkbox("Exibir FEVD", value=False)
61
+ h_irf = st.sidebar.slider("Horizonte IRF (meses)", 1, 36, 12)
62
+
63
+ # ---------- CARREGAR DADOS --------------------------------------------------
64
+ with st.spinner("Baixando séries…"):
65
+ df = fetch_series(start=start_date.strftime("%Y-%m-%d"))
66
+
67
+ st.markdown("### Séries em log-nível (mensal)")
68
+ st.line_chart(df)
69
+
70
+ # ---------- TESTES ADF / JOHANSEN ------------------------------------------
71
+ with st.expander("Testes de estacionariedade e cointegração", expanded=False):
72
+ col_test = st.columns(2)
73
+
74
+ with col_test[0]:
75
+ st.subheader("ADF (nível)")
76
+ for col in df.columns:
77
+ stat, p, *_ = adfuller(df[col])
78
+ st.write(f"**{col}** ADF={stat:.2f} p={p:.4f}")
79
+
80
+ with col_test[1]:
81
+ joh = coint_johansen(df, det_order=0, k_ar_diff=lags)
82
+ st.subheader("Johansen – Trace")
83
+ for i, (ts, cv) in enumerate(zip(joh.lr1, joh.cvt[:,1])):
84
+ decision = "Rejeita" if ts > cv else "Não rejeita"
85
+ st.write(f"r≤{i}: trace {ts:.2f} > crit5 {cv:.2f}? **{decision}**")
86
+
87
+ # ---------- AJUSTE DO MODELO -----------------------------------------------
88
+ if model_type == "VAR":
89
+ var = VAR(df).fit(lags)
90
+ st.success(f"VAR({lags}) ajustado.")
91
+ else:
92
+ r = sum(joh.lr1 > joh.cvt[:,1]) # rank pelo trace
93
+ vecm = VECM(df, k_ar_diff=lags, coint_rank=r, deterministic='co').fit()
94
+ st.success(f"VECM ajustado: rank={r}, p={lags}")
95
+
96
+ # ---------- IRF -------------------------------------------------------------
97
+ with st.expander(" Impulse Response Function (IRF)", expanded=True):
98
+ impulse = st.selectbox("Choque (impulse)", df.columns, index=2)
99
+ response = st.selectbox("Resposta", df.columns, index=0)
100
+ ic = 1 - conf/100
101
+
102
+ if model_type == "VAR":
103
+ irf = var.irf(h_irf).plot(impulse=impulse, response=response,
104
+ orth=False, signif=ic)
105
+ else:
106
+ irf = vecm.irf(h_irf).plot(impulse=impulse, response=response,
107
+ orth=False, signif=ic)
108
+
109
+ st.pyplot(irf.figure)
110
+
111
+ # ---------- FEVD ------------------------------------------------------------
112
+ if show_fe:
113
+ st.markdown("### Forecast-Error Variance Decomposition")
114
+ if model_type == "VAR": # FEVD só p/ VAR em statsmodels 0.13
115
+ fevd = var.fevd(h_irf)
116
+ else:
117
+ fevd = vecm.fevd(h_irf)
118
+
119
+ horizons = [1, 6, 12, h_irf]
120
+ tbl = pd.concat(
121
+ {h: pd.DataFrame(fevd.decomp[h],
122
+ columns=[f"Shock_{v}" for v in df.columns],
123
+ index=[f"Var_{v}" for v in df.columns])
124
+ for h in horizons},
125
+ axis=0
126
+ ).round(3)*100
127
+ st.dataframe(tbl)
128
+
129
+ # ---------- Rodapé ----------------------------------------------------------
130
+ st.caption("Dados: FRED (GDP, Core PCE) & Yahoo Finance (WTI). "
131
+ "Aplicação didática para Engenharia de Produtos Financeiros (UnB-FACE).")