4. Geração da Tabela em HTML : A tabela final é gerada, mostrando as 4 melhores ações, seus retornos, o retorno total, o retorno acumulado das ações e o comparativo com o Ibovespa.
Abaixo, o código. Porém, está dando erro e nao consigo corrigir. Agradeço a ajuda!
import pandas as pd
import yfinance as yf
import datetime as dt
from IPython.core.display import display, HTML
# Lista de tickers
all_tickers = [
"^BVSP", '
ALUP11.SA', '
AMBP3.SA', '
ANIM3.SA', '
ARML3.SA',
'
ASAI3.SA', '
AURA33.SA', '
AURE3.SA', '
AZZA3.SA', '
BAZA3.SA',
'
BBAS3.SA', '
BBDC4.SA', '
BBSE3.SA', '
BEEF3.SA', '
BIOM3.SA',
'
BLAU3.SA', '
BMEB4.SA', '
BMGB4.SA', '
BMOB3.SA', '
BPAC11.SA',
'
BPAN4.SA', '
BRAV3.SA', '
BRBI11.SA', '
BRFS3.SA', '
BRIT3.SA',
'
BRKM5.SA', '
CAMB3.SA', '
CAML3.SA', '
CBAV3.SA', '
CCRO3.SA',
'
CEAB3.SA', '
CMIG4.SA', '
CMIN3.SA', '
COCE5.SA', '
COGN3.SA',
'
CPFE3.SA', '
CPLE6.SA', '
CRFB3.SA', '
CSAN3.SA', '
CSED3.SA',
'
CSMG3.SA', '
CSNA3.SA', '
CSUD3.SA', '
CURY3.SA', '
CVCB3.SA',
'
CXSE3.SA', '
CYRE3.SA', '
DESK3.SA', '
DEXP3.SA', '
DIRR3.SA',
'
DMVF3.SA', '
DXCO3.SA', '
EALT4.SA', '
ECOR3.SA', '
EGIE3.SA',
'
ELET3.SA', '
EMBR3.SA'
]
# Função para buscar os dados históricos
def get_data(tickers):
end_date = dt.date.today()
beg_date = dt.date(2014, 3, 1) # Data inicial: março de 2014
data = pd.DataFrame()
for ticker in tickers:
try:
temp = yf.download(ticker, start=beg_date, end=end_date, interval='1mo')
if 'Adj Close' in temp.columns:
temp = temp[['Adj Close']].reset_index()
temp.rename(columns={'Date': 'Date', 'Adj Close': ticker}, inplace=True)
if data.empty:
data = temp
else:
data = pd.merge(data, temp, on="Date", how='outer')
else:
print(f"Erro ao baixar dados para {ticker}: 'Adj Close' não encontrado.")
except Exception as e:
print(f"Erro ao processar {ticker}: {e}")
data.dropna(inplace=True)
return data
data = get_data(all_tickers)
# Função para calcular retornos mensais
def calculate_returns(data):
returns = pd.DataFrame(index=data.index, columns=all_tickers)
for ticker in all_tickers:
if ticker in data.columns:
returns[ticker] = data[ticker].pct_change()
return returns
returns = calculate_returns(data)
# Função para calcular o momentum absoluto
def calculate_absolute_momentum(returns, periods=[1, 3, 6]):
momentum_abs = pd.DataFrame(index=returns.index)
for period in periods:
period_momentum = returns.rolling(period).sum()
period_momentum.columns = [f"{ticker} - {period}m" for ticker in returns.columns]
momentum_abs = pd.concat([momentum_abs, period_momentum], axis=1)
return momentum_abs
momentum_abs = calculate_absolute_momentum(returns)
# Função para calcular o momentum relativo
def calculate_relative_momentum(returns, benchmark):
relative_momentum = pd.DataFrame(index=returns.index, columns=all_tickers)
for ticker in all_tickers:
if ticker in returns.columns and benchmark in returns.columns:
relative_momentum[ticker] = returns[ticker] - returns[benchmark]
return relative_momentum
# Calcular o momentum relativo com base no benchmark ^BVSP
benchmark = "^BVSP"
relative_momentum = calculate_relative_momentum(returns, benchmark)
# Função para selecionar as ações com o melhor momentum absoluto positivo
def select_top_absolute_momentum(momentum_abs, top_n=4):
positive_momentum = momentum_abs.apply(lambda x: x.where(x > 0, 0)) # Filtra valores positivos
latest_momentum = positive_momentum.iloc[-1] # Última linha
return latest_momentum.nlargest(top_n).index.tolist() # Seleciona os top N
# Selecionar ações com o melhor momentum absoluto positivo
selected_tickers = select_top_absolute_momentum(momentum_abs)
# Função para selecionar as ações com o melhor momentum relativo
def select_top_relative_momentum(relative_momentum, top_n=4):
latest_relative_momentum = relative_momentum.iloc[-1]
return latest_relative_momentum.nlargest(top_n).index.tolist()
# Selecionar ações com o melhor momentum relativo ao benchmark
relative_selected_tickers = select_top_relative_momentum(relative_momentum)
# Escolha final
final_selected_tickers = list(set(selected_tickers).intersection(relative_selected_tickers))
print(f"Escolhendo ações com o melhor momentum absoluto e relativo: {final_selected_tickers}")
# Exibir a tabela
display(HTML(momentum_abs.to_html()))