def bootstrap_term_structure(self, interpolator=LogLinear): tolerance = 1.0e-15 settings = Settings() calendar = JointCalendar(UnitedStates(), UnitedKingdom()) # must be a business day eval_date = self._eval_date settings.evaluation_date = eval_date settlement_days = self._params.settlement_days settlement_date = calendar.advance(eval_date, settlement_days, Days) # must be a business day settlement_date = calendar.adjust(settlement_date) ts = PiecewiseYieldCurve[BootstrapTrait.Discount, interpolator].from_reference_date( settlement_date, self._rate_helpers, DayCounter.from_name( self._termstructure_daycount), accuracy=tolerance) self._term_structure = ts self._discount_term_structure = YieldTermStructure() self._discount_term_structure.link_to(ts) self._forecast_term_structure = YieldTermStructure() self._forecast_term_structure.link_to(ts) return ts
def test_excel_example_with_zero_coupon_bond(self): todays_date = Date(25, August, 2011) settlement_days = 3 face_amount = 100 calendar = TARGET() maturity_date = Date(26, February, 2024) bond = ZeroCouponBond(settlement_days, calendar, face_amount, maturity_date, Following, 100.0, todays_date) discounting_term_structure = YieldTermStructure(relinkable=True) flat_term_structure = FlatForward(settlement_days=1, forward=0.044, calendar=NullCalendar(), daycounter=Actual365Fixed(), compounding=Continuous, frequency=Annual) discounting_term_structure.link_to(flat_term_structure) engine = DiscountingBondEngine(discounting_term_structure) bond.set_pricing_engine(engine) self.assertEquals(calendar.advance(todays_date, 3, Days), bond.settlement_date()) self.assertEquals(0., bond.accrued_amount(bond.settlement_date())) self.assertAlmostEquals(57.6915, bond.clean_price, 4)
def test_create_swap_index(self): settings = Settings.instance() # Market information calendar = TARGET() # must be a business day eval_date = calendar.adjust(today()) settings.evaluation_date = eval_date settlement_days = 2 settlement_date = calendar.advance(eval_date, settlement_days, Days) # must be a business day settlement_date = calendar.adjust(settlement_date) term_structure = YieldTermStructure(relinkable=True) term_structure.link_to( FlatForward(settlement_date, 0.05, Actual365Fixed())) ibor_index = Libor('USD Libor', Period(6, Months), settlement_days, USDCurrency(), calendar, Actual360(), term_structure) index = SwapIndex('family name', Period(3, Months), 10, USDCurrency(), TARGET(), Period(12, Months), Following, Actual360(), ibor_index) self.assertIsNotNone(index)
def test_create_libor_index(self): settings = Settings.instance() # Market information calendar = UnitedStates(LiborImpact) # must be a business day eval_date = calendar.adjust(today()) settings.evaluation_date = eval_date settlement_days = 2 settlement_date = calendar.advance(eval_date, settlement_days, Days) # must be a business day settlement_date = calendar.adjust(settlement_date) term_structure = YieldTermStructure(relinkable=True) term_structure.link_to( FlatForward(settlement_date, 0.05, Actual365Fixed())) index = Libor('USDLibor', Period(6, Months), settlement_days, USDCurrency(), calendar, Actual360(), term_structure) default_libor = USDLibor(Period(6, Months)) for attribute in [ "business_day_convention", "end_of_month", "fixing_calendar", "joint_calendar", "tenor", "fixing_days", "day_counter", "family_name", "name" ]: self.assertEqual(getattr(index, attribute), getattr(default_libor, attribute))
def test_create_libor_index(self): settings = Settings.instance() # Market information calendar = TARGET() # must be a business day eval_date = calendar.adjust(today()) settings.evaluation_date = eval_date settlement_days = 2 settlement_date = calendar.advance(eval_date, settlement_days, Days) # must be a business day settlement_date = calendar.adjust(settlement_date) term_structure = YieldTermStructure(relinkable=True) term_structure.link_to( FlatForward(settlement_date, 0.05, Actual365Fixed())) index = Libor('USD Libor', Period(6, Months), settlement_days, USDCurrency(), calendar, Actual360(), term_structure) t = index.tenor self.assertEquals(t.length, 6) self.assertEquals(t.units, 2) self.assertEquals('USD Libor6M Actual/360', index.name)
def test_relinkable_structures(self): discounting_term_structure = YieldTermStructure() settlement_days = 3 flat_term_structure = FlatForward(settlement_days=settlement_days, forward=0.044, calendar=NullCalendar(), daycounter=Actual360()) discounting_term_structure.link_to(flat_term_structure) evaluation_date = Settings().evaluation_date +100 self.assertEqual( flat_term_structure.discount(evaluation_date), discounting_term_structure.discount(evaluation_date) ) another_flat_term_structure = FlatForward(settlement_days=10, forward=0.067, calendar=NullCalendar(), daycounter=Actual365Fixed()) discounting_term_structure.link_to(another_flat_term_structure) self.assertEqual( another_flat_term_structure.discount(evaluation_date), discounting_term_structure.discount(evaluation_date) ) self.assertNotEqual( flat_term_structure.discount(evaluation_date), discounting_term_structure.discount(evaluation_date) )
def test_create_swap_rate_helper_from_index(self): calendar = UnitedStates() settlement_days = 2 currency = USDCurrency() fixed_leg_tenor = Period(12, Months) fixed_leg_convention = ModifiedFollowing fixed_leg_daycounter = Actual360() family_name = currency.name + 'index' ibor_index = Libor("USDLibor", Period(3, Months), settlement_days, USDCurrency(), UnitedStates(), Actual360(), YieldTermStructure(relinkable=False)) rate = 0.005681 tenor = Period(1, Years) index = SwapIndex(family_name, tenor, settlement_days, currency, calendar, fixed_leg_tenor, fixed_leg_convention, fixed_leg_daycounter, ibor_index) helper = SwapRateHelper.from_index(rate, index) #self.fail( # 'Make this pass: create and ask for the .quote property' # ' Test the from_index and from_tenor methods' #) self.assertIsNotNone(helper) self.assertAlmostEquals(rate, helper.quote) with self.assertRaises(RuntimeError): self.assertAlmostEquals(rate, helper.implied_quote)
def test_creation(self): settlement_date = Date(1, January, 2014) term_structure = YieldTermStructure() term_structure.link_to( FlatForward(settlement_date, 0.05, Actual365Fixed())) index = USDLibor(Period(3, Months), term_structure) self.assertEqual(index.name, 'USDLibor3M Actual/360')
def test_creation(self): settlement_date = Date(1, January, 2014) term_structure = YieldTermStructure(relinkable=True) term_structure.link_to( FlatForward(settlement_date, 0.05, Actual365Fixed())) # Makes sure the constructor does not segfault anymore ;-) index = Euribor6M(term_structure) self.assertEquals(index.name, 'Euribor6M Actual/360')
def test_excel_example_with_fixed_rate_bond(self): '''Port the QuantLib Excel adding bond example to Python. ''' todays_date = Date(25, August, 2011) settings = Settings() settings.evaluation_date = todays_date calendar = TARGET() effective_date = Date(10, Jul, 2006) termination_date = calendar.advance(effective_date, 10, Years, convention=Unadjusted) settlement_days = 3 face_amount = 100.0 coupon_rate = 0.05 redemption = 100.0 fixed_bond_schedule = Schedule.from_rule(effective_date, termination_date, Period(Annual), calendar, ModifiedFollowing, ModifiedFollowing, Backward) issue_date = effective_date bond = FixedRateBond(settlement_days, face_amount, fixed_bond_schedule, [coupon_rate], ActualActual(ISMA), Following, redemption, issue_date) discounting_term_structure = YieldTermStructure() flat_term_structure = FlatForward(settlement_days=1, forward=0.044, calendar=NullCalendar(), daycounter=Actual365Fixed(), compounding=Continuous, frequency=Annual) discounting_term_structure.link_to(flat_term_structure) engine = DiscountingBondEngine(discounting_term_structure) bond.set_pricing_engine(engine) self.assertEqual(Date(10, Jul, 2016), termination_date) self.assertEqual(calendar.advance(todays_date, 3, Days), bond.settlement_date()) self.assertEqual(Date(11, Jul, 2016), bond.maturity_date) self.assertAlmostEqual(0.6849, bond.accrued_amount(bond.settlement_date()), 4) self.assertAlmostEqual(102.1154, bond.clean_price, 4)
def bootstrap_term_structure(self, interpolator='loglinear'): tolerance = 1.0e-15 settings = Settings() calendar = JointCalendar(UnitedStates(), UnitedKingdom()) # must be a business day eval_date = self._eval_date settings.evaluation_date = eval_date settlement_days = self._params.settlement_days settlement_date = calendar.advance(eval_date, settlement_days, Days) # must be a business day settlement_date = calendar.adjust(settlement_date) ts = PiecewiseYieldCurve( 'discount', interpolator, settlement_date, self._rate_helpers, DayCounter.from_name(self._termstructure_daycount), tolerance) self._term_structure = ts self._discount_term_structure = YieldTermStructure(relinkable=True) self._discount_term_structure.link_to(ts) self._forecast_term_structure = YieldTermStructure(relinkable=True) self._forecast_term_structure.link_to(ts) return ts
def setUp(self): self.today = Date(5, 2, 2009) self.settlement_days = 2 self.nominal = 100 self.settings = Settings().__enter__() self.settings.evaluation_date = self.today self.eonia_term_structure = YieldTermStructure() self.eonia_index = Eonia(self.eonia_term_structure) self.calendar = self.eonia_index.fixing_calendar self.settlement = self.calendar.advance(self.today, self.settlement_days, Following) self.eonia_term_structure.link_to(flat_rate(0.05))
class IndexManagerTestCase(unittest.TestCase): settlement_date = Date(1, January, 2014) term_structure = YieldTermStructure() term_structure.link_to(FlatForward(settlement_date, 0.05, Actual365Fixed())) index = USDLibor(Period(3, Months), term_structure) index.add_fixing(Date(5, 2, 2018), 1.79345) index.add_fixing(Date(2, 2, 2018), 1.78902) def test_index_manager_methods(self): self.assertIn(self.index.name.upper(), IndexManager.histories()) ts = IndexManager.get_history(self.index.name.upper()) self.assertEqual(ts[Date(5, 2, 2018)], 1.79345) self.assertEqual(ts[Date(2, 2, 2018)], 1.78902) IndexManager.clear_histories() self.assertFalse(IndexManager.get_history(self.index.name.upper()))
def make_rate_helper(label, rate, dt_obs, currency='USD'): """ Wrapper for deposit and swaps rate helpers makers For Swaps: assume USD swap fixed rates vs. 6M Libor TODO: make this more general """ if (currency.upper() != 'USD'): raise Exception("Only supported currency is USD.") rate_type, tenor, period = _parse_rate_label(label) if not isinstance(dt_obs, Date): dt_obs = pydate_to_qldate(dt_obs) settings = Settings() calendar = JointCalendar(UnitedStates(), UnitedKingdom()) # must be a business day eval_date = calendar.adjust(dt_obs) settings.evaluation_date = eval_date settlement_days = 2 settlement_date = calendar.advance(eval_date, settlement_days, Days) # must be a business day settlement_date = calendar.adjust(settlement_date) end_of_month = True if ((rate_type == 'SWAP') & (period == 'Y')): liborIndex = Libor('USD Libor', Period(6, Months), settlement_days, USDCurrency(), calendar, Actual360(), YieldTermStructure(relinkable=False)) spread = SimpleQuote(0) fwdStart = Period(0, Days) helper = SwapRateHelper.from_tenor(rate, Period(tenor, Years), calendar, Annual, Unadjusted, Thirty360(), liborIndex, spread, fwdStart) elif ((rate_type == 'LIBOR') & (period == 'M')): helper = DepositRateHelper(rate, Period(tenor, Months), settlement_days, calendar, ModifiedFollowing, end_of_month, Actual360()) else: raise Exception("Rate type %s not supported" % label) return (helper)
def setUp(self): self.today = Date(23, November, 2021) Settings().evaluation_date = self.today self.forecast_curve = YieldTermStructure() self.notional = 10_000 self.sofr = Sofr(self.forecast_curve) self.dates = [ Date(18, October, 2021), Date(19, October, 2021), Date(20, October, 2021), Date(21, October, 2021), Date(22, October, 2021), Date(25, October, 2021), Date(26, October, 2021), Date(27, October, 2021), Date(28, October, 2021), Date(29, October, 2021), Date(1, November, 2021), Date(2, November, 2021), Date(3, November, 2021), Date(4, November, 2021), Date(5, November, 2021), Date(8, November, 2021), Date(9, November, 2021), Date(10, November, 2021), Date(12, November, 2021), Date(15, November, 2021), Date(16, November, 2021), Date(17, November, 2021), Date(18, November, 2021), Date(19, November, 2021), Date(22, November, 2021) ] self.past_rates = [ 0.0008, 0.0009, 0.0008, 0.0010, 0.0012, 0.0011, 0.0013, 0.0012, 0.0012, 0.0008, 0.0009, 0.0010, 0.0011, 0.0014, 0.0013, 0.0011, 0.0009, 0.0008, 0.0007, 0.0008, 0.0008, 0.0007, 0.0009, 0.0010, 0.0009 ] self.sofr.add_fixings(self.dates, self.past_rates)
def test_create_swap_index(self): term_structure = YieldTermStructure() term_structure.link_to( FlatForward(forward=0.05, daycounter=Actual365Fixed(), settlement_days=2, calendar=UnitedStates())) ibor_index = USDLibor(Period(3, Months), term_structure) index = SwapIndex('UsdLiborSwapIsdaFixAm', Period(10, Years), 2, USDCurrency(), UnitedStates(GovernmentBond), Period(6, Months), ModifiedFollowing, Thirty360(), ibor_index) index2 = UsdLiborSwapIsdaFixAm(Period(10, Years), term_structure) for attr in [ 'name', 'family_name', 'fixing_calendar', 'tenor', 'day_counter', 'currency' ]: self.assertEqual(getattr(index, attr), getattr(index2, attr))
def testFxMarketConventionsForDatesInEURUSD_ShortEnd(self): """ Testing if FxSwapRateHelper obeys the fx spot market conventions for EURUSD settlement dates on the 3M tenor. """ today = Date(1, 7, 2016) Settings.instance().evaluation_date = today expected_3M_date = Date(5, 10, 2016) fwd_points = 4.0 # critical for ON rate helper period = Period("3M") fixing_days = 2 # empty RelinkableYieldTermStructureHandle is sufficient for testing # dates base_ccy_yts = YieldTermStructure() # In EURUSD, there must be two days to spot date in Target calendar # and one day in US, therefore it is sufficient to pass only Target # as a base calendar. Passing joint calendar would result in wrong # spot date of the trade calendar = TARGET() trading_calendar = UnitedStates() rate_helper = FxSwapRateHelper( SimpleQuote(fwd_points), SimpleQuote(self.fx_spot_quote_EURUSD), period, fixing_days, calendar, ModifiedFollowing, True, True, base_ccy_yts, trading_calendar, ) self.assertEqual(expected_3M_date, rate_helper.latest_date)
def testFxMarketConventionsForDatesInEURUSD_ON_Period(self): """ Testing if FxSwapRateHelper obeys the fx spot market conventions for EURUSD settlement dates on the ON Period. """ today = Date(1, 7, 2016) Settings.instance().evaluation_date = today spot_date = Date(5, 7, 2016) fwd_points = 4.0 # critical for ON rate helper on_period = Period("1d") fixing_days = 0 # empty RelinkableYieldTermStructureHandle is sufficient for testing # dates base_ccy_yts = YieldTermStructure() # In EURUSD, there must be two days to spot date in Target calendar # and one day in US, therefore it is sufficient to pass only Target # as a base calendar calendar = TARGET() trading_calendar = UnitedStates() on_rate_helper = FxSwapRateHelper( SimpleQuote(fwd_points), SimpleQuote(self.fx_spot_quote_EURUSD), on_period, fixing_days, calendar, ModifiedFollowing, False, True, base_ccy_yts, trading_calendar, ) self.assertEqual(spot_date, on_rate_helper.latest_date)
def testFxMarketConventionsForCrossRateONPeriod(self): """ Testing if FxSwapRateHelper obeys the fx spot market conventions for cross rates' ON Period. """ today = Date(1, 7, 2016) Settings.instance().evaluation_date = today spot_date = Date(5, 7, 2016) fwd_points = 4.0 # critical for ON rate helper on_period = Period("1d") fixing_days = 0 # empty RelinkableYieldTermStructureHandle is sufficient for testing # dates base_ccy_yts = YieldTermStructure() us_calendar = UnitedStates() joint_calendar = JointCalendar(TARGET(), Poland()) # Settlement should be on a day where all three centers are operating # and follow EndOfMonth rule on_rate_helper = FxSwapRateHelper( SimpleQuote(fwd_points), SimpleQuote(self.fx_spot_quote_EURPLN), on_period, fixing_days, joint_calendar, ModifiedFollowing, False, True, base_ccy_yts, us_calendar, ) self.assertEqual(spot_date, on_rate_helper.latest_date)
def test_deposit_swap(self): settings = Settings() # Market information calendar = TARGET() todays_date = Date(1, Mar, 2012) # must be a business day eval_date = calendar.adjust(todays_date) settings.evaluation_date = eval_date 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(), YieldTermStructure(relinkable=False)) spread = SimpleQuote(0) fwdStart = Period(0, Days) for m, period, rate in swapData: helper = SwapRateHelper.from_tenor(rate / 100, Period(m, Years), calendar, Annual, Unadjusted, Thirty360(), liborIndex, spread, fwdStart) rate_helpers.append(helper) ts_day_counter = ActualActual(ISDA) tolerance = 1.0e-15 ts = PiecewiseYieldCurve('discount', 'loglinear', settlement_date, rate_helpers, ts_day_counter, tolerance) self.assertEquals(settlement_date, ts.reference_date) # this is not a real test ... self.assertAlmostEquals( 0.9103, ts.discount(calendar.advance(todays_date, 2, Years)), 3) self.assertAlmostEquals( 0.7836, ts.discount(calendar.advance(todays_date, 5, Years)), 3) self.assertAlmostEquals( 0.5827, ts.discount(calendar.advance(todays_date, 10, Years)), 3) self.assertAlmostEquals( 0.4223, ts.discount(calendar.advance(todays_date, 15, Years)), 3)
dON, dTN, dSN, ois1W, ois2W, ois3W, ois1M, oisDated1, oisDated2, oisDated3, oisDated4, oisDated5, ois15M, ois18M, ois21M, ois2Y, ois3Y, ois4Y, ois5Y, ois6Y, ois7Y, ois8Y, ois9Y, ois10Y, ois11Y, ois12Y, ois15Y, ois20Y, ois25Y, ois30Y ] eonia_term_structure = PiecewiseYieldCurve[Discount, Cubic].from_reference_date( todays_date, eonia_instruments, termStructureDayCounter) eonia_term_structure.extrapolation = True # Term structures that will be used for pricing: # the one used for discounting cash flows discountingTermStructure = YieldTermStructure() # the one used for forward rate forecasting forecastingTermStructure = YieldTermStructure() discountingTermStructure.link_to(eonia_term_structure) # /********************* # ** EURIBOR 6M ** # *********************/ euribor6M = Euribor6M() # deposits d6MRate = SimpleQuote(0.00312) # FRAs fra_rates = [
def test_default_constructor(self): term_structure = YieldTermStructure() with self.assertRaises(ValueError): term_structure.discount(Settings().evaluation_date)
def build_eur_curve(self, quotes_date): """ Builds the EUR OIS curve as the collateral currency discount curve :param quotes_date: date fro which it is assumed all market data are valid :return: tuple consisting of objects related to EUR OIS discounting curve: PiecewiseFlatForward, YieldTermStructureHandle RelinkableYieldTermStructureHandle """ calendar = TARGET() settlementDays = 2 todaysDate = quotes_date Settings.instance().evaluation_date = todaysDate todays_Eonia_quote = -0.00341 # market quotes # deposits, key structure as (settlement_days_number, number_of_units_ # for_maturity, unit) deposits = {(0, 1, Days): todays_Eonia_quote} discounting_yts_handle = YieldTermStructure() on_index = Eonia(discounting_yts_handle) on_index.add_fixing(todaysDate, todays_Eonia_quote / 100.0) ois = { (1, Weeks): -0.342, (1, Months): -0.344, (3, Months): -0.349, (6, Months): -0.363, (1, Years): -0.389, } # convert them to Quote objects for k, v in deposits.items(): deposits[k] = SimpleQuote(v / 100.0) for k, v in ois.items(): ois[k] = SimpleQuote(v / 100.0) # build rate helpers dayCounter = Actual360() # looping left if somone wants two add more deposits to tests, e.g. T/N depositHelpers = [ DepositRateHelper( q, Period(n, unit), sett_num, calendar, ModifiedFollowing, True, dayCounter, ) for (sett_num, n, unit), q in deposits.items() ] oisHelpers = [ OISRateHelper( settlementDays, Period(n, unit), q, on_index, discounting_yts_handle ) for (n, unit), q in ois.items() ] rateHelpers = depositHelpers + oisHelpers # term-structure construction oisSwapCurve = PiecewiseYieldCurve[ForwardRate, BackwardFlat].from_reference_date(todaysDate, rateHelpers, Actual360()) oisSwapCurve.extrapolation = True return oisSwapCurve
def test_swap_QL(self): """ Test that a swap with fixed coupon = fair rate has an NPV=0 Create from QL objects """ nominal = 100.0 fixedConvention = Unadjusted floatingConvention = ModifiedFollowing fixedFrequency = Annual floatingFrequency = Semiannual fixedDayCount = Thirty360() floatDayCount = Thirty360() calendar = TARGET() settlement_days = 2 eval_date = Date(2, January, 2014) settings = Settings() settings.evaluation_date = eval_date settlement_date = calendar.advance(eval_date, settlement_days, Days) # must be a business day settlement_date = calendar.adjust(settlement_date) termStructure = YieldTermStructure(relinkable=True) termStructure.link_to( FlatForward(settlement_date, 0.05, Actual365Fixed())) index = Libor('USD Libor', Period(6, Months), settlement_days, USDCurrency(), calendar, Actual360(), termStructure) length = 5 fixedRate = .05 floatingSpread = 0.0 maturity = calendar.advance(settlement_date, length, Years, convention=floatingConvention) fixedSchedule = Schedule(settlement_date, maturity, Period(fixedFrequency), calendar, fixedConvention, fixedConvention, Rule.Forward, False) floatSchedule = Schedule(settlement_date, maturity, Period(floatingFrequency), calendar, floatingConvention, floatingConvention, Rule.Forward, False) engine = DiscountingSwapEngine(termStructure, False, settlement_date, settlement_date) for swap_type in [Payer, Receiver]: swap = VanillaSwap(swap_type, nominal, fixedSchedule, fixedRate, fixedDayCount, floatSchedule, index, floatingSpread, floatDayCount, fixedConvention) swap.set_pricing_engine(engine) fixed_leg = swap.fixed_leg floating_leg = swap.floating_leg f = swap.fair_rate print('fair rate: %f' % f) p = swap.net_present_value print('NPV: %f' % p) swap = VanillaSwap(swap_type, nominal, fixedSchedule, f, fixedDayCount, floatSchedule, index, floatingSpread, floatDayCount, fixedConvention) swap.set_pricing_engine(engine) p = swap.net_present_value print('NPV: %f' % p) self.assertAlmostEqual(p, 0)
def test_zero_curve_on_swap_index(self): todays_date = today() calendar = UnitedStates() # INPUT dayCounter = Actual360() # INPUT currency = USDCurrency() # INPUT Settings.instance().evaluation_date = todays_date settlement_days = 2 settlement_date = calendar.advance(todays_date, period=Period( settlement_days, Days)) liborRates = [ 0.002763, 0.004082, 0.005601, 0.006390, 0.007125, 0.007928, 0.009446, 0.01110 ] liborRatesTenor = [ Period(tenor, Months) for tenor in [1, 2, 3, 4, 5, 6, 9, 12] ] Libor_dayCounter = Actual360() swapRates = [ 0.005681, 0.006970, 0.009310, 0.012010, 0.014628, 0.016881, 0.018745, 0.020260, 0.021545 ] swapRatesTenor = [Period(i, Years) for i in range(2, 11)] # description of the fixed leg of the swap Swap_fixedLegTenor = Period(12, Months) # INPUT Swap_fixedLegConvention = ModifiedFollowing # INPUT Swap_fixedLegDayCounter = Actual360() # INPUT # description of the float leg of the swap Swap_iborIndex = Libor("USDLibor", Period(3, Months), settlement_days, USDCurrency(), UnitedStates(), Actual360(), YieldTermStructure(relinkable=False)) SwapFamilyName = currency.name + "swapIndex" instruments = [] # ++++++++++++++++++++ Creation of the vector of RateHelper (need for the Yield Curve construction) # ++++++++++++++++++++ Libor LiborFamilyName = currency.name + "Libor" instruments = [] for rate, tenor in zip(liborRates, liborRatesTenor): # Index description ___ creation of a Libor index liborIndex = Libor(LiborFamilyName, tenor, settlement_days, currency, calendar, Libor_dayCounter, YieldTermStructure(relinkable=False)) # Initialize rate helper # the DepositRateHelper link the recording rate with the Libor # index instruments.append(DepositRateHelper(rate, index=liborIndex)) for tenor, rate in zip(swapRatesTenor, swapRates): # swap description ___ creation of a swap index. The floating leg is described in the index 'Swap_iborIndex' swapIndex = SwapIndex(SwapFamilyName, tenor, settlement_days, currency, calendar, Swap_fixedLegTenor, Swap_fixedLegConvention, Swap_fixedLegDayCounter, Swap_iborIndex) # Initialize rate helper __ the SwapRateHelper links the swap index width his rate instruments.append(SwapRateHelper.from_index(rate, swapIndex)) # ++++++++++++++++++ Now the creation of the yield curve tolerance = 1.0e-15 ts = PiecewiseYieldCurve('zero', 'linear', settlement_date, instruments, dayCounter, tolerance) self.assertEquals(settlement_date, ts.reference_date)
def test_pricing_bond(self): '''Inspired by the C++ code from http://quantcorner.wordpress.com/.''' settings = Settings() # Date setup calendar = TARGET() # Settlement date settlement_date = calendar.adjust(Date(28, January, 2011)) # Evaluation date fixing_days = 1 settlement_days = 1 todays_date = calendar.advance(settlement_date, -fixing_days, Days) settings.evaluation_date = todays_date # Bound attributes face_amount = 100.0 redemption = 100.0 issue_date = Date(27, January, 2011) maturity_date = Date(31, August, 2020) coupon_rate = 0.03625 bond_yield = 0.034921 discounting_term_structure = YieldTermStructure(relinkable=True) flat_term_structure = FlatForward( reference_date=settlement_date, forward=bond_yield, daycounter=Actual365Fixed( ), #actual_actual.ActualActual(actual_actual.Bond), compounding=Compounded, frequency=Semiannual) # have a look at the FixedRateBondHelper to simplify this # construction discounting_term_structure.link_to(flat_term_structure) #Rate fixed_bond_schedule = Schedule(issue_date, maturity_date, Period(Semiannual), UnitedStates(market=GOVERNMENTBOND), Unadjusted, Unadjusted, Backward, False) bond = FixedRateBond(settlement_days, face_amount, fixed_bond_schedule, [coupon_rate], ActualActual(Bond), Unadjusted, redemption, issue_date) bond.set_pricing_engine(discounting_term_structure) # tests self.assertTrue(Date(27, January, 2011), bond.issue_date) self.assertTrue(Date(31, August, 2020), bond.maturity_date) self.assertTrue(settings.evaluation_date, bond.valuation_date) # the following assertion fails but must be verified self.assertAlmostEqual(101.1, bond.clean_price, 1) self.assertAlmostEqual(101.1, bond.net_present_value, 1) self.assertAlmostEqual(101.1, bond.dirty_price) self.assertAlmostEqual(0.009851, bond.accrued_amount()) print(settings.evaluation_date) print('Principal: {}'.format(face_amount)) print('Issuing date: {} '.format(bond.issue_date)) print('Maturity: {}'.format(bond.maturity_date)) print('Coupon rate: {:.4%}'.format(coupon_rate)) print('Yield: {:.4%}'.format(bond_yield)) print('Net present value: {:.4f}'.format(bond.net_present_value)) print('Clean price: {:.4f}'.format(bond.clean_price)) print('Dirty price: {:.4f}'.format(bond.dirty_price)) print('Accrued coupon: {:.6f}'.format(bond.accrued_amount())) print('Accrued coupon: {:.6f}'.format( bond.accrued_amount(Date(1, March, 2011))))
settlement_days = 3 face_amount = 100.0 coupon_rate = 0.05 redemption = 100.0 fixed_bond_schedule = Schedule(effective_date, termination_date, Period(Annual), calendar, ModifiedFollowing, ModifiedFollowing, Backward) issue_date = effective_date bond = FixedRateBond(settlement_days, face_amount, fixed_bond_schedule, [coupon_rate], ActualActual(ISMA), Following, redemption, issue_date) discounting_term_structure = YieldTermStructure(relinkable=True) flat_term_structure = FlatForward(settlement_days=1, forward=0.044, calendar=NullCalendar(), daycounter=Actual365Fixed(), compounding=Continuous, frequency=Annual) discounting_term_structure.link_to(flat_term_structure) pricing_engine = DiscountingBondEngine(discounting_term_structure) bond.set_pricing_engine(pricing_engine) print('Settlement date: ', bond.settlement_date()) print('Maturity date:', bond.maturity_date) print('Accrued amount: ', bond.accrued_amount(bond.settlement_date())) print('Clean price:', bond.clean_price)
def test_display(self): settings = Settings() # Date setup calendar = TARGET() # Settlement date settlement_date = calendar.adjust(Date(28, January, 2011)) # Evaluation date fixing_days = 1 settlement_days = 1 todays_date = calendar.advance( settlement_date, -fixing_days, Days ) settings.evaluation_date = todays_date # Bound attributes face_amount = 100.0 redemption = 100.0 issue_date = Date(27, January, 2011) maturity_date = Date(31, August, 2020) coupon_rate = 0.03625 bond_yield = 0.034921 flat_discounting_term_structure = YieldTermStructure() flat_term_structure = FlatForward( reference_date = settlement_date, forward = bond_yield, daycounter = Actual365Fixed(), #actual_actual.ActualActual(actual_actual.Bond), compounding = Compounded, frequency = Semiannual) # have a look at the FixedRateBondHelper to simplify this # construction flat_discounting_term_structure.link_to(flat_term_structure) #Rate fixed_bond_schedule = Schedule( issue_date, maturity_date, Period(Semiannual), UnitedStates(market=GOVERNMENTBOND), Unadjusted, Unadjusted, Backward, False); bond = FixedRateBond( settlement_days, face_amount, fixed_bond_schedule, [coupon_rate], ActualActual(Bond), Unadjusted, redemption, issue_date ) d=bf.startDate(bond) zspd=bf.zSpread(bond, 100.0, flat_term_structure, Actual365Fixed(), Compounded, Semiannual, settlement_date, 1e-6, 100, 0.5) #Also need a test case for a PiecewiseTermStructure... 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(SimpleQuote(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(), YieldTermStructure(relinkable=False)) spread = SimpleQuote(0) fwdStart = Period(0, Days) for m, period, rate in swapData: helper = SwapRateHelper.from_tenor( SimpleQuote(rate/100), Period(m, Years), calendar, Annual, Unadjusted, Thirty360(), liborIndex, spread, fwdStart ) rate_helpers.append(helper) ts_day_counter = ActualActual(ISDA) tolerance = 1.0e-15 ts = PiecewiseYieldCurve.from_reference_date( BootstrapTrait.Discount, Interpolator.LogLinear, settlement_date, rate_helpers, ts_day_counter, tolerance) pyc_zspd=bf.zSpread(bond, 102.0, ts, ActualActual(ISDA), Compounded, Semiannual, Date(1, April, 2015), 1e-6, 100, 0.5) pyc_zspd_disco=bf.zSpread(bond, 95.0, ts, ActualActual(ISDA), Compounded, Semiannual, settlement_date, 1e-6, 100, 0.5) yld = bf.yld(bond, 102.0, ActualActual(ISDA), Compounded, Semiannual, settlement_date, 1e-6, 100, 0.5) dur = bf.duration(bond, yld, ActualActual(ISDA), Compounded, Semiannual, 2, settlement_date) yld_disco = bf.yld(bond, 95.0, ActualActual(ISDA), Compounded, Semiannual, settlement_date, 1e-6, 100, 0.5) dur_disco = bf.duration(bond, yld_disco, ActualActual(ISDA), Compounded, Semiannual, 2, settlement_date) self.assertEqual(round(zspd, 6), 0.001281) self.assertEqual(round(pyc_zspd, 4), -0.0264) self.assertEqual(round(pyc_zspd_disco, 4), -0.0114) self.assertEqual(round(yld, 4), 0.0338) self.assertEqual(round(yld_disco, 4), 0.0426) self.assertEqual(round(dur, 4), 8.0655) self.assertEqual(round(dur_disco, 4), 7.9702)
def _bndprice(bond_yield, coupon_rate, pricing_date, maturity_date, period, basis, compounding_frequency): """ Clean price and accrued interest of a bond """ _period = str_to_frequency(period) evaluation_date = pydate_to_qldate(pricing_date) settings = Settings() settings.evaluation_date = evaluation_date calendar = TARGET() termination_date = pydate_to_qldate(maturity_date) # effective date must be before settlement date, but do not # care about exact issuance date of bond effective_date = Date(termination_date.day, termination_date.month, evaluation_date.year) effective_date = calendar.advance(effective_date, -1, Years, convention=Unadjusted) settlement_date = calendar.advance(evaluation_date, 2, Days, convention=ModifiedFollowing) face_amount = 100.0 redemption = 100.0 fixed_bond_schedule = Schedule(effective_date, termination_date, Period(_period), calendar, ModifiedFollowing, ModifiedFollowing, Backward) issue_date = effective_date cnt = DayCounter.from_name(basis) settlement_days = 2 bond = FixedRateBond(settlement_days, face_amount, fixed_bond_schedule, [coupon_rate], cnt, Following, redemption, issue_date) discounting_term_structure = YieldTermStructure(relinkable=True) cnt_yield = DayCounter.from_name('Actual/Actual (Historical)') flat_term_structure = FlatForward(settlement_days=2, forward=bond_yield, calendar=NullCalendar(), daycounter=cnt_yield, compounding=Compounded, frequency=_period) discounting_term_structure.link_to(flat_term_structure) engine = DiscountingBondEngine(discounting_term_structure) bond.set_pricing_engine(engine) price = bond.clean_price ac = bond.accrued_amount(pydate_to_qldate(settlement_date)) return (price, ac)
def test_excel_example_with_floating_rate_bond(self): todays_date = Date(25, August, 2011) settings = Settings() settings.evaluation_date = todays_date calendar = TARGET() effective_date = Date(10, Jul, 2006) termination_date = calendar.advance(effective_date, 10, Years, convention=Unadjusted) settlement_date = calendar.adjust(Date(28, January, 2011)) settlement_days = 3 #1 face_amount = 13749769.27 #2 coupon_rate = 0.05 redemption = 100.0 float_bond_schedule = Schedule(effective_date, termination_date, Period(Annual), calendar, ModifiedFollowing, ModifiedFollowing, Backward) #3 flat_discounting_term_structure = YieldTermStructure(relinkable=True) forecastTermStructure = YieldTermStructure(relinkable=True) dc = Actual360() ibor_index = Euribor6M(forecastTermStructure) #5 fixing_days = 2 #6 gearings = [1, 0.0] #7 spreads = [1, 0.05] #8 caps = [] #9 floors = [] #10 pmt_conv = ModifiedFollowing #11 issue_date = effective_date float_bond = FloatingRateBond(settlement_days, face_amount, float_bond_schedule, ibor_index, dc, fixing_days, gearings, spreads, caps, floors, pmt_conv, redemption, issue_date) flat_term_structure = FlatForward(settlement_days=1, forward=0.055, calendar=NullCalendar(), daycounter=Actual365Fixed(), compounding=Continuous, frequency=Annual) flat_discounting_term_structure.link_to(flat_term_structure) forecastTermStructure.link_to(flat_term_structure) engine = DiscountingBondEngine(flat_discounting_term_structure) float_bond.set_pricing_engine(engine) cons_option_vol = ConstantOptionletVolatility(settlement_days, UnitedStates(SETTLEMENT), pmt_conv, 0.95, Actual365Fixed()) coupon_pricer = BlackIborCouponPricer(cons_option_vol) set_coupon_pricer(float_bond, coupon_pricer) self.assertEquals(Date(10, Jul, 2016), termination_date) self.assertEquals(calendar.advance(todays_date, 3, Days), float_bond.settlement_date()) self.assertEquals(Date(11, Jul, 2016), float_bond.maturity_date) self.assertAlmostEqual( 0.6944, float_bond.accrued_amount(float_bond.settlement_date()), 4) self.assertAlmostEqual(98.2485, float_bond.dirty_price, 4) self.assertAlmostEqual(13500805.2469, float_bond.npv, 4)