Spaces:
Sleeping
Sleeping
Lucas Vasconcelos Rocha
commited on
Commit
•
4565b50
1
Parent(s):
f0cfe63
Add application file
Browse files- App.py +93 -0
- Procfile +1 -0
- data/b3_sem_resumo.xlsx +0 -0
- data/classification_b3.xlsx +0 -0
- data/top_100.xlsx +0 -0
- data/top_200.xlsx +0 -0
- data/top_300.xlsx +0 -0
- data/top_ativos.xlsx +0 -0
- home.py +20 -0
- html01.py +62 -0
- html_home.py +11 -0
- images/b3.png +0 -0
- images/home_image_2.jpeg +0 -0
- login.py +81 -0
- pag1.py +466 -0
- pag2.py +278 -0
- pag3.py +124 -0
- pag4.py +176 -0
- pag5.py +532 -0
- requirements.txt +128 -0
- scrap.py +245 -0
- scripts/scrap.py +234 -0
- setup.sh +13 -0
- style.py +95 -0
- style_0.css +98 -0
- style_1.css +146 -0
- style_2.css +29 -0
- style_3.css +29 -0
- style_4.css +40 -0
- style_5.css +36 -0
- style_login.css +6 -0
- users.csv +3 -0
- 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 |
+
|