1

Pitch: Criei um simulador de precificação do Tesouro Direto e o validei contra 270 mil combinações históricas de taxa e preço

Como investidor de títulos públicos, acho importante saber como os preços dos títulos são compostos. Hoje, com as taxas nas máximas, vemos diversos vídeos de análise, muitas vezes rasos e sem mostrar como o preço é calculado a partir do prazo e da taxa. Por isso criei este simulador e o validei contra quase 270 mil combinações de taxas e preços desde 2004, quando foi lançado o primeiro título IPCA+ com juros semestrais.

A maioria das calculadoras e simuladores existentes não mostra a composição do preço e só entrega o número fechado, sem auditoria do cálculo. Então, além de exibir o preço final, ele mostra cada etapa da composição do PU e permite auditar o cálculo completo. O simulador pode ser acessado em Tesouro em Foco. Nele é possível ver cada detalhe que compõe o preço de um título.

Como o preço de um título é composto

  • Fluxo de pagamentos: títulos com cupom (NTN-F, NTN-B) pagam juros semestrais em datas fixas, ou Renda+ e Educa+ (NTN-B1), pagando fluxos mensais após a data de conversão. O preço é a soma de cada fluxo descontado individualmente, e não uma fórmula fechada.
  • VNA nos indexados: nos IPCA+, o valor nominal é atualizado pela inflação com projeção pro rata entre as divulgações do IPCA. Em geral ocorrem três atualizações mensais: duas projeções divulgadas pela Anbima e uma atualização com o IPCA efetivamente publicado pelo IBGE.
  • Truncamentos: as regras de negociação truncam cotação e preço em casas decimais específicas, em etapas específicas da conta. Sem isso, o resultado nunca bate com o PU.
  • Compra vs. venda: a compra é liquidada em D+1, venda tem regime próprio e mudou em 13/09/2021, quando o Tesouro Direto adotou liquidação D+0 para ordens da manhã. O simulador modela os dois regimes.

Backtest de 270 mil observações históricas desde 2004

Comparei a engine contra quase 270 mil pares de taxa e PU publicados no Tesouro Transparente, e o resultado foi 99,26% de acerto. A distribuição dos erros também é interessante: os meses recentes fecham em 100,00%, e as 1.993 falhas se concentram nos dados mais antigos, principalmente na família IPCA+ com Juros Semestrais (98,17%). O backtest completo é público, com breakdown por família e mês a mês, amarrado ao hash da engine: tesouroemfoco.com/backtest.

Se alguém aqui já mexeu com precificação de NTN-B antiga e tem teoria sobre alguma convenção pré-2012, aceito comentários.

Como validei a quantidade de dias úteis

A maneira mais fácil de validar a contagem de dias úteis é usar a precificação do Prefixado (LTN), que tem fórmula fechada:

PU = 1000 / (1 + taxa)^(du / 252)

Com o histórico completo de PUs e taxas publicado no Tesouro Transparente, dá para fazer o cálculo inverso e recuperar o du que o Tesouro usou em cada dia. O detalhe: como o PU publicado é truncado em centavos (2 casas decimais), o PU verdadeiro está entre pu e pu + 0,01, o que coloca o du dentro de um intervalo. Quando esse intervalo contém exatamente um número inteiro, recuperamos a contagem exata de dias úteis daquela operação.

Usei o DuckDB para gerar os fixtures do backtest, lendo o CSV oficial direto da fonte.

INSTALL httpfs;
LOAD httpfs;
CREATE SECRET disable_ssl (TYPE HTTP, VERIFY_SSL 0);

CREATE OR REPLACE TABLE td_history AS
SELECT
    produto,
    vencimento,
    data_base,
    CAST(taxa_compra / 100 AS DECIMAL(18, 6)) AS taxa_compra,
    CAST(taxa_venda  / 100 AS DECIMAL(18, 6)) AS taxa_venda,
    pu_compra,
    pu_venda
FROM read_csv(
    'https://www.tesourotransparente.gov.br/ckan/dataset/df56aa42-484a-4a59-8184-7676580c81e3/resource/796d2059-14e9-44e3-80c9-2d9e30b405c1/download/precotaxatesourodireto.csv',
    delim = ';',
    decimal_separator = ',',
    dateformat = '%d/%m/%Y',
    header = false,
    skip = 1,
    columns = {
        produto: 'VARCHAR',
        vencimento: 'DATE',
        data_base: 'DATE',
        taxa_compra: 'DECIMAL(18, 6)',
        taxa_venda: 'DECIMAL(18, 6)',
        pu_compra: 'DECIMAL(18, 2)',
        pu_venda: 'DECIMAL(18, 2)',
        pu_base: 'DECIMAL(18, 2)'
    }
)
ORDER BY data_base, produto, vencimento;

CREATE OR REPLACE TABLE td_history_operations_du AS
WITH operations AS (
    SELECT produto, vencimento, data_base,
           pu_compra AS pu, taxa_compra AS taxa, 'compra' AS operacao
    FROM td_history
    WHERE produto = 'Tesouro Prefixado'
      AND pu_compra IS NOT NULL
    UNION ALL
    SELECT produto, vencimento, data_base,
           pu_venda AS pu, taxa_venda AS taxa, 'venda' AS operacao
    FROM td_history
    WHERE produto = 'Tesouro Prefixado'
      AND pu_venda IS NOT NULL
),
intervalo AS (
    SELECT
        *,
        -- PU truncado: o PU real está entre pu e pu + 0,01.
        -- PU maior implica du menor, e vice-versa.
        252.0 * (LN(1000.0 / (pu + 0.01)) / LN(1.0 + taxa)) AS du_minimo,
        252.0 * (LN(1000.0 / pu)          / LN(1.0 + taxa)) AS du_maximo
    FROM operations
)
SELECT
    produto,
    vencimento,
    data_base,
    operacao,
    pu,
    taxa,
    du_minimo,
    CEIL(du_minimo)  AS du_min_inteiro,
    du_maximo,
    FLOOR(du_maximo) AS du_max_inteiro,
    CEIL(du_minimo) - FLOOR(du_maximo) AS ambiguidade
FROM intervalo
ORDER BY data_base, produto, vencimento;

Verificando os casos que poderemos usar ou não:

SELECT count(*) FROM td_history_operations_du WHERE ambiguidade != 0;
-- 6

SELECT count(*) FROM td_history_operations_du WHERE ambiguidade = 0;
-- 55544

Ou seja: em apenas 6 casos o intervalo ficou ambíguo (sem um inteiro único), então eles ficam de fora. Sobram um pouco mais de 55 mil operações com a contagem de dias úteis recuperada de forma exata, e é com base nelas que o motor de calendário é validado. Isso valida o calendário; a precificação completa, com todas as famílias de título, é validada pelo backtest da seção anterior.

API e MCP

Além da interface web, expus em API REST e em um servidor MCP remoto. Basta configurar o endpoint MCP em um cliente compatível e fazer perguntas sobre títulos públicos:

{
  "mcpServers": {
    "tesouro-em-foco": {
      "url": "https://mcp.tesouroemfoco.com/mcp"
    }
  }
}

Deixei publicadas algumas conversas reais com IA usando o MCP.

Feedback

É um projeto independente e educativo (não é recomendação de investimento). Queria feedbacks de vocês:

  1. Que análise vocês gostariam de fazer e não conseguem hoje? (venda antecipada da carteira inteira, IR, comparação entre títulos?)
  2. Para quem mexe com MCP: a conexão foi tranquila no seu client? As descrições das tools estão coerentes?
  3. Encontrou alguma divergência de preço que não está mapeada no backtest?
Carregando publicação patrocinada...