Reafirmando que quando mais exemplos analisamos, mais refinado e fixado vai sendo o conhecimento, tentei reunir algumas linhas de comando em python retornadas do prompt via copilot + um título selecionado na plataforma do tesouro na data corrente.
Segue o gráfico que consegui e o código para quem quiser se aventurar a corrigir, melhorar e republicar
#28/06/25
import sys
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
from datetime import datetime
import matplotlib.dates as mdates
versao_python = sys.version.split()[0]
# ====================================
# PARÂMETROS
# ====================================
valor_unitario_0_01 = 16.99
quantidade = 0.50
valor_inicial = valor_unitario_0_01 * (quantidade / 0.01)
taxa_real = 0.0756 # 7,56% a.a.
ipca = 0.0472 # 4,72% estimado
taxa_b3 = 0.002 # 0,20% a.a.
data_inicio = datetime(2026, 6, 24)
data_fim = datetime(2040, 8, 15)
# ====================================
# TAXAS
# ====================================
taxa_nominal = (1 + taxa_real) * (1 + ipca) - 1
# sem desconto B3
#taxa_mensal = (1 + taxa_nominal) ** (1/12) - 1
# descontando a taxa da B3
taxa_liquida = (1 + taxa_nominal) * (1 - taxa_b3) - 1
taxa_mensal = (1 + taxa_liquida) ** (1/12) - 1
# ====================================
# CRIAÇÃO DAS DATAS
# ====================================
datas = pd.date_range(start=data_inicio, end=data_fim, freq='ME')
# ====================================
# CÁLCULO DO INVESTIMENTO
# ====================================
valores_brutos = [valor_inicial]
for i in range(1, len(datas)):
dias = (datas[i] - datas[i-1]).days
# crescimento do investimento
fator_rendimento = (1 + taxa_nominal) ** (dias / 365)
# desconto da taxa B3
fator_b3 = (1 - taxa_b3) ** (dias / 365)
# valor atualizado
valor = valores_brutos[-1] * fator_rendimento * fator_b3
valores_brutos.append(valor)
# ====================================
# IMPOSTO DE RENDA
# ====================================
aliquota_ir = 0.15 # acima de 720 dias
valor_final_bruto = valores_brutos[-1]
lucro = valor_final_bruto - valor_inicial
ir_valor = lucro * aliquota_ir
valor_final_liquido = valor_final_bruto - ir_valor
lucro_liquido = valor_final_liquido - valor_inicial
# ===============================================
# CÁLCULO SEM TAXA B3 (para comparação)
# ===============================================
valores_sem_b3 = [valor_inicial]
for i in range(1, len(datas)):
dias = (datas[i] - datas[i-1]).days
fator_rendimento = (1 + taxa_nominal) ** (dias / 365)
valor = valores_sem_b3[-1] * fator_rendimento
valores_sem_b3.append(valor)
valor_final_sem_b3 = valores_sem_b3[-1]
# custo total da B3 (efeito real com juros compostos)
custo_b3 = valor_final_sem_b3 - valor_final_bruto
# ===============================================
# IPCA ACUMULADO NO PERÍODO
# ===============================================
dias_total = (data_fim - data_inicio).days
ipca_acumulado = (1 + ipca) ** (dias_total / 365)
lucro_real = valor_final_liquido / ipca_acumulado
lucro_real_percentual = lucro_real / valor_inicial
# ====================================
# DATAFRAME
# ====================================
df = pd.DataFrame({
'Data': datas,
'Valor Bruto': valores_brutos
})
# ====================================
# GRÁFICO
# ====================================
fig, ax = plt.subplots(figsize=(10,5))
# linha principal
ax.plot(df['Data'], df['Valor Bruto'], label='Valor Bruto (c/ Impostos)')
# linha de valor líquido
ax.axhline(valor_final_liquido, linestyle='--', label='Valor Líquido Sacado')
# linha: lucro líquido
ax.axhline(lucro_liquido, linestyle=':', color='purple', label='Ganho Nominal (c/ inflação)')
# linha do valor REAL (poder de compra)
ax.axhline(lucro_real, linestyle='-.', color='orange', label='Ganho Real (acima da inflação)')
# ponto inicial
ax.scatter(df['Data'].iloc[0], valor_inicial, color='green')
ax.annotate(
f"Inicial\nR$ {valor_inicial:,.2f}",
(df['Data'].iloc[0], valor_inicial),
xytext=(5, 12),
textcoords="offset points"
)
# ponto final bruto Nominal
ax.scatter(df['Data'].iloc[-1], valores_brutos[-1], color='red')
ax.annotate(
f"Final\nR$ {valores_brutos[-1]:,.2f}\n{data_fim.strftime('%d/%m/%Y')}",
(df['Data'].iloc[-1], valores_brutos[-1]),
xytext=(5, -15),
textcoords="offset points"
)
# ponto final líquido
ax.scatter(df['Data'].iloc[-1], valor_final_liquido, color='blue')
ax.annotate(
f"Líquido Sacado\nR$ {valor_final_liquido:,.2f}\n{data_fim.strftime('%d/%m/%Y')}",
(df['Data'].iloc[-1], valor_final_liquido),
xytext=(5, -30), # ajuste para não sobrepor o valor bruto
textcoords="offset points"
)
# ponto final lucro líquido
ax.scatter(df['Data'].iloc[-1], lucro_liquido, color='purple')
ax.annotate(
f"Ganho Nominal\nR$ {lucro_liquido:,.2f}",
(df['Data'].iloc[-1], lucro_liquido),
xytext=(5, -20),
textcoords="offset points"
)
# ponto final valor real
ax.scatter(df['Data'].iloc[-1], lucro_real, color='orange')
ax.annotate(
f"Ganho Real\nR$ {lucro_real:,.2f}",
(df['Data'].iloc[-1], lucro_real),
xytext=(5, -20),
textcoords="offset points"
)
# ====================================
# AJUSTES DO EIXO DE DATA
# ====================================
# marcação de anos
ax.xaxis.set_major_locator(mdates.YearLocator(2))
ax.xaxis.set_major_formatter(mdates.DateFormatter('%Y'))
# remove espaço extra nas laterais
ax.margins(x=0)
# ====================================
# ESTILO
# ====================================
ax.set_title("Tesouro IPCA+ 7,56% 2040 - Projeção Mensal")
ax.set_xlabel("Data")
ax.set_ylabel("Valor (R$)")
ax.grid(True)
ax.legend()
# FORÇAR ZERO NO EIXO Y
#ax.set_ylim(bottom=0)
# ===============================
# CAIXA COM DADOS DA SIMULAÇÃO
# ===============================
texto_info = (
f"Python: {versao_python}\n"
f"SIMULAÇÃO:\n"
f"Valor da Cota: R$ {valor_unitario_0_01:,.2f}\n"
f"Cotas aportadas: {(quantidade*100):,.2f}\n"
f"Aporte Único: R$ {valor_inicial:,.2f}\n"
f"Valor Final: R$ {valores_brutos[-1]:,.2f}\n"
f"Líquido sacado: R$ {valor_final_liquido:,.2f}\n"
f"Ganho nominal: R$ {lucro_liquido:,.2f}\n"
f"Ganho real: R$ {lucro_real:,.2f}\n"
f"Ganho real %: {(lucro_real_percentual*100):,.2f}%\n"
f"Alíquita de IR: {int(aliquota_ir*100)}%\n"
f"IR recolhido: R$ {ir_valor:,.2f}\n"
f"Taxa B3 a.a.: {taxa_b3*100:,.2f}%\n"
f"Taxa B3 Paga: R$ {custo_b3:,.2f}\n"
#f"Impacto da B3 no patrimônio: {(custo_b3/valor_final_sem_b3)*100:.2f}%\n"
f"Taxa real: {taxa_real*100:.2f}% a.a.\n"
f"IPCA estimado no cálculo: {ipca*100:.2f}% a.a.\n"
f"Taxa total: {(taxa_nominal*100):.2f}% a.a.\n"
f"Data compra: {data_inicio.strftime('%d/%m/%Y')}\n"
f"Vencimento: {data_fim.strftime('%d/%m/%Y')}\n"
)
plt.gca().text(
0.02, 0.98, # posição (canto superior esquerdo)
texto_info,
transform=plt.gca().transAxes,
fontsize=9,
verticalalignment='top',
bbox=dict(boxstyle="round", facecolor="white", alpha=0.8)
)
plt.tight_layout()
plt.show()