Tulitula commited on
Commit
54bd91f
·
verified ·
1 Parent(s): 3f96b28

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +6 -14
app.py CHANGED
@@ -360,24 +360,17 @@ def suggest_one_per_band(synth: pd.DataFrame, sigma_mkt: float, universe_user: L
360
  for band in ["Low", "Medium", "High"]:
361
  lo, hi = _band_bounds(sigma_mkt, band)
362
  pool = synth[(synth["sigma_hist"] >= lo) & (synth["sigma_hist"] <= hi)].copy()
363
- note = ""
364
  if pool.empty:
365
- # Closest-available logic to keep band meaning intuitive
366
  if band.lower() == "low":
367
  pool = synth.nsmallest(50, "sigma_hist").copy()
368
- note = " (closest available: min σ)"
369
  elif band.lower() == "high":
370
  pool = synth.nlargest(50, "sigma_hist").copy()
371
- note = " (closest available: max σ)"
372
  else: # medium
373
  tmp = synth.copy()
374
  tmp["dist_med"] = (tmp["sigma_hist"] - sigma_mkt).abs()
375
  pool = tmp.nsmallest(100, "dist_med").drop(columns=["dist_med"])
376
- note = " (closest to market σ)"
377
  chosen = rerank_and_pick_one(pool, universe_user, band)
378
- if not chosen.empty:
379
- chosen = chosen.copy()
380
- chosen["__note__"] = note
381
  out[band.lower()] = chosen
382
  return out
383
 
@@ -517,8 +510,7 @@ def compute(
517
  def _fmt(row: pd.Series) -> str:
518
  if row is None or row.empty:
519
  return "No pick available."
520
- note = str(row.get("__note__", "") or "")
521
- return f"CAPM E[r] {row['mu_capm']*100:.2f}%, σ(h) {row['sigma_hist']*100:.2f}%{note}"
522
 
523
  txt_low = _fmt(picks.get("low", pd.Series(dtype=object)))
524
  txt_med = _fmt(picks.get("medium", pd.Series(dtype=object)))
@@ -553,7 +545,7 @@ def compute(
553
  sugg_sigma_hist=chosen_sigma, sugg_mu_capm=chosen_mu
554
  )
555
 
556
- # ---------- ONLY EXPLANATION ADDED BELOW (no calc changes) ----------
557
  info = "\n".join([
558
  "### Inputs",
559
  f"- Lookback years {years_lookback}",
@@ -562,7 +554,7 @@ def compute(
562
  f"- Market ERP {erp_ann:.2%}",
563
  f"- Market σ (hist) {sigma_mkt:.2%}",
564
  "",
565
- "### Your portfolio (CAPM on CML; x=σ_hist, y=CAPM E[r])",
566
  f"- CAPM E[r] {mu_capm:.2%}",
567
  f"- σ (historical) {sigma_hist:.2%}",
568
  "",
@@ -603,7 +595,7 @@ with gr.Blocks(title="Efficient Portfolio Advisor") as demo:
603
  search_btn = gr.Button("Search")
604
  add_btn = gr.Button("Add selected to portfolio")
605
 
606
- gr.Markdown("### Portfolio positions (enter $ amounts; negatives allowed)")
607
  table = gr.Dataframe(
608
  headers=["ticker", "amount_usd"],
609
  datatype=["str", "number"],
@@ -614,7 +606,7 @@ with gr.Blocks(title="Efficient Portfolio Advisor") as demo:
614
  horizon = gr.Number(label="Horizon in years (1–100)", value=HORIZON_YEARS, precision=0)
615
  lookback = gr.Slider(1, 15, value=DEFAULT_LOOKBACK_YEARS, step=1, label="Lookback years for betas & covariances")
616
 
617
- gr.Markdown("### Suggestions (one per band)")
618
  with gr.Row():
619
  btn_low = gr.Button("Show Low")
620
  btn_med = gr.Button("Show Medium")
 
360
  for band in ["Low", "Medium", "High"]:
361
  lo, hi = _band_bounds(sigma_mkt, band)
362
  pool = synth[(synth["sigma_hist"] >= lo) & (synth["sigma_hist"] <= hi)].copy()
 
363
  if pool.empty:
364
+ # choose reasonable substitutes quietly (no extra text)
365
  if band.lower() == "low":
366
  pool = synth.nsmallest(50, "sigma_hist").copy()
 
367
  elif band.lower() == "high":
368
  pool = synth.nlargest(50, "sigma_hist").copy()
 
369
  else: # medium
370
  tmp = synth.copy()
371
  tmp["dist_med"] = (tmp["sigma_hist"] - sigma_mkt).abs()
372
  pool = tmp.nsmallest(100, "dist_med").drop(columns=["dist_med"])
 
373
  chosen = rerank_and_pick_one(pool, universe_user, band)
 
 
 
374
  out[band.lower()] = chosen
375
  return out
376
 
 
510
  def _fmt(row: pd.Series) -> str:
511
  if row is None or row.empty:
512
  return "No pick available."
513
+ return f"CAPM E[r] {row['mu_capm']*100:.2f}%, σ(h) {row['sigma_hist']*100:.2f}%"
 
514
 
515
  txt_low = _fmt(picks.get("low", pd.Series(dtype=object)))
516
  txt_med = _fmt(picks.get("medium", pd.Series(dtype=object)))
 
545
  sugg_sigma_hist=chosen_sigma, sugg_mu_capm=chosen_mu
546
  )
547
 
548
+ # ---------- summary text (cosmetic-only changes made) ----------
549
  info = "\n".join([
550
  "### Inputs",
551
  f"- Lookback years {years_lookback}",
 
554
  f"- Market ERP {erp_ann:.2%}",
555
  f"- Market σ (hist) {sigma_mkt:.2%}",
556
  "",
557
+ "### Your portfolio",
558
  f"- CAPM E[r] {mu_capm:.2%}",
559
  f"- σ (historical) {sigma_hist:.2%}",
560
  "",
 
595
  search_btn = gr.Button("Search")
596
  add_btn = gr.Button("Add selected to portfolio")
597
 
598
+ gr.Markdown("### Portfolio positions")
599
  table = gr.Dataframe(
600
  headers=["ticker", "amount_usd"],
601
  datatype=["str", "number"],
 
606
  horizon = gr.Number(label="Horizon in years (1–100)", value=HORIZON_YEARS, precision=0)
607
  lookback = gr.Slider(1, 15, value=DEFAULT_LOOKBACK_YEARS, step=1, label="Lookback years for betas & covariances")
608
 
609
+ gr.Markdown("### Suggestions")
610
  with gr.Row():
611
  btn_low = gr.Button("Show Low")
612
  btn_med = gr.Button("Show Medium")