Como calcular a inflação implícita e decidir o melhor Tesouro Direto
- Erick Giorgio
- 06 Mar 2025
Existe um jeito simples (e que quase ninguém conhece) para decidir entre os dois tipos. Vou mostrar isso programando Vou criar um script em Python que automatiza essa análise para os títulos do Tesouro Direto. O script vai extrair as taxas dos títulos prefixados e dos títulos IPCA+, fazer os cálculos necessários e exibir os resultados em uma tabela.
O que é a Inflação Implícita no Contexto do Tesouro Direto?
A inflação implícita é a expectativa do mercado para a inflação futura, calculada a partir da diferença entre as taxas dos títulos do Tesouro Prefixado e do Tesouro IPCA+. Ela indica a inflação esperada para o período de vencimento dos títulos e é um indicador importante para os investidores decidirem onde aplicar seu dinheiro.
Como a Inflação Implícita é Calculada?
A inflação implícita é obtida com a seguinte fórmula:

Onde:
Essa relação mostra a inflação esperada para o período, pois o Tesouro IPCA+ remunera o investidor com uma taxa fixa + inflação, enquanto o Tesouro Prefixado oferece um retorno fixo.
Exemplo Prático
Suponha que para um título com vencimento em 2029, as taxas sejam:
Aplicando a fórmula:

Isso significa que o mercado espera uma inflação média de 5,03% ao ano até 2029.
Como Utilizar a Inflação Implícita na Escolha de Investimentos?
Comparação com a inflação projetada
Vamos ao código
class TesouroDiretoExtractor:
"""Classe para extrair dados do Tesouro Direto utilizando vários métodos"""
def __init__(self):
self.tesouro_url = "https://www.tesourodireto.com.br/titulos/precos-e-taxas.htm"
self.tesouro_api_url = "https://www.tesourodireto.com.br/json/br/com/b3/tesourodireto/service/api/treasurybondsinfo.json"
self.headers = {
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36"
}
self.titulos_prefixados = []
self.titulos_ipca = []
def _fazer_requisicao(self, url: str) -> Optional[requests.Response]:
"""Faz uma requisição HTTP para a URL especificada"""
try:
response = requests.get(url, headers=self.headers)
response.raise_for_status()
return response
except requests.exceptions.RequestException as e:
logger.error(f"Erro ao acessar a URL {url}: {e}")
return None
def _extrair_titulos_do_json(self, script_content: str) -> None:
"""Extrai informações de títulos de um script contendo JSON"""
try:
json_match = re.search(r'window\.TD\.titulos\s*=\s*(\[.*?\]);', script_content, re.DOTALL)
if not json_match:
return
json_data = json.loads(json_match.group(1))
for titulo_data in json_data:
nome = titulo_data.get('nome', '')
vencimento = titulo_data.get('vencimento', '')
try:
rentabilidade = float(titulo_data.get('rentabilidade', '0').replace('%', '').replace(',', '.').strip())
except (ValueError, AttributeError):
rentabilidade = 0
if not vencimento:
continue
try:
vencimento_data = datetime.strptime(vencimento, '%d/%m/%Y')
except ValueError:
try:
vencimento_data = datetime(int(vencimento), 1, 1)
except ValueError:
continue
titulo = Titulo(nome, vencimento, vencimento_data, rentabilidade)
if TipoTitulo.PREFIXADO in nome:
self.titulos_prefixados.append(titulo)
elif TipoTitulo.IPCA in nome:
self.titulos_ipca.append(titulo)
except Exception as e:
logger.error(f"Erro ao extrair dados do script: {e}")
Código completo em:
for item in api_data['response']['TrsrBdTradgList']:
nome = item.get('TrsrBd', {}).get('nm', '')
vencimento = item.get('TrsrBd', {}).get('mtrtyDt', '')
taxa_str = item.get('TrsrBd', {}).get('anulInvstmtRate', '')
if taxa_str or taxa_str == 0.0:
taxa_str = item.get('TrsrBd', {}).get('anulRedRate', '')
if not nome or not vencimento or taxa_str <= 0.0:
continue
try:
taxa = float(taxa_str)
vencimento_data = datetime.strptime(vencimento.split("T")[0], "%Y-%m-%d")
vencimento_str = vencimento_data.strftime('%d/%m/%Y')
titulo = Titulo(nome, vencimento_str, vencimento_data, taxa)
if TipoTitulo.PREFIXADO in nome:
self.titulos_prefixados.append(titulo)
elif TipoTitulo.IPCA in nome:
self.titulos_ipca.append(titulo)
except (ValueError, TypeError) as e:
logger.warning(f"Erro ao processar item da API: {e}")
continue
def calcular_comparativo(titulos_prefixados: List[Dict], titulos_ipca: List[Dict]) -> List[Dict]:
"""Calcula o comparativo entre títulos prefixados e IPCA+"""
logger.info("Calculando comparativos entre títulos")
resultados = []
if not titulos_prefixados or not titulos_ipca:
logger.warning("Não há dados suficientes para calcular o comparativo")
return resultados
# Ordenar títulos por data de vencimento
titulos_prefixados.sort(key=lambda x: x["vencimento_data"])
titulos_ipca.sort(key=lambda x: x["vencimento_data"])
# Para cada título prefixado, encontrar o IPCA+ mais próximo em termos de vencimento
for prefixado in titulos_prefixados:
# Encontrar o IPCA+ mais próximo
ipca_mais_proximo = None
diferenca_minima = float('inf')
for ipca in titulos_ipca:
diferenca = abs((prefixado["vencimento_data"] - ipca["vencimento_data"]).days)
if diferenca < diferenca_minima:
diferenca_minima = diferenca
ipca_mais_proximo = ipca
if ipca_mais_proximo:
# Calcular a inflação implícita
prefixado_valor = 1 + (prefixado["rentabilidade"] / 100)
ipca_valor = 1 + (ipca_mais_proximo["rentabilidade"] / 100)
resultado = (prefixado_valor / ipca_valor) - 1
resultado_percentual = resultado * 100
# Criar objeto de resultado e converter para dicionário
titulo_prefixado = Titulo(
prefixado["nome"],
prefixado["vencimento"],
prefixado["vencimento_data"],
prefixado["rentabilidade"]
)
titulo_ipca = Titulo(
ipca_mais_proximo["nome"],
ipca_mais_proximo["vencimento"],
ipca_mais_proximo["vencimento_data"],
ipca_mais_proximo["rentabilidade"]
)
comparativo = ResultadoComparativo(
titulo_prefixado,
titulo_ipca,
resultado_percentual
)
resultados.append(comparativo.to_dict())
return resultados
def exibir_resultados(resultados: List[Dict]) -> Optional[pd.DataFrame]:
"""Exibe os resultados da análise de inflação implícita"""
if not resultados:
logger.warning("Não foi possível calcular os resultados devido à falta de dados")
return None
# Converter para DataFrame
df = pd.DataFrame(resultados)
# Exibir cabeçalho
display(Markdown("# ANÁLISE DE INFLAÇÃO IMPLÍCITA NO TESOURO DIRETO"))
# Criar uma versão simplificada para exibição
df_display = df[["Título Prefixado", "Taxa Prefixado (%)",
"Título IPCA+", "Taxa IPCA+ (%)",
"Inflação Implícita (%)"]]
# print(tabulate(df_display, headers='keys', tablefmt='grid', showindex=False))
html_table = df_display.to_html(index=False)
display(HTML(html_table))
# Exibir explicação e recomendação para cada par de títulos
display(Markdown("# INTERPRETAÇÃO E RECOMENDAÇÃO"))
for i, row in enumerate(resultados):
display(Markdown(f"### Par {i+1}: {row['Título Prefixado']} vs {row['Título IPCA+']} \n"))
display(Markdown(f"Inflação Implícita: **{row['Inflação Implícita (%)']:.2f}%**"))
display(Markdown("O que significa: Este é o valor médio anual do IPCA até o vencimento"))
display(Markdown("que o mercado está prevendo implicitamente."))
display(Markdown(f"Recomendação: **{row['Recomendação']}**"))
display(Markdown("<hr>"))
# Explicação adicional
display(Markdown("## EXPLICAÇÃO DETALHADA:"))
...
Referencias
Código completo em: