Pular para conteúdo

Interpolador

Classe interpoladora para interpolação de taxas de juros.

Parameters:

Name Type Description Default
dias_uteis ArrayLike

Sequência de dias úteis (DU) conhecidos.

required
taxas ArrayLike

Sequência de taxas de juros conhecidas.

required
metodo Literal['flat_forward', 'linear']

Método de interpolação a usar. Opções: "flat_forward" ou "linear".

required
extrapolar bool

Controla apenas o comportamento na ponta longa (DU acima do maior vértice conhecido). Se True, retorna a última taxa conhecida; se False (padrão), retorna NaN. A ponta curta (DU abaixo do menor vértice) sempre retorna a primeira taxa conhecida, independentemente desta flag.

False
Notes
  • Esta classe usa convenção de 252 dias úteis por ano.
  • Instâncias desta classe são imutáveis. Para modificar as configurações de interpolação, crie uma nova instância.

Examples:

>>> from pyield import Interpolador
>>> dus = [30, 60, 90]
>>> txs = [0.045, 0.05, 0.055]

Interpolação linear:

>>> linear = Interpolador(dus, txs, "linear")
>>> linear(45)
0.0475

Interpolação flat forward:

>>> fforward = Interpolador(dus, txs, "flat_forward")
>>> fforward(45)
0.04833068080970859
>>> print(fforward(100))  # Extrapolação desabilitada por padrão
nan
>>> print(fforward(-10))  # Entrada inválida retorna NaN
nan

Se extrapolação estiver habilitada, a última taxa conhecida é usada:

>>> fforward_extrap = Interpolador(dus, txs, "flat_forward", extrapolar=True)
>>> print(fforward_extrap(100))
0.055
Source code in pyield/interpolador.py
def __init__(
    self,
    dias_uteis: ArrayLike,
    taxas: ArrayLike,
    metodo: Literal["flat_forward", "linear"],
    extrapolar: bool = False,
):
    df = (
        pl.DataFrame({"dus": dias_uteis, "txs": taxas})
        .with_columns(pl.col("dus").cast(pl.Int64))
        .with_columns(pl.col("txs").cast(pl.Float64))
        .drop_nulls()
        .drop_nans()
        .unique(subset="dus", keep="last")
        .sort("dus")
    )
    self._df = df
    self._method = str(metodo)
    self._dus = tuple(df.get_column("dus"))
    self._txs = tuple(df.get_column("txs"))
    self._extrapolate = bool(extrapolar)

linear(du, k)

Realiza interpolação de taxa de juros usando o método linear.

A taxa interpolada é dada pela fórmula: y = y1 + (x - x1) * (y2 - y1) / (x2 - x1)

Onde: - (x, y) é o ponto a ser interpolado (du, tx_interpolada). - (x1, y1) é o ponto conhecido anterior (du_j, tx_j). - (x2, y2) é o próximo ponto conhecido (du_k, tx_k).

Parameters:

Name Type Description Default
du int

Número de dias úteis (DU) para os quais a taxa será interpolada.

required
k int

O índice tal que dus[k-1] < du < dus[k].

required

Returns:

Type Description
float

Taxa de juros interpolada em forma decimal.

Source code in pyield/interpolador.py
def linear(self, du: int, k: int) -> float:
    """Realiza interpolação de taxa de juros usando o método linear.

    A taxa interpolada é dada pela fórmula:
    y = y1 + (x - x1) * (y2 - y1) / (x2 - x1)

    Onde:
    - (x, y) é o ponto a ser interpolado (du, tx_interpolada).
    - (x1, y1) é o ponto conhecido anterior (du_j, tx_j).
    - (x2, y2) é o próximo ponto conhecido (du_k, tx_k).

    Args:
        du: Número de dias úteis (DU) para os quais a taxa será interpolada.
        k: O índice tal que dus[k-1] < du < dus[k].

    Returns:
        Taxa de juros interpolada em forma decimal.
    """
    # Obtém os pontos imediatamente anterior e posterior ao DU desejado.
    du_j, tx_j = self._dus[k - 1], self._txs[k - 1]
    du_k, tx_k = self._dus[k], self._txs[k]

    return tx_j + (du - du_j) * (tx_k - tx_j) / (du_k - du_j)

flat_forward(du, k)

Realiza interpolação de taxa de juros usando o método flat forward.

Este método calcula a taxa de juros interpolada para um dado número de dias úteis (du) usando a metodologia flat forward, baseada em dois pontos conhecidos: o ponto atual (k) e o ponto anterior (j).

Assumindo taxas de juros em forma decimal, a taxa interpolada é calculada. O tempo é medido em anos baseado em 252 dias úteis por ano.

Definindo os fatores simples: - fⱼ = 1 + txⱼ - fₖ = 1 + txₖ

A taxa interpolada é dada pela fórmula:

\[ \left(F_j*\left(\frac{F_k}{F_j}\right)^{f_t}\right)^{\frac{1}{au}}-1 \]

Onde os fatores usados na fórmula são definidos como: - Fⱼ = fⱼ^auⱼ é o fator acumulado no ponto j. - Fₖ = fₖ^auₖ é o fator acumulado no ponto k. - fₜ = (au - auⱼ)/(auₖ - auⱼ) é o fator de tempo.

E as variáveis são definidas como: - au = du/252 é o tempo em anos para o ponto interpolado. du é o número de dias úteis para o ponto interpolado (entrada deste método). - k é o índice do ponto conhecido atual. - auₖ = duₖ/252 é o tempo em anos do ponto k. - txₖ é a taxa de juros (decimal) no ponto k. - j é o índice do ponto conhecido anterior (k - 1). - auⱼ = duⱼ/252 é o tempo em anos do ponto j. - txⱼ é a taxa de juros (decimal) no ponto j.

Parameters:

Name Type Description Default
du int

Número de dias úteis (DU) para os quais a taxa será interpolada.

required
k int

Índice tal que dus[k-1] < du < dus[k]. Esse k corresponde ao próximo vértice conhecido após du.

required

Returns:

Type Description
float

Taxa de juros interpolada em forma decimal.

Source code in pyield/interpolador.py
def flat_forward(self, du: int, k: int) -> float:
    r"""Realiza interpolação de taxa de juros usando o método flat forward.

    Este método calcula a taxa de juros interpolada para um dado número de
    dias úteis (``du``) usando a metodologia flat forward, baseada em dois
    pontos conhecidos: o ponto atual (``k``) e o ponto anterior (``j``).

    Assumindo taxas de juros em forma decimal, a taxa interpolada é calculada.
    O tempo é medido em anos baseado em 252 dias úteis por ano.

    Definindo os fatores simples:
    - ``fⱼ = 1 + txⱼ``
    - ``fₖ = 1 + txₖ``

    A taxa interpolada é dada pela fórmula:

    \[
    \left(F_j*\left(\frac{F_k}{F_j}\right)^{f_t}\right)^{\frac{1}{au}}-1
    \]

    Onde os fatores usados na fórmula são definidos como:
    - ``Fⱼ = fⱼ^auⱼ`` é o fator acumulado no ponto ``j``.
    - ``Fₖ = fₖ^auₖ`` é o fator acumulado no ponto ``k``.
    - ``fₜ = (au - auⱼ)/(auₖ - auⱼ)`` é o fator de tempo.

    E as variáveis são definidas como:
    - ``au = du/252`` é o tempo em anos para o ponto interpolado. ``du``
      é o número de dias úteis para o ponto interpolado (entrada deste método).
    - ``k`` é o índice do ponto conhecido atual.
    - ``auₖ = duₖ/252`` é o tempo em anos do ponto ``k``.
    - ``txₖ`` é a taxa de juros (decimal) no ponto ``k``.
    - ``j`` é o índice do ponto conhecido anterior (``k - 1``).
    - ``auⱼ = duⱼ/252`` é o tempo em anos do ponto ``j``.
    - ``txⱼ`` é a taxa de juros (decimal) no ponto ``j``.

    Args:
        du: Número de dias úteis (DU) para os quais a taxa será interpolada.
        k: Índice tal que ``dus[k-1] < du < dus[k]``. Esse ``k``
            corresponde ao próximo vértice conhecido após ``du``.

    Returns:
        Taxa de juros interpolada em forma decimal.
    """
    tx_j = self._txs[k - 1]
    au_j = self._dus[k - 1] / 252
    tx_k = self._txs[k]
    au_k = self._dus[k] / 252
    au = du / 252

    # Siglas: fs = fator simples; fa = fator acumulado; ft = fator de tempo.
    fs_j = 1 + tx_j
    fs_k = 1 + tx_k
    fa_j = fs_j**au_j
    fa_k = fs_k**au_k
    ft = (au - au_j) / (au_k - au_j)
    return (fa_j * (fa_k / fa_j) ** ft) ** (1 / au) - 1

interpolar(du)

Interpola a taxa para um único dia útil.

Parameters:

Name Type Description Default
du int

DU escalar inteiro para interpolação.

required

Returns:

Type Description
float

Taxa interpolada como float. Retorna float("nan") quando o DU

float

for negativo ou estiver acima do maior vértice conhecido com

float

extrapolar=False. DU abaixo do menor vértice sempre retorna

float

a primeira taxa conhecida.

Raises:

Type Description
TypeError

Se du não for um inteiro.

Source code in pyield/interpolador.py
def interpolar(self, du: int) -> float:
    """Interpola a taxa para um único dia útil.

    Args:
        du: DU escalar inteiro para interpolação.

    Returns:
        Taxa interpolada como float. Retorna ``float("nan")`` quando o DU
        for negativo ou estiver acima do maior vértice conhecido com
        ``extrapolar=False``. DU abaixo do menor vértice sempre retorna
        a primeira taxa conhecida.

    Raises:
        TypeError: Se ``du`` não for um inteiro.
    """
    # Aceita qualquer tipo integral (int, np.int64, etc) e rejeita float/string.
    if not isinstance(du, numbers.Integral):
        raise TypeError("du deve ser int. Use interpolar_expr para coluna Polars.")
    return self._taxa_interpolada(int(du))