Comparação Retorno BRA X EUA

Autor

Gilearde J Fagundes

Data de Publicação

9 de junho de 2025

Introdução

Nesta análise, vamos comparar o desempenho de diferentes ativos no Brasil e nos Estados Unidos ao longo do tempo. Utilizaremos dados históricos para entender como esses investimentos se comportaram, do ponto de vista de um investidor brasileiro.

Primeiro, preparamos nosso ambiente importando as bibliotecas e definindo os ativos que serão analisados.

import pandas as pd 
import yfinance as yf
from bcb import sgs, currency
import datetime 
import numpy as np
import plotly.express as px
import time


nomes_ativos = {
    '^BVSP': 'Ibovespa',
    '^GSPC': 'S&P 500',
    'GLD': 'Ouro',
    'SPHD': 'ETF Dividendos EUA',
    'QQQ': 'ETF Nasdaq',
    'CDI': 'CDI'
}
tickers = ['^BVSP', '^GSPC', 'GLD', 'SPHD', 'QQQ']
start_date = '2015-06-30'
end_date = datetime.datetime.now()

Coleta e Tratamento dos Dados

O próximo passo é buscar todos os dados necessários: a cotação do dólar para converter os ativos internacionais, a taxa CDI como nosso benchmark de renda fixa, e os preços dos ativos de renda variável. Consolidamos tudo em um único DataFrame de retornos diários.

#   1. Buscar Cotação do Dólar ---
try:
    cotacoes_do_dolar = currency.get({'USD': 1}, start=start_date, end=end_date)
    cotacoes_do_dolar.index = cotacoes_do_dolar.index.tz_localize(None)
except Exception as e:
    print(f"ERRO: Falha ao buscar cotações do dólar. {e}")
    cotacoes_do_dolar = pd.DataFrame()

#   2. Buscar Dados do CDI ---
try:
    rendimento_cdi = sgs.get({'CDI': 12}, start=start_date, end=end_date)
    rendimento_cdi = rendimento_cdi / 100
    rendimento_cdi.index = rendimento_cdi.index.tz_localize(None)
    rendimento_cdi = rendimento_cdi.rename(columns=nomes_ativos)
except Exception as e:
    print(f"ERRO: Falha ao buscar dados do CDI. {e}")
    rendimento_cdi = pd.DataFrame()

#   3. Buscar Dados dos Ativos (yfinance) 
dados_individuais = {}
print("Iniciando download dos ativos...")
for ticker in tickers:
    try:
        print(f"Baixando dados para {ticker}...")
        dados = yf.download(ticker, start=start_date, end=end_date, progress=False, multi_level_index=False)['Close']
        if not dados.empty:
            dados_individuais[ticker] = dados
        time.sleep(1)
    except Exception as e:
        print(f"AVISO: Falha ao baixar {ticker}. {e}")
print("Download concluído.")


# --- 4. Consolidar e Limpar os Dados (LÓGICA CORRIGIDA) ---

if not dados_individuais or cotacoes_do_dolar.empty or rendimento_cdi.empty:
    raise ValueError("ERRO: Falha na coleta de um ou mais dados essenciais. A análise não pode continuar.")
else:
   
    precos_ativos = pd.concat(dados_individuais, axis=1)
    precos_ativos.index = pd.to_datetime(precos_ativos.index)

    
    precos_ativos = precos_ativos.ffill()

    
    dados_para_converter = precos_ativos.join(cotacoes_do_dolar)
    
    dados_para_converter['USD'] = dados_para_converter['USD'].ffill()

    
    precos_brl = pd.DataFrame(index=dados_para_converter.index)

    
    ativos_em_usd = ['^GSPC', 'GLD', 'SPHD', 'QQQ']
    for ticker in tickers:
        if ticker in ativos_em_usd:
            precos_brl[ticker] = dados_para_converter[ticker] * dados_para_converter['USD']
        elif ticker == '^BVSP':
            precos_brl[ticker] = dados_para_converter[ticker]

    # Renomeia as colunas para os nomes amigáveis
    precos_brl = precos_brl.rename(columns=nomes_ativos)

    # Calcula os retornos diários de todos os ativos (já em REAL)
    retornos_variaveis_brl = precos_brl.pct_change()

    
    dados_completos = retornos_variaveis_brl.join(rendimento_cdi, how='inner')

    
    dados_completos = dados_completos.dropna()
Iniciando download dos ativos...
Baixando dados para ^BVSP...
Baixando dados para ^GSPC...
Baixando dados para GLD...
Baixando dados para SPHD...
Baixando dados para QQQ...
Download concluído.

Análise de Desempenho

Com os dados tratados, calculamos o retorno acumulado de cada ativo. Isso nos permite visualizar o crescimento de um investimento inicial ao longo do tempo.

import matplotlib.pyplot as plt
import matplotlib.ticker as mticker


retorno_acumulado = (1 + dados_completos).cumprod()


retorno_acumulado_normalizado = (retorno_acumulado / retorno_acumulado.iloc[0]) * 100

plt.style.use('seaborn-v0_8-whitegrid')
fig, ax = plt.subplots(figsize=(14, 8))

for ativo in retorno_acumulado_normalizado.columns:
    ax.plot(
        retorno_acumulado_normalizado.index,
        retorno_acumulado_normalizado[ativo],
        label=ativo
    )

ax.set_title('Retorno Acumulado Comparativo (Base 100)', fontsize=18, pad=20)
ax.set_xlabel('Data', fontsize=12)
ax.set_ylabel('Performance (Base 100)', fontsize=12)

ax.legend(
    title='Ativos',
    loc='upper left',
    bbox_to_anchor=(1, 1)
)

ax.yaxis.set_major_formatter(mticker.FuncFormatter(lambda y, _: f'{int(y)}'))
ax.tick_params(axis='x', rotation=45)

plt.tight_layout(rect=[0, 0, 0.85, 1])

print("\nGerando o gráfico de retorno acumulado com Matplotlib...")
plt.show()

Gerando o gráfico de retorno acumulado com Matplotlib...
Figura 1: Desempenho comparativo dos ativos, com retornos normalizados em uma base 100.

O drawdown é uma métrica de risco que mede a maior queda percentual de um ativo a partir de um pico anterior. É essencial para entender a volatilidade e o risco de perda em cada investimento.

# Cálculo do Drawdown
max_acumulado = retorno_acumulado.cummax()
drawdown = (retorno_acumulado - max_acumulado) / max_acumulado

plt.style.use('seaborn-v0_8-whitegrid')
fig, ax = plt.subplots(figsize=(14, 8))


for ativo in drawdown.columns:
    ax.plot(
        drawdown.index, 
        drawdown[ativo],    
        label=ativo         
    )


ax.set_title('Drawdown dos Ativos', fontsize=18, pad=20)
ax.set_xlabel('Data', fontsize=12)
ax.set_ylabel('Drawdown', fontsize=12)
ax.legend(
    title='Ativos',
    loc='upper left',
    bbox_to_anchor=(1, 1) 
)


ax.yaxis.set_major_formatter(mticker.PercentFormatter(xmax=1.0))


ax.axhline(0, color='grey', linestyle='--', linewidth=1)


plt.tight_layout(rect=[0, 0, 0.85, 1])



plt.show()

Métricas de Risco e Retorno

Finalmente, consolidamos as principais métricas de desempenho em uma tabela: * Retorno Anualizado: O retorno médio que o investimento gerou por ano. * Volatilidade Anualizada: Uma medida de risco, indicando o quanto o preço do ativo tende a variar. * Índice Sharpe: A métrica mais importante, que mede o retorno ajustado ao risco. Ela nos diz quanto retorno extra um investidor recebeu por unidade de risco assumido, acima da taxa livre de risco (CDI).

if dados_completos is not None:
    dias_no_periodo = len(dados_completos)
    
    # Retorno Anualizado
    retorno_final = retorno_acumulado.iloc[-1]
    retorno_ao_ano = (retorno_final ** (252 / dias_no_periodo)) - 1
    
    # Volatilidade Anualizada
    vol_historica = dados_completos.std() * np.sqrt(252)
    
    # Índice Sharpe 
    retorno_cdi_ano = retorno_ao_ano.get('CDI', 0)
    retorno_excedente = retorno_ao_ano - retorno_cdi_ano
    sharpe = retorno_excedente / vol_historica
    
    
    tabela_final = pd.DataFrame({
        'Retorno Anualizado': retorno_ao_ano * 100,
        'Volatilidade Anualizada': vol_historica * 100,
        'Índice Sharpe': sharpe
    })
    
   
    tabela_final['Retorno Anualizado'] = tabela_final['Retorno Anualizado'].map('{:.2f}%'.format)
    tabela_final['Volatilidade Anualizada'] = tabela_final['Volatilidade Anualizada'].map('{:.2f}%'.format)
    tabela_final['Índice Sharpe'] = tabela_final['Índice Sharpe'].map('{:.2f}'.format)
    
    display(tabela_final)
else:
    print("Não foi possível gerar a tabela de métricas pois os dados não foram carregados.")
Retorno Anualizado Volatilidade Anualizada Índice Sharpe
Ibovespa 9.99% 23.72% 0.03
S&P 500 21.82% 21.25% 0.59
Ouro 16.88% 19.44% 0.39
ETF Dividendos EUA 17.87% 20.33% 0.42
ETF Nasdaq 29.07% 25.12% 0.79
CDI 9.30% 0.24% 0.00

Conclusão

Ao final de qualquer jornada de investimento, a pergunta que ecoa não é simplesmente “quanto ganhei?”, mas sim “o que precisei enfrentar para chegar até aqui?”. Uma análise financeira madura, portanto, assemelha-se a uma crítica de viagem: não basta descrever o destino, é preciso narrar a travessia. E para avaliar a qualidade dessa travessia no mercado financeiro, onde a incerteza é o oceano e a volatilidade é a tempestade, precisamos de uma bússola mais sofisticada que o mero retorno. Essa bússola é o Índice de Sharpe.

Ele opera sob uma premissa de profunda justiça e racionalidade. Antes de julgar um ativo, o índice primeiro desconta de seu rendimento total aquilo que teria sido obtido sem esforço ou susto, o ganho de um porto seguro, que em nossa análise é a taxa CDI. Esse valor que sobra, o “retorno excedente”, é o verdadeiro prêmio pela coragem, o troféu conquistado por quem se aventurou em águas mais profundas. Mas a sabedoria do índice não para aí. Ele então pega esse prêmio e o coloca em uma balança, pesando-o contra a intensidade da tempestade enfrentada, a volatilidade do ativo. O resultado final, o número que chamamos de Índice de Sharpe, nos conta, com elegância matemática, o quão bem a recompensa compensou o risco.

Quando aplicamos essa régua aos dados de nossa análise, a história que eles contam é cristalina. Vemos o Ibovespa, por exemplo, como um capitão que prometeu tesouros distantes, mas que, após uma viagem de grande turbulência, com o barco sacudindo em mais de 23% de volatilidade, entregou aos seus tripulantes moedas de valor quase idêntico às que poderiam ter sido coletadas na segurança do cais do CDI. O seu Índice de Sharpe, próximo de zero, é o diário de bordo que confirma essa jornada ineficiente: um risco de oceano para uma recompensa de lagoa.

Em contrapartida, os ativos internacionais, dolarizados, navegaram com um vento de popa constante. Sua performance superior não se deveu a um único fator, mas a um poderoso duplo motor. O primeiro, o motor do crescimento intrínseco, impulsionado pela inovação das empresas de tecnologia do Nasdaq e pela força da economia americana. O segundo, e talvez mais crucial para o investidor brasileiro, foi o motor cambial: a valorização estrutural do dólar frente a um real que, historicamente, perde seu poder de compra. Cada ganho obtido no exterior era amplificado ao ser convertido de volta para nossa moeda, como se a própria maré estivesse a nosso favor.

O Índice de Sharpe desses ativos, correspondentemente mais alto, valida essa travessia. Ele nos mostra que, embora a viagem também tenha tido suas ondas, a recompensa final foi mais do que proporcional ao risco, o tesouro encontrado fez jus à ousadia da expedição. A conclusão que emerge dessa cadência de fatos e números, portanto, é menos sobre uma escolha de ativos e mais sobre uma filosofia de alocação. Para o investidor baseado no Brasil, a diversificação internacional transcende a busca por maiores lucros; ela se revela uma estratégia fundamental de engenharia de portfólio, um ato consciente de se proteger das incertezas locais e, ao mesmo tempo, de se posicionar para capturar o crescimento global, com o vento da moeda a seu favor.