Pular para conteúdo

PRE

di_spreads(date, bps=False)

Calcula o DI Spread para títulos prefixados (LTN e NTN-F) em uma data de referência.

spread = taxa indicativa do PRE - taxa de ajuste do DI

Quando bps=False a coluna retorna essa diferença em formato decimal (ex: 0.000439 ≈ 4.39 bps). Quando bps=True o valor é automaticamente multiplicado por 10_000 e exibido diretamente em basis points.

Parameters:

Name Type Description Default
date DateLike

Data de referência para buscar as taxas.

required
bps bool

Se True, retorna spread_di já convertido em basis points. Padrão False.

False

Returns:

Type Description
DataFrame

pl.DataFrame: DataFrame com as colunas do spread.

Output Columns
  • titulo (String): Tipo do título.
  • data_vencimento (Date): Data de vencimento.
  • spread_di (Float64): Spread em decimal ou bps conforme parâmetro (também conhecido como prêmio).

Examples:

>>> from pyield import pre
>>> pre.di_spreads("30-05-2025", bps=True)
shape: (18, 3)
┌────────┬─────────────────┬───────────┐
│ titulo ┆ data_vencimento ┆ spread_di │
│ ---    ┆ ---             ┆ ---       │
│ str    ┆ date            ┆ f64       │
╞════════╪═════════════════╪═══════════╡
│ LTN    ┆ 2025-07-01      ┆ 4.39      │
│ LTN    ┆ 2025-10-01      ┆ -9.0      │
│ LTN    ┆ 2026-01-01      ┆ -4.88     │
│ LTN    ┆ 2026-04-01      ┆ -4.45     │
│ LTN    ┆ 2026-07-01      ┆ 0.81      │
│ …      ┆ …               ┆ …         │
│ NTN-F  ┆ 2027-01-01      ┆ -3.31     │
│ NTN-F  ┆ 2029-01-01      ┆ 14.21     │
│ NTN-F  ┆ 2031-01-01      ┆ 21.61     │
│ NTN-F  ┆ 2033-01-01      ┆ 11.51     │
│ NTN-F  ┆ 2035-01-01      ┆ 22.0      │
└────────┴─────────────────┴───────────┘
Source code in pyield/tn/pre.py
def di_spreads(date: DateLike, bps: bool = False) -> pl.DataFrame:
    """
    Calcula o DI Spread para títulos prefixados (LTN e NTN-F) em uma data de referência.

    spread = taxa indicativa do PRE - taxa de ajuste do DI

    Quando ``bps=False`` a coluna retorna essa diferença em formato decimal
    (ex: 0.000439 ≈ 4.39 bps). Quando ``bps=True`` o valor é automaticamente
    multiplicado por 10_000 e exibido diretamente em basis points.

    Args:
        date (DateLike): Data de referência para buscar as taxas.
        bps (bool): Se True, retorna spread_di já convertido em basis points.
            Padrão False.

    Returns:
        pl.DataFrame: DataFrame com as colunas do spread.

    Output Columns:
        - titulo (String): Tipo do título.
        - data_vencimento (Date): Data de vencimento.
        - spread_di (Float64): Spread em decimal ou bps conforme parâmetro
            (também conhecido como prêmio).

    Examples:
        >>> from pyield import pre
        >>> pre.di_spreads("30-05-2025", bps=True)
        shape: (18, 3)
        ┌────────┬─────────────────┬───────────┐
        │ titulo ┆ data_vencimento ┆ spread_di │
        │ ---    ┆ ---             ┆ ---       │
        │ str    ┆ date            ┆ f64       │
        ╞════════╪═════════════════╪═══════════╡
        │ LTN    ┆ 2025-07-01      ┆ 4.39      │
        │ LTN    ┆ 2025-10-01      ┆ -9.0      │
        │ LTN    ┆ 2026-01-01      ┆ -4.88     │
        │ LTN    ┆ 2026-04-01      ┆ -4.45     │
        │ LTN    ┆ 2026-07-01      ┆ 0.81      │
        │ …      ┆ …               ┆ …         │
        │ NTN-F  ┆ 2027-01-01      ┆ -3.31     │
        │ NTN-F  ┆ 2029-01-01      ┆ 14.21     │
        │ NTN-F  ┆ 2031-01-01      ┆ 21.61     │
        │ NTN-F  ┆ 2033-01-01      ┆ 11.51     │
        │ NTN-F  ┆ 2035-01-01      ┆ 22.0      │
        └────────┴─────────────────┴───────────┘
    """
    # Busca taxas dos títulos (LTN e NTN-F) e adiciona taxa_di
    df = utils.obter_tpf(date, "PRE").select(
        "titulo", "data_vencimento", "taxa_indicativa"
    )
    if df.is_empty():
        return df.select(
            pl.lit("").alias("titulo"),
            pl.lit(None, dtype=pl.Date).alias("data_vencimento"),
            pl.lit(None, dtype=pl.Float64).alias("spread_di"),
        ).clear()
    data_ref = cv.converter_datas(date)
    df = utils.adicionar_taxa_di(df, data_ref)
    df = (
        df.with_columns(spread_di=pl.col("taxa_indicativa") - pl.col("taxa_di"))
        .select("titulo", "data_vencimento", "spread_di")
        .sort("titulo", "data_vencimento")
    )

    if bps:
        df = df.with_columns(pl.col("spread_di") * 10_000)

    return df

spot_rates(date)

Cria a curva PRE (taxas zero cupom) para títulos prefixados brasileiros.

Combina taxas de LTN (já zero cupom) com taxas spot derivadas de NTN-F via bootstrap.

Parameters:

Name Type Description Default
date DateLike

Data de referência para a consulta.

required

Returns:

Type Description
DataFrame

pl.DataFrame: DataFrame com as colunas da curva PRE.

Output Columns
  • data_vencimento (Date): Data de vencimento.
  • dias_uteis (Int64): Dias úteis entre referência e vencimento.
  • taxa_zero (Float64): Taxa zero (zero cupom).

Raises:

Type Description
ValueError

Se algum vencimento não puder ser processado.

Examples:

>>> from pyield import pre
>>> pre.spot_rates("18-06-2025")
shape: (17, 3)
┌─────────────────┬────────────┬───────────┐
│ data_vencimento ┆ dias_uteis ┆ taxa_zero │
│ ---             ┆ ---        ┆ ---       │
│ date            ┆ i64        ┆ f64       │
╞═════════════════╪════════════╪═══════════╡
│ 2025-07-01      ┆ 8          ┆ 0.14835   │
│ 2025-10-01      ┆ 74         ┆ 0.147463  │
│ 2026-01-01      ┆ 138        ┆ 0.147752  │
│ 2026-04-01      ┆ 199        ┆ 0.147947  │
│ 2026-07-01      ┆ 260        ┆ 0.147069  │
│ …               ┆ …          ┆ …         │
│ 2030-01-01      ┆ 1135       ┆ 0.137279  │
│ 2031-01-01      ┆ 1387       ┆ 0.138154  │
│ 2032-01-01      ┆ 1639       ┆ 0.13876   │
│ 2033-01-01      ┆ 1891       ┆ 0.1393    │
│ 2035-01-01      ┆ 2390       ┆ 0.141068  │
└─────────────────┴────────────┴───────────┘
Source code in pyield/tn/pre.py
def spot_rates(date: DateLike) -> pl.DataFrame:
    """
    Cria a curva PRE (taxas zero cupom) para títulos prefixados brasileiros.

    Combina taxas de LTN (já zero cupom) com taxas spot derivadas de NTN-F
    via bootstrap.

    Args:
        date (DateLike): Data de referência para a consulta.

    Returns:
        pl.DataFrame: DataFrame com as colunas da curva PRE.

    Output Columns:
        - data_vencimento (Date): Data de vencimento.
        - dias_uteis (Int64): Dias úteis entre referência e vencimento.
        - taxa_zero (Float64): Taxa zero (zero cupom).

    Raises:
        ValueError: Se algum vencimento não puder ser processado.

    Examples:
        >>> from pyield import pre
        >>> pre.spot_rates("18-06-2025")
        shape: (17, 3)
        ┌─────────────────┬────────────┬───────────┐
        │ data_vencimento ┆ dias_uteis ┆ taxa_zero │
        │ ---             ┆ ---        ┆ ---       │
        │ date            ┆ i64        ┆ f64       │
        ╞═════════════════╪════════════╪═══════════╡
        │ 2025-07-01      ┆ 8          ┆ 0.14835   │
        │ 2025-10-01      ┆ 74         ┆ 0.147463  │
        │ 2026-01-01      ┆ 138        ┆ 0.147752  │
        │ 2026-04-01      ┆ 199        ┆ 0.147947  │
        │ 2026-07-01      ┆ 260        ┆ 0.147069  │
        │ …               ┆ …          ┆ …         │
        │ 2030-01-01      ┆ 1135       ┆ 0.137279  │
        │ 2031-01-01      ┆ 1387       ┆ 0.138154  │
        │ 2032-01-01      ┆ 1639       ┆ 0.13876   │
        │ 2033-01-01      ┆ 1891       ┆ 0.1393    │
        │ 2035-01-01      ┆ 2390       ┆ 0.141068  │
        └─────────────────┴────────────┴───────────┘
    """
    # Busca dados de LTN (zero cupom)
    df_ltn = utils.obter_tpf(date, "LTN").select("data_vencimento", "taxa_indicativa")

    # Busca dados de NTN-F (com cupom)
    df_ntnf = utils.obter_tpf(date, "NTN-F").select(
        "data_vencimento", "taxa_indicativa"
    )

    # Verifica se há dados para ambos os tipos
    if df_ltn.is_empty() and df_ntnf.is_empty():
        return pl.DataFrame(
            schema={
                "data_vencimento": pl.Date,
                "dias_uteis": pl.Int64,
                "taxa_zero": pl.Float64,
            }
        )

    # Se só há NTN-F, não é possível fazer bootstrap sem LTN
    if df_ltn.is_empty():
        raise ValueError(
            "Não é possível construir a curva PRE sem taxas de LTN para bootstrap"
        )

    # Se só há LTN, retorna direto (LTN já são zero cupom)
    if df_ntnf.is_empty():
        df = _processar_ltn_adicionais(date, df_ltn)
    else:
        # Usa spot_rates de NTN-F para calcular zero cupom
        df_spots = ntnf.spot_rates(
            settlement=date,
            ltn_maturities=df_ltn["data_vencimento"],
            ltn_rates=df_ltn["taxa_indicativa"],
            ntnf_maturities=df_ntnf["data_vencimento"],
            ntnf_rates=df_ntnf["taxa_indicativa"],
            show_coupons=False,
        )

        # Encontra vencimentos de LTN que não estão no resultado de NTN-F
        ltn_mask = ~df_ltn["data_vencimento"].is_in(df_spots["data_vencimento"].to_list())
        ltn_not_in_ntnf = df_ltn.filter(ltn_mask)

        if not ltn_not_in_ntnf.is_empty():
            # Processa vencimentos de LTN adicionais
            ltn_subset = _processar_ltn_adicionais(date, ltn_not_in_ntnf)

            # Combina LTN e NTN-F
            df = pl.concat([df_spots, ltn_subset])
        else:
            df = df_spots

    # Validação final
    _validar_resultado_final(df)

    # Ordena por vencimento
    return df.sort("data_vencimento")