codelion commited on
Commit
785660b
Β·
verified Β·
1 Parent(s): c54e392

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +15 -10
app.py CHANGED
@@ -20,8 +20,12 @@ TICKERS = [
20
 
21
  def optimize_portfolio(years, target_return):
22
  try:
23
- data = yf.download(TICKERS, period=f"{years}y", interval="1mo")['Adj Close']
24
- returns = data.pct_change().dropna()
 
 
 
 
25
  mean_returns = returns.mean() * 12
26
  cov_matrix = returns.cov() * 12
27
 
@@ -47,7 +51,7 @@ def optimize_portfolio(years, target_return):
47
  )
48
 
49
  if not result.success:
50
- return "Optimization failed. Try adjusting inputs.", None, None, None
51
 
52
  weights = result.x
53
  port_return = weights @ mean_returns
@@ -60,14 +64,14 @@ def optimize_portfolio(years, target_return):
60
  "Weight (%)": np.round(weights * 100, 2)
61
  }).sort_values("Weight (%)", ascending=False).reset_index(drop=True)
62
 
63
- return df, f"{port_return*100:.2f}%", f"{port_vol*100:.2f}%", f"{sharpe_ratio:.2f}"
64
 
65
  except Exception as e:
66
- return f"Error: {str(e)}", None, None, None
67
 
68
  with gr.Blocks() as demo:
69
  gr.Markdown("# πŸ“ˆ Modern Portfolio Optimizer (MPT)")
70
- gr.Markdown("Select number of years of historical data and your target annual return. This app computes the **minimum risk portfolio** of 25 S&P 500 stocks.")
71
 
72
  with gr.Row():
73
  years_slider = gr.Slider(1, 10, value=5, step=1, label="Years of Historical Data")
@@ -76,14 +80,15 @@ with gr.Blocks() as demo:
76
  run_button = gr.Button("Optimize Portfolio")
77
 
78
  output_table = gr.Dataframe(headers=["Ticker", "Weight (%)"], label="Optimal Allocation")
79
- ret_text = gr.Text(label="Expected Return")
80
- vol_text = gr.Text(label="Expected Volatility")
81
- sharpe_text = gr.Text(label="Sharpe Ratio")
 
82
 
83
  run_button.click(
84
  fn=lambda years, target: optimize_portfolio(years, target / 100),
85
  inputs=[years_slider, return_slider],
86
- outputs=[output_table, ret_text, vol_text, sharpe_text]
87
  )
88
 
89
  demo.launch()
 
20
 
21
  def optimize_portfolio(years, target_return):
22
  try:
23
+ data = yf.download(TICKERS, period=f"{years}y", interval="1mo")
24
+ if "Adj Close" not in data:
25
+ return pd.DataFrame(), "Error: 'Adj Close' column missing.", "", ""
26
+
27
+ prices = data['Adj Close']
28
+ returns = prices.pct_change().dropna()
29
  mean_returns = returns.mean() * 12
30
  cov_matrix = returns.cov() * 12
31
 
 
51
  )
52
 
53
  if not result.success:
54
+ return pd.DataFrame(), "Optimization failed. Try adjusting inputs.", "", ""
55
 
56
  weights = result.x
57
  port_return = weights @ mean_returns
 
64
  "Weight (%)": np.round(weights * 100, 2)
65
  }).sort_values("Weight (%)", ascending=False).reset_index(drop=True)
66
 
67
+ return df, "", f"{port_return*100:.2f}%", f"{port_vol*100:.2f}%", f"{sharpe_ratio:.2f}"
68
 
69
  except Exception as e:
70
+ return pd.DataFrame(), f"Error: {str(e)}", "", "", ""
71
 
72
  with gr.Blocks() as demo:
73
  gr.Markdown("# πŸ“ˆ Modern Portfolio Optimizer (MPT)")
74
+ gr.Markdown("Optimize a portfolio of 25 S&P 500 stocks for **minimum risk** and a **5% annual return target**.")
75
 
76
  with gr.Row():
77
  years_slider = gr.Slider(1, 10, value=5, step=1, label="Years of Historical Data")
 
80
  run_button = gr.Button("Optimize Portfolio")
81
 
82
  output_table = gr.Dataframe(headers=["Ticker", "Weight (%)"], label="Optimal Allocation")
83
+ error_box = gr.Textbox(label="Message", lines=1)
84
+ ret_text = gr.Textbox(label="Expected Return")
85
+ vol_text = gr.Textbox(label="Expected Volatility")
86
+ sharpe_text = gr.Textbox(label="Sharpe Ratio")
87
 
88
  run_button.click(
89
  fn=lambda years, target: optimize_portfolio(years, target / 100),
90
  inputs=[years_slider, return_slider],
91
+ outputs=[output_table, error_box, ret_text, vol_text, sharpe_text]
92
  )
93
 
94
  demo.launch()