Pular para conteúdo

Valor nominal atualizado

As funções yd.vna.vigencia("NTN-B", data) e yd.vna.vigencia("NTN-C", data) retornam o início inclusivo e o fim exclusivo da vigência do VNA, sem consultar a rede. Essas datas permitem selecionar a base e a projeção mensal na aplicação, inclusive quando operação e liquidação pertencem a vigências diferentes.

  • NTN-B: dia 15 até o dia 15 seguinte.
  • NTN-C: primeiro dia do mês até o primeiro dia do mês seguinte.

A aplicação fornece o VNA ao calcular o preço completo dos títulos indexados:

cotacao = yd.ntnb.cotacao("14-08-2026", "15-08-2026", 0.132098)
pu = yd.ntnb.pu(4742.6373, cotacao)
# Decimal('4880.439369')

A seleção do VNA oficial ou projetado permanece explícita no consumidor.

Consulta por título

import pyield as yd

ultimo = yd.vna.ultimo("NTN-B")  # DataFrame com data e VNA publicados
historico = yd.vna.historico("NTN-C", vencimento="01-01-2031")
valor = yd.vna.valor("NTN-B", "15-12-2025")
projecao_ntnb = yd.vna.projetado("NTN-B", "30-06-2026", 4731.856412, 0.45)
projecao_lft = yd.vna.projetado(
    "LFT", "18-09-2026", 19905.773236,
    selic="13.65%",
)

projetado é a operação comum de projeção para todos os títulos. Para NTN-B e NTN-C, inflacao representa a variação mensal em percentual e aceita float ou Decimal. Para LFT, selic representa a taxa anual informada em formato decimal ou percentual explícito. Para reproduzir o acruamento oficial, derive a taxa Selic diária publicada pelo SGS 11. Como ela é publicada em percentual, 0,050788% equivale à taxa decimal 0,00050788 e ao fator derivado 1,00050788; converta essa taxa diária para uma taxa anual equivalente. A série 1178 é a Selic Over anualizada e serve apenas como aproximação. A data-base é o último dia útil anterior à data solicitada. A projeção usa a quantidade de dias úteis até a data solicitada e retorna Decimal. Intervalos diferentes de um dia útil são calculados normalmente e registrados no log. historico e ultimo retornam DataFrames com coluna vna do tipo Float64. O cálculo genérico calcular_vna mantém seu retorno float existente.

Por exemplo, o SGS 11 publicou 0,050788% para 18/09/2026. Isso corresponde ao fator diário 1,00050788; aplicado ao VNA de 17/09/2026 (19905,773236), produz 19915,882980111..., truncado para 19915,882980, exatamente o valor publicado pelo BCB. A série 1178 publicou 13,65% anualizado na mesma data; usá-la diretamente produz uma pequena diferença por causa do arredondamento.

ultimo retorna a última referência de cada série; para NTN-C sem filtro de vencimento, pode retornar mais de uma linha. Datas e valores permanecem juntos. Não há projeção automática. A LFT não possui histórico mensal nem operação de última referência nessa API; sua projeção usa a quantidade de dias úteis do intervalo, base 252 e taxa anual constante dentro da mesma operação projetado. Quando o intervalo não corresponde a exatamente um dia útil, o cálculo é feito normalmente e a ocorrência é registrada no log. Em uma segunda-feira, por exemplo, a base é a sexta-feira útil anterior.

Use apenas yd.vna para operações de VNA. Os aliases vna, vnas, vna_projetado e vigencia foram removidos dos módulos dos títulos. As implementações internas e suas metodologias foram preservadas.

Consulta e cálculo de VNA por título: valor, histórico, último e projeção.

calcular_vna(df, data, *, fator_variacao=None)

Obtém o VNA publicado ou calcula o pró-rata entre pontos publicados.

Parameters:

Name Type Description Default
df DataFrame

DataFrame com as colunas data (Date) e vna (Float64), contendo no máximo um ponto publicado por data.

required
data date

Data para a qual o VNA será obtido ou interpolado.

required
fator_variacao float | None

Fator multiplicativo entre o ponto inicial e o final. Se omitido, é calculado pela razão entre os VNAs dos dois pontos.

None

Returns:

Name Type Description
Float float

VNA publicado ou calculado por pró-rata exponencial. Retorna

float

float('nan') quando não houver pontos publicados dos dois lados da

float

data ou quando ela estiver fora do intervalo disponível.

Notes

Um ponto publicado exatamente na data tem prioridade e ignora fator_variacao. O expoente do pró-rata é truncado em catorze casas e o resultado em seis casas.

Raises:

Type Description
ValueError

Se o VNA-base não for positivo ou a variação for menor ou igual a -100%.

Source code in pyield/vna/_calculo.py
def calcular_vna(
    df: pl.DataFrame,
    data: dt.date,
    *,
    fator_variacao: float | None = None,
) -> float:
    """Obtém o VNA publicado ou calcula o pró-rata entre pontos publicados.

    Args:
        df: DataFrame com as colunas ``data`` (Date) e ``vna`` (Float64),
            contendo no máximo um ponto publicado por data.
        data: Data para a qual o VNA será obtido ou interpolado.
        fator_variacao: Fator multiplicativo entre o ponto inicial e o final.
            Se omitido, é calculado pela razão entre os VNAs dos dois pontos.

    Returns:
        Float: VNA publicado ou calculado por pró-rata exponencial. Retorna
        ``float('nan')`` quando não houver pontos publicados dos dois lados da
        data ou quando ela estiver fora do intervalo disponível.

    Notes:
        Um ponto publicado exatamente na data tem prioridade e ignora
        ``fator_variacao``. O expoente do pró-rata é truncado em catorze casas
        e o resultado em seis casas.

    Raises:
        ValueError: Se o VNA-base não for positivo ou a variação for menor ou
            igual a -100%.
    """
    ponto_exato = df.filter(pl.col("data") == data)
    if ponto_exato.height == 1:
        return float(ponto_exato.item(0, "vna"))

    ponto_inicial = df.filter(pl.col("data") < data).sort("data").tail(1)
    ponto_final = df.filter(pl.col("data") > data).sort("data").head(1)
    if ponto_inicial.is_empty() or ponto_final.is_empty():
        return float("nan")

    data_inicial = ponto_inicial.item(0, "data")
    data_final = ponto_final.item(0, "data")
    vna_inicial = float(ponto_inicial.item(0, "vna"))
    vna_final = float(ponto_final.item(0, "vna"))
    expoente = truncar(
        (data - data_inicial).days / (data_final - data_inicial).days,
        14,
    )
    if fator_variacao is None:
        fator_variacao = vna_final / vna_inicial
    variacao = fator_variacao - 1
    return _aplicar_variacao_pro_rata(vna_inicial, variacao, expoente)

historico(titulo, vencimento=None, *, atualizar=False)

Busca os VNAs mensais publicados pelo Tesouro Nacional.

Parameters:

Name Type Description Default
titulo TipoTitulo

NTN-B ou NTN-C. Histórico de LFT não está disponível.

required
vencimento DateLike | None

Filtro opcional de série para NTN-C. Se omitido, retorna todas as séries. Não se aplica à NTN-B.

None
atualizar bool

Se True, baixa novamente o arquivo de VNA e renova seu cache de 60 segundos. Não atualiza o cache dos índices do IPCA.

False

Returns:

Type Description
DataFrame

DataFrame Polars ordenado por data. Sem série correspondente ao vencimento, retorna DataFrame vazio com o mesmo schema.

Output Columns
  • data (Date): Data de referência publicada.
  • vna (Float64): Valor nominal atualizado publicado.
  • anos_vencimento (List[Int64]): Apenas NTN-C; anos da série.
Notes

Fonte: planilhas de Valor Nominal de NTN-B e NTN-C do Tesouro Transparente. Preserva o schema das consultas específicas por título.

Raises:

Type Description
ValueError

Se o título não for NTN-B ou NTN-C, ou se houver filtro de vencimento para NTN-B.

Source code in pyield/vna/_consulta.py
def historico(
    titulo: TipoTitulo,
    vencimento: DateLike | None = None,
    *,
    atualizar: bool = False,
) -> pl.DataFrame:
    """Busca os VNAs mensais publicados pelo Tesouro Nacional.

    Args:
        titulo: NTN-B ou NTN-C. Histórico de LFT não está disponível.
        vencimento: Filtro opcional de série para NTN-C. Se omitido, retorna
            todas as séries. Não se aplica à NTN-B.
        atualizar: Se True, baixa novamente o arquivo de VNA e renova seu
            cache de 60 segundos. Não atualiza o cache dos índices do IPCA.

    Returns:
        DataFrame Polars ordenado por data. Sem série correspondente ao
            vencimento, retorna DataFrame vazio com o mesmo schema.

    Output Columns:
        - data (Date): Data de referência publicada.
        - vna (Float64): Valor nominal atualizado publicado.
        - anos_vencimento (List[Int64]): Apenas NTN-C; anos da série.

    Notes:
        Fonte: planilhas de Valor Nominal de NTN-B e NTN-C do Tesouro
        Transparente. Preserva o schema das consultas específicas por título.

    Raises:
        ValueError: Se o título não for NTN-B ou NTN-C, ou se houver filtro
            de vencimento para NTN-B.
    """
    modulo = _modulo_mensal(titulo)
    if vencimento is not None and titulo != "NTN-C":
        raise ValueError("Vencimento aplica-se apenas à NTN-C.")
    ano = None
    if vencimento is not None and not any_is_empty(vencimento):
        ano = converter_datas(vencimento).year
    df = modulo.vnas(atualizar=atualizar)
    if ano is not None:
        df = df.filter(pl.col("anos_vencimento").list.contains(ano))
    return df.sort("data")

projetado(titulo, data, vna_base, inflacao=None, *, selic=None)

Projeta o VNA do título conforme sua metodologia.

Parameters:

Name Type Description Default
titulo TipoTitulo

LFT, NTN-B ou NTN-C.

required
data DateLike

Data para a qual projetar o VNA.

required
vna_base float | Decimal

VNA-base correspondente ao início da vigência ou ao último dia útil anterior à data, conforme o título.

required
inflacao float | Decimal | None

Para NTN-B e NTN-C, variação mensal percentual; 0.45 representa 0,45%. Para LFT, taxa anual decimal, finita e maior que -1; informe-a em selic.

None
selic float | Decimal | str | None

Obrigatória apenas para LFT. Aceita taxa decimal ou percentual explícito, como "13.65%". Para reproduzir o acruamento oficial da LFT, use a taxa Selic diária publicada pelo SGS 11. Como ela é publicada em percentual, 0,050788% equivale à taxa decimal 0,00050788 e ao fator derivado 1,00050788. Converta essa taxa diária para uma taxa anual equivalente. A Selic Over do SGS 1178 é anualizada e serve apenas como aproximação. Para NTN-B e NTN-C, deve ser omitida.

None

Returns:

Name Type Description
Decimal Decimal

VNA projetado com seis casas; NaN para entradas nulas.

Notes

NTN-B e NTN-C seguem a metodologia STN: base truncada em seis casas, inflação arredondada em duas e expoente em dias corridos truncado em catorze. LFT usa dias úteis, base 252 e capitalização pela taxa anual informada. A taxa Selic diária publicada pelo SGS 11 é a referência exata para o acruamento; o fator usado no cálculo é 1 + taxa em formato decimal. A função não busca a taxa automaticamente nem faz projeções externas.

Raises:

Type Description
ValueError

Se o título for inválido, a taxa for informada para o título errado, ou houver violação dos limites da metodologia específica.

Examples:

>>> import pyield as yd
>>> yd.vna.projetado("NTN-B", "30-06-2026", 4731.856412, 0.45)
Decimal('4742.491138')
>>> yd.vna.projetado(
...     "LFT",
...     "18-09-2026",
...     19905.773236,
...     selic="13.65%",
... )
Decimal('19915.882987')
Source code in pyield/vna/_consulta.py
def projetado(
    titulo: TipoTitulo,
    data: DateLike,
    vna_base: float | Decimal,
    inflacao: float | Decimal | None = None,
    *,
    selic: float | Decimal | str | None = None,
) -> Decimal:
    """Projeta o VNA do título conforme sua metodologia.

    Args:
        titulo: LFT, NTN-B ou NTN-C.
        data: Data para a qual projetar o VNA.
        vna_base: VNA-base correspondente ao início da vigência ou ao último
            dia útil anterior à data, conforme o título.
        inflacao: Para NTN-B e NTN-C, variação mensal percentual; ``0.45``
            representa 0,45%. Para LFT, taxa anual decimal, finita e maior
            que -1; informe-a em ``selic``.
        selic: Obrigatória apenas para LFT. Aceita taxa decimal ou
            percentual explícito, como ``"13.65%"``. Para reproduzir o
            acruamento oficial da LFT, use a taxa Selic diária publicada pelo
            SGS 11. Como ela é publicada em percentual, ``0,050788%`` equivale
            à taxa decimal ``0,00050788`` e ao fator derivado ``1,00050788``.
            Converta essa taxa diária para uma taxa anual equivalente. A Selic
            Over do SGS 1178 é anualizada e serve apenas como aproximação. Para
            NTN-B e NTN-C, deve ser omitida.

    Returns:
        Decimal: VNA projetado com seis casas; NaN para entradas nulas.

    Notes:
        NTN-B e NTN-C seguem a metodologia STN: base truncada em seis casas,
        inflação arredondada em duas e expoente em dias corridos truncado em
        catorze. LFT usa dias úteis, base 252 e capitalização pela taxa anual
        informada. A taxa Selic diária publicada pelo SGS 11 é a referência
        exata para o acruamento; o fator usado no cálculo é ``1 + taxa`` em
        formato decimal. A função não busca a taxa automaticamente nem faz
        projeções externas.

    Raises:
        ValueError: Se o título for inválido, a taxa for informada para o
            título errado, ou houver violação dos limites da metodologia
            específica.

    Examples:
        >>> import pyield as yd
        >>> yd.vna.projetado("NTN-B", "30-06-2026", 4731.856412, 0.45)
        Decimal('4742.491138')
        >>> yd.vna.projetado(
        ...     "LFT",
        ...     "18-09-2026",
        ...     19905.773236,
        ...     selic="13.65%",
        ... )
        Decimal('19915.882987')
    """
    if titulo not in {"LFT", "NTN-B", "NTN-C"}:
        raise ValueError("Título deve ser LFT, NTN-B ou NTN-C.")
    if titulo == "LFT":
        if inflacao is not None:
            raise ValueError("Use selic para a projeção da LFT.")
        if selic is None:
            return Decimal("NaN")
        if any_is_empty(selic):
            return Decimal("NaN")
        data_convertida = converter_datas(data)
        if du.eh_dia_util(data_convertida):
            data_base = du.deslocar(data_convertida, -1, ajuste="anterior")
        else:
            data_base = du.deslocar(data_convertida, 0, ajuste="anterior")
        return _lft.projetado_lft(data_base, data, vna_base, selic)
    if selic is not None:
        raise ValueError("selic aplica-se apenas à projeção da LFT.")
    return _modulo_mensal(titulo).vna_projetado(data, vna_base, inflacao)

ultimo(titulo, vencimento=None, *, atualizar=False)

Busca a última referência publicada de cada série de VNA.

Parameters:

Name Type Description Default
titulo TipoTitulo

NTN-B ou NTN-C. Última publicação de LFT não está disponível.

required
vencimento DateLike | None

Filtro opcional da NTN-C. Sem filtro, retorna a última referência de cada série. Não se aplica à NTN-B.

None
atualizar bool

Se True, baixa novamente o arquivo de VNA e renova seu cache de 60 segundos. Não atualiza o cache dos índices do IPCA.

False

Returns:

Type Description
DataFrame

DataFrame Polars com data e valor da última publicação de cada série. Retorna vazio quando o histórico consultado estiver vazio.

Output Columns
  • data (Date): Data de referência da última publicação da série.
  • vna (Float64): VNA publicado nessa referência.
  • anos_vencimento (List[Int64]): Apenas NTN-C; anos da série.
Notes

Fonte: históricos do Tesouro Nacional obtidos por historico. O resultado é publicado, sem projeção até a data atual. Preserva as colunas e os tipos do histórico.

Source code in pyield/vna/_consulta.py
def ultimo(
    titulo: TipoTitulo,
    vencimento: DateLike | None = None,
    *,
    atualizar: bool = False,
) -> pl.DataFrame:
    """Busca a última referência publicada de cada série de VNA.

    Args:
        titulo: NTN-B ou NTN-C. Última publicação de LFT não está disponível.
        vencimento: Filtro opcional da NTN-C. Sem filtro, retorna a última
            referência de cada série. Não se aplica à NTN-B.
        atualizar: Se True, baixa novamente o arquivo de VNA e renova seu
            cache de 60 segundos. Não atualiza o cache dos índices do IPCA.

    Returns:
        DataFrame Polars com data e valor da última publicação de cada série.
            Retorna vazio quando o histórico consultado estiver vazio.

    Output Columns:
        - data (Date): Data de referência da última publicação da série.
        - vna (Float64): VNA publicado nessa referência.
        - anos_vencimento (List[Int64]): Apenas NTN-C; anos da série.

    Notes:
        Fonte: históricos do Tesouro Nacional obtidos por ``historico``.
        O resultado é publicado, sem projeção até a data atual. Preserva
        as colunas e os tipos do histórico.
    """
    df = historico(titulo, vencimento, atualizar=atualizar)
    if titulo == "NTN-C":
        return df.unique(subset="anos_vencimento", keep="last", maintain_order=True)
    return df.tail(1)

valor(titulo, data=None, vencimento=None, *, atualizar=False)

Consulta o VNA do título na data informada.

Parameters:

Name Type Description Default
titulo TipoTitulo

LFT, NTN-B ou NTN-C.

required
data DateLike | None

Data de referência. Se nula, retorna Decimal('NaN').

None
vencimento DateLike | None

Necessário para selecionar a série da NTN-C. Não se aplica aos demais títulos.

None
atualizar bool

Se True, baixa novamente o arquivo de VNA e renova seu cache de 60 segundos. Não atualiza o cache dos índices do IPCA.

False

Returns:

Name Type Description
Decimal Decimal

VNA com seis casas ou Decimal('NaN') na ausência de dados, conforme o contrato da consulta específica do título.

Notes

Fontes: Banco Central (arquivo diário SELIC) para LFT; Tesouro Nacional para NTN-B e NTN-C. Entre referências, NTN-B usa os números-índice do IPCA do IBGE, e NTN-C usa a razão entre os VNAs. Não realiza projeção automática. NTN-C sem vencimento retorna NaN.

Raises:

Type Description
ValueError

Se o título for inválido ou o vencimento for informado para um título diferente de NTN-C.

Source code in pyield/vna/_consulta.py
def valor(
    titulo: TipoTitulo,
    data: DateLike | None = None,
    vencimento: DateLike | None = None,
    *,
    atualizar: bool = False,
) -> Decimal:
    """Consulta o VNA do título na data informada.

    Args:
        titulo: LFT, NTN-B ou NTN-C.
        data: Data de referência. Se nula, retorna ``Decimal('NaN')``.
        vencimento: Necessário para selecionar a série da NTN-C. Não se
            aplica aos demais títulos.
        atualizar: Se True, baixa novamente o arquivo de VNA e renova seu
            cache de 60 segundos. Não atualiza o cache dos índices do IPCA.

    Returns:
        Decimal: VNA com seis casas ou ``Decimal('NaN')`` na ausência de dados,
            conforme o contrato da consulta específica do título.

    Notes:
        Fontes: Banco Central (arquivo diário SELIC) para LFT; Tesouro
        Nacional para NTN-B e NTN-C. Entre referências, NTN-B usa os
        números-índice do IPCA do IBGE, e NTN-C usa a razão entre os VNAs.
        Não realiza projeção automática. NTN-C sem vencimento retorna NaN.

    Raises:
        ValueError: Se o título for inválido ou o vencimento for informado
            para um título diferente de NTN-C.
    """
    if titulo not in {"LFT", "NTN-B", "NTN-C"}:
        raise ValueError("Título deve ser LFT, NTN-B ou NTN-C.")
    if titulo == "NTN-C":
        return _ntnc.vna(data, vencimento, atualizar=atualizar)
    if vencimento is not None:
        raise ValueError("Vencimento aplica-se apenas à NTN-C.")
    if titulo == "LFT":
        return _lft.vna(data, atualizar=atualizar)
    return _ntnb.vna(data, atualizar=atualizar)

vigencia(titulo, data)

Obtém o intervalo mensal de atualização do VNA, sem acesso à rede.

Parameters:

Name Type Description Default
titulo TipoTitulo

NTN-B ou NTN-C; LFT não possui essa vigência mensal.

required
data DateLike

Data contida na vigência.

required

Returns:

Type Description
tuple[date, date]

tuple[date, date]: Início inclusivo e fim exclusivo, sem ajuste útil. NTN-B usa dia 15 a dia 15; NTN-C usa primeiro dia a primeiro dia.

Notes

Segue os calendários de atualização do Tesouro Nacional implementados nas funções específicas de cada título.

Raises:

Type Description
ValueError

Se o título não for NTN-B ou NTN-C ou a data for inválida.

Examples:

>>> yd.vna.vigencia("NTN-B", "15-07-2026")
(datetime.date(2026, 7, 15), datetime.date(2026, 8, 15))
Source code in pyield/vna/_consulta.py
def vigencia(titulo: TipoTitulo, data: DateLike) -> tuple[dt.date, dt.date]:
    """Obtém o intervalo mensal de atualização do VNA, sem acesso à rede.

    Args:
        titulo: NTN-B ou NTN-C; LFT não possui essa vigência mensal.
        data: Data contida na vigência.

    Returns:
        tuple[date, date]: Início inclusivo e fim exclusivo, sem ajuste útil.
            NTN-B usa dia 15 a dia 15; NTN-C usa primeiro dia a primeiro dia.

    Notes:
        Segue os calendários de atualização do Tesouro Nacional implementados
        nas funções específicas de cada título.

    Raises:
        ValueError: Se o título não for NTN-B ou NTN-C ou a data for inválida.

    Examples:
        >>> yd.vna.vigencia("NTN-B", "15-07-2026")
        (datetime.date(2026, 7, 15), datetime.date(2026, 8, 15))
    """
    return _modulo_mensal(titulo).vigencia(data)

Atualização manual

As consultas valor, historico e ultimo aceitam atualizar=True:

historico = yd.vna.historico("NTN-C", vencimento="01-01-2031", atualizar=True)
ultimo = yd.vna.ultimo("NTN-B", atualizar=True)
valor = yd.vna.valor("LFT", "31-05-2024", atualizar=True)

A opção ignora e renova o cache interno de 60 segundos do arquivo de VNA. Chamadas seguintes reutilizam o download renovado. Para NTN-B e NTN-C, o cache é por planilha do título, compartilhado entre datas e séries de vencimentos; para LFT, é por data de referência. Erros de download são propagados; a entrada anterior permanece disponível somente até sua expiração original.

O padrão continua sendo atualizar=False. A opção não invalida caches da aplicação nem o cache dos índices do IPCA usados no pró-rata da NTN-B. A coluna data representa a referência do VNA, não o horário do download ou uma nova publicação. Um novo download pode retornar os mesmos dados.