joaogabrielsouza commited on
Commit
6ae8536
·
1 Parent(s): 0845ab1

Publicação do dashboard Portfólio Eficiente com Docker no Hugging Face

Browse files
Files changed (3) hide show
  1. Dashboard_portfolio_eficiente.py +0 -279
  2. Dockerfile +28 -0
  3. README.md +14 -7
Dashboard_portfolio_eficiente.py DELETED
@@ -1,279 +0,0 @@
1
- #!/usr/bin/env python
2
- # coding: utf-8
3
-
4
- # ![MARCADOR.png](attachment:MARCADOR.png)
5
-
6
- # # BI - Distribuições de Probabilidade
7
-
8
- # ## Bibliotecas
9
-
10
- # In[8]:
11
-
12
-
13
- import streamlit as st
14
- import pandas as pd
15
- import numpy as np
16
- import plotly.express as px
17
- import yfinance as yf
18
- from scipy.stats import norm
19
- import seaborn as sns
20
- import plotly.graph_objects as go
21
- from PIL import Image
22
- import subprocess
23
-
24
-
25
- # ### Dashboard
26
-
27
- # In[22]:
28
-
29
-
30
- def load_data(tickers, start_date, end_date):
31
- data = pd.DataFrame()
32
- for ticker in tickers:
33
- data[ticker] = yf.download(ticker, start=start_date, end=end_date)['Close']
34
- data.reset_index(inplace=True)
35
- return data
36
-
37
- def get_ret_vol_sr(weights, log_ret):
38
- weights = np.array(weights)
39
- ret = np.sum(log_ret.mean() * weights * 252)
40
- vol = np.sqrt(np.dot(weights.T, np.dot(log_ret.cov() * 252, weights)))
41
- sr = ret / vol
42
- return np.array([ret, vol, sr])
43
-
44
- def check_sum(weights):
45
- return np.sum(weights) - 1
46
-
47
- # Função ajustada de alocação de ativos
48
- def alocacao_ativos(dataset, dinheiro_total, seed=0, melhores_pesos=[]):
49
- dataset = dataset.copy()
50
-
51
- if seed != 0:
52
- np.random.seed(seed)
53
-
54
- if len(melhores_pesos) > 0:
55
- pesos = melhores_pesos
56
- else:
57
- pesos = np.random.random(len(dataset.columns) - 1)
58
- pesos = pesos / np.sum(pesos)
59
-
60
- colunas = dataset.columns[1:]
61
-
62
- for i, acao in enumerate(colunas):
63
- dataset[acao] = (dataset[acao] / dataset[acao][0]) * pesos[i] * dinheiro_total
64
-
65
- dataset['soma valor'] = dataset[colunas].sum(axis=1)
66
- dataset['taxa retorno'] = dataset['soma valor'].pct_change() * 100
67
-
68
- # Criando um novo DataFrame para 'datas' e 'patrimônio'
69
- patrimonio_df = pd.DataFrame({'Date': dataset['Date'], 'Patrimônio': dataset['soma valor']})
70
-
71
- return dataset, patrimonio_df, dataset['soma valor'].iloc[-1]
72
-
73
- # Função para calcular o VaR
74
- def calcular_var(returns, confidence_level):
75
- returns = np.array(returns)
76
- z_score = norm.ppf(confidence_level)
77
- stdev = np.std(returns)
78
- var = -(returns.mean() + z_score * stdev)
79
- return var
80
-
81
- # Configuração da página
82
- st.set_page_config(page_title="Teoria do Portfólio Eficiente",
83
- layout="wide",
84
- initial_sidebar_state="expanded")
85
-
86
- # Slider CSS customization for green color
87
- st.markdown(
88
- """
89
- <style>
90
- .stSlider > div > div > div > div > div > div {
91
- background-color: #4CAF50 !important; /* Verde para o slider */
92
- }
93
- </style>
94
- """,
95
- unsafe_allow_html=True,
96
- )
97
-
98
- # Carregar as logos
99
- logo_unb = Image.open("Logo/MARCADOR.png")
100
-
101
- # Título e Logos
102
- col1, col2, col3 = st.columns([1, 6, 1])
103
- with col1:
104
- st.image(logo_unb, use_column_width=True)
105
- with col2:
106
- st.markdown("<h1 style='text-align: center; color: #003366;'>Teoria do Portfólio Eficiente</h1>",
107
- unsafe_allow_html=True)
108
- st.markdown("<h3 style='text-align: center; color: #003366;'>Professor João Gabriel de Moraes Souza</h3>",
109
- unsafe_allow_html=True) # Inserir nome do professor
110
- with col3:
111
- st.image(logo_unb, use_column_width=True)
112
-
113
- st.markdown("---")
114
-
115
- tickers = st.multiselect('Selecione as ações:', ['ITUB4.SA', 'BBAS3.SA', 'BBDC4.SA', 'PETR3.SA',
116
- 'CSNA3.SA'],
117
- default=['ITUB4.SA'])
118
-
119
- start_date = st.date_input('Data de Início', value=pd.to_datetime('2012-01-01'))
120
- end_date = st.date_input('Data de Fim', value=pd.to_datetime('2024-12-31'))
121
-
122
- data = load_data(tickers, start_date, end_date)
123
-
124
- if st.checkbox('Mostrar Gráfico de Preço'):
125
- st.subheader('Histórico do Preço das Ações')
126
- figura = px.line(data, x='Date', y=[data[ticker] for ticker in tickers],
127
- labels={'value': 'Preço', 'variable': 'Ações'})
128
- st.plotly_chart(figura)
129
-
130
- if st.checkbox('Mostrar Histórico de Retorno das Ações'):
131
- st.subheader('Histórico de Retorno das Ações')
132
- data.set_index('Date', inplace=True)
133
- log_retornos = np.log(data / data.shift(1))
134
- figura_retornos = px.line(log_retornos, labels={'value': 'Retorno Logarítmico', 'variable': 'Ações'})
135
- st.plotly_chart(figura_retornos)
136
-
137
- # Adicionando seletores para o número de portfólios e valor inicial de investimento
138
- num_ports = st.selectbox('Selecione o número de portfólios para a simulação:',
139
- [100, 1000, 10000], index=2)
140
- valor_inicial = st.number_input('Valor Inicial de Investimento:', min_value=1000,
141
- max_value=100000, value=10000, step=1000)
142
-
143
- global max_sr_ret, max_sr_vol # Definindo variáveis globais
144
-
145
- if st.checkbox('Realizar Simulação de Portfólio'):
146
- st.subheader('Simulação de Portfólio')
147
-
148
- data.dropna(inplace=True)
149
- log_ret = np.log(data / data.shift(1))
150
-
151
- np.random.seed(42)
152
- all_weights = np.zeros((num_ports, len(data.columns)))
153
- ret_arr = np.zeros(num_ports)
154
- vol_arr = np.zeros(num_ports)
155
- sharpe_arr = np.zeros(num_ports)
156
-
157
- for x in range(num_ports):
158
- weights = np.array(np.random.random(len(data.columns)))
159
- weights = weights / np.sum(weights)
160
-
161
- all_weights[x, :] = weights
162
- ret_arr[x], vol_arr[x], sharpe_arr[x] = get_ret_vol_sr(weights, log_ret)
163
-
164
- max_sr_loc = sharpe_arr.argmax()
165
- max_sr_ret = ret_arr[max_sr_loc]
166
- max_sr_vol = vol_arr[max_sr_loc]
167
-
168
- figura_port = px.scatter(x=vol_arr, y=ret_arr, color=sharpe_arr,
169
- color_continuous_scale='viridis',
170
- labels={'x': 'Volatilidade', 'y': 'Retorno'}, title='Simulação de Portfólio')
171
- figura_port.add_scatter(x=[max_sr_vol], y=[max_sr_ret], marker=dict(color='red', size=20),
172
- name='Melhor Sharpe Ratio')
173
- st.plotly_chart(figura_port)
174
-
175
- # Após a simulação de portfólio e identificação dos melhores pesos
176
- if st.checkbox('Mostrar Pesos do Melhor Portfólio'):
177
- # Organizando os pesos em um DataFrame para melhor visualização
178
- ativos = data.columns # Pegando os nomes dos ativos selecionados
179
- pesos = all_weights[max_sr_loc] # Melhores pesos do portfólio
180
- pesos_percentuais = pesos * 100 # Convertendo para porcentagem
181
-
182
- # Criando um DataFrame com os ativos e seus pesos
183
- df_pesos = pd.DataFrame({
184
- 'Ativo': ativos,
185
- 'Peso (%)': pesos_percentuais
186
- })
187
-
188
- # Exibindo o DataFrame com st.table para uma visualização estática
189
- st.write("### Pesos do Melhor Portfólio")
190
- st.dataframe(df_pesos.style.format({'Peso (%)': '{:.2f}%'}))
191
-
192
- # Carregando os dados e executando a função de alocação de ativos
193
- if st.button('Performance Portfólio'):
194
- data = load_data(tickers, start_date, end_date)
195
- dataset, patrimonio_df, soma_valor_final = alocacao_ativos(data, valor_inicial)
196
-
197
- # Plotando a evolução do patrimônio
198
- figura_valor_port = px.line(patrimonio_df, x='Date', y='Patrimônio', title='Evolução do Patrimônio da Carteira')
199
- st.plotly_chart(figura_valor_port)
200
-
201
- st.write(f'Valor final do portfólio: R$ {soma_valor_final:.2f}')
202
-
203
- # Seção para cálculo e exibição do VaR
204
- if 'max_sr_ret' in globals() and 'max_sr_vol' in globals():
205
- st.markdown("## Cálculo do Value at Risk (VaR)")
206
-
207
- # Configuração do nível de confiança para o cálculo do VaR
208
- confidence_level = st.slider('Selecione o Nível de Confiança para o VaR:', min_value=0.80, max_value=0.99, value=0.90)
209
-
210
- # Seletor para escolher entre retorno percentual e valores monetários
211
- modo_var = st.radio("Escolha a exibição do VaR:", ("Retorno Percentual", "Valores Monetários"))
212
-
213
- # Gerar lista de retornos para calcular o VaR (usando os retornos logarítmicos do portfólio simulado)
214
- returns = np.random.normal(max_sr_ret * 100, max_sr_vol * 100, 10000)
215
-
216
- # Calcular o VaR no nível de confiança especificado
217
- var_value = calcular_var(returns, confidence_level)
218
-
219
- # Ajuste para valores monetários se selecionado
220
- if modo_var == "Valores Monetários":
221
- var_value = valor_inicial * (var_value / 100)
222
- returns = returns * (valor_inicial / 100)
223
- y_label = "Densidade (Valores Monetários)"
224
- x_label = "Valores Monetários"
225
- else:
226
- y_label = "Densidade (Retorno Percentual)"
227
- x_label = "Retorno Percentual"
228
-
229
- st.write(f'VaR no intervalo de confiança de {confidence_level * 100:.0f}%: {var_value:.2f}')
230
-
231
- # Plotar a distribuição dos retornos com o nível de VaR usando Plotly
232
- fig = go.Figure()
233
-
234
- # Adicionando o histograma dos retornos
235
- fig.add_trace(go.Histogram(
236
- x=returns,
237
- nbinsx=50,
238
- histnorm='probability',
239
- name='Distribuição de Retornos',
240
- marker=dict(color='skyblue'),
241
- opacity=0.75
242
- ))
243
-
244
- # Linha vertical para indicar o VaR
245
- fig.add_shape(
246
- type="line",
247
- x0=var_value,
248
- y0=0,
249
- x1=var_value,
250
- y1=0.1,
251
- line=dict(color="red", width=2, dash="dash"),
252
- name=f'VaR {confidence_level*100:.0f}%'
253
- )
254
-
255
- # Anotação para o VaR
256
- fig.add_annotation(
257
- x=var_value,
258
- y=0.1,
259
- text=f'VaR {confidence_level*100:.0f}%',
260
- showarrow=True,
261
- arrowhead=2,
262
- ax=40,
263
- ay=-40
264
- )
265
-
266
- # Configurações do layout
267
- fig.update_layout(
268
- title=f'Distribuição dos Retornos com VaR até {confidence_level * 100:.0f}% de Nível de Confiança',
269
- xaxis_title=x_label,
270
- yaxis_title=y_label,
271
- bargap=0.2,
272
- )
273
-
274
- st.plotly_chart(fig)
275
- else:
276
- st.warning("Realize a simulação do portfólio para calcular o VaR.")
277
-
278
-
279
-
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
Dockerfile ADDED
@@ -0,0 +1,28 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Dockerfile para Dashboard de Portfólio Eficiente com Streamlit via Docker
2
+ # syntax=docker/dockerfile:1
3
+
4
+ # Imagem base leve com Python
5
+ FROM python:3.10-slim
6
+
7
+ # Variáveis de ambiente
8
+ ENV PYTHONUNBUFFERED=1 \
9
+ PYTHONDONTWRITEBYTECODE=1
10
+
11
+ # Diretório de trabalho
12
+ WORKDIR /app
13
+
14
+ # Copiar e instalar dependências
15
+ COPY requirements.txt .
16
+ RUN pip install --upgrade pip \
17
+ && pip install --no-cache-dir -r requirements.txt
18
+
19
+ # Copiar logo e script principal
20
+ COPY Logo ./Logo
21
+ COPY Dashboard_portfolio_eficiente_online.py .
22
+
23
+ # Expor porta do Streamlit
24
+ EXPOSE 8501
25
+
26
+ # Comando para iniciar o Streamlit
27
+ CMD ["streamlit", "run", "Dashboard_portfolio_eficiente_online.py", "--server.port=8501", "--server.enableCORS=false"]
28
+
README.md CHANGED
@@ -1,11 +1,18 @@
1
  ---
2
- title: Portfólio Eficiente
3
- emoji: 📈
4
- colorFrom: blue
5
- colorTo: green
6
- sdk: streamlit
7
- sdk_version: "1.32.0"
8
- app_file: Dashboard_portfolio_eficiente_online.py
 
 
 
 
 
9
  pinned: false
 
 
10
  ---
11
 
 
1
  ---
2
+ title: "Portfólio Eficiente"
3
+ emoji: "📈"
4
+ colorFrom: "blue"
5
+ colorTo: "green"
6
+ sdk: "docker"
7
+ app_file: "Dockerfile"
8
+ app_port: 8501
9
+ tags:
10
+ - streamlit
11
+ - finanças
12
+ - portfólio
13
+ - estatística
14
  pinned: false
15
+ short_description: "Alocação Eficiente de Portfólio"
16
+ license: mit
17
  ---
18