Importando Bibliotecas¶

In [ ]:
import pandas as pd
import yfinance as yf
from statsmodels import api as sm
import seaborn as sns
import matplotlib.pyplot as plt
from mplfinance.original_flavor import candlestick_ohlc
import matplotlib.dates as mdates
import numpy as np
from scipy.optimize import minimize
import plotly.graph_objects as go
from plotly.subplots import make_subplots

Selecionando Tickers:¶

In [ ]:
tickers = ['VALE', 'RIG', 'RIO', 'BBD', 'DVN', 'PBR-A', 'EC', 'BP', 'EQNR', 'E', 'SHEL', 'CTRA', 'TTE', 'CTRA', 'PXD', 'OXY', 'MRO', 'XOM', 'ITUB', 'EGIE3.SA']

Motivo da escolha dos Tickers:¶

Selecionamos as seguintes ações para análise:

  • VALE: Vale S.A.
  • RIG: Transocean Ltd.
  • RIO: Rio Tinto Group
  • BBD: Banco Bradesco S.A.
  • DVN: Devon Energy Corporation
  • PBR-A: Petróleo Brasileiro S.A. - Petrobras
  • EC: Ecopetrol S.A.
  • BP: BP p.l.c.
  • EQNR: Equinor ASA
  • E: Eni S.p.A.
  • SHEL: Royal Dutch Shell plc
  • CTRA: Contura Energy, Inc.
  • TTE: Total S.A.
  • CTRA: Contura Energy, Inc.
  • PXD: Pioneer Natural Resources Company
  • OXY: Occidental Petroleum Corporation
  • MRO: Marathon Oil Corporation
  • XOM: Exxon Mobil Corporation
  • ITUB: Itaú Unibanco Holding S.A.
  • EGIE3.SA: Engie Brasil Energia S.A.

A escolha, foi feita com base no setor de energia, que é um dos setores mais importantes da economia mundial, e que tem grande influência no mercado financeiro. Além disso, a escolha de ações de empresas de diferentes países, como Brasil, Estados Unidos, Noruega, Itália, Reino Unido e Colômbia, o que permite uma análise mais ampla do mercado.

Tecnical Analysis (Análise Técnica)¶

Para a análise técnica, vamos utilizar a biblioteca "mplfinance" para plotar os gráficos de candlestick, além disso vamor criar uma função para computar o RSI (Relative Strength Index) e o MACD (Moving Average Convergence Divergence).

In [ ]:
def compute_RSI(data, time_window):
    diff = data.diff(1).dropna()   
    # this preservers dimensions off diff values
    up_chg = 0 * diff
    down_chg = 0 * diff
    # up change is equal to the positive difference, otherwise equal to zero
    up_chg[diff > 0] = diff[ diff>0 ]
    
    # down change is equal to negative deifference, otherwise equal to zero
    down_chg[diff < 0] = diff[ diff < 0 ]
    up_chg_avg   = up_chg.ewm(com=time_window-1 , min_periods=time_window).mean()
    down_chg_avg = down_chg.ewm(com=time_window-1 , min_periods=time_window).mean()
    
    rs = abs(up_chg_avg/down_chg_avg)
    rsi = 100 - 100/(1+rs)
    return rsi


def compute_macd(dados):
    # janela curta, longa e sinal
    short_window = 12
    long_window = 26
    signal_window = 9
    
    # ewm do pandas para o cálculo da média móvel exponencialmente ponderada
    short_media = dados.ewm(span=short_window, adjust=False).mean()
    long_media = dados.ewm(span=long_window, adjust=False).mean()
    
    macd = short_media - long_media
    signal = macd.ewm(span=signal_window, adjust=False).mean()
    
    return macd, signal

Plotando Candlestick + RSI + MACD¶

Nos gráficos abaixo, podemos ver o comportamento dos indicadores RSI e MACD para cada ativo. A linha azul representa o RSI, a linha amarela representa o MACD e a linha magenta representa o sinal do MACD. As linhas tracejadas vermelhas e verdes representam o candlestick do ativo, sendo vermelho para queda e verde para alta.

RSI (Índice de Força Relativa):

  • É um oscilador que mede a velocidade e mudança dos movimentos de preço. É frequentemente usado para identificar condições de sobrecompra ou sobrevenda no mercado.

MACD (Convergência/Divergência de Médias Móveis):

  • É uma ferramenta de análise técnica que utiliza a diferença entre médias móveis exponenciais curtas e longas para prever a direção futura do preço.

Candlestick:

  • Apresentam a variação de preço de uma ação durante um determinado período. Cada "candle" representa o preço de abertura, fechamento, máximo e mínimo durante esse período.
In [ ]:
fig, axes = plt.subplots(nrows=10, ncols=2, figsize=(16, 28))
axes = axes.flatten()

for i, ax1 in enumerate(axes):
    # Coletando dados de cada ativo
    df = yf.download(tickers[i], start='2023-01-01', end='2023-10-01', progress=False)
    df['Date'] = df.index.map(mdates.date2num)
    df['RSI'] = compute_RSI(df['Close'], 14)
    df['MACD'], df['Signal'] = compute_macd(df['Close'])
    
    ax2 = ax1.twinx()
    ax3 = ax1.twinx()
    
    # Definindo data como eixo x
    ax1.xaxis_date()
    ax1.xaxis.set_major_formatter(mdates.DateFormatter('%Y-%m-%d'))
    ax1.set_ylabel('Price', color='k')
    plt.setp(ax1.get_xticklabels(), rotation=45, ha='right', visible=True)  

    # Plotting Candlestick
    candlestick_ohlc(ax1,zip(df['Date'],
                        df['Open'],
                        df['High'],
                        df['Low'],
                        df['Close']),
                        width=0.4, colorup='g', colordown='r')
    
    # Plotting RSI
    ax2.plot(df.index, df['RSI'], label='RSI', color='b', linewidth=1.2)
    ax2.axhline(y=70, color='r', linestyle='--')
    ax2.axhline(y=30, color='r', linestyle='--')
    ax2.set_ylim([0, 100])
    ax2.set_yticks([30, 70])
    ax2.legend(loc='upper left')
    ax1.set_title(tickers[i])

    # Plotting MACD
    ax3.plot(df.index, df['MACD'], label='MACD', color='y', linewidth=0.8)
    ax3.plot(df.index, df['Signal'], label='Signal', color='m', linewidth=0.8)
    ax3.legend(loc='upper right')


plt.tight_layout()
plt.show()

Escolhemos os mêses de 2023, pois é um período recente que permite uma análise mais ampla.

Iremos prestar dar mais prioridade para um RSI abaixo de 30 e acima de 70, pois são os valores que indicam uma possível reversão de tendência. Além disso, iremos prestar atenção na linha do MACD cruzando a linha de sinal, acimas de 0. E observar como os sticks do candlestick estão consecutivamente vermelhos ou verdes.

Daí, podemos ter maior confiabilidade nas ações:

  • VALE
  • BBD
  • EC
  • EQNR
  • EC
  • CTRA
  • ITUB
  • EGIE3.SA

Fundamentalist Analysis (Análise Fundamentalista)¶

Para nossa análise fundamentalista, vamos utilizar a biblioteca "yfinance" para obter os dados financeiros da empresa, além disso vamos criar uma função para retornar os indicadores desejados. São eles:

  • P/L (Preço da ação dividido pelo Lucro por ação)
  • P/B (Preço da ação dividido pelo Valor Patrimonial por ação)
  • Dividend Yield (Dividendos por ação dividido pelo Preço da ação)
  • Cap de Mercado (Preço da ação multiplicado pelo número de ações em circulação)
  • Volume Médio (Volume médio diário negociado)
  • ROA (Retorno sobre o Ativo)
  • ROE (Retorno sobre o Patrimônio Líquido)
  • Margem de Lucro (Lucro Líquido dividido pela Receita Líquida)
  • Relação Dívida-Patrimônio (Dívida Total dividida pelo Patrimônio Líquido)
  • Receita Total
  • EBIDTA (Lucros antes de juros, impostos, depreciação e amortização)

Iremos avaliar os indicadores da seguinte forma:

1 - Liquidez

  • Liquidez Corrente: É o quanto a empresa possui de ativo circulante para cada unidade de passivo circulante. Uma liquidez corrente maior do que 1 é geralmente desejável.

    2 - Volume e Receita

  • Volume Médio: Se refere ao volume médio de negociação de ações em um mercado de ações, o que pode ser relevante para investidores que desejam avaliar a liquidez e o interesse do mercado por uma ação específica.

  • Receita Total: É o quanto a empresa faturou no período.

    2 - Resultados

  • Margem de Lucro (ou Margem Líquida): É o lucro líquido dividido pela receita líquida. É o quanto a empresa ganha de cada real que vende.

  • ROE: Acima de 10%. Acima da taxa básica de juros do país.

  • ROA: Acima de 5%. É o lucro líquido dividido pelo ativo total. É o quanto a empresa ganha de cada real investido.

    3 - Endividamento

  • Dívida Líquida / EBITDA: Mede a capacidade de pagamento da dívida. Quanto menor, melhor. Abaixo de 3.

  • Dívida Líquida / Patrimônio Líquido: Quanto menor, melhor. Abaixo de 1.

    4 - Dividendos

  • Dividend Yield: Relaciona quanto foi pago de dividendo por ação pela cotação da ação no mercado naquele momento, ou seja, quanto o acionista recebeu de dividendo por cada ação que ele possui. Quanto maior, melhor.

    5 - Cotação

  • Preço / Lucro (P/L): Indica quantos anos são necessários para recuperar o investimento.

  • Preço / Valor Patrimonial (P/B): Indica quanto o mercado está disposto a pagar sobre as ações da empresa. Quanto menor, melhor.

  • In [ ]:
    # Função para formatar valores
    def formatar_valor(valor, tipo='moeda'):
        if valor is None:
            return None
        if tipo == 'moeda':
            # O :,.2f indica que o valor deve ser formatado como float com 2 casas decimais e separador de milhar
            return f"R$ {valor:,.2f}"
        elif tipo == 'porcentagem':
            # O :.2f indica que o valor deve ser formatado como float com 2 casas decimais
            return f"{valor * 100:.2f}%"
    
    # Função para extrair indicadores
    def obter_indicadores(ticker):
        # yf.Ticker(ticker) cria um objeto com informações do ticker
        estoque = yf.Ticker(ticker)
        # .info extrai as informações do objeto
        informacoes = estoque.info
    
        # Criando um dicionário com os indicadores desejados
        indicadores = {
            'Setor': informacoes.get('sector', None),
            'Liquidez Corrente': informacoes.get('currentRatio', None),
            'Margem de Lucro': informacoes.get('profitMargins', None),
            'Receita Total': informacoes.get('totalRevenue', None),
            'EBITDA': informacoes.get('ebitda', 1),
            'Relação Dívida-Patrimônio': informacoes.get('debtToEquity', None),
            'P/L (Relação Preço-Lucro)': informacoes.get('trailingPE', None),
            'P/B (Relação Preço-Valor Contábil)': informacoes.get('priceToBook', None),
            'Dividend Yield (Rendimento de Dividendo)': informacoes.get('dividendYield', None),
            'Cap. de Mercado': informacoes.get('marketCap', None),
            'Volume Médio': informacoes.get('averageVolume', None),
            'ROA (Retorno sobre Ativos)': informacoes.get('returnOnAssets', None),
            'ROE (Retorno sobre o Patrimônio Líquido)': informacoes.get('returnOnEquity', None),
        
        }
    
        divida_total = informacoes.get('totalDebt', 0)  # Assume 0 se não disponível
        caixa_e_equivalentes = informacoes.get('cash', 0)  # Assume 0 se não disponível
        divida_liquida = divida_total - caixa_e_equivalentes
        indicadores['Dívida Líquida / EBITDA'] = formatar_valor(divida_liquida / indicadores["EBITDA"])
    
        # Aplicando a formatação
        for chave in indicadores:
            if "Yield" in chave or "ROA" in chave or "ROE" in chave or "Margem" in chave or "Relação" in chave:
                indicadores[chave] = formatar_valor(indicadores[chave], 'porcentagem')
            elif "Liquidez Corrente" in chave or "Cap. de Mercado" in chave or "Receita Total" in chave:
                indicadores[chave] = formatar_valor(indicadores[chave], 'moeda')
    
        return indicadores
    

    Criando um dataframe com os indicadores de todos os ativos¶

    In [ ]:
    data = {}
    # Coletando indicadores para cada ticker
    for ticker in tickers:
        data[ticker] = obter_indicadores(ticker)
    # Transformando o dicionário em um DataFrame
    df = pd.DataFrame(data)
    df
    
    Out[ ]:
    VALE RIG RIO BBD DVN PBR-A EC BP EQNR E SHEL CTRA TTE PXD OXY MRO XOM ITUB EGIE3.SA
    Setor Basic Materials Energy Basic Materials Financial Services Energy Energy Energy Energy Energy Energy Energy Energy Energy Energy Energy Energy Energy Financial Services Utilities
    Liquidez Corrente R$ 1.15 R$ 1.96 R$ 1.99 None R$ 0.98 R$ 0.90 R$ 1.21 R$ 1.17 R$ 1.83 R$ 1.44 R$ 1.46 R$ 1.74 R$ 1.17 R$ 0.73 R$ 1.04 R$ 0.80 R$ 1.48 None R$ 1.28
    Margem de Lucro 27.58% -37.68% 16.39% 20.72% 29.83% 26.89% 15.54% 8.19% 18.70% 7.87% 8.09% 40.53% 8.18% 28.39% 21.55% 30.56% 14.06% 26.66% 28.48%
    Receita Total R$ 206,414,004,224.00 R$ 2,675,000,064.00 R$ 52,445,999,104.00 R$ 72,893,186,048.00 R$ 16,023,000,064.00 R$ 581,562,990,592.00 None R$ 227,586,998,272.00 R$ 128,649,003,008.00 R$ 116,525,998,080.00 R$ 358,589,005,824.00 R$ 7,683,999,744.00 R$ 238,681,997,312.00 R$ 20,387,000,320.00 R$ 31,536,001,024.00 R$ 6,695,000,064.00 R$ 367,977,005,056.00 R$ 118,938,001,408.00 R$ 11,371,320,320.00
    EBITDA 85363998720 866000000 18742999040 1 8830999552 291086991360 1 51136000000 66170998784 18786000896 68989001728 5608999936 52544000000 10110999552 16304000000 4560999936 79138996224 1 6102162944
    Relação Dívida-Patrimônio 4087.60% 7157.10% 2638.40% None 6041.30% 7504.40% 10647.10% 7090.70% 6152.20% 6026.30% 4391.90% 2021.80% 4844.20% 2595.00% 7032.80% 5333.50% 2004.70% None 20550.90%
    P/L (Relação Preço-Lucro) 544.03% None 1189.75% 1033.33% 623.63% 290.09% 301.89% 633.50% 420.60% 561.18% 770.80% 662.97% 840.31% 953.93% 1052.36% 792.26% 925.04% 828.13% 1033.50%
    P/B (Relação Preço-Valor Contábil) 30.71% 58.06% 196.87% 17.84% 265.52% 23.68% 126.98% 628.13% 394.76% 103.67% 112.03% 156.98% 138.12% 237.87% 268.99% 137.92% 232.55% 29.04% 401.31%
    Dividend Yield (Rendimento de Dividendo) 5.49% None 6.32% 6.69% 7.23% 42.46% 28.59% 4.11% 3.66% 6.09% 3.59% 2.96% 4.71% 7.17% 1.11% 1.50% 3.10% 5.49% 2.86%
    Cap. de Mercado R$ 56,965,111,808.00 R$ 6,134,776,832.00 R$ 101,718,212,608.00 R$ 29,646,260,224.00 R$ 29,247,956,992.00 R$ 90,839,924,736.00 R$ 23,025,295,360.00 R$ 109,814,530,048.00 R$ 95,585,411,072.00 R$ 52,119,687,168.00 R$ 211,145,310,208.00 R$ 19,872,811,008.00 R$ 157,538,402,304.00 R$ 52,330,827,776.00 R$ 55,115,685,888.00 R$ 15,499,530,240.00 R$ 460,958,990,336.00 R$ 51,942,543,360.00 R$ 33,477,525,504.00
    Volume Médio 21022598 14843403 2866726 19636626 8316106 7682339 1862403 7493620 2393706 247633 4541599 5728219 1177552 1697265 8935066 10972133 15663249 17697888 1363535
    ROA (Retorno sobre Ativos) 9.98% 0.11% 8.97% 0.85% 17.02% 15.43% 11.99% 8.39% 24.58% 4.71% 7.88% 12.29% 8.13% 12.78% 7.83% 8.26% 10.51% 1.42% 8.12%
    ROE (Retorno sobre o Patrimônio Líquido) 29.59% -9.34% 15.53% 9.48% 44.96% 39.99% 29.13% 23.39% 52.91% 17.25% 15.14% 25.04% 16.89% 25.29% 23.74% 17.97% 27.20% 18.30% 37.62%
    Dívida Líquida / EBITDA R$ 0.93 R$ 8.60 R$ 0.75 R$ 622,578,565,120.00 R$ 0.76 R$ 0.96 R$ 0.00 R$ 1.19 R$ 0.46 R$ 1.78 R$ 1.22 R$ 0.46 R$ 1.07 R$ 0.56 R$ 1.27 R$ 1.31 R$ 0.52 R$ 827,033,976,832.00 R$ 3.13

    Observando os indicadores, notamos uma grande variação entre as empresas. Para avaliar as ações, é crucial considerar o setor em que operam, pois diferentes setores têm normas diferentes. Por exemplo, ações no setor de energia tendem a ter níveis mais elevados de dívida, dada a natureza capital-intensiva do setor.

    Empresas como VALE exibe alto valorvde Relação Dívida-Patrimônio, o que pode indicar alavancagem elevada, mas isso precisa ser analisado no contexto do setor e dos retornos gerados. O Dividend Yield de VALE também é atraente, sugerindo bons retornos para investidores.

    A ação EQNR apresenta um Dividend Yield de 3,66%, o que é atraente para investidores que buscam rendimento. Além disso, o seu ROA (Retorno sobre Ativos) de 8,39% e ROE (Retorno sobre o Patrimônio Líquido) de 52,91% são significativamente altos, indicando eficiência na geração de lucro tanto em relação aos ativos quanto ao patrimônio. Isso sugere que a empresa tem sido rentável e tem gerenciado seus recursos de maneira eficaz. Além disso, sua relação Dívida Líquida / EBITDA é de 0,462363, o que é relativamente baixo, indicando menor risco em termos de alavancagem operacional.

    A ação XOM tem um Dividend Yield sólido de 7,17%, tornando-a uma das mais altas da lista, o que é atraente para aqueles que buscam renda. Além disso, seu P/B (Relação Preço-Valor Contábil) é de 0,925, o que pode sugerir que a ação está ligeiramente subvalorizada. Embora sua relação Dívida-Patrimônio seja alta, é importante considerar que empresas do setor de energia muitas vezes operam com níveis mais elevados de dívida devido à natureza capital-intensiva do setor. Além disso, o ROA de 10,51% e o ROE de 27,20% são impressionantes, indicando uma boa rentabilidade.

    Por outro lado, ações como PBR-A e DVN mostram alguns valores ausentes, o que requer investigação adicional. A ausência de certos dados pode ser devido a questões contábeis, reportagens financeiras ou outras razões.

    Evaluating Correlation between Stocks (Correlação)¶

    Para nossa última métrica, iremos avaliar a correlação entre os ativos que estamos priorizando. Para montar nosso portfólio, é interessante que os ativos não sejam fortemente correlacionados, pois assim, conseguimos diversificar nosso portfólio e reduzir o risco.

    In [ ]:
    # iniciar os retornos
    all_stock_returns = pd.DataFrame()
    
    tickers = ["VALE", "EQNR", "BBD", "EC", "CTRA", "ITUB", "RIG", "XOM"]
    for stock in tickers:
        data = yf.Ticker(stock)
        start_date = "2023-01-01" ### melhorar o intervalo
        end_date = "2023-10-01"  
        data = data.history(start=start_date, end=end_date)
    
        data['returns'] = data['Close'].pct_change()
        
        # adicionar os retornos ao data frame
        all_stock_returns[stock] = data['returns']
    
    # tirar os NAs em cima dos retornos, a primeira linha, por exemplo. 
    all_stock_returns = all_stock_returns.dropna()
    
    In [ ]:
    plt.figure(figsize=(7,7))
    correlation = all_stock_returns.corr()
    sm.graphics.plot_corr(correlation,xnames=list(correlation.columns))
    None
    
    <Figure size 700x700 with 0 Axes>

    Conclusões Finais¶

    Com base em nossa análise, podemos concluir que as ações que indico para montagem de um portfólio de risco baixo são:

    • VALE
    • BBD
    • EQNR
    • RIG
    • CTRA

    Em todas as métricas, essas ações se destacaram, mesmo sem crescimento significativo, apresentaram estabilidade e bons indicadores. Além disso, a correlação entre elas é baixa, o que permite uma diversificação do portfólio.