Estoy utilizando Quantlib en Python para fijar el precio de una opción FX. Estoy comparando el resultado con Bloomberg, para asegurarme de que el código está funcionando correctamente.
Quiero calcular las pérdidas y ganancias de una determinada estrategia de negociación de opciones mediante el uso de la expansión de Taylor de las pérdidas y ganancias (discutido en otro post aquí ) Y también utilizando el VAN de la opción.
Por lo tanto, es importante tener un VAN correcto para cada fecha en que la opción esté viva. La opción que utilizo para probar esto es una opción estilizada de 1 semana.
El problema que se produce es que el VAN coincide con Bloomberg correctamente en la primera, segunda, tercera y última fecha, pero no en las demás.
import QuantLib as ql
Spot = 1.1
Strike = 1.101
Sigma = 10/100
Ccy1Rate = 5/100
Ccy2Rate = 10/100
OptionType = ql.Option.Call
#Option dates in quantlib objects
EvaluationDate = ql.Date(3, 1,2022)
SettlementDate = ql.Date(5, 1, 2022) #Evaluation +2
ExpiryDate = ql.Date(10, 1, 2022) #Evaluation + term which is 1 week
DeliveryDate = ql.Date(12, 1, 2022) #Expiry +2
NumberOfDaysBetween = ExpiryDate - EvaluationDate
#print(NumberOfDaysBetween)
#Generate continuous interest rates
EurRate = Ccy1Rate
UsdRate = Ccy2Rate
#Create QuoteHandle objects. Easily to adapt later on.
#You can only access SimpleQuote objects. When you use setvalue, you can change it.
#These global variables will then be used in pricing the option.
#Everything will be adaptable except for the strike.
SpotGlobal = ql.SimpleQuote(Spot)
SpotHandle = ql.QuoteHandle(SpotGlobal)
VolGlobal = ql.SimpleQuote(Sigma)
VolHandle = ql.QuoteHandle(VolGlobal)
UsdRateGlobal = ql.SimpleQuote(UsdRate)
UsdRateHandle = ql.QuoteHandle(UsdRateGlobal)
EurRateGlobal = ql.SimpleQuote(EurRate)
EurRateHandle = ql.QuoteHandle(EurRateGlobal)
#Settings such as calendar, evaluationdate; daycount
Calendar = ql.UnitedStates()
ql.Settings.instance().evaluationDate = EvaluationDate
DayCountRate = ql.Actual360()
DayCountVolatility = ql.ActualActual()
#Create rate curves, vol surface and GK process
RiskFreeRateEUR = ql.YieldTermStructureHandle(ql.FlatForward(0, Calendar, EurRateHandle, DayCountRate))
RiskFreeRateUSD = ql.YieldTermStructureHandle(ql.FlatForward(0, Calendar, UsdRate, DayCountRate))
Volatility = ql.BlackVolTermStructureHandle(ql.BlackConstantVol(0, Calendar, VolHandle, DayCountVolatility))
GKProcess = ql.GarmanKohlagenProcess(SpotHandle, RiskFreeRateEUR, RiskFreeRateUSD, Volatility)
#Generate option
Payoff = ql.PlainVanillaPayoff(OptionType, Strike)
Exercise = ql.EuropeanExercise(ExpiryDate)
Option = ql.VanillaOption(Payoff, Exercise)
Option.setPricingEngine(ql.AnalyticEuropeanEngine(GKProcess))
BsPrice = Option.NPV()
ql.Settings.instance().includeReferenceDateEvents = True
ql.Settings.instance().evaluationDate = EvaluationDate
print("Premium is:", Option.NPV()*1000000/Spot)
ql.Settings.instance().evaluationDate = EvaluationDate+1
print("Premium is:", Option.NPV()*1000000/Spot)
ql.Settings.instance().evaluationDate = EvaluationDate+2
print("Premium is:", Option.NPV()*1000000/Spot)
ql.Settings.instance().evaluationDate = EvaluationDate+3
print("Premium is:", Option.NPV()*1000000/Spot)
ql.Settings.instance().evaluationDate = EvaluationDate+4
print("Premium is:", Option.NPV()*1000000/Spot)
ql.Settings.instance().evaluationDate = EvaluationDate+7
print("Premium is:", Option.NPV()*1000000/Spot)
Lo que resulta en:
Premium is: 5487.479999102207
Premium is: 5148.552323458257
Premium is: 4774.333578225227
Premium is: 4353.586300232529
Premium is: 3867.4561591587326
Premium is: 909.0909090908089
Sin embargo, según Bloomberg la prima debería ser:
5487.48 (correct)
5148.55 (correct)
4774.33 (correct)
4499.5
4015.7
909.9 (correct)
El resultado al vencimiento viene dado por la fijación de lo siguiente (la opción vence in-the-money):
ql.Settings.instance().includeReferenceDateEvents = True
¿Puede alguien explicar por qué el VAN de repente no coincide para esas 2 fechas?
Capturas de pantalla de la valoración de opciones en Bloomberg
2 votos
En OVML hay dos intervalos de tiempo diferentes: a) tiempo hasta el vencimiento = Fecha de vencimiento - Fecha de precio b) tiempo hasta la entrega = Fecha de entrega - Fecha de prima Quantlib parece no calcular esto (como Matlab, por ejemplo, tampoco lo distingue). Puede ver la fecha de la prima en la parte inferior de la pantalla OVML.