# app_npv_timeline.py # ------------------------------------------------------------- # Herramienta interactiva para calcular el Valor Presente Neto # (NPV) de un proyecto a partir de flujos de caja anuales. # ------------------------------------------------------------- import streamlit as st import numpy as np # 1. CONFIGURACIÓN BÁSICA DE LA PÁGINA st.set_page_config(page_title="Calculadora de NPV", layout="wide") # 2. ENCABEZADO st.title("Calculadora de Valor Presente Neto (NPV)") # 3. ENTRADAS PRINCIPALES # 3.1 Tasa de descuento con slider (0 % – 50 %) discount_rate_pct = st.slider( "Selecciona la tasa de descuento (%)", min_value=0.0, max_value=50.0, value=10.0, step=0.1, help="Costo de oportunidad o rendimiento mínimo aceptable." ) discount_rate = discount_rate_pct / 100 # Convertir a proporción # 3.2 Duración del proyecto en años years = st.slider( "¿Cuántos años dura el proyecto?", min_value=1, max_value=30, value=5, step=1 ) st.markdown("---") # 4. CAPTURA DE FLUJOS DE CAJA MEDIANTE TIMELINE st.subheader("Ingresa los flujos de caja anuales") with st.form("cashflow_form", clear_on_submit=False): # Usamos columnas para generar un "timeline" con recuadros cols = st.columns(years + 1) # +1 porque suele haber flujo en t=0 cashflows = [] for t in range(years + 1): with cols[t]: cf = st.number_input( f"Año {t}", value=0.0, key=f"cf_{t}", format="%.2f" ) cashflows.append(cf) submitted = st.form_submit_button("Calcular NPV") # 5. CÁLCULO DEL NPV if submitted: npv = sum(cf / (1 + discount_rate) ** t for t, cf in enumerate(cashflows)) st.markdown("## Resultado") st.metric(label="Valor Presente Neto (NPV)", value=f"${npv:,.2f}") # 6. VISUALIZACIÓN DEL TIMELINE CON ESTILO st.markdown("### Timeline de Flujos de Caja") timeline_cols = st.columns(years + 1) for t, col in enumerate(timeline_cols): with col: st.markdown( f"""
Año {t}
${cashflows[t]:,.2f}
""", unsafe_allow_html=True ) # 7. INTERPRETACIÓN BÁSICA if npv > 0: st.success("El proyecto genera valor (NPV positivo).") elif npv < 0: st.error("El proyecto destruye valor (NPV negativo).") else: st.info("El proyecto es neutro (NPV = 0).")