def test_christmas_is_holiday(self): calendar = TARGET() date = Date(24, 12, 2011) self.assertTrue(calendar.is_holiday(date))
def test_christmas_is_holiday(self): calendar = TARGET() date = Date(24,12, 2011) self.assertTrue(calendar.is_holiday(date))
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_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., 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) bond.set_pricing_engine(discounting_term_structure) 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)
class FlatForwardTestCase(unittest.TestCase): def setUp(self): self.calendar = TARGET() self.settlement_days = 2 self.adjusted_today = self.calendar.adjust(today()) Settings().evaluation_date = self.adjusted_today self.settlement_date = self.calendar.advance(today(), self.settlement_days, Days) def test_reference_evaluation_data_changed(self): """Testing term structure against evaluation date change... """ quote = SimpleQuote() term_structure = FlatForward( settlement_days=self.settlement_days, forward=quote, calendar=NullCalendar(), daycounter=Actual360() ) quote.value = 0.03 expected = [] for days in [10, 30, 60, 120, 360, 720]: expected.append(term_structure.discount(self.adjusted_today + days)) Settings().evaluation_date = self.adjusted_today + 30 calculated = [] for days in [10, 30, 60, 120, 360, 720]: calculated.append(term_structure.discount(self.adjusted_today + 30 + days)) for i, val in enumerate(expected): self.assertAlmostEquals(val, calculated[i])
def setUp(self): self.calendar = TARGET() self.settlement_days = 2 self.adjusted_today = self.calendar.adjust(today()) Settings().evaluation_date = self.adjusted_today self.settlement_date = self.calendar.advance( today(), self.settlement_days, Days )
def _cfamounts(coupon_rate, pricing_date, maturity_date, period, basis): """ cash flow schedule """ _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) 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) res = zip(*bond.cashflows) return(res)
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( 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) engine = DiscountingBondEngine(discounting_term_structure) bond.set_pricing_engine(engine) self.assertEquals(Date(10, Jul, 2016), termination_date) self.assertEquals(calendar.advance(todays_date, 3, Days), bond.settlement_date()) self.assertEquals(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 zbt_libor_yield(instruments, yields, pricing_date, basis='Actual/Actual (Bond)', compounding_freq='Continuous', maturity_dates=None): """ Bootstrap a zero-coupon curve from libor rates and swap yields Args: insruments: list of instruments, of the form Libor?M for Libor rates and Swap?Y for swap rates yields: market rates pricing_date: the date where market data is observed. Settlement is by default 2 days after pricing_date Optional: compounding_frequency: ... of zero-coupon rates. By default: 'Continuous' Returns: zero_rate: zero-coupon rate maturity_date: ... of corresponding rate """ calendar = TARGET() settings = Settings() # must be a business day eval_date = calendar.adjust(pydate_to_qldate(pricing_date)) settings.evaluation_date = eval_date rates = dict(zip(instruments, yields)) ts = make_term_structure(rates, pricing_date) cnt = DayCounter.from_name(basis) if maturity_dates is None: # schedule of maturity dates from settlement date to last date on # the term structure s = Schedule(effective_date=ts.reference_date, termination_date=ts.max_date, tenor=Period(1, Months), calendar=TARGET()) maturity_dates = [qldate_to_pydate(dt) for dt in s.dates()] cp_freq = compounding_from_name(compounding_freq) zc = [ts.zero_rate(date=pydate_to_qldate(dt), day_counter=cnt, compounding=cp_freq).rate for dt in maturity_dates] return (maturity_dates, zc)
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(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) engine = DiscountingBondEngine(discounting_term_structure) bond.set_pricing_engine(engine) self.assertEquals(Date(10, Jul, 2016), termination_date) self.assertEquals(calendar.advance(todays_date, 3, Days), bond.settlement_date()) self.assertEquals(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 test_calendar_creation(self): calendar = TARGET() self.assertEquals('TARGET', calendar.name()) ukcalendar = UnitedKingdom() self.assertEquals('UK settlement', ukcalendar.name()) lse_cal = UnitedKingdom(market=EXCHANGE) self.assertEquals('London stock exchange', lse_cal.name()) null_calendar = NullCalendar() self.assertEquals('Null', null_calendar.name())
def setUp(self): self.calendar = TARGET() self.settlement_days = 2 self.adjusted_today = self.calendar.adjust(today()) Settings().evaluation_date = self.adjusted_today self.settlement_date = self.calendar.advance(today(), self.settlement_days, Days)
def test_bucket_analysis_option(self): settings = Settings() calendar = TARGET() todays_date = Date(15, May, 1998) settlement_date = Date(17, May, 1998) settings.evaluation_date = todays_date option_type = Put underlying = 40 strike = 40 dividend_yield = 0.00 risk_free_rate = 0.001 volatility = 0.20 maturity = Date(17, May, 1999) daycounter = Actual365Fixed() underlyingH = SimpleQuote(underlying) payoff = PlainVanillaPayoff(option_type, strike) flat_term_structure = FlatForward(reference_date=settlement_date, forward=risk_free_rate, daycounter=daycounter) flat_dividend_ts = FlatForward(reference_date=settlement_date, forward=dividend_yield, daycounter=daycounter) flat_vol_ts = BlackConstantVol(settlement_date, calendar, volatility, daycounter) black_scholes_merton_process = BlackScholesMertonProcess( underlyingH, flat_dividend_ts, flat_term_structure, flat_vol_ts) european_exercise = EuropeanExercise(maturity) european_option = VanillaOption(payoff, european_exercise) analytic_european_engine = AnalyticEuropeanEngine( black_scholes_merton_process) european_option.set_pricing_engine(analytic_european_engine) ba_eo = bucket_analysis([[underlyingH]], [european_option], [1], 0.50, 1) self.assertTrue(2, ba_eo) self.assertTrue(type(tuple), ba_eo) self.assertEquals(1, len(ba_eo[0][0])) self.assertEquals(-0.4582666150152517, ba_eo[0][0][0])
class FlatForwardTestCase(unittest.TestCase): def setUp(self): self.calendar = TARGET() self.settlement_days = 2 self.adjusted_today = self.calendar.adjust(today()) Settings().evaluation_date = self.adjusted_today self.settlement_date = self.calendar.advance( today(), self.settlement_days, Days ) def test_reference_evaluation_data_changed(self): """Testing term structure against evaluation date change... """ quote = SimpleQuote() term_structure = FlatForward(settlement_days=self.settlement_days, forward=quote, calendar=NullCalendar(), daycounter=Actual360()) quote.value = 0.03 expected = [] for days in [10, 30, 60, 120, 360, 720]: expected.append( term_structure.discount(self.adjusted_today + days) ) Settings().evaluation_date = self.adjusted_today + 30 calculated = [] for days in [10, 30, 60, 120, 360, 720]: calculated.append( term_structure.discount(self.adjusted_today+ 30 + days) ) for i, val in enumerate(expected): self.assertAlmostEquals(val, calculated[i])
def test_iteration_on_date_list(self): date_iterator = holiday_list(TARGET(), Date(1, Jan, 2000), Date(1, Jan, 2001)) holidays = [ Date(21, Apr, 2000), Date(24, Apr, 2000), Date(1, May, 2000), Date(25, Dec, 2000), Date(26, Dec, 2000), Date(1, Jan, 2001) ] for date in date_iterator: self.assertIn(date, holidays)
class CalendarFactory: _lookup = dict([(cal.name(), cal) for cal in [ TARGET(), NullCalendar(), Germany(), Germany(EUREX), Germany(FrankfurtStockExchange), Germany(GER_SETTLEMENT), Germany(EUWAX), Germany(XETRA), UnitedKingdom(), UnitedKingdom(EXCHANGE), UnitedKingdom(METALS), UnitedKingdom(UK_SETTLEMENT), UnitedStates(), UnitedStates(GOVERNMENTBOND), UnitedStates(NYSE), UnitedStates(NERC), UnitedStates(US_SETTLEMENT) ]])
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)
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)
def test_bucketanalysis_bond(self): settings = Settings() calendar = TARGET() settlement_date = calendar.adjust(Date(28, January, 2011)) simple_quotes = [] fixing_days = 1 settlement_days = 1 todays_date = calendar.advance( settlement_date, -fixing_days, Days ) settings.evaluation_date = todays_date face_amount = 100.0 redemption = 100.0 issue_date = Date(27, January, 2011) maturity_date = Date(1, January, 2021) coupon_rate = 0.055 bond_yield = 0.034921 flat_discounting_term_structure = YieldTermStructure(relinkable=True) flat_term_structure = FlatForward( reference_date = settlement_date, forward = bond_yield, daycounter = Actual365Fixed(), compounding = Compounded, frequency = Semiannual) flat_discounting_term_structure.link_to(flat_term_structure) 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 ) bfs=bf.BondFunctions() d=bfs.startDate(bond) bfs.display() zspd=bfs.zSpread(bond,100.0,flat_term_structure,Actual365Fixed(), Compounded,Semiannual,settlement_date,1e-6,100,0.5) 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) sq_rate = SimpleQuote(rate/100) helper = DepositRateHelper(sq_rate, tenor, settlement_days, calendar, ModifiedFollowing, end_of_month, Actual360()) simple_quotes.append(sq_rate) 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: sq_rate = SimpleQuote(rate/100) helper = SwapRateHelper.from_tenor( sq_rate, Period(m, Years), calendar, Annual, Unadjusted, Thirty360(), liborIndex, spread, fwdStart ) simple_quotes.append(sq_rate) 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) discounting_term_structure = YieldTermStructure(relinkable=True) discounting_term_structure.link_to(ts) pricing_engine = DiscountingBondEngine(discounting_term_structure) bond.set_pricing_engine(pricing_engine) self.assertAlmostEquals(bond.npv, 100.83702940160767) ba = bucketAnalysis([simple_quotes],[bond],[1],0.0001, 1) self.assertTrue(2,ba) self.assertTrue(type(tuple),ba) self.assertEquals(len(simple_quotes),len(ba[0][0])) self.assertEquals(0, ba[0][0][8])
from quantlib.time.calendars.null_calendar import NullCalendar import quantlib.time.calendars.germany as ger import quantlib.time.calendars.united_states as us import quantlib.time.calendars.united_kingdom as uk import quantlib.time.calendars.japan as jp import quantlib.time.calendars.switzerland as sw from quantlib.time.calendar import TARGET from quantlib.util.object_registry import ObjectRegistry #ISO-3166 country codes (http://en.wikipedia.org/wiki/ISO_3166-1) ISO_3166_CALENDARS = { 'TARGET': TARGET(), 'NULL': NullCalendar(), 'DEU': ger.Germany(), 'EUREX': ger.Germany(ger.EUREX), 'FSE': ger.Germany(ger.FRANKFURT_STOCK_EXCHANGE), 'EUWAX': ger.Germany(ger.EUWAX), 'XETRA': ger.Germany(ger.XETRA), 'GBR': uk.UnitedKingdom(), 'LSE': uk.UnitedKingdom(uk.EXCHANGE), 'LME': uk.UnitedKingdom(uk.METALS), 'USA': us.UnitedStates(), 'USA-GVT-BONDS': us.UnitedStates(us.GOVERNMENTBOND), 'NYSE': us.UnitedStates(us.NYSE), 'NERC': us.UnitedStates(us.NERC), 'JPN': jp.Japan(), 'CHE': sw.Switzerland() } def initialize_code_registry():
from quantlib.compounding import Continuous from quantlib.pricingengines.bond import DiscountingBondEngine from quantlib.time.date import Date, August, Period, Jul, Annual, Years from quantlib.time.daycounter import Actual365Fixed from quantlib.time.daycounters.actual_actual import ActualActual, ISMA from quantlib.time.schedule import Schedule, Backward from quantlib.settings import Settings from quantlib.termstructures.yields.api import (FlatForward, YieldTermStructure) todays_date = Date(25, August, 2011) settings = Settings.instance() 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(effective_date, termination_date, Period(Annual), calendar, ModifiedFollowing, ModifiedFollowing, Backward)
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))))
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_bucketanalysis_bond(self): settings = Settings() calendar = TARGET() settlement_date = calendar.adjust(Date(28, January, 2011)) simple_quotes = [] fixing_days = 1 settlement_days = 1 todays_date = calendar.advance(settlement_date, -fixing_days, Days) settings.evaluation_date = todays_date face_amount = 100.0 redemption = 100.0 issue_date = Date(27, January, 2011) maturity_date = Date(1, January, 2021) coupon_rate = 0.055 bond_yield = 0.034921 flat_discounting_term_structure = YieldTermStructure(relinkable=True) flat_term_structure = FlatForward(reference_date=settlement_date, forward=bond_yield, daycounter=Actual365Fixed(), compounding=Compounded, frequency=Semiannual) flat_discounting_term_structure.link_to(flat_term_structure) 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) zspd = bf.zSpread(bond, 100.0, flat_term_structure, Actual365Fixed(), Compounded, Semiannual, settlement_date, 1e-6, 100, 0.5) 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) sq_rate = SimpleQuote(rate / 100) helper = DepositRateHelper(sq_rate, tenor, settlement_days, calendar, ModifiedFollowing, end_of_month, Actual360()) simple_quotes.append(sq_rate) 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: sq_rate = SimpleQuote(rate / 100) helper = SwapRateHelper.from_tenor(sq_rate, Period(m, Years), calendar, Annual, Unadjusted, Thirty360(), liborIndex, spread, fwdStart) simple_quotes.append(sq_rate) 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) discounting_term_structure = YieldTermStructure(relinkable=True) discounting_term_structure.link_to(ts) pricing_engine = DiscountingBondEngine(discounting_term_structure) bond.set_pricing_engine(pricing_engine) self.assertAlmostEquals(bond.npv, 100.83702940160767) ba = bucket_analysis([simple_quotes], [bond], [1], 0.0001, 1) self.assertTrue(2, ba) self.assertTrue(type(tuple), ba) self.assertEquals(len(simple_quotes), len(ba[0][0])) self.assertEquals(0, ba[0][0][8])
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(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 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( 'discount', '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 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)) )
from quantlib.time.date import Date, August, Period, Jul, Annual, Years from quantlib.time.daycounter import Actual365Fixed from quantlib.time.daycounters.actual_actual import ActualActual, ISMA from quantlib.time.schedule import Schedule, Backward from quantlib.settings import Settings from quantlib.termstructures.yields.api import ( FlatForward, YieldTermStructure ) 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( effective_date, termination_date, Period(Annual),
def test_pricing_bond(): '''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) return bond
class Calendars(dict): ''' Wrapper for quantlib Calendar objects and methods. Accepts python.datetime objects and strings instead of pyql.quantlib dates. :adjust: Adjust date to business day :advance: Advance date by specified period :is_business_day: Checks date can be used as a dict using name property of pyql.quantlib.calendar objects for example: Calendars()['TARGET'] returns TARGET calendar ''' from quantlib.time.calendar import TARGET from quantlib.time.calendars.null_calendar import NullCalendar from quantlib.time.calendars.germany import ( Germany, EUREX, FrankfurtStockExchange, SETTLEMENT as GER_SETTLEMENT, EUWAX, XETRA ) from quantlib.time.calendars.united_kingdom import ( EXCHANGE, METALS, SETTLEMENT as UK_SETTLEMENT, UnitedKingdom ) from quantlib.time.calendars.united_states import ( UnitedStates, GOVERNMENTBOND, NYSE, NERC, SETTLEMENT as US_SETTLEMENT ) _lookup = dict([(cal.name(), cal) for cal in [TARGET(), NullCalendar(), Germany(), Germany(EUREX), Germany( FrankfurtStockExchange), Germany(GER_SETTLEMENT), Germany( EUWAX), Germany(XETRA), UnitedKingdom(), UnitedKingdom(EXCHANGE), UnitedKingdom(METALS), UnitedKingdom(UK_SETTLEMENT), UnitedStates(), UnitedStates(GOVERNMENTBOND), UnitedStates( NYSE), UnitedStates(NERC), UnitedStates(US_SETTLEMENT)] ] ) def __init__(self, *args): dict.__init__(self, self._lookup) self.update(*args) @classmethod def adjust(cls, date, 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(pydate(date)) try: return pydate_from_qldate(calendar.adjust(qldate, convention)) except: try: return pydate_from_qldate(calendar().adjust(qldate, convention)) except: return None @classmethod def advance(cls, date, 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(pydate(date)) 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 @classmethod def is_business_day(cls, date, calendar=None): if not calendar: calendar = cls.TARGET() elif not hasattr(calendar, "advance"): return None qldate = qldate_from_pydate(pydate(date)) try: return calendar.is_business_day(qldate) except: try: return calendar().is_business_day(qldate) except: return None