[Python] Construção de um interpolador simples

O conceito de interpolação, amplamente difundido, pode ser interpretado no mundo de finanças como o método utilizado para definição de uma taxa intermediária entre dois vértices de vencimento já conhecidos em uma curva de juros.

Um simples exemplo:

Para a curva PRÉ-DI do dia 13/04/2020, 2 pontos escolhidos ao acaso são:

Elaboração: Milton Rocha

Um banco ao cotar uma operação em du252, deveria cobrar qual taxa para os prazos [400,401,…,419]?

Visto que o padrão de interpolação da curva PRÉ-DI é Exponencial Flat Forward, o gráfico destas taxas intermediárias é apresentado:

http://www.b3.com.br/data/files/F4/93/B2/F5/9652D6100C22BFC6AC094EA8/Manual%20de%20Metodologia%20de%20Marcacao%20a%20Mercado.pdf – Página 9
Elaboração: Milton Rocha
Elaboração: Milton Rocha

Como fazer um código simples que consiga interpretar em que local o ponto de interpolação se encontra dentre os vértices disponíveis da curva e que consiga achar o ponto anterior e o posterior para uso nas mais diversas fórmulas de interpolação?

class interpolador:
    def __init__(self, p, df, column, dc=252):
        self.df = df
        self.column = column
        self.p = p
        self.dc = dc
        self.x_axis = list(df.index)
        self.y_axis = list(df[column])
        self._config(self.p)
    
    def _config(self, p):
        """
        Função que configura o objeto para definir o ponto anterior e posterior para interpolar
        """
        self.x1 = min(self.df.index, key=lambda a:abs(a-p))
        if p-self.x1>0: self.x2 = self.x_axis[self.x_axis.index(self.x1)+1]
        elif p-self.x1==0: self.x2 = self.x1
        elif p-self.x1<0:
            self.x2 = self.x1
            self.x1 = self.x_axis[self.x_axis.index(self.x1)-1]
        self.y1 = self.y_axis[self.x_axis.index(self.x1)]
        self.y2 = self.y_axis[self.x_axis.index(self.x2)]

A função “_config” é responsável por achar os números mais próximos do ponto, sendo o número de limite superior determinado pelo valor da distância encontrada através da função lambda onde a é cada ponto do DataFrame e p é o ponto desejado de interpolação.

Depois de encontrar os pontos o próximo passo é colocá-los na equação apresentada:

def exp(self):
    """
    Função de interpolação exponencial flat forward
    """
    x1,x2,y1,y2,p,dc = self.x1, self.x2, self.y1, self.y2, self.p, self.dc
    if x1-x2!=0:
        return ((((1+y1)**(x1/dc))*(((1+y2)**(x2/dc))/((1+y1)**(x1/dc)))**((p-x1)/(x2-x1)))**(dc/p))-1
    else:
        return y1

Como bônus deixo o código de interpolação linear e o que interpola um vetor de períodos passado:

def lin(self):
    """
    Função de interpolação linear nas taxas
    """
    x1,x2,y1,y2,p = self.x1, self.x2, self.y1, self.y2, self.p
    if x1-x2!=0:
        return y1+(p-x1)*(y2-y1)/(x2-x1)
    else:
        return y1

def multi_intp(self, arr=[], t='exp'):
    interpolados=[]
    for x in range(len(arr)):
        self.p = arr[x]
        self._config(arr[x])
        if t.lower()=='exp': interpolados.append(self.exp())
        elif t.lower()=='lin': interpolados.append(self.lin())
    return interpolados

-M.R.

Deixe um comentário

Crie um site como este com o WordPress.com
Comece agora