import matplotlib matplotlib.use('Agg') import streamlit as st import pandas as pd from PIL import Image import plotly.graph_objects as go import numpy as np import yfinance as yf import datetime as dt from collections import OrderedDict from sklearn.model_selection import train_test_split from sklearn.ensemble import RandomForestRegressor import uteis as uteis import scrap as scraping def flatten(d): ''' Flatten an OrderedDict object ''' result = OrderedDict() for k, v in d.items(): if isinstance(v, dict): result.update(flatten(v)) else: result[k] = v return result def analise_carteira(): #código para ativar bootstrap css st.markdown( """ """,unsafe_allow_html=True ) top_ativos = pd.read_excel('data/top_200.xlsx')#, index_col=0) col1, col2,col3 = st.columns([0.1,0.4,0.1]) with col2: st.title('Análise de carteira e previsão de lucro') st.subheader('Receba insights sobre suas operações realizadas no passado e preveja se sua próxima operação no futuro será lucrativa, ou não!') st.write('Usando os dados do seu extrato histórico fornecido pelo site da B3 iremos treinar um algorítimo de inteligência artificial que será capaz de analisar suas operações passadas, mostrar padrões que te levaram ao lucro ou prejuízo, além de prever a probabilidade de lucro de uma ação caso ela seja comprada hoje por você') menu = ["Escolha uma opção","Usar algoritmo do site","Usar os dados de minhas operações"] choice = st.selectbox("Menu",menu) if choice == "Usar os dados de minhas operações": # se usuário estiver logado if st.session_state['loged']: #st.subheader('Faça upload aqui do seu extrato da B3') col1, col2,col3 = st.columns([0.1,0.4,0.1]) with col2: with st.expander("Passo a passo de como acessar os dados no site da B3"): st.write('Acessar o site www.investidorb3.com.br') st.write('Aba Extratos > Negociação > Aplicar filtro trazendo dados do último ano > baixar extrato em formato excel') image = Image.open('images/b3.png') st.image(image, use_column_width=True) st.subheader('Faça upload aqui do seu extrato da B3') file = st.file_uploader('Entre com seu extrato (.xlsx)', type = 'xlsx') if file: df = pd.read_excel(file) lista = [] retirar = [] for i in range(len(df['code'])): #PEGANDO SOMENTE AÇÕES AO INVÉS DE FIIS CORRELATAS if len(df.iloc[i]['code']) == 5: lista.append(df.iloc[i]['code']) elif df.iloc[i]['code'][-1] == '1': retirar.append(df.iloc[i]['code'][-1]) #PEGANDO AÇÕES FRACIONADAS E TRANSFORMANDO EM AÇÕES NORMAIS else: lista.append(df.iloc[i]['code'][:-1]) lista = pd.DataFrame(lista)[0].unique() lista_input = [] #PEGAR DADOS HISTÓRICOS DE CADA UMA DAS AÇÕES for i in range(len(lista)): lista_input.append(str(lista[i] + '.SA')) date_year_ago = dt.datetime.today() - dt.timedelta(days=565) date_year_ago = date_year_ago.strftime(format='20%y-%m-%d') data = yf.download(lista_input,start=date_year_ago) #CRIA UMA DF COM UMA LINHA PARA CADA AÇÃO df_filled = pd.DataFrame(columns = ['name']) df_filled['name'] = lista_input # lógica para input de dados calculados #UTILIZA LISTA COM NOMES ÚNICOS DAS AÇÕES, DATAFRAME DA B3, DADOS HISTÓRICOS E A TABELA DE INPUT COM UMA LINHA PARA CADA AÇÃO uteis.inputer_train(lista, df, data, df_filled) df_input = df_filled.fillna(0).replace(np.inf, 0) st.subheader('Avaliação de carteira:') st.write('Lucro Total do período avaliado: R$',round(df_input['Ganho_total'].sum(),2)) #st.write('Rendimento Total do período avaliado: %',round(df_input['Rendimento_total_%'].sum(),2)) df_input = df_input.loc[df_input['data_compra_1'] != 0] df_input['data_compra_1'] = pd.to_datetime(df_input['data_compra_1']).copy() df_ordered = df_input.sort_values('data_compra_1') #ordenando e criando campo mes ano df_ordered['mes/ano'] =df_ordered['data_compra_1'].astype(str).str[:-3] df_grouped = df_ordered.groupby('mes/ano').agg({'Rendimento_total_%':'mean','Ganho_total':'sum'}) df_grouped = df_grouped.reset_index() #from plotly.subplots import make_subplots #fig = make_subplots(rows=2, cols=1, specs=[[{"type": "scatter"}, {"type": "bar"}]], subplot_titles=("Rendimento mensal %","Lucro total mensal R$") ) #fig.add_trace(go.Scatter(x =df_grouped['mes/ano'], y=df_grouped['Rendimento_total_%']), row=1, col=1) #fig.add_trace(go.Bar(x =df_grouped['mes/ano'], y=df_grouped['Ganho_total']), row=1, col=2) #fig.update_layout(height=800, showlegend=False, paper_bgcolor='rgba(0,0,0,0)', plot_bgcolor='rgba(0,0,0,0)') #st.plotly_chart(fig) layout = go.Layout(title="Rendimento mensal %",xaxis=dict(title="mês/ano"), yaxis=dict(title="Rendimento total %")) fig = go.Figure(layout = layout) fig.add_trace(go.Scatter(x =df_grouped['mes/ano'], y=df_grouped['Rendimento_total_%'])) fig.update_layout( height=600, width=800 ,showlegend=False, paper_bgcolor='rgba(255,255,255,0.9)', plot_bgcolor='rgba(255,255,255,0.9)') fig.update_yaxes(showgrid=True, gridwidth=0.1, gridcolor = 'rgb(240,238,238)') st.plotly_chart(fig,use_container_width=True) layout = go.Layout(title="Lucro total mensal R$",xaxis=dict(title="mês/ano"), yaxis=dict(title="Ganho total R$")) fig = go.Figure(layout = layout) fig.add_trace(go.Bar(x =df_grouped['mes/ano'], y=df_grouped['Ganho_total'])) fig.update_layout( height=600, width=800 ,showlegend=False, paper_bgcolor='rgba(255,255,255,0.9)', plot_bgcolor='rgba(255,255,255,0.9)') fig.update_yaxes(showgrid=True, gridwidth=0.1, gridcolor = 'rgb(240,238,238)') st.plotly_chart(fig,use_container_width=True) #MODELAGEM df_ordered['lucro'] = 0 df_ordered.loc[df_ordered['Ganho_total'] > 0 , 'lucro'] = 1 df_ordered = df_ordered.fillna(0).replace(-np.inf, 0) X = df_ordered.drop(['name', 'data_compra_1','mes/ano','Ganho_total','Rendimento_total_%','lucro','Preço_médio_comprado','Preço_médio_vendido'],axis=1) y = df_ordered['lucro'] # divisão entre treino e teste 70/30 X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.30, random_state=42) # Random Forest Regressor MVP regr = RandomForestRegressor(random_state=42) regr.fit(X_train,y_train) predictions = regr.predict(X_test) comparar = pd.DataFrame(y_test) comparar['previsto'] = predictions comparar['dif'] = comparar['previsto'] - comparar['lucro'] erros = len(comparar.loc[comparar['dif'] > 0.5]) + len(comparar.loc[comparar['dif'] < -0.5]) total = len(comparar) precision_model = round(1 - (erros / total),2) st.write('O modelo criado com os seus dados tem uma precisão de acerto de: ',precision_model * 100 ,'%') st.write('Caso a precisão seja baixa ( < 65% ) é necessário mais dados para melhorar a performance do modelo, neste caso utilize nosso modelo pré treinado na opção " Testar com nossos dados" ou incremente seus dados com operações fictícias') #trazendo features + importantes features, rank = uteis.rank(X, y) st.subheader('Estas variáveis são as que mais impactam nas decisões da inteligência artificial') #col1, col2,col3 = st.columns([0.1,0.4,0.1]) col1, col2,col3 = st.columns([1,2,1]) with col2: #st.dataframe(rank['features'].head(10).reset_index(drop=True).T) top_features = rank['features'].head(10).reset_index(drop=True) st.table(top_features) #fazendo previsão em toda a bolsa #lista = scraping.get_data() #todos = pd.DataFrame(flatten(lista).keys()).transpose() #todos.columns = todos.iloc[0] #for i in range(len(lista)): # todos = pd.concat([todos,pd.DataFrame(lista[i]).transpose()]) #todos = todos.iloc[1:] #todos['name'] = (todos.index + '.SA' ) #lista = top_ativos.copy() #PREVENDO 1 AÇÃO ESPECÍFICA col1, col2,col3 = st.columns([0.1,0.4,0.1]) with col2: st.subheader('Escolha o código de até 4 ativos específicos que deseja prever e pressione enter') nome_do_ativo1 = st.text_input('Nome do ativo 1',value='PETR4') nome_do_ativo2 = st.text_input('Nome do ativo 2',value='VALE3') nome_do_ativo3 = st.text_input('Nome do ativo 3',value='WEGE3') nome_do_ativo4 = st.text_input('Nome do ativo 4') if st.button('prever lucro das ações especificadas acima'): ativo1 = str(nome_do_ativo1 + '.SA').upper() ativo2 = str(nome_do_ativo2 + '.SA').upper() ativo3 = str(nome_do_ativo3 + '.SA').upper() ativo4 = str(nome_do_ativo4 + '.SA').upper() nome_do_ativo1 = nome_do_ativo1.upper() nome_do_ativo2 = nome_do_ativo2.upper() nome_do_ativo3 = nome_do_ativo3.upper() nome_do_ativo4 = nome_do_ativo4.upper() todos = pd.DataFrame(columns = ['name']) todos['name'] = [ativo1,ativo2,ativo3,ativo4] lista = pd.DataFrame(columns = ['name']) lista['name'] = [nome_do_ativo1,nome_do_ativo2,nome_do_ativo3,nome_do_ativo4] date_year_ago = dt.datetime.today() - dt.timedelta(days=300) date_year_ago = date_year_ago.strftime(format='20%y-%m-%d') data = yf.download(list(todos['name']),start=date_year_ago) df_filled = pd.DataFrame(columns = ['name']) df_filled['name'] = lista['name'] df_filled['ativo'] = df_filled['name'].copy() df_filled = df_filled.set_index('ativo') df_filled = uteis.inputer_predict(data, df_filled) # retirar nulos e infinitos positivos df_input = df_filled.fillna(0).replace(np.inf, 0) #df_ordered = df_input.fillna(0).replace(-np.inf, 0) input_predict = df_input[list(X.columns)] # retirar nulos e infinitos negativos input_predict = input_predict.fillna(0).replace(-np.inf, 0) predictions = regr.predict(input_predict) input_predict['probabilidade de lucro'] = predictions.round(2) * 100 st.subheader('Previsão de lucro das principais ações da bolsa') st.text('Essa previsão é feita com base nas tendências de sucesso captadas pelas suas operações') #col1, col2,col3 = st.columns([0.1,0.4,0.1]) col1, col2,col3 = st.columns([1,2,1]) with col2: st.table(input_predict['probabilidade de lucro'].sort_values(ascending=False).round(2)) if st.button('prever as top 200 ações de uma vez'): lista = top_ativos.copy() top_ativos['name'] =top_ativos['name'] + '.SA' todos = top_ativos.copy() #todos = top_ativos.head(2) #RETIRAR AQUI PARA PEGAR OS TOP 200 date_year_ago = dt.datetime.today() - dt.timedelta(days=300) date_year_ago = date_year_ago.strftime(format='20%y-%m-%d') data = yf.download(list(todos['name']),start=date_year_ago) df_filled = pd.DataFrame(columns = ['name']) df_filled['name'] = lista['name'] df_filled['ativo'] = df_filled['name'].copy() df_filled = df_filled.set_index('ativo') #uteis.inputer_predict(data, df_filled) df_filled = uteis.inputer_predict(data, df_filled) # retirar nulos e infinitos positivos df_input = df_filled.fillna(0).replace(np.inf, 0) #df_ordered = df_input.fillna(0).replace(-np.inf, 0) input_predict = df_input[list(X.columns)] # retirar nulos e infinitos negativos input_predict = input_predict.fillna(0).replace(-np.inf, 0) predictions = regr.predict(input_predict) input_predict['probabilidade de lucro'] = predictions.round(2) * 100 st.subheader('Previsão de lucro das principais ações da bolsa') st.text('Essa previsão é feita com base nas tendências de sucesso captadas pelas suas operações') col1, col2,col3 = st.columns([1,2,1]) with col2: st.table(input_predict['probabilidade de lucro'].sort_values(ascending=False).round(2)) else: st.warning("Faça o Login na seção Login") if choice == "Usar algoritmo do site": st.subheader('As previsões feitas aqui utilizam dados de movimentação de milhares de operações para composição da inteligência artificial!') df = pd.read_excel('data/b3_sem_resumo.xlsx') lista = [] retirar = [] for i in range(len(df['code'])): #PEGANDO SOMENTE AÇÕES AO INVÉS DE FIIS CORRELATAS if len(df.iloc[i]['code']) == 5: lista.append(df.iloc[i]['code']) elif df.iloc[i]['code'][-1] == '1': retirar.append(df.iloc[i]['code'][-1]) #PEGANDO AÇÕES FRACIONADAS E TRANSFORMANDO EM AÇÕES NORMAIS else: lista.append(df.iloc[i]['code'][:-1]) lista = pd.DataFrame(lista)[0].unique() lista_input = [] #PEGAR DADOS HISTÓRICOS DE CADA UMA DAS AÇÕES for i in range(len(lista)): lista_input.append(str(lista[i] + '.SA')) date_year_ago = dt.datetime.today() - dt.timedelta(days=565) date_year_ago = date_year_ago.strftime(format='20%y-%m-%d') data = yf.download(lista_input,start=date_year_ago) #CRIA UMA DF COM UMA LINHA PARA CADA AÇÃO df_filled = pd.DataFrame(columns = ['name']) df_filled['name'] = lista_input # lógica para input de dados calculados #UTILIZA LISTA COM NOMES ÚNICOS DAS AÇÕES, DATAFRAME DA B3, DADOS HISTÓRICOS E A TABELA DE INPUT COM UMA LINHA PARA CADA AÇÃO uteis.inputer_train(lista, df, data, df_filled) df_input = df_filled.fillna(0).replace(np.inf, 0) # st.subheader('Avaliação de carteira:') # st.write('Lucro Total do período avaliado: R$',round(df_input['Ganho_total'].sum(),2)) # #st.write('Rendimento Total do período avaliado: %',round(df_input['Rendimento_total_%'].sum(),2)) df_input = df_input.loc[df_input['data_compra_1'] != 0] df_input['data_compra_1'] = pd.to_datetime(df_input['data_compra_1']).copy() df_ordered = df_input.sort_values('data_compra_1') #ordenando e criando campo mes ano df_ordered['mes/ano'] =df_ordered['data_compra_1'].astype(str).str[:-3] df_grouped = df_ordered.groupby('mes/ano').agg({'Rendimento_total_%':'mean','Ganho_total':'sum'}) df_grouped = df_grouped.reset_index() #from plotly.subplots import make_subplots #fig = make_subplots(rows=2, cols=1, specs=[[{"type": "scatter"}, {"type": "bar"}]], subplot_titles=("Rendimento mensal %","Lucro total mensal R$") ) #fig.add_trace(go.Scatter(x =df_grouped['mes/ano'], y=df_grouped['Rendimento_total_%']), row=1, col=1) #fig.add_trace(go.Bar(x =df_grouped['mes/ano'], y=df_grouped['Ganho_total']), row=1, col=2) #fig.update_layout(height=800, showlegend=False, paper_bgcolor='rgba(0,0,0,0)', plot_bgcolor='rgba(0,0,0,0)') #st.plotly_chart(fig) # layout = go.Layout(title="Rendimento mensal %",xaxis=dict(title="mês/ano"), yaxis=dict(title="Rendimento total %")) # fig = go.Figure(layout = layout) # fig.add_trace(go.Scatter(x =df_grouped['mes/ano'], y=df_grouped['Rendimento_total_%'])) # fig.update_layout( height=600, width=800 ,showlegend=False, paper_bgcolor='rgba(255,255,255,0.9)', plot_bgcolor='rgba(255,255,255,0.9)') # fig.update_yaxes(showgrid=True, gridwidth=0.1, gridcolor = 'rgb(240,238,238)') # st.plotly_chart(fig,use_container_width=True) # layout = go.Layout(title="Lucro total mensal R$",xaxis=dict(title="mês/ano"), yaxis=dict(title="Ganho total R$")) # fig = go.Figure(layout = layout) # fig.add_trace(go.Bar(x =df_grouped['mes/ano'], y=df_grouped['Ganho_total'])) # fig.update_layout( height=600, width=800 ,showlegend=False, paper_bgcolor='rgba(255,255,255,0.9)', plot_bgcolor='rgba(255,255,255,0.9)') # fig.update_yaxes(showgrid=True, gridwidth=0.1, gridcolor = 'rgb(240,238,238)') # st.plotly_chart(fig,use_container_width=True) #MODELAGEM df_ordered['lucro'] = 0 df_ordered.loc[df_ordered['Ganho_total'] > 0 , 'lucro'] = 1 df_ordered = df_ordered.fillna(0).replace(-np.inf, 0) X = df_ordered.drop(['name', 'data_compra_1','mes/ano','Ganho_total','Rendimento_total_%','lucro','Preço_médio_comprado','Preço_médio_vendido'],axis=1) y = df_ordered['lucro'] # divisão entre treino e teste 70/30 X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.30, random_state=42) # Random Forest Regressor MVP regr = RandomForestRegressor(random_state=42) regr.fit(X_train,y_train) predictions = regr.predict(X_test) comparar = pd.DataFrame(y_test) comparar['previsto'] = predictions comparar['dif'] = comparar['previsto'] - comparar['lucro'] erros = len(comparar.loc[comparar['dif'] > 0.5]) + len(comparar.loc[comparar['dif'] < -0.5]) total = len(comparar) precision_model = round(1 - (erros / total),2) st.write('O modelo utilizado tem uma precisão de acerto de: ',precision_model * 100 ,'%') #trazendo features + importantes features, rank = uteis.rank(X, y) st.subheader('Estas variáveis são as que mais impactam nas decisões desta inteligência artificial') #col1, col2,col3 = st.columns([0.1,0.4,0.1]) col1, col2,col3 = st.columns([1,2,1]) with col2: #st.dataframe(rank['features'].head(10).reset_index(drop=True).T) top_features = rank['features'].head(10).reset_index(drop=True) st.table(top_features) #fazendo previsão em toda a bolsa #lista = scraping.get_data() #todos = pd.DataFrame(flatten(lista).keys()).transpose() #todos.columns = todos.iloc[0] #for i in range(len(lista)): # todos = pd.concat([todos,pd.DataFrame(lista[i]).transpose()]) #todos = todos.iloc[1:] #todos['name'] = (todos.index + '.SA' ) #lista = top_ativos.copy() #PREVENDO 1 AÇÃO ESPECÍFICA col1, col2,col3 = st.columns([0.1,0.4,0.1]) with col2: st.subheader('Escolha o código de até 4 ativos específicos que deseja prever e pressione enter') nome_do_ativo1 = st.text_input('Nome do ativo 1',value='PETR4') nome_do_ativo2 = st.text_input('Nome do ativo 2',value='VALE3') nome_do_ativo3 = st.text_input('Nome do ativo 3',value='WEGE3') nome_do_ativo4 = st.text_input('Nome do ativo 4') if st.button('prever lucro das ações especificadas acima'): ativo1 = str(nome_do_ativo1 + '.SA').upper() ativo2 = str(nome_do_ativo2 + '.SA').upper() ativo3 = str(nome_do_ativo3 + '.SA').upper() ativo4 = str(nome_do_ativo4 + '.SA').upper() nome_do_ativo1 = nome_do_ativo1.upper() nome_do_ativo2 = nome_do_ativo2.upper() nome_do_ativo3 = nome_do_ativo3.upper() nome_do_ativo4 = nome_do_ativo4.upper() todos = pd.DataFrame(columns = ['name']) todos['name'] = [ativo1,ativo2,ativo3,ativo4] lista = pd.DataFrame(columns = ['name']) lista['name'] = [nome_do_ativo1,nome_do_ativo2,nome_do_ativo3,nome_do_ativo4] date_year_ago = dt.datetime.today() - dt.timedelta(days=300) date_year_ago = date_year_ago.strftime(format='20%y-%m-%d') data = yf.download(list(todos['name']),start=date_year_ago) df_filled = pd.DataFrame(columns = ['name']) df_filled['name'] = lista['name'] df_filled['ativo'] = df_filled['name'].copy() df_filled = df_filled.set_index('ativo') df_filled = uteis.inputer_predict(data, df_filled) # retirar nulos e infinitos positivos df_input = df_filled.fillna(0).replace(np.inf, 0) #df_ordered = df_input.fillna(0).replace(-np.inf, 0) input_predict = df_input[list(X.columns)] # retirar nulos e infinitos negativos input_predict = input_predict.fillna(0).replace(-np.inf, 0) predictions = regr.predict(input_predict) input_predict['probabilidade de lucro'] = predictions.round(2) * 100 st.subheader('Previsão de lucro das principais ações da bolsa') st.text('Essa previsão é feita com base nas tendências de sucesso captadas pelo algoritmo do explorador de ativos') #col1, col2,col3 = st.columns([0.1,0.4,0.1]) col1, col2,col3 = st.columns([1,2,1]) with col2: st.table(input_predict['probabilidade de lucro'].sort_values(ascending=False).round(2)) if st.button('prever as top 200 ações de uma vez'): lista = top_ativos.copy() top_ativos['name'] =top_ativos['name'] + '.SA' todos = top_ativos.copy() #todos = top_ativos.head(2) #RETIRAR AQUI PARA PEGAR OS TOP 200 date_year_ago = dt.datetime.today() - dt.timedelta(days=300) date_year_ago = date_year_ago.strftime(format='20%y-%m-%d') data = yf.download(list(todos['name']),start=date_year_ago) df_filled = pd.DataFrame(columns = ['name']) df_filled['name'] = lista['name'] df_filled['ativo'] = df_filled['name'].copy() df_filled = df_filled.set_index('ativo') #uteis.inputer_predict(data, df_filled) df_filled = uteis.inputer_predict(data, df_filled) # retirar nulos e infinitos positivos df_input = df_filled.fillna(0).replace(np.inf, 0) #df_ordered = df_input.fillna(0).replace(-np.inf, 0) input_predict = df_input[list(X.columns)] # retirar nulos e infinitos negativos input_predict = input_predict.fillna(0).replace(-np.inf, 0) predictions = regr.predict(input_predict) input_predict['probabilidade de lucro'] = predictions.round(2) * 100 st.subheader('Previsão de lucro das principais ações da bolsa') st.text('Essa previsão é feita com base nas tendências de sucesso captadas pelas suas operações') col1, col2,col3 = st.columns([1,2,1]) with col2: st.table(input_predict['probabilidade de lucro'].sort_values(ascending=False).round(2))