Swap Pricing: Advancing the Evaluation Date

classic Classic list List threaded Threaded
2 messages Options
Reply | Threaded
Open this post in threaded view
|

Swap Pricing: Advancing the Evaluation Date

Joe Lewis

I am trying to price a swap one month into to the future (not forward starting) using:

 

Settings.instance().evaluationDate = calendar.advance( todaysDate ,1, Months)

 

But there always seems to be an error of missing todays fixing date or failed at 1st alive instrument.  For example I have added this to the end of the example swap.py included in the swig package:

 

# price one month in future

 

Settings.instance().evaluationDate = calendar.advance( todaysDate ,1, Months)

print(tab + "5-years swap paying %s one month in future" % formatRate(fixedRate))

print(rule)

 

discountTermStructure.linkTo(depoFuturesSwapCurve)

forecastTermStructure.linkTo(depoFuturesSwapCurve)

report(forward,'depo-fut-swap')

 

discountTermStructure.linkTo(depoFraSwapCurve)

forecastTermStructure.linkTo(depoFraSwapCurve)

report(forward,'depo-FRA-swap')

 

But it generates an error:

RuntimeError: 1st iteration: failed at 1st alive instrument, maturity December 17th, 2001, reference date November 8th, 2001: root not bracketed: f[0.00816277,0.121267] -> [1.232945e-003,1.232945e-003]

 

Or if I try to advance the EvaluationDate by one day:

Settings.instance().evaluationDate = calendar.advance( todaysDate ,1, Days)

 

It generates this error:

RuntimeError: 1st iteration: failed at 14th alive instrument, maturity November 9th, 2016, reference date November 8th, 2001: 1st leg: time (15.2222) is past max curve time (15.2194)

 

This is my entire code:

 

#############################################################

from QuantLib import *

 

# global data

calendar = TARGET()

todaysDate = Date(6,November,2001);

Settings.instance().evaluationDate = todaysDate

settlementDate = Date(8,November,2001);

 

# market quotes

deposits = { (1,Weeks): 0.0382,

             (1,Months): 0.0372,

             (3,Months): 0.0363,

             (6,Months): 0.0353,

             (9,Months): 0.0348,

             (1,Years): 0.0345 }

 

FRAs = { (3,6): 0.037125,

         (6,9): 0.037125,

         (9,12): 0.037125 }

 

futures = { Date(19,12,2001): 96.2875,

            Date(20,3,2002): 96.7875,

            Date(19,6,2002): 96.9875,

            Date(18,9,2002): 96.6875,

            Date(18,12,2002): 96.4875,

            Date(19,3,2003): 96.3875,

            Date(18,6,2003): 96.2875,

            Date(17,9,2003): 96.0875 }

 

swaps = { (2,Years): 0.037125,

          (3,Years): 0.0398,

          (5,Years): 0.0443,

          (10,Years): 0.05165,

          (15,Years): 0.055175 }

 

# convert them to Quote objects

for n,unit in deposits.keys():

    deposits[(n,unit)] = SimpleQuote(deposits[(n,unit)])

for n,m in FRAs.keys():

    FRAs[(n,m)] = SimpleQuote(FRAs[(n,m)])

for d in futures.keys():

    futures[d] = SimpleQuote(futures[d])

for n,unit in swaps.keys():

    swaps[(n,unit)] = SimpleQuote(swaps[(n,unit)])

 

# build rate helpers

 

dayCounter = Actual360()

settlementDays = 2

depositHelpers = [ DepositRateHelper(QuoteHandle(deposits[(n,unit)]),

                                     Period(n,unit), settlementDays,

                                     calendar, ModifiedFollowing,

                                     False, dayCounter)

                   for n, unit in [(1,Weeks),(1,Months),(3,Months),

                                   (6,Months),(9,Months),(1,Years)] ]

 

dayCounter = Actual360()

settlementDays = 2

fraHelpers = [ FraRateHelper(QuoteHandle(FRAs[(n,m)]),

                             n, m, settlementDays,

                             calendar, ModifiedFollowing,

                             False, dayCounter)

               for n, m in FRAs.keys() ]

 

dayCounter = Actual360()

months = 3

futuresHelpers = [ FuturesRateHelper(QuoteHandle(futures[d]),

                                     d, months,

                                     calendar, ModifiedFollowing,

                                     True, dayCounter,

                                     QuoteHandle(SimpleQuote(0.0)))

                   for d in futures.keys() ]

 

settlementDays = 2

fixedLegFrequency = Annual

fixedLegTenor = Period(1,Years)

fixedLegAdjustment = Unadjusted

fixedLegDayCounter = Thirty360()

floatingLegFrequency = Semiannual

floatingLegTenor = Period(6,Months)

floatingLegAdjustment = ModifiedFollowing

swapHelpers = [ SwapRateHelper(QuoteHandle(swaps[(n,unit)]),

                               Period(n,unit), calendar,

                               fixedLegFrequency, fixedLegAdjustment,

                               fixedLegDayCounter, Euribor6M())

                for n, unit in swaps.keys() ]

 

# term structure handles

 

discountTermStructure = RelinkableYieldTermStructureHandle()

forecastTermStructure = RelinkableYieldTermStructureHandle()

 

# term-structure construction

 

helpers = depositHelpers[:2] + futuresHelpers + swapHelpers[1:]

depoFuturesSwapCurve = PiecewiseFlatForward(settlementDate, helpers,

                                            Actual360())

 

helpers = depositHelpers[:3] + fraHelpers + swapHelpers

depoFraSwapCurve = PiecewiseFlatForward(settlementDate, helpers, Actual360())

 

# swaps to be priced

 

swapEngine = DiscountingSwapEngine(discountTermStructure)

 

nominal = 1000000

length = 5

maturity = calendar.advance(settlementDate,length,Years)

payFixed = True

 

fixedLegFrequency = Annual

fixedLegAdjustment = Unadjusted

fixedLegDayCounter = Thirty360()

fixedRate = 0.04

 

floatingLegFrequency = Semiannual

spread = 0.0

fixingDays = 2

index = Euribor6M(forecastTermStructure)

floatingLegAdjustment = ModifiedFollowing

floatingLegDayCounter = index.dayCounter()

 

fixedSchedule = Schedule(settlementDate, maturity,

                         fixedLegTenor, calendar,

                         fixedLegAdjustment, fixedLegAdjustment,

                         DateGeneration.Forward, False)

floatingSchedule = Schedule(settlementDate, maturity,

                            floatingLegTenor, calendar,

                            floatingLegAdjustment, floatingLegAdjustment,

                            DateGeneration.Forward, False)

 

spot = VanillaSwap(VanillaSwap.Payer, nominal,

                   fixedSchedule, fixedRate, fixedLegDayCounter,

                   floatingSchedule, index, spread,

                   floatingLegDayCounter)

spot.setPricingEngine(swapEngine)

 

forwardStart = calendar.advance(settlementDate,1,Years)

forwardEnd = calendar.advance(forwardStart,length,Years)

fixedSchedule = Schedule(forwardStart, forwardEnd,

                         fixedLegTenor, calendar,

                         fixedLegAdjustment, fixedLegAdjustment,

                         DateGeneration.Forward, False)

floatingSchedule = Schedule(forwardStart, forwardEnd,

                            floatingLegTenor, calendar,

                            floatingLegAdjustment, floatingLegAdjustment,

                            DateGeneration.Forward, False)

 

forward = VanillaSwap(VanillaSwap.Payer, nominal,

                      fixedSchedule, fixedRate, fixedLegDayCounter,

                      floatingSchedule, index, spread,

                      floatingLegDayCounter)

forward.setPricingEngine(swapEngine)

 

# price on the bootstrapped curves

 

def formatPrice(p,digits=2):

    format = '%%.%df' % digits

    return format % p

 

def formatRate(r,digits=2):

    format = '%%.%df %%%%' % digits

    return format % (r*100)

 

headers = ("term structure", "net present value",

           "fair spread", "fair fixed rate" )

separator = " | "

 

format = ''

width = 0

for h in headers[:-1]:

    format += '%%%ds' % len(h)

    format += separator

    width += len(h) + len(separator)

format += '%%%ds' % len(headers[-1])

width += len(headers[-1])

 

rule = "-" * width

dblrule = "=" * width

tab = " " * 8

 

def report(swap, name):

    print(format % (name, formatPrice(swap.NPV(),2),

                    formatRate(swap.fairSpread(),4),

                    formatRate(swap.fairRate(),4)))

 

print(dblrule)

print("5-year market swap-rate = %s" % formatRate(swaps[(5,Years)].value()))

print(dblrule)

 

# price on two different term structures

 

print(tab + "5-years swap paying %s" % formatRate(fixedRate))

print(separator.join(headers))

print(rule)

 

discountTermStructure.linkTo(depoFuturesSwapCurve)

forecastTermStructure.linkTo(depoFuturesSwapCurve)

report(spot,'depo-fut-swap')

 

discountTermStructure.linkTo(depoFraSwapCurve)

forecastTermStructure.linkTo(depoFraSwapCurve)

report(spot,'depo-FRA-swap')

 

print(rule)

 

# price one month in future

 

Settings.instance().evaluationDate = calendar.advance( todaysDate ,1, Months)

print(tab + "5-years swap paying %s one month in future" % formatRate(fixedRate))

print(rule)

 

discountTermStructure.linkTo(depoFuturesSwapCurve)

forecastTermStructure.linkTo(depoFuturesSwapCurve)

report(forward,'depo-fut-swap')

 

discountTermStructure.linkTo(depoFraSwapCurve)

forecastTermStructure.linkTo(depoFraSwapCurve)

report(forward,'depo-FRA-swap')

##################################################################################

 

Please let me know if anyone can shed any light on this.

 

Thanks,

Joe


------------------------------------------------------------------------------

_______________________________________________
QuantLib-users mailing list
[hidden email]
https://lists.sourceforge.net/lists/listinfo/quantlib-users
Reply | Threaded
Open this post in threaded view
|

Re: Swap Pricing: Advancing the Evaluation Date

Luigi Ballabio
Hello,
    the main problem with changing the evaluation date in your setup is that the maturities of the deposits and the swaps will change, but those of the futures won't. So for instance, you'll have the 1-week deposit expiring on December 17th and the 1st futures on December 19th. They're too close, and the implied rates are too different (because they made sense when they were 1 month apart) so the solver can't find a curve that reprices both.

One thing you might consider, if you want some kind of forward price, is to use an implied term structure instead (as in: today's curve gives you an estimate of the forward rates one month from now, so you can build the implied future curve.). You have to be careful, though, if you want to use it together with a bootstrapped curve. I cover the thing here: <https://www.youtube.com/watch?v=8Lc5r0YxAME>.

Luigi



On Thu, Oct 23, 2014 at 8:52 PM, Joe Lewis <[hidden email]> wrote:

I am trying to price a swap one month into to the future (not forward starting) using:

 

Settings.instance().evaluationDate = calendar.advance( todaysDate ,1, Months)

 

But there always seems to be an error of missing todays fixing date or failed at 1st alive instrument.  For example I have added this to the end of the example swap.py included in the swig package:

 

# price one month in future

 

Settings.instance().evaluationDate = calendar.advance( todaysDate ,1, Months)

print(tab + "5-years swap paying %s one month in future" % formatRate(fixedRate))

print(rule)

 

discountTermStructure.linkTo(depoFuturesSwapCurve)

forecastTermStructure.linkTo(depoFuturesSwapCurve)

report(forward,'depo-fut-swap')

 

discountTermStructure.linkTo(depoFraSwapCurve)

forecastTermStructure.linkTo(depoFraSwapCurve)

report(forward,'depo-FRA-swap')

 

But it generates an error:

RuntimeError: 1st iteration: failed at 1st alive instrument, maturity December 17th, 2001, reference date November 8th, 2001: root not bracketed: f[0.00816277,0.121267] -> [1.232945e-003,1.232945e-003]

 

Or if I try to advance the EvaluationDate by one day:

Settings.instance().evaluationDate = calendar.advance( todaysDate ,1, Days)

 

It generates this error:

RuntimeError: 1st iteration: failed at 14th alive instrument, maturity November 9th, 2016, reference date November 8th, 2001: 1st leg: time (15.2222) is past max curve time (15.2194)

 

This is my entire code:

 

#############################################################

from QuantLib import *

 

# global data

calendar = TARGET()

todaysDate = Date(6,November,2001);

Settings.instance().evaluationDate = todaysDate

settlementDate = Date(8,November,2001);

 

# market quotes

deposits = { (1,Weeks): 0.0382,

             (1,Months): 0.0372,

             (3,Months): 0.0363,

             (6,Months): 0.0353,

             (9,Months): 0.0348,

             (1,Years): 0.0345 }

 

FRAs = { (3,6): 0.037125,

         (6,9): 0.037125,

         (9,12): 0.037125 }

 

futures = { Date(19,12,2001): 96.2875,

            Date(20,3,2002): 96.7875,

            Date(19,6,2002): 96.9875,

            Date(18,9,2002): 96.6875,

            Date(18,12,2002): 96.4875,

            Date(19,3,2003): 96.3875,

            Date(18,6,2003): 96.2875,

            Date(17,9,2003): 96.0875 }

 

swaps = { (2,Years): 0.037125,

          (3,Years): 0.0398,

          (5,Years): 0.0443,

          (10,Years): 0.05165,

          (15,Years): 0.055175 }

 

# convert them to Quote objects

for n,unit in deposits.keys():

    deposits[(n,unit)] = SimpleQuote(deposits[(n,unit)])

for n,m in FRAs.keys():

    FRAs[(n,m)] = SimpleQuote(FRAs[(n,m)])

for d in futures.keys():

    futures[d] = SimpleQuote(futures[d])

for n,unit in swaps.keys():

    swaps[(n,unit)] = SimpleQuote(swaps[(n,unit)])

 

# build rate helpers

 

dayCounter = Actual360()

settlementDays = 2

depositHelpers = [ DepositRateHelper(QuoteHandle(deposits[(n,unit)]),

                                     Period(n,unit), settlementDays,

                                     calendar, ModifiedFollowing,

                                     False, dayCounter)

                   for n, unit in [(1,Weeks),(1,Months),(3,Months),

                                   (6,Months),(9,Months),(1,Years)] ]

 

dayCounter = Actual360()

settlementDays = 2

fraHelpers = [ FraRateHelper(QuoteHandle(FRAs[(n,m)]),

                             n, m, settlementDays,

                             calendar, ModifiedFollowing,

                             False, dayCounter)

               for n, m in FRAs.keys() ]

 

dayCounter = Actual360()

months = 3

futuresHelpers = [ FuturesRateHelper(QuoteHandle(futures[d]),

                                     d, months,

                                     calendar, ModifiedFollowing,

                                     True, dayCounter,

                                     QuoteHandle(SimpleQuote(0.0)))

                   for d in futures.keys() ]

 

settlementDays = 2

fixedLegFrequency = Annual

fixedLegTenor = Period(1,Years)

fixedLegAdjustment = Unadjusted

fixedLegDayCounter = Thirty360()

floatingLegFrequency = Semiannual

floatingLegTenor = Period(6,Months)

floatingLegAdjustment = ModifiedFollowing

swapHelpers = [ SwapRateHelper(QuoteHandle(swaps[(n,unit)]),

                               Period(n,unit), calendar,

                               fixedLegFrequency, fixedLegAdjustment,

                               fixedLegDayCounter, Euribor6M())

                for n, unit in swaps.keys() ]

 

# term structure handles

 

discountTermStructure = RelinkableYieldTermStructureHandle()

forecastTermStructure = RelinkableYieldTermStructureHandle()

 

# term-structure construction

 

helpers = depositHelpers[:2] + futuresHelpers + swapHelpers[1:]

depoFuturesSwapCurve = PiecewiseFlatForward(settlementDate, helpers,

                                            Actual360())

 

helpers = depositHelpers[:3] + fraHelpers + swapHelpers

depoFraSwapCurve = PiecewiseFlatForward(settlementDate, helpers, Actual360())

 

# swaps to be priced

 

swapEngine = DiscountingSwapEngine(discountTermStructure)

 

nominal = 1000000

length = 5

maturity = calendar.advance(settlementDate,length,Years)

payFixed = True

 

fixedLegFrequency = Annual

fixedLegAdjustment = Unadjusted

fixedLegDayCounter = Thirty360()

fixedRate = 0.04

 

floatingLegFrequency = Semiannual

spread = 0.0

fixingDays = 2

index = Euribor6M(forecastTermStructure)

floatingLegAdjustment = ModifiedFollowing

floatingLegDayCounter = index.dayCounter()

 

fixedSchedule = Schedule(settlementDate, maturity,

                         fixedLegTenor, calendar,

                         fixedLegAdjustment, fixedLegAdjustment,

                         DateGeneration.Forward, False)

floatingSchedule = Schedule(settlementDate, maturity,

                            floatingLegTenor, calendar,

                            floatingLegAdjustment, floatingLegAdjustment,

                            DateGeneration.Forward, False)

 

spot = VanillaSwap(VanillaSwap.Payer, nominal,

                   fixedSchedule, fixedRate, fixedLegDayCounter,

                   floatingSchedule, index, spread,

                   floatingLegDayCounter)

spot.setPricingEngine(swapEngine)

 

forwardStart = calendar.advance(settlementDate,1,Years)

forwardEnd = calendar.advance(forwardStart,length,Years)

fixedSchedule = Schedule(forwardStart, forwardEnd,

                         fixedLegTenor, calendar,

                         fixedLegAdjustment, fixedLegAdjustment,

                         DateGeneration.Forward, False)

floatingSchedule = Schedule(forwardStart, forwardEnd,

                            floatingLegTenor, calendar,

                            floatingLegAdjustment, floatingLegAdjustment,

                            DateGeneration.Forward, False)

 

forward = VanillaSwap(VanillaSwap.Payer, nominal,

                      fixedSchedule, fixedRate, fixedLegDayCounter,

                      floatingSchedule, index, spread,

                      floatingLegDayCounter)

forward.setPricingEngine(swapEngine)

 

# price on the bootstrapped curves

 

def formatPrice(p,digits=2):

    format = '%%.%df' % digits

    return format % p

 

def formatRate(r,digits=2):

    format = '%%.%df %%%%' % digits

    return format % (r*100)

 

headers = ("term structure", "net present value",

           "fair spread", "fair fixed rate" )

separator = " | "

 

format = ''

width = 0

for h in headers[:-1]:

    format += '%%%ds' % len(h)

    format += separator

    width += len(h) + len(separator)

format += '%%%ds' % len(headers[-1])

width += len(headers[-1])

 

rule = "-" * width

dblrule = "=" * width

tab = " " * 8

 

def report(swap, name):

    print(format % (name, formatPrice(swap.NPV(),2),

                    formatRate(swap.fairSpread(),4),

                    formatRate(swap.fairRate(),4)))

 

print(dblrule)

print("5-year market swap-rate = %s" % formatRate(swaps[(5,Years)].value()))

print(dblrule)

 

# price on two different term structures

 

print(tab + "5-years swap paying %s" % formatRate(fixedRate))

print(separator.join(headers))

print(rule)

 

discountTermStructure.linkTo(depoFuturesSwapCurve)

forecastTermStructure.linkTo(depoFuturesSwapCurve)

report(spot,'depo-fut-swap')

 

discountTermStructure.linkTo(depoFraSwapCurve)

forecastTermStructure.linkTo(depoFraSwapCurve)

report(spot,'depo-FRA-swap')

 

print(rule)

 

# price one month in future

 

Settings.instance().evaluationDate = calendar.advance( todaysDate ,1, Months)

print(tab + "5-years swap paying %s one month in future" % formatRate(fixedRate))

print(rule)

 

discountTermStructure.linkTo(depoFuturesSwapCurve)

forecastTermStructure.linkTo(depoFuturesSwapCurve)

report(forward,'depo-fut-swap')

 

discountTermStructure.linkTo(depoFraSwapCurve)

forecastTermStructure.linkTo(depoFraSwapCurve)

report(forward,'depo-FRA-swap')

##################################################################################

 

Please let me know if anyone can shed any light on this.

 

Thanks,

Joe


------------------------------------------------------------------------------

_______________________________________________
QuantLib-users mailing list
[hidden email]
https://lists.sourceforge.net/lists/listinfo/quantlib-users




--

------------------------------------------------------------------------------
Download BIRT iHub F-Type - The Free Enterprise-Grade BIRT Server
from Actuate! Instantly Supercharge Your Business Reports and Dashboards
with Interactivity, Sharing, Native Excel Exports, App Integration & more
Get technology previously reserved for billion-dollar corporations, FREE
http://pubads.g.doubleclick.net/gampad/clk?id=157005751&iu=/4140/ostg.clktrk
_______________________________________________
QuantLib-users mailing list
[hidden email]
https://lists.sourceforge.net/lists/listinfo/quantlib-users