Spaces:
Sleeping
Sleeping
| # 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""" | |
| <div style='border:1px solid #999; border-radius:6px; | |
| padding:10px; text-align:center;'> | |
| <strong>Año {t}</strong><br> | |
| ${cashflows[t]:,.2f} | |
| </div> | |
| """, | |
| 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).") | |