Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix for TreeSwaptionEngine mispricing #1327

Merged
merged 24 commits into from
Mar 17, 2022

Conversation

ralfkonrad
Copy link
Contributor

This is a fix for #1143.

The idea is similar to the one for #1142. We use the dates from the fixed and floating swap schedule and adjust them to the exercise date if they are within a period of seven days. The adjusted dates are used to create a new snapped swap which than can be discretized. If the coupon is taken into account within preAdjustValuesImpl() or postAdjustValuesImpl() depends on the fact if the period start date of the coupon is before or after the exercise date.

However even if the jump is now at the coupon period dates the TreeSwaptionEngine still seems not to be stable compared to the FdHullWhiteSwaptionEngine.

image

#!/usr/bin/env python
# coding: utf-8

# In[1]:


from typing import Any, Dict

import QuantLib as ql
import matplotlib.pyplot as plt
import pandas as pd


# In[2]:


today = ql.Date(8, 7, 2021)
ql.Settings.instance().evaluation_date = today

termstructure = ql.YieldTermStructureHandle(ql.FlatForward(today, 0.02, ql.Actual365Fixed()))
index = ql.Euribor3M(termstructure)


# In[3]:


def makeSwap(rate: float, effectiveDate: ql.Date) -> ql.VanillaSwap:
    swap = ql.MakeVanillaSwap(
        ql.Period(10, ql.Years),
        index,
        0.05,
        ql.Period(),
        effectiveDate=effectiveDate,
        Nominal=10000.00,
        swapType=ql.Swap.Payer)
    swap.setPricingEngine(ql.DiscountingSwapEngine(termstructure))
    return swap


# In[4]:


def makeBermudanSwaption(callDate: ql.Date) -> ql.Swaption:
    effectiveDate = ql.Date(15, 5, 2025)
    swap = makeSwap(0.00, effectiveDate)
    fairRate = swap.fairRate()
    swap = makeSwap(fairRate, effectiveDate)
    exerciseDates = [effectiveDate, callDate]
    bermudanExercise = ql.BermudanExercise(exerciseDates)
    bermudanSwaption = ql.Swaption(swap, bermudanExercise)
    return bermudanSwaption


# In[5]:


initialCallDate = ql.Date(15, 5, 2030)
calendar = index.fixingCalendar()

data = []

intervalOfDaysToTest = 60
for i in range(-intervalOfDaysToTest, intervalOfDaysToTest+1):
    callDate = initialCallDate + i

    bermudanSwaption = makeBermudanSwaption(callDate)
    model = ql.HullWhite(termstructure)

    bermudanSwaption.setPricingEngine(ql.FdHullWhiteSwaptionEngine(model))
    npvFD = bermudanSwaption.NPV()

    timesteps = 14 * 4 * 3
    bermudanSwaption.setPricingEngine(ql.TreeSwaptionEngine(model, timesteps))
    npvTree = bermudanSwaption.NPV()

    data.append(
        {
            'callDate': pd.Timestamp(callDate.ISO()),
            'FD':       npvFD,
            'Tree':     npvTree
        }
    )


# In[6]:


# Plot the results
df = pd.DataFrame(data)
df.set_index('callDate')

fig, ax = plt.subplots()
fig.set_size_inches(16, 9)
df.plot(ax=ax, style='-o', alpha=0.8, x = 'callDate')
ax.set_title('Compare FdHullWhiteSwaptionEngine with TreeSwaptionEngine', fontsize=20)
ax.set_ylabel('npv', fontsize=14)
ax.grid(True, lw=0.5, alpha=0.5)


# In[ ]:

@coveralls
Copy link

coveralls commented Mar 15, 2022

Coverage Status

Coverage increased (+0.02%) to 71.044% when pulling e741173 on ralfkonrad:feature/treeswaptionengine2 into 1f70a67 on lballabio:master.

@lballabio lballabio linked an issue Mar 17, 2022 that may be closed by this pull request
@lballabio lballabio added this to the Release 1.26 milestone Mar 17, 2022
@lballabio lballabio merged commit 92e37f9 into lballabio:master Mar 17, 2022
@lballabio
Copy link
Owner

Thanks!

@ralfkonrad ralfkonrad deleted the feature/treeswaptionengine2 branch March 22, 2022 18:15
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

TreeSwaptionEngine mispricing
3 participants