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

Se True, extrapola além dos dias úteis conhecidos usando a última taxa disponível. Padrão: False, retornando NaN para valores fora do intervalo.

False

Raises:

Type Description
ValueError

Se dias_uteis e taxas não tiverem o mesmo tamanho.

ValueError

Se o método de interpolação não for reconhecido.

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

Interpolação de array (polars mostra 6 casas decimais por padrão):

>>> fforward([15, 45, 75, 100])
shape: (4,)
Series: 'taxa_interpolada' [f64]
[
    0.045
    0.048331
    0.052997
    null
]
>>> 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 taxas para dia(s) útil(eis) fornecido(s).

Parameters:

Name Type Description Default
du int | ArrayLike

DU(s) para interpolação. Aceita int ou ArrayLike.

required

Returns:

Type Description
float | Series

Taxa(s) interpolada(s). Float para entrada escalar, pl.Series para array.

Source code in pyield/interpolador.py
def interpolar(self, du: int | ArrayLike) -> float | pl.Series:
    """Interpola taxas para dia(s) útil(eis) fornecido(s).

    Args:
        du: DU(s) para interpolação. Aceita int ou ArrayLike.

    Returns:
        Taxa(s) interpolada(s). Float para entrada escalar, pl.Series para array.
    """
    if is_collection(du):
        s_dus = pl.Series(name="taxa_interpolada", values=du, dtype=pl.Int64)
        result = s_dus.map_elements(self._taxa_interpolada, return_dtype=pl.Float64)
        return result.fill_nan(None)

    # Aceita qualquer tipo integral (int, np.int64, etc) e rejeita float/string.
    elif isinstance(du, numbers.Integral):
        return self._taxa_interpolada(int(du))

    else:
        raise TypeError("du deve ser int ou uma estrutura array-like.")