feat(DATA-004): add underlying instrument selector
This commit is contained in:
@@ -86,9 +86,10 @@ async def _resolve_hedge_spot(workspace_id: str | None = None) -> tuple[dict[str
|
||||
|
||||
try:
|
||||
data_service = get_data_service()
|
||||
quote = await data_service.get_quote(data_service.default_symbol)
|
||||
underlying = config.underlying or "GLD"
|
||||
quote = await data_service.get_quote(underlying)
|
||||
spot, source, updated_at = resolve_portfolio_spot_from_quote(
|
||||
config, quote, fallback_symbol=data_service.default_symbol
|
||||
config, quote, fallback_symbol=underlying
|
||||
)
|
||||
portfolio = portfolio_snapshot(config, runtime_spot_price=spot)
|
||||
return portfolio, source, updated_at
|
||||
@@ -120,12 +121,25 @@ async def _render_hedge_page(workspace_id: str | None = None) -> None:
|
||||
)
|
||||
updated_label = f"Quote timestamp: {quote_updated_at}" if quote_updated_at else "Quote timestamp: unavailable"
|
||||
|
||||
# Get underlying for display
|
||||
underlying = "GLD"
|
||||
if workspace_id:
|
||||
try:
|
||||
repo = get_workspace_repository()
|
||||
config = repo.load_portfolio_config(workspace_id)
|
||||
underlying = config.underlying or "GLD"
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
with dashboard_page(
|
||||
"Hedge Analysis",
|
||||
"Compare hedge structures across scenarios, visualize cost-benefit tradeoffs, and inspect net equity impacts.",
|
||||
f"Compare hedge structures across scenarios, visualize cost-benefit tradeoffs, and inspect net equity impacts for {underlying}.",
|
||||
"hedge",
|
||||
workspace_id=workspace_id,
|
||||
):
|
||||
with ui.row().classes("w-full items-center justify-between gap-4 max-md:flex-col max-md:items-start"):
|
||||
ui.label(f"Active underlying: {underlying}").classes("text-sm text-slate-500 dark:text-slate-400")
|
||||
|
||||
left_pane, right_pane = split_page_panes(
|
||||
left_testid="hedge-left-pane",
|
||||
right_testid="hedge-right-pane",
|
||||
|
||||
@@ -141,7 +141,8 @@ async def overview_page(workspace_id: str) -> None:
|
||||
|
||||
config = repo.load_portfolio_config(workspace_id)
|
||||
data_service = get_data_service()
|
||||
symbol = data_service.default_symbol
|
||||
underlying = config.underlying or "GLD"
|
||||
symbol = underlying
|
||||
quote = await data_service.get_quote(symbol)
|
||||
overview_spot_price, overview_source, overview_updated_at = _resolve_overview_spot(
|
||||
config, quote, fallback_symbol=symbol
|
||||
@@ -199,14 +200,14 @@ async def overview_page(workspace_id: str) -> None:
|
||||
|
||||
with dashboard_page(
|
||||
"Overview",
|
||||
"Portfolio health, LTV risk, and quick strategy guidance for the current GLD-backed loan.",
|
||||
f"Portfolio health, LTV risk, and quick strategy guidance for the current {underlying}-backed loan.",
|
||||
"overview",
|
||||
workspace_id=workspace_id,
|
||||
):
|
||||
with ui.row().classes("w-full items-center justify-between gap-4 max-md:flex-col max-md:items-start"):
|
||||
ui.label(quote_status).classes("text-sm text-slate-500 dark:text-slate-400")
|
||||
ui.label(
|
||||
f"Configured collateral baseline: ${config.gold_value:,.0f} · Loan ${config.loan_amount:,.0f}"
|
||||
f"Active underlying: {underlying} · Configured collateral baseline: ${config.gold_value:,.0f} · Loan ${config.loan_amount:,.0f}"
|
||||
).classes("text-sm text-slate-500 dark:text-slate-400")
|
||||
|
||||
left_pane, right_pane = split_page_panes(
|
||||
|
||||
@@ -121,6 +121,7 @@ def settings_page(workspace_id: str) -> None:
|
||||
primary_source=str(primary_source.value),
|
||||
fallback_source=str(fallback_source.value),
|
||||
refresh_interval=parsed_refresh_interval,
|
||||
underlying=str(underlying.value),
|
||||
volatility_spike=float(vol_alert.value),
|
||||
spot_drawdown=float(price_alert.value),
|
||||
email_alerts=bool(email_alerts.value),
|
||||
@@ -244,6 +245,14 @@ def settings_page(workspace_id: str) -> None:
|
||||
"w-full rounded-2xl border border-slate-200 bg-white shadow-sm dark:border-slate-800 dark:bg-slate-900"
|
||||
):
|
||||
ui.label("Data Sources").classes("text-lg font-semibold text-slate-900 dark:text-slate-100")
|
||||
underlying = ui.select(
|
||||
{
|
||||
"GLD": "SPDR Gold Shares ETF (live data via yfinance)",
|
||||
"GC=F": "Gold Futures (coming soon)",
|
||||
},
|
||||
value=config.underlying,
|
||||
label="Underlying instrument",
|
||||
).classes("w-full")
|
||||
primary_source = ui.select(
|
||||
["yfinance", "ibkr", "alpaca"],
|
||||
value=config.primary_source,
|
||||
|
||||
Reference in New Issue
Block a user