Update app.py
Browse files
app.py
CHANGED
|
@@ -58,15 +58,21 @@ confidence_percent = st.slider(
|
|
| 58 |
)
|
| 59 |
confidence_level = confidence_percent / 100
|
| 60 |
|
|
|
|
| 61 |
if st.button("Identificar Tickers") and empresa_input:
|
| 62 |
tickers_detectados = obtener_tickers_desde_nombres(empresa_input)
|
| 63 |
if len(tickers_detectados) >= 2:
|
| 64 |
st.session_state["tickers"] = tickers_detectados
|
| 65 |
-
|
| 66 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
| 67 |
else:
|
| 68 |
st.warning("Se requieren al menos dos tickers v谩lidos.")
|
| 69 |
|
|
|
|
| 70 |
if "tickers" in st.session_state:
|
| 71 |
tickers = st.session_state["tickers"]
|
| 72 |
st.success(f"Tickers detectados: {', '.join(tickers)}")
|
|
@@ -100,13 +106,13 @@ if "tickers" in st.session_state:
|
|
| 100 |
st.warning("鈿狅笍 La suma de los pesos debe ser exactamente 100% para continuar.")
|
| 101 |
else:
|
| 102 |
if st.button("Calcular VaR y CVaR"):
|
| 103 |
-
weights = np.array(
|
| 104 |
start_date = fecha_inicio.strftime("%Y-%m-%d")
|
| 105 |
end_date = datetime.datetime.today().strftime("%Y-%m-%d")
|
| 106 |
data = yf.download(tickers, start=start_date, end=end_date)["Close"]
|
| 107 |
|
| 108 |
if data.empty or data.isnull().all().all():
|
| 109 |
-
st.error("No se encontraron datos hist贸ricos para la fecha seleccionada.
|
| 110 |
else:
|
| 111 |
data = data.dropna()
|
| 112 |
returns = data.pct_change().dropna()
|
|
@@ -138,24 +144,37 @@ if "tickers" in st.session_state:
|
|
| 138 |
x=portfolio_returns,
|
| 139 |
nbinsx=50,
|
| 140 |
marker_color='rgba(200,200,200,0.6)',
|
| 141 |
-
name="Retornos del portafolio"
|
|
|
|
| 142 |
))
|
| 143 |
|
| 144 |
-
# L铆neas
|
| 145 |
-
|
| 146 |
-
|
| 147 |
-
|
| 148 |
-
|
| 149 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 150 |
fig.update_layout(
|
| 151 |
title="Distribuci贸n de Retornos del Portafolio con l铆neas VaR",
|
| 152 |
xaxis_title="Retorno diario",
|
| 153 |
yaxis_title="Frecuencia",
|
| 154 |
-
legend=dict(orientation="h", yanchor="bottom", y=1.
|
| 155 |
plot_bgcolor='rgba(0,0,0,0)',
|
| 156 |
paper_bgcolor='rgba(0,0,0,0)',
|
| 157 |
font=dict(color='white', size=14),
|
| 158 |
-
margin=dict(t=60, l=40, r=40, b=40)
|
|
|
|
| 159 |
)
|
| 160 |
|
| 161 |
st.plotly_chart(fig, use_container_width=True)
|
|
|
|
| 58 |
)
|
| 59 |
confidence_level = confidence_percent / 100
|
| 60 |
|
| 61 |
+
# Bot贸n para detectar tickers
|
| 62 |
if st.button("Identificar Tickers") and empresa_input:
|
| 63 |
tickers_detectados = obtener_tickers_desde_nombres(empresa_input)
|
| 64 |
if len(tickers_detectados) >= 2:
|
| 65 |
st.session_state["tickers"] = tickers_detectados
|
| 66 |
+
# Distribuci贸n inicial corregida para sumar 100%
|
| 67 |
+
base = int(100 / len(tickers_detectados))
|
| 68 |
+
pesos = [base] * (len(tickers_detectados) - 1)
|
| 69 |
+
pesos.append(100 - sum(pesos)) # 脷ltimo ajustado
|
| 70 |
+
for i, ticker in enumerate(tickers_detectados):
|
| 71 |
+
st.session_state[f"weight_{ticker}"] = pesos[i]
|
| 72 |
else:
|
| 73 |
st.warning("Se requieren al menos dos tickers v谩lidos.")
|
| 74 |
|
| 75 |
+
# Si ya hay tickers, continuamos
|
| 76 |
if "tickers" in st.session_state:
|
| 77 |
tickers = st.session_state["tickers"]
|
| 78 |
st.success(f"Tickers detectados: {', '.join(tickers)}")
|
|
|
|
| 106 |
st.warning("鈿狅笍 La suma de los pesos debe ser exactamente 100% para continuar.")
|
| 107 |
else:
|
| 108 |
if st.button("Calcular VaR y CVaR"):
|
| 109 |
+
weights = np.array(weight_inputs) / 100
|
| 110 |
start_date = fecha_inicio.strftime("%Y-%m-%d")
|
| 111 |
end_date = datetime.datetime.today().strftime("%Y-%m-%d")
|
| 112 |
data = yf.download(tickers, start=start_date, end=end_date)["Close"]
|
| 113 |
|
| 114 |
if data.empty or data.isnull().all().all():
|
| 115 |
+
st.error("No se encontraron datos hist贸ricos para la fecha seleccionada.")
|
| 116 |
else:
|
| 117 |
data = data.dropna()
|
| 118 |
returns = data.pct_change().dropna()
|
|
|
|
| 144 |
x=portfolio_returns,
|
| 145 |
nbinsx=50,
|
| 146 |
marker_color='rgba(200,200,200,0.6)',
|
| 147 |
+
name="Retornos del portafolio",
|
| 148 |
+
hovertemplate="%{x:.2%}<extra>Retorno</extra>"
|
| 149 |
))
|
| 150 |
|
| 151 |
+
# L铆neas con leyenda usando go.Scatter
|
| 152 |
+
for val, color, label in zip(
|
| 153 |
+
[historical_VaR, parametric_VaR, mc_VaR],
|
| 154 |
+
["red", "blue", "green"],
|
| 155 |
+
["Historical VaR", "Parametric VaR", "Monte Carlo VaR"]
|
| 156 |
+
):
|
| 157 |
+
fig.add_trace(go.Scatter(
|
| 158 |
+
x=[val, val],
|
| 159 |
+
y=[0, 1],
|
| 160 |
+
mode="lines",
|
| 161 |
+
line=dict(color=color, dash="dash", width=2),
|
| 162 |
+
name=label,
|
| 163 |
+
hoverinfo="skip",
|
| 164 |
+
showlegend=True
|
| 165 |
+
))
|
| 166 |
+
|
| 167 |
+
# Layout
|
| 168 |
fig.update_layout(
|
| 169 |
title="Distribuci贸n de Retornos del Portafolio con l铆neas VaR",
|
| 170 |
xaxis_title="Retorno diario",
|
| 171 |
yaxis_title="Frecuencia",
|
| 172 |
+
legend=dict(orientation="h", yanchor="bottom", y=1.05, xanchor="right", x=1),
|
| 173 |
plot_bgcolor='rgba(0,0,0,0)',
|
| 174 |
paper_bgcolor='rgba(0,0,0,0)',
|
| 175 |
font=dict(color='white', size=14),
|
| 176 |
+
margin=dict(t=60, l=40, r=40, b=40),
|
| 177 |
+
height=500
|
| 178 |
)
|
| 179 |
|
| 180 |
st.plotly_chart(fig, use_container_width=True)
|