tesouro_direto_br é uma biblioteca Python para executar cálculos para gerenciamento de carteira de Títulos Públicos Federais (TPFs) usando dados do Tesouro Direto. Com ela, você poderá:
- inserir seus TPFs e montar uma carteira;
- calcular o valor de mercado dos TPFs (marcação a mercado) e da carteira;
- calcular retorno da carteira;
- visualizar a evolução do valor de mercado e do retorno;
- detalhamento dos custos envolvidos: IOF, IRPF, taxa de custódia B3;
- obter rentabilidade líquida e bruta da carteira/título;
- você pode simular uma carteira hipotética de TPFs;
- você pode comparar com benchmarks como: CDI, ibovespa, IMA-B, IMA-B 5 e IMA-B 5+;
Pode usar o comando:
pip install tesouro-direto-br
Alternativamente, obter diretamente do Github:
pip install https://github.com/rafa-rod/tesouro_direto_br/archive/refs/heads/main.zip
Notei que algumas corretoras mostraram a rentabilidade da carteira de forma equivocada. Algumas mostram apenas de um título, não da carteira e somente de períodos específicos. Além disso, você pode simular investimentos em períodos históricos específicos e estudar suas opções de investimento antes de adquirir algum título específico.
Importe a biblioteca e insira titulos publicos a uma carteira vazia:
import getpass
import tesouro_direto_br as tesouro_direto
#Criar uma carteira vazia:
carteira = tesouro_direto.Carteira(tesouro_direto.Titulo())
#Adicionar titulos publicos:
titulo1 = tesouro_direto.Titulo("Tesouro IPCA+", "2026-08-15", "2021-07-08", 33.65)
titulo2 = tesouro_direto.Titulo("Tesouro Selic", "2025-03-01", "2021-07-08", 50)
carteira.add(titulo1)
carteira.add(titulo2)
Com a carteira montada, é hora de calcular o valor de mercado da carteira (marcação a mercado):
USER = getpass.getuser().lower()
PASS = getpass.getpass("Senha de rede: ")
SERVIDOR = "SERVIDOR"
PORTA = "PORTA"
proxies = {
"http":f"http://{USER}:{PASS}@{SERVIDOR}:{PORTA}",
"https":f"http://{USER}:{PASS}@{SERVIDOR}:{PORTA}",
}
carteira_tesouro_direto = tesouro_direto.calcula_retorno_carteira(carteira, proxies=proxies)
Com os valores de mercado, é possível obter a rentabilidade da carteira:
retorno_carteira, retorno_titulos_acumulado = tesouro_direto.calcula_mtm_carteira(carteira_tesouro_direto)
ano, mes, dia = str(retorno_carteira.index[0]).split('-')
dia = dia.split(" ")[0]
retorno_periodo = retorno_carteira.iloc[-1]*100
print(f"Retorno da Carteira é de {round(retorno_periodo,2)}% desde {dia}/{mes}/{ano}")
Se desejar obter a rentabilidade por período específico (como as corretoras fazem):
rentalibidade_periodo = 100*carteira_tesouro_direto['Rentabilidade Acumulada'].iloc[-1]
print(f"Rentabilidade do período é de {round(rentalibidade_periodo, 3)}%")
A análise melhora se você comparar com um benchmark como o CDI:
import matplotlib.pyplot as plt
import comparar_fundos_br as comp
cdi, cdi_acumulado = comp.get_benchmark(str(carteira_tesouro_direto.index[0]).split(" ")[0],
str(carteira_tesouro_direto.index[-1]).split(" ")[0],
benchmark = "cdi", proxy=proxies)
retorno_cdi = (cdi_acumulado-1)*100
plt.figure(figsize=(17,5))
plt.title("Rentabilidade da Carteira")
plt.plot(carteira_tesouro_direto[["Rentabilidade Acumulada"]]*100)
plt.plot(retorno_cdi, color="red", linestyle="--", lw=1)
plt.legend(["Carteira", "CDI"], frameon=False, loc="center right")
plt.ylabel('%',rotation=0,labelpad=-10,loc="top")
plt.grid(axis="x")
plt.show()
Os custos de cada TPF podem ser obtidos seguindo o script a seguir. Esses serão os custos aproximados caso o TPF seja resgatado na presente data.
nom = tesouro_direto.nomeclatura_titulos()
for tpf in carteira.titulos:
tipo_titulo = tpf["Tipo"]
investimento = tpf["Quantidade"]
data_investimento = tpf["Data Investimento"]
vencimento = tpf["Vencimento"]
venc = vencimento.split("-")[0]
nome_titulo = [nom[tipo_titulo].upper() + "_" + venc + "_" + data_investimento]
print(nome_titulo[0])
mtm_titulo = carteira_tesouro_direto[nome_titulo].dropna()
custos, detalhamento_custos = get_custos( mtm_titulo, custo_b3=True)
print()
O IOF segue uma tabela regressiva de taxa cobrada e é zerado após 30 dias. Já o imposto de renda diminui após dois anos onde atinge o valor mínimo de 15%. As taxas da B3 são cobradas em Janeiro e Julho de cada ano sobre o valor investido e proporcionais ao tempo investido. Tesouro Selic tem isenção para investimentos abaixo de R$ 10.000,00. Maiores detalhes consultar site da B3.
Estou considerando 0% a taxa da corretora uma vez que a maior parte das corretoras não tem cobrado esse valor.
É possível obter as movimentações de vendas ou resgates (recompras) de TPFs:
movimentacao_tpf = movimentacoes_titulos_publicos("venda", proxies=proxies)
#Maiores Movimentações nos últimos 10 dias:
maiores_movimentacoes = movimentacao_pivot.iloc[-10:].T.dropna()
maiores_movimentacoes["Soma"] = maiores_movimentacoes.sum(axis=1)
maiores_movimentacoes = maiores_movimentacoes.sort_values("Soma", ascending=False)
print(maiores_movimentacoes)
#destaque para os 3 maiores movimentos de venda
tres_maiores = maiores_movimentacoes.index[:3].tolist()
maiores = maiores_movimentacoes.drop(["Soma"], axis=1).T
fig = plt.gcf()
fig.set_size_inches(15, 7, forward = False)
plt.rcParams.update({'font.size': 22})
for tit in maiores.drop(tres_maiores, axis=1).columns:
plt.plot(maiores[tit], color="gray", alpha=0.35, label='')
for tit in maiores[tres_maiores].columns:
plt.plot(maiores[tit], lw=3, label=tit)
plt.legend(frameon=False, bbox_to_anchor=(0.95, 1.))
plt.suptitle("Movimentações de Venda de Títulos Públicos")
plt.box(False)
plt.grid(axis="y")
plt.ylabel('Quantidade',rotation=0,labelpad=-30,loc="top")
plt.xticks(rotation=15)
plt.show()
Você pode estudar o comportamento de uma estratégia ou dos títulos em períodos históricos específicos. Para isso, basta informar a opção taxa à função busca_tesouro_direto, veja um exemplo de títulos ofertados entre 17/02/2016 e 01/01/2017:
titulos_ofertados = tesouro_direto.busca_tesouro_direto(tipo="taxa", proxies=proxies).reset_index()
excluir = ["Juros Semestrais", "Renda+", "Educa+"]
titulos_ofertados_filtrado = titulos_ofertados[(titulos_ofertados["Data Base"]>="2016-02-17") &
(titulos_ofertados["Data Base"]<"2017-01-01") &
(~titulos_ofertados["Tipo Titulo"].str.contains("&".join(excluir)))].set_index(["Tipo Titulo",
"Data Vencimento"])
titulos_ofertados_filtrado.tail()
No exemplo acima, optei por excluir TPFs com Juros Semestrais e os novos Renda+ e Educa+ (sequer eram ofertados no período pesquisado). Filtrando por tipo de indexador para facilitar a identificação:
inflacao = titulos_ofertados_filtrado.loc[["Tesouro IPCA+"], :].sort_values("Data Base", ascending=False)
display(inflacao[inflacao["Data Base"]=="2016-02-17"].sort_index(level=1, ascending=True))
prefixado = titulos_ofertados_filtrado.loc[["Tesouro Prefixado"], :].sort_values("Data Base", ascending=False)
display(prefixado[prefixado["Data Base"]=="2016-02-17"].sort_index(level=1, ascending=True))
selic = titulos_ofertados_filtrado.loc[["Tesouro Selic"], :].sort_values("Data Base", ascending=False)
display(selic[selic["Data Base"]=="2016-02-17"].sort_index(level=1, ascending=True))
A partir de um título específico que tenha identificado, pode-se repetir os procedimentos de elaboração de carteira exibido no início deste tutorial e calcular a rentabilidade dos títulos até o vencimento comparando com banchmark. Assim, você consegueria saber se a estratégia foi a que esperava (não necessariamente pode se repetir no futuro).