FernandezUNB commited on
Commit
29871a5
·
verified ·
1 Parent(s): 56942d9

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +170 -67
app.py CHANGED
@@ -1,9 +1,3 @@
1
- # app.py - Gradio Interface for Portfolio Analysis Visualization
2
- # This script creates a dynamic web interface using Gradio to visualize the key components
3
- # from the provided Jupyter notebook. It replicates the data fetching, calculations, and
4
- # visualizations, making them interactive where possible (e.g., selectable date ranges or tickers).
5
- # Deploy this on Hugging Face Spaces by creating a new Space, uploading this app.py, and requirements.txt.
6
-
7
  import gradio as gr
8
  import pandas as pd
9
  import yfinance as yf
@@ -16,6 +10,7 @@ from scipy import stats, optimize
16
  import warnings
17
  from io import BytesIO
18
  import base64
 
19
 
20
  warnings.filterwarnings("ignore")
21
 
@@ -23,29 +18,32 @@ warnings.filterwarnings("ignore")
23
  default_tickers = ['BBAS3.SA', 'ITSA4.SA', 'TAEE11.SA', 'TTEN3.SA', 'BPAC11.SA', '^BVSP']
24
  default_start_date = '2012-01-01'
25
  default_end_date = '2024-07-31'
26
- num_ports = 50000 # Monte Carlo simulations
27
  initial_investment = 35000
28
 
29
- # Function to fetch data (reusable)
30
  def fetch_data(tickers, start_date, end_date):
31
  acoes_df = pd.DataFrame()
32
  for acao in tickers:
33
- acoes_df[acao] = yf.download(acao, start=start_date, end=end_date)['Close']
 
 
 
34
  acoes_df.index = acoes_df.index.strftime('%Y-%m-%d')
35
  acoes_df.reset_index(inplace=True)
36
  acoes_df.rename(columns={'index': 'Date'}, inplace=True)
37
  return acoes_df
38
 
39
- # Function for Historical Prices Plot (Plotly)
40
  def plot_historical_prices(acoes_df):
41
  acoes_viz = acoes_df.copy()
42
- figura = px.line(title='Histórico do preço das ações')
43
  for i in acoes_viz.columns[1:]:
44
  figura.add_scatter(x=acoes_viz["Date"], y=acoes_viz[i], name=i)
45
  figura.update_layout(xaxis_title="Data", yaxis_title="Preço (R$)", hovermode='x unified')
46
  return figura
47
 
48
- # Function for Returns Calculation and Plot
49
  def calculate_and_plot_returns(acoes_df):
50
  dataset = acoes_df.copy()
51
  dataset.drop(labels=['Date'], axis=1, inplace=True)
@@ -54,29 +52,25 @@ def calculate_and_plot_returns(acoes_df):
54
  taxas_retorno = pd.concat([date, taxas_retorno], axis=1)
55
  taxas_retorno = taxas_retorno.dropna()
56
 
57
- # Historical Returns Plot
58
- figura = px.line(title='Histórico de retorno das ações')
59
  for i in taxas_retorno.columns[1:]:
60
  figura.add_scatter(x=taxas_retorno["Date"], y=taxas_retorno[i], name=i)
61
  figura.update_layout(xaxis_title="Data", yaxis_title="Retorno Logarítmico", hovermode='x unified')
62
 
63
- # Stats as text
64
  stats = taxas_retorno.describe().to_html()
65
-
66
  return figura, stats
67
 
68
- # Function for Correlation Matrix (Plotly Heatmap)
69
  def plot_correlation_matrix(taxas_retorno):
70
  correlacao_cols = taxas_retorno.select_dtypes(include=[np.number]).columns
71
  correlacao = taxas_retorno[correlacao_cols].corr()
72
  correlacao = np.round(correlacao, 2)
73
-
74
  custom_colorscale = [[0.0, 'green'], [0.5, 'blue'], [1.0, 'red']]
75
  fig = px.imshow(correlacao, text_auto=True, aspect="auto", color_continuous_scale=custom_colorscale,
76
  labels=dict(color="Correlações"), zmin=-1, zmax=1, title="Matriz de Correlação dos Retornos")
77
  return fig
78
 
79
- # Function for Efficient Frontier (Matplotlib -> Image in Gradio)
80
  def simulate_efficient_frontier(acoes_df, num_ports):
81
  acoes_port = acoes_df.copy()
82
  acoes_port.drop(labels=['^BVSP'], axis=1, inplace=True)
@@ -99,101 +93,210 @@ def simulate_efficient_frontier(acoes_df, num_ports):
99
  vol_arr[x] = np.sqrt(np.dot(weights.T, np.dot(log_ret.cov(), weights)))
100
  sharpe_arr[x] = ret_arr[x] / vol_arr[x]
101
 
102
- # Plot Efficient Frontier
 
 
 
103
  fig, ax = plt.subplots(figsize=(12, 8))
104
  ax.scatter(vol_arr, ret_arr, c=sharpe_arr, cmap='viridis')
 
105
  ax.set_xlabel('Volatilidade')
106
  ax.set_ylabel('Retorno')
107
  ax.set_title('Fronteira Eficiente - Simulação Monte Carlo')
 
108
  ax.grid(True, alpha=0.3)
109
-
110
- # Convert to image for Gradio
111
  buf = BytesIO()
112
  fig.savefig(buf, format="png")
113
  buf.seek(0)
114
  img_base64 = base64.b64encode(buf.read()).decode('utf-8')
115
  plt.close(fig)
116
- return f'<img src="data:image/png;base64,{img_base64}">'
117
-
118
- # Function for Portfolio Simulation and Plots
119
- def simulate_portfolio(acoes_df, initial_investment):
120
- # Similar to notebook's simulation (simplified)
121
- # ... (Implement the simular_portfolio_simples function from the notebook)
122
- # For brevity, assume we return the figures as Plotly
123
- # Placeholder: Return dummy plots
124
- fig_evolution = px.line(title='Evolução do Patrimônio')
125
- fig_returns = px.line(title='Retornos Diários')
126
- return fig_evolution, fig_returns
127
-
128
- # Function for VaR Analysis and Plots
129
- def analyze_var(acoes_df):
130
- # ... (Implement VaR calculations and plots from notebook)
131
- # Placeholder: Return Matplotlib as image
132
- fig, ax = plt.subplots(figsize=(12, 6))
133
- ax.set_title('VaR Analysis')
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
134
  buf = BytesIO()
135
- fig.savefig(buf, format="png")
136
  buf.seek(0)
137
  img_base64 = base64.b64encode(buf.read()).decode('utf-8')
138
  plt.close(fig)
139
- return f'<img src="data:image/png;base64,{img_base64}">'
140
 
141
- # Main Gradio Function: Run all and display in tabs
 
 
 
 
 
 
 
 
 
 
 
142
  def run_analysis(tickers_str, start_date, end_date, num_simulations, investment):
143
- tickers = [t.strip() for t in tickers_str.split(',')]
144
- acoes_df = fetch_data(tickers, start_date, end_date)
145
-
146
- prices_plot = plot_historical_prices(acoes_df)
147
- returns_plot, stats = calculate_and_plot_returns(acoes_df)
148
- corr_plot = plot_correlation_matrix(pd.concat([acoes_df['Date'], np.log(acoes_df.drop('Date', axis=1) / acoes_df.drop('Date', axis=1).shift(1))], axis=1).dropna())
149
- frontier_img = simulate_efficient_frontier(acoes_df, num_simulations)
150
- port_evo, port_ret = simulate_portfolio(acoes_df, investment)
151
- var_img = analyze_var(acoes_df)
152
-
153
- return prices_plot, returns_plot, corr_plot, frontier_img, port_evo, port_ret, var_img, stats
 
 
 
 
 
 
 
154
 
155
  # Gradio Interface
156
  with gr.Blocks(title="Portfolio Analysis Dashboard") as demo:
157
  gr.Markdown("# Portfolio Theory Visualization Dashboard")
158
- gr.Markdown("Dynamic visualizations from your Colab notebook. Customize inputs and explore.")
159
-
160
  with gr.Row():
161
  tickers_input = gr.Textbox(label="Tickers (comma-separated)", value=','.join(default_tickers))
162
  start_date = gr.Textbox(label="Start Date (YYYY-MM-DD)", value=default_start_date)
163
  end_date = gr.Textbox(label="End Date (YYYY-MM-DD)", value=default_end_date)
164
  num_sim = gr.Number(label="Number of Simulations", value=num_ports)
165
  investment = gr.Number(label="Initial Investment (R$)", value=initial_investment)
166
-
167
  run_btn = gr.Button("Run Analysis")
168
-
169
  with gr.Tab("Historical Prices"):
170
  prices_output = gr.Plot()
171
-
172
  with gr.Tab("Returns History"):
173
  returns_output = gr.Plot()
174
-
175
  with gr.Tab("Correlation Matrix"):
176
  corr_output = gr.Plot()
177
-
178
  with gr.Tab("Efficient Frontier"):
179
  frontier_output = gr.HTML()
180
-
181
  with gr.Tab("Portfolio Evolution"):
182
  port_evo_output = gr.Plot()
183
-
184
  with gr.Tab("Daily Returns"):
185
  port_ret_output = gr.Plot()
186
-
187
  with gr.Tab("VaR Analysis"):
188
  var_output = gr.HTML()
189
-
190
  with gr.Tab("Statistics"):
191
  stats_output = gr.HTML()
192
-
193
  run_btn.click(
194
  run_analysis,
195
  inputs=[tickers_input, start_date, end_date, num_sim, investment],
196
  outputs=[prices_output, returns_output, corr_output, frontier_output, port_evo_output, port_ret_output, var_output, stats_output]
197
  )
198
 
199
- demo.launch()
 
 
 
 
 
 
 
 
1
  import gradio as gr
2
  import pandas as pd
3
  import yfinance as yf
 
10
  import warnings
11
  from io import BytesIO
12
  import base64
13
+ from datetime import datetime
14
 
15
  warnings.filterwarnings("ignore")
16
 
 
18
  default_tickers = ['BBAS3.SA', 'ITSA4.SA', 'TAEE11.SA', 'TTEN3.SA', 'BPAC11.SA', '^BVSP']
19
  default_start_date = '2012-01-01'
20
  default_end_date = '2024-07-31'
21
+ num_ports = 50000
22
  initial_investment = 35000
23
 
24
+ # Fetch data
25
  def fetch_data(tickers, start_date, end_date):
26
  acoes_df = pd.DataFrame()
27
  for acao in tickers:
28
+ try:
29
+ acoes_df[acao] = yf.download(acao, start=start_date, end=end_date, progress=False)['Close']
30
+ except Exception as e:
31
+ print(f"Error downloading {acao}: {e}")
32
  acoes_df.index = acoes_df.index.strftime('%Y-%m-%d')
33
  acoes_df.reset_index(inplace=True)
34
  acoes_df.rename(columns={'index': 'Date'}, inplace=True)
35
  return acoes_df
36
 
37
+ # Historical Prices Plot
38
  def plot_historical_prices(acoes_df):
39
  acoes_viz = acoes_df.copy()
40
+ figura = px.line(title='Histórico do Preço das Ações')
41
  for i in acoes_viz.columns[1:]:
42
  figura.add_scatter(x=acoes_viz["Date"], y=acoes_viz[i], name=i)
43
  figura.update_layout(xaxis_title="Data", yaxis_title="Preço (R$)", hovermode='x unified')
44
  return figura
45
 
46
+ # Returns Calculation and Plot
47
  def calculate_and_plot_returns(acoes_df):
48
  dataset = acoes_df.copy()
49
  dataset.drop(labels=['Date'], axis=1, inplace=True)
 
52
  taxas_retorno = pd.concat([date, taxas_retorno], axis=1)
53
  taxas_retorno = taxas_retorno.dropna()
54
 
55
+ figura = px.line(title='Histórico de Retorno das Ações')
 
56
  for i in taxas_retorno.columns[1:]:
57
  figura.add_scatter(x=taxas_retorno["Date"], y=taxas_retorno[i], name=i)
58
  figura.update_layout(xaxis_title="Data", yaxis_title="Retorno Logarítmico", hovermode='x unified')
59
 
 
60
  stats = taxas_retorno.describe().to_html()
 
61
  return figura, stats
62
 
63
+ # Correlation Matrix
64
  def plot_correlation_matrix(taxas_retorno):
65
  correlacao_cols = taxas_retorno.select_dtypes(include=[np.number]).columns
66
  correlacao = taxas_retorno[correlacao_cols].corr()
67
  correlacao = np.round(correlacao, 2)
 
68
  custom_colorscale = [[0.0, 'green'], [0.5, 'blue'], [1.0, 'red']]
69
  fig = px.imshow(correlacao, text_auto=True, aspect="auto", color_continuous_scale=custom_colorscale,
70
  labels=dict(color="Correlações"), zmin=-1, zmax=1, title="Matriz de Correlação dos Retornos")
71
  return fig
72
 
73
+ # Efficient Frontier
74
  def simulate_efficient_frontier(acoes_df, num_ports):
75
  acoes_port = acoes_df.copy()
76
  acoes_port.drop(labels=['^BVSP'], axis=1, inplace=True)
 
93
  vol_arr[x] = np.sqrt(np.dot(weights.T, np.dot(log_ret.cov(), weights)))
94
  sharpe_arr[x] = ret_arr[x] / vol_arr[x]
95
 
96
+ melhores_pesos = all_weights[sharpe_arr.argmax(), :]
97
+ max_sr_vol = vol_arr[sharpe_arr.argmax()]
98
+ max_sr_ret = ret_arr[sharpe_arr.argmax()]
99
+
100
  fig, ax = plt.subplots(figsize=(12, 8))
101
  ax.scatter(vol_arr, ret_arr, c=sharpe_arr, cmap='viridis')
102
+ ax.scatter(max_sr_vol, max_sr_ret, c='red', s=200, marker='*', label='Carteira Ótima')
103
  ax.set_xlabel('Volatilidade')
104
  ax.set_ylabel('Retorno')
105
  ax.set_title('Fronteira Eficiente - Simulação Monte Carlo')
106
+ ax.legend()
107
  ax.grid(True, alpha=0.3)
 
 
108
  buf = BytesIO()
109
  fig.savefig(buf, format="png")
110
  buf.seek(0)
111
  img_base64 = base64.b64encode(buf.read()).decode('utf-8')
112
  plt.close(fig)
113
+ return f'<img src="data:image/png;base64,{img_base64}">', melhores_pesos
114
+
115
+ # Portfolio Simulation
116
+ def simulate_portfolio(acoes_df, initial_investment, melhores_pesos):
117
+ dados_sim = acoes_df.copy()
118
+ if '^BVSP' in dados_sim.columns:
119
+ dados_sim = dados_sim.drop(columns=['^BVSP'])
120
+ datas = dados_sim['Date'].copy()
121
+ precos = dados_sim.drop(columns=['Date']).copy()
122
+
123
+ for col in precos.columns:
124
+ precos[col] = pd.to_numeric(precos[col], errors='coerce')
125
+ precos = precos.dropna()
126
+ datas = datas.iloc[:len(precos)].reset_index(drop=True)
127
+ precos = precos.reset_index(drop=True)
128
+
129
+ precos_norm = precos.copy()
130
+ for col in precos_norm.columns:
131
+ precos_norm[col] = precos_norm[col] / precos_norm[col].iloc[0]
132
+
133
+ portfolio_valores = pd.DataFrame()
134
+ portfolio_valores['Data'] = datas
135
+ nomes_ativos = ['BBAS3.SA', 'ITSA4.SA', 'TAEE11.SA', 'TTEN3.SA', 'BPAC11.SA']
136
+
137
+ for i, ativo in enumerate(nomes_ativos):
138
+ if ativo in precos_norm.columns:
139
+ portfolio_valores[ativo] = precos_norm[ativo] * melhores_pesos[i] * initial_investment
140
+
141
+ colunas_ativos = [col for col in portfolio_valores.columns if col != 'Data']
142
+ portfolio_valores['Valor_Total'] = portfolio_valores[colunas_ativos].sum(axis=1)
143
+ portfolio_valores['Retorno_Diario'] = 0.0
144
+
145
+ for i in range(1, len(portfolio_valores)):
146
+ valor_hoje = portfolio_valores['Valor_Total'].iloc[i]
147
+ valor_ontem = portfolio_valores['Valor_Total'].iloc[i-1]
148
+ if valor_ontem > 0:
149
+ portfolio_valores['Retorno_Diario'].iloc[i] = np.log(valor_hoje / valor_ontem) * 100
150
+
151
+ # Portfolio Evolution Plot
152
+ fig_evo = px.line(x=portfolio_valores['Data'], y=portfolio_valores['Valor_Total'],
153
+ title='Evolução do Patrimônio da Carteira',
154
+ labels={'x': 'Data', 'y': 'Valor (R$)'})
155
+ fig_evo.add_hline(y=portfolio_valores['Valor_Total'].mean(), line_color="green", line_dash="dot",
156
+ annotation_text="Valor Médio")
157
+ fig_evo.add_hline(y=initial_investment, line_color="red", line_dash="dot",
158
+ annotation_text=f"Investimento Inicial (R$ {initial_investment:,.0f})")
159
+
160
+ # Daily Returns Plot
161
+ fig_ret = px.line(x=portfolio_valores['Data'], y=portfolio_valores['Retorno_Diario'],
162
+ title='Retorno Diário do Portfólio',
163
+ labels={'x': 'Data', 'y': 'Retorno (%)'})
164
+ media_retorno = portfolio_valores['Retorno_Diario'].mean()
165
+ fig_ret.add_hline(y=media_retorno, line_color="red", line_dash="dot",
166
+ annotation_text=f"Retorno Médio: {media_retorno:.3f}%")
167
+
168
+ valor_final = portfolio_valores['Valor_Total'].iloc[-1]
169
+ return fig_evo, fig_ret, portfolio_valores, valor_final
170
+
171
+ # VaR Analysis
172
+ def analyze_var(portfolio_resultado, valor_final):
173
+ retornos_portfolio = portfolio_resultado['Retorno_Diario'].copy()[1:].dropna()
174
+
175
+ def calcular_var_historico(retornos, confianca):
176
+ percentil = (1 - confianca) * 100
177
+ return np.percentile(retornos, percentil)
178
+
179
+ var_95_historico = calcular_var_historico(retornos_portfolio, 0.95)
180
+ var_99_historico = calcular_var_historico(retornos_portfolio, 0.99)
181
+ var_95_money = valor_final * (np.exp(var_95_historico/100) - 1)
182
+ var_99_money = valor_final * (np.exp(var_99_historico/100) - 1)
183
+
184
+ def var_monte_carlo(retornos, num_simulacoes=10000, confianca=0.95):
185
+ np.random.seed(42)
186
+ media = retornos.mean()
187
+ desvio = retornos.std()
188
+ simulacoes = np.random.normal(media, desvio, num_simulacoes)
189
+ percentil = (1 - confianca) * 100
190
+ var_mc = np.percentile(simulacoes, percentil)
191
+ return var_mc, simulacoes
192
+
193
+ var_mc_95, simulacoes_95 = var_monte_carlo(retornos_portfolio, confianca=0.95)
194
+ var_mc_99, simulacoes_99 = var_monte_carlo(retornos_portfolio, confianca=0.99)
195
+ var_mc_95_money = valor_final * (np.exp(var_mc_95/100) - 1)
196
+ var_mc_99_money = valor_final * (np.exp(var_mc_99/100) - 1)
197
+
198
+ # VaR Plot
199
+ fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(15, 6))
200
+ ax1.hist(retornos_portfolio, bins=50, alpha=0.7, color='skyblue', edgecolor='black', density=True)
201
+ ax1.axvline(var_95_historico, color='orange', linestyle='--', label=f'VaR 95%: {var_95_historico:.2f}%')
202
+ ax1.axvline(var_99_historico, color='red', linestyle='--', label=f'VaR 99%: {var_99_historico:.2f}%')
203
+ ax1.set_xlabel('Retorno Diário (%)')
204
+ ax1.set_ylabel('Densidade')
205
+ ax1.set_title('Distribuição dos Retornos Históricos\ncom VaR Histórico')
206
+ ax1.legend()
207
+ ax1.grid(True, alpha=0.3)
208
+
209
+ ax2.hist(simulacoes_95, bins=50, alpha=0.7, color='lightgreen', edgecolor='black', density=True)
210
+ ax2.axvline(var_mc_95, color='orange', linestyle='--', label=f'VaR MC 95%: {var_mc_95:.2f}%')
211
+ ax2.axvline(var_mc_99, color='red', linestyle='--', label=f'VaR MC 99%: {var_mc_99:.2f}%')
212
+ ax2.set_xlabel('Retorno Diário (%)')
213
+ ax2.set_ylabel('Densidade')
214
+ ax2.set_title('Distribuição Simulada (Monte Carlo)\ncom VaR Paramétrico')
215
+ ax2.legend()
216
+ ax2.grid(True, alpha=0.3)
217
+ plt.tight_layout()
218
+
219
  buf = BytesIO()
220
+ fig.savefig(buf, format="png", dpi=300)
221
  buf.seek(0)
222
  img_base64 = base64.b64encode(buf.read()).decode('utf-8')
223
  plt.close(fig)
 
224
 
225
+ # VaR Summary
226
+ var_summary = f"""
227
+ <h3>Resumo do VaR</h3>
228
+ <table border='1'>
229
+ <tr><th>Método</th><th>VaR 95% (1 dia)</th><th>VaR 99% (1 dia)</th></tr>
230
+ <tr><td>Histórico</td><td>{var_95_historico:.2f}% (R$ {abs(var_95_money):,.2f})</td><td>{var_99_historico:.2f}% (R$ {abs(var_99_money):,.2f})</td></tr>
231
+ <tr><td>Monte Carlo</td><td>{var_mc_95:.2f}% (R$ {abs(var_mc_95_money):,.2f})</td><td>{var_mc_99:.2f}% (R$ {abs(var_mc_99_money):,.2f})</td></tr>
232
+ </table>
233
+ """
234
+ return f'<img src="data:image/png;base64,{img_base64}">', var_summary
235
+
236
+ # Main Analysis Function
237
  def run_analysis(tickers_str, start_date, end_date, num_simulations, investment):
238
+ try:
239
+ tickers = [t.strip() for t in tickers_str.split(',')]
240
+ start_date = datetime.strptime(start_date, '%Y-%m-%d').strftime('%Y-%m-%d')
241
+ end_date = datetime.strptime(end_date, '%Y-%m-%d').strftime('%Y-%m-%d')
242
+ acoes_df = fetch_data(tickers, start_date, end_date)
243
+ if acoes_df.empty:
244
+ return [f"Error: No data fetched for {tickers}"] * 8
245
+
246
+ prices_plot = plot_historical_prices(acoes_df)
247
+ returns_plot, stats = calculate_and_plot_returns(acoes_df)
248
+ corr_plot = plot_correlation_matrix(pd.concat([acoes_df['Date'], np.log(acoes_df.drop('Date', axis=1) / acoes_df.drop('Date', axis=1).shift(1))], axis=1).dropna())
249
+ frontier_img, melhores_pesos = simulate_efficient_frontier(acoes_df, int(num_simulations))
250
+ port_evo, port_ret, portfolio_resultado, valor_final = simulate_portfolio(acoes_df, investment, melhores_pesos)
251
+ var_img, var_summary = analyze_var(portfolio_resultado, valor_final)
252
+
253
+ return prices_plot, returns_plot, corr_plot, frontier_img, port_evo, port_ret, var_img, stats + var_summary
254
+ except Exception as e:
255
+ return [f"Error: {str(e)}"] * 8
256
 
257
  # Gradio Interface
258
  with gr.Blocks(title="Portfolio Analysis Dashboard") as demo:
259
  gr.Markdown("# Portfolio Theory Visualization Dashboard")
260
+ gr.Markdown("Dynamic visualizations for portfolio analysis. Customize inputs and explore.")
261
+
262
  with gr.Row():
263
  tickers_input = gr.Textbox(label="Tickers (comma-separated)", value=','.join(default_tickers))
264
  start_date = gr.Textbox(label="Start Date (YYYY-MM-DD)", value=default_start_date)
265
  end_date = gr.Textbox(label="End Date (YYYY-MM-DD)", value=default_end_date)
266
  num_sim = gr.Number(label="Number of Simulations", value=num_ports)
267
  investment = gr.Number(label="Initial Investment (R$)", value=initial_investment)
268
+
269
  run_btn = gr.Button("Run Analysis")
270
+
271
  with gr.Tab("Historical Prices"):
272
  prices_output = gr.Plot()
273
+
274
  with gr.Tab("Returns History"):
275
  returns_output = gr.Plot()
276
+
277
  with gr.Tab("Correlation Matrix"):
278
  corr_output = gr.Plot()
279
+
280
  with gr.Tab("Efficient Frontier"):
281
  frontier_output = gr.HTML()
282
+
283
  with gr.Tab("Portfolio Evolution"):
284
  port_evo_output = gr.Plot()
285
+
286
  with gr.Tab("Daily Returns"):
287
  port_ret_output = gr.Plot()
288
+
289
  with gr.Tab("VaR Analysis"):
290
  var_output = gr.HTML()
291
+
292
  with gr.Tab("Statistics"):
293
  stats_output = gr.HTML()
294
+
295
  run_btn.click(
296
  run_analysis,
297
  inputs=[tickers_input, start_date, end_date, num_sim, investment],
298
  outputs=[prices_output, returns_output, corr_output, frontier_output, port_evo_output, port_ret_output, var_output, stats_output]
299
  )
300
 
301
+ if __name__ == "__main__":
302
+ demo.launch()