# app.py import gradio as gr import numpy as np import pandas as pd import matplotlib.pyplot as plt from sklearn.linear_model import LinearRegression # Dados históricos anos = np.arange(2015, 2025) valoresRCL = np.array([ 18461481002, 19881229932, 20719829099, 21742563018, 22503460737, 25058903184, 28277263875, 29460072799, 33214094007, 36114673966 ]) / 1e9 valoresRT = np.array([ 25877008148, 26260519658, 21656374939, 22808686104, 23142025074, 24871412313, 28451064067, 30984998453, 33361387405, 35629361262 ]) / 1e9 IGPM = np.array([10.54, 7.17, -0.52, 7.54, 7.30, 23.14, 17.78, 5.45, -3.18, 6.54]) / 100 PIB = np.array([-3.5, -3.3, 1.3, 1.8, 1.2, -3.3, 4.8, 3.0, 3.2, 3.4]) / 100 # Função principal def simular(n_simulacoes, n_anos_futuros, taxa_isencao): taxa_isencao = taxa_isencao / 100 # converter para proporção # Modelo de regressão delta_RCL = np.diff(valoresRCL) delta_RT = np.diff(valoresRT) X = np.column_stack((IGPM[1:], PIB[1:])) modelo_RCL = LinearRegression().fit(X, delta_RCL) modelo_RT = LinearRegression().fit(X, delta_RT) # Simulação normal mu_igpm, sigma_igpm = np.mean(IGPM), np.std(IGPM) mu_pib, sigma_pib = np.mean(PIB), np.std(PIB) anos_futuros = np.arange(2024, 2024 + n_anos_futuros + 1) igpm_futuro = np.random.normal(mu_igpm, sigma_igpm, (n_simulacoes, n_anos_futuros)) pib_futuro = np.random.normal(mu_pib, sigma_pib, (n_simulacoes, n_anos_futuros)) simulacoes_RCL = np.zeros((n_simulacoes, n_anos_futuros + 1)) simulacoes_RT = np.zeros((n_simulacoes, n_anos_futuros + 1)) simulacoes_RCL[:, 0] = valoresRCL[-1] simulacoes_RT[:, 0] = valoresRT[-1] for t in range(1, n_anos_futuros + 1): X_t = np.column_stack((igpm_futuro[:, t - 1], pib_futuro[:, t - 1])) inc_RCL = modelo_RCL.predict(X_t) inc_RT = modelo_RT.predict(X_t) simulacoes_RCL[:, t] = (simulacoes_RCL[:, t - 1] + inc_RCL) * (1 - taxa_isencao) simulacoes_RT[:, t] = (simulacoes_RT[:, t - 1] + inc_RT) * (1 - taxa_isencao) # Estatísticas media_RCL = np.mean(simulacoes_RCL, axis=0) p10_RCL = np.percentile(simulacoes_RCL, 10, axis=0) p90_RCL = np.percentile(simulacoes_RCL, 90, axis=0) media_RT = np.mean(simulacoes_RT, axis=0) p10_RT = np.percentile(simulacoes_RT, 10, axis=0) p90_RT = np.percentile(simulacoes_RT, 90, axis=0) # Probabilidade de queda def prob_queda(sim): probs = [] for t in range(1, n_anos_futuros + 1): queda = sim[:, t] < sim[:, t - 1] prob = np.mean(queda) * 100 probs.append(f"{anos_futuros[t]}: {prob:.2f}%") return "\n".join(probs) # Gráficos def plot_grafico(y_hist, media, p10, p90, titulo): fig, ax = plt.subplots(figsize=(8, 4)) ax.plot(anos, y_hist, label="Histórico", marker='o') ax.plot(anos_futuros, media, label="Média Simulada") ax.fill_between(anos_futuros, p10, p90, alpha=0.3, label="Faixa 10–90%") ax.set_title(titulo) ax.set_xlabel("Ano") ax.set_ylabel("R$ bi") ax.grid(True) ax.legend() return fig fig_rcl = plot_grafico(valoresRCL, media_RCL, p10_RCL, p90_RCL, "Receita Corrente Líquida (RCL)") fig_rt = plot_grafico(valoresRT, media_RT, p10_RT, p90_RT, "Receita Total (RT)") # Tabela histórica var_RT = [np.nan] + list(100 * np.diff(valoresRT) / valoresRT[:-1]) var_RCL = [np.nan] + list(100 * np.diff(valoresRCL) / valoresRCL[:-1]) df = pd.DataFrame({ "Ano": anos, "RCL (bi R$)": np.round(valoresRCL, 2), "Δ% RCL": np.round(var_RCL, 2), "RT (bi R$)": np.round(valoresRT, 2), "Δ% RT": np.round(var_RT, 2), "IGPM (%)": np.round(IGPM * 100, 2), "PIB (%)": np.round(PIB * 100, 2) }) return ( fig_rcl, fig_rt, df, prob_queda(simulacoes_RCL), prob_queda(simulacoes_RT) ) # Interface Gradio demo = gr.Interface( fn=simular, inputs=[ gr.Slider(100, 5000, value=1000, step=100, label="Número de Simulações"), gr.Slider(1, 10, value=5, step=1, label="Anos de Projeção"), gr.Slider(0, 20, value=5, step=1, label="Taxa de Isenção Fiscal (%)") ], outputs=[ gr.Plot(label="Projeção RCL"), gr.Plot(label="Projeção RT"), gr.Dataframe(label="Tabela de Dados Históricos"), gr.Textbox(label="Prob. Queda RCL"), gr.Textbox(label="Prob. Queda RT") ], title="📊 Simulação Receita Pública - Monte Carlo", description="Monte Carlo com distribuição normal baseada em IGPM e PIB históricos (2015–2024)." ) if __name__ == "__main__": demo.launch()