VicMata commited on
Commit
54e7bf2
·
verified ·
1 Parent(s): 837880e

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +68 -48
app.py CHANGED
@@ -58,7 +58,7 @@ st.title("Calculadora de VaR y CVaR con Gemini y Yahoo Finance")
58
 
59
  empresa_input = st.text_input("Escribe los nombres de las empresas separadas por coma (ej. Apple, Google, Meta):")
60
 
61
- # ✅ Selector de fecha desde el calendario
62
  fecha_inicio = st.date_input(
63
  "Selecciona la fecha de inicio para los históricos:",
64
  value=datetime.date(datetime.datetime.today().year, 1, 2),
@@ -66,58 +66,78 @@ fecha_inicio = st.date_input(
66
  max_value=datetime.date.today()
67
  )
68
 
69
- confidence_level = st.selectbox("Nivel de confianza:", [0.95, 0.99])
 
 
 
 
 
 
 
 
70
 
71
- if st.button("Calcular VaR y CVaR") and empresa_input:
72
  tickers = obtener_tickers_desde_nombres(empresa_input)
73
 
74
  if len(tickers) < 2:
75
  st.warning("Se requieren al menos dos tickers válidos.")
 
76
  else:
77
  st.success(f"Tickers detectados: {', '.join(tickers)}")
78
 
79
- weights = np.array([1 / len(tickers)] * len(tickers))
80
-
81
- start_date = fecha_inicio.strftime("%Y-%m-%d")
82
- end_date = datetime.datetime.today().strftime("%Y-%m-%d")
83
-
84
- data = yf.download(tickers, start=start_date, end=end_date)["Close"]
85
- data = data.dropna()
86
- returns = data.pct_change().dropna()
87
- portfolio_returns = returns.dot(weights)
88
-
89
- tail_prob = 1 - confidence_level
90
- historical_VaR = np.percentile(portfolio_returns, tail_prob * 100)
91
- mean_ret = portfolio_returns.mean()
92
- std_ret = portfolio_returns.std()
93
- z_score = norm.ppf(tail_prob)
94
- parametric_VaR = mean_ret + z_score * std_ret
95
- simulated_returns = np.random.normal(mean_ret, std_ret, 10000)
96
- mc_VaR = np.percentile(simulated_returns, tail_prob * 100)
97
- historical_CVaR = portfolio_returns[portfolio_returns <= historical_VaR].mean()
98
-
99
- st.subheader("Resultados:")
100
- st.markdown(f"**Historical VaR:** {historical_VaR:.4%}")
101
- st.markdown(f"**Parametric VaR:** {parametric_VaR:.4%}")
102
- st.markdown(f"**Monte Carlo VaR:** {mc_VaR:.4%}")
103
- st.markdown(f"**Historical CVaR:** {historical_CVaR:.4%}")
104
-
105
- # Gráfico 1: Histograma
106
- fig1, ax1 = plt.subplots(figsize=(10, 6))
107
- ax1.hist(portfolio_returns, bins=50, density=True, alpha=0.5)
108
- ax1.axvline(historical_VaR, color="red", linestyle="--", label="Historical VaR")
109
- ax1.axvline(parametric_VaR, color="blue", linestyle="--", label="Parametric VaR")
110
- ax1.axvline(mc_VaR, color="green", linestyle="--", label="Monte Carlo VaR")
111
- ax1.set_title("Distribución de Retornos del Portafolio")
112
- ax1.legend()
113
- st.pyplot(fig1)
114
-
115
- # Gráfico 2: Serie de tiempo
116
- fig2, ax2 = plt.subplots(figsize=(10, 6))
117
- ax2.plot(portfolio_returns.index, portfolio_returns, color="purple", label="Portfolio Returns")
118
- ax2.axhline(historical_VaR, color="red", linestyle="--", label="Historical VaR")
119
- ax2.axhline(parametric_VaR, color="blue", linestyle="--", label="Parametric VaR")
120
- ax2.axhline(mc_VaR, color="green", linestyle="--", label="Monte Carlo VaR")
121
- ax2.set_title("Serie de tiempo de los retornos del portafolio")
122
- ax2.legend()
123
- st.pyplot(fig2)
 
 
 
 
 
 
 
 
 
 
 
 
58
 
59
  empresa_input = st.text_input("Escribe los nombres de las empresas separadas por coma (ej. Apple, Google, Meta):")
60
 
61
+ # ✅ Calendario para seleccionar fecha de inicio
62
  fecha_inicio = st.date_input(
63
  "Selecciona la fecha de inicio para los históricos:",
64
  value=datetime.date(datetime.datetime.today().year, 1, 2),
 
66
  max_value=datetime.date.today()
67
  )
68
 
69
+ # Slider para el nivel de confianza
70
+ confidence_percent = st.slider(
71
+ "Nivel de confianza (%) [valores recomendados: 95% o 99%]",
72
+ min_value=90,
73
+ max_value=99,
74
+ value=95,
75
+ step=1
76
+ )
77
+ confidence_level = confidence_percent / 100
78
 
79
+ if st.button("Identificar Tickers") and empresa_input:
80
  tickers = obtener_tickers_desde_nombres(empresa_input)
81
 
82
  if len(tickers) < 2:
83
  st.warning("Se requieren al menos dos tickers válidos.")
84
+ st.stop()
85
  else:
86
  st.success(f"Tickers detectados: {', '.join(tickers)}")
87
 
88
+ st.subheader("Asignar pesos a cada activo (la suma debe ser 100%)")
89
+
90
+ weight_inputs = []
91
+ total_weight = 0
92
+
93
+ cols = st.columns(len(tickers))
94
+ for i, ticker in enumerate(tickers):
95
+ with cols[i]:
96
+ weight = st.number_input(
97
+ f"{ticker} (%)", min_value=0.0, max_value=100.0,
98
+ value=round(100 / len(tickers), 2), key=f"weight_{ticker}"
99
+ )
100
+ weight_inputs.append(weight)
101
+ total_weight += weight
102
+
103
+ if abs(total_weight - 100.0) > 0.01:
104
+ st.warning(f"⚠️ La suma de los pesos es {total_weight:.2f}%. Debe ser exactamente 100%.")
105
+ st.stop()
106
+
107
+ # ✅ Convertimos los pesos a proporciones (0-1)
108
+ weights = np.array(weight_inputs) / 100
109
+
110
+ if st.button("Calcular VaR y CVaR"):
111
+ start_date = fecha_inicio.strftime("%Y-%m-%d")
112
+ end_date = datetime.datetime.today().strftime("%Y-%m-%d")
113
+
114
+ data = yf.download(tickers, start=start_date, end=end_date)["Close"]
115
+ data = data.dropna()
116
+ returns = data.pct_change().dropna()
117
+ portfolio_returns = returns.dot(weights)
118
+
119
+ tail_prob = 1 - confidence_level
120
+ historical_VaR = np.percentile(portfolio_returns, tail_prob * 100)
121
+ mean_ret = portfolio_returns.mean()
122
+ std_ret = portfolio_returns.std()
123
+ z_score = norm.ppf(tail_prob)
124
+ parametric_VaR = mean_ret + z_score * std_ret
125
+ simulated_returns = np.random.normal(mean_ret, std_ret, 10000)
126
+ mc_VaR = np.percentile(simulated_returns, tail_prob * 100)
127
+ historical_CVaR = portfolio_returns[portfolio_returns <= historical_VaR].mean()
128
+
129
+ st.subheader("Resultados del Portafolio:")
130
+ st.markdown(f"**Historical VaR:** {historical_VaR:.4%}")
131
+ st.markdown(f"**Parametric VaR:** {parametric_VaR:.4%}")
132
+ st.markdown(f"**Monte Carlo VaR:** {mc_VaR:.4%}")
133
+ st.markdown(f"**Historical CVaR (Expected Shortfall):** {historical_CVaR:.4%}")
134
+
135
+ # ✅ Gráfico: Histograma con líneas VaR
136
+ fig1, ax1 = plt.subplots(figsize=(10, 6))
137
+ ax1.hist(portfolio_returns, bins=50, density=True, alpha=0.5)
138
+ ax1.axvline(historical_VaR, color="red", linestyle="--", label="Historical VaR")
139
+ ax1.axvline(parametric_VaR, color="blue", linestyle="--", label="Parametric VaR")
140
+ ax1.axvline(mc_VaR, color="green", linestyle="--", label="Monte Carlo VaR")
141
+ ax1.set_title("Distribución de Retornos del Portafolio")
142
+ ax1.legend()
143
+ st.pyplot(fig1)