def test_ed(self): """ Curve construction with EuroDollar futures Not checking numerical accuracy """ # US libor market, with default conventions: # semi-annual fixed vs. 3M Libor m = libor_market('USD(LONDON)') # add quotes eval_date = Date(20, 9, 2004) quotes = [('ED', 1, 96.2875), ('ED', 2, 96.7875), ('ED', 3, 96.9875), ('ED', 4, 96.6875), ('ED', 5, 96.4875), ('ED', 6, 96.3875), ('ED', 7, 96.2875), ('ED', 8, 96.0875)] m.set_quotes(eval_date, quotes) m.bootstrap_term_structure() dt = Date(1, 1, 2005) df = m.discount(dt) print('discount factor for %s (USD Libor): %f' % (dt, df)) self.assertTrue(df > 0)
def test_euribor(self): """ Market tests for Euribor futures. Not checking numerical accuracy. """ # Euribor market instance. m = IborMarket('Euribor Market', 'EUR:1Y') evaluation_date = Date(20, 3, 2014) quotes = [ (u'ERM4', Date(18, 6, 2014), 99.67), (u'ERU4', Date(17, 9, 2014), 99.67), (u'ERZ4', Date(17, 12, 2014), 99.66), (u'ERH5', Date(18, 3, 2015), 99.63), (u'ERM5', Date(17, 6, 2015), 99.59), (u'ERU5', Date(16, 9, 2015), 99.53), (u'ERZ5', Date(16, 12, 2015), 99.46), (u'ERH6', Date(16, 3, 2016), 99.38), ] m.set_quotes(evaluation_date, quotes) m.bootstrap_term_structure() dt = Date(20, 6, 2014) df = m.discount(dt) self.assertTrue(df > 0)
def test_create_fixed_rate_bond_helper(self): issue_date = Date(20, 3, 2014) maturity = Date(20, 3, 2019) schedule = Schedule( issue_date, maturity, Period(Annual), TARGET(), ModifiedFollowing, ModifiedFollowing, Backward, False ) clean_price = 71.23 settlement_days = 3 rates = [0.035] daycounter = DayCounter.from_name("Actual/Actual (Bond)") helper = FixedRateBondHelper( SimpleQuote(clean_price), settlement_days, 100.0, schedule, rates, daycounter, Following, 100.0, issue_date) self.assertEqual(helper.quote, clean_price)
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 testFxMarketConventionsForCrossRate(self): """ Testing if FxSwapRateHelper obeys the fx spot market conventions for cross rates. """ today = Date(1, 7, 2016) spot_date = Date(5, 7, 2016) self.build_curves(today) us_calendar = UnitedStates() joint_calendar = JointCalendar(TARGET(), Poland()) settlement_calendar = JointCalendar(joint_calendar, us_calendar) # Settlement should be on a day where all three centers are operating # and follow EndOfMonth rule maturities = [ settlement_calendar.advance(spot_date, n, unit, convention=ModifiedFollowing, end_of_month=True) for n, unit in self.fx_swap_quotes ] for m, helper in zip(maturities, self.eur_pln_fx_swap_helpers): self.assertEqual(m, helper.latest_date)
def test_implied_ts(self): dates = [Date('2017-09-11'), Date('2017-12-11'), Date('2018-03-11')] dfs = [1.0, 0.8, 0.7] dc = DiscountCurve(dates, dfs, Actual365Fixed()) dc_implied = ImpliedTermStructure(dc, Date('2017-11-11')) for d in dates[1:]: self.assertEqual(dc_implied.discount(d), dc.discount(d) / dc.discount(Date('2017-11-11')))
def test_creation(self): settings = Settings() # Market information calendar = TARGET() # must be a business day settings.evaluation_date = calendar.adjust(today()) settlement_date = Date(18, September, 2008) # must be a business day settlement_date = calendar.adjust(settlement_date); quotes = [SimpleQuote(0.0096), SimpleQuote(0.0145), SimpleQuote(0.0194)] tenors = [3, 6, 12] rate_helpers = [] calendar = TARGET() deposit_day_counter = Actual365Fixed() convention = ModifiedFollowing end_of_month = True for quote, month in zip(quotes, tenors): tenor = Period(month, Months) fixing_days = 3 helper = DepositRateHelper( quote, tenor, fixing_days, calendar, convention, end_of_month, deposit_day_counter ) rate_helpers.append(helper) ts_day_counter = ActualActual(ISDA) tolerance = 1.0e-15 ts = PiecewiseYieldCurve[BootstrapTrait.Discount, LogLinear].from_reference_date( settlement_date, rate_helpers, ts_day_counter, accuracy=tolerance ) self.assertIsNotNone(ts) self.assertEqual( Date(18, September, 2008), ts.reference_date) # this is not a real test ... self.assertAlmostEqual(0.9975, ts.discount(Date(21, 12, 2008)), 4) self.assertAlmostEqual(0.9944, ts.discount(Date(21, 4, 2009)), 4) self.assertAlmostEqual(0.9904, ts.discount(Date(21, 9, 2009)), 4) dates, dfs = zip(*ts.nodes) self.assertAlmostEqual(list(dates), ts.dates) self.assertAlmostEqual(list(dfs), ts.data)
def test_hull_white_calibration(self): """ Adapted from ShortRateModelTest::testCachedHullWhite() """ today = Date(15, February, 2002) settlement = Date(19, February, 2002) self.settings.evaluation_date = today yield_ts = FlatForward(settlement, forward=0.04875825, settlement_days=0, calendar=NullCalendar(), daycounter=Actual365Fixed()) model = HullWhite(yield_ts, a=0.05, sigma=.005) data = [[1, 5, 0.1148 ], [2, 4, 0.1108 ], [3, 3, 0.1070 ], [4, 2, 0.1021 ], [5, 1, 0.1000 ]] index = Euribor6M(yield_ts) engine = JamshidianSwaptionEngine(model) swaptions = [] for start, length, volatility in data: vol = SimpleQuote(volatility) helper = SwaptionHelper(Period(start, Years), Period(length, Years), vol, index, Period(1, Years), Thirty360(), Actual360(), yield_ts) helper.set_pricing_engine(engine) swaptions.append(helper) # Set up the optimization problem om = LevenbergMarquardt(1.0e-8, 1.0e-8, 1.0e-8) endCriteria = EndCriteria(10000, 100, 1e-6, 1e-8, 1e-8) model.calibrate(swaptions, om, endCriteria) print('Hull White calibrated parameters:\na: %f sigma: %f' % (model.a, model.sigma)) cached_a = 0.0464041 cached_sigma = 0.00579912 tolerance = 1.0e-5 self.assertAlmostEqual(cached_a, model.a, delta=tolerance) self.assertAlmostEqual(cached_sigma, model.sigma, delta=tolerance)
def setUp(self): self.settings = Settings() self.calendar = TARGET() self.todays_date = Date(15, May, 1998) self.settlement_date = Date(17, May, 1998) self.settings.evaluation_date = self.todays_date # options parameters self.option_type = Put self.underlying = 36 self.strike = 40 self.dividend_yield = 0.00 self.risk_free_rate = 0.06 self.volatility = 0.20 self.maturity = Date(17, May, 1999) self.daycounter = Actual365Fixed() self.underlyingH = SimpleQuote(self.underlying) # bootstrap the yield/dividend/vol curves self.flat_term_structure = FlatForward( reference_date=self.settlement_date, forward=self.risk_free_rate, daycounter=self.daycounter) self.flat_dividend_ts = FlatForward( reference_date=self.settlement_date, forward=self.dividend_yield, daycounter=self.daycounter) self.flat_vol_ts = BlackConstantVol(self.settlement_date, self.calendar, self.volatility, self.daycounter) self.black_scholes_merton_process = BlackScholesMertonProcess( self.underlyingH, self.flat_dividend_ts, self.flat_term_structure, self.flat_vol_ts) self.payoff = PlainVanillaPayoff(self.option_type, self.strike) #Additional parameters for testing DividendVanillaOption self.dividend_dates = [] self.dividends = [] self.american_time_steps = 600 self.american_grid_points = 600 #Parameters for implied volatility: self.accuracy = 0.001 self.max_evaluations = 1000 self.min_vol = 0.001 self.max_vol = 4 self.target_price = 4.485992
def test_settings_context_manager(self): Settings().evaluation_date = Date(1, 1, 2018) with Settings() as settings: settings.evaluation_date = Date(5, 11, 2018) settings.include_todays_cashflows = True self.assertTrue(Settings().include_todays_cashflows) self.assertEqual(Settings().evaluation_date, settings.evaluation_date) self.assertEqual(Settings().evaluation_date, Date(1, 1, 2018)) self.assertFalse(Settings().include_todays_cashflows)
def pydate_to_qldate(date): """ Converts a datetime object or a date string into a QL Date. """ if isinstance(date, basestring): yy, mm, dd = _parsedate(date) return Date(dd, mm, yy) else: return Date(date.day, date.month, date.year)
def test_construction(self): self.assertEqual(self.fut_quote.volatility, self.volatility.value) self.assertEqual(self.fut_quote.mean_reversion, self.mean_reversion.value) self.assertEqual(self.fut_quote.futures_value, self.quote.value) imm_date = Date(21, 12, 2022) self.assertEqual(self.fut_quote.imm_date, imm_date) last_date = Date(10, 12, 2022) fut_quote = FuturesConvAdjustmentQuote(self.index, last_date, self.quote, self.volatility, self.mean_reversion) self.assertEqual(fut_quote.imm_date, last_date)
def example03(): print("example 3:\n") todays_date = Date(13, 6, 2011) Settings.instance().evaluation_date = todays_date quotes = [0.00445, 0.00949, 0.01234, 0.01776, 0.01935, 0.02084] tenors = [1, 2, 3, 6, 9, 12] calendar = WeekendsOnly() deps = [ DepositRateHelper(q, Period(t, Months), 2, calendar, ModifiedFollowing, False, Actual360()) for q, t in zip(quotes, tenors) ] quotes = [ 0.01652, 0.02018, 0.02303, 0.02525, 0.0285, 0.02931, 0.03017, 0.03092, 0.03160, 0.03231, 0.03367, 0.03419, 0.03411, 0.03411, 0.03412 ] tenors = [2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 15, 20, 25, 30] swaps = [ SwapRateHelper.from_tenor(q, Period(t, Years), calendar, Annual, ModifiedFollowing, Thirty360(), Euribor6M(), SimpleQuote(0)) for q, t in zip(quotes, tenors) ] yield_helpers = deps + swaps isda_yts = PiecewiseYieldCurve(BootstrapTrait.Discount, Interpolator.LogLinear, 0, WeekendsOnly(), yield_helpers, Actual365Fixed()) spreads = [0.007927, 0.012239, 0.016979, 0.019271, 0.020860] tenors = [1, 3, 5, 7, 10] spread_helpers = [SpreadCdsHelper(0.007927, Period(6, Months), 1, WeekendsOnly(), Quarterly, Following, Rule.CDS2015, Actual360(), 0.4, isda_yts, True, True, Date(), Actual360(True), True, PricingModel.ISDA)] + \ [SpreadCdsHelper(s, Period(t, Years), 1, WeekendsOnly(), Quarterly, Following, Rule.CDS2015, Actual360(), 0.4, isda_yts, True, True, Date(), Actual360(True), True, PricingModel.ISDA) for s, t in zip(spreads, tenors)] isda_cts = PiecewiseDefaultCurve(ProbabilityTrait.SurvivalProbability, Interpolator.LogLinear, 0, WeekendsOnly(), spread_helpers, Actual365Fixed()) isda_pricer = IsdaCdsEngine(isda_cts, 0.4, isda_yts) print("Isda yield curve:") for h in yield_helpers: d = h.latest_date t = isda_yts.time_from_reference(d) print(d, t, isda_yts.zero_rate(d, Actual365Fixed()).rate) print() print("Isda credit curve:") for h in spread_helpers: d = h.latest_date t = isda_cts.time_from_reference(d) print(d, t, isda_cts.survival_probability(d))
def test_creation(self): settings = Settings() # Market information calendar = TARGET() # must be a business day settings.evaluation_date = calendar.adjust(today()) settlement_date = Date(18, September, 2008) # must be a business day settlement_date = calendar.adjust(settlement_date); quotes = [0.0096, 0.0145, 0.0194] tenors = [3, 6, 12] rate_helpers = [] calendar = TARGET() deposit_day_counter = Actual365Fixed() convention = ModifiedFollowing end_of_month = True for quote, month in zip(quotes, tenors): tenor = Period(month, Months) fixing_days = 3 helper = DepositRateHelper( quote, tenor, fixing_days, calendar, convention, end_of_month, deposit_day_counter ) 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 ) self.assertIsNotNone(ts) self.assertEquals( Date(18, September, 2008), ts.reference_date) # this is not a real test ... self.assertAlmostEquals(0.9975, ts.discount(Date(21, 12, 2008)), 4) self.assertAlmostEquals(0.9944, ts.discount(Date(21, 4, 2009)), 4) self.assertAlmostEquals(0.9904, ts.discount(Date(21, 9, 2009)), 4)
def test_relativedate_rate_helper(self): tenor = Period(3, Months) fixing_days = 3 calendar = TARGET() convention = ModifiedFollowing end_of_month = True deposit_day_counter = Actual365Fixed() helper = DepositRateHelper(0.005, tenor, fixing_days, calendar, convention, end_of_month, deposit_day_counter) Settings.instance().evaluation_date = Date(8, 6, 2016) self.assertEqual(helper.latest_date, Date(13, 9, 2016))
def setUp(self): option_date = Date(20, 9, 2017) Settings().evaluation_date = Date(4, 8, 2017) self.strikes = (np.array([50, 55, 57.5, 60, 62.5, 65, 67.5, 70, 75, 80, 85, 90, 95, 100]) * 1e-4).tolist() vol = np.array([28.5, 31.6, 33.7, 36.1, 38.7, 41.5, 44.1, 46.5, 50.8, 54.4, 57.3, 59.8, 61.8, 63.6]) * 1e-2 vol_quotes = [SimpleQuote(q) for q in vol] self.forward = SimpleQuote(58.71e-4) atm_vol = (60-58.71)/1.5*33.7 + (58.71-57.5)/1.5*36.1 self.sabr_smile = SabrInterpolatedSmileSection(option_date, self.forward, self.strikes, False, SimpleQuote(0.4), vol_quotes, 0.1, 1, 0.1, 0.5, is_beta_fixed=True)
def setUp(self): self.settings = Settings() self.calendar = TARGET() self.todays_date = Date(15, May, 1998) self.settlement_date = Date(17, May, 1998) self.settings.evaluation_date = self.todays_date # options parameters self.option_type = Put self.underlying = 36 self.strike = 40 self.dividend_yield = 0.00 self.risk_free_rate = 0.06 self.volatility = 0.20 self.maturity = Date(17, May, 1999) self.daycounter = Actual365Fixed() self.underlyingH = SimpleQuote(self.underlying) # bootstrap the yield/dividend/vol curves self.flat_term_structure = FlatForward( reference_date = self.settlement_date, forward = self.risk_free_rate, daycounter = self.daycounter ) self.flat_dividend_ts = FlatForward( reference_date = self.settlement_date, forward = self.dividend_yield, daycounter = self.daycounter ) self.flat_vol_ts = BlackConstantVol( self.settlement_date, self.calendar, self.volatility, self.daycounter ) self.black_scholes_merton_process = BlackScholesMertonProcess( self.underlyingH, self.flat_dividend_ts, self.flat_term_structure, self.flat_vol_ts ) self.payoff = PlainVanillaPayoff(self.option_type, self.strike)
def test_all_types_of_piecewise_curves(self): settings = Settings() # Market information calendar = TARGET() todays_date = Date(12, September, 2008) # must be a business day settings.evaluation_date = calendar.adjust(todays_date) settlement_date = Date(18, September, 2008) # must be a business day settlement_date = calendar.adjust(settlement_date) quotes = [ SimpleQuote(0.0096), SimpleQuote(0.0145), SimpleQuote(0.0194) ] tenors = [3, 6, 12] rate_helpers = [] deposit_day_counter = Actual365Fixed() convention = ModifiedFollowing end_of_month = True for quote, month in zip(quotes, tenors): tenor = Period(month, Months) fixing_days = 3 helper = DepositRateHelper(quote, tenor, fixing_days, calendar, convention, end_of_month, deposit_day_counter) rate_helpers.append(helper) tolerance = 1.0e-15 for trait in BootstrapTrait: for interpolation in Interpolator: ts = PiecewiseYieldCurve.from_reference_date( trait, interpolation, settlement_date, rate_helpers, deposit_day_counter, tolerance) self.assertIsNotNone(ts) self.assertEqual(Date(18, September, 2008), ts.reference_date)
def test_bond_schedule_anotherday(self): '''Test date calculations and role of settings when evaluation date set to arbitrary date. This test is known to fail with boost 1.42. ''' todays_date = Date(30, 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, Rule.Backward ) issue_date = effective_date bond = FixedRateBond( settlement_days, face_amount, fixed_bond_schedule, [coupon_rate], ActualActual(ISMA), Following, redemption, issue_date ) self.assertEqual( calendar.advance(todays_date, 3, Days), bond.settlement_date())
def test_discount_curve(self): settings = Settings() settings.evaluation_date = Date(6, 10, 2016) # Market information calendar = TARGET() quotes = [SimpleQuote(0.0096), SimpleQuote(0.0145), SimpleQuote(0.0194)] tenors = [3, 6, 12] deposit_day_counter = Actual365Fixed() convention = ModifiedFollowing end_of_month = True fixing_days = 3 rate_helpers = [DepositRateHelper( quote, Period(month, Months), fixing_days, calendar, convention, end_of_month, deposit_day_counter) for quote, month in zip(quotes, tenors)] ts_day_counter = ActualActual(ISDA) tolerance = 1.0e-15 ts = PiecewiseYieldCurve( BootstrapTrait.ForwardRate, Interpolator.BackwardFlat, 2, calendar, rate_helpers, ts_day_counter, tolerance ) dates = [rh.latest_date for rh in rate_helpers] dfs = [ts.discount(d) for d in dates] dates.insert(0, ts.reference_date) dfs.insert(0, 1) ts_discount = DiscountCurve(dates, dfs, ts_day_counter, calendar) self.assertTrue(ts.discount(0.75), ts_discount.discount(0.75))
def test_bump_yieldcurve(self): settings = Settings() settings.evaluation_date = Date(6, 10, 2016) # Market information calendar = TARGET() quotes = [SimpleQuote(0.0096), SimpleQuote(0.0145), SimpleQuote(0.0194)] tenors = [3, 6, 12] deposit_day_counter = Actual365Fixed() convention = ModifiedFollowing end_of_month = True fixing_days = 3 rate_helpers = [DepositRateHelper( quote, Period(month, Months), fixing_days, calendar, convention, end_of_month, deposit_day_counter) for quote, month in zip(quotes, tenors)] ts_day_counter = ActualActual(ISDA) tolerance = 1.0e-15 ts = PiecewiseYieldCurve( BootstrapTrait.Discount, Interpolator.LogLinear, 2, calendar, rate_helpers, ts_day_counter, tolerance ) old_discount = ts.discount(ts.max_date) # parallel shift of 1 bps for rh in rate_helpers: rh.quote.value += 1e-4 self.assertEqual([q.value for q in quotes], [rh.quote.value for rh in rate_helpers]) new_discount = ts.discount(ts.max_date) self.assertTrue(new_discount < old_discount)
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 create_helper(): calendar = TARGET() todays_date = Date(15, May, 2007) todays_date = calendar.adjust(todays_date) Settings.instance().evaluation_date = todays_date flat_rate = SimpleQuote(0.01) ts_curve = FlatForward(todays_date, flat_rate, Actual365Fixed()) recovery_rate = 0.5 quoted_spreads = 0.0150 tenor = Period(5, Years) helper = SpreadCdsHelper(quoted_spreads, tenor, 0, calendar, Quarterly, Following, Rule.TwentiethIMM, Actual365Fixed(), recovery_rate, ts_curve, model=PricingModel.Midpoint) return todays_date, helper
class FlatHazardRateTestCase(unittest.TestCase): calendar = TARGET() todays_date = Date(15, May, 2007) todays_date = calendar.adjust(todays_date) d = todays_date + Period(3, Years) def test_create_flat_hazard(self): Settings.instance().evaluation_date = self.todays_date flat_curve = FlatHazardRate(2, self.calendar, 0.05, Actual365Fixed()) flat_curve_from_reference_date = FlatHazardRate.from_reference_date( self.calendar.advance(self.todays_date, 2, Days), 0.05, Actual365Fixed()) self.assertIsNotNone(flat_curve) self.assertIsNotNone(flat_curve_from_reference_date) self.assertEqual( flat_curve.time_from_reference(self.d), flat_curve_from_reference_date.time_from_reference(self.d)) self.assertAlmostEqual(flat_curve.hazard_rate(self.d), 0.05) self.assertAlmostEqual( flat_curve.survival_probability(self.d), math.exp(-0.05 * flat_curve.time_from_reference(self.d))) def test_flat_hazard_with_quote(self): Settings.instance().evaluation_date = self.todays_date hazard_rate = SimpleQuote() flat_curve = FlatHazardRate(2, self.calendar, hazard_rate, Actual365Fixed()) for h in [0.01, 0.02, 0.03]: hazard_rate.value = h self.assertAlmostEqual( flat_curve.survival_probability(self.d), math.exp(-h * flat_curve.time_from_reference(self.d)))
def test_zero_curve(self): rate_helpers = build_helpers() settings = Settings() calendar = TARGET() # must be a business Days dtObs = date(2007, 4, 27) eval_date = calendar.adjust(pydate_to_qldate(dtObs)) 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) ts_day_counter = ActualActual(ISDA) tolerance = 1.0e-2 ts = PiecewiseYieldCurve.from_reference_date(BootstrapTrait.Discount, Interpolator.LogLinear, settlement_date, rate_helpers, ts_day_counter, tolerance) # max_date raises an exception... ts.extrapolation = True zr = ts.zero_rate(Date(10, 5, 2027), ts_day_counter, 2) self.assertAlmostEqual(zr.rate, 0.0539332, 6)
def testImpliedRates(self): """ Testing if rates implied from the curve are returning fx forwards very close to those used for bootstrapping """ self.build_curves(self.default_quote_date) # Not sure if all Python versions and machine will guarantee that the # lists are not messed, probably some ordered maps should be used # here while retrieving values from fx_swap_quotes dictionary original_quotes = list(self.fx_swap_quotes.values()) spot_date = Date(30, 8, 2016) spot_df = self.eur_ois_curve.discount( spot_date) / self.pln_eur_implied_curve.discount(spot_date) for original_quote, maturity in zip(original_quotes, self.maturities): original_forward = self.fx_spot_quote_EURPLN + original_quote curve_impl_forward = ( self.fx_spot_quote_EURPLN * self.eur_ois_curve.discount(maturity) / self.pln_eur_implied_curve.discount(maturity) / spot_df ) self.assertAlmostEqual(original_forward, curve_impl_forward, places=6)
def setUp(self): Settings.instance().evaluation_date = Date(26, 5, 2021) self.basis_point = 1.0e-4 self.settlement_days = 2 self.business_day_convention = Following self.calendar = TARGET() self.day_count = Actual365Fixed() self.end_of_month = False base_ccy_idx_handle = flat_rate(0.007) quoted_ccy_idx_handle = flat_rate(0.015) self.base_ccy_idx = Euribor3M(base_ccy_idx_handle) self.quote_ccy_idx = USDLibor( Period(3, Months), quoted_ccy_idx_handle) self.collateral_ccy_handle = flat_rate(0.009) # Cross currency basis swaps data source: # N. Moreni, A. Pallavicini (2015) # FX Modelling in Collateralized Markets: foreign measures, basis curves # and pricing formulae. # section 4.2.1, Table 2. self.cross_currency_basis_quotes = ((Period(1, Years), -14.5), (Period(18, Months), -18.5), (Period(2, Years), -20.5), (Period(3, Years), -23.75), (Period(4, Years), -25.5), (Period(5, Years), -26.5), (Period(7, Years), -26.75), (Period(10, Years), -26.25), (Period(15, Years), -24.75), (Period(20, Years), -23.25), (Period(30, Years), -20.50))
def setUp(self): self.settings = Settings() self.calendar = NullCalendar() self.todays_date = Date(15, May, 1998) self.settlement_date = Date(17, May, 1998) self.settings.evaluation_date = self.todays_date # options parameters self.dividend_yield = 0.00 self.risk_free_rate = 0.06 self.volatility = 0.25 self.spot = SimpleQuote(100) self.maturity = Date(17, May, 1999) self.daycounter = Actual365Fixed() self.tol = 1e-2 # bootstrap the yield/dividend/vol curves dates = [self.settlement_date] + \ [self.settlement_date + Period(i + 1, Years) for i in range(40)] rates = [0.01] + \ [0.01 + 0.0002 * np.exp(np.sin(i / 4.0)) for i in range(40)] divRates = [0.02] + \ [0.02 + 0.0001 * np.exp(np.sin(i / 5.0)) for i in range(40)] self.r_ts = ZeroCurve(dates, rates, self.daycounter) self.q_ts = ZeroCurve(dates, divRates, self.daycounter) self.vol_ts = BlackConstantVol( self.settlement_date, self.calendar, self.volatility, self.daycounter ) self.black_scholes_merton_process = BlackScholesMertonProcess( self.spot, self.q_ts, self.r_ts, self.vol_ts ) self.dates = dates
def test_deposit_end_of_month(self): tenor = Period(3, Months) fixing_days = 0 calendar = TARGET() convention = ModifiedFollowing end_of_month = True deposit_day_counter = Actual365Fixed() helper_end_of_month = DepositRateHelper(0.005, tenor, fixing_days, calendar, convention, True, deposit_day_counter) helper_no_end_of_month = DepositRateHelper(0.005, tenor, fixing_days, calendar, convention, False, deposit_day_counter) Settings.instance().evaluation_date = Date(29, 2, 2016) self.assertEqual(helper_end_of_month.latest_date, Date(31, 5, 2016)) self.assertEqual(helper_no_end_of_month.latest_date, Date(30, 5, 2016))
def example02(): print("example 2:\n") todays_date = Date(25, 9, 2014) Settings.instance().evaluation_date = todays_date calendar = TARGET() term_date = calendar.adjust(todays_date + Period(2, Years), Following) cds_schedule = Schedule(todays_date, term_date, Period(Quarterly), WeekendsOnly(), ModifiedFollowing, ModifiedFollowing, date_generation_rule=Rule.CDS) for date in cds_schedule: print(date) print() todays_date = Date(21, 10, 2014) Settings.instance().evaluation_date = todays_date quotes = [0.00006, 0.00045, 0.00081, 0.001840, 0.00256, 0.00337] tenors = [1, 2, 3, 6, 9, 12] deps = [DepositRateHelper(q, Period(t, Months), 2, calendar, ModifiedFollowing, False, Actual360()) for q, t in zip(quotes, tenors)] tenors = [2, 3, 4, 5, 6, 7, 8, 9, 10, 12, 15, 20, 30] quotes = [0.00223, 0.002760, 0.003530, 0.004520, 0.005720, 0.007050, 0.008420, 0.009720, 0.010900, 0.012870, 0.014970, 0.017, 0.01821] swaps = [SwapRateHelper.from_tenor(q, Period(t, Years), calendar, Annual, ModifiedFollowing, Thirty360(), Euribor6M(), SimpleQuote(0)) for q, t in zip(quotes, tenors)] helpers = deps + swaps YC = PiecewiseYieldCurve.from_reference_date(BootstrapTrait.Discount, Interpolator.LogLinear, todays_date, helpers, Actual365Fixed()) YC.extrapolation = True print("ISDA rate curve:") for h in helpers: print("{0}: {1:.6f}\t{2:.6f}".format(h.latest_date, YC.zero_rate(h.latest_date, Actual365Fixed(), 2).rate, YC.discount(h.latest_date))) defaultTs0 = FlatHazardRate(0, WeekendsOnly(), 0.016739207493630, Actual365Fixed()) cds_schedule = Schedule.from_rule(Date(22, 9, 2014), Date(20, 12, 2019), Period(3, Months), WeekendsOnly(), Following, Unadjusted, Rule.CDS, False) nominal = 100000000 trade = CreditDefaultSwap(Side.Buyer, nominal, 0.01, cds_schedule, Following, Actual360(), True, True, Date(22, 10, 2014), Actual360(True), True) engine = IsdaCdsEngine(defaultTs0, 0.4, YC, False) trade.set_pricing_engine(engine) print("reference trade NPV = {0}\n".format(trade.npv))
def zero_curve(ts, dtObs): dtMax = ts.max_date calendar = TARGET() days = range(10, 365 * 20, 30) dtMat = [min(dtMax, calendar.advance(Date.from_datetime(dtObs), d, Days)) for d in days] # largest dtMat < dtMax, yet QL run time error df = np.array([ts.discount(dt) for dt in dtMat]) dtMat = [pydate_from_qldate(dt) for dt in dtMat] dtToday = dtObs.date() dt = np.array([(d - dtToday).days / 365.0 for d in dtMat]) zc = -np.log(df) / dt return (dtMat, zc)
def _get_option_npv(self): """ Suboptimal getter for the npv. FIXME: We currently have to recreate most of the objects because we do not expose enough of the QuantLib api. """ # convert datetime object to QlDate maturity = QlDate.from_datetime(self.maturity) underlyingH = SimpleQuote(self.underlying) # bootstrap the yield/dividend/vol curves flat_term_structure = FlatForward( reference_date = settlement_date, forward = self.risk_free_rate, daycounter = self.daycounter ) flat_dividend_ts = FlatForward( reference_date = settlement_date, forward = self.dividend_yield, daycounter = self.daycounter ) flat_vol_ts = BlackConstantVol( settlement_date, calendar, self.volatility, self.daycounter ) black_scholes_merton_process = BlackScholesMertonProcess( underlyingH, flat_dividend_ts, flat_term_structure,flat_vol_ts ) payoff = PlainVanillaPayoff(self.option_type, self.strike) 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) return european_option.net_present_value
def get_term_structure(df_libor, dtObs): settings = Settings() # Market information calendar = TARGET() # must be a business day eval_date = calendar.adjust(Date.from_datetime(dtObs)) 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, 'Libor1M'], [3, Months, 'Libor3M'], [6, Months, 'Libor6M']] swapData = [[1, Years, 'Swap1Y'], [2, Years, 'Swap2Y'], [3, Years, 'Swap3Y'], [4, Years, 'Swap4Y'], [5, Years, 'Swap5Y'], [7, Years, 'Swap7Y'], [10, Years, 'Swap10Y'], [30, Years, 'Swap30Y']] rate_helpers = [] end_of_month = True for m, period, label in depositData: tenor = Period(m, Months) rate = df_libor.get_value(dtObs, label) helper = DepositRateHelper(SimpleQuote(rate / 100.0), tenor, settlement_days, calendar, ModifiedFollowing, end_of_month, Actual360()) rate_helpers.append(helper) liborIndex = Libor('USD Libor', Period(3, Months), settlement_days, USDCurrency(), calendar, Actual360()) spread = SimpleQuote(0) fwdStart = Period(0, Days) for m, period, label in swapData: rate = df_libor.get_value(dtObs, label) helper = SwapRateHelper.from_tenor( SimpleQuote(rate / 100.0), Period(m, Years), calendar, Semiannual, ModifiedFollowing, 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) ts.extrapolation = True return ts