Tulitula commited on
Commit
c83ef19
·
verified ·
1 Parent(s): e056211

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +31 -18
app.py CHANGED
@@ -449,7 +449,6 @@ def compute(
449
  pick_band_to_show: str, # "Low" | "Medium" | "High"
450
  progress=gr.Progress(track_tqdm=True),
451
  ):
452
- # progress UI
453
  progress(0.03, desc="Validating tickers...")
454
 
455
  # sanitize table
@@ -490,7 +489,6 @@ def compute(
490
  moms = estimate_all_moments_aligned(symbols, years_lookback, rf_ann)
491
  betas, covA, erp_ann, sigma_mkt = moms["betas"], moms["cov_ann"], moms["erp_ann"], moms["sigma_m_ann"]
492
 
493
- # Weights
494
  gross = sum(abs(v) for v in amounts.values())
495
  if gross <= 1e-12:
496
  return (
@@ -588,17 +586,12 @@ def compute(
588
  # -------------- UI --------------
589
  with gr.Blocks(
590
  title="Efficient Portfolio Advisor",
591
- css="""
592
- /* make the left column occupy full width until results are visible */
593
- """
594
  ) as demo:
595
  gr.Markdown(
596
  "## Efficient Portfolio Advisor\n"
597
  "Search symbols, enter **dollar amounts**, set horizon. Returns use Yahoo Finance monthly data; risk-free from FRED."
598
  )
599
 
600
- # Two-column layout, but right column hidden initially.
601
- # When right column is hidden, the left column visually fills the page.
602
  with gr.Row():
603
  with gr.Column(scale=5) as left_col:
604
  # --- Vertical flow: Search -> Button -> Matches -> Add ---
@@ -607,7 +600,6 @@ with gr.Blocks(
607
  search_note = gr.Markdown()
608
  matches = gr.Dropdown(choices=[], label="Matches")
609
  add_btn = gr.Button("Add selected to portfolio")
610
- # ----------------------------------------------------------
611
 
612
  gr.Markdown("### Portfolio positions")
613
  table = gr.Dataframe(
@@ -620,6 +612,9 @@ with gr.Blocks(
620
  horizon = gr.Number(label="Horizon in years (1–100)", value=HORIZON_YEARS, precision=0)
621
  lookback = gr.Slider(1, 15, value=DEFAULT_LOOKBACK_YEARS, step=1, label="Lookback years for betas & covariances")
622
 
 
 
 
623
  # Compute button directly under lookback slider
624
  run_btn = gr.Button("Compute (build dataset & suggest)")
625
 
@@ -663,8 +658,19 @@ with gr.Blocks(
663
  table.change(fn=lock_ticker_column, inputs=table, outputs=table)
664
  horizon.change(fn=set_horizon, inputs=horizon, outputs=[])
665
 
666
- # Compute (default to Medium band) shows built-in progress bar
667
- compute_evt = run_btn.click(
 
 
 
 
 
 
 
 
 
 
 
668
  fn=compute,
669
  inputs=[lookback, table, gr.State("Medium")],
670
  outputs=[
@@ -672,25 +678,27 @@ with gr.Blocks(
672
  low_txt, med_txt, high_txt,
673
  gr.State(), gr.State(), gr.State(), gr.State(), gr.State(), gr.State(), gr.State(),
674
  gr.State(), gr.State()
675
- ]
 
676
  )
677
 
678
- # After compute finishes, reveal all results + Suggestions UI + right column
679
  def _reveal():
680
  up = gr.update(visible=True)
681
  return (up, up, up, up, up, up, up, up, up, up, up, up, up)
682
 
683
- compute_evt.then(
684
  _reveal,
685
  inputs=[],
686
  outputs=[
687
- right_col, # show right column (so layout "shrinks" to two columns)
688
  plot, summary, positions, sugg_table, dl,
689
  sugg_hdr, btn_low, btn_med, btn_high, low_txt, med_txt, high_txt
690
  ]
691
  )
692
 
693
- # Band buttons (work once they’re revealed)
 
 
694
  btn_low.click(
695
  fn=compute,
696
  inputs=[lookback, table, gr.State("Low")],
@@ -699,7 +707,8 @@ with gr.Blocks(
699
  low_txt, med_txt, high_txt,
700
  gr.State(), gr.State(), gr.State(), gr.State(), gr.State(), gr.State(), gr.State(),
701
  gr.State(), gr.State()
702
- ]
 
703
  )
704
  btn_med.click(
705
  fn=compute,
@@ -709,7 +718,8 @@ with gr.Blocks(
709
  low_txt, med_txt, high_txt,
710
  gr.State(), gr.State(), gr.State(), gr.State(), gr.State(), gr.State(), gr.State(),
711
  gr.State(), gr.State()
712
- ]
 
713
  )
714
  btn_high.click(
715
  fn=compute,
@@ -719,7 +729,8 @@ with gr.Blocks(
719
  low_txt, med_txt, high_txt,
720
  gr.State(), gr.State(), gr.State(), gr.State(), gr.State(), gr.State(), gr.State(),
721
  gr.State(), gr.State()
722
- ]
 
723
  )
724
 
725
  # initialize risk-free at launch
@@ -727,4 +738,6 @@ RF_CODE = fred_series_for_horizon(HORIZON_YEARS)
727
  RF_ANN = fetch_fred_yield_annual(RF_CODE)
728
 
729
  if __name__ == "__main__":
 
 
730
  demo.launch(server_name="0.0.0.0", server_port=7860, show_api=False)
 
449
  pick_band_to_show: str, # "Low" | "Medium" | "High"
450
  progress=gr.Progress(track_tqdm=True),
451
  ):
 
452
  progress(0.03, desc="Validating tickers...")
453
 
454
  # sanitize table
 
489
  moms = estimate_all_moments_aligned(symbols, years_lookback, rf_ann)
490
  betas, covA, erp_ann, sigma_mkt = moms["betas"], moms["cov_ann"], moms["erp_ann"], moms["sigma_m_ann"]
491
 
 
492
  gross = sum(abs(v) for v in amounts.values())
493
  if gross <= 1e-12:
494
  return (
 
586
  # -------------- UI --------------
587
  with gr.Blocks(
588
  title="Efficient Portfolio Advisor",
 
 
 
589
  ) as demo:
590
  gr.Markdown(
591
  "## Efficient Portfolio Advisor\n"
592
  "Search symbols, enter **dollar amounts**, set horizon. Returns use Yahoo Finance monthly data; risk-free from FRED."
593
  )
594
 
 
 
595
  with gr.Row():
596
  with gr.Column(scale=5) as left_col:
597
  # --- Vertical flow: Search -> Button -> Matches -> Add ---
 
600
  search_note = gr.Markdown()
601
  matches = gr.Dropdown(choices=[], label="Matches")
602
  add_btn = gr.Button("Add selected to portfolio")
 
603
 
604
  gr.Markdown("### Portfolio positions")
605
  table = gr.Dataframe(
 
612
  horizon = gr.Number(label="Horizon in years (1–100)", value=HORIZON_YEARS, precision=0)
613
  lookback = gr.Slider(1, 15, value=DEFAULT_LOOKBACK_YEARS, step=1, label="Lookback years for betas & covariances")
614
 
615
+ # Loading banner (appears instantly on click, hidden after results show)
616
+ loading_md = gr.Markdown("⏳ Working... fetching data and computing suggestions...", visible=False)
617
+
618
  # Compute button directly under lookback slider
619
  run_btn = gr.Button("Compute (build dataset & suggest)")
620
 
 
658
  table.change(fn=lock_ticker_column, inputs=table, outputs=table)
659
  horizon.change(fn=set_horizon, inputs=horizon, outputs=[])
660
 
661
+ # Small helpers to toggle the loading banner
662
+ def _show_loading():
663
+ return gr.update(visible=True)
664
+ def _hide_loading():
665
+ return gr.update(visible=False)
666
+
667
+ # 1) Show loading immediately
668
+ # 2) Run compute (with full-page progress bar)
669
+ # 3) Reveal results and suggestion controls
670
+ # 4) Hide loading banner
671
+ show_evt = run_btn.click(_show_loading, inputs=[], outputs=[loading_md])
672
+
673
+ compute_evt = show_evt.then(
674
  fn=compute,
675
  inputs=[lookback, table, gr.State("Medium")],
676
  outputs=[
 
678
  low_txt, med_txt, high_txt,
679
  gr.State(), gr.State(), gr.State(), gr.State(), gr.State(), gr.State(), gr.State(),
680
  gr.State(), gr.State()
681
+ ],
682
+ show_progress="full", # <-- full-page progress overlay
683
  )
684
 
 
685
  def _reveal():
686
  up = gr.update(visible=True)
687
  return (up, up, up, up, up, up, up, up, up, up, up, up, up)
688
 
689
+ after_compute = compute_evt.then(
690
  _reveal,
691
  inputs=[],
692
  outputs=[
693
+ right_col,
694
  plot, summary, positions, sugg_table, dl,
695
  sugg_hdr, btn_low, btn_med, btn_high, low_txt, med_txt, high_txt
696
  ]
697
  )
698
 
699
+ after_compute.then(_hide_loading, inputs=[], outputs=[loading_md])
700
+
701
+ # Band buttons (after reveal). Also request full progress overlay.
702
  btn_low.click(
703
  fn=compute,
704
  inputs=[lookback, table, gr.State("Low")],
 
707
  low_txt, med_txt, high_txt,
708
  gr.State(), gr.State(), gr.State(), gr.State(), gr.State(), gr.State(), gr.State(),
709
  gr.State(), gr.State()
710
+ ],
711
+ show_progress="full",
712
  )
713
  btn_med.click(
714
  fn=compute,
 
718
  low_txt, med_txt, high_txt,
719
  gr.State(), gr.State(), gr.State(), gr.State(), gr.State(), gr.State(), gr.State(),
720
  gr.State(), gr.State()
721
+ ],
722
+ show_progress="full",
723
  )
724
  btn_high.click(
725
  fn=compute,
 
729
  low_txt, med_txt, high_txt,
730
  gr.State(), gr.State(), gr.State(), gr.State(), gr.State(), gr.State(), gr.State(),
731
  gr.State(), gr.State()
732
+ ],
733
+ show_progress="full",
734
  )
735
 
736
  # initialize risk-free at launch
 
738
  RF_ANN = fetch_fred_yield_annual(RF_CODE)
739
 
740
  if __name__ == "__main__":
741
+ # enable event queue so progress bar + async UI updates work properly
742
+ demo.queue()
743
  demo.launch(server_name="0.0.0.0", server_port=7860, show_api=False)