Pegumenezes commited on
Commit
4c3c53a
·
verified ·
1 Parent(s): 0b95db3

Update src/streamlit_app.py

Browse files
Files changed (1) hide show
  1. src/streamlit_app.py +33 -48
src/streamlit_app.py CHANGED
@@ -1,4 +1,4 @@
1
- # --- 1. IMPORTAÇÕES E CONFIGURAÇÃO DA PÁGINA ---
2
  import streamlit as st
3
  import pandas as pd
4
  import numpy as np
@@ -57,14 +57,21 @@ def calcular_payback_descontado(fluxo_caixa, taxa_desconto):
57
  return np.inf
58
 
59
  @st.cache_data
60
- def simular_faturamento_bootstrap(_df_dados_mensais_numeric, precos_dict, cenarios_dict, n_simulacoes=2000, seed=42):
 
61
  np.random.seed(seed)
62
  faturamentos_simulados = {nome: [] for nome in cenarios_dict.keys()}
63
- for nome_cen, fator in cenarios_dict.items():
64
  for _ in range(n_simulacoes):
65
  df_amostrado = _df_dados_mensais_numeric.sample(n=12, replace=True)
66
- faturamento_anual_iteracao = sum(df_amostrado[material].sum() * preco for material, preco in precos_dict.items())
67
- faturamentos_simulados[nome_cen].append(faturamento_anual_iteracao * fator)
 
 
 
 
 
 
68
  return {nome: np.array(data) for nome, data in faturamentos_simulados.items()}
69
 
70
  def gerar_fluxo_caixa_projeto(investimento_inicial, receita_anual_base, custos_operacionais_anuais, horizonte_anos, taxa_crescimento):
@@ -78,7 +85,6 @@ def gerar_fluxo_caixa_projeto(investimento_inicial, receita_anual_base, custos_o
78
  # --- 4. CARREGAMENTO DE DADOS (FUNÇÃO CACHEADA) ---
79
  @st.cache_data
80
  def carregar_dados():
81
- """Carrega apenas os dados iniciais do projeto. É seguro cachear esta função."""
82
  meses = ['Jan', 'Fev', 'Mar', 'Abr', 'Mai', 'Jun', 'Jul', 'Ago', 'Set', 'Out', 'Nov', 'Dez']
83
  dados_2024 = {
84
  'Mes': meses, 'Papel_Papelao': [8047, 11287, 8184, 10183, 5699, 5830, 7465, 5600, 2960, 5175, 9656, 3960],
@@ -88,18 +94,10 @@ def carregar_dados():
88
  }
89
  df_2024 = pd.DataFrame(dados_2024)
90
  df_2024_numeric = df_2024.drop(columns='Mes')
91
-
92
- dados_anuais = {
93
- 'Ano': [2022, 2023, 2024], 'Papel_Papelao': [18780, 58718, df_2024_numeric['Papel_Papelao'].sum()],
94
- 'Plastico': [5340, 1041, df_2024_numeric['Plastico'].sum()],
95
- 'Metal': [1300, 1737, df_2024_numeric['Metal'].sum()],
96
- 'Vidro': [0, 725, df_2024_numeric['Vidro'].sum()]
97
- }
98
  df_anuais = pd.DataFrame(dados_anuais).set_index('Ano')
99
-
100
  precos_iniciais = {'Papel_Papelao': 0.50, 'Plastico': 0.80, 'Metal': 2.00, 'Vidro': 0.30}
101
  custos_mensais_iniciais = {"Locacao_Maquina": 1100, "Coleta_Destinacao": 350, "Mao_de_Obra": 2500, "Outros": 500}
102
-
103
  return df_2024, df_anuais, precos_iniciais, df_2024_numeric, custos_mensais_iniciais
104
 
105
  # --- 5. EXECUÇÃO INICIAL E SIDEBAR DE CONTROLES ---
@@ -109,38 +107,29 @@ st.sidebar.title(" Painel de Controle")
109
  st.sidebar.markdown("Use os menus abaixo para navegar entre as análises e ajustar os parâmetros do projeto.")
110
  st.sidebar.divider()
111
 
112
- pagina_selecionada = st.sidebar.radio( "Menu de Navegação",
113
  ["🔎 Análise Exploratória (EDA)", "🎯 Simulação de Faturamento", "📊 Análise de Viabilidade"],
114
  captions=["Análise dos dados históricos", "Projeção de receitas via simulação", "Cálculos de VPL, TIR e Risco"]
115
  )
116
  st.sidebar.divider()
117
 
118
- # --- PREMISSAS FINANCEIRAS COM AS ALTERAÇÕES ---
119
  with st.sidebar.expander("⚙️ Premissas Financeiras do Projeto", expanded=True):
120
- # Alteração 1: Investimento inicial com novo valor padrão
121
  investimento_inicial = st.number_input("Investimento Inicial (R$)", min_value=1000.0, value=10000.0, step=1000.0)
122
-
123
- # Alteração 2: Custos mensais editáveis em vez de custo anual único
124
  st.markdown("**Custos Fixos Mensais (R$)**")
125
- custos_mensais_editaveis = {}
126
- for custo, valor in custos_mensais_iniciais.items():
127
- custos_mensais_editaveis[custo] = st.number_input(custo.replace("_", " "), value=valor, step=50, key=custo)
128
-
129
- # O custo anual agora é calculado a partir dos custos mensais
130
  custos_operacionais_anuais = sum(custos_mensais_editaveis.values()) * 12
131
  st.info(f"Custo Anual Calculado: **{formatar_brl(custos_operacionais_anuais)}**")
132
-
133
  horizonte_projeto = st.slider("Horizonte do Projeto (anos)", 3, 20, 10)
134
  taxa_desconto = st.slider("Taxa de Desconto (TMA) (%)", 5.0, 25.0, 12.0, 0.5) / 100
135
  taxa_crescimento = st.slider("Crescimento Anual (Receitas/Custos) (%)", 0.0, 10.0, 3.0, 0.5) / 100
136
  taxa_reinvestimento = st.slider("Taxa de Reinvestimento (MTIR) (%)", 2.0, 18.0, 10.0, 0.5) / 100
137
 
138
  with st.sidebar.expander("📈 Preços e Cenários de Simulação", expanded=False):
 
 
139
  st.markdown("**Preços dos Materiais (R$/kg)**")
140
  precos_editaveis = {material: st.number_input(f"{material.replace('_', ' ')}", value=preco, step=0.1, key=f"preco_{material}") for material, preco in precos_iniciais.items()}
141
-
142
- st.markdown("**Fatores dos Cenários**")
143
- # Alteração 3: Cenário pessimista com novo valor padrão
144
  fator_pessimista = st.slider("Cenário Pessimista (%)", 0, 100, 60) / 100
145
  fator_otimista = st.slider("Cenário Otimista (%)", 100, 200, 115) / 100
146
 
@@ -148,11 +137,9 @@ st.sidebar.divider()
148
  st.sidebar.info(f"Última atualização: {pd.Timestamp.now(tz='America/Sao_Paulo').strftime('%d/%m/%Y %H:%M')}")
149
 
150
 
151
- # --- 6. LÓGICA DE RENDERIZAÇÃO DAS PÁGINAS (sem alterações aqui) ---
152
- # O restante do código permanece o mesmo, pois ele já utiliza as variáveis
153
- # que ajustamos na barra lateral.
154
-
155
  if pagina_selecionada == "🔎 Análise Exploratória (EDA)":
 
156
  st.title("🔎 Análise Exploratória dos Dados de Coleta")
157
  st.markdown("O primeiro passo para qualquer projeção é entender o passado. Aqui, exploramos os dados históricos de coleta para identificar padrões, sazonalidades e anomalias.")
158
  st.divider()
@@ -174,22 +161,25 @@ if pagina_selecionada == "🔎 Análise Exploratória (EDA)":
174
  st.plotly_chart(fig_boxplot, use_container_width=True)
175
  st.info("O **gráfico de linhas** mostra a tendência e sazonalidade ao longo do ano. O **boxplot** revela a volatilidade de cada material: caixas mais 'altas' indicam maior variação mensal, o que se traduz em maior risco e incerteza no faturamento.")
176
 
 
177
  elif pagina_selecionada == "🎯 Simulação de Faturamento":
178
  st.title("🎯 Simulação e Projeção de Faturamento Anual")
179
- st.markdown("Utilizando a técnica de bootstrapping, simulamos 2.000 possíveis anos de faturamento com base na volatilidade dos dados de 2024. Isso nos uma visão probabilística das receitas do projeto.")
180
  st.divider()
181
 
182
  cenarios = {'Pessimista': fator_pessimista, 'Base': 1.0, 'Otimista': fator_otimista}
183
- simulacoes_faturamento = simular_faturamento_bootstrap(df_2024_numeric, precos_editaveis, cenarios)
 
184
 
185
  kpi1, kpi2, kpi3 = st.columns(3)
186
  media_faturamento_base = np.mean(simulacoes_faturamento['Base'])
187
- p05_base, p95_base = np.percentile(simulacoes_faturamento['Base'], [5, 95])
188
- faturamento_material_base = {m: df_2024_numeric[m].sum() * p for m, p in precos_editaveis.items()}
189
  material_mais_rentavel = max(faturamento_material_base, key=faturamento_material_base.get)
190
 
191
  kpi1.metric("Faturamento Anual Médio (Base)", formatar_brl(media_faturamento_base))
192
- kpi2.metric("Intervalo de Confiança 90% (Base)", f"{formatar_brl(p05_base)} - {formatar_brl(p95_base)}")
 
193
  kpi3.metric("Material Mais Rentável (Base 2024)", material_mais_rentavel.replace('_', ' '))
194
  st.divider()
195
 
@@ -212,7 +202,7 @@ elif pagina_selecionada == "📊 Análise de Viabilidade":
212
  st.markdown("Esta é a etapa final, onde combinamos as projeções de receita com as premissas de investimento e custos para avaliar a viabilidade do projeto sob a ótica do risco.")
213
 
214
  cenarios = {'Pessimista': fator_pessimista, 'Base': 1.0, 'Otimista': fator_otimista}
215
- simulacoes_faturamento = simular_faturamento_bootstrap(df_2024_numeric, precos_editaveis, cenarios)
216
 
217
  cenario_analise = st.radio("Selecione o cenário para a análise detalhada:", options=list(cenarios.keys()), index=1, horizontal=True)
218
  st.divider()
@@ -239,10 +229,7 @@ elif pagina_selecionada == "📊 Análise de Viabilidade":
239
  st.subheader("Visualização do Fluxo de Caixa do Projeto")
240
  df_fluxo = pd.DataFrame({'Ano': list(range(horizonte_projeto + 1)), 'Fluxo de Caixa': fluxo_caixa_projeto})
241
  df_fluxo['Fluxo Acumulado'] = df_fluxo['Fluxo de Caixa'].cumsum()
242
- fig_fluxo = go.Figure(data=[
243
- go.Bar(name='Fluxo Anual', x=df_fluxo['Ano'], y=df_fluxo['Fluxo de Caixa'], marker_color=['#d62728' if x < 0 else '#2ca02c' for x in df_fluxo['Fluxo de Caixa']]),
244
- go.Scatter(name='Fluxo Acumulado', x=df_fluxo['Ano'], y=df_fluxo['Fluxo Acumulado'], mode='lines+markers')
245
- ])
246
  fig_fluxo.update_layout(title_text="Fluxo de Caixa Anual e Acumulado", hovermode='x unified')
247
  st.plotly_chart(fig_fluxo, use_container_width=True)
248
 
@@ -253,11 +240,13 @@ elif pagina_selecionada == "📊 Análise de Viabilidade":
253
 
254
  prob_viabilidade = (np.array(vpls_mc) >= 0).mean()
255
  vpl_medio_mc = np.mean(vpls_mc)
 
256
 
257
  mc1, mc2, mc3 = st.columns(3)
258
  mc1.metric("VPL Médio Simulado", formatar_brl(vpl_medio_mc))
259
  mc2.metric("Probabilidade de Viabilidade", formatar_percentual(prob_viabilidade))
260
- mc3.metric("Intervalo 90% do VPL", f"{formatar_brl(np.percentile(vpls_mc, 5))} a {formatar_brl(np.percentile(vpls_mc, 95))}")
 
261
 
262
  fig_mc = px.histogram(x=vpls_mc, nbins=50, title=f"Distribuição do VPL ({len(vpls_mc)} Simulações)")
263
  fig_mc.add_vline(x=0, line_dash="dash", line_color="red", annotation_text="Viabilidade")
@@ -268,17 +257,13 @@ elif pagina_selecionada == "📊 Análise de Viabilidade":
268
  conclusoes = []
269
  if vpl >= 0: conclusoes.append(f"✅ **Projeto VIÁVEL** no cenário '{cenario_analise}', com um VPL de **{formatar_brl(vpl)}**.")
270
  else: conclusoes.append(f"❌ **Projeto INVIÁVEL** no cenário '{cenario_analise}', com um VPL de **{formatar_brl(vpl)}**.")
271
-
272
  if not pd.isna(tir) and tir > taxa_desconto: conclusoes.append(f"✅ A **TIR de {formatar_percentual(tir)} é superior à TMA de {formatar_percentual(taxa_desconto)}**, reforçando a atratividade.")
273
  else: conclusoes.append(f"❌ A **TIR de {formatar_percentual(tir)} é inferior à TMA**, um forte indicador contra o investimento.")
274
-
275
  if prob_viabilidade > 0.75: conclusoes.append(f"✅ A simulação de Monte Carlo aponta uma **alta probabilidade de sucesso de {formatar_percentual(prob_viabilidade)}**.")
276
  elif prob_viabilidade > 0.5: conclusoes.append(f"⚠️ A probabilidade de sucesso de **{formatar_percentual(prob_viabilidade)} é moderada**.")
277
  else: conclusoes.append(f"❌ A probabilidade de sucesso de **{formatar_percentual(prob_viabilidade)} é baixa**, indicando risco elevado.")
278
-
279
  st.markdown("#### Conclusões Chave:")
280
  for c in conclusoes: st.markdown(f"- {c}")
281
-
282
  st.markdown("#### Parecer Final:")
283
  if vpl > 0 and prob_viabilidade > 0.7:
284
  st.success("**RECOMENDAÇÃO: APROVAR O PROJETO.** Os indicadores são fortemente positivos e a análise de risco confere robustez à decisão.")
 
1
+ # --- 1. IMPORTAÇÕES E CONFIGURAÇÃO DA PÁGINA ---
2
  import streamlit as st
3
  import pandas as pd
4
  import numpy as np
 
57
  return np.inf
58
 
59
  @st.cache_data
60
+ # Alteração 2.1: A função agora recebe a eficiência geral da coleta
61
+ def simular_faturamento_bootstrap(_df_dados_mensais_numeric, precos_dict, cenarios_dict, eficiencia_geral_coleta, n_simulacoes=2000, seed=42):
62
  np.random.seed(seed)
63
  faturamentos_simulados = {nome: [] for nome in cenarios_dict.keys()}
64
+ for nome_cen, fator_cenario in cenarios_dict.items():
65
  for _ in range(n_simulacoes):
66
  df_amostrado = _df_dados_mensais_numeric.sample(n=12, replace=True)
67
+ # Faturamento bruto com 100% da coleta histórica
68
+ faturamento_bruto_iteracao = sum(df_amostrado[material].sum() * preco for material, preco in precos_dict.items())
69
+
70
+ # Alteração 2.2: Aplica a eficiência geral e depois o fator do cenário
71
+ faturamento_liquido = faturamento_bruto_iteracao * eficiencia_geral_coleta * fator_cenario
72
+
73
+ faturamentos_simulados[nome_cen].append(faturamento_liquido)
74
+
75
  return {nome: np.array(data) for nome, data in faturamentos_simulados.items()}
76
 
77
  def gerar_fluxo_caixa_projeto(investimento_inicial, receita_anual_base, custos_operacionais_anuais, horizonte_anos, taxa_crescimento):
 
85
  # --- 4. CARREGAMENTO DE DADOS (FUNÇÃO CACHEADA) ---
86
  @st.cache_data
87
  def carregar_dados():
 
88
  meses = ['Jan', 'Fev', 'Mar', 'Abr', 'Mai', 'Jun', 'Jul', 'Ago', 'Set', 'Out', 'Nov', 'Dez']
89
  dados_2024 = {
90
  'Mes': meses, 'Papel_Papelao': [8047, 11287, 8184, 10183, 5699, 5830, 7465, 5600, 2960, 5175, 9656, 3960],
 
94
  }
95
  df_2024 = pd.DataFrame(dados_2024)
96
  df_2024_numeric = df_2024.drop(columns='Mes')
97
+ dados_anuais = {'Ano': [2022, 2023, 2024], 'Papel_Papelao': [18780, 58718, df_2024_numeric['Papel_Papelao'].sum()], 'Plastico': [5340, 1041, df_2024_numeric['Plastico'].sum()], 'Metal': [1300, 1737, df_2024_numeric['Metal'].sum()], 'Vidro': [0, 725, df_2024_numeric['Vidro'].sum()]}
 
 
 
 
 
 
98
  df_anuais = pd.DataFrame(dados_anuais).set_index('Ano')
 
99
  precos_iniciais = {'Papel_Papelao': 0.50, 'Plastico': 0.80, 'Metal': 2.00, 'Vidro': 0.30}
100
  custos_mensais_iniciais = {"Locacao_Maquina": 1100, "Coleta_Destinacao": 350, "Mao_de_Obra": 2500, "Outros": 500}
 
101
  return df_2024, df_anuais, precos_iniciais, df_2024_numeric, custos_mensais_iniciais
102
 
103
  # --- 5. EXECUÇÃO INICIAL E SIDEBAR DE CONTROLES ---
 
107
  st.sidebar.markdown("Use os menus abaixo para navegar entre as análises e ajustar os parâmetros do projeto.")
108
  st.sidebar.divider()
109
 
110
+ pagina_selecionada = st.sidebar.radio("Menu de Navegação",
111
  ["🔎 Análise Exploratória (EDA)", "🎯 Simulação de Faturamento", "📊 Análise de Viabilidade"],
112
  captions=["Análise dos dados históricos", "Projeção de receitas via simulação", "Cálculos de VPL, TIR e Risco"]
113
  )
114
  st.sidebar.divider()
115
 
 
116
  with st.sidebar.expander("⚙️ Premissas Financeiras do Projeto", expanded=True):
 
117
  investimento_inicial = st.number_input("Investimento Inicial (R$)", min_value=1000.0, value=10000.0, step=1000.0)
 
 
118
  st.markdown("**Custos Fixos Mensais (R$)**")
119
+ custos_mensais_editaveis = {custo: st.number_input(custo.replace("_", " "), value=valor, step=50, key=custo) for custo, valor in custos_mensais_iniciais.items()}
 
 
 
 
120
  custos_operacionais_anuais = sum(custos_mensais_editaveis.values()) * 12
121
  st.info(f"Custo Anual Calculado: **{formatar_brl(custos_operacionais_anuais)}**")
 
122
  horizonte_projeto = st.slider("Horizonte do Projeto (anos)", 3, 20, 10)
123
  taxa_desconto = st.slider("Taxa de Desconto (TMA) (%)", 5.0, 25.0, 12.0, 0.5) / 100
124
  taxa_crescimento = st.slider("Crescimento Anual (Receitas/Custos) (%)", 0.0, 10.0, 3.0, 0.5) / 100
125
  taxa_reinvestimento = st.slider("Taxa de Reinvestimento (MTIR) (%)", 2.0, 18.0, 10.0, 0.5) / 100
126
 
127
  with st.sidebar.expander("📈 Preços e Cenários de Simulação", expanded=False):
128
+ # Alteração 2.3: Novo controle mestre de eficiência
129
+ eficiencia_coleta_geral = st.slider("Eficiência Geral da Coleta (%)", 0, 100, 60, help="Fator mestre que afeta a quantidade de material coletado em todos os cenários.") / 100
130
  st.markdown("**Preços dos Materiais (R$/kg)**")
131
  precos_editaveis = {material: st.number_input(f"{material.replace('_', ' ')}", value=preco, step=0.1, key=f"preco_{material}") for material, preco in precos_iniciais.items()}
132
+ st.markdown("**Fatores de Variação de Cenário**")
 
 
133
  fator_pessimista = st.slider("Cenário Pessimista (%)", 0, 100, 60) / 100
134
  fator_otimista = st.slider("Cenário Otimista (%)", 100, 200, 115) / 100
135
 
 
137
  st.sidebar.info(f"Última atualização: {pd.Timestamp.now(tz='America/Sao_Paulo').strftime('%d/%m/%Y %H:%M')}")
138
 
139
 
140
+ # --- 6. LÓGICA DE RENDERIZAÇÃO DAS PÁGINAS ---
 
 
 
141
  if pagina_selecionada == "🔎 Análise Exploratória (EDA)":
142
+ # ... (código desta página não precisa de alteração)
143
  st.title("🔎 Análise Exploratória dos Dados de Coleta")
144
  st.markdown("O primeiro passo para qualquer projeção é entender o passado. Aqui, exploramos os dados históricos de coleta para identificar padrões, sazonalidades e anomalias.")
145
  st.divider()
 
161
  st.plotly_chart(fig_boxplot, use_container_width=True)
162
  st.info("O **gráfico de linhas** mostra a tendência e sazonalidade ao longo do ano. O **boxplot** revela a volatilidade de cada material: caixas mais 'altas' indicam maior variação mensal, o que se traduz em maior risco e incerteza no faturamento.")
163
 
164
+
165
  elif pagina_selecionada == "🎯 Simulação de Faturamento":
166
  st.title("🎯 Simulação e Projeção de Faturamento Anual")
167
+ st.markdown("Utilizando a técnica de bootstrapping, simulamos 2.000 possíveis anos de faturamento com base na volatilidade dos dados de 2024 e na eficiência de coleta definida.")
168
  st.divider()
169
 
170
  cenarios = {'Pessimista': fator_pessimista, 'Base': 1.0, 'Otimista': fator_otimista}
171
+ # Alteração 2.4: Passa o novo fator de eficiência para a função
172
+ simulacoes_faturamento = simular_faturamento_bootstrap(df_2024_numeric, precos_editaveis, cenarios, eficiencia_coleta_geral)
173
 
174
  kpi1, kpi2, kpi3 = st.columns(3)
175
  media_faturamento_base = np.mean(simulacoes_faturamento['Base'])
176
+ desvio_padrao_base = np.std(simulacoes_faturamento['Base']) # Alteração 1.1: Calcula o desvio padrão
177
+ faturamento_material_base = {m: df_2024_numeric[m].sum() * p * eficiencia_coleta_geral for m, p in precos_editaveis.items()}
178
  material_mais_rentavel = max(faturamento_material_base, key=faturamento_material_base.get)
179
 
180
  kpi1.metric("Faturamento Anual Médio (Base)", formatar_brl(media_faturamento_base))
181
+ # Alteração 1.2: Substitui o intervalo pelo desvio padrão
182
+ kpi2.metric("Desvio Padrão do Faturamento", formatar_brl(desvio_padrao_base), help="Mede a volatilidade ou risco do faturamento. Valores mais altos indicam maior incerteza.")
183
  kpi3.metric("Material Mais Rentável (Base 2024)", material_mais_rentavel.replace('_', ' '))
184
  st.divider()
185
 
 
202
  st.markdown("Esta é a etapa final, onde combinamos as projeções de receita com as premissas de investimento e custos para avaliar a viabilidade do projeto sob a ótica do risco.")
203
 
204
  cenarios = {'Pessimista': fator_pessimista, 'Base': 1.0, 'Otimista': fator_otimista}
205
+ simulacoes_faturamento = simular_faturamento_bootstrap(df_2024_numeric, precos_editaveis, cenarios, eficiencia_coleta_geral)
206
 
207
  cenario_analise = st.radio("Selecione o cenário para a análise detalhada:", options=list(cenarios.keys()), index=1, horizontal=True)
208
  st.divider()
 
229
  st.subheader("Visualização do Fluxo de Caixa do Projeto")
230
  df_fluxo = pd.DataFrame({'Ano': list(range(horizonte_projeto + 1)), 'Fluxo de Caixa': fluxo_caixa_projeto})
231
  df_fluxo['Fluxo Acumulado'] = df_fluxo['Fluxo de Caixa'].cumsum()
232
+ fig_fluxo = go.Figure(data=[go.Bar(name='Fluxo Anual', x=df_fluxo['Ano'], y=df_fluxo['Fluxo de Caixa'], marker_color=['#d62728' if x < 0 else '#2ca02c' for x in df_fluxo['Fluxo de Caixa']]), go.Scatter(name='Fluxo Acumulado', x=df_fluxo['Ano'], y=df_fluxo['Fluxo Acumulado'], mode='lines+markers')])
 
 
 
233
  fig_fluxo.update_layout(title_text="Fluxo de Caixa Anual e Acumulado", hovermode='x unified')
234
  st.plotly_chart(fig_fluxo, use_container_width=True)
235
 
 
240
 
241
  prob_viabilidade = (np.array(vpls_mc) >= 0).mean()
242
  vpl_medio_mc = np.mean(vpls_mc)
243
+ vpl_std_mc = np.std(vpls_mc) # Alteração 1.3: Calcula o desvio padrão do VPL
244
 
245
  mc1, mc2, mc3 = st.columns(3)
246
  mc1.metric("VPL Médio Simulado", formatar_brl(vpl_medio_mc))
247
  mc2.metric("Probabilidade de Viabilidade", formatar_percentual(prob_viabilidade))
248
+ # Alteração 1.4: Substitui o intervalo pelo desvio padrão
249
+ mc3.metric("Desvio Padrão do VPL", formatar_brl(vpl_std_mc), help="Mede a volatilidade ou risco do VPL. Valores mais altos indicam maior incerteza.")
250
 
251
  fig_mc = px.histogram(x=vpls_mc, nbins=50, title=f"Distribuição do VPL ({len(vpls_mc)} Simulações)")
252
  fig_mc.add_vline(x=0, line_dash="dash", line_color="red", annotation_text="Viabilidade")
 
257
  conclusoes = []
258
  if vpl >= 0: conclusoes.append(f"✅ **Projeto VIÁVEL** no cenário '{cenario_analise}', com um VPL de **{formatar_brl(vpl)}**.")
259
  else: conclusoes.append(f"❌ **Projeto INVIÁVEL** no cenário '{cenario_analise}', com um VPL de **{formatar_brl(vpl)}**.")
 
260
  if not pd.isna(tir) and tir > taxa_desconto: conclusoes.append(f"✅ A **TIR de {formatar_percentual(tir)} é superior à TMA de {formatar_percentual(taxa_desconto)}**, reforçando a atratividade.")
261
  else: conclusoes.append(f"❌ A **TIR de {formatar_percentual(tir)} é inferior à TMA**, um forte indicador contra o investimento.")
 
262
  if prob_viabilidade > 0.75: conclusoes.append(f"✅ A simulação de Monte Carlo aponta uma **alta probabilidade de sucesso de {formatar_percentual(prob_viabilidade)}**.")
263
  elif prob_viabilidade > 0.5: conclusoes.append(f"⚠️ A probabilidade de sucesso de **{formatar_percentual(prob_viabilidade)} é moderada**.")
264
  else: conclusoes.append(f"❌ A probabilidade de sucesso de **{formatar_percentual(prob_viabilidade)} é baixa**, indicando risco elevado.")
 
265
  st.markdown("#### Conclusões Chave:")
266
  for c in conclusoes: st.markdown(f"- {c}")
 
267
  st.markdown("#### Parecer Final:")
268
  if vpl > 0 and prob_viabilidade > 0.7:
269
  st.success("**RECOMENDAÇÃO: APROVAR O PROJETO.** Os indicadores são fortemente positivos e a análise de risco confere robustez à decisão.")