Parte 1
A Análise Técnica Básica (ATB) da B3/BOVESPA compreende as etapas de:
Importe os pacotes Python utilizados na ATB.
import os
from io import BytesIO
from zipfile import ZipFile
import matplotlib as mpl
import matplotlib.pyplot as plt
import numpy as np
import pandas as pd
import seaborn as sns
Os dados utilizados estão disponíveis no site da B3 e devem ser baixados, e depois copiados, da pasta onde foram baixados em arquivos (no Windows é a pasta Downloads), para pasta de trabalho BOVESPA.
Os arquivos baixados estão em formato compactado (com extensão .zip), geralmente referido como formato zipado, e são baixados por períodos (diário, mensal ou anual).
Confirme que é humano na opção de confirmação da janela do captcha anti-robô.
Após baixados, os arquivos de cotação devem ser transferidos para o diretório de trabalho BOVESPA, onde poderão ser localizados, carregados e utilizados.
Crie uma pasta nomeada "BOVESPA" na raiz do seu disco "C:" (ou no disco em que desejar, usaremos C como referência).
Com o navegador da Internet carregue a página de séries históricas da B3/BOVESPA.
O site de séries históricas pode ser acessado aqui.
Clique em "Qual o formato do arquivo?" e depois clique em "Arquivo de demonstração".
Observe no canto inferior esquerdo o arquivo baixado.
Copie o arquivo de demonstração "SeriesHistoricas_ DemoCotacoesHistoricas12022003.zip" da pasta onde foi baixado (geralmente a pasta Downloads do Windows) para a pasta "BOVESPA".
Clique nesse arquivo e com o botão direito do mouse selecione a opção "extrair aqui" (ou "extract here"), para extrair o arquivo-texto de dentro do arquivo-zip.
O arquivo-texto "DemoCotacoesHistoricas12022003.txt" de demostração contem as linhas dos dados do pregão do dia 12/02/2003.
Com os pacotes do Python importados, iniciamos a usar o Python com as instruções para a realização da ATB (Análise Técnica Básica).
Primeiro, selecionamos a pasta BOVESPA como pasta de trabalho, onde os arquivos utilizados serão localizados.
os.chdir("C:\\bovespa")
Os arquivos zipados de cotações baixados do site da B3 contêm, internamente, um único arquivo-texto com n linhas dentro, contendo diversos campos de dados, onde n é o número total de cotações realizadas, nas datas de pregão presentes no arquivo.
Estas linhas contêm, colados um no outro sem nenhum separador, juntos, os dados da cotação presentes da linha.
Estes dados são separados através de sua posição e tamanho na linha, com o uso do layout que define as posições, tipos, tamanhos e decimais dos campos.
A descrição do layout está disponível no arquivo "SeriesHistoricas_Layout.pdf".
Agora clique em "Como interpretar o arquivo?" e então clique em "Layout do arquivo de cotações" para baixar o arquivo "SeriesHistoricas_Layout.pdf".
Observe no canto inferior esquerdo o ícone do arquivo baixado.
Copie o arquivo, da pasta onde foi baixado (no Windows é a pasta Downloads), para a pasta de trabalho BOVESPA.
Abra este arquivo para ver o conteúdo do layout.
A seguir temos a sequência das páginas contidas no arquivo PDF com o layout dos arquivos de cotações.
Criamos na pasta de trabalho BOVESPA um arquivo-texto no formato CSV, nomeado "bovespa_layout.csv", esquematizando, a partir das informações de layout no PDF da B3, os dados dos campos nas linhas de cotações dos arquivos zipados da B3.
Este arquivo pode ser baixado aqui.
Baixe o arquivo e copie para a pasta de trabalho BOVESPA.
Abra o arquivo no modo de leitura de texto ("rt") e imprima as linhas para ver o conteúdo do arquivo.
f = open("bovespa_layout.csv","rt",encoding='UTF-8')
line = f.readline()
while line:
print(line)
line = f.readline()
f.close()
Conteúdo do arquivo:
Carregue na variável dfbvlay o dataframe do Pandas, a partir do arquivo-csv do layout.
Observe a declaração do formato "UTF-8" de texto e o uso do caracter ";" como separador das colunas usadas no layout.
dfbvlay = pd.read_csv("bovespa_layout.csv",encoding='UTF-8',sep=";")
Imprima o dataframe e veja o conteúdo do dataframe do layout de cotações.
print(dfbvlay)
A função cieda_b3_tipos_tamanhos_decimais carrega em 3 listas - tipos, tamanhos e decimais - os dados de layout dos campos da variável fbvlay, a fim de otimizar o acesso a estes dados.
def cieda_b3_tipos_tamanhos_decimais(dfbvlay):
tipos = []
tamanhos = []
decimais = []
for row in dfbvlay.itertuples(index=True, name='Pandas'):
tipos.append(row.TIPO)
tamanhos.append(row.TAM)
decimais.append(row.DEC)
return tipos, tamanhos, decimais
Verifique o conteúdo das listas.
Carregue as listas com a função e as imprima para ver o conteúdo.
As listas são de mesmo tamanho, e têm correspondência de índices, formando conjuntos com o tipo, tamanho e decimais do campo.
tipos, tamanhos, decimais = cieda_b3_tipos_tamanhos_decimais(dfbvlay)
print("TIPOS :", tipos)
print("TAMANHOS :", tamanhos)
print("DECIMAIS :", decimais)
A função insert_str é auxiliar e serve para inserir um texto dentro de outro.
def insert_str(string, str_to_insert, index):
return string[:index] + str_to_insert + string[index:]
A função cieda_b3_percorrer_linhas_cotacoes recebe o arquivo-zip ou o arquivo-texto dezipado (extraido do arquivo-zip) e percorre as linhas, decodificando os campos, utilizando o esquema do layout.
def cieda_b3_percorrer_linhas_cotacoes(arqcot, tipos, tamanhos, decimais):
lista = [] # lista de linhas com colunas de campos inicia vazia
linha = arqcot.readline() # primeira linha é lida do arquivo
while linha: # enquanto houver linhas
if isinstance(linha,bytes): # se a linha vier do arquivo-zip estará como uma sequência de bytes
linha = linha.decode('UTF-8').strip() # a sequência de bytes é convertida para texto
if linha[:2] == "01": # os dois primeiros caracteres igual "01" indicam que a linha é de cotação
cols = [] # a lista de campos é iniciada vazia
for colnum in range(len(tipos)): # enquanto houverem tipos, há campos
tipo = tipos[colnum] # tipo do campo sendo processado
tam = tamanhos[colnum] # tamanho do campo na linha de texto
str = linha[0:tam] # é lida a porção da linha de texto com o dado do campo
linha = linha[tam:] # linha recebe o restante sem o campo atual
if tipo == "X": # o campo é alfanumérico?
cols.append(str.strip()) # o valor do campo é colocado na lista de campos sem brancos antes ou depois
if tipo == "D": # o campo é data?
ano = str[:4] # parte AAAA do formato AAAAMMDD da data
mes = str[4:6] # parte MM do formato AAAAMMDD da data
dia = str[6:] # parte DD do formato AAAAMMDD da data
cols.extend([ # a data é destrinchada em 6 campos de datas correspondentes
"{}-{}-{}".format(ano,mes,dia), # "AAAA-MM-DD" texto
int(dia), # DD inteiro
int(mes), # MM inteiro
int(ano), # AAAA inteiro
int(str), # AAAAMMDD inteiro
int("{}{}".format(ano,mes)), # AAAAMM inteiro
"{}-{}-{}".format(dia,mes,ano)]) # "DD-MM-AAAA" texto
elif tipo == "N": # o campo é numérico
dec = decimais[colnum] # número de casas decimais do campo numérico
if dec: # tem decimais?
str = insert_str(str,".",tam-dec) # inserir o "." no local correto
cols.append(float(str)) # incluir o campo numérico como um tipo real na lista de campos
else:
cols.append(int(str)) # incluir o campo numérico como um tipo inteiro na lista de campos
lista.append(cols) # adicionar a lista de campos na lista de linhas de cotações
linha = arqcot.readline() # ler a próxima linha de texto de cotação no arquivo zip ou txt.
return lista # é retorna a lista de linhas de campos
A função cieda_b3_ler_lista_arq_txt_cot() retorna a lista (do tipo list nativo do Python), com as linhas de dados das cotações lidas do arquivo-txt dezipado do arquivo-zip baixado.
Esta função executa 3 instruções em conjunto:
def cieda_b3_ler_lista_arq_txt_cot(dfbvlay, nome_arq_cot_bv):
tipos, tamanhos, decimais = cieda_b3_tipos_tamanhos_decimais(dfbvlay)
arqcot = open(nome_arq_cot_bv,"rt",encoding='UTF-8')
return cieda_b3_percorrer_linhas_cotacoes(arqcot,tipos,tamanhos,decimais)
A lista de linhas de campos retornada deve ser convertida para um dataframe do Pandas para trabalho.
Primeiro convertemos a lista para o primeiro dataframe (que será posteriormente ajustado para economizar memória), usando a lista de dados das cotações e outra lista correspondente de nomes das colunas (columns) do dataframe.
def cieda_b3_df_cot_converter_lista(lista):
colunas = [
'TIPREG', 'DATPRE', 'DIAPRE', 'MESPRE', 'ANOPRE', 'AMDPRE', 'AMPRE', 'DMAPRE',
'CODBDI', 'CODNEG', 'TPMERC', 'NOMRES', 'ESPECI', 'PRAZOT',
'MODREF', 'PREABE', 'PREMAX', 'PREMIN', 'PREMED', 'PREULT',
'PREOFC', 'PREOFV', 'TOTNEG', 'QUATOT', 'VOLTOT', 'PREEXE',
'INDOPC', 'DATVEN', 'DIAVEN', 'MESVEN', 'ANOVEN', 'AMDVEN', 'AMVEN', 'DMAVEN',
'FATCOT', 'PTOEXE', 'CODISI', 'DISMES']
return pd.DataFrame(lista,columns=colunas)
A função cieda_b3_df_cot_ajustar() permite o ajuste dos tipos numéricos dos campos do dataframe.
Os tipos dos campos numéricos são convertidos, daqueles com representação binária de maior precisão, para outros com menor precisão.
Não ocorre alteração de valores, mesmo com a diminição da representação binária.
Ocorrem (1) diminuição do espaço ocupado de memória pelo dataframe e (2) aumento da velocidade de processamento.
def cieda_b3_df_cot_ajustar(df):
return df.astype({
'DIAPRE':'int8',
'MESPRE':'int8',
'ANOPRE':'int16',
'AMDPRE':'int32',
'AMPRE' :'int32',
'TPMERC':'int8',
'PREABE':'float16',
'PREMAX':'float16',
'PREMIN':'float16',
'PREMED':'float16',
'PREULT':'float16',
'PREOFC':'float16',
'PREOFV':'float16',
'TOTNEG':'int32',
'PREEXE':'float16',
'INDOPC':'int16',
'FATCOT':'int16',
'PTOEXE':'float16',
'DISMES':'int16',
'DIAVEN':'int8',
'MESVEN':'int8',
'ANOVEN':'int16',
'AMDVEN':'int32',
'AMVEN' :'int32'})
A função cieda_b3_df_ler_arq_cot() retorna o dataframe comprimido do arquivo de cotações.
Realiza 3 instruções em conjunto:
def cieda_b3_df_ler_arq_cot(dfbvlay, nome_arq_cot_bv):
lista = cieda_b3_ler_lista_arq_txt_cot(dfbvlay,nome_arq_cot_bv)
df = cieda_b3_df_cot_converter_lista(lista)
return cieda_b3_df_cot_ajustar(df)
Declarada a função cieda_b3_df_ler_arq_cot, carregamos o dataframe ajustado a partir do arquivo-texto de demonstração "DemoCotacoesHistoricas12022003.txt", dezipado de dentro do arquivo-zip "SeriesHistoricas_ DemoCotacoesHistoricas12022003.zip".
O arquivo contém as cotações de diversos códigos de negociação (VALE3, PETR4, USIM3 etc), do dia 12/02/2003, entretanto com apenas uma linha de cotação por código de negociação, já que contém apenas um dia de prergão no seu conteúdo.
df_d12m2a3 = cieda_b3_df_ler_arq_cot(dfbvlay,"DemoCotacoesHistoricas12022003.txt")
print(df_d12m2a3)
A função cieda_b3_col_data recebe uma data de ano, ano/mês ou ano/mês/dia, ajustando o valor e selecionando a coluna de data em função desse valor de data.
def cieda_b3_col_data(data,limite=0,sufixo="PRE"):
if data == -1:
col = None
elif data == -2:
col = 'AMD'+sufixo
data = limite
elif data <= 99:
col = 'ANO'+sufixo
data += 2000
elif data <= 9999:
col = 'AM'+sufixo
data += 200000
elif data <= 99999999:
col = 'AMD'+sufixo
if data <= 999999:
data += 20000000
else:
col = data = None
return col, data
A função cieda_b3_df_dp() retorna um dataframe com os campos do datafame df com as linhas de cotações com datas entre da dataini e datafim.
def cieda_b3_df_dp(df=None, dataini=-1, datafim=-1, debug=False):
# testar se os dados são valores inteiros representando ano/mes/dia
ok1 = (isinstance(dataini, int) and isinstance(datafim, int))
# testar se estes valores inteiros estão nas faixas permitidas
ok2 = ((-2 <= dataini <= -1) or (dataini >= 0)) and ((-2 <= datafim <= -1) or (datafim >= 0))
# retornar se as condições forem inválidas
if not (ok1 and ok2):
return None # None representa "argumentos inválidos"
print("argumentos inválidos")
# testes das faixas de datas
# se os valores das datas inicial e final forem -1 ou -2 será utilizado todo o dataset
colini, dataini = cieda_b3_col_data(dataini,0)
colfim, datafim = cieda_b3_col_data(datafim,99999999)
if colini:
if colfim: # tem data inicial e final
if debug: print("1")
aux = df[(df[colini] >= dataini) & (df[colfim] <= datafim)]
else: # sem data final basta a data inicial
if debug: print("2")
aux = df[(df[colini] == dataini)]
else:
if colfim: # sem data inicial basta a data final
if debug: print("3")
aux = df[(df[colfim] == datafim)]
else: # sem data inicial e final retorna o dataframe todo
if debug: print("4")
aux = df
if debug:
print(aux)
print('colini: ', colini)
print('colfim: ', colfim)
print('datini: ', dataini)
print('datfim: ', datafim)
return aux
A função cieda_b3_df_cndp retorna o subconjunto de dados dos códigos de negociação, em determinada faixa de datas, com colunas variáveis.
def cieda_b3_df_cndp(df=None,cols="",codneg="",dataini=-1,datafim=-1,debug=False):
# testar se os dados são ano/mes AAMM
ok1 = (isinstance(dataini, int) and isinstance(datafim, int))
ok2 = (-2 <= dataini <= -1) or (dataini >= 0) and ((-2 <= datafim <= -1) or (datafim >= 0))
if not (ok1 and ok2):
print("argumentos inválidos")
return
codigos = codneg.split(",")
colini, dataini = cieda_b3_col_data(dataini,0)
colfim, datafim = cieda_b3_col_data(datafim,99999999)
if colini:
if colfim: # tem data inicial e final
if debug: print("1")
aux = df[(df['CODNEG'].isin(codigos)) & (df[colini] >= dataini) & (df[colfim] <= datafim)]
else: # sem data final basta a data inicial
if debug: print("2")
aux = df[(df['CODNEG'].isin(codigos)) & (df[colini] == dataini)]
else:
if colfim: # sem data inicial basta a data final
if debug: print("3")
aux = df[(df['CODNEG'].isin(codigos)) & (df[colini] >= dataini) & (df[colfim] <= datafim)]
else: # sem data inicial e final retorna o dataframe todo
if debug: print("4")
aux = df[df['CODNEG'].isin(codigos)]
if cols:
cols = cols.split(",")
tam = len(cols)
if tam == 1:
aux = aux[cols[0]]
else:
if (tam == 2) and not(cols[1]):
cols = cols[0]
aux = aux[[cols]]
else:
aux = aux[cols]
if debug:
print(aux)
print('cols: ', cols)
print('codneg: ', codigos)
print('colini: ', colini)
print('colfim: ', colfim)
print('datini: ', dataini)
print('datfim: ', datafim)
return aux
Atalho para função cieda_b3_df_cndp
def cndp(*args,**kwargs):
return cieda_b3_df_cndp(*args,**kwargs)
Exemplo de subconjunto de códigos de negociação e data do pregão
df_d12m2a3_VALE3_PETR4 = cieda_b3_df_cndp(
df_d12m2a3,
"CODNEG,PREABE,PREMIN,PREMAX,PREULT",
"VALE3,PETR4")
print(df_d12m2a3_VALE3_PETR4)
A função cieda_b3_plot_cndp plota no gráfico a quantidade de pregões no eixo x e os valores da coluna de "col" no eixo y, dos códigos de negociação de "codneg".
def cieda_b3_plot_cndp(df,col,codneg):
dfcn = df[df["CODNEG"] == codneg] # retorna o dataframe de códigos de negociação e colunas desejadas
x = [x+1 for x in list(range(len(dfcn)))] # x com as quantidades de pregões
y = dfcn[col] # y com as colunas desejadas
plt.plot(x,y,label=codneg) # plota no gráfico pregões x valores das colunas
mpl.rc('figure', figsize=(16,12))
font = {'family' : 'Dejavu Sans',
'weight' : 'bold',
'size' : 12}
mpl.rc('font', **font)
Gráfico simples de um pregão
cieda_b3_plot_cndp(df_d12m2a3,"PREULT","VALE3")
plt.show()
NameError: name 'df_d12m2a3' is not defined A função cieda_b3_ler_arquivo_zip_cotacoes() retorna a lista de cotações extraida do arquivo-txt dentro do arquivo-zip baixado do site da B3.
def cieda_b3_ler_arquivo_zip_cotacoes(dfbvlay,nome_arq_cot_bv):
tipos, tamanhos, decimais = cieda_b3_tipos_tamanhos_decimais(dfbvlay)
arq_zip = open(nome_arq_cot_bv,"rb")
meu_zip = ZipFile(BytesIO(arq_zip.read()))
lista = None
for nome_arq_zip in meu_zip.namelist():
lista = cieda_b3_percorrer_linhas_cotacoes(meu_zip.open(nome_arq_zip,"r"),tipos,tamanhos,decimais)
break
return lista
A função cieda_b3_df_ler_arq_zip_cot() retorna o dataframe ajustado de cotações da lista.
def cieda_b3_df_ler_arq_zip_cot(dfbvlay,nome_arq_cot_bv):
lista = cieda_b3_ler_arquivo_zip_cotacoes(dfbvlay,nome_arq_cot_bv)
df = cieda_b3_df_cot_converter_lista(lista)
return cieda_b3_df_cot_ajustar(df)
Carregamento das cotações do ano de 2022.
carregamento_leve = 1
#
if carregamento_leve:
df_a22 = cieda_b3_df_ler_arq_zip_cot(dfbvlay,"COTAHIST_M082022.ZIP")
else:
df_a22 = cieda_b3_df_ler_arq_zip_cot(dfbvlay,"COTAHIST_A2022.ZIP")
Carregamento das cotações de janeiro a setembro de 2022.
df_m1m9a22 = cieda_b3_df_dp(df_a22,2201,2209)
Imprima o dataframe "df_m1m9a22".
print(df_m1m9a22)
Obtemos o dataframe com os dados usando a data inicial e a data final com ano e mes na forma curta.
df_m7m9a22 = cieda_b3_df_dp(df_m1m9a22,2207,2209)
Imprimimos o dataframe e observamos o conteúdo.
print(df_m7m9a22)
Obtemos o dataframe com os dados usando a data inicial com ano e mes na forma curta.
df_m8a22 = cieda_b3_df_dp(df_m7m9a22,2208)
Imprimimos o dataframe e observamos o conteúdo.
print(df_m8a22)
A função cieda_b3_plot_col_codneg() plota o dataframe com as colunas em col, dos campos das cotações, do código de negociação codneg.
def cieda_b3_plot_col_codneg(df,col,codneg):
dfaux = df[df["CODNEG"] == codneg]
x = [x+1 for x in list(range(len(dfaux)))]
y = dfaux[col]
plt.plot(x,y,label=codneg)
A função cieda_b3_show_grafico mostra o gráfico utilizando os argumentos de titulo, xlabel, ylabel e legenda.
def cieda_b3_show_grafico(titulo="Sem título", xlabel="eixo x", ylabel="eixo y", legenda=False):
plt.title(titulo)
plt.xlabel(xlabel)
plt.ylabel(ylabel)
if legenda:
plt.legend()
plt.show()
A função cieda_b3_show_multi_cndp() plota as séries e mostra o gráfico do dataframe de df, usando as colunas de col, os códigos de negociações de codnegs, e a faixa de datas de dataini a datafim.
def cieda_b3_show_multi_cndp(df, col, codnegs, dataini=-1, datafim=-1, sobrepor=False):
dfaux = cieda_b3_df_cndp(df,"CODNEG,DMAPRE,"+col,codnegs,dataini,datafim)
data_inicial = dfaux["DMAPRE"].iloc[0]
data_final = dfaux["DMAPRE"].iloc[-1]
xlabel = "Pregões de {} a {}".format(data_inicial,data_final)
codnegs_unicos = dfaux["CODNEG"].unique()
for codneg in codnegs_unicos:
cieda_b3_plot_col_codneg(dfaux,col,codneg)
if not sobrepor:
cieda_b3_show_grafico("CODNEG: "+codneg, xlabel, col, True)
if sobrepor:
titulo = "CODNEG: "+", ".join(codnegs_unicos)
cieda_b3_show_grafico(titulo, xlabel, col, True)
Gráficos de linhas de diferentes campos do código de negociação VALE3 dos pregões dos meses entre abril a junho no ano de 2022.
Gráfico de linhas de preço de fechamento.
cieda_b3_show_multi_cndp(df_m7m9a22,"PREULT","VALE3")
NameError: name 'df_m7m9a22' is not defined Gráfico de linhas de volume total.
cieda_b3_show_multi_cndp(df_m7m9a22,"VOLTOT","VALE3")
NameError: name 'df_m7m9a22' is not defined A média móvel é um importante indicador da categoria dos Rastreadores de Tendência.
Mede o valor médio do preço, volume ou outro indicador em um determinado período.
Sua representação gráfica geralmente é feita por meio de uma linha que se movimenta a cada novo dado recebido para cálculo.
def cieda_b3_mms(precos, taxa):
return precos.rolling(taxa).mean()
def cieda_b3_std(precos, taxa):
return precos.rolling(taxa).std()
def cieda_b3_show_cnpumms(df,codneg,dataini=-1,datafim=-1,taxa=21):
df_aux_1 = cieda_b3_df_cndp(df,'DMAPRE,PREULT',codneg,dataini,datafim)
df_aux_1.index = np.arange(df_aux_1.shape[0]) # Converter o index para um vetor [0, 1, 2, ...número de linhas]
precos_fechamento = df_aux_1['PREULT'] # Usar apenas preços de fechamento
mms = cieda_b3_mms(precos_fechamento, taxa)
plt.title(codneg + ' MMS')
plt.xlabel('Pregões')
plt.ylabel('Preços fechamento')
plt.plot(precos_fechamento, label='Preços fechamento')
plt.plot(mms, label='MMS {} dias'.format(taxa))
plt.legend()
plt.show()
Teste com VALE3 no ano de 2022.
cieda_b3_show_cnpumms(df_m7m9a22,"VALE3")
NameError: name 'df_m7m9a22' is not defined As bandas de Bollinger mantêm uma relação intensa com a volatilidade, podendo ajudar na antecipação de movimentos fortes, e na identificação de pontos de compra e venda.
Observando o gráfico de um ativo ao longo do tempo, é possível perceber períodos de alta volatilidade, e outros nos quais parece que compradores e vendedores fizeram um trato em favor da tranquilidade e da paz de espirito.
A análise detalhada do gráfico, no entanto, nos mostra mais.
O preço de um ativo dificilmente foge de uma determinada região, sendo constantemente atraído para uma zona de equilíbrio.
Essa zona pode ser identificada com a utilização de médias móveis.
A partir dessas observações, o analista técnico John Bollinger criou as bandas de Bollinger. Elas consistem em duas linhas, uma superior e outra inferior, traçadas a partir de uma determinada distância de uma média móvel.
Esse conceito é, basicamente, o mesmo de envelopes.
Nos envelopes, temos também duas linhas as quais são calculadas a partir de um determinado percentual de distância da média.
A diferença introduzida por Bollinger está na utilização do desvio padrão.
A função cieda_b3_mms_std_bb retorna as listas da média móvel simples, desvio-padrão móvel e as bandas inferior e superior de Bollinger.
def cieda_b3_mms_std_bb(serie, taxa=21):
mms = cieda_b3_mms(serie, taxa)
std = cieda_b3_std(serie, taxa)
bbsup = mms + std * 2 # Calcular banda superior
bbinf = mms - std * 2 # Calcular banda inferior
return mms, std, bbsup, bbinf
A função cieda_b3_serie_mms_std_bb_cndp retorna as listas mms, std, bbsup e bbinf, respectivamente as listas da média móvel simples, do desvio-padrão moveis e das bandas superior e inferior de Bollinger.
def cieda_b3_serie_mms_std_bb_cndp(df,col,codneg,dataini=-1,datafim=-1):
dfaux = cieda_b3_df_cndp(df,"DMAPRE,"+col,codneg,dataini,datafim)
dfaux.index = np.arange(dfaux.shape[0]) # Converter o index para um vetor [0, 1, 2, ...número de linhas]
data_inicial = dfaux["DMAPRE"].iloc[0]
data_final = dfaux["DMAPRE"].iloc[-1]
serie = dfaux[col] # Usar apenas a coluna de "col"
# mms = cieda_b3_mms(serie, 21) # Média Móvel Simples de 21 dias
mms, std, bbsup, bbinf = cieda_b3_mms_std_bb(serie)
return serie, mms, std, bbsup, bbinf, data_inicial, data_final
Função cieda_b3_plot_bb_cn plota a série, a média móvel simples e as bandas superior e inferior de Bollinger.
def cieda_b3_plot_bb_cn(serie, mms, std, bbsup, bbinf, taxa=21):
plt.plot(serie, label="Preços fechamento")
plt.plot(mms, label="MMS {} dias".format(taxa))
plt.plot(bbsup, label="Bollinger Superior", c="g")
plt.plot(bbinf, label="Bollinger Inferior", c="r")
A função cieda_b3_show_bollinger_serie_cn mostra o gráfico com as bandas de Bollinger de uma série.
def cieda_b3_show_bollinger_serie_cn(codneg, data_inicial, data_final, serie, mms, std, bbsup, bbinf, taxa=21):
cieda_b3_plot_bb_cn(serie, mms, std, bbsup, bbinf)
cieda_b3_show_grafico(
"Bandas de Bollinger de CODNEG: {}".format(codneg),
"Pregões de {} a {}".format(data_inicial,data_final),
"Preços fechamento",
True)
Preparação da série e apresentação do Gráfico com as bandas de Bollinger.
def cieda_b3_show_col_cn_bb(df,col,codneg,dataini=-1,datafim=-1):
serie,mms,std,bbsup,bbinf,data_inicial,data_final = cieda_b3_serie_mms_std_bb_cndp(df,col,codneg,dataini,datafim)
cieda_b3_show_bollinger_serie_cn(codneg,data_inicial,data_final,serie,mms,std,bbsup,bbinf)
Se houverem poucos pregões do código de negociação na faixa de data definida o envelope de Bollinger não fica bem definido.
cieda_b3_show_col_cn_bb(df_m1m9a22,"PREULT","VALE3",2208,2209)
NameError: name 'df_m1m9a22' is not defined Com uma faixa com mais de 4 meses de cotações permite boa definição do envelope de Bollinger.
cieda_b3_show_col_cn_bb(df_m1m9a22,"PREULT","VALE3",2204,2209)
NameError: name 'df_m1m9a22' is not defined Quanto mais cotações melhor a definição do envelope de Bollinger.
cieda_b3_show_col_cn_bb(df_m1m9a22,"PREULT","VALE3",2201,2209)
NameError: name 'df_m1m9a22' is not defined Gráfico único: sobreposição das séries dos código de cotação em um único gráfico.
cieda_b3_show_multi_cndp(df_m7m9a22,"PREULT","VALE3,PETR3,PETR4,USIM3",sobrepor=True)
NameError: name 'df_m7m9a22' is not defined Gráficos separados: apresentação de gráficos separados para cada código de negociação.
cieda_b3_show_multi_cndp(df_m7m9a22,"PREULT","VALE3,PETR3,PETR4,USIM3")
NameError: name 'df_m7m9a22' is not defined Histogramas são gráficos de visualização clássica, geralmente com barras, que representamm a distribuição de uma ou mais variáveis contando o número de observações (frequências) que se enquadram em compartimentos discretos, denominados classes de frequências.
No histograma a base de cada uma das barras representa uma classe e a altura representa a quantidade ou frequência absoluta com que o valor de cada classe ocorre.
Ao mesmo tempo, pode ser utilizado como um indicador de dispersão de processos.
Os tipos de histogramas são: simétrico, distorcido à direita, distorcido à esquerda, bimodal, multimodal e achatado (platô)).
A função cieda_b3_hist_col_codneg() plota o histograma do dataframe, da coluna em col e a série do código de negociação em codneg.
def cieda_b3_hist_col_codneg(df, col, codneg, bins=10, palette='pastel'):
dfaux = df[df["CODNEG"] == codneg]
# x = dfaux[col]
# plt.hist(y,label=codneg)
cm = sns.color_palette("plasma",bins) #Splitting the palette in the same amount of numbers bins
plot = sns.histplot(data=dfaux, x=col, bins=bins)
for bin_,i in zip(plot.patches,cm):
bin_.set_facecolor(i)
A função cieda_b3_show_hist_multi_cndp() plota o histograma e mostra o gráfico das séries do dataframe de df dos códigos de negociações de codnegs, usando s coluna de col e a faixa de datas de dataini a datafim.
def cieda_b3_show_hist_multi_cndp(df, col, codnegs, dataini=-1, datafim=-1, sobrepor=False):
dfaux = cieda_b3_df_cndp(df,"CODNEG,DMAPRE,"+col,codnegs,dataini,datafim)
data_inicial = dfaux["DMAPRE"].iloc[0]
data_final = dfaux["DMAPRE"].iloc[-1]
xlabel = "{} de {} a {}".format(col,data_inicial,data_final)
codnegs_unicos = dfaux["CODNEG"].unique()
for codneg in codnegs_unicos:
cieda_b3_hist_col_codneg(df,col,codneg)
cieda_b3_show_grafico("CODNEG: "+codneg, xlabel, "Frequência")
Podem ser apresentados, em gráficos separados, os histogramas de múltiplos códigos de negociação, em lista, separados por vírgula, em faixas de datas determinadas.
Histogramas de último preço total dos meses 4 a 6 de 2022.
codnegs = "VALE3,PETR3,PETR4,USIM3"
#
cieda_b3_show_hist_multi_cndp(df_m7m9a22,"PREULT",codnegs)
NameError: name 'df_m7m9a22' is not defined Histogramas de último preço total dos meses 1 a 9 de 2022.
cieda_b3_show_hist_multi_cndp(df_m1m9a22,"PREULT",codnegs)
NameError: name 'df_m1m9a22' is not defined Histogramas de volume total dos meses 4 a 6 de 2022.
cieda_b3_show_hist_multi_cndp(df_m7m9a22,"VOLTOT",codnegs)
NameError: name 'df_m7m9a22' is not defined Histogramas de volume total dos meses 1 a 9 de 2022.
cieda_b3_show_hist_multi_cndp(df_m1m9a22,"VOLTOT",codnegs)
NameError: name 'df_m1m9a22' is not defined O Python permite o acesso com facilidade, nos arquivos-zip baixados do site da B3, aos dados da Bovespa.
A Análise Técnica Básica (ATB) proporciona boa visão inicial das informações obtidas a partir dos dados das cotações nos arquivos.
As possibilidades de visualização de informações dos dados são muitas, e serão apresentadas continuamente nos capítulos seguintes, de acordo com o seguinte planejamento:
CONTATO:
Para receber a versão PDF, tirar dúvidas ou fazer contato conosco envie email para atendimento@cieda.com.br.