feat(BT-003B): add event comparison drilldown
This commit is contained in:
@@ -309,6 +309,8 @@ def _render_event_comparison_page(workspace_id: str | None = None) -> None:
|
||||
)
|
||||
render_selected_summary(entry_spot=float(scenario.initial_portfolio.entry_spot))
|
||||
chart_model = service.chart_model(report)
|
||||
drilldown_options = service.drilldown_options(report)
|
||||
initial_drilldown_slug = next(iter(drilldown_options), None)
|
||||
|
||||
with result_panel:
|
||||
with ui.card().classes(
|
||||
@@ -388,6 +390,132 @@ def _render_event_comparison_page(workspace_id: str | None = None) -> None:
|
||||
row_key="rank",
|
||||
).classes("w-full")
|
||||
|
||||
with ui.card().classes(
|
||||
"w-full rounded-2xl border border-slate-200 bg-white shadow-sm dark:border-slate-800 dark:bg-slate-900"
|
||||
):
|
||||
ui.label("Strategy Drilldown").classes("text-lg font-semibold text-slate-900 dark:text-slate-100")
|
||||
ui.label(
|
||||
"Select a ranked strategy to inspect margin-call pressure, payoff realization, and the full seeded daily path."
|
||||
).classes("text-sm text-slate-500 dark:text-slate-400")
|
||||
drilldown_select = ui.select(
|
||||
drilldown_options,
|
||||
value=initial_drilldown_slug,
|
||||
label="Strategy drilldown",
|
||||
).classes("w-full")
|
||||
drilldown_container = ui.column().classes("w-full gap-4")
|
||||
|
||||
def render_drilldown() -> None:
|
||||
drilldown_container.clear()
|
||||
if drilldown_select.value is None:
|
||||
return
|
||||
drilldown = service.drilldown_model(report, template_slug=str(drilldown_select.value))
|
||||
breach_dates = ", ".join(drilldown.breach_dates) if drilldown.breach_dates else "None"
|
||||
worst_ltv_point = (
|
||||
f"{drilldown.worst_ltv_date} · {drilldown.worst_ltv_hedged:.1%}"
|
||||
if drilldown.worst_ltv_date is not None
|
||||
else "Unavailable"
|
||||
)
|
||||
with drilldown_container:
|
||||
ui.label(f"Selected strategy: {drilldown.template_name}").classes(
|
||||
"text-lg font-semibold text-slate-900 dark:text-slate-100"
|
||||
)
|
||||
ui.label(
|
||||
f"Rank #{drilldown.rank} · {'Survived margin call' if drilldown.survived_margin_call else 'Breached margin threshold'}"
|
||||
).classes("text-sm text-slate-500 dark:text-slate-400")
|
||||
with ui.grid(columns=4).classes("w-full gap-4 max-lg:grid-cols-2 max-sm:grid-cols-1"):
|
||||
cards = [
|
||||
("Margin-call days", str(drilldown.margin_call_days_hedged)),
|
||||
("Payoff realized", f"${drilldown.total_option_payoff_realized:,.0f}"),
|
||||
("Hedge cost", f"${drilldown.hedge_cost:,.0f}"),
|
||||
("Final equity", f"${drilldown.final_equity:,.0f}"),
|
||||
]
|
||||
for label, value in cards:
|
||||
with ui.card().classes(
|
||||
"rounded-xl border border-slate-200 bg-slate-50 p-4 shadow-none dark:border-slate-800 dark:bg-slate-950"
|
||||
):
|
||||
ui.label(label).classes("text-sm text-slate-500 dark:text-slate-400")
|
||||
ui.label(value).classes("text-xl font-bold text-slate-900 dark:text-slate-100")
|
||||
with ui.grid(columns=2).classes("w-full gap-4 max-md:grid-cols-1"):
|
||||
with ui.card().classes(
|
||||
"rounded-xl border border-slate-200 bg-slate-50 p-4 shadow-none dark:border-slate-800 dark:bg-slate-950"
|
||||
):
|
||||
ui.label("Worst LTV point").classes("text-sm text-slate-500 dark:text-slate-400")
|
||||
ui.label(worst_ltv_point).classes(
|
||||
"text-xl font-bold text-slate-900 dark:text-slate-100"
|
||||
)
|
||||
with ui.card().classes(
|
||||
"rounded-xl border border-amber-200 bg-amber-50 p-4 shadow-none dark:border-amber-900/60 dark:bg-amber-950/30"
|
||||
):
|
||||
ui.label("Margin threshold breach dates").classes(
|
||||
"text-sm text-amber-700 dark:text-amber-300"
|
||||
)
|
||||
ui.label(breach_dates).classes(
|
||||
"text-base font-semibold text-amber-800 dark:text-amber-200"
|
||||
)
|
||||
with ui.card().classes(
|
||||
"w-full rounded-xl border border-slate-200 bg-slate-50 p-4 shadow-none dark:border-slate-800 dark:bg-slate-950"
|
||||
):
|
||||
ui.label("Daily path details").classes(
|
||||
"text-base font-semibold text-slate-900 dark:text-slate-100"
|
||||
)
|
||||
ui.table(
|
||||
columns=[
|
||||
{"name": "date", "label": "Date", "field": "date", "align": "left"},
|
||||
{
|
||||
"name": "spot_close",
|
||||
"label": "Spot",
|
||||
"field": "spot_close",
|
||||
"align": "right",
|
||||
},
|
||||
{
|
||||
"name": "net_portfolio_value",
|
||||
"label": "Net hedged",
|
||||
"field": "net_portfolio_value",
|
||||
"align": "right",
|
||||
},
|
||||
{
|
||||
"name": "option_market_value",
|
||||
"label": "Option value",
|
||||
"field": "option_market_value",
|
||||
"align": "right",
|
||||
},
|
||||
{
|
||||
"name": "realized_option_cashflow",
|
||||
"label": "Payoff realized",
|
||||
"field": "realized_option_cashflow",
|
||||
"align": "right",
|
||||
},
|
||||
{
|
||||
"name": "ltv_hedged",
|
||||
"label": "Hedged LTV",
|
||||
"field": "ltv_hedged",
|
||||
"align": "right",
|
||||
},
|
||||
{
|
||||
"name": "margin_call_hedged",
|
||||
"label": "Breach",
|
||||
"field": "margin_call_hedged",
|
||||
"align": "center",
|
||||
},
|
||||
],
|
||||
rows=[
|
||||
{
|
||||
"date": row.date,
|
||||
"spot_close": f"${row.spot_close:,.2f}",
|
||||
"net_portfolio_value": f"${row.net_portfolio_value:,.0f}",
|
||||
"option_market_value": f"${row.option_market_value:,.0f}",
|
||||
"realized_option_cashflow": f"${row.realized_option_cashflow:,.0f}",
|
||||
"ltv_hedged": f"{row.ltv_hedged:.1%}",
|
||||
"margin_call_hedged": "Yes" if row.margin_call_hedged else "No",
|
||||
}
|
||||
for row in drilldown.rows
|
||||
],
|
||||
row_key="date",
|
||||
).classes("w-full")
|
||||
|
||||
drilldown_select.on_value_change(lambda _: render_drilldown())
|
||||
render_drilldown()
|
||||
|
||||
with ui.card().classes(
|
||||
"w-full rounded-2xl border border-slate-200 bg-white shadow-sm dark:border-slate-800 dark:bg-slate-900"
|
||||
):
|
||||
|
||||
Reference in New Issue
Block a user