# ================================================ # Dashboard Interativo - ROI e Simulação de Overbooking # ================================================ # Para rodar: streamlit run app.py # ================================================ import streamlit as st import numpy as np import pandas as pd import matplotlib.pyplot as plt # ========================== # Função para simulação binomial # ========================== def simulate_binomial_revenue(N, p, r, nsim=10000, random_seed=None): rng = np.random.default_rng(random_seed) X = rng.binomial(n=N, p=p, size=nsim) # número de sucessos return X * r # ========================== # Configurações iniciais do dashboard # ========================== st.set_page_config(page_title="Simulação ROI - Aérea Confiável", layout="wide") st.title("✈️ Simulação de ROI - Sistema de Previsão de Overbooking") st.markdown(""" Este dashboard simula diferentes cenários de desempenho do sistema de previsão da **Aérea Confiável**, permitindo analisar **risco** e **retorno esperado**. """) # ========================== # Sidebar - Entradas do usuário # ========================== st.sidebar.header("⚙️ Parâmetros da Simulação") # Entradas financeiras investimento_inicial = st.sidebar.number_input("Investimento Inicial (R$)", min_value=10000.0, value=50000.0, step=1000.0) receita_alvo = st.sidebar.number_input("Receita Alvo (R$)", min_value=10000.0, value=80000.0, step=1000.0) custo_operacional = st.sidebar.number_input("Custo Operacional Anual (R$)", min_value=0.0, value=10000.0, step=1000.0) # Entradas do modelo binomial N = st.sidebar.slider("Número de Oportunidades (N)", min_value=50, max_value=500, value=200, step=10) p0 = st.sidebar.slider("Probabilidade Base de Sucesso (p0)", min_value=0.05, max_value=0.95, value=0.40, step=0.01) # Ajuste de cenários delta = st.sidebar.slider("Variação da Probabilidade ±", min_value=0.05, max_value=0.30, value=0.15, step=0.01) # Simulações nsim = st.sidebar.slider("Número de Simulações", min_value=1000, max_value=50000, value=20000, step=1000) # Limite de receita mínima target_threshold = st.sidebar.number_input("Receita Mínima Desejada (R$)", min_value=0.0, value=60000.0, step=1000.0) st.sidebar.markdown("---") st.sidebar.info("Ajuste os parâmetros acima para explorar diferentes cenários.") # ========================== # Cálculo do ROI determinístico # ========================== lucro_investimento = receita_alvo - custo_operacional roi_deterministico = (lucro_investimento / investimento_inicial) * 100 st.subheader("📊 ROI Determinístico") st.metric(label="ROI (%)", value=f"{roi_deterministico:.2f}%") st.caption("ROI calculado apenas com os valores fixos, sem considerar incertezas.") # ========================== # Configuração dos cenários # ========================== cenarios = { "Pessimista": max(0.01, p0 - delta), "Real": p0, "Otimista": min(0.99, p0 + delta) } # Receita por sucesso r = receita_alvo / (N * p0) # ========================== # Simulação # ========================== sim_results = {} summary_rows = [] for nome, p in cenarios.items(): receita = simulate_binomial_revenue(N, p, r, nsim=nsim) sim_results[nome] = receita # Estatísticas media = receita.mean() mediana = np.median(receita) desvio = receita.std(ddof=1) prob_abaixo = (receita < target_threshold).mean() roi_sim = (receita - custo_operacional) / investimento_inicial * 100 media_roi = roi_sim.mean() prob_roi_negativo = (roi_sim < 0).mean() pct_10 = np.percentile(roi_sim, 10) pct_90 = np.percentile(roi_sim, 90) summary_rows.append({ "Cenário": nome, "p (Prob. Sucesso)": p, "Receita Média (R$)": media, "Mediana Receita (R$)": mediana, "Desvio Padrão (R$)": desvio, f"P(Receita < {target_threshold:,.0f})": prob_abaixo, "ROI Médio (%)": media_roi, "P(ROI < 0%)": prob_roi_negativo, "ROI 10%": pct_10, "ROI 90%": pct_90 }) summary_df = pd.DataFrame(summary_rows).set_index("Cenário") # ========================== # Exibir Tabela # ========================== st.subheader("📈 Resumo dos Cenários") st.dataframe(summary_df.style.format({ "Receita Média (R$)": "R$ {:,.2f}", "Mediana Receita (R$)": "R$ {:,.2f}", "Desvio Padrão (R$)": "R$ {:,.2f}", f"P(Receita < {target_threshold:,.0f})": "{:.2%}", "ROI Médio (%)": "{:.2f}%", "P(ROI < 0%)": "{:.2%}", "ROI 10%": "{:.2f}%", "ROI 90%": "{:.2f}%" })) # ========================== # Visualização - Gráficos # ========================== st.subheader("📊 Distribuição da Receita por Cenário") fig, ax = plt.subplots(figsize=(10,5)) for nome, receita in sim_results.items(): ax.hist(receita, bins=50, alpha=0.6, label=f"{nome} (p={cenarios[nome]:.2f})") ax.axvline(target_threshold, color='red', linestyle='--', label='Meta Receita' if nome=="Pessimista" else "") ax.set_title("Distribuição da Receita Anual") ax.set_xlabel("Receita (R$)") ax.set_ylabel("Frequência") ax.legend() ax.grid(True) st.pyplot(fig) # ROI Distribution st.subheader("📊 Distribuição do ROI por Cenário") fig2, ax2 = plt.subplots(figsize=(10,5)) for nome, receita in sim_results.items(): roi_sim = (receita - custo_operacional) / investimento_inicial * 100 ax2.hist(roi_sim, bins=60, alpha=0.5, label=f"{nome} (p={cenarios[nome]:.2f})", density=True) ax2.set_title("Distribuição do ROI (%)") ax2.set_xlabel("ROI (%)") ax2.set_ylabel("Densidade") ax2.legend() ax2.grid(True) st.pyplot(fig2) # ========================== # Conclusão baseada nos resultados # ========================== st.subheader("💡 Conclusões e Recomendações") st.markdown(f""" - **ROI determinístico:** {roi_deterministico:.2f}% - Cenário pessimista ainda mostra uma **probabilidade significativa de receita abaixo de R$ {target_threshold:,.0f}**, o que indica risco operacional. - No cenário otimista, o ROI médio ultrapassa 200%, com risco quase nulo de perdas. - A empresa deve considerar: - Ajustar políticas de overbooking por rota ou perfil de cliente. - Integrar dados em tempo real para reduzir variabilidade. - Explorar precificação dinâmica para maximizar receita. """)