Uma taxa por prazo
Até aqui um único rendimento descontava todos os pagamentos de um título. Na realidade o dinheiro emprestado por 6 meses, 2 anos e 10 anos rende taxas diferentes, e o padrão pelos prazos é a curva de juros. Uma taxa zero é a taxa anual de um único pagamento em uma data dada, sem cupons intermediários. Em geral a curva sobe com o prazo (os investidores querem mais para esperar mais), mas pode ser plana ou invertida, quando as taxas curtas superam as longas, o que os mercados leem como um alerta sobre o crescimento.
import numpy as np
maturities = np.array([0.5, 1, 2, 5, 10, 30]) # years where the market quotes a rate
rates = np.array([0.040, 0.042, 0.045, 0.048, 0.050, 0.052]) # an upward-sloping curve
# The rate at 3 years is not quoted: interpolate linearly between 2 years (4.5%) and 5 years (4.8%)
print(float(np.interp(3, maturities, rates))) # 0.046
print(np.interp([0.25, 7, 40], maturities, rates).tolist()) # [0.04, 0.0488, 0.052] flat outside the quoted rangeFatores de desconto e taxa a termo
Uma taxa zero r para o prazo t dá o fator de desconto (1 + r) ** -t: quanto vale hoje uma unidade paga em t. A curva também esconde expectativas. Emprestar por 2 anos a 4,5% deve igualar emprestar por 1 ano a 4,2% e depois emprestar de novo por um ano a uma taxa combinada f: (1 + 4,5%)² = (1 + 4,2%)(1 + f), logo f = 4,80%. Essa taxa a termo é a taxa de equilíbrio do segundo ano, fixada hoje. Em geral f = ((1 + r2) ** t2 / (1 + r1) ** t1) ** (1 / (t2 - t1)) - 1.
def discount_factor(rate, t):
return (1 + rate) ** -t
print(round(float(discount_factor(0.045, 2)), 5)) # 0.91573 one unit paid in 2 years
r1, t1, r2, t2 = 0.042, 1, 0.045, 2
forward = ((1 + r2) ** t2 / (1 + r1) ** t1) ** (1 / (t2 - t1)) - 1
print(round(forward, 5)) # 0.04801 the rate for year 2, implied by the curve
print(round((1 + r1) ** t1 * (1 + forward) ** (t2 - t1), 5), round((1 + r2) ** t2, 5)) # 1.09 1.09 both routes agreePrecificar na curva inteira
Precificar com um único rendimento trata igualmente um pagamento de 1 ano e um de 10 anos. A abordagem pela curva é mais fiel: para cada pagamento leia a taxa zero da sua própria data (interpolando se preciso), transforme-a em fator de desconto e some fluxo * fator. Dois títulos com os mesmos fluxos devem ter o mesmo preço quaisquer que sejam seus rendimentos cotados, e é assim que os bancos marcam títulos a mercado. Para um título de 3 anos a 5% em nossa curva o preço é 1011,25, contra 1010,98 com 4,6% plano: próximo aqui porque a curva é suave, mas títulos diferentes reagem de formas diferentes quando a curva se torce.
times = np.array([1.0, 2.0, 3.0])
flows = np.array([50.0, 50.0, 1050.0]) # a 3-year 5% bond with annual coupons
zero = np.interp(times, maturities, rates)
print(zero.tolist()) # [0.042, 0.045, 0.046]
print((discount_factor(zero, times)).round(5).tolist()) # [0.95969, 0.91573, 0.87379]
print(round(float((flows * discount_factor(zero, times)).sum()), 4)) # 1011.2462 on the curve
print(round(float((flows / 1.046 ** times).sum()), 4)) # 1010.9752 with one flat 4.6% instead# The forward rates between the quoted maturities, in one array expression
t = np.array([1.0, 2.0, 5.0])
r = np.array([0.042, 0.045, 0.048])
forwards = ((1 + r[1:]) ** t[1:] / (1 + r[:-1]) ** t[:-1]) ** (1 / np.diff(t)) - 1
print(forwards.round(5).tolist()) # [0.04801, 0.05] year 2 and years 3 to 5: an upward-sloping curve implies rising forwardsnp.interp mantém a taxa plana, o que é uma convenção, não um fato. Declare o método sempre que publicar uma curva.- Uma curva de juros é a taxa zero por prazo; leia prazos ausentes por interpolação (
np.interp, plana fora do intervalo). - Fator de desconto
(1 + r) ** -t; taxa a termo((1 + r2) ** t2 / (1 + r1) ** t1) ** (1 / (t2 - t1)) - 1. - Preço = soma de
fluxo * fator de desconto, cada fluxo à taxa zero da sua data; declare o método de interpolação.
A seguir: os pagamentos das opções, o que uma call ou uma put paga no vencimento, ponto de partida da precificação de opções.
Lab: o que é avaliado
- Ler uma taxa entre os prazos cotados com
interpolate_rate25 pts - Transformar uma taxa em fator de desconto com
discount_factor25 pts - Ler a taxa futura escondida na curva com
forward_rate25 pts - Precificar um fluxo de pagamentos em toda a curva com
price_on_curve25 pts