def daycount(cls, date1, date2, daycounter=None): pydate1, pydate2 = map(parse_date, (date1, date2)) if not daycounter: daycounter = cls.ActualActual() qldate1 = qldate_from_pydate(pydate1) qldate2 = qldate_from_pydate(pydate2) return daycounter.day_count(qldate1, qldate2)
def fromdates(cls, settle, maturity, daycount=ActualActual()): ''' Returns the tenor associated with settlement and maturity. ''' settle = qldate_from_pydate(settle) maturity = qldate_from_pydate(maturity) years_ = daycount.year_fraction(settle, maturity) if years_ >= 1.0: t = "".join((str(int(round(years_))), "Y")) else: t = "".join((str(int(round(years_ * 12.))), "M")) return cls(t)
def fromdates(cls, settle, maturity, daycount=ActualActual()): ''' Returns the tenor associated with settlement and maturity. ''' settle = qldate_from_pydate(settle) maturity = qldate_from_pydate(maturity) years_ = daycount.year_fraction(settle, maturity) if years_ >= 1.0: t = "".join((str(int(round(years_))),"Y")) else: t = "".join((str(int(round(years_*12.))),"M")) return cls(t)
def year_fraction(cls, date1, date2, daycounter=None): ''' Calculate the fraction of a year between two date1 and date2, based on the daycount specified. dates may be ccyymmdd or python datetime.dates ''' pydate1, pydate2 = map(parse_date, (date1, date2)) if not daycounter: daycounter = cls.ActualActual() qldate1 = qldate_from_pydate(pydate1) qldate2 = qldate_from_pydate(pydate2) return daycounter.year_fraction(qldate1, qldate2)
def schedule(self, settle_, maturity_, convention=Unadjusted, calendar=TARGET(), aspy=True): ''' tenor('3m').schedule(settleDate, maturityDate) or tenor('3m').schedule(settleDate, '10Y') gives a schedule of dates from settleDate to maturity with a short front stub. ''' settle_ = qldate_from_pydate(settle_) mty_ = qldate_from_pydate(maturity_) sched = [] if type(maturity_) == str and not mty_: maturity_ = Tenor(maturity_).advance(settle_, convention=convention, calendar=calendar) else: maturity_ = mty_ dt = maturity_ while dt.serial > settle_.serial: sched.append(calendar.adjust(dt, convention)) dt = self.advance(dt, reverse=True) else: sched.append(settle_) sched.sort(key=lambda dt: dt.serial) if aspy: sched = [pydate_from_qldate(dt) for dt in sched] return sched
def advance(self, date_, convention=Unadjusted, calendar=TARGET(), reverse=False, aspy=True): date_ = qldate_from_pydate(date_) length_ = self.length if not reverse else -self.length date_ = calendar.advance(date_, length_, self.timeunit, convention=convention) return date_ if not aspy else pydate_from_qldate(date_)
def schedule(self, settle_, maturity_, convention=Unadjusted, calendar=TARGET(), aspy=True): ''' tenor('3m').schedule(settleDate, maturityDate) or tenor('3m').schedule(settleDate, '10Y') gives a schedule of dates from settleDate to maturity with a short front stub. ''' settle_ = qldate_from_pydate(settle_) mty_ = qldate_from_pydate(maturity_) sched = [] if type(maturity_) == str and not mty_: maturity_ = Tenor(maturity_).advance(settle_, convention=convention, calendar=calendar ) else: maturity_ = mty_ dt = maturity_ while dt.serial > settle_.serial: sched.append(calendar.adjust(dt, convention)) dt = self.advance(dt, reverse=True) else: sched.append(settle_) sched.sort(key=lambda dt: dt.serial) if aspy: sched = [pydate_from_qldate(dt) for dt in sched] return sched
def test_create_libor_index(self): settings = Settings(calendar = TARGET()).instance() calendar = settings.calendar eval_date = qldate_from_pydate(settings.today()) settlement_days = 2 settlement_date = calendar.advance(eval_date, settlement_days, Days) # must be a business day settlement_date = calendar.adjust(settlement_date); index = Libor('USD Libor', Period(6, Months), settlement_days, USDCurrency(), calendar, Actual360()) self.assertEquals('USD Libor6M Actual/360', index.name)
def is_business_day(cls, pydate, calendar=None): if not calendar: calendar = cls.TARGET() elif not hasattr(calendar, "advance"): return None qldate = qldate_from_pydate(parse_date(pydate)) try: return calendar.is_business_day(qldate) except: try: return calendar().is_business_day(qldate) except: return None
def adjust(cls, pydate, calendar=None, convention=None): if not calendar: calendar = cls.TARGET() elif not hasattr(calendar, "adjust"): return None if not convention: convention = BusinessDayConventions.Following qldate = qldate_from_pydate(parse_date(pydate)) try: return pydate_from_qldate(calendar.adjust(qldate, convention)) except: try: return pydate_from_qldate(calendar().adjust(qldate, convention)) except: return None
def advance(cls, pydate, n, timeunit=None, calendar=None, convention=None): """ Advance pydate according the specified calendar and convention :pydate: e.g. 19600809, date(1964, 9, 29), '5-23-1993' :n: integer :timeunit: e.g., enums.TimeUnits.Days usage ----- Note 9/6/1980 is a weekend >>> Calendars.advance(19800906, 1) datetime.date(1980, 9, 8) """ if not calendar: calendar = cls.TARGET() elif not hasattr(calendar, "advance"): return None if not convention: convention = BusinessDayConventions.Following if not timeunit: timeunit = TimeUnits.Days qldate = qldate_from_pydate(parse_date(pydate)) try: return pydate_from_qldate(calendar.advance(qldate, n, timeunit)) except: try: return pydate_from_qldate( calendar().advance(qldate, n, timeunit) ) except: print("failure {}".format(qldate)) return None
def adjust(cls, pydate, calendar=None, convention=None): if not calendar: calendar = cls.TARGET() elif not hasattr(calendar, "adjust"): return None if not convention: convention = BusinessDayConventions.Following qldate = qldate_from_pydate(parse_date(pydate)) try: return pydate_from_qldate(calendar.adjust(qldate, convention)) except: try: return pydate_from_qldate(calendar().adjust( qldate, convention)) except: return None
def advance(cls, pydate, n, timeunit=None, calendar=None, convention=None): """ Advance pydate according the specified calendar and convention :pydate: e.g. 19600809, date(1964, 9, 29), '5-23-1993' :n: integer :timeunit: e.g., enums.TimeUnits.Days usage ----- Note 9/6/1980 is a weekend >>> Calendars.advance(19800906, 1) datetime.date(1980, 9, 8) """ if not calendar: calendar = cls.TARGET() elif not hasattr(calendar, "advance"): return None if not convention: convention = BusinessDayConventions.Following if not timeunit: timeunit = TimeUnits.Days qldate = qldate_from_pydate(parse_date(pydate)) try: return pydate_from_qldate(calendar.advance(qldate, n, timeunit)) except: try: return pydate_from_qldate(calendar().advance( qldate, n, timeunit)) except: print("failure {}".format(qldate)) return None
def test_deposit_swap(self): # Market information settings = Settings(calendar=TARGET()) calendar = settings.calendar # must be a business day eval_date = qldate_from_pydate(settings.today()) settlement_days = 2 settlement_date = calendar.advance(eval_date, settlement_days, Days) # must be a business day settlement_date = calendar.adjust(settlement_date) depositData = [[1, Months, 4.581], [2, Months, 4.573], [3, Months, 4.557], [6, Months, 4.496], [9, Months, 4.490]] swapData = [[1, Years, 4.54], [5, Years, 4.99], [10, Years, 5.47], [20, Years, 5.89], [30, Years, 5.96]] rate_helpers = [] end_of_month = True for m, period, rate in depositData: tenor = Period(m, Months) helper = DepositRateHelper(rate / 100, tenor, settlement_days, calendar, ModifiedFollowing, end_of_month, Actual360()) rate_helpers.append(helper) liborIndex = Libor('USD Libor', Period(6, Months), settlement_days, USDCurrency(), calendar, Actual360()) spread = SimpleQuote(0) fwdStart = Period(0, Days) for m, period, rate in swapData: rate = SimpleQuote(rate / 100) helper = SwapRateHelper(rate, Period(m, Years), calendar, Annual, Unadjusted, Thirty360(), liborIndex, spread, fwdStart) rate_helpers.append(helper) ts_day_counter = ActualActual(ISDA) tolerance = 1.0e-15 ts = term_structure_factory('discount', 'loglinear', settlement_date, rate_helpers, ts_day_counter, tolerance) # this is not a real test ... self.assertAlmostEquals( 0.9103, ts.discount(calendar.advance(today(), 2, Years)), 3) self.assertAlmostEquals( 0.7836, ts.discount(calendar.advance(today(), 5, Years)), 3) self.assertAlmostEquals( 0.5827, ts.discount(calendar.advance(today(), 10, Years)), 3) self.assertAlmostEquals( 0.4223, ts.discount(calendar.advance(today(), 15, Years)), 3)
def test_deposit_swap(self): # Market information settings = Settings(calendar = TARGET()) calendar = settings.calendar # must be a business day eval_date = qldate_from_pydate(settings.today()) settlement_days = 2 settlement_date = calendar.advance(eval_date, settlement_days, Days) # must be a business day settlement_date = calendar.adjust(settlement_date); depositData = [[ 1, Months, 4.581 ], [ 2, Months, 4.573 ], [ 3, Months, 4.557 ], [ 6, Months, 4.496 ], [ 9, Months, 4.490 ]] swapData = [[ 1, Years, 4.54 ], [ 5, Years, 4.99 ], [ 10, Years, 5.47 ], [ 20, Years, 5.89 ], [ 30, Years, 5.96 ]] rate_helpers = [] end_of_month = True for m, period, rate in depositData: tenor = Period(m, Months) helper = DepositRateHelper(rate/100, tenor, settlement_days, calendar, ModifiedFollowing, end_of_month, Actual360()) rate_helpers.append(helper) liborIndex = Libor('USD Libor', Period(6, Months), settlement_days, USDCurrency(), calendar, Actual360()) spread = SimpleQuote(0) fwdStart = Period(0, Days) for m, period, rate in swapData: rate = SimpleQuote(rate/100) helper = SwapRateHelper(rate, Period(m, Years), calendar, Annual, Unadjusted, Thirty360(), liborIndex, spread, fwdStart) rate_helpers.append(helper) ts_day_counter = ActualActual(ISDA) tolerance = 1.0e-15 ts = term_structure_factory( 'discount', 'loglinear', settlement_date, rate_helpers, ts_day_counter, tolerance) # this is not a real test ... self.assertAlmostEquals(0.9103, ts.discount(calendar.advance(today(), 2, Years)),3) self.assertAlmostEquals(0.7836, ts.discount(calendar.advance(today(), 5, Years)),3) self.assertAlmostEquals(0.5827, ts.discount(calendar.advance(today(), 10, Years)),3) self.assertAlmostEquals(0.4223, ts.discount(calendar.advance(today(), 15, Years)),3)