60 lines
2.0 KiB
Python
60 lines
2.0 KiB
Python
"""Stress Tests tab — bank run sweep."""
|
|
|
|
import streamlit as st
|
|
|
|
from src.composed.simulator import scenario_bank_run
|
|
from dashboard.charts import fig_bank_run_sweep
|
|
|
|
|
|
def render():
|
|
st.header("Stress Tests")
|
|
|
|
config = st.session_state.get("myco_config")
|
|
n_assets = config.n_reserve_assets if config else 3
|
|
|
|
col1, col2 = st.columns(2)
|
|
with col1:
|
|
fractions_str = st.text_input(
|
|
"Redemption fractions (comma-separated)",
|
|
"0.02, 0.05, 0.10, 0.20",
|
|
)
|
|
with col2:
|
|
initial_reserve = st.number_input(
|
|
"Initial reserve ($)", 10_000, 1_000_000, 100_000, step=10_000,
|
|
)
|
|
|
|
st.caption(f"Using **{n_assets}** reserve assets from System Config.")
|
|
|
|
if st.button("Run Stress Test", key="stress_run"):
|
|
fractions = [float(f.strip()) for f in fractions_str.split(",")]
|
|
results = {}
|
|
|
|
progress = st.progress(0)
|
|
for i, frac in enumerate(fractions):
|
|
with st.spinner(f"Running {frac:.0%} redemption..."):
|
|
results[frac] = scenario_bank_run(
|
|
initial_reserve=float(initial_reserve),
|
|
n_assets=n_assets,
|
|
redemption_fraction=frac,
|
|
)
|
|
progress.progress((i + 1) / len(fractions))
|
|
|
|
st.session_state["stress_results"] = results
|
|
|
|
if "stress_results" in st.session_state:
|
|
results = st.session_state["stress_results"]
|
|
|
|
# Summary table
|
|
cols = st.columns(len(results))
|
|
for i, (frac, result) in enumerate(results.items()):
|
|
final_ratio = result.backing_ratio[-1]
|
|
with cols[i]:
|
|
st.metric(
|
|
f"{frac:.0%} Redemption",
|
|
f"Backing: {final_ratio:.4f}",
|
|
delta="Survived" if final_ratio > 0.5 else "Failed",
|
|
delta_color="normal" if final_ratio > 0.5 else "inverse",
|
|
)
|
|
|
|
st.plotly_chart(fig_bank_run_sweep(results), use_container_width=True)
|