Lucas Vasconcelos Rocha commited on
Commit
4565b50
1 Parent(s): f0cfe63

Add application file

Browse files
Files changed (33) hide show
  1. App.py +93 -0
  2. Procfile +1 -0
  3. data/b3_sem_resumo.xlsx +0 -0
  4. data/classification_b3.xlsx +0 -0
  5. data/top_100.xlsx +0 -0
  6. data/top_200.xlsx +0 -0
  7. data/top_300.xlsx +0 -0
  8. data/top_ativos.xlsx +0 -0
  9. home.py +20 -0
  10. html01.py +62 -0
  11. html_home.py +11 -0
  12. images/b3.png +0 -0
  13. images/home_image_2.jpeg +0 -0
  14. login.py +81 -0
  15. pag1.py +466 -0
  16. pag2.py +278 -0
  17. pag3.py +124 -0
  18. pag4.py +176 -0
  19. pag5.py +532 -0
  20. requirements.txt +128 -0
  21. scrap.py +245 -0
  22. scripts/scrap.py +234 -0
  23. setup.sh +13 -0
  24. style.py +95 -0
  25. style_0.css +98 -0
  26. style_1.css +146 -0
  27. style_2.css +29 -0
  28. style_3.css +29 -0
  29. style_4.css +40 -0
  30. style_5.css +36 -0
  31. style_login.css +6 -0
  32. users.csv +3 -0
  33. uteis.py +485 -0
App.py ADDED
@@ -0,0 +1,93 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # ----------------------------------LIBS -------------------------------------------------------------
2
+ import streamlit as st
3
+ st.set_page_config( # Alternate names: setup_page, page, layout
4
+ layout="wide", # Can be "centered" or "wide". In the future also "dashboard", etc.
5
+ initial_sidebar_state="auto", # Can be "auto", "expanded", "collapsed"
6
+ page_title=None, # String or None. Strings get appended with "• Streamlit".
7
+ page_icon=None, # String, anything supported by st.image, or None.
8
+ )
9
+
10
+ import matplotlib
11
+ matplotlib.use('Agg')
12
+
13
+ from streamlit_option_menu import option_menu
14
+
15
+ import warnings
16
+ warnings.filterwarnings('ignore')
17
+
18
+ import datetime as dt
19
+ dia = dt.datetime.today().strftime(format='20%y-%m-%d')
20
+
21
+ import style as style
22
+ import home as home
23
+ import login as login
24
+ import pag1 as pag1
25
+ import pag2 as pag2
26
+ import pag3 as pag3
27
+ import pag4 as pag4
28
+ import pag5 as pag5
29
+
30
+
31
+ # ----------------------------------DEFS -------------------------------------------------------------
32
+
33
+ #carrega os arquivos css
34
+ def local_css(file_name):
35
+ with open(file_name) as f:
36
+ st.markdown(f'<style>{f.read()}</style>', unsafe_allow_html=True)
37
+
38
+ def main():
39
+
40
+ #css comum para todas páginas (menu)
41
+ #local_css("style_0.css")
42
+
43
+ #esconder botão de menu e marca dágua no rodapé
44
+ #style.hidden_menu_and_footer()
45
+
46
+ #cabeçalho detalhe superior da página
47
+ #style.headerstyle()
48
+
49
+ # ----------------------------------MENU -------------------------------------------------------------
50
+
51
+ with st.sidebar:
52
+ style.sidebarwidth()
53
+ n_sprites = option_menu('Menu',["Home","Login","Análise técnica", "Comparar ações", "Análise fundamentalista", "Rastrear ações", "Previsão de lucro"],
54
+ icons=['house','person','bar-chart', 'book', 'bullseye', 'binoculars','cash-coin'],
55
+ default_index=0, menu_icon="app-indicator", #orientation='horizontal',
56
+ styles={
57
+ "container": {"padding": "2!important", "background-color": "#ffffff" }, # ,"background-size": "cover","margin": "0px"},
58
+ "nav-link": {"font-size": "12px", "text-align": "left", "--hover-color": "#4a7198","font-weight": "bold"}, #,"position": "relative","display": "inline"},
59
+ "nav-link-selected": {"background-color": "#4a7198"},
60
+ })
61
+
62
+ # ----------------------------------PAGES -------------------------------------------------------------
63
+ if n_sprites == "Home":
64
+ #local_css("style_1.css")
65
+ home.initial_page()
66
+
67
+ if n_sprites == "Login":
68
+ #local_css("style_login.css")
69
+ login.login_section()
70
+
71
+ if n_sprites == "Análise técnica":
72
+ #local_css("style_1.css")
73
+ pag1.analise_tecnica_fundamentalista()
74
+
75
+ if n_sprites == "Comparar ações":
76
+ #local_css("style_2.css")
77
+ pag2.comparacao_ativos()
78
+
79
+ if n_sprites == "Análise fundamentalista":
80
+ #local_css("style_3.css")
81
+ pag3.descobrir_ativos()
82
+
83
+ if n_sprites == "Rastrear ações":
84
+ #local_css("style_4.css")
85
+ pag4.rastreador()
86
+
87
+ if n_sprites == "Previsão de lucro":
88
+ #local_css("style_5.css")
89
+ pag5.analise_carteira()
90
+
91
+ if __name__ == '__main__':
92
+ main()
93
+
Procfile ADDED
@@ -0,0 +1 @@
 
1
+ web: sh setup.sh && streamlit run App.py
data/b3_sem_resumo.xlsx ADDED
Binary file (10.8 kB). View file
data/classification_b3.xlsx ADDED
Binary file (31.8 kB). View file
data/top_100.xlsx ADDED
Binary file (9.41 kB). View file
data/top_200.xlsx ADDED
Binary file (10.8 kB). View file
data/top_300.xlsx ADDED
Binary file (12.6 kB). View file
data/top_ativos.xlsx ADDED
Binary file (13.9 kB). View file
home.py ADDED
@@ -0,0 +1,20 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import matplotlib
2
+ matplotlib.use('Agg')
3
+
4
+ import streamlit as st
5
+
6
+ import html_home as html_home
7
+ from PIL import Image
8
+
9
+ def initial_page():
10
+
11
+ #código para ativar bootstrap css
12
+ st.markdown(
13
+ """
14
+ <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css" integrity="sha384-Gn5384xqQ1aoWXA+058RXPxPg6fy4IWvTNh0E263XmFcJlSAwiGgFAW/dAiS6JXm" crossorigin="anonymous">
15
+ <script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/js/bootstrap.min.js" integrity="sha384-JZR6Spejh4U02d8jOt6vLEHfe/JQGiRRSQQxSfFWpi1MquVdAyjUar5+76PVCmYl" crossorigin="anonymous"></script>
16
+ """,unsafe_allow_html=True
17
+ )
18
+
19
+ image = Image.open('images/home_image_2.jpeg')
20
+ st.image(image, use_column_width=True)
html01.py ADDED
@@ -0,0 +1,62 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import streamlit as st
2
+
3
+ #card
4
+ def card_info(title, subtitle1, subtitle2, text, link):
5
+
6
+ st.markdown(
7
+ f"""
8
+ <div class="card-main" style="width: 100%;" "border-radius: 30px;">
9
+ <div class="card-body">
10
+ <h5 class="card-title" style="text-align: center;">{title}</h5>
11
+ <h6 class="card-subtitle mb-2 text-muted" style="text-align: center;">{subtitle1}</h6>
12
+ <h6 class="card-subtitle mb-2 text-muted" style="text-align: center;">{subtitle2}</h6>
13
+ <p class="card-text" style="text-align: left;">{text}</p>
14
+ <a href="#" class="card-link" style="text-align: center;">{link}</a>
15
+ </div>
16
+ </div>
17
+ """, unsafe_allow_html=True
18
+ )
19
+
20
+
21
+
22
+
23
+
24
+
25
+
26
+
27
+
28
+
29
+
30
+
31
+ # KPI com cards bootstrap
32
+ # st.markdown(
33
+ # f"""
34
+ # <div class="card-deck" style= "-webkit-box-orient: horizontal; width: 830px;" >
35
+
36
+ # <div class="card">
37
+ # <div class="card-body text-center">
38
+ # <p class="card-text" style="font-size: 20px; color: rgb(167, 174, 177); font-weight: bold;">P/L</p>
39
+ # <p class="card-text" style=" font-size: 40px">{fundamentus['P/L'][0]}</p>
40
+ # </div>
41
+ # </div>
42
+ # <div class="card">
43
+ # <div class="card-body text-center">
44
+ # <p class="card-text" style="font-size: 20px; color: rgb(167, 174, 177); font-weight: bold;">P/VP</p>
45
+ # <p class="card-text" style=" font-size: 40px;">{fundamentus['P/VP'][0]}</p>
46
+ # </div>
47
+ # </div>
48
+ # <div class="card">
49
+ # <div class="card-body text-center">
50
+ # <p class="card-text" style="font-size: 20px;color: rgb(167, 174, 177); font-weight: bold; ">Recomendação</p>
51
+ # <p class="card-text" style=" font-size: 40px; ">{info['recommendationKey']}</p>
52
+ # </div>
53
+ # </div>
54
+ # <div class="card">
55
+ # <div class="card-body text-center">
56
+ # <p class="card-text" style="font-size: 20px;color: rgb(167, 174, 177); font-weight: bold;">Próximo dividendo</p>
57
+ # <p class="card-text" style=" font-size: 20px;">{pfizer.calendar.transpose()['Earnings Date'].dt.strftime('%d/%m/%Y')[0]}</p>
58
+ # </div>
59
+ # </div>
60
+ # </div>
61
+ # """,unsafe_allow_html=True
62
+ # )
html_home.py ADDED
@@ -0,0 +1,11 @@
 
 
 
 
 
 
 
 
 
 
 
1
+ import streamlit as st
2
+
3
+ #card
4
+ def home():
5
+
6
+ st.markdown(
7
+ f"""
8
+
9
+
10
+
11
+ """, unsafe_allow_html=True)
images/b3.png ADDED
images/home_image_2.jpeg ADDED
login.py ADDED
@@ -0,0 +1,81 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import matplotlib
2
+ matplotlib.use('Agg')
3
+
4
+ import streamlit as st
5
+
6
+ import pandas as pd
7
+
8
+ def login_section():
9
+
10
+ #código para ativar bootstrap css
11
+ st.markdown(
12
+ """
13
+ <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css" integrity="sha384-Gn5384xqQ1aoWXA+058RXPxPg6fy4IWvTNh0E263XmFcJlSAwiGgFAW/dAiS6JXm" crossorigin="anonymous">
14
+ <script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/js/bootstrap.min.js" integrity="sha384-JZR6Spejh4U02d8jOt6vLEHfe/JQGiRRSQQxSfFWpi1MquVdAyjUar5+76PVCmYl" crossorigin="anonymous"></script>
15
+ """,unsafe_allow_html=True
16
+ )
17
+
18
+ users = pd.read_csv('users.csv', sep=';',dtype=str)
19
+
20
+ col1, col2, col3,col4,col5 = st.columns([1,1,1,1,1])
21
+ with col2:
22
+
23
+ st.header('Login')
24
+
25
+ username = st.text_input("User Name")
26
+ password = st.text_input("Password",type='password')
27
+
28
+ if 'username' not in st.session_state:
29
+ st.session_state['username'] = [username]
30
+
31
+ if 'loged' not in st.session_state:
32
+ st.session_state['loged'] = ''
33
+
34
+ if st.button('Login'):
35
+ if len(users[users['user'].str.contains(username, na=False)]) > 0:
36
+ if len(users[users['pass'].str.contains(password, na=False)]) > 0:
37
+ st.session_state['loged'] = 'Logado'
38
+
39
+ else:
40
+ st.text('Senha incorreta')
41
+
42
+ if password == users['pass'][0]:
43
+ st.write('acesso manager')
44
+ st.dataframe(users)
45
+
46
+
47
+ #esse código iniciará em outras páginas as funções para quem estiver logado
48
+ if st.session_state['loged']:
49
+ st.write(st.session_state['loged'])
50
+
51
+ with col4:
52
+
53
+ st.header('Cadastro')
54
+
55
+ cad_nome = st.text_input("Nome")
56
+ cad_email = st.text_input("Email")
57
+ cad_username = st.text_input("Cadastre um nome de usuário")
58
+ cad_password = st.text_input("Cadastre uma senha",type='password')
59
+ cad_password_2 = st.text_input("Repita a senha",type='password')
60
+ cad_premium = 'não'
61
+
62
+ df_cad = pd.DataFrame( [[cad_nome,cad_username,cad_password,cad_email, cad_premium]] ,columns=['name','user','pass','email','premium'] )
63
+
64
+ if st.button('Cadastrar'):
65
+ if len(users[users['user'].str.contains(cad_username, na=False)]) == 0:
66
+ dfs = [users,df_cad]
67
+ users = pd.concat( dfs,axis=0,ignore_index=True)
68
+ users.to_csv('users.csv', index=False, sep=';')
69
+ st.text('Cadastro efetuado com sucesso, realize o Login')
70
+ else:
71
+ st.text('Usuário já existente')
72
+
73
+
74
+
75
+
76
+
77
+
78
+
79
+
80
+
81
+
pag1.py ADDED
@@ -0,0 +1,466 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import matplotlib
2
+ matplotlib.use('Agg')
3
+
4
+ #from turtle import width
5
+ import streamlit as st
6
+ from yahooquery import Ticker
7
+ import pandas as pd
8
+ import yfinance as yf
9
+ # from fbprophet import Prophet
10
+ import numpy as np
11
+ import plotly.graph_objects as go
12
+
13
+ import scrap as scraping
14
+
15
+ import style as style
16
+
17
+ import html01 as html01
18
+
19
+
20
+ def analise_tecnica_fundamentalista():
21
+
22
+ #código para ativar bootstrap css
23
+ st.markdown(
24
+ """
25
+ <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css" integrity="sha384-Gn5384xqQ1aoWXA+058RXPxPg6fy4IWvTNh0E263XmFcJlSAwiGgFAW/dAiS6JXm" crossorigin="anonymous">
26
+ <script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/js/bootstrap.min.js" integrity="sha384-JZR6Spejh4U02d8jOt6vLEHfe/JQGiRRSQQxSfFWpi1MquVdAyjUar5+76PVCmYl" crossorigin="anonymous"></script>
27
+ """,unsafe_allow_html=True
28
+ )
29
+
30
+ col1, col2,col3 = st.columns([0.1,0.4,0.1])
31
+ with col2:
32
+ st.title('Análise Técnica')
33
+ st.subheader('Escolha o ativo que deseja analisar e pressione enter')
34
+ #nome_do_ativo = st.text_input('Nome do ativo ex: PETR4, VALE3, WEGE3...')
35
+ codigo_nome = pd.read_excel('data/classification_b3.xlsx')
36
+ nome_do_ativo = st.selectbox('Esoolha a ação que deseja analisar', (codigo_nome['TICKER']) )
37
+
38
+ style.space(1)
39
+
40
+ if nome_do_ativo != "":
41
+ nome_do_ativo = str(nome_do_ativo + '.SA').upper()
42
+ df = Ticker(nome_do_ativo,country='Brazil')
43
+ time = df.history( period='max')
44
+
45
+ # ------------------------------ RESUMO ----------------------------
46
+
47
+ resumo = pd.DataFrame(df.summary_detail)
48
+ resumo = resumo.transpose()
49
+ if len(nome_do_ativo) == 8:
50
+ fundamentus = scraping.get_specific_data(nome_do_ativo[:5])
51
+ fundamentus = pd.DataFrame([fundamentus])
52
+
53
+ try:
54
+
55
+ pfizer = yf.Ticker(nome_do_ativo)
56
+ info = pfizer.info
57
+ if info['recommendationKey'] == 'buy':
58
+ recomendation = 'alta'
59
+ else:
60
+ recomendation = 'baixa'
61
+
62
+ #KPIS
63
+ metric1, metric2, metric3, metric4 = st.columns([1,1,1,1])
64
+
65
+ with metric1:
66
+ st.metric(label="P/L",value=f"{fundamentus['P/L'][0]}")
67
+ with metric2:
68
+ st.metric(label="P/VP",value=f"{fundamentus['P/VP'][0]}")
69
+ with metric3:
70
+ st.metric(label="Tendência", value=f"{recomendation}")
71
+ with metric4:
72
+ st.metric(label="Próximo dividendo", value=f"{pfizer.calendar.transpose()['Earnings Date'].dt.strftime('%d/%m/%Y')[0]}")
73
+
74
+ style.space(2)
75
+
76
+ #card info
77
+ html01.card_info(info['longName'], info['sector'], info['industry'], info['longBusinessSummary'], info['website'])
78
+
79
+ style.space(2)
80
+
81
+ except:
82
+ exit
83
+
84
+ else:
85
+ st.write('---------------------------------------------------------------------')
86
+ st.dataframe(resumo)
87
+ pfizer = yf.Ticker(nome_do_ativo)
88
+ info = pfizer.info
89
+ st.title('Company Profile')
90
+ st.subheader(info['longName'])
91
+ try:
92
+ st.markdown('** Sector **: ' + info['sector'])
93
+ st.markdown('** Industry **: ' + info['industry'])
94
+ st.markdown('** Website **: ' + info['website'])
95
+ except:
96
+ exit
97
+
98
+ # ------------------------------ GRÁFICOS DE RENDIMENTO ----------------------------
99
+
100
+ if len(nome_do_ativo) == 8:
101
+
102
+ import datetime
103
+ fundamentalist = df.income_statement()
104
+ fundamentalist['data'] = fundamentalist['asOfDate'].dt.strftime('%d/%m/%Y')
105
+ fundamentalist = fundamentalist.drop_duplicates('asOfDate')
106
+ fundamentalist = fundamentalist.loc[fundamentalist['periodType'] == '12M']
107
+
108
+ #volatilidade
109
+ TRADING_DAYS = 360
110
+ returns = np.log(time['close']/time['close'].shift(1))
111
+ returns.fillna(0, inplace=True)
112
+ volatility = returns.rolling(window=TRADING_DAYS).std()*np.sqrt(TRADING_DAYS)
113
+ vol = pd.DataFrame(volatility.iloc[-360:]).reset_index()
114
+
115
+ #sharpe ratio
116
+ sharpe_ratio = returns.mean()/volatility
117
+ sharpe = pd.DataFrame(sharpe_ratio.iloc[-360:]).reset_index()
118
+
119
+ div = time.reset_index()
120
+ div['year'] = pd.to_datetime(div['date']).dt.strftime('%Y')
121
+ div_group = div.groupby('year').agg({'close':'mean','dividends':'sum'})
122
+ div_group['dividendo(%)'] = round((div_group['dividends'] * 100 ) / div_group['close'],4)
123
+
124
+ from plotly.subplots import make_subplots
125
+ fig = make_subplots(
126
+ rows=3, cols=2,
127
+ specs=[[{"type": "bar"}, {"type": "bar"}],
128
+ [{"type": "bar"}, {"type": "bar"}],
129
+ [{"type": "scatter"}, {"type": "scatter"}]],
130
+ subplot_titles=("Receita Total","Lucro",'Dividendos (%)','Dividendos unitário R$','Volatilidade', 'Sharpe ratio (Retorno/ Risco)')
131
+ )
132
+
133
+ fig.add_trace(go.Bar(x =pfizer.financials.transpose().index, y=pfizer.financials.transpose()['Total Revenue']), row=1, col=1)
134
+
135
+ fig.add_trace(go.Bar(x =pfizer.financials.transpose().index, y=pfizer.financials.transpose()['Net Income From Continuing Ops']), row=1, col=2)
136
+
137
+ fig.add_trace(go.Bar(x =div_group.reset_index().tail(5)['year'], y=div_group.reset_index().tail(5)['dividendo(%)']),row=2, col=1)
138
+
139
+ fig.add_trace(go.Bar(x =div_group.reset_index().tail(5)['year'], y=div_group.reset_index().tail(5)['dividends']),row=2, col=2)
140
+
141
+ fig.add_trace(go.Scatter(x =vol['date'], y=vol['close']),row=3, col=1)
142
+
143
+ fig.add_trace(go.Scatter(x =sharpe['date'], y=sharpe['close']),row=3, col=2)
144
+
145
+ fig.update_layout( height=800, width=800 ,showlegend=False, paper_bgcolor='rgba(255,255,255,0.9)', plot_bgcolor='rgba(255,255,255,0.9)')
146
+ fig.update_yaxes(showgrid=True, gridwidth=0.1, gridcolor = 'rgb(240,238,238)')
147
+
148
+ col1, col2, col3 = st.columns([1,8,1])
149
+ #with col2:
150
+ st.plotly_chart(fig,use_container_width=True)
151
+
152
+
153
+ else:
154
+ #volatilidade
155
+ TRADING_DAYS = 160
156
+ returns = np.log(time['close']/time['close'].shift(1))
157
+ returns.fillna(0, inplace=True)
158
+ volatility = returns.rolling(window=TRADING_DAYS).std()*np.sqrt(TRADING_DAYS)
159
+ vol = pd.DataFrame(volatility.iloc[-160:]).reset_index()
160
+
161
+ #sharpe ratio
162
+ sharpe_ratio = returns.mean()/volatility
163
+ sharpe = pd.DataFrame(sharpe_ratio.iloc[-160:]).reset_index()
164
+
165
+ from plotly.subplots import make_subplots
166
+ fig = make_subplots(
167
+ rows=1, cols=2,
168
+ specs=[[{"type": "scatter"}, {"type": "scatter"}]],
169
+ subplot_titles=('Volatilidade', 'Sharpe ratio (Retorno/ Risco)')
170
+ )
171
+
172
+ fig.add_trace(go.Scatter(x =vol['date'], y=vol['close']),row=1, col=1)
173
+
174
+ fig.add_trace(go.Scatter(x =sharpe['date'], y=sharpe['close']),row=1, col=2)
175
+
176
+ fig.update_layout( height=800, width=800 ,showlegend=False, paper_bgcolor='rgba(255,255,255,0.9)', plot_bgcolor='rgba(255,255,255,0.9)')
177
+ fig.update_yaxes(showgrid=True, gridwidth=0.1, gridcolor = 'rgb(240,238,238)')
178
+
179
+
180
+ col1, col2, col3 = st.columns([1,8,1])
181
+ #with col2:
182
+ st.plotly_chart(fig,use_container_width=True)
183
+
184
+ # ------------------------------ GRÁFICOS DE Candlestick----------------------------
185
+ with st.expander("Entenda o gráfico de Candlestick, clique para saber mais"):
186
+ st.write("""Gráfico de Candlestick , O formato contém os valores dos preços que a ação atingiu durante o período de tempo que está sendo analisado. São os preços de:""")
187
+ st.write('Abertura: preço pelo qual foi fechado o primeiro negócio do período')
188
+ st.write('Fechamento: preço pelo qual foi fechado o último negócio do período')
189
+ st.write('Máximo: maior preço negociado no período')
190
+ st.write('Mínimo: menor preço negociado no período')
191
+
192
+ fig = make_subplots(rows=2, cols=1, shared_xaxes=True,
193
+ vertical_spacing=0.03, subplot_titles=('Candlestick', 'Volume'),
194
+ row_width=[0.2, 0.7])
195
+
196
+ # Plot OHLC on 1st row
197
+ fig.add_trace(go.Candlestick(x=time.reset_index()['date'][-90:],
198
+ open=time['open'][-90:], high=time['high'][-90:],
199
+ low=time['low'][-90:], close=time['close'][-90:], name="OHLC"),
200
+ row=1, col=1)
201
+
202
+ # Bar trace for volumes on 2nd row without legend
203
+ fig.add_trace(go.Bar(x=time.reset_index()['date'][-90:], y=time['volume'][-90:], showlegend=False), row=2, col=1)
204
+
205
+ # Do not show OHLC's rangeslider plot
206
+ fig.update(layout_xaxis_rangeslider_visible=False)
207
+
208
+ fig.update_layout( height=600, showlegend=False, paper_bgcolor='rgba(255,255,255,0.9)', plot_bgcolor='rgba(255,255,255,0.9)') #width=800 ,
209
+ fig.update_yaxes(showgrid=True, gridwidth=0.1, gridcolor = 'rgb(240,238,238)')
210
+
211
+
212
+
213
+ st.plotly_chart(fig,use_container_width=True)
214
+
215
+ # ------------------------------ GRÁFICOS DE Retorno acumulado----------------------------
216
+ with st.expander("Entenda o gráfico de Retorno acumulado, clique para saber mais"):
217
+ st.write("""Gráfico de Retorno acumulado, Acúmulo de retorno calculado desde a data de início escolhida até o dia de hoje.""")
218
+
219
+ layout = go.Layout(title="Retorno acumulado",xaxis=dict(title="Data"), yaxis=dict(title="Retorno"))
220
+ fig = go.Figure(layout = layout)
221
+ fig.add_trace(go.Scatter(x=time.reset_index()['date'][-365:], y=time.reset_index()['close'][-365:].pct_change().cumsum(), mode='lines', line_width=3,line_color='rgb(0,0,0)'))
222
+
223
+ 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)')
224
+ fig.update_yaxes(showgrid=True, gridwidth=0.1, gridcolor = 'rgb(240,238,238)')
225
+
226
+ st.plotly_chart(fig,use_container_width=True)
227
+
228
+ # ------------------------------ GRÁFICOS DE Médias móveis----------------------------
229
+ with st.expander("Entenda o gráfico de Médias móveis, clique para saber mais"):
230
+ st.write("""Gráfico de Médias móveis, Cada ponto no gráfico representa a média dos últimos x dias, exemplo MM20 = média móvel dos última 20 dias.""")
231
+ st.write("""Com ela, é possível identificar o equilíbrio dos preços no mercado, observando tendências de alta, neutra ou baixa. A representação gráfica das Médias Móveis é normalmente feita por uma linha, que se movimenta conforme os dados novos recebidos para o cálculo.""")
232
+
233
+ rolling_200 = time['close'].rolling(window=200)
234
+ rolling_mean_200 = rolling_200.mean()
235
+
236
+ rolling_50 = time['close'].rolling(window=72)
237
+ rolling_mean_50 = rolling_50.mean()
238
+
239
+ rolling_20 = time['close'].rolling(window=20)
240
+ rolling_mean_20 = rolling_20.mean()
241
+
242
+ rolling_10 = time['close'].rolling(window=9)
243
+ rolling_mean_10 = rolling_10.mean()
244
+
245
+ layout = go.Layout(title="Médias móveis - ative ou desative clicando na legenda da média",xaxis=dict(title="Data"), yaxis=dict(title="Preço R$"))
246
+ fig = go.Figure(layout = layout)
247
+ fig.add_trace(go.Scatter(x=time.reset_index()['date'][-120:], y=time["close"][-120:], mode='lines', line_width=3,name='Real',line_color='rgb(0,0,0)'))
248
+ fig.add_trace(go.Scatter(x=time.reset_index()['date'][-120:], y=rolling_mean_200[-120:],mode='lines',name='MM(200)',opacity = 0.6))
249
+ fig.add_trace(go.Scatter(x=time.reset_index()['date'][-120:], y=rolling_mean_50[-120:],mode='lines',name='MM(72)',opacity = 0.6))
250
+ fig.add_trace(go.Scatter(x=time.reset_index()['date'][-120:], y=rolling_mean_20[-120:],mode='lines',name='MM(20)',opacity = 0.6))
251
+ fig.add_trace(go.Scatter(x=time.reset_index()['date'][-120:], y=rolling_mean_10[-120:],mode='lines',name='MM(9)',opacity = 0.6,line_color='rgb(100,149,237)'))
252
+
253
+ fig.update_yaxes(showgrid=True, gridwidth=0.1, gridcolor = 'rgb(240,238,238)')
254
+ fig.update_layout(autosize=True, height=600, width=800 ,showlegend=True, paper_bgcolor='rgba(255,255,255,0.9)', plot_bgcolor='rgba(255,255,255,0.9)')
255
+
256
+
257
+ st.plotly_chart(fig,use_container_width=True)
258
+
259
+ # ------------------------------ GRÁFICOS DE Retração de Fibonacci----------------------------
260
+ with st.expander("Entenda o gráfico de Retração de Fibonacci, clique para saber mais"):
261
+ st.write("""Gráfico de Retração de Fibonacci, A retração de Fibonacci é composta por linhas horizontais que cortam a série de preços. A distância entre essas linhas varia obedecendo a chamada série numérica de Fibonacci. Na análise técnica esses valores são expressos em porcentagem e são: 100%, 61,8%, 38,2%, 23,6%, 0%.""")
262
+ st.write("""Muito utilizado para tentar identificar uma tendência de alta ou de baixa. Uma das técnicas é analisar se a ação caiu até a linha de 38,2% (verde) para voltar a subir (retração com tendência de alta) ou se caiu passando os 38,2% pode representar uma tendência de baixa ou alta com pouca força.""")
263
+ st.write('Tente sempre escolher a quantidade de dias analisados para começar a análise após o maior fundo de baixa histórico')
264
+ time_fibo = time.copy()
265
+
266
+
267
+ periodo_fibonacci = int(st.number_input(label='periodo fibonacci - traçada do menor valor encontrado no período de tempo setado abaixo até o maior valor encontrado para frente',value= 45 ))
268
+
269
+ Price_Min =time_fibo[-periodo_fibonacci:]['low'].min()
270
+ Price_Max =time_fibo[-periodo_fibonacci:]['high'].max()
271
+
272
+ Diff = Price_Max-Price_Min
273
+ level1 = Price_Max - 0.236 * Diff
274
+ level2 = Price_Max - 0.382 * Diff
275
+ level3 = Price_Max - 0.618 * Diff
276
+
277
+ # st.write ('0% >>' f'{round(Price_Max,2)}')
278
+ # st.write ('23,6% >>' f'{round(level1,2)}')
279
+ # st.write ('38,2% >>' f'{round(level2,2)}')
280
+ # st.write ('61,8% >>' f'{round(level3,2)}')
281
+ # st.write ('100% >>' f'{round(Price_Min,2)}')
282
+
283
+ time_fibo['Price_Min'] = Price_Min
284
+ time_fibo['level1'] = level1
285
+ time_fibo['level2'] = level2
286
+ time_fibo['level3'] = level3
287
+ time_fibo['Price_Max'] = Price_Max
288
+
289
+ layout = go.Layout(title=f'Retração de Fibonacci',xaxis=dict(title="Data"), yaxis=dict(title="Preço"))
290
+ fig = go.Figure(layout = layout)
291
+ fig.add_trace(go.Scatter(x=time_fibo[-periodo_fibonacci:].reset_index()['date'], y=time_fibo[-periodo_fibonacci:].close, mode='lines', line_width=3,name='Preço real',line_color='rgb(0,0,0)'))
292
+ fig.add_trace(go.Scatter(x=time_fibo[-periodo_fibonacci:].reset_index()['date'], y=time_fibo[-periodo_fibonacci:].Price_Min, mode='lines', line_width=0.5,name='100%',line_color='rgb(255,0,0)',))
293
+ fig.add_trace(go.Scatter(x=time_fibo[-periodo_fibonacci:].reset_index()['date'], y=time_fibo[-periodo_fibonacci:].level3, mode='lines', line_width=0.5,name='61,8%',line_color='rgb(255,255,0)',fill= 'tonexty', fillcolor ="rgba(255, 0, 0, 0.2)"))
294
+ fig.add_trace(go.Scatter(x=time_fibo[-periodo_fibonacci:].reset_index()['date'], y=time_fibo[-periodo_fibonacci:].level2, mode='lines', line_width=0.5,name='38,2%',line_color='rgb(0,128,0)',fill= 'tonexty', fillcolor ="rgba(255, 255, 0, 0.2)"))
295
+ fig.add_trace(go.Scatter(x=time_fibo[-periodo_fibonacci:].reset_index()['date'], y=time_fibo[-periodo_fibonacci:].level1, mode='lines', line_width=0.5,name='23,6%',line_color='rgb(128,128,128)',fill= 'tonexty', fillcolor ="rgba(0, 128, 0, 0.2)"))
296
+ fig.add_trace(go.Scatter(x=time_fibo[-periodo_fibonacci:].reset_index()['date'], y=time_fibo[-periodo_fibonacci:].Price_Max, mode='lines', line_width=0.5,name='0%',line_color='rgb(0,0,255)',fill= 'tonexty', fillcolor ="rgba(128, 128, 128, 0.2)"))
297
+
298
+ 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)')
299
+ fig.update_yaxes(showgrid=True, gridwidth=0.1, gridcolor = 'rgb(240,238,238)')
300
+
301
+ st.plotly_chart(fig,use_container_width=True)
302
+
303
+ # ------------------------------ GRÁFICOS DE RSI----------------------------
304
+ try:
305
+
306
+ delta = time['close'][-periodo_RSI:].diff()
307
+ up, down = delta.copy(), delta.copy()
308
+
309
+ up[up < 0] = 0
310
+ down[down > 0] = 0
311
+
312
+ period = 14
313
+
314
+ rUp = up.ewm(com=period - 1, adjust=False).mean()
315
+ rDown = down.ewm(com=period - 1, adjust=False).mean().abs()
316
+
317
+ time['RSI_' + str(period)] = 100 - 100 / (1 + rUp / rDown)
318
+ time['RSI_' + str(period)].fillna(0, inplace=True)
319
+
320
+ layout = go.Layout(title=f'RSI {periodo_RSI}',xaxis=dict(title="Data"), yaxis=dict(title="%RSI"))
321
+ fig = go.Figure(layout = layout)
322
+ fig.add_trace(go.Scatter(x=time.reset_index()['date'][-periodo_RSI:], y=round(time['RSI_14'][-periodo_RSI:],2), mode='lines', line_width=3,name=f'RSI {periodo_RSI}',line_color='rgb(0,0,0)'))
323
+
324
+ 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)')
325
+ fig.update_yaxes(showgrid=True, gridwidth=0.1, gridcolor = 'rgb(240,238,238)')
326
+
327
+ periodo_RSI = int(st.number_input(label='periodo RSI',value=90))
328
+
329
+ with st.expander("Entenda o gráfico de Índice de Força Relativa (RSI), clique para saber mais"):
330
+ st.write("""Gráfico de Índice de Força Relativa (RSI), é um indicador versátil que mede a velocidade e a mudança do movimento dos preços. O RSI pode ser usado para: Determine quando um instrumento está sobrecomprado ou sobrevendido.""")
331
+ st.write('Comprar ativos que apresentem um baixo valor de RSI pode ser um bom indicador de desconto!')
332
+
333
+ st.plotly_chart(fig,use_container_width=True)
334
+
335
+ except:
336
+ exit
337
+
338
+ # ------------------------------ GRÁFICOS DE pivôs----------------------------
339
+ with st.expander("Entenda o gráfico de pivôs, clique para saber mais"):
340
+ st.write("""O Pivot Point pode ser utilizado para calcular as possíveis zonas de suporte e resistência do ativo para o período desejado, o que ajuda a entender a pressão compradora (suporte) e a pressão vendedora (resistência).""")
341
+ st.write(' Os pontos do pivô podem ser utilizados como valores de stop-loss (preço de saída com perda) ou stop-gain (preço de saída com lucro) por exemplo.')
342
+
343
+
344
+
345
+ periodo_pivo = int(st.number_input(label='periodo pivô',value=20))
346
+
347
+ time['PP'] = pd.Series((time['high'] + time['low'] + time['close']) /3)
348
+ time['R1'] = pd.Series(2 * time['PP'] - time['low'])
349
+ time['S1'] = pd.Series(2 * time['PP'] - time['high'])
350
+ time['R2'] = pd.Series(time['PP'] + time['high'] - time['low'])
351
+ time['S2'] = pd.Series(time['PP'] - time['high'] + time['low'])
352
+
353
+ layout = go.Layout(title=f'Pivô',xaxis=dict(title="Data"), yaxis=dict(title="Preço"))
354
+ fig = go.Figure(layout = layout)
355
+ fig.add_trace(go.Scatter(x=time.reset_index()['date'][-periodo_pivo:], y=round(time['close'][-periodo_pivo:],2), mode='lines', line_width=3,name=f'preço real',line_color='rgb(0,0,0)'))
356
+ fig.add_trace(go.Scatter(x=time.reset_index()['date'][-periodo_pivo:], y=round(time['PP'][-periodo_pivo:],2), mode='lines', line_width=1,name=f'Ponto do pivô',line_color='rgb(0,128,0)'))
357
+ fig.add_trace(go.Scatter(x=time.reset_index()['date'][-periodo_pivo:], y=round(time['R1'][-periodo_pivo:],2), mode='lines', line_width=1,name=f'Resistência 1',line_color='rgb(100,149,237)'))
358
+ fig.add_trace(go.Scatter(x=time.reset_index()['date'][-periodo_pivo:], y=round(time['S1'][-periodo_pivo:],2), mode='lines', line_width=1,name=f'Suporte 1',line_color='rgb(100,149,237)'))
359
+ fig.add_trace(go.Scatter(x=time.reset_index()['date'][-periodo_pivo:], y=round(time['R2'][-periodo_pivo:],2), mode='lines', line_width=1,name=f'Resistência 2',line_color='rgb(255,0,0)'))
360
+ fig.add_trace(go.Scatter(x=time.reset_index()['date'][-periodo_pivo:], y=round(time['S2'][-periodo_pivo:],2), mode='lines', line_width=1,name=f'Suporte 2',line_color='rgb(255,0,0)'))
361
+
362
+ 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)')
363
+ fig.update_yaxes(showgrid=True, gridwidth=0.1, gridcolor = 'rgb(240,238,238)')
364
+
365
+ st.plotly_chart(fig,use_container_width=True)
366
+
367
+ # ------------------------------ GRÁFICOS DE Bolinger----------------------------
368
+ with st.expander("Entenda o gráfico de Bolinger, clique para saber mais"):
369
+ st.write("""Quando o preço do ativo ultrapassa a banda superior, observamos uma tendência de alta do ativo. Por outro lado, se o preço fica abaixo da banda inferior, há então uma tendência de baixa. Entretanto, deve-se ficar atento aos sinais de força dos ativos ao ultrapassar as bandas.""")
370
+
371
+ periodo_bolinger = int(st.number_input(label='periodo Bolinger',value=180))
372
+
373
+ time['MA20'] = time['close'].rolling(20).mean()
374
+ time['20 Day STD'] = time['close'].rolling(window=20).std()
375
+ time['Upper Band'] = time['MA20'] + (time['20 Day STD'] * 2)
376
+ time['Lower Band'] = time['MA20'] - (time['20 Day STD'] * 2)
377
+
378
+ layout = go.Layout(title=f'Banda de Bolinger',xaxis=dict(title="Data"), yaxis=dict(title="Preço"))
379
+ fig = go.Figure(layout = layout)
380
+ fig.add_trace(go.Scatter(x=time.reset_index()['date'][-periodo_bolinger:], y=round(time['Upper Band'][-periodo_bolinger:],2), mode='lines', line_width=1,name=f'Banda superior',line_color='rgb(255,0,0)'))
381
+ fig.add_trace(go.Scatter(x=time.reset_index()['date'][-periodo_bolinger:], y=round(time['Lower Band'][-periodo_bolinger:],2), mode='lines', line_width=1,name=f'Banda inferior',line_color='rgb(255,0,0)',fill= 'tonexty', fillcolor ="rgba(255, 0, 0, 0.1)",opacity=0.2))
382
+ fig.add_trace(go.Scatter(x=time.reset_index()['date'][-periodo_bolinger:], y=round(time['close'][-periodo_bolinger:],2), mode='lines', line_width=3,name=f'preço real',line_color='rgb(0,0,0)'))
383
+ fig.add_trace(go.Scatter(x=time.reset_index()['date'][-periodo_bolinger:], y=round(time['MA20'][-periodo_bolinger:],2), mode='lines', line_width=2,name=f'MM 20',line_color='rgb(0,128,0)'))
384
+
385
+ 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)')
386
+ fig.update_yaxes(showgrid=True, gridwidth=0.1, gridcolor = 'rgb(240,238,238)')
387
+
388
+ st.plotly_chart(fig,use_container_width=True)
389
+
390
+ #with st.expander("Entenda o gráfico de Previsão, clique para saber mais"):
391
+ # st.write("""Previsão que leva em conta apenas o movimento gráfico histórico do ativo, porém sabemos que o preço do ativo varia por outros diversos fatores. Com isso, esse é um parâmetro apenas como expectativa caso todos os outros fatores envolvidos se mantivessem.""")
392
+
393
+
394
+ # # ------------------------------ Previsões----------------------------
395
+
396
+ # st.subheader('Previsões')
397
+
398
+ # st.write('As previsões são feitas levando em conta apenas o movimento gráfico, porém o movimento do preço de um ativo é influenciado por diversos outros fatores, com isso, deve se considerar as previsões como uma hipótese de o preço do ativo variar somente pela sua variação gráfica')
399
+
400
+ # st.write('Previsão considerando os últimos 365 dias, pode ser entendida como uma tendência dos dados segundo o último ano')
401
+
402
+ # st.write('Opção de alterar a previsão: caso esteja buscando resultados a curto prazo é possível alterar o "periodo analisado" para fazer previsões apenas com base nos últimos x dias. Neste caso o movimento gráfico para trás dos dias selecionados não serão levados em conta')
403
+ # periodo_analisado = int(st.number_input(label='período analisado (dias de resultados passados)',value=360))
404
+
405
+ # st.write('Opção de alterar a previsão: possibilidade de prever resultados futuros por mais de 30 dias')
406
+ # periodo_futuro = int(st.number_input(label='período futuro a prever (dias)',value=30))
407
+
408
+ # time = time.reset_index()
409
+ # time = time[['date','close']]
410
+ # time.columns = ['ds','y']
411
+
412
+ # #Modelling
413
+ # m = Prophet()
414
+ # m.fit(time[-periodo_analisado:])
415
+ # future = m.make_future_dataframe(periods= periodo_futuro, freq='B')
416
+ # forecast = m.predict(future[-periodo_futuro:])
417
+
418
+ # from fbprophet.plot import plot_plotly, plot_components_plotly
419
+
420
+ # fig1 = plot_plotly(m, forecast)
421
+ # fig1.update_layout( height=600, width=800 ,showlegend=False, paper_bgcolor='rgba(255,255,255,0.9)', plot_bgcolor='rgba(255,255,255,0.9)')
422
+ # fig1.update_yaxes(showgrid=True, gridwidth=0.1, gridcolor = 'rgb(240,238,238)')
423
+
424
+ # st.plotly_chart(fig1,use_container_width=True)
425
+
426
+ # st.subheader('Tendência diária e semanal')
427
+ # st.write('0 = segunda, 1 = terça, ... , 5 = sábado, 6 = domingo')
428
+ # fig2 = m.plot_components(forecast,uncertainty = False,weekly_start=1)
429
+
430
+
431
+ # st.plotly_chart(fig2,use_container_width=True)
432
+
433
+
434
+
435
+
436
+
437
+
438
+
439
+
440
+
441
+
442
+
443
+
444
+
445
+
446
+
447
+
448
+
449
+
450
+
451
+
452
+
453
+
454
+
455
+ #st.write('Previsão considerando as últimas semanas, pode ser entendida como uma tendência dos dados segundo os últimos dias. Leva em consideração diversos fatores como: Índice de força relativa RSI, oscilador estocástico %K, Indicador Willian %R além do movimento gráfico dos últimos dias')
456
+
457
+ #predict = stocker.predict.tomorrow(nome_do_ativo)
458
+
459
+ #st.write('Previsão para o dia:',f'{predict[2]}','é que a ação feche no valor de: R$',f'{predict[0]}')
460
+
461
+ #preço_ontem= round(time['y'][-1:].values[0],2)
462
+ #if predict[0] < preço_ontem:
463
+ #st.write('Previsão para o dia:',f'{predict[2]}','é que a ação caia de ',f'{preço_ontem}', 'para valor de: R$ ',f'{predict[0]}')
464
+ #else:
465
+ #st.write('Previsão para o dia:',f'{predict[2]}','é que a ação suba de ',f'{preço_ontem}', 'para valor de: R$ ',f'{predict[0]}')
466
+
pag2.py ADDED
@@ -0,0 +1,278 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from multiprocessing import Value
2
+ import matplotlib
3
+ matplotlib.use('Agg')
4
+
5
+ import streamlit as st
6
+ from yahooquery import Ticker
7
+ import pandas as pd
8
+ import numpy as np
9
+ import plotly.graph_objects as go
10
+ import datetime as dt
11
+ from collections import OrderedDict
12
+
13
+ import style as style
14
+
15
+
16
+
17
+ import scrap as scraping
18
+
19
+ def flatten(d):
20
+ '''
21
+ Flatten an OrderedDict object
22
+ '''
23
+ result = OrderedDict()
24
+ for k, v in d.items():
25
+ if isinstance(v, dict):
26
+ result.update(flatten(v))
27
+ else:
28
+ result[k] = v
29
+ return result
30
+
31
+
32
+ def comparacao_ativos():
33
+ #código para ativar bootstrap css
34
+ st.markdown(
35
+ """
36
+ <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css" integrity="sha384-Gn5384xqQ1aoWXA+058RXPxPg6fy4IWvTNh0E263XmFcJlSAwiGgFAW/dAiS6JXm" crossorigin="anonymous">
37
+ <script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/js/bootstrap.min.js" integrity="sha384-JZR6Spejh4U02d8jOt6vLEHfe/JQGiRRSQQxSfFWpi1MquVdAyjUar5+76PVCmYl" crossorigin="anonymous"></script>
38
+ """,unsafe_allow_html=True
39
+ )
40
+
41
+ col1, col2,col3 = st.columns([0.1,0.4,0.1])
42
+ with col2:
43
+ st.title('Comparação de ativos')
44
+ st.subheader('Escolha 4 ativos para comparar')
45
+ codigo_nome = pd.read_excel('data/classification_b3.xlsx')
46
+ nome_do_ativo1 = st.selectbox('Nome do 1º ativo', (codigo_nome['TICKER']),key=1 )
47
+ nome_do_ativo2 = st.selectbox('Nome do 2º ativo', (codigo_nome['TICKER']),key=2)
48
+ nome_do_ativo3 = st.selectbox('Nome do 3º ativo', (codigo_nome['TICKER']),key=3 )
49
+ nome_do_ativo4 = st.selectbox('Nome do 4º ativo', (codigo_nome['TICKER']),key=4 )
50
+ style.space(1)
51
+
52
+ if nome_do_ativo4 != "":
53
+ st.subheader('Analisando os dados')
54
+ nome_do_ativo1 = str(nome_do_ativo1 + '.SA').upper()
55
+ nome_do_ativo2 = str(nome_do_ativo2 + '.SA').upper()
56
+ nome_do_ativo3 = str(nome_do_ativo3 + '.SA').upper()
57
+ nome_do_ativo4 = str(nome_do_ativo4 + '.SA').upper()
58
+
59
+ df = Ticker([nome_do_ativo1,nome_do_ativo2,nome_do_ativo3,nome_do_ativo4],country='Brazil')
60
+ time = df.history( start='2020-01-01', end = (dt.datetime.today() + dt.timedelta(days=1)).strftime(format='20%y-%m-%d'))
61
+ lista = scraping.get_data()
62
+ todos = pd.DataFrame(flatten(lista).keys()).transpose()
63
+ todos.columns = todos.iloc[0]
64
+
65
+ for i in range(len(lista)):
66
+ todos = pd.concat([todos,pd.DataFrame(lista[i]).transpose()])
67
+
68
+ todos = todos.iloc[1:]
69
+
70
+
71
+ todos['P/L'] = todos['P/L'].str.replace('.','')
72
+ todos['DY'] = todos['DY'].str.replace('%','')
73
+ todos['Liq.2m.'] = todos['Liq.2m.'].str.replace('.','')
74
+ todos['Pat.Liq'] = todos['Pat.Liq'].str.replace('.','')
75
+ todos = todos.replace(',','.', regex=True)
76
+ todos = todos.apply(pd.to_numeric,errors='ignore').round(2)
77
+ todos.rename(columns={'cotacao': 'Cotação'}, inplace=True)
78
+ comparar = todos.loc[todos.index.isin([nome_do_ativo1[:5],nome_do_ativo2[:5],nome_do_ativo3[:5],nome_do_ativo4[:5]])]
79
+
80
+ st.dataframe(comparar)
81
+ # st.dataframe(comparar.style.format({"Cotação": "{:.2f}", "P/L": "{:.2f}", "P/VP": "{:.2f}", "P/Ativo": "{:.2f}"
82
+ # , "P/EBIT": "{:.2f}", "P/Ativ.Circ.Liq.": "{:.2f}", "EBITDA": "{:.2f}", "Liq.Corr.": "{:.2f}", "Liq.2m.": "{:.2f}"
83
+ # , "Pat.Liq": "{:.2f}", "Div.Brut/Pat.": "{:.2f}"
84
+ # }))
85
+
86
+
87
+ # ------------------------------ INÍCIO Comparação DY ---------------
88
+
89
+ col1, col2 = st.columns([0.5,0.5])
90
+ with col1:
91
+ layout = go.Layout(title="DY",xaxis=dict(title="Ativo"), yaxis=dict(title="DY %"))
92
+ fig = go.Figure(layout = layout)
93
+ fig.add_trace(go.Bar(x=comparar.sort_values('DY',ascending=True).index, y=comparar.sort_values('DY',ascending=True)['DY'] ))
94
+ fig.update_layout( height=500, showlegend=False, paper_bgcolor='rgba(255,255,255,0.9)', plot_bgcolor='rgba(255,255,255,0.9)')
95
+ fig.update_yaxes(showgrid=True, gridwidth=0.1, gridcolor = 'rgb(240,238,238)')
96
+
97
+ st.plotly_chart(fig,use_container_width=True)
98
+
99
+ # ------------------------------ INÍCIO Comparação P/L ---------------
100
+ with col2:
101
+ layout = go.Layout(title="P/L",xaxis=dict(title="Ativo"), yaxis=dict(title="P/L"))
102
+ fig = go.Figure(layout = layout)
103
+ fig.add_trace(go.Bar(x=comparar.sort_values('P/L',ascending=True).index, y=comparar.sort_values('P/L',ascending=True)['P/L'] ))
104
+ fig.update_layout( height=500, showlegend=False, paper_bgcolor='rgba(255,255,255,0.9)', plot_bgcolor='rgba(255,255,255,0.9)')
105
+ fig.update_yaxes(showgrid=True, gridwidth=0.1, gridcolor = 'rgb(240,238,238)')
106
+
107
+ st.plotly_chart(fig,use_container_width=True)
108
+
109
+ # ------------------------------ INÍCIO Comparação P/V---------------
110
+ with col1:
111
+ layout = go.Layout(title="P/VP",xaxis=dict(title="Ativo"), yaxis=dict(title="P/VP"))
112
+ fig = go.Figure(layout = layout)
113
+ fig.add_trace(go.Bar(x=comparar.sort_values('P/VP',ascending=True).index, y=comparar.sort_values('P/VP',ascending=True)['P/VP'] ))
114
+ fig.update_layout( height=500, showlegend=False, paper_bgcolor='rgba(255,255,255,0.9)', plot_bgcolor='rgba(255,255,255,0.9)')
115
+ fig.update_yaxes(showgrid=True, gridwidth=0.1, gridcolor = 'rgb(240,238,238)')
116
+
117
+ st.plotly_chart(fig,use_container_width=True)
118
+
119
+ # ------------------------------ INÍCIO Comparação P/L * P/VP---------------
120
+
121
+ with col2:
122
+ layout = go.Layout(title="P/L X P/VP",xaxis=dict(title="Ativo"), yaxis=dict(title="P/L X P/VP"))
123
+ fig = go.Figure(layout = layout)
124
+ fig.add_trace(go.Bar(x=comparar.index, y=comparar['P/L'] * comparar['P/VP'] ))
125
+ fig.update_layout( height=500, showlegend=False, paper_bgcolor='rgba(255,255,255,0.9)', plot_bgcolor='rgba(255,255,255,0.9)')
126
+ fig.update_yaxes(showgrid=True, gridwidth=0.1, gridcolor = 'rgb(240,238,238)')
127
+
128
+ st.plotly_chart(fig,use_container_width=True)
129
+
130
+ # ------------------------------ GRÁFICOS DE retorno acumulado----------------------------
131
+
132
+ periodo_inicio = int(st.number_input(label='periodo retorno acumulado',value=360))
133
+
134
+ ret = time.reset_index()
135
+ layout = go.Layout(title="Retorno acumulado",xaxis=dict(title="Data"), yaxis=dict(title="Retorno"))
136
+ fig = go.Figure(layout = layout)
137
+ for i in range(len(ret['symbol'].unique())):
138
+ fig.add_trace(go.Scatter(x=ret.loc[ret['symbol']==ret['symbol'].unique()[i]][-periodo_inicio:]['date'], y=ret.loc[ret['symbol']==ret['symbol'].unique()[i]][-periodo_inicio:]['close'].pct_change().cumsum(),mode='lines',name=ret.reset_index()['symbol'].unique()[i]))
139
+
140
+ fig.update_layout( height=500, showlegend=False, paper_bgcolor='rgba(255,255,255,0.9)', plot_bgcolor='rgba(255,255,255,0.9)')
141
+ fig.update_yaxes(showgrid=True, gridwidth=0.1, gridcolor = 'rgb(240,238,238)')
142
+
143
+ st.plotly_chart(fig,use_container_width=True)
144
+
145
+ # ------------------------------ GRÁFICOS DE MÉDIAS MÓVEIS 50----------------------------
146
+
147
+ rolling_50 = time['close'].rolling(window=50)
148
+ rolling_mean_50 = rolling_50.mean()
149
+ rolling_mean_50 = pd.DataFrame(rolling_mean_50.reset_index())
150
+ # mm50 = time.reset_index()
151
+
152
+
153
+ layout = go.Layout(title="MÉDIAS MÓVEIS 50",xaxis=dict(title="Data"), yaxis=dict(title="Preço R$"))
154
+ fig = go.Figure(layout = layout)
155
+ for i in range(len(rolling_mean_50['symbol'].unique())):
156
+ fig.add_trace(go.Scatter(x=rolling_mean_50.loc[rolling_mean_50['symbol']==rolling_mean_50['symbol'].unique()[i]]['date'], y=rolling_mean_50.loc[rolling_mean_50['symbol']==rolling_mean_50['symbol'].unique()[i]]['close'],mode='lines',name=time.reset_index()['symbol'].unique()[i]))
157
+
158
+ fig.update_layout( height=500, showlegend=False, paper_bgcolor='rgba(255,255,255,0.9)', plot_bgcolor='rgba(255,255,255,0.9)')
159
+ fig.update_yaxes(showgrid=True, gridwidth=0.1, gridcolor = 'rgb(240,238,238)')
160
+
161
+ st.plotly_chart(fig,use_container_width=True)
162
+
163
+ # ------------------------------ GRÁFICOS DE MÉDIAS MÓVEIS 20----------------------------
164
+
165
+ rolling_50 = time['close'].rolling(window=20)
166
+ rolling_mean_50 = rolling_50.mean()
167
+ rolling_mean_50 = pd.DataFrame(rolling_mean_50.reset_index())
168
+ # mm50 = time.reset_index()
169
+
170
+
171
+ layout = go.Layout(title="MÉDIAS MÓVEIS 20",xaxis=dict(title="Data"), yaxis=dict(title="Preço R$"))
172
+ fig = go.Figure(layout = layout)
173
+ for i in range(len(rolling_mean_50['symbol'].unique())):
174
+ fig.add_trace(go.Scatter(x=rolling_mean_50.loc[rolling_mean_50['symbol']==rolling_mean_50['symbol'].unique()[i]]['date'], y=rolling_mean_50.loc[rolling_mean_50['symbol']==rolling_mean_50['symbol'].unique()[i]]['close'],mode='lines',name=time.reset_index()['symbol'].unique()[i]))
175
+
176
+ fig.update_layout( height=500, showlegend=False, paper_bgcolor='rgba(255,255,255,0.9)', plot_bgcolor='rgba(255,255,255,0.9)')
177
+ fig.update_yaxes(showgrid=True, gridwidth=0.1, gridcolor = 'rgb(240,238,238)')
178
+
179
+ st.plotly_chart(fig,use_container_width=True)
180
+
181
+ # ------------------------------ GRÁFICOS DE volatilidade---------------------------
182
+ col1, col2 = st.columns([0.5,0.5])
183
+ with col1:
184
+ TRADING_DAYS = 360
185
+ returns = np.log(time['close']/time['close'].shift(1))
186
+ returns.fillna(0, inplace=True)
187
+ volatility = returns.rolling(window=TRADING_DAYS).std()*np.sqrt(TRADING_DAYS)
188
+ vol = pd.DataFrame(volatility).reset_index()
189
+ vol = vol.dropna()
190
+
191
+ layout = go.Layout(title=f"Volatilidade",xaxis=dict(title="Data"), yaxis=dict(title="Volatilidade"))
192
+ fig = go.Figure(layout = layout)
193
+ for i in range(len(vol['symbol'].unique())):
194
+ fig.add_trace(go.Scatter(x=vol.loc[vol['symbol']==vol['symbol'].unique()[i]]['date'], y=vol.loc[vol['symbol']==vol['symbol'].unique()[i]]['close'],name=vol['symbol'].unique()[i] ))
195
+ fig.update_layout( height=500, showlegend=False, paper_bgcolor='rgba(255,255,255,0.9)', plot_bgcolor='rgba(255,255,255,0.9)')
196
+ fig.update_yaxes(showgrid=True, gridwidth=0.1, gridcolor = 'rgb(240,238,238)')
197
+
198
+ st.plotly_chart(fig,use_container_width=True)
199
+
200
+ # ------------------------------ GRÁFICOS DE sharpe_ratio---------------------------
201
+ with col2:
202
+ sharpe_ratio = returns.mean()/volatility
203
+ sharpe = pd.DataFrame(sharpe_ratio).reset_index()
204
+ sharpe = sharpe.dropna()
205
+
206
+ layout = go.Layout(title=f"SHARP (Risco / Volatilidade)",xaxis=dict(title="Data"), yaxis=dict(title="Sharp"))
207
+ fig = go.Figure(layout = layout)
208
+ for i in range(len(sharpe['symbol'].unique())):
209
+ fig.add_trace(go.Scatter(x=sharpe.loc[sharpe['symbol']==sharpe['symbol'].unique()[i]]['date'], y=sharpe.loc[sharpe['symbol']==sharpe['symbol'].unique()[i]]['close'],name=sharpe['symbol'].unique()[i] ))
210
+ fig.update_layout( height=500, showlegend=False, paper_bgcolor='rgba(255,255,255,0.9)', plot_bgcolor='rgba(255,255,255,0.9)')
211
+ fig.update_yaxes(showgrid=True, gridwidth=0.1, gridcolor = 'rgb(240,238,238)')
212
+
213
+ st.plotly_chart(fig,use_container_width=True)
214
+
215
+ # ------------------------------ GRÁFICOS DE correlação--------------------------
216
+ try:
217
+
218
+ time = time.reset_index()
219
+ time = time[['symbol','date','close']]
220
+ df_1 = time.loc[time['symbol'] == time['symbol'].unique()[0]]
221
+ df_1 = df_1.set_index('date')
222
+ df_1.columns = df_1.columns.values + '-' + df_1.symbol.unique()
223
+ df_1.drop(df_1.columns[0],axis=1,inplace=True)
224
+ df_2 = time.loc[time['symbol'] == time['symbol'].unique()[1]]
225
+ df_2 = df_2.set_index('date')
226
+ df_2.columns = df_2.columns.values + '-' + df_2.symbol.unique()
227
+ df_2.drop(df_2.columns[0],axis=1,inplace=True)
228
+ df_3 = time.loc[time['symbol'] == time['symbol'].unique()[2]]
229
+ df_3 = df_3.set_index('date')
230
+ df_3.columns = df_3.columns.values + '-' + df_3.symbol.unique()
231
+ df_3.drop(df_3.columns[0],axis=1,inplace=True)
232
+ df_4 = time.loc[time['symbol'] == time['symbol'].unique()[3]]
233
+ df_4 = df_4.set_index('date')
234
+ df_4.columns = df_4.columns.values + '-' + df_4.symbol.unique()
235
+ df_4.drop(df_4.columns[0],axis=1,inplace=True)
236
+
237
+ merged = pd.merge(pd.merge(pd.merge(df_1,df_2,left_on=df_1.index,right_on=df_2.index,how='left'),df_3,left_on='key_0',right_on=df_3.index,how='left'),df_4,left_on='key_0',right_on=df_4.index,how='left').rename({'key_0':'date'},axis=1).set_index('date')
238
+
239
+ retscomp = merged.pct_change()
240
+
241
+
242
+ #plt.figure(figsize=(10,8))
243
+
244
+ #sns.heatmap(retscomp.corr(),annot=True)
245
+ #st.set_option('deprecation.showPyplotGlobalUse', False)
246
+ #st.pyplot()
247
+
248
+ import plotly.express as px
249
+
250
+ df = px.data.medals_wide(indexed=True)
251
+ fig = px.imshow(retscomp.corr(),color_continuous_scale='YlOrRd',labels=dict(x="Correlação"))
252
+ #fig.update_layout(autosize=False,width=1200,height=800, paper_bgcolor='rgba(0,0,0,0)', plot_bgcolor='rgba(0,0,0,0)')
253
+ fig.update_layout( height=500, showlegend=False, paper_bgcolor='rgba(255,255,255,0.9)', plot_bgcolor='rgba(255,255,255,0.9)')
254
+ fig.update_yaxes(showgrid=True, gridwidth=0.1, gridcolor = 'rgb(240,238,238)')
255
+ fig.update_xaxes(side="top")
256
+
257
+ st.plotly_chart(fig,use_container_width=True)
258
+ except:
259
+ exit
260
+
261
+ # ------------------------------ GRÁFICOS DE mapa de risco--------------------------
262
+
263
+ map = returns.reset_index()
264
+ layout = go.Layout(title=f"Mapa de Risco x Retorno",xaxis=dict(title="Retorno esperado"), yaxis=dict(title="Risco"))
265
+ fig = go.Figure(layout = layout)
266
+ for i in range(len(map['symbol'].unique())):
267
+ fig.add_trace(go.Scatter(x=[map.loc[map['symbol']==map['symbol'].unique()[i]]['close'].mean() * 100], y=[map.loc[map['symbol']==map['symbol'].unique()[i]]['close'].std() * 100],name=map['symbol'].unique()[i],marker=dict(size=30)))
268
+ #fig.add_trace(go.Scatter(x=[map['close'].mean()], y=[map['close'].std()],text=map['symbol'].unique()))
269
+ fig.update_xaxes(zeroline=True, zerolinewidth=2, zerolinecolor='Red')#, range=[-0.005, 0.01])
270
+ fig.update_yaxes(zeroline=True, zerolinewidth=2, zerolinecolor='Red')#, range=[-0.01, 0.1])
271
+ fig.update_traces(textposition='top center')
272
+ #fig.update_layout(autosize=False,width=800,height=600, paper_bgcolor='rgba(0,0,0,0)', plot_bgcolor='rgba(0,0,0,0)')
273
+
274
+ fig.update_layout( height=500, showlegend=False, paper_bgcolor='rgba(255,255,255,0.9)', plot_bgcolor='rgba(255,255,255,0.9)')
275
+ fig.update_yaxes(showgrid=True, gridwidth=0.1, gridcolor = 'rgb(240,238,238)')
276
+
277
+ st.plotly_chart(fig,use_container_width=True)
278
+
pag3.py ADDED
@@ -0,0 +1,124 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import matplotlib
2
+ matplotlib.use('Agg')
3
+
4
+ import streamlit as st
5
+ import pandas as pd
6
+ import numpy as np
7
+ from collections import OrderedDict
8
+
9
+ import scrap as scraping
10
+
11
+ from st_aggrid import AgGrid
12
+
13
+
14
+
15
+ def flatten(d):
16
+ '''
17
+ Flatten an OrderedDict object
18
+ '''
19
+ result = OrderedDict()
20
+ for k, v in d.items():
21
+ if isinstance(v, dict):
22
+ result.update(flatten(v))
23
+ else:
24
+ result[k] = v
25
+ return result
26
+
27
+ def descobrir_ativos():
28
+ #código para ativar bootstrap css
29
+ st.markdown(
30
+ """
31
+ <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css" integrity="sha384-Gn5384xqQ1aoWXA+058RXPxPg6fy4IWvTNh0E263XmFcJlSAwiGgFAW/dAiS6JXm" crossorigin="anonymous">
32
+ <script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/js/bootstrap.min.js" integrity="sha384-JZR6Spejh4U02d8jOt6vLEHfe/JQGiRRSQQxSfFWpi1MquVdAyjUar5+76PVCmYl" crossorigin="anonymous"></script>
33
+ """,unsafe_allow_html=True
34
+ )
35
+
36
+ col1, col2,col3 = st.columns([0.1,0.4,0.1])
37
+ with col2:
38
+ st.title('Analisar ativos com filtros e recomendações fundamentalistas')
39
+ st.title("")
40
+
41
+ st.subheader('Médias dos principais setores, subsetores e segmentos')
42
+
43
+ codigo_nome = pd.read_excel('data/classification_b3.xlsx')
44
+
45
+ lista = scraping.get_data()
46
+ todos = pd.DataFrame(flatten(lista).keys()).transpose()
47
+ todos.columns = todos.iloc[0]
48
+
49
+ for i in range(len(lista)):
50
+ todos = pd.concat([todos,pd.DataFrame(lista[i]).transpose()])
51
+
52
+ todos = todos.iloc[1:]
53
+ todos = todos.reset_index()
54
+
55
+
56
+
57
+ #tratamentos
58
+ todos['P/L'] = todos['P/L'].str.replace('.','')
59
+ todos['DY'] = todos['DY'].apply(lambda x: x[:-1])
60
+ todos['Cresc.5a %'] = todos['Cresc.5a'].apply(lambda x: x[:-1]).str.replace('.','').str.replace(',','.').astype(float)
61
+ todos['ROE'] = todos['ROE'].apply(lambda x: x[:-1]).str.replace('.','').str.replace(',','.').astype(float)
62
+ todos['Pat.Liq'] = todos['Pat.Liq'].str.replace('.','')
63
+ todos = todos.replace(',','.', regex=True)
64
+ todos = todos.apply(pd.to_numeric,errors='ignore')
65
+ todos.rename(columns={'cotacao': 'Cotação'}, inplace=True)
66
+ todos.rename(columns={'index': 'Código'}, inplace=True)
67
+
68
+
69
+
70
+ #criação colunas
71
+ todos['VPA'] = todos['Cotação'] / todos['P/VP']
72
+ todos['Lucro Líquido'] = (todos['ROE'] /100 ) * 1159400000
73
+ todos['Quantidade de ações'] = 1159400000 / todos['VPA']
74
+ todos['LPA'] = todos['Lucro Líquido'] / todos['Quantidade de ações']
75
+ todos['DPA'] = todos['Cotação'] * (todos['DY'] / 100)
76
+ todos['Payout'] = todos['DPA'] / todos['LPA']
77
+ todos['Expectativa de crescimento'] = (1 - todos['Payout']) * todos['ROE']
78
+ todos['Valuation Bazin'] = todos['DPA'] / 0.06
79
+ todos['Desconto Bazin'] = (todos['Valuation Bazin'] - todos['Cotação']) / todos['Valuation Bazin']
80
+ todos['Valuation Graham'] = (22.5 * todos['LPA'] * todos['VPA']) ** 0.5
81
+ todos['Desconto Graham'] = (todos['Valuation Graham'] - todos['Cotação']) / todos['Valuation Graham']
82
+
83
+ todos = todos.fillna(0)
84
+
85
+ merged = pd.merge(todos,codigo_nome,on='Código', how="left")
86
+ merged.replace([np.inf, -np.inf], 0, inplace=True)
87
+
88
+ #group
89
+ col1, col2, col3 = st.columns([1,1,1])
90
+ with col1:
91
+ grouped_setor = merged.groupby('Setor').mean()
92
+ st.dataframe(grouped_setor[['Expectativa de crescimento','Desconto Graham', 'Desconto Bazin']].sort_values('Expectativa de crescimento', ascending=False).reset_index())
93
+
94
+ with col2:
95
+ grouped_subsetor = merged.groupby('Subsetor').mean()
96
+ st.dataframe(grouped_subsetor[['Expectativa de crescimento','Desconto Graham', 'Desconto Bazin']].sort_values('Expectativa de crescimento', ascending=False).reset_index())
97
+
98
+ with col3:
99
+ grouped_subsetor = merged.groupby('Segmento').mean()
100
+ st.dataframe(grouped_subsetor[['Expectativa de crescimento','Desconto Graham', 'Desconto Bazin']].sort_values('Expectativa de crescimento', ascending=False).reset_index())
101
+
102
+
103
+
104
+ #filter
105
+ col1, col2,col3 = st.columns([0.1,0.4,0.1])
106
+ st.title('')
107
+
108
+ with col2:
109
+ st.write('Aplique alguns filtros na tabela')
110
+ exp_min = float(st.number_input(label='Expectativa de crescimento >',value=10,step=5))
111
+ desc_bazin = int(st.number_input(label='Desconto Bazin >',value=0.3,step=0.1))
112
+ desc_graham = float(st.number_input(label='Desconto Graham >',value=0.3,step=0.1))
113
+
114
+ filtred = merged.loc[(merged['Expectativa de crescimento']>= exp_min) & (merged['Desconto Bazin']>= desc_bazin) & (merged['Desconto Graham']>= desc_graham) & (merged['Desconto Bazin']!= 0)& (merged['Desconto Graham']!= 0)]
115
+ filtred = filtred.sort_values('Expectativa de crescimento',ascending=False)
116
+
117
+
118
+
119
+ #st.dataframe(merged[['Código','Cotação', 'Pat.Liq', 'Expectativa de crescimento','Desconto Bazin', 'Desconto Graham','Nome', 'Setor','Subsetor', 'Segmento']])
120
+ AgGrid(filtred[['Código','Cotação', 'Lucro Líquido', 'Expectativa de crescimento','Desconto Bazin', 'Desconto Graham','Nome', 'Setor','Subsetor', 'Segmento']].round(2))
121
+
122
+
123
+
124
+
pag4.py ADDED
@@ -0,0 +1,176 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import matplotlib
2
+ matplotlib.use('Agg')
3
+
4
+ import streamlit as st
5
+ import pandas as pd
6
+ import datetime as dt
7
+ from yahooquery import Ticker
8
+ import plotly.graph_objects as go
9
+
10
+ from collections import OrderedDict
11
+
12
+ import matplotlib
13
+
14
+ import scrap as scraping
15
+
16
+ def flatten(d):
17
+ '''
18
+ Flatten an OrderedDict object
19
+ '''
20
+ result = OrderedDict()
21
+ for k, v in d.items():
22
+ if isinstance(v, dict):
23
+ result.update(flatten(v))
24
+ else:
25
+ result[k] = v
26
+ return result
27
+
28
+ def rastreador():
29
+ #código para ativar bootstrap css
30
+ st.markdown(
31
+ """
32
+ <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css" integrity="sha384-Gn5384xqQ1aoWXA+058RXPxPg6fy4IWvTNh0E263XmFcJlSAwiGgFAW/dAiS6JXm" crossorigin="anonymous">
33
+ <script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/js/bootstrap.min.js" integrity="sha384-JZR6Spejh4U02d8jOt6vLEHfe/JQGiRRSQQxSfFWpi1MquVdAyjUar5+76PVCmYl" crossorigin="anonymous"></script>
34
+ """,unsafe_allow_html=True
35
+ )
36
+
37
+ col1, col2,col3 = st.columns([0.1,0.4,0.1])
38
+ with col2:
39
+
40
+ st.title('Rastreador de oportunidades por setup')
41
+
42
+ st.expander('Este rastreador identifica oportunidades para swing trade vasculhando as principais ações listadas na B3, o filtro consiste em encontrar ativos que tenham médias móveis exponenciais de 9 e 72 cruzadas para cima')
43
+
44
+ st.subheader('Aplique alguns filtros para acelerar o rastreador')
45
+ st.write('Serão rastreadas apenas as ações listadas na tabela filtrada abaixo')
46
+
47
+ PVP_máximo = float(st.number_input(label='PVP máximo',value=1.0))
48
+ Patr_liq_min = int(st.number_input(label='Patrimônio líquido mínimo',value=1000000000))
49
+ cotacao_max = float(st.number_input(label='Cotação máxima',value=100))
50
+
51
+
52
+ lista = scraping.get_data()
53
+ todos = pd.DataFrame(flatten(lista).keys()).transpose()
54
+ todos.columns = todos.iloc[0]
55
+ for i in range(len(lista)):
56
+ todos = pd.concat([todos,pd.DataFrame(lista[i]).transpose()])
57
+
58
+ todos = todos.iloc[1:]
59
+ todos = todos.replace(',','.', regex=True)
60
+ todos = todos.apply(pd.to_numeric,errors='ignore').round(2)
61
+ todos['Pat.Liq'] = todos['Pat.Liq'].str.replace(r"[^0-9]+", '').replace('.','').replace(',','').replace('-','').astype(float)
62
+
63
+ todos = todos.loc[(todos['P/VP']<= PVP_máximo) & (todos['Pat.Liq']>= Patr_liq_min) & (todos['cotacao']<= cotacao_max)]
64
+ show = todos.reset_index()
65
+ st.dataframe(show)
66
+
67
+ st.subheader('Setup')
68
+ col1, col2,col3 = st.columns([0.1,0.4,0.1])
69
+ with col2:
70
+ st.checkbox('Médias móveis exponenciais de 9 e 72 cruzadas para cima')
71
+
72
+
73
+
74
+
75
+ if st.button("Iniciar rastreador"):
76
+
77
+ # lista = scraping.get_data()
78
+ # todos = pd.DataFrame(flatten(lista).keys()).transpose()
79
+ # todos.columns = todos.iloc[0]
80
+
81
+ # for i in range(len(lista)):
82
+ # todos = pd.concat([todos,pd.DataFrame(lista[i]).transpose()])
83
+
84
+ # todos = todos.iloc[1:]
85
+ # todos = todos.replace(',','.', regex=True)
86
+ # todos = todos.apply(pd.to_numeric,errors='ignore').round(2)
87
+ # todos['Pat.Liq'] = todos['Pat.Liq'].str.replace(r"[^0-9]+", '').replace('.','').replace(',','').replace('-','').astype(float)
88
+ # todos = todos.loc[(todos['P/VP']<= PVP_máximo) & (todos['Pat.Liq']>= Patr_liq_min) & (todos['cotacao']<= cotacao_max)]
89
+
90
+
91
+ start = (dt.datetime.today() + dt.timedelta(days=-300)).strftime(format='20%y-%m-%d')
92
+ dia_limite = (dt.datetime.today() + dt.timedelta(days=-30)).strftime(format='20%y-%m-%d')
93
+
94
+
95
+ with st.expander("Aguarde estamos vasculhando todas as ações da bolsa (Mantenha esta barra minimizada)!"):
96
+ save = []
97
+ #for i in range(len(tudo)):
98
+ for i in range(len(todos)):
99
+ try:
100
+
101
+ #nome_do_ativo = str(tudo.iloc[i][0] + '.SA')
102
+ nome_do_ativo = str(todos.index[i] + '.SA')
103
+ #filtra todos que cruzaram média nos últimos 50 dias pelo menos
104
+ try:
105
+ df = Ticker(nome_do_ativo ,country='Brazil')
106
+ time = df.history( start= start )
107
+ rolling_9 = time['close'].rolling(window=9)
108
+ rolling_mean_9 = rolling_9.mean().round(1)
109
+
110
+ rolling_72 = time['close'].rolling(window=72)
111
+ rolling_mean_72 = rolling_72.mean().round(1)
112
+ time['MM9'] = rolling_mean_9.fillna(0)
113
+ time['MM72'] = rolling_mean_72.fillna(0)
114
+ time['cruzamento'] = time['MM9'] - time['MM72']
115
+ buy = time.tail(50).loc[(time.tail(50)['cruzamento']==0)]
116
+ except:
117
+ exit
118
+
119
+
120
+ except:
121
+ exit
122
+
123
+
124
+ if buy.empty == False:
125
+ try:
126
+ #filtra todo mundo que tem a MM 72 > que a MM 9 e quem tem volume do último dia > 5000
127
+ if time['MM72'].iloc[-1] < time['MM9'].iloc[-1] and time.tail(1)['volume'][0] > 10000:
128
+ save.append(buy.index[0][0])
129
+ print(buy.index[0][0])
130
+ #layout = go.Layout(title="Resultados",xaxis=dict(title="Data"), yaxis=dict(title="Preço R$"))
131
+ #fig = go.Figure(layout = layout)
132
+ #fig.add_trace(go.Candlestick(x=time.reset_index()['date'][-50:], open=time['open'][-50:],high=time['high'][-50:],low=time['low'][-50:],close=time['close'][-50:]))
133
+ #fig.update_layout(autosize=False,width=1000,height=800,)
134
+ #fig.show()
135
+ #print()
136
+ else:
137
+ continue
138
+ except:
139
+ exit
140
+
141
+ else:
142
+ exit
143
+
144
+
145
+ st.dataframe(save)
146
+ save = pd.DataFrame(save)
147
+
148
+ from plotly.subplots import make_subplots
149
+
150
+
151
+ for i in range(len(save)):
152
+ df = Ticker(save.iloc[i] ,country='Brazil')
153
+ time = df.history( start= start )
154
+
155
+
156
+
157
+ fig = make_subplots(rows=2, cols=1, shared_xaxes=True,
158
+ vertical_spacing=0.03, subplot_titles=(st.write(save.iloc[i]), 'Volume'),
159
+ row_width=[0.2, 0.7])
160
+
161
+ # Plot OHLC on 1st row
162
+ fig.add_trace(go.Candlestick(x=time.reset_index()['date'][-90:],
163
+ open=time['open'][-90:], high=time['high'][-90:],
164
+ low=time['low'][-90:], close=time['close'][-90:], name="OHLC"),
165
+ row=1, col=1)
166
+
167
+ # Bar trace for volumes on 2nd row without legend
168
+ fig.add_trace(go.Bar(x=time.reset_index()['date'][-90:], y=time['volume'][-90:], showlegend=False), row=2, col=1)
169
+
170
+ # Do not show OHLC's rangeslider plot
171
+ fig.update(layout_xaxis_rangeslider_visible=False)
172
+ #fig.update_layout(autosize=False,width=800,height=800, paper_bgcolor='rgba(0,0,0,0)', plot_bgcolor='rgba(0,0,0,0)')
173
+ fig.update_layout(height=600, showlegend=False, paper_bgcolor='rgba(255,255,255,0.9)', plot_bgcolor='rgba(255,255,255,0.9)') #width=800 ,
174
+ fig.update_yaxes(showgrid=True, gridwidth=0.1, gridcolor = 'rgb(240,238,238)')
175
+
176
+ st.plotly_chart(fig,use_container_width=True)
pag5.py ADDED
@@ -0,0 +1,532 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import matplotlib
2
+ matplotlib.use('Agg')
3
+
4
+ import streamlit as st
5
+
6
+
7
+ import pandas as pd
8
+ from PIL import Image
9
+ import plotly.graph_objects as go
10
+ import numpy as np
11
+ import yfinance as yf
12
+ import datetime as dt
13
+ from collections import OrderedDict
14
+ from sklearn.model_selection import train_test_split
15
+ from sklearn.ensemble import RandomForestRegressor
16
+
17
+
18
+
19
+ import uteis as uteis
20
+ import scrap as scraping
21
+
22
+
23
+ def flatten(d):
24
+ '''
25
+ Flatten an OrderedDict object
26
+ '''
27
+ result = OrderedDict()
28
+ for k, v in d.items():
29
+ if isinstance(v, dict):
30
+ result.update(flatten(v))
31
+ else:
32
+ result[k] = v
33
+ return result
34
+
35
+
36
+ def analise_carteira():
37
+ #código para ativar bootstrap css
38
+ st.markdown(
39
+ """
40
+ <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css" integrity="sha384-Gn5384xqQ1aoWXA+058RXPxPg6fy4IWvTNh0E263XmFcJlSAwiGgFAW/dAiS6JXm" crossorigin="anonymous">
41
+ <script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/js/bootstrap.min.js" integrity="sha384-JZR6Spejh4U02d8jOt6vLEHfe/JQGiRRSQQxSfFWpi1MquVdAyjUar5+76PVCmYl" crossorigin="anonymous"></script>
42
+ """,unsafe_allow_html=True
43
+ )
44
+
45
+ top_ativos = pd.read_excel('data/top_200.xlsx')#, index_col=0)
46
+
47
+ col1, col2,col3 = st.columns([0.1,0.4,0.1])
48
+ with col2:
49
+ st.title('Análise de carteira e previsão de lucro')
50
+ 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!')
51
+ 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ê')
52
+
53
+ menu = ["Escolha uma opção","Usar algoritmo do site","Usar os dados de minhas operações"]
54
+ choice = st.selectbox("Menu",menu)
55
+
56
+
57
+ if choice == "Usar os dados de minhas operações":
58
+ # se usuário estiver logado
59
+ if st.session_state['loged']:
60
+ #st.subheader('Faça upload aqui do seu extrato da B3')
61
+ col1, col2,col3 = st.columns([0.1,0.4,0.1])
62
+ with col2:
63
+ with st.expander("Passo a passo de como acessar os dados no site da B3"):
64
+ st.write('Acessar o site www.investidorb3.com.br')
65
+ st.write('Aba Extratos > Negociação > Aplicar filtro trazendo dados do último ano > baixar extrato em formato excel')
66
+ image = Image.open('images/b3.png')
67
+ st.image(image, use_column_width=True)
68
+
69
+ st.subheader('Faça upload aqui do seu extrato da B3')
70
+ file = st.file_uploader('Entre com seu extrato (.xlsx)', type = 'xlsx')
71
+ if file:
72
+ df = pd.read_excel(file)
73
+ lista = []
74
+ retirar = []
75
+ for i in range(len(df['Código de Negociação'])):
76
+ #PEGANDO SOMENTE AÇÕES AO INVÉS DE FIIS CORRELATAS
77
+ if len(df.iloc[i]['Código de Negociação']) == 5:
78
+ lista.append(df.iloc[i]['Código de Negociação'])
79
+
80
+ elif df.iloc[i]['Código de Negociação'][-1] == '1':
81
+ retirar.append(df.iloc[i]['Código de Negociação'][-1])
82
+ #PEGANDO AÇÕES FRACIONADAS E TRANSFORMANDO EM AÇÕES NORMAIS
83
+ else:
84
+ lista.append(df.iloc[i]['Código de Negociação'][:-1])
85
+
86
+ lista = pd.DataFrame(lista)[0].unique()
87
+ lista_input = []
88
+
89
+ #PEGAR DADOS HISTÓRICOS DE CADA UMA DAS AÇÕES
90
+ for i in range(len(lista)):
91
+
92
+ lista_input.append(str(lista[i] + '.SA'))
93
+
94
+ date_year_ago = dt.datetime.today() - dt.timedelta(days=565)
95
+ date_year_ago = date_year_ago.strftime(format='20%y-%m-%d')
96
+ data = yf.download(lista_input,start=date_year_ago)
97
+
98
+ #CRIA UMA DF COM UMA LINHA PARA CADA AÇÃO
99
+ df_filled = pd.DataFrame(columns = ['name'])
100
+ df_filled['name'] = lista_input
101
+
102
+ # lógica para input de dados calculados
103
+ #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
104
+ uteis.inputer_train(lista, df, data, df_filled)
105
+
106
+ df_input = df_filled.fillna(0).replace(np.inf, 0)
107
+
108
+ st.subheader('Avaliação de carteira:')
109
+ st.write('Lucro Total do período avaliado: R$',round(df_input['Ganho_total'].sum(),2))
110
+ #st.write('Rendimento Total do período avaliado: %',round(df_input['Rendimento_total_%'].sum(),2))
111
+
112
+ df_input = df_input.loc[df_input['data_compra_1'] != 0]
113
+ df_input['data_compra_1'] = pd.to_datetime(df_input['data_compra_1']).copy()
114
+ df_ordered = df_input.sort_values('data_compra_1')
115
+ #ordenando e criando campo mes ano
116
+ df_ordered['mes/ano'] =df_ordered['data_compra_1'].astype(str).str[:-3]
117
+ df_grouped = df_ordered.groupby('mes/ano').agg({'Rendimento_total_%':'mean','Ganho_total':'sum'})
118
+ df_grouped = df_grouped.reset_index()
119
+
120
+ #from plotly.subplots import make_subplots
121
+ #fig = make_subplots(rows=2, cols=1, specs=[[{"type": "scatter"}, {"type": "bar"}]], subplot_titles=("Rendimento mensal %","Lucro total mensal R$") )
122
+ #fig.add_trace(go.Scatter(x =df_grouped['mes/ano'], y=df_grouped['Rendimento_total_%']), row=1, col=1)
123
+ #fig.add_trace(go.Bar(x =df_grouped['mes/ano'], y=df_grouped['Ganho_total']), row=1, col=2)
124
+ #fig.update_layout(height=800, showlegend=False, paper_bgcolor='rgba(0,0,0,0)', plot_bgcolor='rgba(0,0,0,0)')
125
+ #st.plotly_chart(fig)
126
+
127
+ layout = go.Layout(title="Rendimento mensal %",xaxis=dict(title="mês/ano"), yaxis=dict(title="Rendimento total %"))
128
+ fig = go.Figure(layout = layout)
129
+ fig.add_trace(go.Scatter(x =df_grouped['mes/ano'], y=df_grouped['Rendimento_total_%']))
130
+
131
+ 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)')
132
+ fig.update_yaxes(showgrid=True, gridwidth=0.1, gridcolor = 'rgb(240,238,238)')
133
+ st.plotly_chart(fig,use_container_width=True)
134
+
135
+ layout = go.Layout(title="Lucro total mensal R$",xaxis=dict(title="mês/ano"), yaxis=dict(title="Ganho total R$"))
136
+ fig = go.Figure(layout = layout)
137
+ fig.add_trace(go.Bar(x =df_grouped['mes/ano'], y=df_grouped['Ganho_total']))
138
+
139
+ 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)')
140
+ fig.update_yaxes(showgrid=True, gridwidth=0.1, gridcolor = 'rgb(240,238,238)')
141
+ st.plotly_chart(fig,use_container_width=True)
142
+
143
+ #MODELAGEM
144
+
145
+ df_ordered['lucro'] = 0
146
+ df_ordered.loc[df_ordered['Ganho_total'] > 0 , 'lucro'] = 1
147
+ df_ordered = df_ordered.fillna(0).replace(-np.inf, 0)
148
+
149
+ 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)
150
+ y = df_ordered['lucro']
151
+
152
+ # divisão entre treino e teste 70/30
153
+ X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.30, random_state=42)
154
+
155
+ # Random Forest Regressor MVP
156
+ regr = RandomForestRegressor(random_state=42)
157
+ regr.fit(X_train,y_train)
158
+
159
+ predictions = regr.predict(X_test)
160
+
161
+ comparar = pd.DataFrame(y_test)
162
+ comparar['previsto'] = predictions
163
+ comparar['dif'] = comparar['previsto'] - comparar['lucro']
164
+
165
+ erros = len(comparar.loc[comparar['dif'] > 0.5]) + len(comparar.loc[comparar['dif'] < -0.5])
166
+ total = len(comparar)
167
+ precision_model = round(1 - (erros / total),2)
168
+
169
+ st.write('O modelo criado com os seus dados tem uma precisão de acerto de: ',precision_model * 100 ,'%')
170
+ 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')
171
+
172
+ #trazendo features + importantes
173
+
174
+ features, rank = uteis.rank(X, y)
175
+
176
+ st.subheader('Estas variáveis são as que mais impactam nas decisões da inteligência artificial')
177
+ #col1, col2,col3 = st.columns([0.1,0.4,0.1])
178
+ col1, col2,col3 = st.columns([1,2,1])
179
+ with col2:
180
+ #st.dataframe(rank['features'].head(10).reset_index(drop=True).T)
181
+ top_features = rank['features'].head(10).reset_index(drop=True)
182
+ st.table(top_features)
183
+
184
+ #fazendo previsão em toda a bolsa
185
+
186
+ #lista = scraping.get_data()
187
+ #todos = pd.DataFrame(flatten(lista).keys()).transpose()
188
+ #todos.columns = todos.iloc[0]
189
+ #for i in range(len(lista)):
190
+ # todos = pd.concat([todos,pd.DataFrame(lista[i]).transpose()])
191
+
192
+ #todos = todos.iloc[1:]
193
+ #todos['name'] = (todos.index + '.SA' )
194
+
195
+ #lista = top_ativos.copy()
196
+
197
+
198
+ #PREVENDO 1 AÇÃO ESPECÍFICA
199
+ col1, col2,col3 = st.columns([0.1,0.4,0.1])
200
+ with col2:
201
+ st.subheader('Escolha o código de até 4 ativos específicos que deseja prever e pressione enter')
202
+ nome_do_ativo1 = st.text_input('Nome do ativo 1',value='PETR4')
203
+ nome_do_ativo2 = st.text_input('Nome do ativo 2',value='VALE3')
204
+ nome_do_ativo3 = st.text_input('Nome do ativo 3',value='WEGE3')
205
+ nome_do_ativo4 = st.text_input('Nome do ativo 4')
206
+
207
+
208
+ if st.button('prever lucro das ações especificadas acima'):
209
+ ativo1 = str(nome_do_ativo1 + '.SA').upper()
210
+ ativo2 = str(nome_do_ativo2 + '.SA').upper()
211
+ ativo3 = str(nome_do_ativo3 + '.SA').upper()
212
+ ativo4 = str(nome_do_ativo4 + '.SA').upper()
213
+
214
+ nome_do_ativo1 = nome_do_ativo1.upper()
215
+ nome_do_ativo2 = nome_do_ativo2.upper()
216
+ nome_do_ativo3 = nome_do_ativo3.upper()
217
+ nome_do_ativo4 = nome_do_ativo4.upper()
218
+
219
+ todos = pd.DataFrame(columns = ['name'])
220
+ todos['name'] = [ativo1,ativo2,ativo3,ativo4]
221
+
222
+ lista = pd.DataFrame(columns = ['name'])
223
+ lista['name'] = [nome_do_ativo1,nome_do_ativo2,nome_do_ativo3,nome_do_ativo4]
224
+
225
+ date_year_ago = dt.datetime.today() - dt.timedelta(days=300)
226
+ date_year_ago = date_year_ago.strftime(format='20%y-%m-%d')
227
+
228
+
229
+ data = yf.download(list(todos['name']),start=date_year_ago)
230
+
231
+ df_filled = pd.DataFrame(columns = ['name'])
232
+ df_filled['name'] = lista['name']
233
+
234
+ df_filled['ativo'] = df_filled['name'].copy()
235
+ df_filled = df_filled.set_index('ativo')
236
+
237
+ df_filled = uteis.inputer_predict(data, df_filled)
238
+ # retirar nulos e infinitos positivos
239
+ df_input = df_filled.fillna(0).replace(np.inf, 0)
240
+ #df_ordered = df_input.fillna(0).replace(-np.inf, 0)
241
+ input_predict = df_input[list(X.columns)]
242
+ # retirar nulos e infinitos negativos
243
+ input_predict = input_predict.fillna(0).replace(-np.inf, 0)
244
+ predictions = regr.predict(input_predict)
245
+ input_predict['probabilidade de lucro'] = predictions.round(2) * 100
246
+
247
+ st.subheader('Previsão de lucro das principais ações da bolsa')
248
+ st.text('Essa previsão é feita com base nas tendências de sucesso captadas pelas suas operações')
249
+
250
+ #col1, col2,col3 = st.columns([0.1,0.4,0.1])
251
+ col1, col2,col3 = st.columns([1,2,1])
252
+ with col2:
253
+ st.table(input_predict['probabilidade de lucro'].sort_values(ascending=False).round(2))
254
+
255
+
256
+ if st.button('prever as top 200 ações de uma vez'):
257
+ lista = top_ativos.copy()
258
+ top_ativos['name'] =top_ativos['name'] + '.SA'
259
+ todos = top_ativos.copy()
260
+ #todos = top_ativos.head(2) #RETIRAR AQUI PARA PEGAR OS TOP 200
261
+
262
+ date_year_ago = dt.datetime.today() - dt.timedelta(days=300)
263
+ date_year_ago = date_year_ago.strftime(format='20%y-%m-%d')
264
+
265
+
266
+ data = yf.download(list(todos['name']),start=date_year_ago)
267
+
268
+ df_filled = pd.DataFrame(columns = ['name'])
269
+ df_filled['name'] = lista['name']
270
+
271
+ df_filled['ativo'] = df_filled['name'].copy()
272
+ df_filled = df_filled.set_index('ativo')
273
+
274
+ #uteis.inputer_predict(data, df_filled)
275
+
276
+
277
+ df_filled = uteis.inputer_predict(data, df_filled)
278
+ # retirar nulos e infinitos positivos
279
+ df_input = df_filled.fillna(0).replace(np.inf, 0)
280
+ #df_ordered = df_input.fillna(0).replace(-np.inf, 0)
281
+ input_predict = df_input[list(X.columns)]
282
+ # retirar nulos e infinitos negativos
283
+ input_predict = input_predict.fillna(0).replace(-np.inf, 0)
284
+ predictions = regr.predict(input_predict)
285
+ input_predict['probabilidade de lucro'] = predictions.round(2) * 100
286
+
287
+ st.subheader('Previsão de lucro das principais ações da bolsa')
288
+ st.text('Essa previsão é feita com base nas tendências de sucesso captadas pelas suas operações')
289
+ col1, col2,col3 = st.columns([1,2,1])
290
+ with col2:
291
+
292
+ st.table(input_predict['probabilidade de lucro'].sort_values(ascending=False).round(2))
293
+
294
+
295
+ else:
296
+ st.warning("Faça o Login na seção Login")
297
+
298
+
299
+ if choice == "Usar algoritmo do site":
300
+ st.subheader('As previsões feitas aqui utilizam dados de movimentação de milhares de operações para composição da inteligência artificial!')
301
+
302
+ df = pd.read_excel('data/b3_sem_resumo.xlsx')
303
+ lista = []
304
+ retirar = []
305
+ for i in range(len(df['Código de Negociação'])):
306
+ #PEGANDO SOMENTE AÇÕES AO INVÉS DE FIIS CORRELATAS
307
+ if len(df.iloc[i]['Código de Negociação']) == 5:
308
+ lista.append(df.iloc[i]['Código de Negociação'])
309
+
310
+ elif df.iloc[i]['Código de Negociação'][-1] == '1':
311
+ retirar.append(df.iloc[i]['Código de Negociação'][-1])
312
+ #PEGANDO AÇÕES FRACIONADAS E TRANSFORMANDO EM AÇÕES NORMAIS
313
+ else:
314
+ lista.append(df.iloc[i]['Código de Negociação'][:-1])
315
+
316
+ lista = pd.DataFrame(lista)[0].unique()
317
+ lista_input = []
318
+
319
+ #PEGAR DADOS HISTÓRICOS DE CADA UMA DAS AÇÕES
320
+ for i in range(len(lista)):
321
+
322
+ lista_input.append(str(lista[i] + '.SA'))
323
+
324
+ date_year_ago = dt.datetime.today() - dt.timedelta(days=565)
325
+ date_year_ago = date_year_ago.strftime(format='20%y-%m-%d')
326
+ data = yf.download(lista_input,start=date_year_ago)
327
+
328
+ #CRIA UMA DF COM UMA LINHA PARA CADA AÇÃO
329
+ df_filled = pd.DataFrame(columns = ['name'])
330
+ df_filled['name'] = lista_input
331
+
332
+ # lógica para input de dados calculados
333
+ #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
334
+ uteis.inputer_train(lista, df, data, df_filled)
335
+
336
+ df_input = df_filled.fillna(0).replace(np.inf, 0)
337
+
338
+ # st.subheader('Avaliação de carteira:')
339
+ # st.write('Lucro Total do período avaliado: R$',round(df_input['Ganho_total'].sum(),2))
340
+ # #st.write('Rendimento Total do período avaliado: %',round(df_input['Rendimento_total_%'].sum(),2))
341
+
342
+ df_input = df_input.loc[df_input['data_compra_1'] != 0]
343
+ df_input['data_compra_1'] = pd.to_datetime(df_input['data_compra_1']).copy()
344
+ df_ordered = df_input.sort_values('data_compra_1')
345
+ #ordenando e criando campo mes ano
346
+ df_ordered['mes/ano'] =df_ordered['data_compra_1'].astype(str).str[:-3]
347
+ df_grouped = df_ordered.groupby('mes/ano').agg({'Rendimento_total_%':'mean','Ganho_total':'sum'})
348
+ df_grouped = df_grouped.reset_index()
349
+
350
+ #from plotly.subplots import make_subplots
351
+ #fig = make_subplots(rows=2, cols=1, specs=[[{"type": "scatter"}, {"type": "bar"}]], subplot_titles=("Rendimento mensal %","Lucro total mensal R$") )
352
+ #fig.add_trace(go.Scatter(x =df_grouped['mes/ano'], y=df_grouped['Rendimento_total_%']), row=1, col=1)
353
+ #fig.add_trace(go.Bar(x =df_grouped['mes/ano'], y=df_grouped['Ganho_total']), row=1, col=2)
354
+ #fig.update_layout(height=800, showlegend=False, paper_bgcolor='rgba(0,0,0,0)', plot_bgcolor='rgba(0,0,0,0)')
355
+ #st.plotly_chart(fig)
356
+
357
+ # layout = go.Layout(title="Rendimento mensal %",xaxis=dict(title="mês/ano"), yaxis=dict(title="Rendimento total %"))
358
+ # fig = go.Figure(layout = layout)
359
+ # fig.add_trace(go.Scatter(x =df_grouped['mes/ano'], y=df_grouped['Rendimento_total_%']))
360
+
361
+ # 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)')
362
+ # fig.update_yaxes(showgrid=True, gridwidth=0.1, gridcolor = 'rgb(240,238,238)')
363
+ # st.plotly_chart(fig,use_container_width=True)
364
+
365
+ # layout = go.Layout(title="Lucro total mensal R$",xaxis=dict(title="mês/ano"), yaxis=dict(title="Ganho total R$"))
366
+ # fig = go.Figure(layout = layout)
367
+ # fig.add_trace(go.Bar(x =df_grouped['mes/ano'], y=df_grouped['Ganho_total']))
368
+
369
+ # 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)')
370
+ # fig.update_yaxes(showgrid=True, gridwidth=0.1, gridcolor = 'rgb(240,238,238)')
371
+ # st.plotly_chart(fig,use_container_width=True)
372
+
373
+ #MODELAGEM
374
+
375
+ df_ordered['lucro'] = 0
376
+ df_ordered.loc[df_ordered['Ganho_total'] > 0 , 'lucro'] = 1
377
+ df_ordered = df_ordered.fillna(0).replace(-np.inf, 0)
378
+
379
+ 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)
380
+ y = df_ordered['lucro']
381
+
382
+ # divisão entre treino e teste 70/30
383
+ X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.30, random_state=42)
384
+
385
+ # Random Forest Regressor MVP
386
+ regr = RandomForestRegressor(random_state=42)
387
+ regr.fit(X_train,y_train)
388
+
389
+ predictions = regr.predict(X_test)
390
+
391
+ comparar = pd.DataFrame(y_test)
392
+ comparar['previsto'] = predictions
393
+ comparar['dif'] = comparar['previsto'] - comparar['lucro']
394
+
395
+ erros = len(comparar.loc[comparar['dif'] > 0.5]) + len(comparar.loc[comparar['dif'] < -0.5])
396
+ total = len(comparar)
397
+ precision_model = round(1 - (erros / total),2)
398
+
399
+ st.write('O modelo utilizado tem uma precisão de acerto de: ',precision_model * 100 ,'%')
400
+
401
+ #trazendo features + importantes
402
+
403
+ features, rank = uteis.rank(X, y)
404
+
405
+ st.subheader('Estas variáveis são as que mais impactam nas decisões desta inteligência artificial')
406
+ #col1, col2,col3 = st.columns([0.1,0.4,0.1])
407
+ col1, col2,col3 = st.columns([1,2,1])
408
+ with col2:
409
+ #st.dataframe(rank['features'].head(10).reset_index(drop=True).T)
410
+ top_features = rank['features'].head(10).reset_index(drop=True)
411
+ st.table(top_features)
412
+
413
+ #fazendo previsão em toda a bolsa
414
+
415
+ #lista = scraping.get_data()
416
+ #todos = pd.DataFrame(flatten(lista).keys()).transpose()
417
+ #todos.columns = todos.iloc[0]
418
+ #for i in range(len(lista)):
419
+ # todos = pd.concat([todos,pd.DataFrame(lista[i]).transpose()])
420
+
421
+ #todos = todos.iloc[1:]
422
+ #todos['name'] = (todos.index + '.SA' )
423
+
424
+ #lista = top_ativos.copy()
425
+
426
+
427
+ #PREVENDO 1 AÇÃO ESPECÍFICA
428
+ col1, col2,col3 = st.columns([0.1,0.4,0.1])
429
+ with col2:
430
+ st.subheader('Escolha o código de até 4 ativos específicos que deseja prever e pressione enter')
431
+ nome_do_ativo1 = st.text_input('Nome do ativo 1',value='PETR4')
432
+ nome_do_ativo2 = st.text_input('Nome do ativo 2',value='VALE3')
433
+ nome_do_ativo3 = st.text_input('Nome do ativo 3',value='WEGE3')
434
+ nome_do_ativo4 = st.text_input('Nome do ativo 4')
435
+
436
+
437
+ if st.button('prever lucro das ações especificadas acima'):
438
+ ativo1 = str(nome_do_ativo1 + '.SA').upper()
439
+ ativo2 = str(nome_do_ativo2 + '.SA').upper()
440
+ ativo3 = str(nome_do_ativo3 + '.SA').upper()
441
+ ativo4 = str(nome_do_ativo4 + '.SA').upper()
442
+
443
+ nome_do_ativo1 = nome_do_ativo1.upper()
444
+ nome_do_ativo2 = nome_do_ativo2.upper()
445
+ nome_do_ativo3 = nome_do_ativo3.upper()
446
+ nome_do_ativo4 = nome_do_ativo4.upper()
447
+
448
+ todos = pd.DataFrame(columns = ['name'])
449
+ todos['name'] = [ativo1,ativo2,ativo3,ativo4]
450
+
451
+ lista = pd.DataFrame(columns = ['name'])
452
+ lista['name'] = [nome_do_ativo1,nome_do_ativo2,nome_do_ativo3,nome_do_ativo4]
453
+
454
+ date_year_ago = dt.datetime.today() - dt.timedelta(days=300)
455
+ date_year_ago = date_year_ago.strftime(format='20%y-%m-%d')
456
+
457
+
458
+ data = yf.download(list(todos['name']),start=date_year_ago)
459
+
460
+ df_filled = pd.DataFrame(columns = ['name'])
461
+ df_filled['name'] = lista['name']
462
+
463
+ df_filled['ativo'] = df_filled['name'].copy()
464
+ df_filled = df_filled.set_index('ativo')
465
+
466
+ df_filled = uteis.inputer_predict(data, df_filled)
467
+ # retirar nulos e infinitos positivos
468
+ df_input = df_filled.fillna(0).replace(np.inf, 0)
469
+ #df_ordered = df_input.fillna(0).replace(-np.inf, 0)
470
+ input_predict = df_input[list(X.columns)]
471
+ # retirar nulos e infinitos negativos
472
+ input_predict = input_predict.fillna(0).replace(-np.inf, 0)
473
+ predictions = regr.predict(input_predict)
474
+ input_predict['probabilidade de lucro'] = predictions.round(2) * 100
475
+
476
+ st.subheader('Previsão de lucro das principais ações da bolsa')
477
+ st.text('Essa previsão é feita com base nas tendências de sucesso captadas pelo algoritmo do explorador de ativos')
478
+
479
+ #col1, col2,col3 = st.columns([0.1,0.4,0.1])
480
+ col1, col2,col3 = st.columns([1,2,1])
481
+ with col2:
482
+ st.table(input_predict['probabilidade de lucro'].sort_values(ascending=False).round(2))
483
+
484
+
485
+ if st.button('prever as top 200 ações de uma vez'):
486
+ lista = top_ativos.copy()
487
+ top_ativos['name'] =top_ativos['name'] + '.SA'
488
+ todos = top_ativos.copy()
489
+ #todos = top_ativos.head(2) #RETIRAR AQUI PARA PEGAR OS TOP 200
490
+
491
+ date_year_ago = dt.datetime.today() - dt.timedelta(days=300)
492
+ date_year_ago = date_year_ago.strftime(format='20%y-%m-%d')
493
+
494
+
495
+ data = yf.download(list(todos['name']),start=date_year_ago)
496
+
497
+ df_filled = pd.DataFrame(columns = ['name'])
498
+ df_filled['name'] = lista['name']
499
+
500
+ df_filled['ativo'] = df_filled['name'].copy()
501
+ df_filled = df_filled.set_index('ativo')
502
+
503
+ #uteis.inputer_predict(data, df_filled)
504
+
505
+
506
+ df_filled = uteis.inputer_predict(data, df_filled)
507
+ # retirar nulos e infinitos positivos
508
+ df_input = df_filled.fillna(0).replace(np.inf, 0)
509
+ #df_ordered = df_input.fillna(0).replace(-np.inf, 0)
510
+ input_predict = df_input[list(X.columns)]
511
+ # retirar nulos e infinitos negativos
512
+ input_predict = input_predict.fillna(0).replace(-np.inf, 0)
513
+ predictions = regr.predict(input_predict)
514
+ input_predict['probabilidade de lucro'] = predictions.round(2) * 100
515
+
516
+ st.subheader('Previsão de lucro das principais ações da bolsa')
517
+ st.text('Essa previsão é feita com base nas tendências de sucesso captadas pelas suas operações')
518
+ col1, col2,col3 = st.columns([1,2,1])
519
+ with col2:
520
+
521
+ st.table(input_predict['probabilidade de lucro'].sort_values(ascending=False).round(2))
522
+
523
+
524
+
525
+
526
+
527
+
528
+
529
+
530
+
531
+
532
+
requirements.txt ADDED
@@ -0,0 +1,128 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ altair==4.2.0
2
+ argon2-cffi==21.3.0
3
+ argon2-cffi-bindings==21.2.0
4
+ asttokens==2.0.5
5
+ async-generator==1.10
6
+ attrs==21.4.0
7
+ backcall==0.2.0
8
+ beautifulsoup4==4.11.1
9
+ bleach==5.0.0
10
+ blinker==1.4
11
+ cachetools==5.2.0
12
+ cffi==1.15.0
13
+ charset-normalizer==2.0.12
14
+ click==8.1.3
15
+ colorama==0.4.5
16
+ commonmark==0.9.1
17
+ cryptography==37.0.2
18
+ cycler==0.11.0
19
+ debugpy==1.6.0
20
+ decorator==5.1.1
21
+ defusedxml==0.7.1
22
+ entrypoints==0.4
23
+ et-xmlfile==1.1.0
24
+ executing==0.8.3
25
+ fastjsonschema==2.15.3
26
+ fonttools==4.33.3
27
+ gitdb==4.0.9
28
+ GitPython==3.1.27
29
+ h11==0.13.0
30
+ idna==3.3
31
+ importlib-metadata==4.12.0
32
+ ipykernel==6.15.0
33
+ ipywidgets==7.7.1
34
+ jedi==0.18.1
35
+ Jinja2==3.1.2
36
+ joblib==1.1.0
37
+ jsonschema==4.6.0
38
+ jupyter-client==7.3.4
39
+ jupyter-core==4.10.0
40
+ jupyterlab-pygments==0.2.2
41
+ jupyterlab-widgets==1.1.1
42
+ kiwisolver==1.4.3
43
+ lxml==4.9.0
44
+ MarkupSafe==2.1.1
45
+ matplotlib==3.5.2
46
+ matplotlib-inline==0.1.3
47
+ mistune==0.8.4
48
+ multitasking==0.0.10
49
+ nbclient==0.6.4
50
+ nbconvert==6.5.0
51
+ nbformat==5.4.0
52
+ nest-asyncio==1.5.5
53
+ notebook==6.4.12
54
+ numpy==1.23.0
55
+ openpyxl==3.0.10
56
+ outcome==1.2.0
57
+ packaging==21.3
58
+ pandas==1.2
59
+ pandocfilters==1.5.0
60
+ parso==0.8.3
61
+ pickleshare==0.7.5
62
+ Pillow==9.1.1
63
+ plotly==5.9.0
64
+ prometheus-client==0.14.1
65
+ prompt-toolkit==3.0.29
66
+ protobuf==3.20.1
67
+ psutil==5.9.1
68
+ pure-eval==0.2.2
69
+ pyarrow==8.0.0
70
+ pycparser==2.21
71
+ pydeck==0.7.1
72
+ Pygments==2.12.0
73
+ pymongo==4.1.1
74
+ Pympler==1.0.1
75
+ pyOpenSSL==22.0.0
76
+ pyparsing==3.0.9
77
+ pyrsistent==0.18.1
78
+ PySocks==1.7.1
79
+ python-dateutil==2.8.2
80
+ python-dotenv==0.19.2
81
+ pytz==2022.1
82
+ pytz-deprecation-shim==0.1.0.post0
83
+ pyzmq==23.2.0
84
+ requests==2.28.0
85
+ requests-futures==1.0.0
86
+ rich==12.4.4
87
+ scikit-learn==1.1.1
88
+ scipy==1.8.1
89
+ selenium==4.3.0
90
+ semver==2.13.0
91
+ Send2Trash==1.8.0
92
+ simplejson==3.17.6
93
+ six==1.16.0
94
+ sklearn==0.0
95
+ smmap==5.0.0
96
+ sniffio==1.2.0
97
+ sortedcontainers==2.4.0
98
+ soupsieve==2.3.2.post1
99
+ stack-data==0.3.0
100
+ streamlit==1.10.0
101
+ streamlit-aggrid==0.2.3.post2
102
+ streamlit-option-menu==0.3.2
103
+ tenacity==8.0.1
104
+ terminado==0.15.0
105
+ threadpoolctl==3.1.0
106
+ tinycss2==1.1.1
107
+ toml==0.10.2
108
+ toolz==0.11.2
109
+ tornado==6.1
110
+ tqdm==4.64.0
111
+ traitlets==5.3.0
112
+ trio==0.21.0
113
+ trio-websocket==0.9.2
114
+ typing_extensions==4.2.0
115
+ tzdata==2022.1
116
+ tzlocal==4.2
117
+ urllib3==1.26.9
118
+ validators==0.20.0
119
+ watchdog==2.1.9
120
+ wcwidth==0.2.5
121
+ webdriver-manager==3.7.1
122
+ webencodings==0.5.1
123
+ widgetsnbextension==3.6.1
124
+ wincertstore==0.2
125
+ wsproto==1.1.0
126
+ yahooquery==2.2.15
127
+ yfinance==0.1.72
128
+ zipp==3.8.0
scrap.py ADDED
@@ -0,0 +1,245 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from selenium import webdriver
2
+ from webdriver_manager.chrome import ChromeDriverManager
3
+ from time import sleep
4
+ from tqdm.notebook import tqdm
5
+ #from selenium.webdriver.chrome.options import Options
6
+ import time
7
+ import sys
8
+ import requests
9
+
10
+ import http.cookiejar
11
+ import time
12
+ import lxml
13
+ import re
14
+ import urllib.request
15
+ import json
16
+ import ast
17
+ import datetime
18
+
19
+ from pymongo import MongoClient
20
+
21
+ from datetime import datetime
22
+ from lxml.html import fragment_fromstring
23
+
24
+ from collections import OrderedDict
25
+
26
+ import urllib.parse
27
+
28
+
29
+
30
+
31
+ def get_data(*args, **kwargs):
32
+ class AppURLopener(urllib.request.FancyURLopener):
33
+ version = "Mozilla/5.0"
34
+
35
+ opener = AppURLopener()
36
+ response = opener.open('http://httpbin.org/user-agent')
37
+
38
+ url = 'http://www.fundamentus.com.br/resultado.php'
39
+ cj = http.cookiejar.CookieJar()
40
+ opener = urllib.request.build_opener(urllib.request.HTTPCookieProcessor(cj))
41
+
42
+ opener.addheaders = [('User-agent', 'Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/41.0.2228.0 Safari/537.3'),
43
+ ('Accept', 'text/html, text/plain, text/css, text/sgml, */*;q=0.01')
44
+ ]
45
+
46
+ #opener.addheaders = [('User-agent', 'Mozilla/5.0 (Windows; U; Windows NT 6.1; rv:2.2) Gecko/20110201'),
47
+ # ('Accept', 'text/html, text/plain, text/css, text/sgml, */*;q=0.01')]
48
+
49
+ # Aqui estão os parâmetros de busca das ações
50
+ # Estão em branco para que retorne todas as disponíveis
51
+ data = {'pl_min':'','pl_max':'','pvp_min':'','pvp_max' :'','psr_min':'','psr_max':'','divy_min':'','divy_max':'', 'pativos_min':'','pativos_max':'','pcapgiro_min':'','pcapgiro_max':'','pebit_min':'','pebit_max':'', 'fgrah_min':'',
52
+ 'fgrah_max':'', 'firma_ebit_min':'', 'firma_ebit_max':'','margemebit_min':'','margemebit_max':'', 'margemliq_min':'','margemliq_max':'', 'liqcorr_min':'','liqcorr_max':'','roic_min':'','roic_max':'','roe_min':'', 'roe_max':'','liq_min':'','liq_max':'','patrim_min':'','patrim_max':'','divbruta_min':'','divbruta_max':'', 'tx_cresc_rec_min':'','tx_cresc_rec_max':'','setor':'','negociada':'ON','ordem':'1','x':'28','y':'16'}
53
+
54
+ with opener.open(url, urllib.parse.urlencode(data).encode('UTF-8')) as link:
55
+ content = link.read().decode('ISO-8859-1')
56
+
57
+ pattern = re.compile('<table id="resultado".*</table>', re.DOTALL)
58
+ reg = re.findall(pattern, content)[0]
59
+ page = fragment_fromstring(reg)
60
+ lista = OrderedDict()
61
+
62
+
63
+ stocks = page.xpath('tbody')[0].findall("tr")
64
+
65
+ todos = []
66
+ for i in range(0, len(stocks)):
67
+ lista[i] = {
68
+ stocks[i].getchildren()[0][0].getchildren()[0].text: {
69
+ 'cotacao': stocks[i].getchildren()[1].text,
70
+ 'P/L': stocks[i].getchildren()[2].text,
71
+ 'P/VP': stocks[i].getchildren()[3].text,
72
+ 'PSR': stocks[i].getchildren()[4].text,
73
+ 'DY': stocks[i].getchildren()[5].text,
74
+ 'P/Ativo': stocks[i].getchildren()[6].text,
75
+ 'P/Cap.Giro': stocks[i].getchildren()[7].text,
76
+ 'P/EBIT': stocks[i].getchildren()[8].text,
77
+ 'P/Ativ.Circ.Liq.': stocks[i].getchildren()[9].text,
78
+ 'EV/EBIT': stocks[i].getchildren()[10].text,
79
+ 'EBITDA': stocks[i].getchildren()[11].text,
80
+ 'Mrg. Ebit': stocks[i].getchildren()[12].text,
81
+ 'Mrg.Liq.': stocks[i].getchildren()[13].text,
82
+ 'Liq.Corr.': stocks[i].getchildren()[14].text,
83
+ 'ROIC': stocks[i].getchildren()[15].text,
84
+ 'ROE': stocks[i].getchildren()[16].text,
85
+ 'Liq.2m.': stocks[i].getchildren()[17].text,
86
+ 'Pat.Liq': stocks[i].getchildren()[18].text,
87
+ 'Div.Brut/Pat.': stocks[i].getchildren()[19].text,
88
+ 'Cresc.5a': stocks[i].getchildren()[20].text
89
+ }
90
+ }
91
+
92
+ return lista
93
+
94
+ def get_specific_data(stock):
95
+ class AppURLopener(urllib.request.FancyURLopener):
96
+ version = "Mozilla/5.0"
97
+
98
+ opener = AppURLopener()
99
+ response = opener.open('http://httpbin.org/user-agent')
100
+
101
+ url = "http://www.fundamentus.com.br/detalhes.php?papel=" + stock
102
+ cj = http.cookiejar.CookieJar()
103
+ opener = urllib.request.build_opener(urllib.request.HTTPCookieProcessor(cj))
104
+
105
+ opener.addheaders = [('User-agent', 'Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/41.0.2228.0 Safari/537.3'),
106
+ ('Accept', 'text/html, text/plain, text/css, text/sgml, */*;q=0.01')
107
+ ]
108
+
109
+
110
+
111
+
112
+
113
+ #opener.addheaders = [('User-agent', 'Mozilla/5.0 (Windows; U; Windows NT 6.1; rv:2.2) Gecko/20110201'),
114
+ # ('Accept', 'text/html, text/plain, text/css, text/sgml, */*;q=0.01')]
115
+
116
+ # Get data from site
117
+ link = opener.open(url, urllib.parse.urlencode({}).encode('UTF-8'))
118
+ content = link.read().decode('ISO-8859-1')
119
+
120
+ # Get all table instances
121
+ pattern = re.compile('<table class="w728">.*</table>', re.DOTALL)
122
+ reg = re.findall(pattern, content)[0]
123
+ reg = "<div>" + reg + "</div>"
124
+ page = fragment_fromstring(reg)
125
+ all_data = {}
126
+
127
+ # There is 5 tables with tr, I will get all trs
128
+ all_trs = []
129
+ all_tables = page.xpath("table")
130
+
131
+ for i in range(0, len(all_tables)):
132
+ all_trs = all_trs + all_tables[i].findall("tr")
133
+
134
+ # Run through all the trs and get the label and the
135
+ # data for each line
136
+ for tr_index in range(0, len(all_trs)):
137
+ tr = all_trs[tr_index]
138
+ # Get into td
139
+ all_tds = tr.getchildren()
140
+ for td_index in range(0, len(all_tds)):
141
+ td = all_tds[td_index]
142
+
143
+ label = ""
144
+ data = ""
145
+
146
+ # The page has tds with contents and some
147
+ # other with not
148
+ if (td.get("class").find("label") != -1):
149
+ # We have a label
150
+ for span in td.getchildren():
151
+ if (span.get("class").find("txt") != -1):
152
+ label = span.text
153
+
154
+ # If we did find a label we have to look
155
+ # for a value
156
+ if (label and len(label) > 0):
157
+ next_td = all_tds[td_index + 1]
158
+
159
+ if (next_td.get("class").find("data") != -1):
160
+ # We have a data
161
+ for span in next_td.getchildren():
162
+ if (span.get("class").find("txt") != -1):
163
+ if (span.text):
164
+ data = span.text
165
+ else:
166
+ # If it is a link
167
+ span_children = span.getchildren()
168
+ if (span_children and len(span_children) > 0):
169
+ data = span_children[0].text
170
+
171
+ # Include into dict
172
+ all_data[label] = data
173
+
174
+ # Erase it
175
+ label = ""
176
+ data = ""
177
+
178
+ return all_data
179
+
180
+
181
+
182
+
183
+ def coletar_scrap():
184
+ sys.path.insert(0,'/usr/lib/chromium-browser/chromedriver')
185
+ URL = 'https://statusinvest.com.br/acoes/busca-avancada'
186
+ #output = 'busca-avancada.csv'
187
+
188
+ #if path.exists(output):
189
+ # os.remove(output)
190
+
191
+ #chrome_options = Options()
192
+ #chrome_options.binary_location = GOOGLE_CHROME_BIN
193
+ #chrome_options.add_argument('--disable-gpu')
194
+ #chrome_options.add_argument('--no-sandbox')
195
+ #driver = webdriver.Chrome(executable_path=CHROMEDRIVER_PATH, chrome_options=chrome_options)
196
+
197
+ #driver = webdriver.Chrome('chromedriver/chromedriver.exe')
198
+
199
+ #chrome_options = webdriver.ChromeOptions()
200
+ #chrome_options.add_argument('--headless')
201
+ #chrome_options.add_argument('--no-sandbox')
202
+ #chrome_options.add_argument('--disable-dev-shm-usage')
203
+ #driver = webdriver.Chrome('chromedriver',chrome_options=chrome_options)
204
+
205
+ gChromeOptions = webdriver.ChromeOptions()
206
+ gChromeOptions.add_argument("window-size=1920x1480")
207
+ gChromeOptions.add_argument("disable-dev-shm-usage")
208
+ driver = webdriver.Chrome(
209
+ chrome_options=gChromeOptions, executable_path=ChromeDriverManager().install()
210
+ )
211
+
212
+ #driver = webdriver.Chrome(ChromeDriverManager(chrome_type=ChromeType.GOOGLE).install())
213
+ #driver.get(URL)
214
+ driver.get(URL)
215
+ sleep(5)
216
+
217
+ button_buscar = driver.find_element_by_xpath('//div/button[contains(@class,"find")]')
218
+
219
+ button_buscar.click()
220
+ sleep(5)
221
+
222
+ button_skip = driver.find_element_by_xpath('//div/button[contains(@class,"btn-close")]')
223
+
224
+ button_skip.click()
225
+ sleep(5)
226
+
227
+ button_download = driver.find_element_by_xpath('//div/a[contains(@class, "btn-download")]')
228
+ button_download.click()
229
+ sleep(1)
230
+
231
+ #if path.exists(output):
232
+
233
+
234
+ df = pd.read_csv('busca-avancada.csv', sep=';', decimal=',', thousands='.')
235
+ driver.close()
236
+ return df
237
+
238
+
239
+ def scrap_fundamentus():
240
+ url = 'http://www.fundamentus.com.br/resultado.php'
241
+ headers = {'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/50.0.2661.102 Safari/537.36'}
242
+ result = requests.get(url, headers=headers)
243
+ df = pd.read_html(result.content)[0]
244
+
245
+ return df
scripts/scrap.py ADDED
@@ -0,0 +1,234 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from selenium import webdriver
2
+ from webdriver_manager.chrome import ChromeDriverManager
3
+ from time import sleep
4
+ #from tqdm.notebook import tqdm
5
+ #from selenium.webdriver.chrome.options import Options
6
+ import sys
7
+ import requests
8
+ import http.cookiejar
9
+ import re
10
+ import urllib.request
11
+ from lxml.html import fragment_fromstring
12
+ from collections import OrderedDict
13
+ import urllib.parse
14
+ import pandas as pd
15
+
16
+
17
+
18
+
19
+
20
+ def get_data(*args, **kwargs):
21
+ class AppURLopener(urllib.request.FancyURLopener):
22
+ version = "Mozilla/5.0"
23
+
24
+ opener = AppURLopener()
25
+ response = opener.open('http://httpbin.org/user-agent')
26
+
27
+ url = 'http://www.fundamentus.com.br/resultado.php'
28
+ cj = http.cookiejar.CookieJar()
29
+ opener = urllib.request.build_opener(urllib.request.HTTPCookieProcessor(cj))
30
+
31
+ opener.addheaders = [('User-agent', 'Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/41.0.2228.0 Safari/537.3'),
32
+ ('Accept', 'text/html, text/plain, text/css, text/sgml, */*;q=0.01')
33
+ ]
34
+
35
+ #opener.addheaders = [('User-agent', 'Mozilla/5.0 (Windows; U; Windows NT 6.1; rv:2.2) Gecko/20110201'),
36
+ # ('Accept', 'text/html, text/plain, text/css, text/sgml, */*;q=0.01')]
37
+
38
+ # Aqui estão os parâmetros de busca das ações
39
+ # Estão em branco para que retorne todas as disponíveis
40
+ data = {'pl_min':'','pl_max':'','pvp_min':'','pvp_max' :'','psr_min':'','psr_max':'','divy_min':'','divy_max':'', 'pativos_min':'','pativos_max':'','pcapgiro_min':'','pcapgiro_max':'','pebit_min':'','pebit_max':'', 'fgrah_min':'',
41
+ 'fgrah_max':'', 'firma_ebit_min':'', 'firma_ebit_max':'','margemebit_min':'','margemebit_max':'', 'margemliq_min':'','margemliq_max':'', 'liqcorr_min':'','liqcorr_max':'','roic_min':'','roic_max':'','roe_min':'', 'roe_max':'','liq_min':'','liq_max':'','patrim_min':'','patrim_max':'','divbruta_min':'','divbruta_max':'', 'tx_cresc_rec_min':'','tx_cresc_rec_max':'','setor':'','negociada':'ON','ordem':'1','x':'28','y':'16'}
42
+
43
+ with opener.open(url, urllib.parse.urlencode(data).encode('UTF-8')) as link:
44
+ content = link.read().decode('ISO-8859-1')
45
+
46
+ pattern = re.compile('<table id="resultado".*</table>', re.DOTALL)
47
+ reg = re.findall(pattern, content)[0]
48
+ page = fragment_fromstring(reg)
49
+ lista = OrderedDict()
50
+
51
+
52
+ stocks = page.xpath('tbody')[0].findall("tr")
53
+
54
+ todos = []
55
+ for i in range(0, len(stocks)):
56
+ lista[i] = {
57
+ stocks[i].getchildren()[0][0].getchildren()[0].text: {
58
+ 'cotacao': stocks[i].getchildren()[1].text,
59
+ 'P/L': stocks[i].getchildren()[2].text,
60
+ 'P/VP': stocks[i].getchildren()[3].text,
61
+ 'PSR': stocks[i].getchildren()[4].text,
62
+ 'DY': stocks[i].getchildren()[5].text,
63
+ 'P/Ativo': stocks[i].getchildren()[6].text,
64
+ 'P/Cap.Giro': stocks[i].getchildren()[7].text,
65
+ 'P/EBIT': stocks[i].getchildren()[8].text,
66
+ 'P/Ativ.Circ.Liq.': stocks[i].getchildren()[9].text,
67
+ 'EV/EBIT': stocks[i].getchildren()[10].text,
68
+ 'EBITDA': stocks[i].getchildren()[11].text,
69
+ 'Mrg. Ebit': stocks[i].getchildren()[12].text,
70
+ 'Mrg.Liq.': stocks[i].getchildren()[13].text,
71
+ 'Liq.Corr.': stocks[i].getchildren()[14].text,
72
+ 'ROIC': stocks[i].getchildren()[15].text,
73
+ 'ROE': stocks[i].getchildren()[16].text,
74
+ 'Liq.2m.': stocks[i].getchildren()[17].text,
75
+ 'Pat.Liq': stocks[i].getchildren()[18].text,
76
+ 'Div.Brut/Pat.': stocks[i].getchildren()[19].text,
77
+ 'Cresc.5a': stocks[i].getchildren()[20].text
78
+ }
79
+ }
80
+
81
+ return lista
82
+
83
+ def get_specific_data(stock):
84
+ class AppURLopener(urllib.request.FancyURLopener):
85
+ version = "Mozilla/5.0"
86
+
87
+ opener = AppURLopener()
88
+ response = opener.open('http://httpbin.org/user-agent')
89
+
90
+ url = "http://www.fundamentus.com.br/detalhes.php?papel=" + stock
91
+ cj = http.cookiejar.CookieJar()
92
+ opener = urllib.request.build_opener(urllib.request.HTTPCookieProcessor(cj))
93
+
94
+ opener.addheaders = [('User-agent', 'Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/41.0.2228.0 Safari/537.3'),
95
+ ('Accept', 'text/html, text/plain, text/css, text/sgml, */*;q=0.01')
96
+ ]
97
+
98
+
99
+
100
+
101
+
102
+ #opener.addheaders = [('User-agent', 'Mozilla/5.0 (Windows; U; Windows NT 6.1; rv:2.2) Gecko/20110201'),
103
+ # ('Accept', 'text/html, text/plain, text/css, text/sgml, */*;q=0.01')]
104
+
105
+ # Get data from site
106
+ link = opener.open(url, urllib.parse.urlencode({}).encode('UTF-8'))
107
+ content = link.read().decode('ISO-8859-1')
108
+
109
+ # Get all table instances
110
+ pattern = re.compile('<table class="w728">.*</table>', re.DOTALL)
111
+ reg = re.findall(pattern, content)[0]
112
+ reg = "<div>" + reg + "</div>"
113
+ page = fragment_fromstring(reg)
114
+ all_data = {}
115
+
116
+ # There is 5 tables with tr, I will get all trs
117
+ all_trs = []
118
+ all_tables = page.xpath("table")
119
+
120
+ for i in range(0, len(all_tables)):
121
+ all_trs = all_trs + all_tables[i].findall("tr")
122
+
123
+ # Run through all the trs and get the label and the
124
+ # data for each line
125
+ for tr_index in range(0, len(all_trs)):
126
+ tr = all_trs[tr_index]
127
+ # Get into td
128
+ all_tds = tr.getchildren()
129
+ for td_index in range(0, len(all_tds)):
130
+ td = all_tds[td_index]
131
+
132
+ label = ""
133
+ data = ""
134
+
135
+ # The page has tds with contents and some
136
+ # other with not
137
+ if (td.get("class").find("label") != -1):
138
+ # We have a label
139
+ for span in td.getchildren():
140
+ if (span.get("class").find("txt") != -1):
141
+ label = span.text
142
+
143
+ # If we did find a label we have to look
144
+ # for a value
145
+ if (label and len(label) > 0):
146
+ next_td = all_tds[td_index + 1]
147
+
148
+ if (next_td.get("class").find("data") != -1):
149
+ # We have a data
150
+ for span in next_td.getchildren():
151
+ if (span.get("class").find("txt") != -1):
152
+ if (span.text):
153
+ data = span.text
154
+ else:
155
+ # If it is a link
156
+ span_children = span.getchildren()
157
+ if (span_children and len(span_children) > 0):
158
+ data = span_children[0].text
159
+
160
+ # Include into dict
161
+ all_data[label] = data
162
+
163
+ # Erase it
164
+ label = ""
165
+ data = ""
166
+
167
+ return all_data
168
+
169
+
170
+
171
+
172
+ def coletar_scrap():
173
+ sys.path.insert(0,'/usr/lib/chromium-browser/chromedriver')
174
+ URL = 'https://statusinvest.com.br/acoes/busca-avancada'
175
+ #output = 'busca-avancada.csv'
176
+
177
+ #if path.exists(output):
178
+ # os.remove(output)
179
+
180
+ #chrome_options = Options()
181
+ #chrome_options.binary_location = GOOGLE_CHROME_BIN
182
+ #chrome_options.add_argument('--disable-gpu')
183
+ #chrome_options.add_argument('--no-sandbox')
184
+ #driver = webdriver.Chrome(executable_path=CHROMEDRIVER_PATH, chrome_options=chrome_options)
185
+
186
+ #driver = webdriver.Chrome('chromedriver/chromedriver.exe')
187
+
188
+ #chrome_options = webdriver.ChromeOptions()
189
+ #chrome_options.add_argument('--headless')
190
+ #chrome_options.add_argument('--no-sandbox')
191
+ #chrome_options.add_argument('--disable-dev-shm-usage')
192
+ #driver = webdriver.Chrome('chromedriver',chrome_options=chrome_options)
193
+
194
+ gChromeOptions = webdriver.ChromeOptions()
195
+ gChromeOptions.add_argument("window-size=1920x1480")
196
+ gChromeOptions.add_argument("disable-dev-shm-usage")
197
+ driver = webdriver.Chrome(
198
+ chrome_options=gChromeOptions, executable_path=ChromeDriverManager().install()
199
+ )
200
+
201
+ #driver = webdriver.Chrome(ChromeDriverManager(chrome_type=ChromeType.GOOGLE).install())
202
+ #driver.get(URL)
203
+ driver.get(URL)
204
+ sleep(5)
205
+
206
+ button_buscar = driver.find_element_by_xpath('//div/button[contains(@class,"find")]')
207
+
208
+ button_buscar.click()
209
+ sleep(5)
210
+
211
+ button_skip = driver.find_element_by_xpath('//div/button[contains(@class,"btn-close")]')
212
+
213
+ button_skip.click()
214
+ sleep(5)
215
+
216
+ button_download = driver.find_element_by_xpath('//div/a[contains(@class, "btn-download")]')
217
+ button_download.click()
218
+ sleep(1)
219
+
220
+ #if path.exists(output):
221
+
222
+
223
+ df = pd.read_csv('busca-avancada.csv', sep=';', decimal=',', thousands='.')
224
+ driver.close()
225
+ return df
226
+
227
+
228
+ def scrap_fundamentus():
229
+ url = 'http://www.fundamentus.com.br/resultado.php'
230
+ headers = {'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/50.0.2661.102 Safari/537.36'}
231
+ result = requests.get(url, headers=headers)
232
+ df = pd.read_html(result.content)[0]
233
+
234
+ return df
setup.sh ADDED
@@ -0,0 +1,13 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ mkdir -p ~/.streamlit/
2
+
3
+ echo "\
4
+ [general]\n\
5
+ email = \"lucas.vasconcelos3@gmail.com\"\n\
6
+ " > ~/.streamlit/credentials.toml
7
+
8
+ echo "\
9
+ [server]\n\
10
+ headless = true\n\
11
+ enableCORS=false\n\
12
+ port = $PORT\n\
13
+ " > ~/.streamlit/config.toml
style.py ADDED
@@ -0,0 +1,95 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import base64
2
+ import streamlit as st
3
+
4
+ from streamlit_option_menu import option_menu
5
+
6
+ def get_base64(bin_file):
7
+ with open(bin_file, 'rb') as f:
8
+ data = f.read()
9
+ return base64.b64encode(data).decode()
10
+
11
+ def set_background(png_file):
12
+ bin_str = get_base64(png_file)
13
+ page_bg_img = '''
14
+ <style>
15
+ .stApp {
16
+ background-image: url("data:image/png;base64,%s");
17
+ background-size: cover;
18
+ }
19
+ </style>
20
+ ''' % bin_str
21
+ st.markdown(page_bg_img, unsafe_allow_html=True)
22
+
23
+ #esconder botões do streamlit
24
+ def hidden_menu_and_footer():
25
+ hide_menu = '''
26
+ <style>
27
+ #MainMenu {
28
+ visibility:hidden;
29
+ }
30
+
31
+ footer{
32
+ visibility:hidden;
33
+ }
34
+
35
+ </style>
36
+ '''
37
+ st.markdown(hide_menu, unsafe_allow_html=True)
38
+
39
+ #linha no cabeçalho branca desing
40
+ def headerstyle():
41
+ st.markdown(
42
+ f"""
43
+ <nav class="navbar fixed-top navbar-light bg-white" style="color: #ffffff; padding: 0.8rem 1rem;">
44
+ <span class="navbar-brand mb-0 h1" " > </span>
45
+ </nav>
46
+ """, unsafe_allow_html=True
47
+ )
48
+
49
+
50
+ #espaço entre plots
51
+ def space(tamanho):
52
+ if tamanho == 1:
53
+ st.title('')
54
+ if tamanho == 2:
55
+ st.header('')
56
+ if tamanho == 3:
57
+ st.write('')
58
+
59
+ def sidebarwidth():
60
+ st.markdown(
61
+ """
62
+ <style>
63
+ [data-testid="stSidebar"][aria-expanded="true"] > div:first-child {
64
+ width: 250px;
65
+ }
66
+ [data-testid="stSidebar"][aria-expanded="false"] > div:first-child {
67
+ width: 250px;
68
+ margin-left: -500px;
69
+ }
70
+ </style>
71
+ """,
72
+ unsafe_allow_html=True,
73
+ )
74
+
75
+ def font_google():
76
+ st.markdown(
77
+ """
78
+ <style>
79
+ @font-face {
80
+ font-family: 'Roboto';
81
+ font-style: normal;
82
+ font-weight: 400;
83
+ src: url(https://fonts.gstatic.com/s/tangerine/v12/IurY6Y5j_oScZZow4VOxCZZM.woff2) format('woff2');
84
+ unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+2000-206F, U+2074, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
85
+ }
86
+
87
+ html, body, [class*="css"] {
88
+ font-family: 'Roboto';
89
+ font-size: 48px;
90
+ }
91
+ </style>
92
+
93
+ """,
94
+ unsafe_allow_html=True,
95
+ )
style_0.css ADDED
@@ -0,0 +1,98 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ p{
2
+ color:rgb(74, 113, 152);
3
+ text-align: center;
4
+ font-size: 14px;
5
+ font-family: 'Bree Serif', serif;
6
+ }
7
+
8
+
9
+
10
+ /* sidebar */
11
+ .css-ppzyts {
12
+ background-color: rgb(255, 255, 255);
13
+ background-attachment: fixed;
14
+ flex-shrink: 0;
15
+ height: 100vh;
16
+ overflow: auto;
17
+ padding: 3rem 1rem;
18
+ position: relative;
19
+ transition: margin-left 300ms ease 0s, box-shadow 300ms ease 0s;
20
+ width: 15rem;
21
+ z-index: 100;
22
+ margin-left: 0px;
23
+ }
24
+
25
+
26
+ /* botão input */
27
+ .st-b7 {
28
+ width: 600px;
29
+ border-radius: 2.25rem;
30
+
31
+
32
+ }
33
+
34
+ /* Plotly */
35
+ .main-svg{
36
+ border-radius: 2.25rem;
37
+ width: 100%;
38
+ display: flex;
39
+ flex-wrap: wrap;
40
+ -webkit-box-flex: 1;
41
+ flex-grow: 1;
42
+ -webkit-box-align: stretch;
43
+ align-items: stretch;
44
+ }
45
+
46
+ .plot-container.plotly{
47
+ width: 100%;
48
+ display: flex;
49
+ flex-wrap: wrap;
50
+ -webkit-box-flex: 1;
51
+ flex-grow: 1;
52
+ -webkit-box-align: stretch;
53
+ align-items: stretch;
54
+
55
+ }
56
+
57
+
58
+ /* DataFrame style */
59
+ .stDataFrame {
60
+ border-radius: 10px;
61
+ background: rgb(240, 238, 238);
62
+ background-color:#fff;
63
+ }
64
+
65
+
66
+
67
+
68
+
69
+
70
+
71
+
72
+
73
+
74
+
75
+
76
+
77
+
78
+
79
+
80
+
81
+ /* centralização página */
82
+
83
+ /* .css-12oz5g7 {
84
+ flex: 1 1 0%;
85
+ width: 100%;
86
+ padding: 6rem 1rem 10rem;
87
+ max-width: 46rem;
88
+ } */
89
+
90
+ /* .css-18e3th9 {
91
+ flex: 1 1 0%;
92
+ width: 100%;
93
+ padding: 6rem 1rem 10rem;
94
+ min-width: auto;
95
+ max-width: initial;
96
+ text-align: center;
97
+ justify-content: center;
98
+ } */
style_1.css ADDED
@@ -0,0 +1,146 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ p{
2
+ color:rgb(74, 113, 152);
3
+ text-align: center;
4
+ font-size: 14px;
5
+ font-family: 'Bree Serif', serif;
6
+ }
7
+
8
+
9
+
10
+
11
+ /* MÉTRICS KPIS STREAMLIT */
12
+ .css-12w0qpk.e1tzin5v2{
13
+ display: fixed;
14
+ flex-wrap: wrap;
15
+ -webkit-box-flex: 1;
16
+ flex-grow: 1;
17
+ -webkit-box-align: stretch;
18
+ align-items: stretch;
19
+ gap: 1rem;
20
+ background-color:#fff;
21
+ border-radius: 2.25rem;
22
+ text-align: center;
23
+ width: 800px;
24
+
25
+ }
26
+
27
+ /* card conteudo */
28
+
29
+ .card-main .card-body {
30
+ display: fixed;
31
+ flex-wrap: wrap;
32
+ -webkit-box-flex: 1;
33
+ flex-grow: 1;
34
+ -webkit-box-align: stretch;
35
+ align-items: stretch;
36
+ gap: 1rem;
37
+ background-color:#fff;
38
+ border-radius: 2.25rem;
39
+ text-align: center;
40
+ width: 100%;
41
+ }
42
+
43
+ /* botão input */
44
+ .st-b7 {
45
+ width: 100%;
46
+ border-radius: 2.25rem;
47
+
48
+
49
+ }
50
+
51
+ .css-18e3th9 {
52
+ flex: 1 1 0%;
53
+ width: 100%;
54
+ padding: 6rem 1rem 10rem;
55
+ min-width: auto;
56
+ max-width: initial;
57
+ text-align: center;
58
+ justify-content: center;
59
+ align-items: center;
60
+ align-content: center;
61
+ align-self: center;
62
+ vertical-align: center;
63
+ }
64
+
65
+
66
+
67
+
68
+ /* KPI BOOSTRAP */
69
+
70
+ /* .icon {
71
+ float: right;
72
+ font-size:500%;
73
+ position: absolute;
74
+ top:0rem;
75
+ right:-0.3rem;
76
+ opacity: .16;
77
+ }
78
+
79
+
80
+ #container
81
+ {
82
+ width: 800px;
83
+ display: flex;
84
+ }
85
+
86
+ .kpi-card
87
+ {
88
+ overflow: hidden;
89
+ position: relative;
90
+ box-shadow: 1px 1px 3px rgba(0,0,0,0.75);;
91
+ display: inline-block;
92
+ float: left;
93
+ padding: 1em;
94
+ border-radius: 0.3em;
95
+ font-family: sans-serif;
96
+ width: 240px;
97
+ min-width: 180px;
98
+ margin-left: 0.5em;
99
+ margin-top: 0.5em;
100
+ }
101
+
102
+ .card-value {
103
+ display: block;
104
+ font-size: 200%;
105
+ font-weight: bolder;
106
+ }
107
+
108
+ .card-text {
109
+ display:block;
110
+ font-size: 70%;
111
+ padding-left: 0.2em;
112
+ } */
113
+
114
+ /* Todos os cards juntos */
115
+ /* .card-deck {
116
+ -webkit-box-orient: horizontal;
117
+ -webkit-box-direction: normal;
118
+ -ms-flex-flow: row wrap;
119
+ flex-flow: row wrap;
120
+ margin-right: 0px;
121
+ margin-left: -15px;
122
+ width: 430px;
123
+
124
+ }
125
+
126
+
127
+ .card-deck .card {
128
+ display: -webkit-box;
129
+ display: -ms-flexbox;
130
+ display: flex;
131
+ -webkit-box-flex: 1;
132
+ -ms-flex: 1 0 0%;
133
+ flex: 1 0 0%;
134
+ -webkit-box-orient: vertical;
135
+ -webkit-box-direction: normal;
136
+ -ms-flex-direction: column;
137
+ flex-direction: column;
138
+ margin-right: 15px;
139
+ margin-bottom: 0;
140
+ margin-left: 15px;
141
+ border-radius: 2.25rem;
142
+ } */
143
+
144
+
145
+
146
+
style_2.css ADDED
@@ -0,0 +1,29 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ p{
2
+ color:rgb(74, 113, 152);
3
+ text-align: center;
4
+ font-size: 14px;
5
+ font-family: 'Bree Serif', serif;
6
+ }
7
+
8
+
9
+ /* botão input */
10
+ .st-b7 {
11
+ width: 100%;
12
+ border-radius: 2.25rem;
13
+
14
+
15
+ }
16
+
17
+ .css-18e3th9 {
18
+ flex: 1 1 0%;
19
+ width: 100%;
20
+ padding: 6rem 1rem 10rem;
21
+ min-width: auto;
22
+ max-width: initial;
23
+ text-align: center;
24
+ justify-content: center;
25
+ align-items: center;
26
+ align-content: center;
27
+ align-self: center;
28
+ vertical-align: center;
29
+ }
style_3.css ADDED
@@ -0,0 +1,29 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ p{
2
+ color:rgb(74, 113, 152);
3
+ text-align: center;
4
+ font-size: 14px;
5
+ font-family: 'Bree Serif', serif;
6
+ }
7
+
8
+
9
+ /* botão input */
10
+ .st-b7 {
11
+ width: 100%;
12
+ border-radius: 2.25rem;
13
+
14
+
15
+ }
16
+
17
+ .css-18e3th9 {
18
+ flex: 1 1 0%;
19
+ width: 100%;
20
+ padding: 6rem 1rem 10rem;
21
+ min-width: auto;
22
+ max-width: initial;
23
+ text-align: center;
24
+ justify-content: center;
25
+ align-items: center;
26
+ align-content: center;
27
+ align-self: center;
28
+ vertical-align: center;
29
+ }
style_4.css ADDED
@@ -0,0 +1,40 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ p{
2
+ color:rgb(74, 113, 152);
3
+ text-align: center;
4
+ font-size: 14px;
5
+ font-family: 'Bree Serif', serif;
6
+ }
7
+
8
+ /* .css-18e3th9 {
9
+ flex: 1 1 0%;
10
+ width: 100%;
11
+ padding: 6rem 1rem 10rem;
12
+ min-width: auto;
13
+ max-width: initial;
14
+ text-align: center;
15
+ justify-content: center;
16
+ } */
17
+
18
+
19
+
20
+ /* botão input */
21
+ .st-b7 {
22
+ width: 100%;
23
+ border-radius: 2.25rem;
24
+
25
+
26
+ }
27
+
28
+ .css-18e3th9 {
29
+ flex: 1 1 0%;
30
+ width: 100%;
31
+ padding: 6rem 1rem 10rem;
32
+ min-width: auto;
33
+ max-width: initial;
34
+ text-align: center;
35
+ justify-content: center;
36
+ align-items: center;
37
+ align-content: center;
38
+ align-self: center;
39
+ vertical-align: center;
40
+ }
style_5.css ADDED
@@ -0,0 +1,36 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ p{
2
+ color:rgb(74, 113, 152);
3
+ text-align: center;
4
+ font-size: 14px;
5
+ font-family: 'Bree Serif', serif;
6
+ }
7
+
8
+ .css-18e3th9 {
9
+ flex: 1 1 0%;
10
+ width: 100%;
11
+ padding: 6rem 1rem 10rem;
12
+ min-width: auto;
13
+ max-width: initial;
14
+ text-align: center;
15
+ justify-content: center;
16
+ align-items: center;
17
+ align-content: center;
18
+ align-self: center;
19
+ vertical-align: center;
20
+ }
21
+
22
+
23
+ /* DataFrame style */
24
+ .stDataFrame {
25
+ border-radius: 10px;
26
+ background: rgb(240, 238, 238);
27
+ background-color:#fff;
28
+ }
29
+
30
+ /* botão input */
31
+ .st-b7 {
32
+ width: 100%;
33
+ border-radius: 2.25rem;
34
+
35
+
36
+ }
style_login.css ADDED
@@ -0,0 +1,6 @@
 
 
 
 
 
 
1
+ /* botão input */
2
+ .st-b7 {
3
+ width: 250px;
4
+ border-radius: 2.25rem;
5
+
6
+ }
users.csv ADDED
@@ -0,0 +1,3 @@
 
 
 
1
+ name;user;pass;email;premium
2
+ Lucas Vasconcelos Rocha;lucasrocha;senhadosite;lucas.vasconcelos3@gmail.com;sim
3
+ testando;teste;123;;
uteis.py ADDED
@@ -0,0 +1,485 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+
2
+ #import streamlit as st
3
+ import pandas as pd
4
+ from sklearn.ensemble import RandomForestRegressor
5
+
6
+ def rank( X, y):
7
+ """
8
+ Gets a rank of relation of features to target
9
+ The output is a list of combination of features order by relevance by 'RF rank'
10
+
11
+ :param X: Train data without target
12
+ :param y: Target
13
+
14
+ """
15
+
16
+ X = X
17
+ y = y
18
+ # estimators
19
+ rank = pd.DataFrame({'features': X.columns})
20
+
21
+
22
+ rfr = RandomForestRegressor(n_jobs=-1, n_estimators=50, verbose=3)
23
+ rfr.fit(X, y)
24
+ rank['RFR'] = (rfr.feature_importances_ * 100)
25
+
26
+ #print(rank.sort_values('RFR', ascending=False))
27
+
28
+ # opções de listas de features selecionadas para cada estimador
29
+ lista_comb_feat_RFR = []
30
+ #for x in range(2, 11):
31
+ for x in range(2, len(rank)):
32
+ lista_comb_feat_RFR.append(rank.sort_values('RFR', ascending=False).head(x)['features'].tolist())
33
+
34
+ return lista_comb_feat_RFR , rank.sort_values('RFR', ascending=False)
35
+
36
+ #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
37
+ def inputer_train(lista, df, data, df_filled):
38
+
39
+ for i in range(len(lista)):
40
+ if df.loc[(df['Código de Negociação'].str.contains(lista[i]))].sort_values('Tipo de Movimentação')[-1:]['Tipo de Movimentação'].item() == 'Venda':
41
+
42
+ #Construção das variáveis
43
+ preco_medio_compra = df.loc[(df['Código de Negociação'].str.contains(lista[i])) & (df['Tipo de Movimentação'] == 'Compra' )]['Preço'].mean()
44
+ quantidade_comprada = df.loc[(df['Código de Negociação'].str.contains(lista[i])) & (df['Tipo de Movimentação'] == 'Compra' )]['Quantidade'].sum()
45
+ preco_medio_vendido = df.loc[(df['Código de Negociação'].str.contains(lista[i])) & (df['Tipo de Movimentação'] == 'Venda' )]['Preço'].mean()
46
+ quantidade_vendida = df.loc[(df['Código de Negociação'].str.contains(lista[i])) & (df['Tipo de Movimentação'] == 'Venda' )]['Quantidade'].sum()
47
+
48
+ data_compra_1 = df.loc[(df['Código de Negociação'].str.contains(lista[i]))].sort_values('Data do Negócio')[-1:]['Data do Negócio'].item()
49
+ Ganho_total = (preco_medio_vendido - preco_medio_compra) * quantidade_vendida
50
+ rendimento_total = round(((preco_medio_vendido - preco_medio_compra) / preco_medio_vendido) * 100,2)
51
+
52
+ #dados históricos ticker
53
+ dados_acao = pd.DataFrame(data.loc[ : , (['Open','High','Low','Close','Adj Close','Volume'],lista[i]+".SA")])
54
+ #dados_acao_filtrado = dados_acao.loc[dados_acao.index <= data_compra_1]
55
+ dados_acao_filtrado = dados_acao.loc[dados_acao.index <= pd.to_datetime(data_compra_1)]
56
+
57
+ #RENDIMENTO ULTIMOS X DIAS (ONTEM X DIA COMPARADO)
58
+
59
+ #valor da ultima cotação
60
+ cotacao_last = dados_acao_filtrado['Close'][-1:][lista[i]+".SA"][0]
61
+ #valor cotação x dias atras
62
+ try:
63
+ cotacao_7 = dados_acao_filtrado['Close'][-7:-6][lista[i]+".SA"][0]
64
+ cotacao_14 = dados_acao_filtrado['Close'][-14:-13][lista[i]+".SA"][0]
65
+ cotacao30 = dados_acao_filtrado['Close'][-30:-29][lista[i]+".SA"][0]
66
+ cotacao_60 = dados_acao_filtrado['Close'][-60:-59][lista[i]+".SA"][0]
67
+ cotacao_90 = dados_acao_filtrado['Close'][-90:-89][lista[i]+".SA"][0]
68
+ #% da queda ou aumento ultimos x dias
69
+ crescimento_7 = round(((cotacao_last - cotacao_7) / cotacao_7) * 100,2)
70
+ crescimento_14 = round(((cotacao_last - cotacao_14) / cotacao_14) * 100,2)
71
+ crescimento_30 = round(((cotacao_last - cotacao30) / cotacao30) * 100,2)
72
+ crescimento_60 = round(((cotacao_last - cotacao_60) / cotacao_60) * 100,2)
73
+ crescimento_90 = round(((cotacao_last - cotacao_90) / cotacao_90) * 100,2)
74
+
75
+ except:
76
+ exit
77
+
78
+ #CRESCIMENTO VOLUME ULTIMOS X DIAS (ONTEM X DIA COMPARADO)
79
+
80
+ #volume do dia anterior a compra
81
+ volume_last = dados_acao_filtrado['Volume'][-1:][lista[i]+".SA"][0]
82
+ #valor cotação x dias atras
83
+ try:
84
+ volume_7 = dados_acao_filtrado['Volume'][-7:-6][lista[i]+".SA"][0]
85
+ volume_14 = dados_acao_filtrado['Volume'][-14:-13][lista[i]+".SA"][0]
86
+ volume30 = dados_acao_filtrado['Volume'][-30:-29][lista[i]+".SA"][0]
87
+ volume_60 = dados_acao_filtrado['Volume'][-60:-59][lista[i]+".SA"][0]
88
+ volume_90 = dados_acao_filtrado['Volume'][-90:-89][lista[i]+".SA"][0]
89
+ #% da queda ou aumento ultimos x dias
90
+ crescimento_vol_7 = round(((volume_last - volume_7) / volume_7) * 100,2)
91
+ crescimento_vol_14 = round(((volume_last - volume_14) / volume_14) * 100,2)
92
+ crescimento_vol_30 = round(((volume_last - volume30) / volume30) * 100,2)
93
+ crescimento_vol_60 = round(((volume_last - volume_60) / volume_60) * 100,2)
94
+ crescimento_vol_90 = round(((volume_last - volume_90) / volume_90) * 100,2)
95
+
96
+ except:
97
+ exit
98
+
99
+ #RSI
100
+ try:
101
+ delta = dados_acao_filtrado['Close'][-90:].diff()
102
+ up, down = delta.copy(), delta.copy()
103
+ up[up < 0] = 0
104
+ down[down > 0] = 0
105
+ period = 14
106
+ rUp = up.ewm(com=period - 1, adjust=False).mean()
107
+ rDown = down.ewm(com=period - 1, adjust=False).mean().abs()
108
+ delta['RSI'] = 100 - 100 / (1 + rUp / rDown).fillna(0)
109
+
110
+ rsi_0 = delta['RSI'][-1:][0]
111
+ rsi_7 = delta['RSI'][-7:-6][0]
112
+ rsi_14 = delta['RSI'][-14:-13][0]
113
+ rsi_30 = delta['RSI'][-30:-29][0]
114
+ rsi_60 = delta['RSI'][-60:-59][0]
115
+
116
+ #% da queda ou aumento ultimos x dias
117
+ cresc_rsi_7 = round(((rsi_0 - rsi_7) / rsi_7) * 100,2)
118
+ cresc_rsi_14 = round(((rsi_0 - rsi_14) / rsi_14) * 100,2)
119
+ cresc_rsi_30 = round(((rsi_0 - rsi_30) / rsi_30) * 100,2)
120
+ cresc_rsi_60 = round(((rsi_0 - rsi_60) / rsi_60) * 100,2)
121
+
122
+ except:
123
+ exit
124
+
125
+ #BOLINGER
126
+
127
+ try:
128
+ bolinger = dados_acao_filtrado.copy()
129
+ bolinger['MA20'] = dados_acao_filtrado['Close'].rolling(20).mean()
130
+ bolinger['20 Day STD'] = bolinger['Close'].rolling(window=20).std()
131
+ bolinger['Upper Band'] = bolinger['MA20'] + (bolinger['20 Day STD'] * 2)
132
+ bolinger['Lower Band'] = bolinger['MA20'] - (bolinger['20 Day STD'] * 2)
133
+
134
+ boolinger_up_0 = bolinger['Upper Band'][-1:][0]
135
+ boolinger_down_0 = bolinger['Lower Band'][-1:][0]
136
+ boolinger_up_7 = bolinger['Upper Band'][-7:-6][0]
137
+ boolinger_down_7 = bolinger['Lower Band'][-7:-6][0]
138
+
139
+ delta_bolinger_0 = round((boolinger_up_0 - boolinger_down_0) / boolinger_down_0 * 100,2)
140
+ cresc_bolinger_up_7 = round((boolinger_up_0 - boolinger_up_7) / boolinger_up_7 * 100,2)
141
+ cresc_bolinger_down_7 = round((boolinger_down_0 - boolinger_down_7) / boolinger_down_7 * 100,2)
142
+
143
+ except:
144
+ exit
145
+
146
+
147
+ #MÉDIAS MOVEIS
148
+ try:
149
+ time = dados_acao_filtrado.copy()
150
+ rolling_9 = time['Close'].rolling(window=9)
151
+ rolling_mean_9 = rolling_9.mean().round(1)
152
+
153
+ rolling_20 = time['Close'].rolling(window=20)
154
+ rolling_mean_20 = rolling_20.mean().round(1)
155
+
156
+ rolling_72 = time['Close'].rolling(window=72)
157
+ rolling_mean_72 = rolling_72.mean().round(1)
158
+ time['MM9'] = rolling_mean_9.fillna(0)
159
+ time['MM20'] = rolling_mean_20.fillna(0)
160
+ time['MM72'] = rolling_mean_72.fillna(0)
161
+ time['cruzamento'] = time['MM9'] - time['MM72']
162
+ buy = time.tail(50).loc[(time.tail(50)['cruzamento']==0)]
163
+
164
+ if buy.empty == False:
165
+ cruzou_mm = 1
166
+ else:
167
+ cruzou_mm = 0
168
+
169
+ if time['MM72'].iloc[-1] < time['MM9'].iloc[-1]:
170
+ direcao_cruzada_cima = 1
171
+ else:
172
+ direcao_cruzada_cima = 0
173
+
174
+
175
+ mm9_0 = time['MM9'][-1:][0]
176
+ mm9_7 = time['MM9'][-7:-6][0]
177
+ mm9_14 = time['MM9'][-14:-13][0]
178
+ mm9_30 = time['MM9'][-30:-29][0]
179
+ mm9_60 = time['MM9'][-60:-59][0]
180
+
181
+ mm20_0 = time['MM20'][-1:][0]
182
+ mm20_7 = time['MM20'][-7:-6][0]
183
+ mm20_14 = time['MM20'][-14:-13][0]
184
+ mm20_30 = time['MM20'][-30:-29][0]
185
+ mm20_60 = time['MM20'][-60:-59][0]
186
+
187
+ mm72_0 = time['MM72'][-1:][0]
188
+ mm72_7 = time['MM72'][-7:-6][0]
189
+ mm72_14 = time['MM72'][-14:-13][0]
190
+ mm72_30 = time['MM72'][-30:-29][0]
191
+ mm72_60 = time['MM72'][-60:-59][0]
192
+
193
+ #% da queda ou aumento ultimos x dias
194
+ cresc_mm9_7 = round(((mm9_0 - mm9_7) / mm9_7) * 100,2)
195
+ cresc_mm9_14 = round(((mm9_0 - mm9_14) / mm9_14) * 100,2)
196
+ cresc_mm9_30 = round(((mm9_0 - mm9_30) / mm9_30) * 100,2)
197
+ cresc_mm9_60 = round(((mm9_0 - mm9_60) / mm9_60) * 100,2)
198
+
199
+ #% da queda ou aumento ultimos x dias
200
+ cresc_mm20_7 = round(((mm20_0 - mm20_7) / mm20_7) * 100,2)
201
+ cresc_mm20_14 = round(((mm20_0 - mm20_14) / mm20_14) * 100,2)
202
+ cresc_mm20_30 = round(((mm20_0 - mm20_30) / mm20_30) * 100,2)
203
+ cresc_mm20_60 = round(((mm20_0 - mm20_60) / mm20_60) * 100,2)
204
+
205
+ #% da queda ou aumento ultimos x dias
206
+ cresc_mm72_7 = round(((mm72_0 - mm72_7) / mm72_7) * 100,2)
207
+ cresc_mm72_14 = round(((mm72_0 - mm72_14) / mm72_14) * 100,2)
208
+ cresc_mm72_30 = round(((mm72_0 - mm72_30) / mm72_30) * 100,2)
209
+ cresc_mm72_60 = round(((mm72_0 - mm72_60) / mm72_60) * 100,2)
210
+
211
+ except:
212
+ exit
213
+
214
+ #try:
215
+ # pfizer = yf.Ticker(lista[i])
216
+ # info = pfizer.info
217
+
218
+ # setor = info['sector']
219
+ # atividade = info['industry']
220
+
221
+ #except:
222
+ # exit
223
+
224
+ try:
225
+ #Atribuições
226
+ df_filled.loc[df_filled['name'].str.contains(lista[i]),'data_compra_1'] = data_compra_1
227
+ df_filled.loc[df_filled['name'].str.contains(lista[i]),'Preço_médio_comprado'] = preco_medio_compra
228
+ df_filled.loc[df_filled['name'].str.contains(lista[i]),'Preço_médio_vendido'] = preco_medio_vendido
229
+ df_filled.loc[df_filled['name'].str.contains(lista[i]),'Ganho_total'] = Ganho_total
230
+
231
+ #df_filled.loc[df_filled['name'].str.contains(lista[i]),'Setor'] = setor
232
+ #df_filled.loc[df_filled['name'].str.contains(lista[i]),'Atividade'] = atividade
233
+
234
+ df_filled.loc[df_filled['name'].str.contains(lista[i]),'Rendimento_total_%'] = rendimento_total
235
+ df_filled.loc[df_filled['name'].str.contains(lista[i]),'Rendimento_ultimos_7_dias'] = crescimento_7
236
+ df_filled.loc[df_filled['name'].str.contains(lista[i]),'Rendimento_ultimos_14_dias'] = crescimento_14
237
+ df_filled.loc[df_filled['name'].str.contains(lista[i]),'Rendimento_ultimos_30_dias'] = crescimento_30
238
+ df_filled.loc[df_filled['name'].str.contains(lista[i]),'Rendimento_ultimos_60_dias'] = crescimento_60
239
+ df_filled.loc[df_filled['name'].str.contains(lista[i]),'Rendimento_ultimos_90_dias'] = crescimento_90
240
+
241
+ df_filled.loc[df_filled['name'].str.contains(lista[i]),'crescimento_vol_ultimos_7_dias'] = crescimento_vol_7
242
+ df_filled.loc[df_filled['name'].str.contains(lista[i]),'crescimento_vol_ultimos_14_dias'] = crescimento_vol_14
243
+ df_filled.loc[df_filled['name'].str.contains(lista[i]),'crescimento_vol_ultimos_30_dias'] = crescimento_vol_30
244
+ df_filled.loc[df_filled['name'].str.contains(lista[i]),'crescimento_vol_ultimos_60_dias'] = crescimento_vol_60
245
+ df_filled.loc[df_filled['name'].str.contains(lista[i]),'crescimento_vol_ultimos_90_dias'] = crescimento_vol_90
246
+
247
+ df_filled.loc[df_filled['name'].str.contains(lista[i]),'rsi'] = rsi_0
248
+ df_filled.loc[df_filled['name'].str.contains(lista[i]),'cresc_rsi_ultimos_7_dias'] = cresc_rsi_7
249
+ df_filled.loc[df_filled['name'].str.contains(lista[i]),'cresc_rsi_ultimos_14_dias'] = cresc_rsi_14
250
+ df_filled.loc[df_filled['name'].str.contains(lista[i]),'cresc_rsi_ultimos_30_dias'] = cresc_rsi_30
251
+ df_filled.loc[df_filled['name'].str.contains(lista[i]),'cresc_rsi_ultimos_60_dias'] = cresc_rsi_60
252
+
253
+ df_filled.loc[df_filled['name'].str.contains(lista[i]),'delta_bolinger_0'] = delta_bolinger_0
254
+ df_filled.loc[df_filled['name'].str.contains(lista[i]),'cresc_bolinger_up_7'] = cresc_bolinger_up_7
255
+ df_filled.loc[df_filled['name'].str.contains(lista[i]),'cresc_bolinger_down_7'] = cresc_bolinger_down_7
256
+
257
+ df_filled.loc[df_filled['name'].str.contains(lista[i]),'cruzou_mm'] = cruzou_mm
258
+ df_filled.loc[df_filled['name'].str.contains(lista[i]),'direcao_cruzada_mm_cima'] = direcao_cruzada_cima
259
+
260
+ df_filled.loc[df_filled['name'].str.contains(lista[i]),'cresc_mm9_ultimos_7_dias'] = cresc_mm9_7
261
+ df_filled.loc[df_filled['name'].str.contains(lista[i]),'cresc_mm9_ultimos_14_dias'] = cresc_mm9_14
262
+ df_filled.loc[df_filled['name'].str.contains(lista[i]),'cresc_mm9_ultimos_30_dias'] = cresc_mm9_30
263
+ df_filled.loc[df_filled['name'].str.contains(lista[i]),'cresc_mm9_ultimos_60_dias'] = cresc_mm9_60
264
+
265
+ df_filled.loc[df_filled['name'].str.contains(lista[i]),'cresc_mm20_ultimos_7_dias'] = cresc_mm20_7
266
+ df_filled.loc[df_filled['name'].str.contains(lista[i]),'cresc_mm20_ultimos_14_dias'] = cresc_mm20_14
267
+ df_filled.loc[df_filled['name'].str.contains(lista[i]),'cresc_mm20_ultimos_30_dias'] = cresc_mm20_30
268
+ df_filled.loc[df_filled['name'].str.contains(lista[i]),'cresc_mm20_ultimos_60_dias'] = cresc_mm20_60
269
+
270
+ df_filled.loc[df_filled['name'].str.contains(lista[i]),'cresc_mm72_ultimos_7_dias'] = cresc_mm72_7
271
+ df_filled.loc[df_filled['name'].str.contains(lista[i]),'cresc_mm72_ultimos_14_dias'] = cresc_mm72_14
272
+ df_filled.loc[df_filled['name'].str.contains(lista[i]),'cresc_mm72_ultimos_30_dias'] = cresc_mm72_30
273
+ df_filled.loc[df_filled['name'].str.contains(lista[i]),'cresc_mm72_ultimos_60_dias'] = cresc_mm72_60
274
+
275
+ except:
276
+ exit
277
+
278
+ def inputer_predict(data, df_filled):
279
+
280
+ lista = list(df_filled['name'])
281
+ for i in range(len(df_filled)):
282
+ dados_acao = pd.DataFrame(data.loc[ : , (['Open','High','Low','Close','Adj Close','Volume'],lista[i]+".SA")])
283
+ dados_acao_filtrado = dados_acao.copy()
284
+ #RENDIMENTO ULTIMOS X DIAS (ONTEM X DIA COMPARADO)
285
+ #valor da ultima cotação
286
+ cotacao_last = dados_acao_filtrado['Close'][-1:][lista[i]+".SA"][0]
287
+ #valor cotação x dias atras
288
+ try:
289
+ cotacao_7 = dados_acao_filtrado['Close'][-7:-6][lista[i]+".SA"][0]
290
+ cotacao_14 = dados_acao_filtrado['Close'][-14:-13][lista[i]+".SA"][0]
291
+ cotacao30 = dados_acao_filtrado['Close'][-30:-29][lista[i]+".SA"][0]
292
+ cotacao_60 = dados_acao_filtrado['Close'][-60:-59][lista[i]+".SA"][0]
293
+ cotacao_90 = dados_acao_filtrado['Close'][-90:-89][lista[i]+".SA"][0]
294
+ #% da queda ou aumento ultimos x dias
295
+ crescimento_7 = round(((cotacao_last - cotacao_7) / cotacao_7) * 100,2)
296
+ crescimento_14 = round(((cotacao_last - cotacao_14) / cotacao_14) * 100,2)
297
+ crescimento_30 = round(((cotacao_last - cotacao30) / cotacao30) * 100,2)
298
+ crescimento_60 = round(((cotacao_last - cotacao_60) / cotacao_60) * 100,2)
299
+ crescimento_90 = round(((cotacao_last - cotacao_90) / cotacao_90) * 100,2)
300
+ except:
301
+ exit
302
+ #CRESCIMENTO VOLUME ULTIMOS X DIAS (ONTEM X DIA COMPARADO)
303
+ #volume do dia anterior a compra
304
+ volume_last = dados_acao_filtrado['Volume'][-1:][lista[i]+".SA"][0]
305
+ #valor cotação x dias atras
306
+ try:
307
+ volume_7 = dados_acao_filtrado['Volume'][-7:-6][lista[i]+".SA"][0]
308
+ volume_14 = dados_acao_filtrado['Volume'][-14:-13][lista[i]+".SA"][0]
309
+ volume30 = dados_acao_filtrado['Volume'][-30:-29][lista[i]+".SA"][0]
310
+ volume_60 = dados_acao_filtrado['Volume'][-60:-59][lista[i]+".SA"][0]
311
+ volume_90 = dados_acao_filtrado['Volume'][-90:-89][lista[i]+".SA"][0]
312
+ #% da queda ou aumento ultimos x dias
313
+ crescimento_vol_7 = round(((volume_last - volume_7) / volume_7) * 100,2)
314
+ crescimento_vol_14 = round(((volume_last - volume_14) / volume_14) * 100,2)
315
+ crescimento_vol_30 = round(((volume_last - volume30) / volume30) * 100,2)
316
+ crescimento_vol_60 = round(((volume_last - volume_60) / volume_60) * 100,2)
317
+ crescimento_vol_90 = round(((volume_last - volume_90) / volume_90) * 100,2)
318
+ except:
319
+ exit
320
+ #RSI
321
+ try:
322
+ delta = dados_acao_filtrado['Close'][-90:].diff()
323
+ up, down = delta.copy(), delta.copy()
324
+ up[up < 0] = 0
325
+ down[down > 0] = 0
326
+ period = 14
327
+ rUp = up.ewm(com=period - 1, adjust=False).mean()
328
+ rDown = down.ewm(com=period - 1, adjust=False).mean().abs()
329
+ delta['RSI'] = 100 - 100 / (1 + rUp / rDown).fillna(0)
330
+
331
+ rsi_0 = delta['RSI'][-1:][0]
332
+ rsi_7 = delta['RSI'][-7:-6][0]
333
+ rsi_14 = delta['RSI'][-14:-13][0]
334
+ rsi_30 = delta['RSI'][-30:-29][0]
335
+ rsi_60 = delta['RSI'][-60:-59][0]
336
+
337
+ #% da queda ou aumento ultimos x dias
338
+ cresc_rsi_7 = round(((rsi_0 - rsi_7) / rsi_7) * 100,2)
339
+ cresc_rsi_14 = round(((rsi_0 - rsi_14) / rsi_14) * 100,2)
340
+ cresc_rsi_30 = round(((rsi_0 - rsi_30) / rsi_30) * 100,2)
341
+ cresc_rsi_60 = round(((rsi_0 - rsi_60) / rsi_60) * 100,2)
342
+ except:
343
+ exit
344
+ #BOLINGER
345
+ try:
346
+ bolinger = dados_acao_filtrado.copy()
347
+ bolinger['MA20'] = dados_acao_filtrado['Close'].rolling(20).mean()
348
+ bolinger['20 Day STD'] = bolinger['Close'].rolling(window=20).std()
349
+ bolinger['Upper Band'] = bolinger['MA20'] + (bolinger['20 Day STD'] * 2)
350
+ bolinger['Lower Band'] = bolinger['MA20'] - (bolinger['20 Day STD'] * 2)
351
+
352
+ boolinger_up_0 = bolinger['Upper Band'][-1:][0]
353
+ boolinger_down_0 = bolinger['Lower Band'][-1:][0]
354
+ boolinger_up_7 = bolinger['Upper Band'][-7:-6][0]
355
+ boolinger_down_7 = bolinger['Lower Band'][-7:-6][0]
356
+
357
+ delta_bolinger_0 = round((boolinger_up_0 - boolinger_down_0) / boolinger_down_0 * 100,2)
358
+ cresc_bolinger_up_7 = round((boolinger_up_0 - boolinger_up_7) / boolinger_up_7 * 100,2)
359
+ cresc_bolinger_down_7 = round((boolinger_down_0 - boolinger_down_7) / boolinger_down_7 * 100,2)
360
+ except:
361
+ exit
362
+ #MÉDIAS MOVEIS
363
+ try:
364
+ time = dados_acao_filtrado.copy()
365
+ rolling_9 = time['Close'].rolling(window=9)
366
+ rolling_mean_9 = rolling_9.mean().round(1)
367
+
368
+ rolling_20 = time['Close'].rolling(window=20)
369
+ rolling_mean_20 = rolling_20.mean().round(1)
370
+
371
+ rolling_72 = time['Close'].rolling(window=72)
372
+ rolling_mean_72 = rolling_72.mean().round(1)
373
+ time['MM9'] = rolling_mean_9.fillna(0)
374
+ time['MM20'] = rolling_mean_20.fillna(0)
375
+ time['MM72'] = rolling_mean_72.fillna(0)
376
+ time['cruzamento'] = time['MM9'] - time['MM72']
377
+ buy = time.tail(50).loc[(time.tail(50)['cruzamento']==0)]
378
+
379
+ if buy.empty == False:
380
+ cruzou_mm = 1
381
+ else:
382
+ cruzou_mm = 0
383
+
384
+ if time['MM72'].iloc[-1] < time['MM9'].iloc[-1]:
385
+ direcao_cruzada_cima = 1
386
+ else:
387
+ direcao_cruzada_cima = 0
388
+
389
+ mm9_0 = time['MM9'][-1:][0]
390
+ mm9_7 = time['MM9'][-7:-6][0]
391
+ mm9_14 = time['MM9'][-14:-13][0]
392
+ mm9_30 = time['MM9'][-30:-29][0]
393
+ mm9_60 = time['MM9'][-60:-59][0]
394
+
395
+ mm20_0 = time['MM20'][-1:][0]
396
+ mm20_7 = time['MM20'][-7:-6][0]
397
+ mm20_14 = time['MM20'][-14:-13][0]
398
+ mm20_30 = time['MM20'][-30:-29][0]
399
+ mm20_60 = time['MM20'][-60:-59][0]
400
+
401
+ mm72_0 = time['MM72'][-1:][0]
402
+ mm72_7 = time['MM72'][-7:-6][0]
403
+ mm72_14 = time['MM72'][-14:-13][0]
404
+ mm72_30 = time['MM72'][-30:-29][0]
405
+ mm72_60 = time['MM72'][-60:-59][0]
406
+
407
+ #% da queda ou aumento ultimos x dias
408
+ cresc_mm9_7 = round(((mm9_0 - mm9_7) / mm9_7) * 100,2)
409
+ cresc_mm9_14 = round(((mm9_0 - mm9_14) / mm9_14) * 100,2)
410
+ cresc_mm9_30 = round(((mm9_0 - mm9_30) / mm9_30) * 100,2)
411
+ cresc_mm9_60 = round(((mm9_0 - mm9_60) / mm9_60) * 100,2)
412
+
413
+ #% da queda ou aumento ultimos x dias
414
+ cresc_mm20_7 = round(((mm20_0 - mm20_7) / mm20_7) * 100,2)
415
+ cresc_mm20_14 = round(((mm20_0 - mm20_14) / mm20_14) * 100,2)
416
+ cresc_mm20_30 = round(((mm20_0 - mm20_30) / mm20_30) * 100,2)
417
+ cresc_mm20_60 = round(((mm20_0 - mm20_60) / mm20_60) * 100,2)
418
+
419
+ #% da queda ou aumento ultimos x dias
420
+ cresc_mm72_7 = round(((mm72_0 - mm72_7) / mm72_7) * 100,2)
421
+ cresc_mm72_14 = round(((mm72_0 - mm72_14) / mm72_14) * 100,2)
422
+ cresc_mm72_30 = round(((mm72_0 - mm72_30) / mm72_30) * 100,2)
423
+ cresc_mm72_60 = round(((mm72_0 - mm72_60) / mm72_60) * 100,2)
424
+
425
+ except:
426
+ exit
427
+
428
+ try:
429
+
430
+ #Atribuições
431
+ #df_filled.loc[df_filled['name'].str.contains(lista[i]),'data_compra_1'] = data_compra_1
432
+ #df_filled.loc[df_filled['name'].str.contains(lista[i]),'Preço_médio_comprado'] = preco_medio_compra
433
+ #df_filled.loc[df_filled['name'].str.contains(lista[i]),'Preço_médio_vendido'] = preco_medio_vendido
434
+ #df_filled.loc[df_filled['name'].str.contains(lista[i]),'Ganho_total'] = Ganho_total
435
+
436
+ #df_filled.loc[df_filled['name'].str.contains(lista[i]),'Setor'] = setor
437
+ #df_filled.loc[df_filled['name'].str.contains(lista[i]),'Atividade'] = atividade
438
+
439
+ #df_filled.loc[df_filled['name'].str.contains(lista[i]),'Rendimento_total_%'] = rendimento_total
440
+ df_filled.loc[df_filled['name'].str.contains(lista[i]),'Rendimento_ultimos_7_dias'] = crescimento_7
441
+ df_filled.loc[df_filled['name'].str.contains(lista[i]),'Rendimento_ultimos_14_dias'] = crescimento_14
442
+ df_filled.loc[df_filled['name'].str.contains(lista[i]),'Rendimento_ultimos_30_dias'] = crescimento_30
443
+ df_filled.loc[df_filled['name'].str.contains(lista[i]),'Rendimento_ultimos_60_dias'] = crescimento_60
444
+ df_filled.loc[df_filled['name'].str.contains(lista[i]),'Rendimento_ultimos_90_dias'] = crescimento_90
445
+
446
+ df_filled.loc[df_filled['name'].str.contains(lista[i]),'crescimento_vol_ultimos_7_dias'] = crescimento_vol_7
447
+ df_filled.loc[df_filled['name'].str.contains(lista[i]),'crescimento_vol_ultimos_14_dias'] = crescimento_vol_14
448
+ df_filled.loc[df_filled['name'].str.contains(lista[i]),'crescimento_vol_ultimos_30_dias'] = crescimento_vol_30
449
+ df_filled.loc[df_filled['name'].str.contains(lista[i]),'crescimento_vol_ultimos_60_dias'] = crescimento_vol_60
450
+ df_filled.loc[df_filled['name'].str.contains(lista[i]),'crescimento_vol_ultimos_90_dias'] = crescimento_vol_90
451
+
452
+ df_filled.loc[df_filled['name'].str.contains(lista[i]),'rsi'] = rsi_0
453
+ df_filled.loc[df_filled['name'].str.contains(lista[i]),'cresc_rsi_ultimos_7_dias'] = cresc_rsi_7
454
+ df_filled.loc[df_filled['name'].str.contains(lista[i]),'cresc_rsi_ultimos_14_dias'] = cresc_rsi_14
455
+ df_filled.loc[df_filled['name'].str.contains(lista[i]),'cresc_rsi_ultimos_30_dias'] = cresc_rsi_30
456
+ df_filled.loc[df_filled['name'].str.contains(lista[i]),'cresc_rsi_ultimos_60_dias'] = cresc_rsi_60
457
+
458
+ df_filled.loc[df_filled['name'].str.contains(lista[i]),'delta_bolinger_0'] = delta_bolinger_0
459
+ df_filled.loc[df_filled['name'].str.contains(lista[i]),'cresc_bolinger_up_7'] = cresc_bolinger_up_7
460
+ df_filled.loc[df_filled['name'].str.contains(lista[i]),'cresc_bolinger_down_7'] = cresc_bolinger_down_7
461
+
462
+ df_filled.loc[df_filled['name'].str.contains(lista[i]),'cruzou_mm'] = cruzou_mm
463
+ df_filled.loc[df_filled['name'].str.contains(lista[i]),'direcao_cruzada_mm_cima'] = direcao_cruzada_cima
464
+
465
+ df_filled.loc[df_filled['name'].str.contains(lista[i]),'cresc_mm9_ultimos_7_dias'] = cresc_mm9_7
466
+ df_filled.loc[df_filled['name'].str.contains(lista[i]),'cresc_mm9_ultimos_14_dias'] = cresc_mm9_14
467
+ df_filled.loc[df_filled['name'].str.contains(lista[i]),'cresc_mm9_ultimos_30_dias'] = cresc_mm9_30
468
+ df_filled.loc[df_filled['name'].str.contains(lista[i]),'cresc_mm9_ultimos_60_dias'] = cresc_mm9_60
469
+
470
+ df_filled.loc[df_filled['name'].str.contains(lista[i]),'cresc_mm20_ultimos_7_dias'] = cresc_mm20_7
471
+ df_filled.loc[df_filled['name'].str.contains(lista[i]),'cresc_mm20_ultimos_14_dias'] = cresc_mm20_14
472
+ df_filled.loc[df_filled['name'].str.contains(lista[i]),'cresc_mm20_ultimos_30_dias'] = cresc_mm20_30
473
+ df_filled.loc[df_filled['name'].str.contains(lista[i]),'cresc_mm20_ultimos_60_dias'] = cresc_mm20_60
474
+
475
+ df_filled.loc[df_filled['name'].str.contains(lista[i]),'cresc_mm72_ultimos_7_dias'] = cresc_mm72_7
476
+ df_filled.loc[df_filled['name'].str.contains(lista[i]),'cresc_mm72_ultimos_14_dias'] = cresc_mm72_14
477
+ df_filled.loc[df_filled['name'].str.contains(lista[i]),'cresc_mm72_ultimos_30_dias'] = cresc_mm72_30
478
+ df_filled.loc[df_filled['name'].str.contains(lista[i]),'cresc_mm72_ultimos_60_dias'] = cresc_mm72_60
479
+
480
+
481
+ except:
482
+ exit
483
+
484
+ return df_filled
485
+