3 votos

Modelo Negro y Normal para Caplet usando Python

Soy capaz de Price Caplet utilizando el modelo Black 76 en Python. Sin embargo, no puedo calcular el mismo precio con el modelo normal. ¿Alguien puede sugerir lo que falta?

Estoy valorando caplet que limita el tipo de interés de un préstamo de 10000 al 8% anual trimestral compuesto durante tres meses a partir de un año.

La curva cero es plana, del 6,9394% anual. La volatilidad a un año es del 20% anual.

Además, si usted puede sugerir el mejor lugar para ver la práctica SABR modelo de aplicación utilizando python que sería genial.

Código para el negro en Python:

from scipy.stats import norm
import math

def black(F_0,y,expiry,vol,rfr,expiry_1,isCall):
    option_value = 0
    if expiry * vol == 0.0:
        if isCall:
            option_value = max(F_0 - y, 0.0)
        else:
            option_value = max(y - F_0 , 0.0)
    else:
        d1 = dPlusBlack(F_0 = F_0 , y = y, expiry = expiry ,vol = vol)
        d2 = dMinusBlack(F_0 = F_0 , y = y, expiry = expiry ,vol = vol)
        if isCall:
             option_value = (math.exp((-rfr)*expiry_1))*(F_0 * norm.cdf(d1) - y *norm.cdf(d2))
        else:
             option_value = (math.exp((-rfr)*expiry_1))*(y * norm.cdf(-d2) - F_0 *norm.cdf(-d1))
    return option_value
def dPlusBlack(F_0 , y, expiry , vol):
    d_plus = ((math.log(F_0 / y) + 0.5 * vol * vol * expiry)/ vol / math.sqrt(expiry))
    return d_plus
def dMinusBlack(F_0 , y, expiry , vol):
    d_minus = (dPlusBlack(F_0 = F_0 , y = y, expiry = expiry ,vol = vol ) - vol * math.sqrt(expiry))
    return d_minus
a = black(0.07,0.08,1,0.20,0.069394,1.25,"isCall")
a = 0.0020646470930435683

Código para bachelier

from scipy.stats import norm
import math

def bachelier(F_0,y,expiry,vol,rfr,expiry_1,isCall):
    option_value = 0
    if expiry * vol == 0.0:
        if isCall:
            option_value = max(F_0 - y, 0.0)
        else:
            option_value = max(y - F_0 , 0.0)
    else:
        d1 = dPlusBachelier(F_0 = F_0 , y = y, expiry = expiry ,vol = vol)
        if isCall:
             option_value = (math.exp((-rfr)*expiry_1))*((F_0 - y)* norm.cdf(d1) + vol * math.sqrt(expiry) * norm.cdf(d1))
        else:
             option_value = (math.exp((-rfr)*expiry_1))*((y-F_0) * norm.cdf(-d1) + vol * math.sqrt(expiry) * norm.cdf(-d1))
    return option_value

def dPlusBachelier(F_0 , y, expiry , vol):
    d_plus = (F_0 - y)/ (vol * math.sqrt(expiry))
    return d_plus

a = bachelier(0.07,0.08,1,0.20,0.069394,1.25,"isCall")

0 votos

¿No debería ser la segunda parte de tu option_value en el código de bachelier norm.pdf(d1)?

5voto

Fischer Puntos 59

¿utilizas el mismo 20% de volatilidad para black76 y Bachelier?

El negro76 es un modelo lognormal, en el que las volatilidades se expresan como variaciones relativas de los precios. El modelo bachelier/normal expresa las volatilidades como variaciones absolutas.

¿Eso podría ser lo que te estás perdiendo?

Saludos cordiales

0voto

Josh Arenberg Puntos 737

Siento llegar un poco tarde a la fiesta. Acabo de ver tu post mientras trataba de escribir mi propio modelo negro. Voy al error es un error tipográfico en dplus

d_plus = ((math.log(F_0 / y) + 0.5 * vol * vol * expiry)/ vol / math.sqrt(expiry))

Debería serlo:

d_plus = ((math.log(F_0 / y) + 0.5 * vol * vol * expiry)/( vol * math.sqrt(expiry)))

Saludos cordiales, Varun

Finanhelp.com

FinanHelp es una comunidad para personas con conocimientos de economía y finanzas, o quiere aprender. Puedes hacer tus propias preguntas o resolver las de los demás.

Powered by:

X