简体   繁体   中英

Quantlib - giving a strange error

I am using Quantlib to bootstrap a curve and then get the discounting rate.

In general the usual steps work fine.

However, for the data given below, it throws a strange error.

Code:

def create_ois_swaps(self, ois_swap_rates, helpers=None):
    ''' Creates a OIS rate helper from incoming OIS rates
        Input:
        ois_swap_rates: list of tuples comprising of (start_date, end_date, rate, label)
    '''
    if self.helpers is None:
        self.helpers = [
            DatedOISRateHelper(start_date, end_date, QuoteHandle(SimpleQuote(rate / 100)), self.ff_local)
            for start_date, end_date, rate in [tuple((fixed_bond.pydate_to_qldate(sd),
                                                      fixed_bond.pydate_to_qldate(ed),
                                                      rate)) for sd, ed, rate, label
                                               in ois_swap_rates if label not in ['ONTN', 'TN']]]
    else:
        self.helpers += [DatedOISRateHelper(start_date,
                                            end_date,
                                            QuoteHandle(SimpleQuote(rate / 100)), self.ff_local)
                         for start_date, end_date, rate in [tuple((fixed_bond.pydate_to_qldate(sd),
                                                                   fixed_bond.pydate_to_qldate(ed),
                                                                   rate)) for sd, ed, rate, label
                                                            in ois_swap_rates if label not in ['ONTN', 'TN']]]
    # for start_date, end_date, rate in ois_swap_rates]
    self.ois_curve_c = PiecewiseLogCubicDiscount(0, self.calendar, self.helpers, Actual365Fixed())
    self.ois_curve_c.enableExtrapolation()

def bootstrap_usd_ois_3M_curve(self,
                               usd_3M_swap_rates,
                               discountCurve,
                               bootStrapMethod=BootStrapMethod.PiecewiseLogCubicDiscount):

    discount_curve = RelinkableYieldTermStructureHandle()
    discount_curve.linkTo(discountCurve)
    self.helpers += [SwapRateHelper(QuoteHandle(SimpleQuote(rate / 100)),
                                    Period(int(label[:-1]), Years),
                                    TARGET(),
                                    Semiannual,
                                    Unadjusted,
                                    Thirty360(Thirty360.BondBasis),
                                    Euribor3M(),
                                    QuoteHandle(),
                                    Period(0, Days),
                                    discount_curve)
                     for sd, ed, rate, label in usd_3M_swap_rates if label not in ['ONTN', 'TN']]
    # for rate, tenor in usd_3M_swap_rates]

    if bootStrapMethod == BootStrapMethod.PiecewiseLogCubicDiscount:
        self.usd_3M_c = PiecewiseLogCubicDiscount(0, TARGET(), self.helpers, Actual365Fixed())
    elif bootStrapMethod == BootStrapMethod.PiecewiseFlatForward:
        self.usd_3M_c = PiecewiseFlatForward(0, TARGET(), self.helpers, Actual365Fixed())

    # Also, we enable extrapolation beyond the maturity of the last helper; that is mostly
    # for convenience as we retrieve rates to plot the curve near its far end.
    self.usd_3M_c.enableExtrapolation()

in my main code, I call the above 2 functions as:-

create the OIS curve

usd_ois.create_ois_swaps(ois_rate_ql)

bootstrap the curve

usd_ois.bootstrap_usd_ois_3M_curve(usd_3M_swap_rates=libor_rate_ql, discountCurve=usd_ois.ois_curve_c, bootStrapMethod=BootStrapMethod.PiecewiseFlatForward)

Dates:

Curve valuation date: 2017.01.02

for discounting_Rate:-

start_date: 2017.01.02 end_date: 2018.01.01 dayCount: ACT/360

Error message:

return _QuantLib.YieldTermStructure_forwardRate(self, *args) RuntimeError: negative time (-0.00273973) given`

Curve object

curve object Data used: libor and OIS rates used for bootstrapping

State of curve object

state of curve object

Notice I have a 1) discounting OIS curve and a 2) forward 3M curve

Valuation date is Jan 2nd , 2017

The call I am making is on the discounting curve as follows:- ois_curve.ois_curve_c.forwardRate(pydate_to_qldate(start_date), pydate_to_qldate(end_date), daycount, Simple).rate() * 100

where start_Date = 2nd Jan, 2017 end_date = 2nd Jan, 2018

I am running the same code over a range of dates. Most of the dates- its successful, but few of the dates- it strangely throws this error

For reference, I'm summarizing here the comments above. The evaluation date (January 2nd, 2017) is a holiday for the calendar used by the curve; therefore, the curve moves its reference date to the next business day. At that point, January 2nd is in the past as far as the curve is concerned and asking for a rate on that date results in an error.

I agree that, at least, the error should be made more readable. I'm not sure that setting the evaluation date to a holiday should necessarily invalidate the curve. Throwing an error is probably not feasible; we might have different curves using different calendars, and setting the evaluation date to a holiday for one of those should be ok as long as we only use the valid curves.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM