Commit ·
4628e83
1
Parent(s): 9a85282
🚀 Versão inicial do dashboard interativo com ARIMA e SARIMA + Bootstrap
Browse files- Dashboard_ARIMA_SARIMA.py +149 -0
- Dashboard_Diagnostico_ST.py +0 -165
- Dockerfile +6 -6
- README.md +11 -8
Dashboard_ARIMA_SARIMA.py
ADDED
|
@@ -0,0 +1,149 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#!/usr/bin/env python
|
| 2 |
+
# coding: utf-8
|
| 3 |
+
|
| 4 |
+
# 
|
| 5 |
+
|
| 6 |
+
# # Dashboard - Séries Temporais Financeiras (Previsão)
|
| 7 |
+
|
| 8 |
+
# In[5]:
|
| 9 |
+
|
| 10 |
+
|
| 11 |
+
import streamlit as st
|
| 12 |
+
import pandas as pd
|
| 13 |
+
import numpy as np
|
| 14 |
+
import matplotlib.pyplot as plt
|
| 15 |
+
import seaborn as sns
|
| 16 |
+
import plotly.graph_objects as go
|
| 17 |
+
|
| 18 |
+
from yahooquery import Ticker
|
| 19 |
+
from statsmodels.graphics.tsaplots import plot_acf, plot_pacf
|
| 20 |
+
from pmdarima import auto_arima
|
| 21 |
+
from statsmodels.tsa.statespace.sarimax import SARIMAX
|
| 22 |
+
from statsmodels.stats.diagnostic import acorr_ljungbox
|
| 23 |
+
import io
|
| 24 |
+
from PIL import Image
|
| 25 |
+
|
| 26 |
+
import warnings
|
| 27 |
+
|
| 28 |
+
warnings.filterwarnings("ignore")
|
| 29 |
+
|
| 30 |
+
import subprocess
|
| 31 |
+
|
| 32 |
+
|
| 33 |
+
# ## Dashboard
|
| 34 |
+
|
| 35 |
+
# In[12]:
|
| 36 |
+
|
| 37 |
+
|
| 38 |
+
# Função com cache
|
| 39 |
+
@st.cache_data(ttl=3600)
|
| 40 |
+
def carregar_dados(ativo):
|
| 41 |
+
ticker = Ticker(ativo)
|
| 42 |
+
df_raw = ticker.history(start='2012-01-01', interval='1d').reset_index()
|
| 43 |
+
df_raw['date'] = pd.to_datetime(df_raw['date'], utc=True, errors='coerce').dt.tz_convert(None)
|
| 44 |
+
df_prices = df_raw[df_raw['adjclose'].notna()][['date', 'adjclose']].rename(columns={'date': 'Data', 'adjclose': 'Preco'})
|
| 45 |
+
df_prices.set_index('Data', inplace=True)
|
| 46 |
+
df_prices = df_prices[~df_prices.index.duplicated()]
|
| 47 |
+
return df_prices
|
| 48 |
+
|
| 49 |
+
# Função para diagnosticar FAC/FACP
|
| 50 |
+
def plot_diagnostico(serie):
|
| 51 |
+
fig, axs = plt.subplots(2, 1, figsize=(10, 6))
|
| 52 |
+
plot_acf(serie.dropna(), lags=36, ax=axs[0])
|
| 53 |
+
axs[0].set_title("FAC")
|
| 54 |
+
plot_pacf(serie.dropna(), lags=36, ax=axs[1])
|
| 55 |
+
axs[1].set_title("FACP")
|
| 56 |
+
fig.tight_layout()
|
| 57 |
+
return fig
|
| 58 |
+
|
| 59 |
+
# Função para simulação bootstrap
|
| 60 |
+
def bootstrap_previsao(modelo_base, treino, steps, order, seasonal_order, n_sim=10):
|
| 61 |
+
resid = modelo_base.resid.dropna()
|
| 62 |
+
sim_matrix = []
|
| 63 |
+
for _ in range(n_sim):
|
| 64 |
+
shocks = np.random.choice(resid, size=steps, replace=True)
|
| 65 |
+
history = list(treino)
|
| 66 |
+
sim = []
|
| 67 |
+
for i in range(steps):
|
| 68 |
+
mod = SARIMAX(history, order=order, seasonal_order=seasonal_order, trend='c').filter(modelo_base.params)
|
| 69 |
+
next_val = mod.forecast(steps=1)[0]
|
| 70 |
+
val = next_val + shocks[i]
|
| 71 |
+
sim.append(val)
|
| 72 |
+
history.append(val)
|
| 73 |
+
sim_matrix.append(sim)
|
| 74 |
+
sim_df = pd.DataFrame(sim_matrix).T
|
| 75 |
+
return sim_df
|
| 76 |
+
|
| 77 |
+
# Configuração da página
|
| 78 |
+
st.set_page_config(page_title="Previsão SARIMA com Bootstrap", layout="wide")
|
| 79 |
+
st.title("📈 Dashboard de Séries Temporais com SARIMA + Bootstrap")
|
| 80 |
+
|
| 81 |
+
# Sidebar
|
| 82 |
+
st.sidebar.header("Configurações do Modelo")
|
| 83 |
+
ativo = st.sidebar.selectbox("Escolha o ativo:", ["PETR4.SA", "NG=F", "WEAT", "AMZN", "WMT"])
|
| 84 |
+
auto = st.sidebar.radio("Seleção do modelo:", ["AutoARIMA", "Manual"])
|
| 85 |
+
|
| 86 |
+
# Carregar série
|
| 87 |
+
df_diaria = carregar_dados(ativo)
|
| 88 |
+
serie = df_diaria['Preco'].resample('M').mean().dropna()
|
| 89 |
+
|
| 90 |
+
st.subheader("📊 Série histórica (mensal)")
|
| 91 |
+
st.line_chart(serie)
|
| 92 |
+
|
| 93 |
+
# Diagnóstico FAC/FACP
|
| 94 |
+
if st.button("🔍 Ver Diagnóstico FAC/FACP"):
|
| 95 |
+
st.subheader("FAC e FACP da série diferenciada")
|
| 96 |
+
fig_diag = plot_diagnostico(serie.diff().dropna())
|
| 97 |
+
st.pyplot(fig_diag)
|
| 98 |
+
|
| 99 |
+
# Definição do modelo
|
| 100 |
+
if auto == "AutoARIMA":
|
| 101 |
+
model_arima = auto_arima(serie, seasonal=True, m=12, trace=False, suppress_warnings=True)
|
| 102 |
+
order = model_arima.order
|
| 103 |
+
seasonal_order = model_arima.seasonal_order[:3] + (12,)
|
| 104 |
+
else:
|
| 105 |
+
order = tuple(map(int, st.sidebar.text_input("Order (p,d,q):", "1,1,1").split(",")))
|
| 106 |
+
seasonal_order = tuple(map(int, st.sidebar.text_input("Seasonal Order (P,D,Q,s):", "1,1,1,12").split(",")))
|
| 107 |
+
|
| 108 |
+
modelo = SARIMAX(serie, order=order, seasonal_order=seasonal_order, trend='c').fit(disp=False)
|
| 109 |
+
|
| 110 |
+
# Ljung-Box
|
| 111 |
+
if st.button("📈 Testar Ljung-Box nos resíduos"):
|
| 112 |
+
st.subheader("📈 Teste de Ljung-Box nos resíduos")
|
| 113 |
+
alpha = st.slider("Escolha o nível de significância (α)", 0.01, 0.10, 0.05, step=0.01)
|
| 114 |
+
lb_test = acorr_ljungbox(modelo.resid.dropna(), lags=[12], return_df=True)
|
| 115 |
+
st.dataframe(lb_test)
|
| 116 |
+
pval = lb_test['lb_pvalue'].values[0]
|
| 117 |
+
if pval < alpha:
|
| 118 |
+
st.error(f"p-valor = {pval:.4f} < {alpha:.2f} → Rejeitamos H₀: resíduos não são ruído branco.")
|
| 119 |
+
else:
|
| 120 |
+
st.success(f"p-valor = {pval:.4f} ≥ {alpha:.2f} → Não rejeitamos H₀: resíduos são ruído branco.")
|
| 121 |
+
|
| 122 |
+
# Parâmetros de previsão
|
| 123 |
+
n_passos = st.sidebar.slider("Horizonte de previsão (meses)", 6, 36, 12)
|
| 124 |
+
n_sim = st.sidebar.slider("Nº simulações bootstrap", 5, 50, 10)
|
| 125 |
+
|
| 126 |
+
# Previsão e gráfico final
|
| 127 |
+
if st.button("📈 Gerar Previsão com IC (Bootstrap)"):
|
| 128 |
+
forecast_index = pd.date_range(serie.index[-1] + pd.DateOffset(months=1), periods=n_passos, freq="M")
|
| 129 |
+
sim_df = bootstrap_previsao(modelo, list(serie), n_passos, order, seasonal_order, n_sim=n_sim)
|
| 130 |
+
ci_lower = sim_df.quantile(0.025, axis=1)
|
| 131 |
+
ci_upper = sim_df.quantile(0.975, axis=1)
|
| 132 |
+
median = sim_df.median(axis=1)
|
| 133 |
+
|
| 134 |
+
fig = go.Figure()
|
| 135 |
+
fig.add_trace(go.Scatter(x=serie.index, y=serie, name="Histórico", line=dict(color="blue")))
|
| 136 |
+
fig.add_trace(go.Scatter(x=forecast_index, y=median, name="Previsão", line=dict(color="red")))
|
| 137 |
+
fig.add_trace(go.Scatter(
|
| 138 |
+
x=list(forecast_index) + list(forecast_index[::-1]),
|
| 139 |
+
y=list(ci_lower) + list(ci_upper[::-1]),
|
| 140 |
+
fill='toself',
|
| 141 |
+
fillcolor='rgba(255,182,193,0.3)',
|
| 142 |
+
line=dict(color='rgba(255,255,255,0)'),
|
| 143 |
+
name='IC 95%',
|
| 144 |
+
hoverinfo='skip'
|
| 145 |
+
))
|
| 146 |
+
fig.update_layout(title=f"Previsão SARIMA + Bootstrap ({ativo})",
|
| 147 |
+
xaxis_title="Data", yaxis_title="Preço Ajustado",
|
| 148 |
+
template="plotly_white", height=500)
|
| 149 |
+
st.plotly_chart(fig, use_container_width=True)
|
Dashboard_Diagnostico_ST.py
DELETED
|
@@ -1,165 +0,0 @@
|
|
| 1 |
-
#!/usr/bin/env python
|
| 2 |
-
# coding: utf-8
|
| 3 |
-
|
| 4 |
-
import streamlit as st
|
| 5 |
-
import pandas as pd
|
| 6 |
-
import numpy as np
|
| 7 |
-
from yahooquery import Ticker
|
| 8 |
-
import plotly.graph_objects as go
|
| 9 |
-
from statsmodels.tsa.stattools import adfuller, kpss, acf, pacf
|
| 10 |
-
from statsmodels.stats.diagnostic import acorr_ljungbox, het_arch
|
| 11 |
-
from statsmodels.stats.stattools import jarque_bera
|
| 12 |
-
from PIL import Image
|
| 13 |
-
|
| 14 |
-
# Configuração da página
|
| 15 |
-
st.set_page_config(
|
| 16 |
-
page_title="Diagnóstico de Séries Temporais Financeiras",
|
| 17 |
-
layout="wide",
|
| 18 |
-
initial_sidebar_state="expanded"
|
| 19 |
-
)
|
| 20 |
-
|
| 21 |
-
# Estilo do slider
|
| 22 |
-
st.markdown("""
|
| 23 |
-
<style>
|
| 24 |
-
.stSlider > div > div > div > div > div > div {
|
| 25 |
-
background-color: #4CAF50 !important;
|
| 26 |
-
}
|
| 27 |
-
</style>
|
| 28 |
-
""", unsafe_allow_html=True)
|
| 29 |
-
|
| 30 |
-
# Logo
|
| 31 |
-
logo_unb = Image.open("Logo/MARCADOR.png")
|
| 32 |
-
col1, col2, col3 = st.columns([1, 6, 1])
|
| 33 |
-
with col1:
|
| 34 |
-
st.image(logo_unb, use_column_width=True)
|
| 35 |
-
with col2:
|
| 36 |
-
st.markdown("<h1 style='text-align: center; color: #003366;'>Diagnóstico de Séries Temporais Financeiras</h1>", unsafe_allow_html=True)
|
| 37 |
-
st.markdown("<h3 style='text-align: center; color: #003366;'>Professor João Gabriel de Moraes Souza</h3>", unsafe_allow_html=True)
|
| 38 |
-
with col3:
|
| 39 |
-
st.image(logo_unb, use_column_width=True)
|
| 40 |
-
|
| 41 |
-
# Interface
|
| 42 |
-
ativos = ['ITUB4.SA', 'BBAS3.SA', 'BBDC4.SA', 'PETR3.SA', 'CSNA3.SA']
|
| 43 |
-
ativo = st.selectbox("Escolha um ativo:", ativos)
|
| 44 |
-
tipo_serie = st.radio("Tipo de série:", ["Preços", "Retornos"])
|
| 45 |
-
alpha = st.slider("Nível de significância (α):", min_value=0.01, max_value=0.10, value=0.01, step=0.01)
|
| 46 |
-
diagnostico = st.selectbox("Escolha o tipo de diagnóstico:", [
|
| 47 |
-
"Estacionariedade",
|
| 48 |
-
"Ergodicidade",
|
| 49 |
-
"Autocorrelação",
|
| 50 |
-
"Heterocedasticidade",
|
| 51 |
-
"Normalidade"
|
| 52 |
-
])
|
| 53 |
-
|
| 54 |
-
# Cache para download de dados
|
| 55 |
-
@st.cache_data(ttl=3600)
|
| 56 |
-
def carregar_dados(ativo):
|
| 57 |
-
ticker = Ticker(ativo)
|
| 58 |
-
df_raw = ticker.history(start='2012-01-01', interval='1d').reset_index()
|
| 59 |
-
df_raw['date'] = pd.to_datetime(df_raw['date'], utc=True, errors='coerce').dt.tz_convert(None)
|
| 60 |
-
df_prices = df_raw[df_raw['adjclose'].notna()][['date', 'adjclose']].rename(columns={'date': 'Data', 'adjclose': 'Preco'})
|
| 61 |
-
df_prices.set_index('Data', inplace=True)
|
| 62 |
-
df_prices = df_prices[~df_prices.index.duplicated()]
|
| 63 |
-
return df_prices
|
| 64 |
-
|
| 65 |
-
# Carregar dados cacheados
|
| 66 |
-
df_prices = carregar_dados(ativo)
|
| 67 |
-
|
| 68 |
-
# Calcular série conforme tipo
|
| 69 |
-
if tipo_serie == "Retornos":
|
| 70 |
-
serie = np.log(df_prices / df_prices.shift(1)).dropna()
|
| 71 |
-
else:
|
| 72 |
-
serie = df_prices.copy()
|
| 73 |
-
|
| 74 |
-
# Visualização da série
|
| 75 |
-
st.markdown("### Dados Históricos")
|
| 76 |
-
st.line_chart(serie)
|
| 77 |
-
|
| 78 |
-
# Diagnóstico
|
| 79 |
-
st.markdown(f"### Diagnóstico: {diagnostico}")
|
| 80 |
-
|
| 81 |
-
if diagnostico == "Estacionariedade":
|
| 82 |
-
try:
|
| 83 |
-
adf_stat, adf_p, *_ = adfuller(serie.values.flatten())
|
| 84 |
-
if adf_p < alpha:
|
| 85 |
-
st.success(f"ADF: p-valor = {adf_p:.4f} < α → estacionária ao nível de {alpha*100:.0f}%")
|
| 86 |
-
else:
|
| 87 |
-
st.warning(f"ADF: p-valor = {adf_p:.4f} ≥ α → não estacionária ao nível de {alpha*100:.0f}%")
|
| 88 |
-
except Exception as e:
|
| 89 |
-
st.error(f"Erro no teste ADF: {e}")
|
| 90 |
-
|
| 91 |
-
try:
|
| 92 |
-
kpss_stat, kpss_p, *_ = kpss(serie.values.flatten(), nlags='auto')
|
| 93 |
-
if kpss_p < alpha:
|
| 94 |
-
st.warning(f"KPSS: p-valor = {kpss_p:.4f} < α → rejeita estacionariedade ao nível de {alpha*100:.0f}%")
|
| 95 |
-
else:
|
| 96 |
-
st.success(f"KPSS: p-valor = {kpss_p:.4f} ≥ α → estacionariedade não rejeitada")
|
| 97 |
-
except Exception as e:
|
| 98 |
-
st.error(f"Erro no teste KPSS: {e}")
|
| 99 |
-
|
| 100 |
-
elif diagnostico == "Ergodicidade":
|
| 101 |
-
expanding_mean = serie.expanding().mean()
|
| 102 |
-
fig = go.Figure([go.Scatter(x=expanding_mean.index, y=expanding_mean.values.flatten())])
|
| 103 |
-
fig.update_layout(title="Média Acumulada (Ergodicidade)", xaxis_title="Data", yaxis_title="Média")
|
| 104 |
-
st.plotly_chart(fig)
|
| 105 |
-
|
| 106 |
-
elif diagnostico == "Autocorrelação":
|
| 107 |
-
try:
|
| 108 |
-
serie_valida = serie.values.flatten()
|
| 109 |
-
serie_valida = serie_valida[~np.isnan(serie_valida)]
|
| 110 |
-
serie_valida = serie_valida[~np.isinf(serie_valida)]
|
| 111 |
-
|
| 112 |
-
if len(serie_valida) > 30 and np.std(serie_valida) > 0:
|
| 113 |
-
lb_p = acorr_ljungbox(serie_valida, lags=[10], return_df=True)['lb_pvalue'].iloc[0]
|
| 114 |
-
if lb_p < alpha:
|
| 115 |
-
st.warning(f"Ljung-Box: p-valor = {lb_p:.4f} < α → autocorrelação presente")
|
| 116 |
-
else:
|
| 117 |
-
st.success(f"Ljung-Box: p-valor = {lb_p:.4f} ≥ α → sem evidência de autocorrelação")
|
| 118 |
-
else:
|
| 119 |
-
st.warning("Série inválida para o teste de Ljung-Box: tamanho insuficiente ou variância nula.")
|
| 120 |
-
except Exception as e:
|
| 121 |
-
st.error(f"Erro no teste Ljung-Box: {e}")
|
| 122 |
-
|
| 123 |
-
try:
|
| 124 |
-
acf_vals = acf(serie_valida, nlags=30)
|
| 125 |
-
pacf_vals = pacf(serie_valida, nlags=30)
|
| 126 |
-
lags = list(range(len(acf_vals)))
|
| 127 |
-
|
| 128 |
-
fig_acf = go.Figure([go.Bar(x=lags, y=acf_vals)])
|
| 129 |
-
fig_acf.update_layout(title="Autocorrelação (ACF)", xaxis_title="Lag", yaxis_title="ACF")
|
| 130 |
-
st.plotly_chart(fig_acf)
|
| 131 |
-
|
| 132 |
-
fig_pacf = go.Figure([go.Bar(x=lags, y=pacf_vals)])
|
| 133 |
-
fig_pacf.update_layout(title="Autocorrelação Parcial (PACF)", xaxis_title="Lag", yaxis_title="PACF")
|
| 134 |
-
st.plotly_chart(fig_pacf)
|
| 135 |
-
|
| 136 |
-
except Exception as e:
|
| 137 |
-
st.error(f"Erro nos gráficos ACF/PACF: {e}")
|
| 138 |
-
|
| 139 |
-
elif diagnostico == "Heterocedasticidade":
|
| 140 |
-
try:
|
| 141 |
-
serie_valida = serie.values.flatten()
|
| 142 |
-
serie_valida = serie_valida[~np.isnan(serie_valida)]
|
| 143 |
-
serie_valida = serie_valida[~np.isinf(serie_valida)]
|
| 144 |
-
|
| 145 |
-
if len(serie_valida) > 30 and np.std(serie_valida) > 0:
|
| 146 |
-
p_arch = het_arch(serie_valida)[1]
|
| 147 |
-
if p_arch < alpha:
|
| 148 |
-
st.warning(f"ARCH: p-valor = {p_arch:.4f} < α → heterocedasticidade condicional presente")
|
| 149 |
-
else:
|
| 150 |
-
st.success(f"ARCH: p-valor = {p_arch:.4f} ≥ α → sem evidência de heterocedasticidade")
|
| 151 |
-
else:
|
| 152 |
-
st.warning("Série inválida para o teste ARCH: tamanho insuficiente ou variância nula.")
|
| 153 |
-
except Exception as e:
|
| 154 |
-
st.error(f"Erro no teste ARCH: {e}")
|
| 155 |
-
|
| 156 |
-
elif diagnostico == "Normalidade":
|
| 157 |
-
try:
|
| 158 |
-
jb_stat, jb_p, *_ = jarque_bera(serie.values.flatten())
|
| 159 |
-
if jb_p < alpha:
|
| 160 |
-
st.warning(f"Jarque-Bera: p-valor = {jb_p:.4f} < α → distribuição não normal")
|
| 161 |
-
else:
|
| 162 |
-
st.success(f"Jarque-Bera: p-valor = {jb_p:.4f} ≥ α → distribuição aproximadamente normal")
|
| 163 |
-
except Exception as e:
|
| 164 |
-
st.error(f"Erro no teste Jarque-Bera: {e}")
|
| 165 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Dockerfile
CHANGED
|
@@ -1,7 +1,6 @@
|
|
| 1 |
-
# Dockerfile para
|
| 2 |
|
| 3 |
# syntax=docker/dockerfile:1
|
| 4 |
-
|
| 5 |
FROM python:3.10-slim
|
| 6 |
|
| 7 |
ENV PYTHONUNBUFFERED=1 \
|
|
@@ -9,15 +8,16 @@ ENV PYTHONUNBUFFERED=1 \
|
|
| 9 |
|
| 10 |
WORKDIR /app
|
| 11 |
|
| 12 |
-
#
|
| 13 |
COPY requirements.txt .
|
| 14 |
RUN pip install --upgrade pip && pip install --no-cache-dir -r requirements.txt
|
| 15 |
|
| 16 |
-
# Copiar
|
| 17 |
COPY Logo ./Logo
|
| 18 |
-
COPY
|
| 19 |
|
|
|
|
| 20 |
EXPOSE 8501
|
| 21 |
|
| 22 |
-
CMD ["streamlit", "run", "
|
| 23 |
|
|
|
|
| 1 |
+
# Dockerfile para Dashboard ARIMA + SARIMA com Bootstrap (Streamlit)
|
| 2 |
|
| 3 |
# syntax=docker/dockerfile:1
|
|
|
|
| 4 |
FROM python:3.10-slim
|
| 5 |
|
| 6 |
ENV PYTHONUNBUFFERED=1 \
|
|
|
|
| 8 |
|
| 9 |
WORKDIR /app
|
| 10 |
|
| 11 |
+
# Instalar dependências
|
| 12 |
COPY requirements.txt .
|
| 13 |
RUN pip install --upgrade pip && pip install --no-cache-dir -r requirements.txt
|
| 14 |
|
| 15 |
+
# Copiar arquivos da aplicação
|
| 16 |
COPY Logo ./Logo
|
| 17 |
+
COPY Dashboard_ARIMA_SARIMA.py .
|
| 18 |
|
| 19 |
+
# Porta padrão do Streamlit
|
| 20 |
EXPOSE 8501
|
| 21 |
|
| 22 |
+
CMD ["streamlit", "run", "Dashboard_ARIMA_SARIMA.py", "--server.port=8501", "--server.enableCORS=false", "--server.address=0.0.0.0"]
|
| 23 |
|
README.md
CHANGED
|
@@ -1,20 +1,23 @@
|
|
| 1 |
---
|
| 2 |
-
title: "
|
| 3 |
emoji: "📊"
|
| 4 |
-
colorFrom: "
|
| 5 |
-
colorTo: "
|
| 6 |
sdk: "docker"
|
| 7 |
app_file: "Dockerfile"
|
| 8 |
app_port: 8501
|
| 9 |
tags:
|
| 10 |
- streamlit
|
| 11 |
- séries temporais
|
| 12 |
-
-
|
| 13 |
-
-
|
| 14 |
-
-
|
|
|
|
|
|
|
| 15 |
- finanças
|
| 16 |
- UnB
|
| 17 |
-
pinned:
|
| 18 |
-
short_description: "
|
| 19 |
license: mit
|
| 20 |
---
|
|
|
|
|
|
| 1 |
---
|
| 2 |
+
title: "📈 Dashboard ARIMA + SARIMA + Bootstrap"
|
| 3 |
emoji: "📊"
|
| 4 |
+
colorFrom: "red"
|
| 5 |
+
colorTo: "black"
|
| 6 |
sdk: "docker"
|
| 7 |
app_file: "Dockerfile"
|
| 8 |
app_port: 8501
|
| 9 |
tags:
|
| 10 |
- streamlit
|
| 11 |
- séries temporais
|
| 12 |
+
- previsão
|
| 13 |
+
- ARIMA
|
| 14 |
+
- SARIMA
|
| 15 |
+
- bootstrap
|
| 16 |
+
- estatística
|
| 17 |
- finanças
|
| 18 |
- UnB
|
| 19 |
+
pinned: true
|
| 20 |
+
short_description: "Previsão com ARIMA e SARIMA"
|
| 21 |
license: mit
|
| 22 |
---
|
| 23 |
+
|